1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 03:35:27 +00:00

Merge branch 'angrydraugrs' into 'master'

Evaluate the attack early for non-biped attacks with no hit key (#7524)

Closes #7524

See merge request OpenMW/openmw!3331
This commit is contained in:
jvoisin 2023-08-13 13:18:22 +00:00
commit 7d9f5f676a
2 changed files with 32 additions and 14 deletions

View File

@ -1115,8 +1115,12 @@ namespace MWMechanics
} }
++hitKey; ++hitKey;
} }
if (!hasHitKey && mAttackStrength != -1.f) if (!hasHitKey)
{ {
// State update doesn't expect the start key to be the hit key,
// so we have to do this early.
prepareHit();
if (groupname == "attack1" || groupname == "swimattack1") if (groupname == "attack1" || groupname == "swimattack1")
charClass.hit( charClass.hit(
mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess);
@ -1126,7 +1130,6 @@ namespace MWMechanics
else if (groupname == "attack3" || groupname == "swimattack3") else if (groupname == "attack3" || groupname == "swimattack3")
charClass.hit( charClass.hit(
mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess);
mAttackStrength = -1.f;
} }
} }
else if (action == "shoot attach") else if (action == "shoot attach")
@ -1219,6 +1222,25 @@ namespace MWMechanics
(mAnimation->getCurrentTime(mCurrentWeapon) - minAttackTime) / (maxAttackTime - minAttackTime), 0.f, 1.f); (mAnimation->getCurrentTime(mCurrentWeapon) - minAttackTime) / (maxAttackTime - minAttackTime), 0.f, 1.f);
} }
void CharacterController::prepareHit()
{
if (mAttackStrength != -1.f)
return;
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
mAttackStrength = calculateWindUp();
if (mAttackStrength == -1.f)
mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability(prng));
ESM::WeaponType::Class weapclass = getWeaponType(mWeaponType)->mWeaponClass;
if (weapclass != ESM::WeaponType::Ranged && weapclass != ESM::WeaponType::Thrown)
{
mAttackSuccess = mPtr.getClass().evaluateHit(mPtr, mAttackVictim, mAttackHitPos);
if (!mAttackSuccess)
mAttackStrength = 0.f;
playSwishSound();
}
}
bool CharacterController::updateWeaponState() bool CharacterController::updateWeaponState()
{ {
const auto world = MWBase::Environment::get().getWorld(); const auto world = MWBase::Environment::get().getWorld();
@ -1641,8 +1663,6 @@ namespace MWMechanics
stopKey = mAttackType + " max attack"; stopKey = mAttackType + " max attack";
} }
mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false,
weapSpeed, startKey, stopKey, 0.0f, 0);
mUpperBodyState = UpperBodyState::AttackWindUp; mUpperBodyState = UpperBodyState::AttackWindUp;
// Reset the attack results when the attack starts. // Reset the attack results when the attack starts.
@ -1651,6 +1671,9 @@ namespace MWMechanics
mAttackSuccess = false; mAttackSuccess = false;
mAttackVictim = MWWorld::Ptr(); mAttackVictim = MWWorld::Ptr();
mAttackHitPos = osg::Vec3f(); mAttackHitPos = osg::Vec3f();
mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false,
weapSpeed, startKey, stopKey, 0.0f, 0);
} }
} }
@ -1688,18 +1711,11 @@ namespace MWMechanics
sndMgr->playSound3D(target, ESM::RefId::stringRefId(resultSound), 1.0f, 1.0f); sndMgr->playSound3D(target, ESM::RefId::stringRefId(resultSound), 1.0f, 1.0f);
} }
} }
// Evaluate the attack results and play the swish sound.
// Attack animations with no hit key do this earlier.
else else
{ {
mAttackStrength = calculateWindUp(); prepareHit();
if (mAttackStrength == -1.f)
mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability(prng));
if (weapclass != ESM::WeaponType::Ranged && weapclass != ESM::WeaponType::Thrown)
{
mAttackSuccess = cls.evaluateHit(mPtr, mAttackVictim, mAttackHitPos);
if (!mAttackSuccess)
mAttackStrength = 0.f;
playSwishSound();
}
} }
if (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon)) if (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon))

View File

@ -242,6 +242,8 @@ namespace MWMechanics
bool getAttackingOrSpell() const; bool getAttackingOrSpell() const;
void setAttackingOrSpell(bool attackingOrSpell) const; void setAttackingOrSpell(bool attackingOrSpell) const;
void prepareHit();
public: public:
CharacterController(const MWWorld::Ptr& ptr, MWRender::Animation* anim); CharacterController(const MWWorld::Ptr& ptr, MWRender::Animation* anim);
virtual ~CharacterController(); virtual ~CharacterController();