summaryrefslogtreecommitdiff
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
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
-rw-r--r--src/game.cpp12
-rw-r--r--src/net/manaserv/inventoryhandler.cpp161
-rw-r--r--src/net/manaserv/inventoryhandler.h40
3 files changed, 171 insertions, 42 deletions
diff --git a/src/game.cpp b/src/game.cpp
index ef930d92..6fda630e 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -156,13 +156,11 @@ static void createGuiWindows()
tradeWindow = new TradeWindow;
switch (Net::getNetworkType())
{
- case ServerInfo::TMWATHENA:
- equipmentWindow = new TmwAthena::TaEquipmentWindow(
- PlayerInfo::getEquipment());
- break;
- case ServerInfo::MANASERV:
- default:
- equipmentWindow = new EquipmentWindow(PlayerInfo::getEquipment());
+ case ServerInfo::TMWATHENA:
+ case ServerInfo::MANASERV:
+ default:
+ equipmentWindow =
+ new TmwAthena::TaEquipmentWindow(PlayerInfo::getEquipment());
break;
}
statusWindow = new StatusWindow;
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)
{
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index 2733f3da..255f601c 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -29,33 +29,35 @@
#include "net/manaserv/messagehandler.h"
+#include <vector>
+
namespace ManaServ {
-class EquipBackend : public Equipment::Backend
+class EquipBackend : public Equipment::Backend, public EventListener
{
public:
- EquipBackend()
- { memset(mEquipment, 0, sizeof(mEquipment)); }
-
- Item *getEquipment(int index) const
- { return 0; }
+ EquipBackend();
- void clear()
- {
- }
+ Item *getEquipment(int index) const;
+ void clear();
- void setEquipment(unsigned int slot, unsigned int used, int reference)
- {
- printf("Equip: %d at %dx%d\n", reference, slot, used);
- }
+ void equip(int inventorySlot, int equipSlot, int amountUsed = 1);
+ void unequip(int inventorySlot);
- void addEquipment(unsigned int slot, int reference)
- {
- printf("Equip: %d at %d\n", reference, slot);
- }
+ void event(Event::Channel channel, const Event &event);
private:
- Item *mEquipment[EQUIPMENT_SIZE];
+ void readEquipFile();
+
+ struct SlotType {
+ std::string name;
+ int count;
+ bool visible;
+ int firstIndex;
+ };
+
+ std::vector<Item*> mSlots;
+ std::vector<SlotType> mSlotTypes;
};
class InventoryHandler : public MessageHandler, Net::InventoryHandler,
@@ -73,7 +75,7 @@ class InventoryHandler : public MessageHandler, Net::InventoryHandler,
size_t getSize(int type) const;
private:
- EquipBackend mEquips;
+ EquipBackend mEquipBackend;
};
} // namespace ManaServ