Merge remote-tracking branch 'upstream/master' into osgshadow-test-vdsm

pull/541/head
AnyOldName3 6 years ago
commit b178e1868a

@ -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 $<$<CONFIG:Debug>:_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()

@ -7,7 +7,6 @@
#include "engine.hpp"
#if defined(_WIN32)
// For OutputDebugString
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

@ -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
{

@ -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;

@ -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<int>(mX), static_cast<int>(mY), static_cast<int>(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;

@ -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
}

@ -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);
}

@ -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;

@ -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<MWWorld::Ptr> targetActors;
std::pair<MWWorld::Ptr, osg::Vec3f> 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;

@ -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<AiWanderStorage>();
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<AiWanderStorage>();
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())

@ -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()

@ -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 <Windows.h>
class DebugOutput : public DebugOutputBase
{
public:

@ -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 <class ... Args>
ScopeGuarded(Args&& ... args)
: mValue(std::forward<Args>(args) ...)
: mMutex()
, mValue(std::forward<Args>(args) ...)
{}
ScopeGuarded(const ScopeGuarded& other)
@ -83,7 +89,7 @@ namespace Misc
{
public:
SharedGuarded()
: mMutex(std::make_shared<std::mutex>())
: mMutex(std::make_shared<std::mutex>()), mValue()
{}
SharedGuarded(std::shared_ptr<T> value)

Loading…
Cancel
Save