Add more evade directions and order them to make a circle

revert-6246b479
elsid 11 months ago
parent 19940987a3
commit 579e533621
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -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

@ -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;
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
};
namespace
{
// NOTE: determined empirically but probably need further tweaking
constexpr float distanceSameSpot = 0.5f;
constexpr float durationSameSpot = 1.5f;
constexpr float durationToEvade = 1;
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;
}
}
}

@ -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;
};
}

Loading…
Cancel
Save