mirror of
https://github.com/OpenMW/openmw.git
synced 2025-12-16 05:43:08 +00:00
Add more evade directions and order them to make a circle
This commit is contained in:
parent
19940987a3
commit
579e533621
3 changed files with 30 additions and 43 deletions
|
|
@ -63,6 +63,7 @@
|
||||||
Bug #7413: Generated wilderness cells don't spawn fish
|
Bug #7413: Generated wilderness cells don't spawn fish
|
||||||
Bug #7415: Unbreakable lock discrepancies
|
Bug #7415: Unbreakable lock discrepancies
|
||||||
Bug #7428: AutoCalc flag is not used to calculate enchantment costs
|
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
|
Bug #7459: Icons get stacked on the cursor when picking up multiple items simultaneously
|
||||||
Feature #3537: Shader-based water ripples
|
Feature #3537: Shader-based water ripples
|
||||||
Feature #5492: Let rain and snow collide with statics
|
Feature #5492: Let rain and snow collide with statics
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,23 @@
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
// NOTE: determined empirically but probably need further tweaking
|
namespace
|
||||||
static const float DIST_SAME_SPOT = 0.5f;
|
{
|
||||||
static const float DURATION_SAME_SPOT = 1.5f;
|
// NOTE: determined empirically but probably need further tweaking
|
||||||
static const float DURATION_TO_EVADE = 0.4f;
|
constexpr float distanceSameSpot = 0.5f;
|
||||||
|
constexpr float durationSameSpot = 1.5f;
|
||||||
|
constexpr float durationToEvade = 1;
|
||||||
|
|
||||||
const float ObstacleCheck::evadeDirections[NUM_EVADE_DIRECTIONS][2] = {
|
constexpr float evadeDirections[][2] = {
|
||||||
{ 1.0f, 0.0f }, // move to side
|
{ 1.0f, 1.0f }, // move to side and forward
|
||||||
{ 1.0f, -1.0f }, // move to side and backwards
|
{ 1.0f, 0.0f }, // move to side
|
||||||
{ -1.0f, 0.0f }, // move to other side
|
{ 1.0f, -1.0f }, // move to side and backwards
|
||||||
{ -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)
|
bool proximityToDoor(const MWWorld::Ptr& actor, float minDist)
|
||||||
{
|
{
|
||||||
|
|
@ -94,9 +100,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleCheck::ObstacleCheck()
|
ObstacleCheck::ObstacleCheck()
|
||||||
: mWalkState(WalkState::Initial)
|
: mEvadeDirectionIndex(std::size(evadeDirections) - 1)
|
||||||
, mStateDuration(0)
|
|
||||||
, mEvadeDirectionIndex(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,7 +154,7 @@ namespace MWMechanics
|
||||||
mDestination = destination;
|
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 prevDistance = (destination - mPrev).length();
|
||||||
const float currentDistance = (destination - position).length();
|
const float currentDistance = (destination - position).length();
|
||||||
const float movedDistance = prevDistance - currentDistance;
|
const float movedDistance = prevDistance - currentDistance;
|
||||||
|
|
@ -174,19 +178,20 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
mStateDuration += duration;
|
mStateDuration += duration;
|
||||||
if (mStateDuration < DURATION_SAME_SPOT)
|
if (mStateDuration < durationSameSpot)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWalkState = WalkState::Evade;
|
mWalkState = WalkState::Evade;
|
||||||
mStateDuration = 0;
|
mStateDuration = 0;
|
||||||
chooseEvasionDirection();
|
if (++mEvadeDirectionIndex == std::size(evadeDirections))
|
||||||
|
mEvadeDirectionIndex = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mStateDuration += duration;
|
mStateDuration += duration;
|
||||||
if (mStateDuration >= DURATION_TO_EVADE)
|
if (mStateDuration >= durationToEvade)
|
||||||
{
|
{
|
||||||
// tried to evade, assume all is ok and start again
|
// tried to evade, assume all is ok and start again
|
||||||
mWalkState = WalkState::Norm;
|
mWalkState = WalkState::Norm;
|
||||||
|
|
@ -200,15 +205,4 @@ namespace MWMechanics
|
||||||
actorMovement.mPosition[0] = evadeDirections[mEvadeDirectionIndex][0];
|
actorMovement.mPosition[0] = evadeDirections[mEvadeDirectionIndex][0];
|
||||||
actorMovement.mPosition[1] = evadeDirections[mEvadeDirectionIndex][1];
|
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;
|
struct Movement;
|
||||||
|
|
||||||
static constexpr int NUM_EVADE_DIRECTIONS = 4;
|
|
||||||
|
|
||||||
/// tests actor's proximity to a closed door by default
|
/// tests actor's proximity to a closed door by default
|
||||||
bool proximityToDoor(const MWWorld::Ptr& actor, float minDist);
|
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);
|
void update(const MWWorld::Ptr& actor, const osg::Vec3f& destination, float duration);
|
||||||
|
|
||||||
// change direction to try to fix "stuck" actor
|
// change direction to try to fix "stuck" actor
|
||||||
void takeEvasiveAction(MWMechanics::Movement& actorMovement) const;
|
void takeEvasiveAction(Movement& actorMovement) const;
|
||||||
|
|
||||||
private:
|
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
|
enum class WalkState
|
||||||
{
|
{
|
||||||
Initial,
|
Initial,
|
||||||
Norm,
|
Norm,
|
||||||
CheckStuck,
|
CheckStuck,
|
||||||
Evade
|
Evade,
|
||||||
};
|
};
|
||||||
WalkState mWalkState;
|
|
||||||
|
|
||||||
float mStateDuration;
|
WalkState mWalkState = WalkState::Initial;
|
||||||
int mEvadeDirectionIndex;
|
float mStateDuration = 0;
|
||||||
float mInitialDistance = 0;
|
float mInitialDistance = 0;
|
||||||
|
std::size_t mEvadeDirectionIndex;
|
||||||
void chooseEvasionDirection();
|
osg::Vec3f mPrev;
|
||||||
|
osg::Vec3f mDestination;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue