1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-15 00:56:36 +00:00

Merge branch 'itemusage' into 'master'

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

Closes #8675

See merge request OpenMW/openmw!4870
This commit is contained in:
psi29a 2025-08-31 18:00:29 +00:00
commit 1d08d3b900

View file

@ -621,20 +621,23 @@ 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;
const auto [canEquipResult, canEquipMsg] = ptr.getClass().canBeEquipped(ptr, mPtr);
// 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)
{ {
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage1}"); if (isFromDragAndDrop)
mDragAndDrop->drop(mTradeModel, mItemView);
MWBase::Environment::get().getWindowManager()->messageBox(canEquipMsg);
return; return;
} }
bool canEquip = ptr.getClass().canBeEquipped(ptr, mPtr).first != 0; const bool willEquip = canEquipResult != 0 || force;
bool shouldSetOnPcEquip = canEquip || force;
// If the item has a script, set OnPCEquip or PCSkipEquip to 1 // If the item has a script, set OnPCEquip or PCSkipEquip to 1
if (!script.empty() && shouldSetOnPcEquip) if (!script.empty() && willEquip)
{ {
// Ingredients, books and repair hammers must not have OnPCEquip set to 1 here // Ingredients, books and repair hammers must not have OnPCEquip set to 1 here
bool isBook = type == ESM::Book::sRecordId; bool isBook = type == ESM::Book::sRecordId;
@ -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())
@ -659,18 +661,20 @@ namespace MWGui
useCount += it->getCellRef().getCount(); useCount += it->getCellRef().getCount();
} }
action->execute(player, !canEquip); action->execute(player, !willEquip);
// Partial equipping // Partial equipping
int excess = ptr.getCellRef().getCount() - useCount; int excess = ptr.getCellRef().getCount() - useCount;
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 (!willEquip)
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