summaryrefslogtreecommitdiff
path: root/src/net/manaserv/inventoryhandler.cpp
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-04-09 15:48:51 +0200
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-06-02 16:41:35 +0200
commitc2eab288ecc7d7c5e26d02ccecf285cbc0c218ed (patch)
tree37b755bc559a40209291e5ed4961de36fc7788dd /src/net/manaserv/inventoryhandler.cpp
parentc5390a30868f7eb3b5337963dba20911ea7dc6ea (diff)
downloadmana-c2eab288ecc7d7c5e26d02ccecf285cbc0c218ed.tar.gz
mana-c2eab288ecc7d7c5e26d02ccecf285cbc0c218ed.tar.bz2
mana-c2eab288ecc7d7c5e26d02ccecf285cbc0c218ed.tar.xz
mana-c2eab288ecc7d7c5e26d02ccecf285cbc0c218ed.zip
Some work on the manaserv equipment backend
Currently the same equipment window is used as for tmwAthena so that at least something is visible. This means the location of equipped items is currently illogical. It is now possible to equip and unequip items. Mantis-issue: 164 Reviewed-by: Stefan Dombrowski
Diffstat (limited to 'src/net/manaserv/inventoryhandler.cpp')
-rw-r--r--src/net/manaserv/inventoryhandler.cpp161
1 files changed, 145 insertions, 16 deletions
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index ff9b69e6..c8dae1c3 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -26,8 +26,11 @@
#include "item.h"
#include "itemshortcut.h"
#include "localplayer.h"
+#include "log.h"
#include "playerinfo.h"
+#include "gui/inventorywindow.h"
+
#include "net/manaserv/connection.h"
#include "net/manaserv/messagein.h"
#include "net/manaserv/messageout.h"
@@ -41,6 +44,125 @@ namespace ManaServ {
extern Connection *gameServerConnection;
+EquipBackend::EquipBackend()
+{
+ listen(Event::ClientChannel);
+}
+
+Item *EquipBackend::getEquipment(int index) const
+{
+ if (index < 0 || (unsigned) index >= mSlots.size())
+ return 0;
+ return mSlots.at(index);
+}
+
+void EquipBackend::clear()
+{
+ for (std::vector<Item*>::iterator i = mSlots.begin(), i_end = mSlots.end();
+ i != i_end; ++i)
+ {
+ if (Item *item = *i)
+ item->setEquipped(false);
+ }
+ mSlots.assign(mSlots.size(), 0);
+}
+
+void EquipBackend::equip(int inventorySlot, int equipSlot, int amountUsed)
+{
+ if (equipSlot < 0 || (unsigned) equipSlot >= mSlotTypes.size())
+ {
+ logger->log("ManaServ::EquipBackend: Equipment slot out of range");
+ return;
+ }
+
+ const SlotType &slotType = mSlotTypes.at(equipSlot);
+ Item *item = PlayerInfo::getInventory()->getItem(inventorySlot);
+
+ if (!item)
+ {
+ logger->log("ManaServ::EquipBackend: No item at index %d",
+ inventorySlot);
+ return;
+ }
+
+ // 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;
+
+ for (; i < end_i && amountUsed > 0; ++i)
+ {
+ if (!mSlots.at(i))
+ {
+ mSlots[i] = item;
+ --amountUsed;
+
+ item->setEquipped(true);
+ inventoryWindow->updateButtons();
+ }
+ }
+}
+
+void EquipBackend::unequip(int inventorySlot)
+{
+ Item *item = PlayerInfo::getInventory()->getItem(inventorySlot);
+
+ if (!item)
+ {
+ logger->log("ManaServ::EquipBackend: No item at index %d",
+ inventorySlot);
+ return;
+ }
+
+ for (unsigned i = 0; i < mSlots.size(); ++i)
+ if (mSlots.at(i) == item)
+ mSlots[i] = 0;
+
+ item->setEquipped(false);
+ inventoryWindow->updateButtons();
+}
+
+void EquipBackend::event(Event::Channel, const Event &event)
+{
+ if (event.getType() == Event::LoadingDatabases)
+ readEquipFile();
+}
+
+void EquipBackend::readEquipFile()
+{
+ mSlots.clear();
+ mSlotTypes.clear();
+
+ XML::Document doc("equip.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "equip-slots"))
+ {
+ logger->log("ManaServ::EquipBackend: Error while reading equip.xml!");
+ return;
+ }
+
+ int slotCount = 0;
+
+ for_each_xml_child_node(childNode, rootNode)
+ {
+ if (!xmlStrEqual(childNode->name, BAD_CAST "slot"))
+ continue;
+
+ SlotType slotType;
+ slotType.name = XML::getProperty(childNode, "name", std::string());
+ slotType.count = XML::getProperty(childNode, "count", 1);
+ slotType.visible = XML::getBoolProperty(childNode, "visible", false);
+ slotType.firstIndex = slotCount;
+
+ mSlotTypes.push_back(slotType);
+ slotCount += slotType.count;
+ }
+
+ mSlots.resize(slotCount);
+}
+
+
InventoryHandler::InventoryHandler()
{
static const Uint16 _messages[] = {
@@ -62,21 +184,21 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
case GPMSG_INVENTORY_FULL:
{
PlayerInfo::clearInventory();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
+ PlayerInfo::getEquipment()->setBackend(&mEquipBackend);
int count = msg.readInt16();
while (count--)
{
- unsigned int slot = msg.readInt16();
+ int slot = msg.readInt16();
int id = msg.readInt16();
- unsigned int amount = msg.readInt16();
+ int amount = msg.readInt16();
PlayerInfo::setInventoryItem(slot, id, amount);
}
while (msg.getUnreadLength())
{
- unsigned int slot = msg.readInt8();
- unsigned int ref = msg.readInt16();
+ int equipSlot = msg.readInt8();
+ int inventorySlot = msg.readInt16();
- mEquips.addEquipment(slot, ref);
+ mEquipBackend.equip(inventorySlot, equipSlot);
}
}
break;
@@ -94,14 +216,25 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
case GPMSG_EQUIP:
while (msg.getUnreadLength())
{
- unsigned int ref = msg.readInt16();
- int count = msg.readInt8();
- while (count--)
+ int inventorySlot = msg.readInt16();
+ int equipSlotCount = msg.readInt8();
+
+ if (equipSlotCount == 0)
{
- unsigned int slot = msg.readInt8();
- unsigned int used = msg.readInt8();
+ // No slots means to unequip this item
+ mEquipBackend.unequip(inventorySlot);
+ }
+ else
+ {
+ // Otherwise equip the item in the given slots
+ while (equipSlotCount--)
+ {
+ unsigned int equipSlot = msg.readInt8();
+ unsigned int amountUsed = msg.readInt8();
- mEquips.setEquipment(slot, used, ref);
+ mEquipBackend.equip(inventorySlot, equipSlot,
+ amountUsed);
+ }
}
}
break;
@@ -131,10 +264,6 @@ void InventoryHandler::event(Event::Channel channel,
MessageOut msg(PGMSG_UNEQUIP);
msg.writeInt8(index);
gameServerConnection->send(msg);
-
- // Tidy equipment directly to avoid weapon still shown bug,
- // for instance.
- mEquips.setEquipment(index, 0, 0);
}
else if (event.getType() == Event::DoUse)
{