mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 20:49:56 +00:00
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;
|
float mTimer;
|
||||||
bool mMoving;
|
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;
|
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…
Reference in a new issue