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:
parent
8e69c80bf6
commit
387624e158
1 changed files with 15 additions and 5 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue