1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 16:20:21 +00:00

enable z-moving for flying/water combatants

This commit is contained in:
mrcheko 2014-04-22 22:59:39 +04:00
parent f811abb752
commit fbd0ffe86f
2 changed files with 29 additions and 13 deletions

View File

@ -38,7 +38,7 @@ namespace
return Ogre::Radian( Ogre::Math::ACos(dir.y / len) * sgn(Ogre::Math::ASin(dir.x / len)) ).valueDegrees(); return Ogre::Radian( Ogre::Math::ACos(dir.y / len) * sgn(Ogre::Math::ASin(dir.x / len)) ).valueDegrees();
} }
const float PATHFIND_Z_REACH = 50.0f; const float PATHFIND_Z_REACH = 50.0f;
// distance at which actor pays more attention to decide whether to shortcut or stick to pathgrid // distance at which actor pays more attention to decide whether to shortcut or stick to pathgrid
const float PATHFIND_CAUTION_DIST = 500.0f; const float PATHFIND_CAUTION_DIST = 500.0f;
// distance after which actor (failed previously to shortcut) will try again // distance after which actor (failed previously to shortcut) will try again
@ -115,6 +115,7 @@ namespace MWMechanics
} }
mTimerAttack -= duration; mTimerAttack -= duration;
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(mStrike); actor.getClass().getCreatureStats(actor).setAttackingOrSpell(mStrike);
@ -229,6 +230,17 @@ namespace MWMechanics
mLastPos = pos; mLastPos = pos;
// check if can move along z-axis
bool canMoveByZ;
if(canMoveByZ = ((actor.getClass().isNpc() || actor.getClass().canSwim(actor)) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|| (actor.getClass().canFly(actor) && MWBase::Environment::get().getWorld()->isFlying(actor)))
{
float zToTarget = vTargetPos.z - pos.pos[2];
mMovement.mPosition[1] = sqrt(distToTarget*distToTarget - zToTarget*zToTarget); // XY-plane vec length
mMovement.mPosition[2] = zToTarget;
}
if(distToTarget < rangeMelee || (distToTarget <= rangeCloseUp && mFollowTarget && !isStuck) ) if(distToTarget < rangeMelee || (distToTarget <= rangeCloseUp && mFollowTarget && !isStuck) )
{ {
//Melee and Close-up combat //Melee and Close-up combat
@ -238,12 +250,13 @@ namespace MWMechanics
if (mFollowTarget && distToTarget > rangeMelee) if (mFollowTarget && distToTarget > rangeMelee)
{ {
//Close-up combat: just run up on target //Close-up combat: just run up on target
mMovement.mPosition[1] = 1; if(!canMoveByZ) mMovement.mPosition[1] = 1;
} }
else else
{ {
//Melee: stop running and attack //Melee: stop running and attack
mMovement.mPosition[1] = 0; mMovement.mPosition[1] = 0;
if(canMoveByZ) mMovement.mPosition[2] = 0;
// When attacking with a weapon, choose between slash, thrust or chop // When attacking with a weapon, choose between slash, thrust or chop
if (actor.getClass().hasInventoryStore(actor)) if (actor.getClass().hasInventoryStore(actor))
@ -295,15 +308,16 @@ namespace MWMechanics
preferShortcut = checkWayIsClear(vActorPos, vTargetPos, distToTarget > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2); preferShortcut = checkWayIsClear(vActorPos, vTargetPos, distToTarget > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2);
} }
if(preferShortcut) if(canMoveByZ) preferShortcut = true;
{
if(preferShortcut)
{
mTargetAngle = getZAngleToDir(vDirToTarget, distToTarget); mTargetAngle = getZAngleToDir(vDirToTarget, distToTarget);
mForceNoShortcut = false; mForceNoShortcut = false;
mShortcutFailPos.pos[0] = mShortcutFailPos.pos[1] = mShortcutFailPos.pos[2] = 0; mShortcutFailPos.pos[0] = mShortcutFailPos.pos[1] = mShortcutFailPos.pos[2] = 0;
if(mPathFinder.isPathConstructed()) mPathFinder.clearPath();
mPathFinder.clearPath(); }
} else // if shortcut failed stick to path grid
else // if shortcut failed stick to path grid
{ {
if(!isStuck && mShortcutFailPos.pos[0] == 0.0f && mShortcutFailPos.pos[1] == 0.0f && mShortcutFailPos.pos[2] == 0.0f) if(!isStuck && mShortcutFailPos.pos[0] == 0.0f && mShortcutFailPos.pos[1] == 0.0f && mShortcutFailPos.pos[2] == 0.0f)
{ {
@ -344,7 +358,7 @@ namespace MWMechanics
} }
} }
mMovement.mPosition[1] = 1; if(!canMoveByZ) mMovement.mPosition[1] = 1;
mReadyToAttack = false; mReadyToAttack = false;
} }

View File

@ -1018,6 +1018,7 @@ void CharacterController::update(float duration)
vec.x *= mMovementSpeed; vec.x *= mMovementSpeed;
vec.y *= mMovementSpeed; vec.y *= mMovementSpeed;
if(inwater || flying) vec.z *= mMovementSpeed;
CharacterState movestate = CharState_None; CharacterState movestate = CharState_None;
CharacterState idlestate = CharState_SpecialIdle; CharacterState idlestate = CharState_SpecialIdle;
@ -1084,7 +1085,8 @@ void CharacterController::update(float duration)
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss, fatigue.getCurrent() < 0); fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss, fatigue.getCurrent() < 0);
cls.getCreatureStats(mPtr).setFatigue(fatigue); cls.getCreatureStats(mPtr).setFatigue(fatigue);
if(sneak || inwater || flying) // kind of hack, reason - creatures can move along z when in water/flying
if(sneak || ((inwater || flying) && mPtr.getRefData().getHandle() == "player"))
vec.z = 0.0f; vec.z = 0.0f;
if (inwater || flying) if (inwater || flying)
@ -1119,7 +1121,7 @@ void CharacterController::update(float duration)
vec.y *= mult; vec.y *= mult;
vec.z = 0.0f; vec.z = 0.0f;
} }
else if(vec.z > 0.0f && mJumpState == JumpState_None) else if(!inwater && !flying && vec.z > 0.0f && mJumpState == JumpState_None)
{ {
// Started a jump. // Started a jump.
float z = cls.getJump(mPtr); float z = cls.getJump(mPtr);
@ -1179,9 +1181,9 @@ void CharacterController::update(float duration)
} }
else else
{ {
if(!(vec.z > 0.0f)) if(!(vec.z > 0.0f))
mJumpState = JumpState_None; mJumpState = JumpState_None;
vec.z = 0.0f; if(!inwater && !flying) vec.z = 0.0f;
if(std::abs(vec.x/2.0f) > std::abs(vec.y)) if(std::abs(vec.x/2.0f) > std::abs(vec.y))
{ {