Drop objects that cannot be equipped *after* Lua lets us equip them (#8675)

Ensure broken weapons/armor are dropped
This commit is contained in:
Alexei Kotov 2025-08-22 04:51:07 +03:00
parent 4fd9e5b2bb
commit 8232c473d0

View File

@ -621,11 +621,14 @@ namespace MWGui
auto type = ptr.getType(); auto type = ptr.getType();
bool isWeaponOrArmor = type == ESM::Weapon::sRecordId || type == ESM::Armor::sRecordId; bool isWeaponOrArmor = type == ESM::Weapon::sRecordId || type == ESM::Armor::sRecordId;
bool isBroken = ptr.getClass().hasItemHealth(ptr) && ptr.getCellRef().getCharge() == 0; bool isBroken = ptr.getClass().hasItemHealth(ptr) && ptr.getCellRef().getCharge() == 0;
const bool isFromDragAndDrop = mDragAndDrop->mIsOnDragAndDrop && mDragAndDrop->mItem.mBase == ptr;
// In vanilla, broken armor or weapons cannot be equipped // In vanilla, broken armor or weapons cannot be equipped
// tools with 0 charges is equippable // tools with 0 charges is equippable
if (isBroken && isWeaponOrArmor) if (isBroken && isWeaponOrArmor)
{ {
if (isFromDragAndDrop)
mDragAndDrop->drop(mTradeModel, mItemView);
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage1}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage1}");
return; return;
} }
@ -649,7 +652,6 @@ namespace MWGui
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
auto [eqSlots, canStack] = ptr.getClass().getEquipmentSlots(ptr); auto [eqSlots, canStack] = ptr.getClass().getEquipmentSlots(ptr);
bool isFromDragAndDrop = mDragAndDrop->mItem.mBase == ptr;
int useCount = isFromDragAndDrop ? mDragAndDrop->mDraggedCount : ptr.getCellRef().getCount(); int useCount = isFromDragAndDrop ? mDragAndDrop->mDraggedCount : ptr.getCellRef().getCount();
if (!eqSlots.empty()) if (!eqSlots.empty())
@ -666,11 +668,13 @@ namespace MWGui
if (excess > 0 && canStack) if (excess > 0 && canStack)
invStore.unequipItemQuantity(ptr, excess); invStore.unequipItemQuantity(ptr, excess);
if (mDragAndDrop->mIsOnDragAndDrop && isFromDragAndDrop) if (isFromDragAndDrop)
{ {
// Feature: Don't finish draganddrop if potion or ingredient was used // Feature: Don't finish draganddrop if potion or ingredient was used
if (type == ESM::Potion::sRecordId || type == ESM::Ingredient::sRecordId) if (type == ESM::Potion::sRecordId || type == ESM::Ingredient::sRecordId)
mDragAndDrop->update(); mDragAndDrop->update();
else if (!shouldSetOnPcEquip)
mDragAndDrop->drop(mTradeModel, mItemView);
else else
mDragAndDrop->finish(); mDragAndDrop->finish();
} }
@ -689,14 +693,6 @@ namespace MWGui
{ {
MWWorld::Ptr ptr = mDragAndDrop->mItem.mBase; MWWorld::Ptr ptr = mDragAndDrop->mItem.mBase;
auto [canEquipRes, canEquipMsg] = ptr.getClass().canBeEquipped(ptr, mPtr);
if (canEquipRes == 0) // cannot equip
{
mDragAndDrop->drop(mTradeModel, mItemView); // also plays down sound
MWBase::Environment::get().getWindowManager()->messageBox(canEquipMsg);
return;
}
if (mDragAndDrop->mSourceModel != mTradeModel) if (mDragAndDrop->mSourceModel != mTradeModel)
{ {
// Move item to the player's inventory // Move item to the player's inventory