diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index 64a6ff3ff98..6b7667a71a5 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -95,9 +95,7 @@ CombatDamage Combat::getCombatDamage(const std::shared_ptr &creature, damage.secondary.value = weapon->getElementDamage(player, target, tool); if (params.useCharges) { auto charges = tool->getAttribute(ItemAttribute_t::CHARGES); - if (charges == 0) { - player->updateSupplyTracker(tool); - } else { + if (charges != 0) { g_game().transformItem(tool, tool->getID(), charges - 1); } } diff --git a/src/creatures/players/cyclopedia/player_badge.hpp b/src/creatures/players/cyclopedia/player_badge.hpp index cc8135b41e4..6b1aa365978 100644 --- a/src/creatures/players/cyclopedia/player_badge.hpp +++ b/src/creatures/players/cyclopedia/player_badge.hpp @@ -11,7 +11,9 @@ class Player; class KV; -class Account; +namespace account { + class Account; +} enum class CyclopediaBadge_t : uint8_t; diff --git a/src/game/game.cpp b/src/game/game.cpp index 068ecad4a50..0464b6123db 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -2397,6 +2397,7 @@ ReturnValue Game::internalRemoveItem(const std::shared_ptr &items, int32_t } if (!test) { + item->playerUpdateSupplyTracker(); int32_t index = cylinder->getThingIndex(item); // remove the item cylinder->removeThing(item, count); @@ -2840,10 +2841,12 @@ std::shared_ptr Game::transformItem(std::shared_ptr item, uint16_t n auto decaying = item->getDecaying(); // If the item is decaying, we need to transform it to the new item - if (decaying > DECAYING_FALSE && item->getDuration() <= 1 && newType.decayTo) { + const auto &itemDuration = item->getDuration(); + if (decaying > DECAYING_FALSE && itemDuration == 0 && newType.decayTo) { g_logger().debug("Decay duration old type {}, transformEquipTo {}, transformDeEquipTo {}", curType.decayTo, curType.transformEquipTo, curType.transformDeEquipTo); g_logger().debug("Decay duration new type decayTo {}, transformEquipTo {}, transformDeEquipTo {}", newType.decayTo, newType.transformEquipTo, newType.transformDeEquipTo); itemId = newType.decayTo; + item->playerUpdateSupplyTracker(); } else if (curType.id != newType.id) { if (newType.group != curType.group) { item->setDefaultSubtype(); @@ -2859,11 +2862,9 @@ std::shared_ptr Game::transformItem(std::shared_ptr item, uint16_t n cylinder->updateThing(item, itemId, count); cylinder->postAddNotification(item, cylinder, itemIndex); - std::shared_ptr quiver = cylinder->getItem(); - if (quiver && quiver->isQuiver() - && quiver->getHoldingPlayer() - && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { - quiver->getHoldingPlayer()->sendInventoryItem(CONST_SLOT_RIGHT, quiver); + const auto &cylinderItem = cylinder->getItem(); + if (cylinderItem) { + cylinderItem->sendUpdateQuiver(); } item->startDecaying(); @@ -2871,11 +2872,9 @@ std::shared_ptr Game::transformItem(std::shared_ptr item, uint16_t n } } - std::shared_ptr quiver = cylinder->getItem(); - if (quiver && quiver->isQuiver() - && quiver->getHoldingPlayer() - && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { - quiver->getHoldingPlayer()->sendInventoryItem(CONST_SLOT_RIGHT, quiver); + const auto &cylinderItem = cylinder->getItem(); + if (cylinderItem) { + cylinderItem->sendUpdateQuiver(); } // Replacing the the old item with the new while maintaining the old position diff --git a/src/items/decay/decay.cpp b/src/items/decay/decay.cpp index 299890f0b4f..a5ea9fd903d 100644 --- a/src/items/decay/decay.cpp +++ b/src/items/decay/decay.cpp @@ -142,7 +142,6 @@ void Decay::checkDecay() { item->setDuration(item->getDuration()); item->setDecaying(DECAYING_FALSE); } else { - item->setDecaying(DECAYING_FALSE); internalDecayItem(item); } } @@ -213,13 +212,6 @@ void Decay::internalDecayItem(const std::shared_ptr &item) { return; } - if (player) { - auto slotPosition = item->getSlotPosition(); - if ((slotPosition & SLOTP_NECKLACE) || (slotPosition & SLOTP_RING)) { - player->updateSupplyTracker(item); - } - } - ReturnValue ret = g_game().internalRemoveItem(item); if (ret != RETURNVALUE_NOERROR) { g_logger().error("[Decay::internalDecayItem] - internalDecayItem failed, " diff --git a/src/items/item.cpp b/src/items/item.cpp index 14af2cfb47f..d5bffe5def5 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -3465,3 +3465,28 @@ int32_t ItemProperties::getDuration() const { return getAttribute(ItemAttribute_t::DURATION); } } +void Item::sendUpdateQuiver() { + const auto &player = getHoldingPlayer(); + const auto &item = static_self_cast(); + const auto &inventoryItem = player->getInventoryItem(CONST_SLOT_RIGHT); + if (player && isQuiver() && inventoryItem == item) { + player->sendInventoryItem(CONST_SLOT_RIGHT, item); + } +} + +void Item::playerUpdateSupplyTracker() { + const auto &player = getHoldingPlayer(); + if (!player) { + return; + } + + static const std::array slotsToCheck = {CONST_SLOT_NECKLACE, CONST_SLOT_RING}; + const auto &item = static_self_cast(); + for (const Slots_t slot : slotsToCheck) { + const auto &inventoryItem = player->getInventoryItem(slot); + if (inventoryItem && inventoryItem == item) { + player->updateSupplyTracker(item); + break; + } + } +} \ No newline at end of file diff --git a/src/items/item.hpp b/src/items/item.hpp index d199fab15cf..612dd5f795b 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -705,6 +705,9 @@ class Item : virtual public Thing, public ItemProperties, public SharedObject { bool canBeMoved() const; void checkDecayMapItemOnMove(); + void sendUpdateQuiver(); + void playerUpdateSupplyTracker(); + protected: std::weak_ptr m_parent;