mirror of
https://github.com/OpenMW/openmw.git
synced 2025-12-13 04:43:06 +00:00
Evaluate the attack early for non-biped attacks with no hit key (#7524)
This commit is contained in:
parent
84e71f4977
commit
9723912ee0
2 changed files with 32 additions and 14 deletions
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue