AiFollow: add a threshold when turning to target

experimental
Andrei Kortunov 7 years ago
parent 1bdcecc32e
commit d8d47f081b

@ -22,8 +22,15 @@ struct AiFollowStorage : AiTemporaryBase
{ {
float mTimer; float mTimer;
bool mMoving; bool mMoving;
float mTargetAngleRadians;
AiFollowStorage() : mTimer(0.f), mMoving(false) {} bool mTurnActorToTarget;
AiFollowStorage() :
mTimer(0.f),
mMoving(false),
mTargetAngleRadians(0.f),
mTurnActorToTarget(false)
{}
}; };
int AiFollow::mFollowIndexCounter = 0; int AiFollow::mFollowIndexCounter = 0;
@ -73,6 +80,15 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
AiFollowStorage& storage = state.get<AiFollowStorage>(); AiFollowStorage& storage = state.get<AiFollowStorage>();
bool& rotate = storage.mTurnActorToTarget;
if (rotate)
{
if (zTurn(actor, storage.mTargetAngleRadians))
rotate = false;
return false;
}
// 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)
{ {
@ -144,13 +160,33 @@ 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 (!storage.mMoving) short baseFollowDistance = followDistance;
{ short threshold = 30; // to avoid constant switching between moving/stopping
const short threshold = 10; // to avoid constant switching between moving/stopping if (storage.mMoving)
followDistance -= threshold;
else
followDistance += threshold; 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)
{
float faceAngleRadians = std::atan2(dir.x(), dir.y());
if (!zTurn(actor, faceAngleRadians, osg::DegreesToRadians(45.f)))
{
storage.mTargetAngleRadians = faceAngleRadians;
storage.mTurnActorToTarget = true;
}
return false;
} }
storage.mMoving = !pathTo(actor, dest, duration, followDistance); // Go to the destination storage.mMoving = !pathTo(actor, dest, duration, baseFollowDistance); // Go to the destination
if (storage.mMoving) if (storage.mMoving)
{ {

Loading…
Cancel
Save