diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b64d26f8..081cc91976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ Bug #7413: Generated wilderness cells don't spawn fish Bug #7415: Unbreakable lock discrepancies Bug #7428: AutoCalc flag is not used to calculate enchantment costs + Bug #7450: Evading obstacles does not work for actors missing certain animations Bug #7459: Icons get stacked on the cursor when picking up multiple items simultaneously Feature #3537: Shader-based water ripples Feature #5492: Let rain and snow collide with statics diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index ae06c05dc9..8f7829e634 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -15,17 +15,23 @@ namespace MWMechanics { - // NOTE: determined empirically but probably need further tweaking - static const float DIST_SAME_SPOT = 0.5f; - static const float DURATION_SAME_SPOT = 1.5f; - static const float DURATION_TO_EVADE = 0.4f; + namespace + { + // NOTE: determined empirically but probably need further tweaking + constexpr float distanceSameSpot = 0.5f; + constexpr float durationSameSpot = 1.5f; + constexpr float durationToEvade = 1; - const float ObstacleCheck::evadeDirections[NUM_EVADE_DIRECTIONS][2] = { - { 1.0f, 0.0f }, // move to side - { 1.0f, -1.0f }, // move to side and backwards - { -1.0f, 0.0f }, // move to other side - { -1.0f, -1.0f } // move to side and backwards - }; + constexpr float evadeDirections[][2] = { + { 1.0f, 1.0f }, // move to side and forward + { 1.0f, 0.0f }, // move to side + { 1.0f, -1.0f }, // move to side and backwards + { 0.0f, -1.0f }, // move backwards + { -1.0f, -1.0f }, // move to other side and backwards + { -1.0f, 0.0f }, // move to other side + { -1.0f, 1.0f }, // move to other side and forward + }; + } bool proximityToDoor(const MWWorld::Ptr& actor, float minDist) { @@ -94,9 +100,7 @@ namespace MWMechanics } ObstacleCheck::ObstacleCheck() - : mWalkState(WalkState::Initial) - , mStateDuration(0) - , mEvadeDirectionIndex(0) + : mEvadeDirectionIndex(std::size(evadeDirections) - 1) { } @@ -150,7 +154,7 @@ namespace MWMechanics mDestination = destination; } - const float distSameSpot = DIST_SAME_SPOT * actor.getClass().getCurrentSpeed(actor) * duration; + const float distSameSpot = distanceSameSpot * actor.getClass().getCurrentSpeed(actor) * duration; const float prevDistance = (destination - mPrev).length(); const float currentDistance = (destination - position).length(); const float movedDistance = prevDistance - currentDistance; @@ -174,19 +178,20 @@ namespace MWMechanics } mStateDuration += duration; - if (mStateDuration < DURATION_SAME_SPOT) + if (mStateDuration < durationSameSpot) { return; } mWalkState = WalkState::Evade; mStateDuration = 0; - chooseEvasionDirection(); + if (++mEvadeDirectionIndex == std::size(evadeDirections)) + mEvadeDirectionIndex = 0; return; } mStateDuration += duration; - if (mStateDuration >= DURATION_TO_EVADE) + if (mStateDuration >= durationToEvade) { // tried to evade, assume all is ok and start again mWalkState = WalkState::Norm; @@ -200,15 +205,4 @@ namespace MWMechanics actorMovement.mPosition[0] = evadeDirections[mEvadeDirectionIndex][0]; actorMovement.mPosition[1] = evadeDirections[mEvadeDirectionIndex][1]; } - - void ObstacleCheck::chooseEvasionDirection() - { - // change direction if attempt didn't work - ++mEvadeDirectionIndex; - if (mEvadeDirectionIndex == NUM_EVADE_DIRECTIONS) - { - mEvadeDirectionIndex = 0; - } - } - } diff --git a/apps/openmw/mwmechanics/obstacle.hpp b/apps/openmw/mwmechanics/obstacle.hpp index be9680f527..4ca36423ea 100644 --- a/apps/openmw/mwmechanics/obstacle.hpp +++ b/apps/openmw/mwmechanics/obstacle.hpp @@ -15,8 +15,6 @@ namespace MWMechanics { struct Movement; - static constexpr int NUM_EVADE_DIRECTIONS = 4; - /// tests actor's proximity to a closed door by default bool proximityToDoor(const MWWorld::Ptr& actor, float minDist); @@ -41,29 +39,23 @@ namespace MWMechanics void update(const MWWorld::Ptr& actor, const osg::Vec3f& destination, float duration); // change direction to try to fix "stuck" actor - void takeEvasiveAction(MWMechanics::Movement& actorMovement) const; + void takeEvasiveAction(Movement& actorMovement) const; private: - osg::Vec3f mPrev; - osg::Vec3f mDestination; - - // directions to try moving in when get stuck - static const float evadeDirections[NUM_EVADE_DIRECTIONS][2]; - enum class WalkState { Initial, Norm, CheckStuck, - Evade + Evade, }; - WalkState mWalkState; - float mStateDuration; - int mEvadeDirectionIndex; + WalkState mWalkState = WalkState::Initial; + float mStateDuration = 0; float mInitialDistance = 0; - - void chooseEvasionDirection(); + std::size_t mEvadeDirectionIndex; + osg::Vec3f mPrev; + osg::Vec3f mDestination; }; }