1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-29 13:20:35 +00:00

Update ObstacleCheck once per frame

This commit is contained in:
elsid 2018-08-18 18:26:00 +03:00
parent ad027d13fa
commit c9f3064cbd
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
6 changed files with 15 additions and 22 deletions

View File

@ -187,8 +187,10 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
if (mRotateOnTheRunChecks > 0) mRotateOnTheRunChecks--;
}
mObstacleCheck.update(actor, duration);
// handle obstacles on the way
evadeObstacles(actor, duration, pos);
evadeObstacles(actor, pos);
}
// turn to next path point by X,Z axes
@ -198,14 +200,14 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
return false;
}
void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor, float duration, const ESM::Position& pos)
void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor, const ESM::Position& pos)
{
zTurn(actor, mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]));
MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor);
// check if stuck due to obstacles
if (!mObstacleCheck.check(actor, duration)) return;
if (!mObstacleCheck.isEvading()) return;
// first check if obstacle is a door
static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance();

View File

@ -124,7 +124,8 @@ namespace MWMechanics
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell);
void evadeObstacles(const MWWorld::Ptr& actor, float duration, const ESM::Position& pos);
void evadeObstacles(const MWWorld::Ptr& actor, const ESM::Position& pos);
void openDoors(const MWWorld::Ptr& actor);
const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell);

View File

@ -167,14 +167,14 @@ namespace MWMechanics
if (AI_REACTION_TIME <= lastReaction)
{
lastReaction = 0;
return reactionTimeActions(actor, storage, currentCell, cellChange, pos, duration);
return reactionTimeActions(actor, storage, currentCell, cellChange, pos);
}
else
return false;
}
bool AiWander::reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage,
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos, float duration)
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos)
{
if (mDistance <= 0)
storage.mCanWanderAlongPathGrid = false;
@ -224,7 +224,7 @@ namespace MWMechanics
}
// If Wandering manually and hit an obstacle, stop
if (storage.mIsWanderingManually && mObstacleCheck.check(actor, duration, 2.0f)) {
if (storage.mIsWanderingManually && mObstacleCheck.isEvading()) {
completeManualWalking(actor, storage);
}

View File

@ -145,7 +145,7 @@ namespace MWMechanics
void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage, ESM::Position& pos);
void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage);
bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage,
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos, float duration);
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos);
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);

View File

@ -96,11 +96,6 @@ namespace MWMechanics
mEvadeDuration = 0;
}
bool ObstacleCheck::isNormalState() const
{
return mWalkState == State_Norm;
}
bool ObstacleCheck::isEvading() const
{
return mWalkState == State_Evade;
@ -128,7 +123,7 @@ namespace MWMechanics
* u = how long to move sideways
*
*/
bool ObstacleCheck::check(const MWWorld::Ptr& actor, float duration, float scaleMinimumDistance)
void ObstacleCheck::update(const MWWorld::Ptr& actor, float duration, float scaleMinimumDistance)
{
const MWWorld::Class& cls = actor.getClass();
ESM::Position pos = actor.getRefData().getPosition();
@ -180,9 +175,7 @@ namespace MWMechanics
case State_Evade:
{
mEvadeDuration += duration;
if(mEvadeDuration < DURATION_TO_EVADE)
return true;
else
if(mEvadeDuration >= DURATION_TO_EVADE)
{
// tried to evade, assume all is ok and start again
mWalkState = State_Norm;
@ -191,7 +184,6 @@ namespace MWMechanics
}
/* NO DEFAULT CASE */
}
return false; // no obstacles to evade (yet)
}
void ObstacleCheck::takeEvasiveAction(MWMechanics::Movement& actorMovement)

View File

@ -27,12 +27,10 @@ namespace MWMechanics
// Clear the timers and set the state machine to default
void clear();
bool isNormalState() const;
bool isEvading() const;
// Returns true if there is an obstacle and an evasive action
// should be taken
bool check(const MWWorld::Ptr& actor, float duration, float scaleMinimumDistance = 1.0f);
// Updates internal state, call each frame for moving actor
void update(const MWWorld::Ptr& actor, float duration, float scaleMinimumDistance = 1.0f);
// change direction to try to fix "stuck" actor
void takeEvasiveAction(MWMechanics::Movement& actorMovement);