summaryrefslogtreecommitdiff
path: root/src/net/manaserv
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/manaserv')
-rw-r--r--src/net/manaserv/inventoryhandler.cpp124
-rw-r--r--src/net/manaserv/inventoryhandler.h4
-rw-r--r--src/net/manaserv/manaserv_protocol.h8
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