diff options
Diffstat (limited to 'src/net/manaserv/inventoryhandler.cpp')
-rw-r--r-- | src/net/manaserv/inventoryhandler.cpp | 153 |
1 files changed, 100 insertions, 53 deletions
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index c8dae1c3..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.readInt8(); - int inventorySlot = msg.readInt16(); + int equipSlot = 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 equipSlotCount = msg.readInt8(); + 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.readInt8(); - unsigned int amountUsed = msg.readInt8(); + 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; } @@ -256,19 +302,19 @@ void InventoryHandler::event(Event::Channel channel, if (event.getType() == Event::DoEquip) { MessageOut msg(PGMSG_EQUIP); - msg.writeInt8(index); + msg.writeInt16(index); gameServerConnection->send(msg); } else if (event.getType() == Event::DoUnequip) { MessageOut msg(PGMSG_UNEQUIP); - msg.writeInt8(index); + msg.writeInt16(index); gameServerConnection->send(msg); } else if (event.getType() == Event::DoUse) { MessageOut msg(PGMSG_USE_ITEM); - msg.writeInt8(index); + msg.writeInt16(index); gameServerConnection->send(msg); } else if (event.getType() == Event::DoDrop) @@ -276,8 +322,8 @@ void InventoryHandler::event(Event::Channel channel, int amount = event.getInt("amount", 1); MessageOut msg(PGMSG_DROP); - msg.writeInt8(index); - msg.writeInt8(amount); + msg.writeInt16(index); + msg.writeInt16(amount); gameServerConnection->send(msg); } else if (event.getType() == Event::DoSplit) @@ -288,9 +334,9 @@ void InventoryHandler::event(Event::Channel channel, if (newIndex > Inventory::NO_SLOT_INDEX) { MessageOut msg(PGMSG_MOVE_ITEM); - msg.writeInt8(index); - msg.writeInt8(newIndex); - msg.writeInt8(amount); + msg.writeInt16(index); + msg.writeInt16(newIndex); + msg.writeInt16(amount); gameServerConnection->send(msg); } } @@ -304,9 +350,9 @@ void InventoryHandler::event(Event::Channel channel, return; MessageOut msg(PGMSG_MOVE_ITEM); - msg.writeInt8(index); - msg.writeInt8(newIndex); - msg.writeInt8(item->getQuantity()); + msg.writeInt16(index); + msg.writeInt16(newIndex); + msg.writeInt16(item->getQuantity()); gameServerConnection->send(msg); } else @@ -315,7 +361,8 @@ void InventoryHandler::event(Event::Channel channel, int destination = event.getInt("destination"); int amount = event.getInt("amount", 1);*/ - // TODO + // TODO Support drag'n'drop to the map ground, or with other + // windows. } } } |