summaryrefslogtreecommitdiff
path: root/src/net/manaserv
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-11 03:01:09 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-11 03:01:09 +0200
commitc392eab58774154177a0e790a414c2c52c8ce83b (patch)
treed0e071902795a1d978897fa897555abeaf6072d3 /src/net/manaserv
parentdef23555acf313526ecec1c94684932ee8541335 (diff)
parentadfa29a6436c2bb1ff2f05ef83e2eb0fa99d6068 (diff)
downloadmana-client-c392eab58774154177a0e790a414c2c52c8ce83b.tar.gz
mana-client-c392eab58774154177a0e790a414c2c52c8ce83b.tar.bz2
mana-client-c392eab58774154177a0e790a414c2c52c8ce83b.tar.xz
mana-client-c392eab58774154177a0e790a414c2c52c8ce83b.zip
Merge branch 'master' of git://gitorious.org/~bertram/mana/mana-equipment-fix into equipment-fix
Diffstat (limited to 'src/net/manaserv')
-rw-r--r--src/net/manaserv/inventoryhandler.cpp153
-rw-r--r--src/net/manaserv/inventoryhandler.h4
-rw-r--r--src/net/manaserv/manaserv_protocol.h12
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