diff --git a/CMakeLists.txt b/CMakeLists.txt index 081a2befa..593fcd757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,9 +275,6 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) endif (APPLE) -# Set up DEBUG define -set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1) - if (NOT APPLE) set(OPENMW_MYGUI_FILES_ROOT ${OpenMW_BINARY_DIR}) set(OPENMW_SHADERS_ROOT ${OpenMW_BINARY_DIR}) @@ -607,7 +604,7 @@ if (WIN32) if (USE_DEBUG_CONSOLE AND BUILD_OPENMW) set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE") - set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE") + set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS $<$:_CONSOLE>) elseif (BUILD_OPENMW) # Turn off debug console, debug output will be written to visual studio output instead set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS") @@ -617,7 +614,6 @@ if (WIN32) if (BUILD_OPENMW) # Release builds don't use the debug console set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") - set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_RELEASE "_WINDOWS") set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS") endif() diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 176adfad0..7c39a785e 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -7,7 +7,6 @@ #include "engine.hpp" #if defined(_WIN32) -// For OutputDebugString #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index f1d42ea1c..c4a8417db 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -29,14 +29,13 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); - if (target == MWWorld::Ptr() || - !target.getRefData().getCount() || !target.getRefData().isEnabled() // Really we should check whether the target is currently registered - // with the MechanicsManager - ) - return true; //Target doesn't exist + // Stop if the target doesn't exist + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return true; //Set the target destination for the actor - const auto dest = target.getRefData().getPosition().asVec3(); + const osg::Vec3f dest = target.getRefData().getPosition().asVec3(); if (pathTo(actor, dest, duration, MWBase::Environment::get().getWorld()->getMaxActivationDistance())) //Stop when you get in activation range { diff --git a/apps/openmw/mwmechanics/aibreathe.cpp b/apps/openmw/mwmechanics/aibreathe.cpp index 36acc75d5..4955f683c 100644 --- a/apps/openmw/mwmechanics/aibreathe.cpp +++ b/apps/openmw/mwmechanics/aibreathe.cpp @@ -26,9 +26,9 @@ bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterContro { if (actorClass.getNpcStats(actor).getTimeToStartDrowning() < fHoldBreathTime / 2) { - actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); + actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); - actor.getClass().getMovementSettings(actor).mPosition[1] = 1; + actorClass.getMovementSettings(actor).mPosition[1] = 1; smoothTurn(actor, -180, 0); return false; diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 59c840a49..3d018d780 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -83,24 +83,13 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false); - const float* const leaderPos = actor.getRefData().getPosition().pos; - const float* const followerPos = follower.getRefData().getPosition().pos; - double differenceBetween[3]; + const osg::Vec3f leaderPos = actor.getRefData().getPosition().asVec3(); + const osg::Vec3f followerPos = follower.getRefData().getPosition().asVec3(); - for (short counter = 0; counter < 3; counter++) - differenceBetween[counter] = (leaderPos[counter] - followerPos[counter]); - - double distanceBetweenResult = - (differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * - differenceBetween[2]); - - if (distanceBetweenResult <= mMaxDist * mMaxDist) + if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist) { - ESM::Pathgrid::Point point(static_cast(mX), static_cast(mY), static_cast(mZ)); - point.mAutogenerated = 0; - point.mConnectionNum = 0; - point.mUnknown = 0; - if (pathTo(actor, osg::Vec3f(mX, mY, mZ), duration)) //Returns true on path complete + const osg::Vec3f dest(mX, mY, mZ); + if (pathTo(actor, dest, duration)) //Returns true on path complete { mRemainingDuration = mDuration; return true; diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index 2bd685035..09e8d0ecd 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -74,12 +74,12 @@ AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow) bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - MWWorld::Ptr target = getTarget(); + const MWWorld::Ptr target = getTarget(); - if (target.isEmpty() || !target.getRefData().getCount() || !target.getRefData().isEnabled() // Really we should be checking whether the target is currently registered - // with the MechanicsManager - ) - return false; // Target is not here right now, wait for it to return + // Target is not here right now, wait for it to return + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return false; actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); @@ -94,6 +94,10 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte return false; } + const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); + const osg::Vec3f targetPos(target.getRefData().getPosition().asVec3()); + const osg::Vec3f targetDir = targetPos - actorPos; + // AiFollow requires the target to be in range and within sight for the initial activation if (!mActive) { @@ -101,9 +105,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte if (storage.mTimer < 0) { - if ((actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length2() - < 500*500 - && MWBase::Environment::get().getWorld()->getLOS(actor, target)) + if (targetDir.length2() < 500*500 && MWBase::Environment::get().getWorld()->getLOS(actor, target)) mActive = true; storage.mTimer = 0.5f; } @@ -111,8 +113,6 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte if (!mActive) return false; - ESM::Position pos = actor.getRefData().getPosition(); //position of the actor - // The distances below are approximations based on observations of the original engine. // If only one actor is following the target, it uses 186. // If there are multiple actors following the same target, they form a group with each group member at 313 + (130 * i) distance to the target. @@ -145,9 +145,8 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte } } - if ((pos.pos[0]-mX)*(pos.pos[0]-mX) + - (pos.pos[1]-mY)*(pos.pos[1]-mY) + - (pos.pos[2]-mZ)*(pos.pos[2]-mZ) < followDistance*followDistance) //Close-ish to final position + osg::Vec3f finalPos(mX, mY, mZ); + if ((actorPos-finalPos).length2() < followDistance*followDistance) //Close-ish to final position { if (actor.getCell()->isExterior()) //Outside? { @@ -162,8 +161,6 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte } } - //Set the target destination from the actor - const auto dest = target.getRefData().getPosition().asVec3(); short baseFollowDistance = followDistance; short threshold = 30; // to avoid constant switching between moving/stopping @@ -172,15 +169,9 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte else followDistance += threshold; - osg::Vec3f targetPos(target.getRefData().getPosition().asVec3()); - osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); - - osg::Vec3f dir = targetPos - actorPos; - float targetDistSqr = dir.length2(); - - if (targetDistSqr <= followDistance * followDistance) + if (targetDir.length2() <= followDistance * followDistance) { - float faceAngleRadians = std::atan2(dir.x(), dir.y()); + float faceAngleRadians = std::atan2(targetDir.x(), targetDir.y()); if (!zTurn(actor, faceAngleRadians, osg::DegreesToRadians(45.f))) { @@ -191,16 +182,14 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte return false; } - storage.mMoving = !pathTo(actor, dest, duration, baseFollowDistance); // Go to the destination + storage.mMoving = !pathTo(actor, targetPos, duration, baseFollowDistance); // Go to the destination if (storage.mMoving) { //Check if you're far away - float dist = distance(dest, pos.asVec3()); - - if (dist > 450) + if (targetDir.length2() > 450 * 450) actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, true); //Make NPC run - else if (dist < 325) //Have a bit of a dead zone, otherwise npc will constantly flip between running and not when right on the edge of the running threshold + else if (targetDir.length2() < 325 * 325) //Have a bit of a dead zone, otherwise npc will constantly flip between running and not when right on the edge of the running threshold actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, false); //make NPC walk } diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index a61b2fa37..bb1650532 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -101,11 +101,11 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& { mTimer += duration; //Update timer - const auto position = actor.getRefData().getPosition().asVec3(); //position of the actor - const auto world = MWBase::Environment::get().getWorld(); + const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); //position of the actor + MWBase::World* world = MWBase::Environment::get().getWorld(); { - const auto halfExtents = world->getHalfExtents(actor); + const osg::Vec3f halfExtents = world->getHalfExtents(actor); world->updateActorPath(actor, mPathFinder.getPath(), halfExtents, position, dest); } @@ -139,7 +139,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& { if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path { - const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); + const osg::Vec3f playerHalfExtents = world->getHalfExtents(getPlayer()); // Using player half extents for better performance mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); mRotateOnTheRunChecks = 3; @@ -161,7 +161,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& if (!mPathFinder.getPath().empty()) //Path has points in it { - const auto& lastPos = mPathFinder.getPath().back(); //Get the end of the proposed path + const osg::Vec3f& lastPos = mPathFinder.getPath().back(); //Get the end of the proposed path if(distance(dest, lastPos) > 100) //End of the path is far from the destination mPathFinder.addPointToPath(dest); //Adds the final destination to the path, to try to get to where you want to go @@ -171,9 +171,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& mTimer = 0; } - const auto pointTolerance = std::min(actor.getClass().getSpeed(actor), DEFAULT_TOLERANCE); + const float pointTolerance = std::min(actor.getClass().getSpeed(actor), DEFAULT_TOLERANCE); - mPathFinder.update(position, pointTolerance, destTolerance); + mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE); if (isDestReached || mPathFinder.checkPathCompleted()) // if path is finished { @@ -223,7 +223,7 @@ void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor) void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) { - const auto world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); static float distance = world->getMaxActivationDistance(); const MWWorld::Ptr door = getNearbyDoor(actor, distance); @@ -296,11 +296,7 @@ bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const os bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor) { - const auto world = MWBase::Environment::get().getWorld(); - const bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && world->isSwimming(actor)) - || world->isFlying(actor); - - if (actorCanMoveByZ) + if (canActorMoveByZAxis(actor)) return true; const float actorSpeed = actor.getClass().getSpeed(actor); @@ -309,18 +305,17 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin const float offsetXY = distToTarget > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2; - const bool isClear = checkWayIsClear(startPoint, endPoint, offsetXY); - // update shortcut prohibit state - if (isClear) + if (checkWayIsClear(startPoint, endPoint, offsetXY)) { if (mShortcutProhibited) { mShortcutProhibited = false; mShortcutFailPos = osg::Vec3f(); } + return true; } - if (!isClear) + else { if (mShortcutFailPos == osg::Vec3f()) { @@ -329,7 +324,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin } } - return isClear; + return false; } bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell) @@ -399,7 +394,7 @@ bool MWMechanics::AiPackage::isReachableRotatingOnTheRun(const MWWorld::Ptr& act DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::Ptr& actor) const { - const auto& actorClass = actor.getClass(); + const MWWorld::Class& actorClass = actor.getClass(); DetourNavigator::Flags result = DetourNavigator::Flag_none; if (actorClass.isPureWaterCreature(actor) || (getTypeId() != TypeIdWander && actorClass.canSwim(actor))) @@ -416,7 +411,6 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld:: bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const { - const auto world = MWBase::Environment::get().getWorld(); - const auto& actorClass = actor.getClass(); - return (actorClass.canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor); + MWBase::World* world = MWBase::Environment::get().getWorld(); + return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor); } diff --git a/apps/openmw/mwmechanics/aipursue.cpp b/apps/openmw/mwmechanics/aipursue.cpp index f746df3ff..4bec050d7 100644 --- a/apps/openmw/mwmechanics/aipursue.cpp +++ b/apps/openmw/mwmechanics/aipursue.cpp @@ -35,27 +35,27 @@ bool AiPursue::execute (const MWWorld::Ptr& actor, CharacterController& characte const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); //The target to follow - if(target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled() // Really we should be checking whether the target is currently registered - // with the MechanicsManager - ) - return true; //Target doesn't exist + // Stop if the target doesn't exist + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return true; if (isTargetMagicallyHidden(target)) return true; - if(target.getClass().getCreatureStats(target).isDead()) + if (target.getClass().getCreatureStats(target).isDead()) return true; actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); - //Set the target desition from the actor - const auto dest = target.getRefData().getPosition().asVec3(); - ESM::Position aPos = actor.getRefData().getPosition(); + //Set the target destination + const osg::Vec3f dest = target.getRefData().getPosition().asVec3(); + const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); - float pathTolerance = 100.0; + const float pathTolerance = 100.f; if (pathTo(actor, dest, duration, pathTolerance) && - std::abs(dest.z() - aPos.pos[2]) < pathTolerance) // check the true distance in case the target is far away in Z-direction + std::abs(dest.z() - actorPos.z()) < pathTolerance) // check the true distance in case the target is far away in Z-direction { target.getClass().activate(target,actor).get()->execute(actor); //Arrest player when reached return true; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index cce9c0314..d87029809 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -21,8 +21,8 @@ bool isWithinMaxRange(const osg::Vec3f& pos1, const osg::Vec3f& pos2) { // Maximum travel distance for vanilla compatibility. // Was likely meant to prevent NPCs walking into non-loaded exterior cells, but for some reason is used in interior cells as well. - // We can make this configurable at some point, but the default *must* be the below value. Anything else will break shoddily-written content (*cough* MW *cough*) in bizarre ways. - bool aiDistance = MWBase::Environment::get().getMechanicsManager()->getActorsProcessingRange(); + // The specific range below is configurable, but its limit is currently 7168 units. Anything greater will break shoddily-written content (*cough* MW *cough*) in bizarre ways. + float aiDistance = MWBase::Environment::get().getMechanicsManager()->getActorsProcessingRange(); return (pos1 - pos2).length2() <= aiDistance*aiDistance; } @@ -47,18 +47,19 @@ namespace MWMechanics bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - ESM::Position pos = actor.getRefData().getPosition(); + const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); + const osg::Vec3f targetPos(mX, mY, mZ); actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); - if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3())) + if (!isWithinMaxRange(targetPos, actorPos)) return false; // Unfortunately, with vanilla assets destination is sometimes blocked by other actor. // If we got close to target, check for actors nearby. If they are, finish AI package. int destinationTolerance = 64; - if (distance(pos.asVec3(), osg::Vec3f(mX, mY, mZ)) <= destinationTolerance) + if (distance(actorPos, targetPos) <= destinationTolerance) { std::vector targetActors; std::pair result = MWBase::Environment::get().getWorld()->getHitContact(actor, destinationTolerance, targetActors); @@ -70,7 +71,7 @@ namespace MWMechanics } } - if (pathTo(actor, osg::Vec3f(mX, mY, mZ), duration)) + if (pathTo(actor, targetPos, duration)) { actor.getClass().getMovementSettings(actor).mPosition[1] = 0; return true; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index ad11f6d4e..833a37127 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -124,14 +124,13 @@ namespace MWMechanics */ bool AiWander::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - // get or create temporary storage - AiWanderStorage& storage = state.get(); - - const MWWorld::CellStore*& currentCell = storage.mCell; MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor); - if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0) + if (cStats.isDead() || cStats.getHealth().getCurrent() <= 0) return true; // Don't bother with dead actors + // get or create temporary storage + AiWanderStorage& storage = state.get(); + const MWWorld::CellStore*& currentCell = storage.mCell; bool cellChange = currentCell && (actor.getCell() != currentCell); if(!currentCell || cellChange) { @@ -159,8 +158,7 @@ namespace MWMechanics } else { - const auto world = MWBase::Environment::get().getWorld(); - const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); + const osg::Vec3f playerHalfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(getPlayer()); // Using player half extents for better performance mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); } @@ -279,9 +277,7 @@ namespace MWMechanics if (mHasDestination) return mDestination; - const ESM::Pathgrid::Point currentPosition = actor.getRefData().getPosition().pos; - const osg::Vec3f currentPositionVec3f = osg::Vec3f(currentPosition.mX, currentPosition.mY, currentPosition.mZ); - return currentPositionVec3f; + return actor.getRefData().getPosition().asVec3(); } bool AiWander::isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage) @@ -314,18 +310,17 @@ namespace MWMechanics const float destinationX = mInitialActorPosition.x() + wanderRadius * std::cos(randomDirection); const float destinationY = mInitialActorPosition.y() + wanderRadius * std::sin(randomDirection); const float destinationZ = mInitialActorPosition.z(); - const osg::Vec3f destinationPosition(destinationX, destinationY, destinationZ); mDestination = osg::Vec3f(destinationX, destinationY, destinationZ); // Check if land creature will walk onto water or if water creature will swim onto land if ((!isWaterCreature && !destinationIsAtWater(actor, mDestination)) || (isWaterCreature && !destinationThroughGround(currentPosition, mDestination))) { - const auto world = MWBase::Environment::get().getWorld();; - const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); - mPathFinder.buildPath(actor, currentPosition, destinationPosition, actor.getCell(), + // Using player half extents for better performance + const osg::Vec3f playerHalfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(getPlayer()); + mPathFinder.buildPath(actor, currentPosition, mDestination, actor.getCell(), getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); - mPathFinder.addPointToPath(destinationPosition); + mPathFinder.addPointToPath(mDestination); if (mPathFinder.isPathConstructed()) { @@ -520,9 +515,9 @@ namespace MWMechanics // Only say Idle voices when player is in LOS // A bit counterintuitive, likely vanilla did this to reduce the appearance of // voices going through walls? - const ESM::Position& pos = actor.getRefData().getPosition(); - if (roll < x && (player.getRefData().getPosition().asVec3() - pos.asVec3()).length2() - < 3000 * 3000 // maybe should be fAudioVoiceDefaultMaxDistance*fAudioMaxDistanceMult instead + const osg::Vec3f playerPos(player.getRefData().getPosition().asVec3()); + const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); + if (roll < x && (playerPos - actorPos).length2() < 3000 * 3000 // maybe should be fAudioVoiceDefaultMaxDistance*fAudioMaxDistanceMult instead && MWBase::Environment::get().getWorld()->getLOS(player, actor)) MWBase::Environment::get().getDialogueManager()->say(actor, "idle"); } @@ -541,13 +536,12 @@ namespace MWMechanics MWWorld::Ptr player = getPlayer(); osg::Vec3f playerPos(player.getRefData().getPosition().asVec3()); osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); - float playerDistSqr = (playerPos - actorPos).length2(); int& greetingTimer = storage.mGreetingTimer; AiWanderStorage::GreetingState& greetingState = storage.mSaidGreeting; if (greetingState == AiWanderStorage::Greet_None) { - if ((playerDistSqr <= helloDistance*helloDistance) && + if ((playerPos - actorPos).length2() <= helloDistance*helloDistance && !player.getClass().getCreatureStats(player).isDead() && MWBase::Environment::get().getWorld()->getLOS(player, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor)) greetingTimer++; @@ -583,7 +577,7 @@ namespace MWMechanics if (greetingState == AiWanderStorage::Greet_Done) { float resetDist = 2 * helloDistance; - if (playerDistSqr >= resetDist*resetDist) + if ((playerPos - actorPos).length2() >= resetDist*resetDist) greetingState = AiWanderStorage::Greet_None; } } @@ -605,10 +599,10 @@ namespace MWMechanics ToWorldCoordinates(dest, storage.mCell->getCell()); // actor position is already in world coordinates - const auto start = actorPos.asVec3(); + const osg::Vec3f start = actorPos.asVec3(); // don't take shortcuts for wandering - const auto destVec3f = PathFinder::makeOsgVec3(dest); + const osg::Vec3f destVec3f = PathFinder::makeOsgVec3(dest); mPathFinder.buildPathByPathgrid(start, destVec3f, actor.getCell(), getPathGridGraph(actor.getCell())); if (mPathFinder.isPathConstructed()) diff --git a/cmake/FindRecastNavigation.cmake b/cmake/FindRecastNavigation.cmake deleted file mode 100644 index 2126b8855..000000000 --- a/cmake/FindRecastNavigation.cmake +++ /dev/null @@ -1,40 +0,0 @@ -find_path(RecastNavigation_INCLUDE_DIR - NAMES Recast.h - HINTS $ENV{RecastNavigation_ROOT} - ${RecastNavigation_ROOT} - PATH_SUFFIXES include -) -mark_as_advanced(RecastNavigation_INCLUDE_DIR) - -include(FindPackageHandleStandardArgs) - -set(RecastNavigation_LIBRARIES "") - -foreach(COMPONENT ${RecastNavigation_FIND_COMPONENTS}) - if(NOT RecastNavigation_${COMPONENT}_FOUND) - find_library(RecastNavigation_${COMPONENT}_LIBRARY - HINTS $ENV{RecastNavigation_ROOT} - ${RecastNavigation_ROOT} - NAMES ${COMPONENT} - PATH_SUFFIXES lib - ) - find_package_handle_standard_args(RecastNavigation_${COMPONENT} DEFAULT_MSG - RecastNavigation_${COMPONENT}_LIBRARY - RecastNavigation_INCLUDE_DIR - ) - mark_as_advanced(RecastNavigation_${COMPONENT}_LIBRARY) - if(RecastNavigation_${COMPONENT}_FOUND) - list(APPEND RecastNavigation_LIBRARIES ${RecastNavigation_${COMPONENT}_LIBRARY}) - endif() - endif() -endforeach() -mark_as_advanced(RecastNavigation_LIBRARIES) - -find_package_handle_standard_args(RecastNavigation DEFAULT_MSG - RecastNavigation_LIBRARIES - RecastNavigation_INCLUDE_DIR -) - -if(RecastNavigation_FOUND) - set(RecastNavigation_INCLUDE_DIRS ${RecastNavigation_INCLUDE_DIR}) -endif() diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index f47f58e45..361f321cb 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -44,6 +44,10 @@ namespace Debug }; #if defined(_WIN32) && defined(_DEBUG) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif // !WIN32_LEAN_AND_MEAN +#include class DebugOutput : public DebugOutputBase { public: diff --git a/components/misc/guarded.hpp b/components/misc/guarded.hpp index db619569a..4cb0564b1 100644 --- a/components/misc/guarded.hpp +++ b/components/misc/guarded.hpp @@ -38,19 +38,25 @@ namespace Misc class ScopeGuarded { public: - ScopeGuarded() = default; + ScopeGuarded() + : mMutex() + , mValue() + {} ScopeGuarded(const T& value) - : mValue(value) + : mMutex() + , mValue(value) {} ScopeGuarded(T&& value) - : mValue(std::move(value)) + : mMutex() + , mValue(std::move(value)) {} template ScopeGuarded(Args&& ... args) - : mValue(std::forward(args) ...) + : mMutex() + , mValue(std::forward(args) ...) {} ScopeGuarded(const ScopeGuarded& other) @@ -83,7 +89,7 @@ namespace Misc { public: SharedGuarded() - : mMutex(std::make_shared()) + : mMutex(std::make_shared()), mValue() {} SharedGuarded(std::shared_ptr value)