1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 22:15:32 +00:00

Add a threshold to AiFollow distance

Idle animations can move the actor around slightly, which sometimes causes AiFollow to constantly toggle between "arrived" and "following" state even when the player isn't moving. Could be observed by summoning a bonelord.
This commit is contained in:
scrawl 2015-09-26 01:55:12 +02:00
parent 8e69c80bf6
commit 387624e158

View file

@ -20,8 +20,9 @@ namespace MWMechanics
struct AiFollowStorage : AiTemporaryBase struct AiFollowStorage : AiTemporaryBase
{ {
float mTimer; float mTimer;
bool mMoving;
AiFollowStorage() : mTimer(0.f) {} AiFollowStorage() : mTimer(0.f), mMoving(false) {}
}; };
int AiFollow::mFollowIndexCounter = 0; int AiFollow::mFollowIndexCounter = 0;
@ -64,10 +65,11 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
AiFollowStorage& storage = state.get<AiFollowStorage>();
// AiFollow requires the target to be in range and within sight for the initial activation // AiFollow requires the target to be in range and within sight for the initial activation
if (!mActive) if (!mActive)
{ {
AiFollowStorage& storage = state.get<AiFollowStorage>();
storage.mTimer -= duration; storage.mTimer -= duration;
if (storage.mTimer < 0) if (storage.mTimer < 0)
@ -126,7 +128,15 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
//Set the target destination from the actor //Set the target destination from the actor
ESM::Pathgrid::Point dest = target.getRefData().getPosition().pos; ESM::Pathgrid::Point dest = target.getRefData().getPosition().pos;
if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < followDistance) //Stop when you get close float dist = distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]);
const float threshold = 10;
if (storage.mMoving) //Stop when you get close
storage.mMoving = (dist > followDistance);
else
storage.mMoving = (dist > followDistance + threshold);
if(!storage.mMoving)
{ {
actor.getClass().getMovementSettings(actor).mPosition[1] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
@ -141,9 +151,9 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
} }
//Check if you're far away //Check if you're far away
if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) > 450) if(dist > 450)
actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, true); //Make NPC run actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, true); //Make NPC run
else if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < 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 threshhold 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 threshhold
actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, false); //make NPC walk actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, false); //make NPC walk
return false; return false;