diff --git a/.travis.yml b/.travis.yml index 465d80f57..997289704 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ os: - linux - osx -osx_image: xcode7.3 +osx_image: xcode8.2 language: cpp sudo: required dist: trusty diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 6955825a4..f3d0f716b 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -12,7 +12,7 @@ cd build cmake \ -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.8" \ --D CMAKE_OSX_SYSROOT="macosx10.11" \ +-D CMAKE_OSX_SYSROOT="macosx10.12" \ -D CMAKE_BUILD_TYPE=Debug \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D DESIRED_QT_VERSION=5 \ diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index c363185ee..4a4a9a573 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -75,6 +75,14 @@ namespace ESSImport out.mMarkedPosition.rot[0] = out.mMarkedPosition.rot[1] = 0.0f; out.mMarkedPosition.rot[2] = mark.mRotZ; } + + if (pcdt.mHasENAM) + { + const int cellSize = 8192; + out.mLastKnownExteriorPosition[0] = (pcdt.mENAM.mCellX + 0.5f) * cellSize; + out.mLastKnownExteriorPosition[1] = (pcdt.mENAM.mCellY + 0.5f) * cellSize; + out.mLastKnownExteriorPosition[2] = 0.0f; + } } } diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index 2288b149c..6921cce92 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -62,7 +62,10 @@ namespace ESSImport playerCellId.mPaged = true; playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0; mPlayer.mCellId = playerCellId; - //mPlayer.mLastKnownExteriorPosition + mPlayer.mLastKnownExteriorPosition[0] + = mPlayer.mLastKnownExteriorPosition[1] + = mPlayer.mLastKnownExteriorPosition[2] + = 0.0f; mPlayer.mHasMark = 0; mPlayer.mCurrentCrimeId = 0; // TODO mPlayer.mObject.blank(); diff --git a/apps/essimporter/importplayer.cpp b/apps/essimporter/importplayer.cpp index 85a3c3fd5..8c275a286 100644 --- a/apps/essimporter/importplayer.cpp +++ b/apps/essimporter/importplayer.cpp @@ -37,6 +37,14 @@ namespace ESSImport if (esm.isNextSub("NAM9")) esm.skipHSub(); + // Rest state. You shouldn't even be able to save during rest, but skip just in case. + if (esm.isNextSub("RNAM")) + /* + int hoursLeft; + float x, y, z; // resting position + */ + esm.skipHSub(); // 16 bytes + mBounty = 0; esm.getHNOT(mBounty, "CNAM"); @@ -70,12 +78,19 @@ namespace ESSImport mFactions.push_back(fnam); } - if (esm.isNextSub("AADT")) - esm.skipHSub(); // 44 bytes, no clue + mHasAADT = false; + if (esm.isNextSub("AADT")) // Attack animation data? + { + mHasAADT = true; + esm.getHT(mAADT); + } if (esm.isNextSub("KNAM")) esm.skipHSub(); // assigned Quick Keys, I think + if (esm.isNextSub("ANIS")) + esm.skipHSub(); // 16 bytes + if (esm.isNextSub("WERE")) { // some werewolf data, 152 bytes @@ -83,10 +98,6 @@ namespace ESSImport esm.getSubHeader(); esm.skip(152); } - - // unsure if before or after WERE - if (esm.isNextSub("ANIS")) - esm.skipHSub(); } } diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 775994444..924522383 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -98,6 +98,12 @@ struct PCDT int mCellX; int mCellY; }; + + struct AADT // 44 bytes + { + int animGroupIndex; // See convertANIS() for the mapping. + unsigned char mUnknown5[40]; + }; #pragma pack(pop) std::vector mFactions; @@ -109,6 +115,9 @@ struct PCDT bool mHasENAM; ENAM mENAM; // last exterior cell + bool mHasAADT; + AADT mAADT; + void load(ESM::ESMReader& esm); }; diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 51e92c77e..df8df81fb 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -218,7 +218,6 @@ if (MSVC) if (CMAKE_CL_64) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) - add_definitions("-D_USE_MATH_DEFINES") endif (MSVC) if (WIN32) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 37a84b287..d51918152 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -107,11 +107,11 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const { const MWWorld::Ptr player = MWMechanics::getPlayer(); + MWMechanics::NpcStats& stats = player.getClass().getNpcStats (player); - // check player faction + // check player faction and rank if (!info.mPcFaction.empty()) { - MWMechanics::NpcStats& stats = player.getClass().getNpcStats (player); std::map::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (info.mPcFaction)); if(iter==stats.getFactionRanks().end()) @@ -121,6 +121,18 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const if (iter->second < info.mData.mPCrank) return false; } + else if (info.mData.mPCrank != -1) + { + // required PC faction is not specified but PC rank is; use speaker's faction + std::map::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (mActor.getClass().getPrimaryFaction(mActor))); + + if(iter==stats.getFactionRanks().end()) + return false; + + // check rank + if (iter->second < info.mData.mPCrank) + return false; + } // check cell if (!info.mCell.empty()) diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index b7e24a7ee..72e1c09f3 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -428,7 +428,9 @@ namespace MWGui { // split lines const int lineHeight = currentFontHeight(); - unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()) / lineHeight; + unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()); + if (lineHeight > 0) + lastLine /= lineHeight; int ret = mPaginator.getCurrentTop() + lastLine * lineHeight; // first empty lines that would go to the next page should be ignored diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 544fb0199..7cfa38ff2 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -996,6 +996,8 @@ namespace MWPhysics bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr &actor, const float waterlevel) { const Actor* physicActor = getActor(actor); + if (!physicActor) + return false; const float halfZ = physicActor->getHalfExtents().z(); const osg::Vec3f actorPosition = physicActor->getPosition(); const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index fba5f17b2..57dd29c33 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -943,8 +943,8 @@ public: void setState(const MoonState& state) { - float radsX = ((state.mRotationFromHorizon) * M_PI) / 180.0f; - float radsZ = ((state.mRotationFromNorth) * M_PI) / 180.0f; + float radsX = ((state.mRotationFromHorizon) * static_cast(osg::PI)) / 180.0f; + float radsZ = ((state.mRotationFromNorth) * static_cast(osg::PI)) / 180.0f; osg::Quat rotX(radsX, osg::Vec3f(1.0f, 0.0f, 0.0f)); osg::Quat rotZ(radsZ, osg::Vec3f(0.0f, 0.0f, 1.0f)); @@ -954,7 +954,7 @@ public: // The moon quad is initially oriented facing down, so we need to offset its X-axis // rotation to rotate it to face the camera when sitting at the horizon. - osg::Quat attX((-M_PI / 2.0f) + radsX, osg::Vec3f(1.0f, 0.0f, 0.0f)); + osg::Quat attX((-static_cast(osg::PI) / 2.0f) + radsX, osg::Vec3f(1.0f, 0.0f, 0.0f)); mTransform->setAttitude(attX * rotZ); setPhase(state.mPhase); diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 0a1ec669e..3745554ef 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -408,8 +408,7 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) std::pair, bool> itemsSlots = weapon->getClass().getEquipmentSlots (*weapon); - for (std::vector::const_iterator slot (itemsSlots.first.begin()); - slot!=itemsSlots.first.end(); ++slot) + if (!itemsSlots.first.empty()) { if (!itemsSlots.second) { @@ -419,8 +418,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) } } - slots_[*slot] = weapon; - break; + int slot = itemsSlots.first.front(); + slots_[slot] = weapon; } break; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 48ab1187f..b7c5736bd 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -695,9 +695,9 @@ void WeatherManager::update(float duration, bool paused) double theta; if ( !is_night ) { - theta = M_PI * (adjustedHour - mSunriseTime) / dayDuration; + theta = static_cast(osg::PI) * (adjustedHour - mSunriseTime) / dayDuration; } else { - theta = M_PI * (1.f - (adjustedHour - adjustedNightStart) / nightDuration); + theta = static_cast(osg::PI) * (1.f - (adjustedHour - adjustedNightStart) / nightDuration); } osg::Vec3f final(