mirror of
https://github.com/mehah/otclient
synced 2026-08-15 16:29:06 -04:00
fix: useInventoryItemWith source stackpos on pre-780 protocols (7.6 usewith) (#1755)
Bug Fixes: - Improved compatibility when using inventory items on older client versions, reducing silent failures. - The game now correctly identifies the matching inventory item and uses accurate slot/stack information for the action. - If the item isn’t found in the player’s inventory, the game will check nearby containers and proceed when available.
This commit is contained in:
parent
fec1cca042
commit
a7d1b3961e
2 changed files with 26 additions and 0 deletions
|
|
@ -885,6 +885,18 @@ void Game::useInventoryItemWith(const uint16_t itemId, const ThingPtr& toThing)
|
|||
if (!canPerformGameAction() || !toThing)
|
||||
return;
|
||||
|
||||
// pre-780 protocols resolve the source item by its real inventory slot and
|
||||
// stackpos, so the synthetic Position(0xFFFF, 0, 0) below (source stackpos 0)
|
||||
// addresses the wrong slot and the use silently fails (e.g. rope on 7.6).
|
||||
// resolve the real item and go through useWith, the same gate the hotkey and
|
||||
// keybind code already apply. see #1541
|
||||
if (getClientVersion() < 780) {
|
||||
if (const auto& item = findPlayerItem(itemId, -1)) {
|
||||
useWith(item, toThing);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
|
||||
if (toThing->isCreature())
|
||||
m_protocolGame->sendUseOnCreature(pos, itemId, 0, toThing->getId());
|
||||
|
|
@ -894,6 +906,19 @@ void Game::useInventoryItemWith(const uint16_t itemId, const ThingPtr& toThing)
|
|||
g_lua.callGlobalField("g_game", "onUseWith", pos, itemId, toThing, 0);
|
||||
}
|
||||
|
||||
ItemPtr Game::findPlayerItem(const uint32_t itemId, const int subType)
|
||||
{
|
||||
if (m_localPlayer) {
|
||||
for (int slot = Otc::InventorySlotHead; slot < Otc::LastInventorySlot; ++slot) {
|
||||
const auto& item = m_localPlayer->getInventoryItem(static_cast<Otc::InventorySlot>(slot));
|
||||
if (item && item->getId() == itemId && (subType == -1 || item->getSubType() == subType))
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return findItemInContainers(itemId, subType, 0);
|
||||
}
|
||||
|
||||
ItemPtr Game::findItemInContainers(const uint32_t itemId, const int subType, const uint8_t tier)
|
||||
{
|
||||
for (const auto& it : m_containers) {
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ public:
|
|||
void useInventoryItem(uint16_t itemId);
|
||||
void useInventoryItemWith(uint16_t itemId, const ThingPtr& toThing);
|
||||
ItemPtr findItemInContainers(uint32_t itemId, int subType, uint8_t tier);
|
||||
ItemPtr findPlayerItem(uint32_t itemId, int subType);
|
||||
|
||||
// container related
|
||||
int open(const ItemPtr& item, const ContainerPtr& previousContainer);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue