When stuck, try moving backwards as well as to side.

sceneinput
dteviot 9 years ago
parent 5369d20682
commit 60d0ad9283

@ -15,6 +15,14 @@ namespace MWMechanics
static const float DURATION_SAME_SPOT = 1.0f; static const float DURATION_SAME_SPOT = 1.0f;
static const float DURATION_TO_EVADE = 0.4f; 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
};
// Proximity check function for interior doors. Given that most interior cells // Proximity check function for interior doors. Given that most interior cells
// do not have many doors performance shouldn't be too much of an issue. // do not have many doors performance shouldn't be too much of an issue.
// //
@ -69,7 +77,7 @@ namespace MWMechanics
, mStuckDuration(0) , mStuckDuration(0)
, mEvadeDuration(0) , mEvadeDuration(0)
, mDistSameSpot(-1) // avoid calculating it each time , mDistSameSpot(-1) // avoid calculating it each time
, mEvadeDirection(1.0f) , mEvadeDirectionIndex(0)
{ {
} }
@ -176,8 +184,8 @@ namespace MWMechanics
void ObstacleCheck::takeEvasiveAction(MWMechanics::Movement& actorMovement) void ObstacleCheck::takeEvasiveAction(MWMechanics::Movement& actorMovement)
{ {
actorMovement.mPosition[0] = mEvadeDirection; actorMovement.mPosition[0] = evadeDirections[mEvadeDirectionIndex][0];
actorMovement.mPosition[1] = 0; actorMovement.mPosition[1] = evadeDirections[mEvadeDirectionIndex][1];
} }
void ObstacleCheck::chooseEvasionDirection(bool samePosition) void ObstacleCheck::chooseEvasionDirection(bool samePosition)
@ -185,7 +193,11 @@ namespace MWMechanics
// change direction if attempt didn't work // change direction if attempt didn't work
if (samePosition && (0 < mEvadeDuration)) if (samePosition && (0 < mEvadeDuration))
{ {
mEvadeDirection = mEvadeDirection == 1.0f ? -1.0f : 1.0f; ++mEvadeDirectionIndex;
if (mEvadeDirectionIndex == NUM_EVADE_DIRECTIONS)
{
mEvadeDirectionIndex = 0;
}
} }
} }

@ -13,6 +13,8 @@ namespace MWMechanics
/// NOTE: determined empirically based on in-game behaviour /// NOTE: determined empirically based on in-game behaviour
static const float MIN_DIST_TO_DOOR_SQUARED = 128*128; static const float MIN_DIST_TO_DOOR_SQUARED = 128*128;
static const 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, bool proximityToDoor(const MWWorld::Ptr& actor,
float minSqr = MIN_DIST_TO_DOOR_SQUARED, float minSqr = MIN_DIST_TO_DOOR_SQUARED,
@ -47,6 +49,9 @@ namespace MWMechanics
float mPrevX; float mPrevX;
float mPrevY; float mPrevY;
// directions to try moving in when get stuck
static const float evadeDirections[NUM_EVADE_DIRECTIONS][2];
enum WalkState enum WalkState
{ {
State_Norm, State_Norm,
@ -58,7 +63,7 @@ namespace MWMechanics
float mStuckDuration; // accumulate time here while in same spot float mStuckDuration; // accumulate time here while in same spot
float mEvadeDuration; float mEvadeDuration;
float mDistSameSpot; // take account of actor's speed float mDistSameSpot; // take account of actor's speed
float mEvadeDirection; int mEvadeDirectionIndex;
void chooseEvasionDirection(bool samePosition); void chooseEvasionDirection(bool samePosition);
}; };

Loading…
Cancel
Save