1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-04 21:40:03 +00:00

Clean up updateWeaponState()

This commit is contained in:
Alexei Kotov 2022-08-08 20:17:02 +03:00
parent e5ef9f1464
commit ac892f2bfd
2 changed files with 39 additions and 57 deletions

View File

@ -1113,7 +1113,7 @@ bool CharacterController::updateCarriedLeftVisible(const int weaptype) const
return mAnimation->updateCarriedLeftVisible(weaptype); return mAnimation->updateCarriedLeftVisible(weaptype);
} }
bool CharacterController::updateWeaponState(CharacterState idle) bool CharacterController::updateWeaponState()
{ {
const auto world = MWBase::Environment::get().getWorld(); const auto world = MWBase::Environment::get().getWorld();
auto& prng = world->getPrng(); auto& prng = world->getPrng();
@ -1166,8 +1166,7 @@ bool CharacterController::updateWeaponState(CharacterState idle)
bool forcestateupdate = false; bool forcestateupdate = false;
// We should not play equipping animation and sound during weapon->weapon transition // We should not play equipping animation and sound during weapon->weapon transition
const bool isStillWeapon = weaptype != ESM::Weapon::HandToHand && weaptype != ESM::Weapon::Spell && weaptype != ESM::Weapon::None && const bool isStillWeapon = isRealWeapon(mWeaponType) && isRealWeapon(weaptype);
mWeaponType != ESM::Weapon::HandToHand && mWeaponType != ESM::Weapon::Spell && mWeaponType != ESM::Weapon::None;
// If the current weapon type was changed in the middle of attack (e.g. by Equip console command or when bound spell expires), // If the current weapon type was changed in the middle of attack (e.g. by Equip console command or when bound spell expires),
// we should force actor to the "weapon equipped" state, interrupt attack and update animations. // we should force actor to the "weapon equipped" state, interrupt attack and update animations.
@ -1179,7 +1178,6 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mUpperBodyState = UpperBodyState::WeaponEquipped; mUpperBodyState = UpperBodyState::WeaponEquipped;
setAttackingOrSpell(false); setAttackingOrSpell(false);
mAnimation->showWeapons(true); mAnimation->showWeapons(true);
stats.setAttackingOrSpell(false);
} }
if(!isKnockedOut() && !isKnockedDown() && !isRecovery()) if(!isKnockedOut() && !isKnockedDown() && !isRecovery())
@ -1247,7 +1245,8 @@ bool CharacterController::updateWeaponState(CharacterState idle)
if (!isStillWeapon) if (!isStillWeapon)
{ {
clearStateAnimation(mCurrentWeapon); if (animPlaying)
mAnimation->disable(mCurrentWeapon);
if (weaptype != ESM::Weapon::None) if (weaptype != ESM::Weapon::None)
{ {
mAnimation->showWeapons(false); mAnimation->showWeapons(false);
@ -1265,12 +1264,15 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mUpperBodyState = UpperBodyState::Equipping; mUpperBodyState = UpperBodyState::Equipping;
// If we do not have the "equip attach" key, show weapon manually. // If we do not have the "equip attach" key, show weapon manually.
if (weaptype != ESM::Weapon::Spell) if (weaptype != ESM::Weapon::Spell && mAnimation->getTextKeyTime(weapgroup+": equip attach") < 0)
{ {
if (mAnimation->getTextKeyTime(weapgroup+": equip attach") < 0) mAnimation->showWeapons(true);
mAnimation->showWeapons(true);
} }
} }
if (!upSoundId.empty())
{
sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f);
}
} }
if(isWerewolf) if(isWerewolf)
@ -1286,10 +1288,6 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mWeaponType = weaptype; mWeaponType = weaptype;
mCurrentWeapon = weapgroup; mCurrentWeapon = weapgroup;
if(!upSoundId.empty() && !isStillWeapon)
{
sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f);
}
} }
// Make sure that we disabled unequipping animation // Make sure that we disabled unequipping animation
@ -1297,7 +1295,6 @@ bool CharacterController::updateWeaponState(CharacterState idle)
{ {
resetCurrentWeaponState(); resetCurrentWeaponState();
mWeaponType = ESM::Weapon::None; mWeaponType = ESM::Weapon::None;
mCurrentWeapon = getWeaponAnimation(mWeaponType);
} }
} }
} }
@ -1319,20 +1316,17 @@ bool CharacterController::updateWeaponState(CharacterState idle)
// Cancel attack if we no longer have ammunition // Cancel attack if we no longer have ammunition
bool ammunition = true; bool ammunition = true;
bool isWeapon = false;
float weapSpeed = 1.f; float weapSpeed = 1.f;
if (cls.hasInventoryStore(mPtr)) if (cls.hasInventoryStore(mPtr))
{ {
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
MWWorld::ConstContainerStoreIterator weapon = getActiveWeapon(mPtr, &weaptype); if (stats.getDrawState() == DrawState::Weapon && !mWeapon.isEmpty() && mWeapon.getType() == ESM::Weapon::sRecordId)
isWeapon = (weapon != inv.end() && weapon->getType() == ESM::Weapon::sRecordId);
if (isWeapon)
{ {
weapSpeed = weapon->get<ESM::Weapon>()->mBase->mData.mSpeed; weapSpeed = mWeapon.get<ESM::Weapon>()->mBase->mData.mSpeed;
MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
int ammotype = getWeaponType(weapon->get<ESM::Weapon>()->mBase->mData.mType)->mAmmoType; int ammotype = getWeaponType(mWeapon.get<ESM::Weapon>()->mBase->mData.mType)->mAmmoType;
if (ammotype != ESM::Weapon::None && (ammo == inv.end() || ammo->get<ESM::Weapon>()->mBase->mData.mType != ammotype)) if (ammotype != ESM::Weapon::None)
ammunition = false; ammunition = ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ammotype;
} }
if (!ammunition && mUpperBodyState > UpperBodyState::WeaponEquipped) if (!ammunition && mUpperBodyState > UpperBodyState::WeaponEquipped)
@ -1341,6 +1335,20 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mAnimation->disable(mCurrentWeapon); mAnimation->disable(mCurrentWeapon);
mUpperBodyState = UpperBodyState::WeaponEquipped; mUpperBodyState = UpperBodyState::WeaponEquipped;
} }
MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if (torch != inv.end() && torch->getType() == ESM::Light::sRecordId && updateCarriedLeftVisible(mWeaponType))
{
if (mAnimation->isPlaying("shield"))
mAnimation->disable("shield");
mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm,
false, 1.0f, "start", "stop", 0.0f, std::numeric_limits<size_t>::max(), true);
}
else if (mAnimation->isPlaying("torch"))
{
mAnimation->disable("torch");
}
} }
// Combat for actors with persistent animations obviously will be buggy // Combat for actors with persistent animations obviously will be buggy
@ -1358,9 +1366,7 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mAttackStrength = 0; mAttackStrength = 0;
// Randomize attacks for non-bipedal creatures // Randomize attacks for non-bipedal creatures
if (cls.getType() == ESM::Creature::sRecordId && if (!cls.isBipedal(mPtr) && (!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon)))
!cls.isBipedal(mPtr) &&
(!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon)))
{ {
mCurrentWeapon = chooseRandomAttackAnimation(); mCurrentWeapon = chooseRandomAttackAnimation();
} }
@ -1495,18 +1501,16 @@ bool CharacterController::updateWeaponState(CharacterState idle)
else if(mWeaponType == ESM::Weapon::PickProbe) else if(mWeaponType == ESM::Weapon::PickProbe)
{ {
world->breakInvisibility(mPtr); world->breakInvisibility(mPtr);
MWWorld::ContainerStoreIterator weapon = cls.getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
MWWorld::Ptr item = *weapon;
// TODO: this will only work for the player, and needs to be fixed if NPCs should ever use lockpicks/probes. // TODO: this will only work for the player, and needs to be fixed if NPCs should ever use lockpicks/probes.
MWWorld::Ptr target = world->getFacedObject(); MWWorld::Ptr target = world->getFacedObject();
std::string resultMessage, resultSound; std::string resultMessage, resultSound;
if(!target.isEmpty()) if(!target.isEmpty())
{ {
if(item.getType() == ESM::Lockpick::sRecordId) if (mWeapon.getType() == ESM::Lockpick::sRecordId)
Security(mPtr).pickLock(target, item, resultMessage, resultSound); Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound);
else if(item.getType() == ESM::Probe::sRecordId) else if (mWeapon.getType() == ESM::Probe::sRecordId)
Security(mPtr).probeTrap(target, item, resultMessage, resultSound); Security(mPtr).probeTrap(target, mWeapon, resultMessage, resultSound);
} }
mAnimation->play(mCurrentWeapon, priorityWeapon, mAnimation->play(mCurrentWeapon, priorityWeapon,
MWRender::Animation::BlendMask_All, true, MWRender::Animation::BlendMask_All, true,
@ -1540,10 +1544,9 @@ bool CharacterController::updateWeaponState(CharacterState idle)
{ {
if (Settings::Manager::getBool("best attack", "Game")) if (Settings::Manager::getBool("best attack", "Game"))
{ {
if (isWeapon) if (!mWeapon.isEmpty() && mWeapon.getType() == ESM::Weapon::sRecordId)
{ {
MWWorld::ConstContainerStoreIterator weapon = cls.getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight); mAttackType = getBestAttack(mWeapon.get<ESM::Weapon>()->mBase);
mAttackType = getBestAttack(weapon->get<ESM::Weapon>()->mBase);
} }
else else
{ {
@ -1578,9 +1581,7 @@ bool CharacterController::updateWeaponState(CharacterState idle)
} }
// We should not break swim and sneak animations // We should not break swim and sneak animations
if (resetIdle && if (resetIdle && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
idle != CharState_IdleSneak && idle != CharState_IdleSwim &&
mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
{ {
resetCurrentIdleState(); resetCurrentIdleState();
} }
@ -1788,25 +1789,6 @@ bool CharacterController::updateWeaponState(CharacterState idle)
mUpperBodyState = UpperBodyState::WeaponEquipped; mUpperBodyState = UpperBodyState::WeaponEquipped;
} }
if (cls.hasInventoryStore(mPtr))
{
const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr);
MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getType() == ESM::Light::sRecordId
&& updateCarriedLeftVisible(mWeaponType))
{
if (mAnimation->isPlaying("shield"))
mAnimation->disable("shield");
mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm,
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true);
}
else if (mAnimation->isPlaying("torch"))
{
mAnimation->disable("torch");
}
}
mAnimation->setAccurateAiming(mUpperBodyState > UpperBodyState::WeaponEquipped); mAnimation->setAccurateAiming(mUpperBodyState > UpperBodyState::WeaponEquipped);
return forcestateupdate; return forcestateupdate;
@ -2270,7 +2252,7 @@ void CharacterController::update(float duration)
if (!mSkipAnim) if (!mSkipAnim)
{ {
refreshCurrentAnims(idlestate, movestate, jumpstate, updateWeaponState(idlestate)); refreshCurrentAnims(idlestate, movestate, jumpstate, updateWeaponState());
updateIdleStormState(inwater); updateIdleStormState(inwater);
} }

View File

@ -204,7 +204,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
void clearAnimQueue(bool clearPersistAnims = false); void clearAnimQueue(bool clearPersistAnims = false);
bool updateWeaponState(CharacterState idle); bool updateWeaponState();
void updateIdleStormState(bool inwater) const; void updateIdleStormState(bool inwater) const;
std::string chooseRandomAttackAnimation() const; std::string chooseRandomAttackAnimation() const;