Merge remote-tracking branch 'dteviot/AiCombatPerFrameUpdate'

sceneinput
Marc Zinnschlag 10 years ago
commit 1eed1c4d23

@ -429,6 +429,7 @@ namespace MWMechanics
// (within attack dist) || (not quite attack dist while following) // (within attack dist) || (not quite attack dist while following)
if(inLOS && (distToTarget < rangeAttack || (distToTarget <= rangeFollow && followTarget && !isStuck))) if(inLOS && (distToTarget < rangeAttack || (distToTarget <= rangeFollow && followTarget && !isStuck)))
{ {
mPathFinder.clearPath();
//Melee and Close-up combat //Melee and Close-up combat
// getXAngleToDir determines vertical angle to target: // getXAngleToDir determines vertical angle to target:
@ -503,12 +504,14 @@ namespace MWMechanics
} }
// don't use pathgrid when actor can move in 3 dimensions // don't use pathgrid when actor can move in 3 dimensions
if(canMoveByZ) preferShortcut = true; if (canMoveByZ)
{
preferShortcut = true;
movement.mRotation[0] = getXAngleToDir(vDirToTarget, distToTarget);
}
if(preferShortcut) if(preferShortcut)
{ {
if (canMoveByZ)
movement.mRotation[0] = getXAngleToDir(vDirToTarget, distToTarget);
movement.mRotation[2] = getZAngleToDir(vDirToTarget); movement.mRotation[2] = getZAngleToDir(vDirToTarget);
forceNoShortcut = false; forceNoShortcut = false;
shortcutFailPos.pos[0] = shortcutFailPos.pos[1] = shortcutFailPos.pos[2] = 0; shortcutFailPos.pos[0] = shortcutFailPos.pos[1] = shortcutFailPos.pos[2] = 0;
@ -526,9 +529,7 @@ namespace MWMechanics
buildNewPath(actor, target); //may fail to build a path, check before use buildNewPath(actor, target); //may fail to build a path, check before use
//delete visited path node // if current actor pos is closer to target then last point of path (excluding target itself) then go straight on target
mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1]);
// This works on the borders between the path grid and areas with no waypoints. // This works on the borders between the path grid and areas with no waypoints.
if(inLOS && mPathFinder.getPath().size() > 1) if(inLOS && mPathFinder.getPath().size() > 1)
{ {
@ -537,21 +538,16 @@ namespace MWMechanics
--pntIter; --pntIter;
osg::Vec3f vBeforeTarget(PathFinder::MakeOsgVec3(*pntIter)); osg::Vec3f vBeforeTarget(PathFinder::MakeOsgVec3(*pntIter));
// if current actor pos is closer to target then last point of path (excluding target itself) then go straight on target
if(distToTarget <= (vTargetPos - vBeforeTarget).length()) if(distToTarget <= (vTargetPos - vBeforeTarget).length())
{ {
movement.mRotation[2] = getZAngleToDir(vDirToTarget); mPathFinder.clearPath();
preferShortcut = true;
} }
} }
// if there is no new path, then go straight on target // if there is no new path, then go straight on target
if(!preferShortcut) if (!mPathFinder.isPathConstructed())
{ {
if(!mPathFinder.getPath().empty()) movement.mRotation[2] = getZAngleToDir(vDirToTarget);
movement.mRotation[2] = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
else
movement.mRotation[2] = getZAngleToDir(vDirToTarget);
} }
} }
@ -571,9 +567,25 @@ namespace MWMechanics
void AiCombat::UpdateActorsMovement(const MWWorld::Ptr& actor, MWMechanics::Movement& desiredMovement) void AiCombat::UpdateActorsMovement(const MWWorld::Ptr& actor, MWMechanics::Movement& desiredMovement)
{ {
MWMechanics::Movement& actorMovementSettings = actor.getClass().getMovementSettings(actor); MWMechanics::Movement& actorMovementSettings = actor.getClass().getMovementSettings(actor);
actorMovementSettings = desiredMovement; if (mPathFinder.isPathConstructed())
RotateActorOnAxis(actor, 2, actorMovementSettings, desiredMovement); {
RotateActorOnAxis(actor, 0, actorMovementSettings, desiredMovement); const ESM::Position& pos = actor.getRefData().getPosition();
if (mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1]))
{
actorMovementSettings.mPosition[1] = 0;
}
else
{
zTurn(actor, mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]));
actorMovementSettings.mPosition[1] = 1;
}
}
else
{
actorMovementSettings = desiredMovement;
RotateActorOnAxis(actor, 2, actorMovementSettings, desiredMovement);
RotateActorOnAxis(actor, 0, actorMovementSettings, desiredMovement);
}
} }
void AiCombat::RotateActorOnAxis(const MWWorld::Ptr& actor, int axis, void AiCombat::RotateActorOnAxis(const MWWorld::Ptr& actor, int axis,
@ -689,16 +701,14 @@ ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics:
int chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1])/2; int chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1])/2;
int thrust = (weapon->mData.mThrust[0] + weapon->mData.mThrust[1])/2; int thrust = (weapon->mData.mThrust[0] + weapon->mData.mThrust[1])/2;
float total = static_cast<float>(slash + chop + thrust); float roll = Misc::Rng::rollClosedProbability() * (slash + chop + thrust);
if(roll <= slash)
float roll = Misc::Rng::rollClosedProbability();
if(roll <= (slash/total))
{ {
movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f; movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f;
movement.mPosition[1] = 0; movement.mPosition[1] = 0;
attackType = ESM::Weapon::AT_Slash; attackType = ESM::Weapon::AT_Slash;
} }
else if(roll <= (slash + (thrust/total))) else if(roll <= (slash + thrust))
{ {
movement.mPosition[1] = 1; movement.mPosition[1] = 1;
attackType = ESM::Weapon::AT_Thrust; attackType = ESM::Weapon::AT_Thrust;

@ -87,14 +87,14 @@ namespace
namespace MWMechanics namespace MWMechanics
{ {
float sqrDistanceIgnoreZ(ESM::Pathgrid::Point point, float x, float y) float sqrDistanceIgnoreZ(const ESM::Pathgrid::Point& point, float x, float y)
{ {
x -= point.mX; x -= point.mX;
y -= point.mY; y -= point.mY;
return (x * x + y * y); return (x * x + y * y);
} }
float distance(ESM::Pathgrid::Point point, float x, float y, float z) float distance(const ESM::Pathgrid::Point& point, float x, float y, float z)
{ {
x -= point.mX; x -= point.mX;
y -= point.mY; y -= point.mY;
@ -102,7 +102,7 @@ namespace MWMechanics
return sqrt(x * x + y * y + z * z); return sqrt(x * x + y * y + z * z);
} }
float distance(ESM::Pathgrid::Point a, ESM::Pathgrid::Point b) float distance(const ESM::Pathgrid::Point& a, const ESM::Pathgrid::Point& b)
{ {
float x = static_cast<float>(a.mX - b.mX); float x = static_cast<float>(a.mX - b.mX);
float y = static_cast<float>(a.mY - b.mY); float y = static_cast<float>(a.mY - b.mY);
@ -272,7 +272,7 @@ namespace MWMechanics
if(mPath.empty()) if(mPath.empty())
return true; return true;
ESM::Pathgrid::Point nextPoint = *mPath.begin(); const ESM::Pathgrid::Point& nextPoint = *mPath.begin();
if (sqrDistanceIgnoreZ(nextPoint, x, y) < tolerance*tolerance) if (sqrDistanceIgnoreZ(nextPoint, x, y) < tolerance*tolerance)
{ {
mPath.pop_front(); mPath.pop_front();

@ -12,8 +12,8 @@ namespace MWWorld
namespace MWMechanics namespace MWMechanics
{ {
float distance(ESM::Pathgrid::Point point, float x, float y, float); float distance(const ESM::Pathgrid::Point& point, float x, float y, float);
float distance(ESM::Pathgrid::Point a, ESM::Pathgrid::Point b); float distance(const ESM::Pathgrid::Point& a, const ESM::Pathgrid::Point& b);
class PathFinder class PathFinder
{ {
public: public:

Loading…
Cancel
Save