summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-19 02:41:30 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-19 02:41:30 +0200
commit011135415f7f9c5cfeb220540621dfd1c46e6db9 (patch)
tree55dd2943dca362045e7ed96ef72924728343351e /src/net
parentc392eab58774154177a0e790a414c2c52c8ce83b (diff)
parent27114fa2694318f2a1c56cb828a3b79731efcb74 (diff)
downloadmana-client-011135415f7f9c5cfeb220540621dfd1c46e6db9.tar.gz
mana-client-011135415f7f9c5cfeb220540621dfd1c46e6db9.tar.bz2
mana-client-011135415f7f9c5cfeb220540621dfd1c46e6db9.tar.xz
mana-client-011135415f7f9c5cfeb220540621dfd1c46e6db9.zip
Merge git://gitorious.org/~bertram/mana/mana-equipment-fix into equipment-fix
Diffstat (limited to 'src/net')
-rw-r--r--src/net/inventoryhandler.h7
-rw-r--r--src/net/manaserv/beinghandler.cpp34
-rw-r--r--src/net/manaserv/beinghandler.h10
-rw-r--r--src/net/manaserv/charhandler.cpp12
-rw-r--r--src/net/manaserv/inventoryhandler.cpp245
-rw-r--r--src/net/manaserv/inventoryhandler.h78
-rw-r--r--src/net/manaserv/manaserv_protocol.h25
-rw-r--r--src/net/tmwa/inventoryhandler.cpp5
-rw-r--r--src/net/tmwa/inventoryhandler.h67
9 files changed, 352 insertions, 131 deletions
diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h
index 93b56a40..f1dea956 100644
--- a/src/net/inventoryhandler.h
+++ b/src/net/inventoryhandler.h
@@ -38,6 +38,13 @@ class InventoryHandler
// TODO: fix/remove me
virtual size_t getSize(int type) const = 0;
+
+ virtual bool isWeaponSlot(unsigned int slotTypeId) const = 0;
+
+ virtual bool isAmmoSlot(unsigned int slotTypeId) const = 0;
+
+ virtual unsigned int getVisibleSlotsNumber() const
+ { return 0; }
};
} // namespace Net
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 4d45da8a..44c3d77b 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -31,8 +31,10 @@
#include "gui/okdialog.h"
+#include "net/net.h"
#include "net/messagein.h"
+#include "net/manaserv/inventoryhandler.h"
#include "net/manaserv/playerhandler.h"
#include "net/manaserv/manaserv_protocol.h"
@@ -93,29 +95,17 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
static void handleLooks(Being *being, Net::MessageIn &msg)
{
- // Order of sent slots. Has to be in sync with the server code.
- static int const nb_slots = 4;
- static int const slots[nb_slots] =
- { SPRITE_WEAPON, SPRITE_HAT, SPRITE_TOPCLOTHES,
- SPRITE_BOTTOMCLOTHES };
+ int lookChanges = msg.readInt8();
- int mask = msg.readInt8();
-
- if (mask & (1 << 7))
- {
- // The equipment has to be cleared first.
- for (int i = 0; i < nb_slots; ++i)
- {
- being->setSprite(slots[i], 0);
- }
- }
+ if (lookChanges <= 0)
+ return;
- // Fill slots enumerated by the bitmask.
- for (int i = 0; i < nb_slots; ++i)
+ while (lookChanges-- > 0)
{
- if (!(mask & (1 << i))) continue;
- int id = msg.readInt16();
- being->setSprite(slots[i], id,"", (slots[i] == SPRITE_WEAPON));
+ unsigned int slotTypeId = msg.readInt8();
+ being->setSprite(slotTypeId + FIXED_SPRITE_LAYER_SIZE,
+ msg.readInt16(), "",
+ Net::getInventoryHandler()->isWeaponSlot(slotTypeId));
}
}
@@ -154,7 +144,7 @@ void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg)
being->setName(name);
}
int hs = msg.readInt8(), hc = msg.readInt8();
- being->setSprite(SPRITE_HAIR, hs * -1, ColorDB::get(hc));
+ being->setSprite(SPRITE_LAYER_HAIR, hs * -1, ColorDB::get(hc));
being->setGender(msg.readInt8() == GENDER_MALE ?
GENDER_MALE : GENDER_FEMALE);
handleLooks(being, msg);
@@ -342,7 +332,7 @@ void BeingHandler::handleBeingLooksChangeMessage(Net::MessageIn &msg)
{
int style = msg.readInt16();
int color = msg.readInt16();
- being->setSprite(SPRITE_HAIR, style * -1, ColorDB::get(color));
+ being->setSprite(SPRITE_LAYER_HAIR, style * -1, ColorDB::get(color));
}
}
diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h
index 04c766d9..4a1f9f21 100644
--- a/src/net/manaserv/beinghandler.h
+++ b/src/net/manaserv/beinghandler.h
@@ -28,6 +28,16 @@
namespace ManaServ {
+/**
+ * enum for sprites layers.
+ */
+enum SpriteLayer
+{
+ SPRITE_LAYER_BASE = 0,
+ SPRITE_LAYER_HAIR,
+ FIXED_SPRITE_LAYER_SIZE
+};
+
class BeingHandler : public MessageHandler
{
public:
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
index 79f3b35a..b1ddc96a 100644
--- a/src/net/manaserv/charhandler.cpp
+++ b/src/net/manaserv/charhandler.cpp
@@ -34,6 +34,8 @@
#include "net/manaserv/connection.h"
#include "net/manaserv/gamehandler.h"
+#include "net/manaserv/beinghandler.h"
+#include "net/manaserv/inventoryhandler.h"
#include "net/manaserv/messagein.h"
#include "net/manaserv/messageout.h"
#include "net/manaserv/manaserv_protocol.h"
@@ -355,17 +357,19 @@ void CharHandler::switchCharacter()
unsigned int CharHandler::baseSprite() const
{
- return SPRITE_BASE;
+ return SPRITE_LAYER_BASE;
}
unsigned int CharHandler::hairSprite() const
{
- return SPRITE_HAIR;
+ return SPRITE_LAYER_HAIR;
}
unsigned int CharHandler::maxSprite() const
{
- return SPRITE_VECTOREND;
+ static unsigned int visibleSlots = FIXED_SPRITE_LAYER_SIZE
+ + Net::getInventoryHandler()->getVisibleSlotsNumber();
+ return visibleSlots;
}
void CharHandler::updateCharacters()
@@ -387,7 +391,7 @@ void CharHandler::updateCharacters()
LocalPlayer *player = character->dummy = new LocalPlayer;
player->setName(info.name);
player->setGender(info.gender);
- player->setSprite(SPRITE_HAIR, info.hairStyle * -1,
+ player->setSprite(SPRITE_LAYER_HAIR, info.hairStyle * -1,
ColorDB::get(info.hairColor));
character->data.mAttributes[LEVEL] = info.level;
character->data.mAttributes[CHAR_POINTS] = info.characterPoints;
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index acef8ddd..1a74f732 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -29,6 +29,7 @@
#include "log.h"
#include "playerinfo.h"
+#include "gui/equipmentwindow.h"
#include "gui/inventorywindow.h"
#include "net/manaserv/connection.h"
@@ -38,6 +39,10 @@
#include "resources/iteminfo.h"
+#include "utils/stringutils.h"
+
+#define EQUIP_FILE "equip.xml"
+
extern Net::InventoryHandler *inventoryHandler;
namespace ManaServ {
@@ -45,11 +50,11 @@ namespace ManaServ {
struct EquipItemInfo
{
- EquipItemInfo(int itemId, int equipSlot, int amountUsed):
- mItemId(itemId), mEquipSlot(equipSlot), mAmountUsed(amountUsed)
+ EquipItemInfo(int itemId, int slotTypeId, int amountUsed):
+ mItemId(itemId), mSlotTypeId(slotTypeId), mAmountUsed(amountUsed)
{}
- int mItemId, mEquipSlot, mAmountUsed;
+ int mItemId, mSlotTypeId, mAmountUsed;
};
extern Connection *gameServerConnection;
@@ -57,31 +62,71 @@ extern Connection *gameServerConnection;
EquipBackend::EquipBackend()
{
listen(Event::ClientChannel);
+ mVisibleSlots = 0;
+}
+
+Item *EquipBackend::getEquipment(int slotIndex) const
+{
+ Slots::const_iterator it = mSlots.find(slotIndex);
+ return it == mSlots.end() ? 0 : it->second.item;
+}
+
+std::string EquipBackend::getSlotName(int slotIndex) const
+{
+ Slots::const_iterator it = mSlots.find(slotIndex);
+ return it == mSlots.end() ? std::string() : it->second.name;
}
-Item *EquipBackend::getEquipment(int index) const
+void EquipBackend::triggerUnequip(int slotIndex) const
{
- if (index < 0 || (unsigned) index >= mSlots.size())
- return 0;
- return mSlots.at(index);
+ // First get the itemInstance
+ Slots::const_iterator it = mSlots.find(slotIndex);
+
+ if (it == mSlots.end() || it->second.itemInstance == 0 || !it->second.item)
+ return;
+
+ Event event(Event::DoUnequip);
+ event.setItem("item", it->second.item);
+ event.setInt("itemInstance", it->second.itemInstance);
+ event.trigger(Event::ItemChannel);
}
+
void EquipBackend::clear()
{
- for (std::vector<Item*>::iterator i = mSlots.begin(), i_end = mSlots.end();
- i != i_end; ++i)
+ for (Slots::iterator i = mSlots.begin(), i_end = mSlots.end();
+ i != i_end; ++i)
{
- if (Item *item = *i)
- item->setEquipped(false);
+ if (i->second.item)
+ {
+ delete i->second.item;
+ i->second.item = 0;
+ }
}
- mSlots.assign(mSlots.size(), 0);
+ mSlots.clear();
}
-void EquipBackend::equip(int itemId, int equipSlot, int amountUsed)
+void EquipBackend::equip(int itemId, int slotTypeId, int amountUsed,
+ int itemInstance)
{
- if (equipSlot < 0 || (unsigned) equipSlot >= mSlotTypes.size())
+ if (itemInstance <= 0)
+ {
+ logger->log("ManaServ::EquipBackend: Equipment slot %i"
+ " has an invalid item instance.", slotTypeId);
+ return;
+ }
+
+ Slots::iterator it = mSlots.begin();
+ Slots::iterator it_end = mSlots.end();
+ bool slotTypeFound = false;
+ for (; it != it_end; ++it)
+ if (it->second.slotTypeId == (unsigned)slotTypeId)
+ slotTypeFound = true;
+
+ if (!slotTypeFound)
{
- logger->log("ManaServ::EquipBackend: Equipment slot out of range");
+ logger->log("ManaServ::EquipBackend: Equipment slot %i"
+ " is not existing.", slotTypeId);
return;
}
@@ -92,50 +137,52 @@ void EquipBackend::equip(int itemId, int equipSlot, int amountUsed)
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;
- const int end_i = i + slotType.count;
-
- for (; i < end_i && amountUsed > 0; ++i)
+ // Place the item in the slots with corresponding id until
+ // the capacity requested has been reached
+ for (it = mSlots.begin(); it != it_end && amountUsed > 0; ++it)
{
- if (!mSlots.at(i))
+ // If we're on the right slot type and that its unit
+ // isn't already equipped, we can equip there.
+ // The slots are already sorted by id, and subId anyway.
+ if (it->second.slotTypeId == (unsigned)slotTypeId
+ && (!it->second.itemInstance) && (!it->second.item))
{
- mSlots[i] = itemInstance;
+ it->second.itemInstance = itemInstance;
+ it->second.item = new Item(itemId, 1, true);
--amountUsed;
}
}
}
-void EquipBackend::unequip(int equipmentSlot)
+void EquipBackend::unequip(int itemInstance)
{
- if (equipmentSlot < 0 || (unsigned) equipmentSlot >= mSlotTypes.size())
+ Slots::iterator it = mSlots.begin();
+ Slots::iterator it_end = mSlots.end();
+ bool itemInstanceFound = false;
+ for (; it != it_end; ++it)
+ if (it->second.itemInstance == (unsigned)itemInstance)
+ itemInstanceFound = true;
+
+ if (!itemInstanceFound)
{
- logger->log("ManaServ::EquipBackend: Equipment slot out of range");
+ logger->log("ManaServ::EquipBackend: Equipment item instance %i"
+ " is not existing. The item couldn't be unequipped!",
+ itemInstance);
return;
}
- const SlotType &slotType = mSlotTypes.at(equipmentSlot);
-
- // 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)
+ for (it = mSlots.begin(); it != it_end; ++it)
{
- if (mSlots.at(i))
+ if (it->second.itemInstance != (unsigned)itemInstance)
+ continue;
+
+ // We remove the item
+ it->second.itemInstance = 0;
+ // We also delete the item objects
+ if (it->second.item)
{
- if (!deleteDone)
- {
- delete mSlots[i];
- deleteDone = true;
- }
- mSlots[i] = 0;
+ delete it->second.item;
+ it->second.item = 0;
}
}
}
@@ -148,38 +195,84 @@ void EquipBackend::event(Event::Channel, const Event &event)
void EquipBackend::readEquipFile()
{
- mSlots.clear();
- mSlotTypes.clear();
+ clear();
- XML::Document doc("equip.xml");
+ XML::Document doc(EQUIP_FILE);
xmlNodePtr rootNode = doc.rootNode();
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "equip-slots"))
{
- logger->log("ManaServ::EquipBackend: Error while reading equip.xml!");
+ logger->log("ManaServ::EquipBackend: Error while reading "
+ EQUIP_FILE "!");
return;
}
- int slotCount = 0;
+ // The current client slot index
+ unsigned int slotIndex = 0;
+ mVisibleSlots = 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, "capacity", 1);
- slotType.visible = XML::getBoolProperty(childNode, "visible", false);
- slotType.firstIndex = slotCount;
+ Slot slot;
+ slot.slotTypeId = XML::getProperty(childNode, "id", 0);
+ std::string name = XML::getProperty(childNode, "name", std::string());
+ const int capacity = XML::getProperty(childNode, "capacity", 1);
+ slot.weaponSlot = XML::getBoolProperty(childNode, "weapon", false);
+ slot.ammoSlot = XML::getBoolProperty(childNode, "ammo", false);
+
+ if (XML::getBoolProperty(childNode, "visible", false))
+ ++mVisibleSlots;
+
+ if (slot.slotTypeId > 0 && capacity > 0)
+ {
+ if (name.empty())
+ slot.name = toString(slot.slotTypeId);
+ else
+ slot.name = name;
+
+ // The map is filled until the capacity is reached
+ for (int i = 1; i < capacity + 1; ++i)
+ {
+ // Add the capacity part in the name
+ // when there is more than one slot unit. i.e: 1/3, 2/3
+ if (capacity > 1)
+ {
+ slot.name = name + " " + toString(i)
+ + "/" + toString(capacity);
+ }
- mSlotTypes.push_back(slotType);
- slotCount += slotType.count;
+ slot.subId = i;
+ mSlots.insert(std::make_pair(slotIndex, slot));
+ ++slotIndex;
+ }
+ }
}
+}
- mSlots.resize(slotCount);
+bool EquipBackend::isWeaponSlot(int slotTypeId) const
+{
+ for (Slots::const_iterator it = mSlots.begin(), it_end = mSlots.end();
+ it != it_end; ++it)
+ {
+ if (it->second.slotTypeId == (unsigned)slotTypeId)
+ return it->second.weaponSlot;
+ }
+ return false;
}
+bool EquipBackend::isAmmoSlot(int slotTypeId) const
+{
+ for (Slots::const_iterator it = mSlots.begin(), it_end = mSlots.end();
+ it != it_end; ++it)
+ {
+ if (it->second.slotTypeId == (unsigned)slotTypeId)
+ return it->second.ammoSlot;
+ }
+ return false;
+}
InventoryHandler::InventoryHandler()
{
@@ -212,12 +305,12 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
PlayerInfo::setInventoryItem(slot, id, amount);
}
- // A map of { item instance, {equip slot, item id, amount used}}
+ // A map of { item instance, {slot type id, item id, amount used}}
std::map<int, EquipItemInfo> equipItemsInfo;
std::map<int, EquipItemInfo>::iterator it;
while (msg.getUnreadLength())
{
- int equipSlot = msg.readInt16();
+ int slotTypeId = msg.readInt16();
int itemId = msg.readInt16();
int itemInstance = msg.readInt16();
@@ -227,7 +320,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
{
// Add a new entry
equipItemsInfo.insert(std::make_pair(itemInstance,
- EquipItemInfo(itemId, equipSlot, 1)));
+ EquipItemInfo(itemId, slotTypeId, 1)));
}
else
{
@@ -240,9 +333,13 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
++it)
{
mEquipBackend.equip(it->second.mItemId,
- it->second.mEquipSlot,
- it->second.mAmountUsed);
+ it->second.mSlotTypeId,
+ it->second.mAmountUsed,
+ it->first);
}
+ // The backend is ready, we can setup the equipment window.
+ if (equipmentWindow)
+ equipmentWindow->loadEquipBoxes();
}
break;
@@ -267,18 +364,22 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
// Otherwise equip the item in the given slots
while (equipSlotCount--)
{
- unsigned int equipSlot = msg.readInt16();
+ unsigned int parameter = msg.readInt16();
unsigned int amountUsed = msg.readInt16();
if (amountUsed == 0)
{
- // No slots means to unequip this item
- mEquipBackend.unequip(equipSlot);
+ // No amount means to unequip this item
+ // Note that in that case, the parameter is
+ // in fact the itemInstanceId
+ mEquipBackend.unequip(parameter);
}
else
{
- mEquipBackend.equip(itemId, equipSlot,
- amountUsed);
+ int itemInstance = msg.readInt16();
+ // The parameter is in that case the slot type id.
+ mEquipBackend.equip(itemId, parameter,
+ amountUsed, itemInstance);
}
}
@@ -293,8 +394,9 @@ void InventoryHandler::event(Event::Channel channel,
if (channel == Event::ItemChannel)
{
Item *item = event.getItem("item");
+ int itemInstance = event.getInt("itemInstance", 0);
- if (!item)
+ if (!item && itemInstance == 0)
return;
int index = item->getInvIndex();
@@ -308,7 +410,7 @@ void InventoryHandler::event(Event::Channel channel,
else if (event.getType() == Event::DoUnequip)
{
MessageOut msg(PGMSG_UNEQUIP);
- msg.writeInt16(index);
+ msg.writeInt16(itemInstance);
gameServerConnection->send(msg);
}
else if (event.getType() == Event::DoUse)
@@ -370,8 +472,7 @@ void InventoryHandler::event(Event::Channel channel,
bool InventoryHandler::canSplit(const Item *item)
{
- return item && !item->getInfo().getEquippable()
- && item->getQuantity() > 1;
+ return item && item->getQuantity() > 1;
}
size_t InventoryHandler::getSize(int type) const
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index a57b493a..bf3022ab 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -38,26 +38,75 @@ class EquipBackend : public Equipment::Backend, public EventListener
public:
EquipBackend();
- Item *getEquipment(int index) const;
+ Item *getEquipment(int slotIndex) const;
+ std::string getSlotName(int slotIndex) const;
void clear();
- void equip(int itemId, int equipSlot, int amountUsed = 1);
- void unequip(int equipSlot);
+ void equip(int itemId, int slotTypeId, int amountUsed = 1,
+ int itemInstance = 0);
+ void unequip(int slotTypeId);
void event(Event::Channel channel, const Event &event);
+ int getSlotNumber() const
+ { return mSlots.size(); }
+
+ unsigned int getVisibleSlotsNumber() const
+ { return mVisibleSlots; }
+
+ void triggerUnequip(int slotIndex) const;
+
+ bool isWeaponSlot(int slotTypeId) const;
+ bool isAmmoSlot(int slotTypeId) const;
+
private:
void readEquipFile();
- struct SlotType {
+ struct Slot {
+ Slot():
+ item(0),
+ slotTypeId(0),
+ subId(0),
+ itemInstance(0),
+ weaponSlot(false),
+ ammoSlot(false)
+ {}
+
+ // Generic info
std::string name;
- int count;
- bool visible;
- int firstIndex;
- };
- std::vector<Item*> mSlots;
- std::vector<SlotType> mSlotTypes;
+ // The Item reference, used for graphical representation
+ // and info.
+ Item *item;
+
+ // Manaserv specific info
+
+ // Used to know which (server-side) slot id it is.
+ unsigned int slotTypeId;
+ // Static part
+ // The sub id is used to know in which order the slots are
+ // when the slotType has more than one slot capacity:
+ // I.e.: capacity = 6, subId will be between 1 and 6
+ // for each slots in the map.
+ // This is used to sort the multimap along with the slot id.
+ unsigned int subId;
+
+ // This is the (per character) unique item Id, used especially when
+ // equipping the same item multiple times on the same slot type.
+ unsigned int itemInstance;
+
+ // Tell whether the slot is a weapon slot
+ bool weaponSlot;
+
+ // Tell whether the slot is an ammo slot
+ bool ammoSlot;
+ };
+
+ unsigned int mVisibleSlots;
+
+ // slot client index, slot info
+ typedef std::map<unsigned int, Slot> Slots;
+ Slots mSlots;
};
class InventoryHandler : public MessageHandler, Net::InventoryHandler,
@@ -74,6 +123,15 @@ class InventoryHandler : public MessageHandler, Net::InventoryHandler,
size_t getSize(int type) const;
+ bool isWeaponSlot(unsigned int slotTypeId) const
+ { return mEquipBackend.isWeaponSlot(slotTypeId); }
+
+ bool isAmmoSlot(unsigned int slotTypeId) const
+ { return mEquipBackend.isAmmoSlot(slotTypeId); }
+
+ unsigned int getVisibleSlotsNumber() const
+ { return mEquipBackend.getVisibleSlotsNumber(); }
+
private:
EquipBackend mEquipBackend;
};
diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h
index 70c634b5..2c790d26 100644
--- a/src/net/manaserv/manaserv_protocol.h
+++ b/src/net/manaserv/manaserv_protocol.h
@@ -93,11 +93,11 @@ enum {
PGMSG_PICKUP = 0x0110, // W*2 position
PGMSG_DROP = 0x0111, // W slot, W amount
PGMSG_EQUIP = 0x0112, // W inventory slot
- PGMSG_UNEQUIP = 0x0113, // W equipment slot
+ PGMSG_UNEQUIP = 0x0113, // W item Instance id
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 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_EQUIP = 0x0122, // W item Id, W equip slot type count //{ W equip slot, W capacity used, W item instance}*//<- When equipping, //{ W item instance, W 0}*//<- When unequipping
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
@@ -108,12 +108,12 @@ enum {
GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute
PGMSG_RESPAWN = 0x0180, // -
GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position, B direction
- // character: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }*
+ // character: S name, B hair style, B hair color, B gender, B sprite layers changed, { B slot type, W item id }*
// monster: W type id
// npc: W type id
GPMSG_BEING_LEAVE = 0x0201, // W being id
GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
- GPMSG_BEING_LOOKS_CHANGE = 0x0210, // W weapon, W hat, W top clothes, W bottom clothes
+ GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B sprite layers changed, { B slot type, W item id }*
PGMSG_WALK = 0x0260, // W*2 destination
PGMSG_ACTION_CHANGE = 0x0270, // B Action
GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
@@ -421,23 +421,6 @@ enum BeingDirection
RIGHT = 8
};
-/**
- * enum for sprites layers.
- * WARNING: Has to be in sync with the same enum in the Sprite class
- * of the client!
- */
-enum SpriteLayer
-{
- SPRITE_BASE = 0,
- SPRITE_SHOE,
- SPRITE_BOTTOMCLOTHES,
- SPRITE_TOPCLOTHES,
- SPRITE_HAIR,
- SPRITE_HAT,
- SPRITE_WEAPON,
- SPRITE_VECTOREND
-};
-
} // namespace ManaServ
#endif // MANASERV_PROTOCOL_H
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
index ff875e69..76eb85f5 100644
--- a/src/net/tmwa/inventoryhandler.cpp
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -31,6 +31,7 @@
#include "localplayer.h"
#include "log.h"
+#include "gui/equipmentwindow.h"
#include "gui/widgets/chattab.h"
#include "net/messagein.h"
@@ -388,6 +389,10 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
{
mEquips.setEquipment(getSlot(equipType), index);
}
+
+ // Load the equipment boxes
+ if (equipmentWindow)
+ equipmentWindow->loadEquipBoxes();
}
break;
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index 218723e6..4c29e95b 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -34,6 +34,10 @@
#include "net/tmwa/messagehandler.h"
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+
#include <list>
namespace TmwAthena {
@@ -52,9 +56,40 @@ class EquipBackend : public Equipment::Backend
return PlayerInfo::getInventory()->getItem(invyIndex);
}
+ std::string getSlotName(int slotIndex) const
+ {
+ switch (slotIndex)
+ {
+ case EQUIP_TORSO_SLOT:
+ return std::string(_("Torso"));
+ case EQUIP_ARMS_SLOT:
+ return std::string(_("Arms"));
+ case EQUIP_HEAD_SLOT:
+ return std::string(_("Head"));
+ case EQUIP_LEGS_SLOT:
+ return std::string(_("Legs"));
+ case EQUIP_FEET_SLOT:
+ return std::string(_("Feet"));
+ case EQUIP_RING1_SLOT:
+ return std::string(_("Ring 1/2"));
+ case EQUIP_RING2_SLOT:
+ return std::string(_("Ring 2/2"));
+ case EQUIP_NECKLACE_SLOT:
+ return std::string(_("Necklace"));
+ case EQUIP_FIGHT1_SLOT:
+ return std::string(_("Hand 1/2"));
+ case EQUIP_FIGHT2_SLOT:
+ return std::string(_("Hand 2/2"));
+ case EQUIP_PROJECTILE_SLOT:
+ return std::string(_("Ammo"));
+ default:
+ return std::string();
+ }
+ }
+
void clear()
{
- for (int i = 0; i < EQUIPMENT_SIZE; i++)
+ for (int i = 0; i < EQUIP_VECTOR_END; i++)
{
if (mEquipment[i] != -1)
{
@@ -82,8 +117,30 @@ class EquipBackend : public Equipment::Backend
inventoryWindow->updateButtons();
}
+ void triggerUnequip(int slotIndex) const
+ {
+ Item *item = getEquipment(slotIndex);
+ if (item)
+ item->doEvent(Event::DoUnequip);
+ }
+
+ int getSlotNumber() const
+ { return EQUIP_VECTOR_END; }
+
+ // Note the slot type id is equal to the slot Index for tA.
+ bool isWeaponSlot(unsigned int slotTypeId) const
+ {
+ return (slotTypeId == EQUIP_FIGHT1_SLOT
+ || slotTypeId == EQUIP_FIGHT1_SLOT);
+ }
+
+ bool isAmmoSlot(unsigned int slotTypeId) const
+ {
+ return (slotTypeId == EQUIP_PROJECTILE_SLOT);
+ }
+
private:
- int mEquipment[EQUIPMENT_SIZE];
+ int mEquipment[EQUIP_VECTOR_END];
};
/**
@@ -129,6 +186,12 @@ class InventoryHandler : public MessageHandler, public Net::InventoryHandler,
size_t getSize(int type) const;
+ bool isWeaponSlot(unsigned int slotTypeId) const
+ { return mEquips.isWeaponSlot(slotTypeId); }
+
+ bool isAmmoSlot(unsigned int slotTypeId) const
+ { return mEquips.isAmmoSlot(slotTypeId); }
+
private:
EquipBackend mEquips;
InventoryItems mInventoryItems;