diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 1c78b3dfef..a8bf90ff03 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -146,6 +146,7 @@ namespace MWClass { // Do not allow equip tools from inventory during attack if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc) + && !MWBase::Environment::get().getMechanicsManager()->isCastingSpell(npc) && MWBase::Environment::get().getWindowManager()->isGuiMode()) return { 0, "#{sCantEquipWeapWarning}" }; diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 110614bffd..a46a2aefee 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -144,6 +144,7 @@ namespace MWClass { // Do not allow equip tools from inventory during attack if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc) + && !MWBase::Environment::get().getMechanicsManager()->isCastingSpell(npc) && MWBase::Environment::get().getWindowManager()->isGuiMode()) return { 0, "#{sCantEquipWeapWarning}" }; diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 863083ee94..197c3ff1b3 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -270,10 +270,25 @@ namespace MWClass std::pair Weapon::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { + int type = ptr.get()->mBase->mData.mType; + // Do not allow equip weapons from inventory during attack if (npc.isInCell() && MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc)) - return { 0, "#{sCantEquipWeapWarning}" }; + { + int activeWeaponType = ESM::Weapon::None; + MWMechanics::getActiveWeapon(npc, &activeWeaponType); + if (activeWeaponType > ESM::Weapon::None || activeWeaponType == ESM::Weapon::HandToHand) + { + auto* activeWeapon = MWMechanics::getWeaponType(activeWeaponType); + bool isAmmo = MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Class::Ammo; + bool activeWeapUsesAmmo = activeWeapon->mWeaponClass == ESM::WeaponType::Class::Ranged; + bool sameAmmoType = activeWeapon->mAmmoType == type; + // special case for ammo equipping + if ((activeWeapUsesAmmo && !sameAmmoType) || !isAmmo) + return { 0, "#{sCantEquipWeapWarning}" }; + } + } if (hasItemHealth(ptr) && getItemHealth(ptr) == 0) return { 0, "#{sInventoryMessage1}" }; @@ -283,7 +298,6 @@ namespace MWClass if (slots.first.empty()) return { 0, {} }; - int type = ptr.get()->mBase->mData.mType; if (MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded) { return { 2, {} }; diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 44be79ab91..09b7012977 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -325,10 +325,10 @@ namespace MWGui // If we unequip weapon during attack, it can lead to unexpected behaviour if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(mPtr)) { - bool isWeapon = item.mBase.getType() == ESM::Weapon::sRecordId; MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); - - if (isWeapon && invStore.isEquipped(item.mBase)) + MWWorld::ContainerStoreIterator weapIt = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + bool weapActive = mPtr.getClass().getCreatureStats(mPtr).getDrawState() == MWMechanics::DrawState::Weapon; + if (weapActive && weapIt != invStore.end() && *weapIt == item.mBase) { MWBase::Environment::get().getWindowManager()->messageBox("#{sCantEquipWeapWarning}"); return;