mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:45:31 +00:00
Merge remote-tracking branch 'dteviot/FixStuckDraft'
This commit is contained in:
commit
41191ea367
4 changed files with 36 additions and 26 deletions
|
@ -458,28 +458,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
followTarget = false;
|
followTarget = false;
|
||||||
|
|
||||||
buildNewPath(actor, target); //may fail to build a path, check before use
|
buildNewPath(actor, target);
|
||||||
|
|
||||||
// if current actor pos is closer to target then last point of path (excluding target itself) then go straight on target
|
// should always return a path (even if it's just go straight on target.)
|
||||||
// This works on the borders between the path grid and areas with no waypoints.
|
assert(mPathFinder.isPathConstructed());
|
||||||
if(inLOS && mPathFinder.getPath().size() > 1)
|
|
||||||
{
|
|
||||||
// get point just before target
|
|
||||||
std::list<ESM::Pathgrid::Point>::const_iterator pntIter = --mPathFinder.getPath().end();
|
|
||||||
--pntIter;
|
|
||||||
osg::Vec3f vBeforeTarget(PathFinder::MakeOsgVec3(*pntIter));
|
|
||||||
|
|
||||||
if(distToTarget <= (vTargetPos - vBeforeTarget).length())
|
|
||||||
{
|
|
||||||
mPathFinder.clearPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there is no new path, then go straight on target
|
|
||||||
if (!mPathFinder.isPathConstructed())
|
|
||||||
{
|
|
||||||
movement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readyToAttack)
|
if (readyToAttack)
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -215,6 +215,17 @@ namespace MWMechanics
|
||||||
endPointInLocalCoords,
|
endPointInLocalCoords,
|
||||||
startNode);
|
startNode);
|
||||||
|
|
||||||
|
// if it's shorter for actor to travel from start to end, than to travel from either
|
||||||
|
// start or end to nearest pathgrid point, just travel from start to end.
|
||||||
|
float startToEndLength2 = (endPointInLocalCoords - startPointInLocalCoords).length2();
|
||||||
|
float endTolastNodeLength2 = distanceSquared(mPathgrid->mPoints[endNode.first], endPointInLocalCoords);
|
||||||
|
float startTo1stNodeLength2 = distanceSquared(mPathgrid->mPoints[startNode], startPointInLocalCoords);
|
||||||
|
if ((startToEndLength2 < startTo1stNodeLength2) || (startToEndLength2 < endTolastNodeLength2))
|
||||||
|
{
|
||||||
|
mPath.push_back(endPoint);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// AiWander has logic that depends on whether a path was created,
|
// AiWander has logic that depends on whether a path was created,
|
||||||
// deleting allowed nodes if not. Hence a path needs to be created
|
// deleting allowed nodes if not. Hence a path needs to be created
|
||||||
// even if the start and the end points are the same.
|
// even if the start and the end points are the same.
|
||||||
|
|
Loading…
Reference in a new issue