forked from mirror/openmw-tes3mp
Merge pull request #1391 from akortunov/aifollow
AiFollow: add a threshold when turning to target
This commit is contained in:
commit
b73ed5ccac
1 changed files with 41 additions and 5 deletions
|
@ -22,8 +22,15 @@ struct AiFollowStorage : AiTemporaryBase
|
|||
{
|
||||
float mTimer;
|
||||
bool mMoving;
|
||||
float mTargetAngleRadians;
|
||||
bool mTurnActorToTarget;
|
||||
|
||||
AiFollowStorage() : mTimer(0.f), mMoving(false) {}
|
||||
AiFollowStorage() :
|
||||
mTimer(0.f),
|
||||
mMoving(false),
|
||||
mTargetAngleRadians(0.f),
|
||||
mTurnActorToTarget(false)
|
||||
{}
|
||||
};
|
||||
|
||||
int AiFollow::mFollowIndexCounter = 0;
|
||||
|
@ -73,6 +80,15 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
|
|||
|
||||
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
|
||||
if (!mActive)
|
||||
{
|
||||
|
@ -144,13 +160,33 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
|
|||
//Set the target destination from the actor
|
||||
ESM::Pathgrid::Point dest = target.getRefData().getPosition().pos;
|
||||
|
||||
if (!storage.mMoving)
|
||||
{
|
||||
const short threshold = 10; // to avoid constant switching between moving/stopping
|
||||
short baseFollowDistance = followDistance;
|
||||
short threshold = 30; // to avoid constant switching between moving/stopping
|
||||
if (storage.mMoving)
|
||||
followDistance -= threshold;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue