1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-31 19:20:26 +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--; if (mRotateOnTheRunChecks > 0) mRotateOnTheRunChecks--;
} }
mObstacleCheck.update(actor, duration);
// handle obstacles on the way // handle obstacles on the way
evadeObstacles(actor, duration, pos); evadeObstacles(actor, pos);
} }
// turn to next path point by X,Z axes // 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; 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])); zTurn(actor, mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]));
MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor); MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor);
// check if stuck due to obstacles // check if stuck due to obstacles
if (!mObstacleCheck.check(actor, duration)) return; if (!mObstacleCheck.isEvading()) return;
// first check if obstacle is a door // first check if obstacle is a door
static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); 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); 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); void openDoors(const MWWorld::Ptr& actor);
const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell); const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell);

View File

@ -167,14 +167,14 @@ namespace MWMechanics
if (AI_REACTION_TIME <= lastReaction) if (AI_REACTION_TIME <= lastReaction)
{ {
lastReaction = 0; lastReaction = 0;
return reactionTimeActions(actor, storage, currentCell, cellChange, pos, duration); return reactionTimeActions(actor, storage, currentCell, cellChange, pos);
} }
else else
return false; return false;
} }
bool AiWander::reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage, 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) if (mDistance <= 0)
storage.mCanWanderAlongPathGrid = false; storage.mCanWanderAlongPathGrid = false;
@ -224,7 +224,7 @@ namespace MWMechanics
} }
// If Wandering manually and hit an obstacle, stop // 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); 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 onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage, ESM::Position& pos);
void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage); void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage);
bool reactionTimeActions(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); bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance); void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination); bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);

View File

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

View File

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