diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-08-11 03:01:09 +0200 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-08-11 03:01:09 +0200 |
commit | c392eab58774154177a0e790a414c2c52c8ce83b (patch) | |
tree | d0e071902795a1d978897fa897555abeaf6072d3 /src/net | |
parent | def23555acf313526ecec1c94684932ee8541335 (diff) | |
parent | adfa29a6436c2bb1ff2f05ef83e2eb0fa99d6068 (diff) | |
download | mana-c392eab58774154177a0e790a414c2c52c8ce83b.tar.gz mana-c392eab58774154177a0e790a414c2c52c8ce83b.tar.bz2 mana-c392eab58774154177a0e790a414c2c52c8ce83b.tar.xz mana-c392eab58774154177a0e790a414c2c52c8ce83b.zip |
Merge branch 'master' of git://gitorious.org/~bertram/mana/mana-equipment-fix into equipment-fix
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/manaserv/inventoryhandler.cpp | 153 | ||||
-rw-r--r-- | src/net/manaserv/inventoryhandler.h | 4 | ||||
-rw-r--r-- | src/net/manaserv/manaserv_protocol.h | 12 |
3 files changed, 108 insertions, 61 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. } } } 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 27d7c7b8..70c634b5 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -91,13 +91,13 @@ enum { GPMSG_PLAYER_MAP_CHANGE = 0x0100, // S filename, W x, W y GPMSG_PLAYER_SERVER_CHANGE = 0x0101, // B*32 token, S game address, W game port PGMSG_PICKUP = 0x0110, // W*2 position - PGMSG_DROP = 0x0111, // B slot, B amount - PGMSG_EQUIP = 0x0112, // B slot - PGMSG_UNEQUIP = 0x0113, // B slot - PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount + PGMSG_DROP = 0x0111, // W slot, W amount + 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 }, { B equip slot, W invy slot}* - GPMSG_EQUIP = 0x0122, // { W Invy slot, B equip slot type count { B equip slot, B 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 |