From caf715fc482e700d80eab7592a4e61e4a0417294 Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Thu, 18 Aug 2011 00:44:57 +0200 Subject: Fixed a crash when dealing with unknown equipped items. --- src/game-server/inventory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 1eaf8b91..e244f651 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -119,7 +119,7 @@ void Inventory::initialize() << it2->second.itemId << " from the equipment of '" << mCharacter->getName() << "'!"); - mPoss->equipSlots.erase(++it2); + mPoss->equipSlots.erase(it2++); continue; } -- cgit v1.2.3-60-g2f50 From 10fd0338203a46cec913859fd5e38b61fa24a30f Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Thu, 18 Aug 2011 00:55:12 +0200 Subject: Change the unequip function to make use of the item instance id. It will make the client capable to tell which item is to be unequipped when there are several item equipped within a slot type, for instance. The client has now yet to be upgraded to follow the new protocol. --- src/common/manaserv_protocol.h | 4 ++-- src/game-server/inventory.cpp | 26 ++++++++++++-------------- src/game-server/inventory.h | 4 ++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h index 6c51aef9..25dd7c77 100644 --- a/src/common/manaserv_protocol.h +++ b/src/common/manaserv_protocol.h @@ -91,11 +91,11 @@ enum { PGMSG_PICKUP = 0x0110, // W*2 position PGMSG_DROP = 0x0111, // W slot, W amount PGMSG_EQUIP = 0x0112, // W inventory slot - PGMSG_UNEQUIP = 0x0113, // W equipment slot + PGMSG_UNEQUIP = 0x0113, // W item Instance id PGMSG_MOVE_ITEM = 0x0114, // W slot1, W slot2, W amount GPMSG_INVENTORY = 0x0120, // { W slot, W item id [, W amount] (if item id is nonzero) }* GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount }, { W equip slot, W item Id, W item Instance}* - GPMSG_EQUIP = 0x0122, // W item Id, W equip slot type count { W equip slot, W capacity used}* + GPMSG_EQUIP = 0x0122, // W item Id, W equip slot type count //{ W equip slot, W capacity used}*//<- When equipping, //{ W item instance, W 0}*//<- When unequipping GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, D base value (in 1/256ths), D modified value (in 1/256ths)}* GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }* GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index e244f651..c3d2bfcb 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -726,6 +726,8 @@ bool Inventory::equip(int inventorySlot) equipMsg.writeInt16(it2->first); // Capacity used equipMsg.writeInt16(it2->second); + // Item instance + equipMsg.writeInt16(itemInstance); } // New item trigger @@ -740,27 +742,21 @@ bool Inventory::equip(int inventorySlot) return true; } -bool Inventory::unequip(unsigned int equipmentSlot) +bool Inventory::unequip(unsigned int itemInstance) { // map of { itemInstance, itemId } std::map itemIdListToInventory; - bool changed = false; MessageOut equipMsg(GPMSG_EQUIP); equipMsg.writeInt16(0); // Item Id, useless in case of unequip. - equipMsg.writeInt16(1); // Number of slot types touched, - // 1 in case of unequip. // Empties all equip entries that point to the given equipment slot // The equipment slots should NEVER be erased after initialization! for (EquipData::iterator it = mPoss->equipSlots.begin(), it_end = mPoss->equipSlots.end(); it != it_end; ++it) { - if (it->first == equipmentSlot && it->second.itemId != 0) + if (it->second.itemInstance == itemInstance) { - if (!it->second.itemInstance) - continue; - // Add the item to the inventory list if not already present there std::map::const_iterator it2 = itemIdListToInventory.find(it->second.itemInstance); @@ -771,12 +767,14 @@ bool Inventory::unequip(unsigned int equipmentSlot) (it->second.itemInstance, it->second.itemId)); } - changed = true; it->second.itemId = 0; it->second.itemInstance = 0; } } + // Number of slot types touched, + equipMsg.writeInt16(itemIdListToInventory.size()); + // Apply unequip trigger(s), and move the item(s) back to inventory. for (std::map::const_iterator it2 = itemIdListToInventory.begin(), it2_end = itemIdListToInventory.end(); @@ -784,16 +782,16 @@ bool Inventory::unequip(unsigned int equipmentSlot) { updateEquipmentTrigger(it2->second, 0); insert(it2->second, 1); - } - if (changed) - { - equipMsg.writeInt16(equipmentSlot); + equipMsg.writeInt16(it2->first); equipMsg.writeInt16(0); // Capacity used, set to 0 to unequip. } if (equipMsg.getLength() > 2) + { gameHandler->sendTo(mCharacter, equipMsg); + return true; + } - return changed; + return false; } diff --git a/src/game-server/inventory.h b/src/game-server/inventory.h index 06f55e06..39f83216 100644 --- a/src/game-server/inventory.h +++ b/src/game-server/inventory.h @@ -65,10 +65,10 @@ class Inventory /** * Unequips item from given equipment slot. - * @param equipmentSlot Where to remove item(s). + * @param itemInstance The item instance id used to know what to unequip * @returns Whether it was unequipped. */ - bool unequip(unsigned int equipmentSlot); + bool unequip(unsigned int itemInstance); /** * Inserts some items into the inventory. -- cgit v1.2.3-60-g2f50