summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp2
-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.cpp29
-rw-r--r--src/net/manaserv/inventoryhandler.h27
-rw-r--r--src/net/manaserv/manaserv_protocol.h21
-rw-r--r--src/net/tmwa/inventoryhandler.h18
9 files changed, 112 insertions, 48 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 4f546f6d..6c2a1517 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1067,8 +1067,6 @@ void Being::updateColors()
void Being::setSprite(unsigned int slot, int id, const std::string &color,
bool isWeapon)
{
- assert(slot < Net::getCharHandler()->maxSprite());
-
if (slot >= size())
ensureSize(slot + 1);
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 a5875e08..1a74f732 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -62,6 +62,7 @@ extern Connection *gameServerConnection;
EquipBackend::EquipBackend()
{
listen(Event::ClientChannel);
+ mVisibleSlots = 0;
}
Item *EquipBackend::getEquipment(int slotIndex) const
@@ -208,6 +209,7 @@ void EquipBackend::readEquipFile()
// The current client slot index
unsigned int slotIndex = 0;
+ mVisibleSlots = 0;
for_each_xml_child_node(childNode, rootNode)
{
@@ -218,6 +220,11 @@ void EquipBackend::readEquipFile()
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)
{
@@ -245,6 +252,28 @@ void EquipBackend::readEquipFile()
}
}
+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()
{
static const Uint16 _messages[] = {
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index aed41d6c..bf3022ab 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -51,8 +51,14 @@ class EquipBackend : public Equipment::Backend, public EventListener
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();
@@ -61,7 +67,9 @@ class EquipBackend : public Equipment::Backend, public EventListener
item(0),
slotTypeId(0),
subId(0),
- itemInstance(0)
+ itemInstance(0),
+ weaponSlot(false),
+ ammoSlot(false)
{}
// Generic info
@@ -86,8 +94,16 @@ class EquipBackend : public Equipment::Backend, public EventListener
// 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;
@@ -107,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 624e5ac0..cd24d838 100644
--- a/src/net/manaserv/manaserv_protocol.h
+++ b/src/net/manaserv/manaserv_protocol.h
@@ -106,12 +106,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
@@ -419,23 +419,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.h b/src/net/tmwa/inventoryhandler.h
index 44ddd896..4c29e95b 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -127,6 +127,18 @@ class EquipBackend : public Equipment::Backend
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[EQUIP_VECTOR_END];
};
@@ -174,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;