diff options
Diffstat (limited to 'src/net/manaserv')
-rw-r--r-- | src/net/manaserv/inventoryhandler.cpp | 124 | ||||
-rw-r--r-- | src/net/manaserv/inventoryhandler.h | 4 | ||||
-rw-r--r-- | src/net/manaserv/manaserv_protocol.h | 8 |
3 files changed, 91 insertions, 45 deletions
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index cf7e8483..acef8ddd 100644 --- a/src/net/manaserv/inventoryhandler.cpp +++ b/src/net/manaserv/inventoryhandler.cpp @@ -42,6 +42,16 @@ extern Net::InventoryHandler *inventoryHandler; namespace ManaServ { +struct EquipItemInfo +{ + + EquipItemInfo(int itemId, int equipSlot, int amountUsed): + mItemId(itemId), mEquipSlot(equipSlot), mAmountUsed(amountUsed) + {} + + int mItemId, mEquipSlot, mAmountUsed; +}; + extern Connection *gameServerConnection; EquipBackend::EquipBackend() @@ -67,7 +77,7 @@ void EquipBackend::clear() mSlots.assign(mSlots.size(), 0); } -void EquipBackend::equip(int inventorySlot, int equipSlot, int amountUsed) +void EquipBackend::equip(int itemId, int equipSlot, int amountUsed) { if (equipSlot < 0 || (unsigned) equipSlot >= mSlotTypes.size()) { @@ -75,16 +85,17 @@ void EquipBackend::equip(int inventorySlot, int equipSlot, int amountUsed) return; } - const SlotType &slotType = mSlotTypes.at(equipSlot); - Item *item = PlayerInfo::getInventory()->getItem(inventorySlot); - - if (!item) + if (!itemDb->exists(itemId)) { - logger->log("ManaServ::EquipBackend: No item at index %d", - inventorySlot); + logger->log("ManaServ::EquipBackend: No item with id %d", + itemId); return; } + const SlotType &slotType = mSlotTypes.at(equipSlot); + + Item *itemInstance = new Item(itemId, 1, true); + // Start at first index and search upwards for free slots to place the // item at the given inventory slot in int i = slotType.firstIndex; @@ -94,32 +105,39 @@ void EquipBackend::equip(int inventorySlot, int equipSlot, int amountUsed) { if (!mSlots.at(i)) { - mSlots[i] = item; + mSlots[i] = itemInstance; --amountUsed; - - item->setEquipped(true); - inventoryWindow->updateButtons(); } } } -void EquipBackend::unequip(int inventorySlot) +void EquipBackend::unequip(int equipmentSlot) { - Item *item = PlayerInfo::getInventory()->getItem(inventorySlot); - - if (!item) + if (equipmentSlot < 0 || (unsigned) equipmentSlot >= mSlotTypes.size()) { - logger->log("ManaServ::EquipBackend: No item at index %d", - inventorySlot); + logger->log("ManaServ::EquipBackend: Equipment slot out of range"); return; } - for (unsigned i = 0; i < mSlots.size(); ++i) - if (mSlots.at(i) == item) - mSlots[i] = 0; + const SlotType &slotType = mSlotTypes.at(equipmentSlot); - item->setEquipped(false); - inventoryWindow->updateButtons(); + // Start at first index and search upwards for free slots to place the + // item at the given inventory slot in + int i = slotType.firstIndex; + const int end_i = i + slotType.count; + bool deleteDone = false; + for (; i < end_i; ++i) + { + if (mSlots.at(i)) + { + if (!deleteDone) + { + delete mSlots[i]; + deleteDone = true; + } + mSlots[i] = 0; + } + } } void EquipBackend::event(Event::Channel, const Event &event) @@ -151,7 +169,7 @@ void EquipBackend::readEquipFile() SlotType slotType; slotType.name = XML::getProperty(childNode, "name", std::string()); - slotType.count = XML::getProperty(childNode, "count", 1); + slotType.count = XML::getProperty(childNode, "capacity", 1); slotType.visible = XML::getBoolProperty(childNode, "visible", false); slotType.firstIndex = slotCount; @@ -193,12 +211,37 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) int amount = msg.readInt16(); PlayerInfo::setInventoryItem(slot, id, amount); } + + // A map of { item instance, {equip slot, item id, amount used}} + std::map<int, EquipItemInfo> equipItemsInfo; + std::map<int, EquipItemInfo>::iterator it; while (msg.getUnreadLength()) { int equipSlot = msg.readInt16(); - int inventorySlot = msg.readInt16(); + int itemId = msg.readInt16(); + int itemInstance = msg.readInt16(); + + // Turn the data received into a usable format + it = equipItemsInfo.find(itemInstance); + if (it == equipItemsInfo.end()) + { + // Add a new entry + equipItemsInfo.insert(std::make_pair(itemInstance, + EquipItemInfo(itemId, equipSlot, 1))); + } + else + { + // Add amount to the existing entry + it->second.mAmountUsed++; + } + } - mEquipBackend.equip(inventorySlot, equipSlot); + for (it = equipItemsInfo.begin(); it != equipItemsInfo.end(); + ++it) + { + mEquipBackend.equip(it->second.mItemId, + it->second.mEquipSlot, + it->second.mAmountUsed); } } break; @@ -214,28 +257,31 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) break; case GPMSG_EQUIP: - while (msg.getUnreadLength()) { - int inventorySlot = msg.readInt16(); + int itemId = msg.readInt16(); int equipSlotCount = msg.readInt16(); - if (equipSlotCount == 0) - { - // No slots means to unequip this item - mEquipBackend.unequip(inventorySlot); - } - else + if (equipSlotCount <= 0) + break; + + // Otherwise equip the item in the given slots + while (equipSlotCount--) { - // Otherwise equip the item in the given slots - while (equipSlotCount--) - { - unsigned int equipSlot = msg.readInt16(); - unsigned int amountUsed = msg.readInt16(); + unsigned int equipSlot = msg.readInt16(); + unsigned int amountUsed = msg.readInt16(); - mEquipBackend.equip(inventorySlot, equipSlot, + if (amountUsed == 0) + { + // No slots means to unequip this item + mEquipBackend.unequip(equipSlot); + } + else + { + mEquipBackend.equip(itemId, equipSlot, amountUsed); } } + } break; } diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h index 255f601c..a57b493a 100644 --- a/src/net/manaserv/inventoryhandler.h +++ b/src/net/manaserv/inventoryhandler.h @@ -41,8 +41,8 @@ class EquipBackend : public Equipment::Backend, public EventListener Item *getEquipment(int index) const; void clear(); - void equip(int inventorySlot, int equipSlot, int amountUsed = 1); - void unequip(int inventorySlot); + void equip(int itemId, int equipSlot, int amountUsed = 1); + void unequip(int equipSlot); void event(Event::Channel channel, const Event &event); diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index 1543504e..12d05e11 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -90,12 +90,12 @@ enum { GPMSG_PLAYER_SERVER_CHANGE = 0x0101, // B*32 token, S game address, W game port PGMSG_PICKUP = 0x0110, // W*2 position PGMSG_DROP = 0x0111, // W slot, W amount - PGMSG_EQUIP = 0x0112, // W slot - PGMSG_UNEQUIP = 0x0113, // W slot + PGMSG_EQUIP = 0x0112, // W inventory slot + PGMSG_UNEQUIP = 0x0113, // W equipment slot 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 invy slot}* - GPMSG_EQUIP = 0x0122, // { W Invy slot, W equip slot type count { W equip slot, W number used} }* + GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount }, { W equip slot type, W item id, W item instance}* + GPMSG_EQUIP = 0x0122, // W item Id, W equip slot type count { W equip slot, W capacity used}* 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 |