From dcadae652ec89b554e75da8c12b6d4a655ccc888 Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Wed, 27 Jul 2011 15:31:21 +0200 Subject: Followed server protocol changes. Also documented a TODO. --- src/net/manaserv/inventoryhandler.cpp | 33 +++++++++++++++++---------------- src/net/manaserv/manaserv_protocol.h | 12 ++++++------ 2 files changed, 23 insertions(+), 22 deletions(-) (limited to 'src/net/manaserv') diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index c8dae1c3..cf7e8483 100644 --- a/src/net/manaserv/inventoryhandler.cpp +++ b/src/net/manaserv/inventoryhandler.cpp @@ -195,7 +195,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) } while (msg.getUnreadLength()) { - int equipSlot = msg.readInt8(); + int equipSlot = msg.readInt16(); int inventorySlot = msg.readInt16(); mEquipBackend.equip(inventorySlot, equipSlot); @@ -217,7 +217,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) while (msg.getUnreadLength()) { int inventorySlot = msg.readInt16(); - int equipSlotCount = msg.readInt8(); + int equipSlotCount = msg.readInt16(); if (equipSlotCount == 0) { @@ -229,8 +229,8 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) // 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, amountUsed); @@ -256,19 +256,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 +276,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 +288,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 +304,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 +315,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/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index 66da57df..1543504e 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -89,13 +89,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 slot + PGMSG_UNEQUIP = 0x0113, // W 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, W invy slot}* + GPMSG_EQUIP = 0x0122, // { W Invy slot, W equip slot type count { W equip slot, W number 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 -- cgit v1.2.3-60-g2f50 From adfa29a6436c2bb1ff2f05ef83e2eb0fa99d6068 Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Thu, 11 Aug 2011 02:26:52 +0200 Subject: Adapted the client to the latest server changes. There are two bugs left I'll take care about in the near future: - Items dealing with more than one slot capacity are only showing on the first equip slot. - The unequip button doesn't get updated when clicking on the equipped item. A client design limitation known: - The client still don't handle correctly items applied on more than one item type at equip time. --- src/net/manaserv/inventoryhandler.cpp | 124 +++++++++++++++++++++++----------- src/net/manaserv/inventoryhandler.h | 4 +- src/net/manaserv/manaserv_protocol.h | 8 +-- 3 files changed, 91 insertions(+), 45 deletions(-) (limited to 'src/net/manaserv') 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 equipItemsInfo; + std::map::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 -- cgit v1.2.3-60-g2f50