mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
Slightly modify aicombat to make it more difficult to get around an enemy. The difference is visible only if turning is slow (i.e. if smooth movement enabled).
This commit is contained in:
parent
6a75942907
commit
79a72e4b44
1 changed files with 28 additions and 30 deletions
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <components/esm/aisequence.hpp>
|
||||
|
||||
#include <components/misc/mathutil.hpp>
|
||||
|
||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||
|
||||
#include "../mwphysics/collisiontype.hpp"
|
||||
|
@ -240,10 +242,6 @@ namespace MWMechanics
|
|||
|
||||
if (storage.mReadyToAttack)
|
||||
{
|
||||
storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target);
|
||||
// start new attack
|
||||
storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat);
|
||||
|
||||
if (isRangedCombat)
|
||||
{
|
||||
// rotate actor taking into account target movement direction and projectile speed
|
||||
|
@ -259,6 +257,10 @@ namespace MWMechanics
|
|||
storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir);
|
||||
storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated
|
||||
}
|
||||
|
||||
storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target);
|
||||
// start new attack
|
||||
storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -372,9 +374,13 @@ namespace MWMechanics
|
|||
void AiCombat::updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage)
|
||||
{
|
||||
// apply combat movement
|
||||
float deltaAngle = storage.mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2];
|
||||
osg::Vec2f movement = Misc::rotateVec2f(
|
||||
osg::Vec2f(storage.mMovement.mPosition[0], storage.mMovement.mPosition[1]), -deltaAngle);
|
||||
|
||||
MWMechanics::Movement& actorMovementSettings = actor.getClass().getMovementSettings(actor);
|
||||
actorMovementSettings.mPosition[0] = storage.mMovement.mPosition[0];
|
||||
actorMovementSettings.mPosition[1] = storage.mMovement.mPosition[1];
|
||||
actorMovementSettings.mPosition[0] = movement.x();
|
||||
actorMovementSettings.mPosition[1] = movement.y();
|
||||
actorMovementSettings.mPosition[2] = storage.mMovement.mPosition[2];
|
||||
|
||||
rotateActorOnAxis(actor, 2, actorMovementSettings, storage);
|
||||
|
@ -385,26 +391,11 @@ namespace MWMechanics
|
|||
MWMechanics::Movement& actorMovementSettings, AiCombatStorage& storage)
|
||||
{
|
||||
actorMovementSettings.mRotation[axis] = 0;
|
||||
float& targetAngleRadians = storage.mMovement.mRotation[axis];
|
||||
if (targetAngleRadians != 0)
|
||||
{
|
||||
// Some attack animations contain small amount of movement.
|
||||
// Since we use cone shapes for melee, we can use a threshold to avoid jittering
|
||||
std::shared_ptr<Action>& currentAction = storage.mCurrentAction;
|
||||
bool isRangedCombat = false;
|
||||
currentAction->getCombatRange(isRangedCombat);
|
||||
// Check if the actor now facing desired direction, no need to turn any more
|
||||
if (isRangedCombat)
|
||||
{
|
||||
if (smoothTurn(actor, targetAngleRadians, axis))
|
||||
targetAngleRadians = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (smoothTurn(actor, targetAngleRadians, axis, osg::DegreesToRadians(3.f)))
|
||||
targetAngleRadians = 0;
|
||||
}
|
||||
}
|
||||
bool isRangedCombat = false;
|
||||
storage.mCurrentAction->getCombatRange(isRangedCombat);
|
||||
float eps = isRangedCombat ? osg::DegreesToRadians(0.5) : osg::DegreesToRadians(3.f);
|
||||
float targetAngleRadians = storage.mMovement.mRotation[axis];
|
||||
smoothTurn(actor, targetAngleRadians, axis, eps);
|
||||
}
|
||||
|
||||
MWWorld::Ptr AiCombat::getTarget() const
|
||||
|
@ -489,12 +480,19 @@ namespace MWMechanics
|
|||
// Note: do not use for ranged combat yet since in couple with back up behaviour can move actor out of cliff
|
||||
else if (actor.getClass().isBipedal(actor))
|
||||
{
|
||||
// apply sideway movement (kind of dodging) with some probability
|
||||
// if actor is within range of target's weapon
|
||||
if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25)
|
||||
float moveDuration = 0;
|
||||
float angleToTarget = Misc::normalizeAngle(mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2]);
|
||||
// Apply a big side step if enemy tries to get around and come from behind.
|
||||
// Otherwise apply a random side step (kind of dodging) with some probability
|
||||
// if actor is within range of target's weapon.
|
||||
if (std::abs(angleToTarget) > osg::PI / 4)
|
||||
moveDuration = 0.2;
|
||||
else if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25)
|
||||
moveDuration = 0.1f + 0.1f * Misc::Rng::rollClosedProbability();
|
||||
if (moveDuration > 0)
|
||||
{
|
||||
mMovement.mPosition[0] = Misc::Rng::rollProbability() < 0.5 ? 1.0f : -1.0f; // to the left/right
|
||||
mTimerCombatMove = 0.1f + 0.1f * Misc::Rng::rollClosedProbability();
|
||||
mTimerCombatMove = moveDuration;
|
||||
mCombatMove = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue