summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--example/clientdata/equip.xml25
-rw-r--r--src/game-server/inventory.cpp2
-rw-r--r--src/game-server/itemmanager.cpp105
-rw-r--r--src/game-server/itemmanager.h44
-rw-r--r--src/game-server/state.cpp2
5 files changed, 99 insertions, 79 deletions
diff --git a/example/clientdata/equip.xml b/example/clientdata/equip.xml
index 0d1c1d3..097229c 100644
--- a/example/clientdata/equip.xml
+++ b/example/clientdata/equip.xml
@@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- Notes:
+ The id and name parameters must be unique.
+ The count parameter indicates the 'size' of the slot.
+ The visible parameter indicates whether the item is visible
+ on the map character. Hence, whether the server should send appearance
+ updates when making changes on it.
+-->
<equip-slots>
- <slot name="hand" count="2" visible="true" />
- <slot name="torso" count="1" visible="true" />
- <slot name="arms" count="1" />
- <slot name="head" count="1" visible="true" />
- <slot name="legs" count="1" visible="true" />
- <slot name="ring" count="1" />
- <slot name="necklace" count="1" />
- <slot name="feet" count="1" />
- <slot name="ammo" count="1" />
+ <slot id="1" name="hand" capacity="2" visible="true" />
+ <slot id="2" name="torso" capacity="1" visible="true" />
+ <slot id="3" name="arms" capacity="1" />
+ <slot id="4" name="head" capacity="1" visible="true" />
+ <slot id="5" name="legs" capacity="1" visible="true" />
+ <slot id="6" name="ring" capacity="1" />
+ <slot id="7" name="necklace" capacity="1" />
+ <slot id="8" name="feet" capacity="1" />
+ <slot id="9" name="ammo" capacity="1" />
</equip-slots>
diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp
index 988877c..44aac04 100644
--- a/src/game-server/inventory.cpp
+++ b/src/game-server/inventory.cpp
@@ -574,7 +574,7 @@ bool Inventory::equip(int slot, bool override)
++it3)
{
// it3 -> { slot id, number required }
- unsigned int max = itemManager->getMaxSlotsFromId(it3->first),
+ unsigned int max = itemManager->getEquipSlotCapacity(it3->first),
used = mPoss->equipSlots.count(it3->first);
if (max - used >= it3->second)
continue;
diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp
index d21c791..bfe3489 100644
--- a/src/game-server/itemmanager.cpp
+++ b/src/game-server/itemmanager.cpp
@@ -71,52 +71,22 @@ unsigned int ItemManager::getDatabaseVersion() const
return mItemDatabaseVersion;
}
-const std::string &ItemManager::getEquipNameFromId(unsigned int id) const
+unsigned int ItemManager::getEquipSlotIdFromName(const std::string &name) const
{
- return mEquipSlots.at(id).first;
+ EquipSlotInfo *slotInfo = mNamedEquipSlotsInfo.find(name);
+ return slotInfo ? slotInfo->slotId : 0;
}
-unsigned int ItemManager::getEquipIdFromName(const std::string &name) const
+unsigned int ItemManager::getEquipSlotCapacity(unsigned int id) const
{
- for (unsigned int i = 0; i < mEquipSlots.size(); ++i)
- if (name == mEquipSlots.at(i).first)
- return i;
- LOG_WARN("Item Manager: attempt to find equip id from name \"" <<
- name << "\" not found, defaulting to 0!");
- return 0;
-}
-
-unsigned int ItemManager::getMaxSlotsFromId(unsigned int id) const
-{
- return mEquipSlots.at(id).second;
-}
-
-unsigned int ItemManager::getVisibleSlotCount() const
-{
- if (!mVisibleEquipSlotCount)
- {
- for (VisibleEquipSlots::const_iterator it = mVisibleEquipSlots.begin(),
- it_end = mVisibleEquipSlots.end();
- it != it_end;
- ++it)
- {
- mVisibleEquipSlotCount += mEquipSlots.at(*it).second;
- }
- }
- return mVisibleEquipSlotCount;
+ EquipSlotsInfo::const_iterator i = mEquipSlotsInfo.find(id);
+ return i != mEquipSlotsInfo.end() ? i->second.slotCapacity : 0;
}
bool ItemManager::isEquipSlotVisible(unsigned int id) const
{
- for (VisibleEquipSlots::const_iterator it = mVisibleEquipSlots.begin(),
- it_end = mVisibleEquipSlots.end();
- it != it_end;
- ++it)
- {
- if (*it == id)
- return true;
- }
- return false;
+ EquipSlotsInfo::const_iterator i = mEquipSlotsInfo.find(id);
+ return i != mEquipSlotsInfo.end() ? i->second.visibleSlot : false;
}
void ItemManager::readEquipSlotsFile()
@@ -133,42 +103,55 @@ void ItemManager::readEquipSlotsFile()
LOG_INFO("Loading equip slots: " << mEquipSlotsFile);
- unsigned totalCount = 0;
+ unsigned totalCapacity = 0;
unsigned slotCount = 0;
- unsigned visibleSlotCount = 0;
+ mVisibleEquipSlotCount = 0;
for_each_xml_child_node(node, rootNode)
{
if (xmlStrEqual(node->name, BAD_CAST "slot"))
{
+ const int slotId = XML::getProperty(node, "id", 0);
const std::string name = XML::getProperty(node, "name",
std::string());
- const int count = XML::getProperty(node, "count", 0);
+ const int capacity = XML::getProperty(node, "capacity", 0);
- if (name.empty() || count <= 0)
+ if (slotId <= 0 || name.empty() || capacity <= 0)
{
- LOG_WARN("Item Manager: equip slot has no name or zero count");
+ LOG_WARN("Item Manager: equip slot " << slotId
+ << ": (" << name << ") has no name or zero count. "
+ "The slot has been ignored.");
+ continue;
}
- else
+
+ bool visible = XML::getBoolProperty(node, "visible", false);
+ if (visible)
{
- bool visible = XML::getProperty(node, "visible", "false") != "false";
- if (visible)
+ if (++mVisibleEquipSlotCount > 7)
{
- mVisibleEquipSlots.push_back(mEquipSlots.size());
- if (++visibleSlotCount > 7)
- LOG_WARN("Item Manager: More than 7 visible equip slot!"
- "This will not work with current netcode!");
+ LOG_WARN("Item Manager: More than 7 visible equip slot!"
+ "This will not work with current netcode!");
}
- mEquipSlots.push_back(std::pair<std::string, unsigned int>
- (name, count));
- totalCount += count;
- ++slotCount;
}
+
+ EquipSlotsInfo::iterator i = mEquipSlotsInfo.find(slotId);
+
+ if (i != mEquipSlotsInfo.end())
+ {
+ LOG_WARN("Item Manager: Ignoring duplicate definition "
+ "of equip slot '" << slotId << "'!");
+ continue;
+ }
+ EquipSlotInfo equipSlotInfo(slotId, name, capacity, visible);
+ mEquipSlotsInfo[slotId] = equipSlotInfo;
+ mNamedEquipSlotsInfo.insert(name, &equipSlotInfo);
+ totalCapacity += capacity;
+ ++slotCount;
}
}
LOG_INFO("Loaded '" << slotCount << "' slot types with '"
- << totalCount << "' slots.");
+ << totalCapacity << "' slots.");
}
void ItemManager::readItemsFile()
@@ -274,8 +257,18 @@ void ItemManager::readEquipNode(xmlNodePtr equipNode, ItemClass *item)
LOG_WARN("Item Manager: empty equip slot definition!");
continue;
}
- req.push_back(std::make_pair(getEquipIdFromName(slot),
+ if (utils::isNumeric(slot))
+ {
+ // When the slot id is given
+ req.push_back(std::make_pair(utils::stringToInt(slot),
+ XML::getProperty(subNode, "required", 1)));
+ }
+ else
+ {
+ // When its name is given
+ req.push_back(std::make_pair(getEquipSlotIdFromName(slot),
XML::getProperty(subNode, "required", 1)));
+ }
}
}
if (req.empty())
diff --git a/src/game-server/itemmanager.h b/src/game-server/itemmanager.h
index c310df4..29feee8 100644
--- a/src/game-server/itemmanager.h
+++ b/src/game-server/itemmanager.h
@@ -30,6 +30,24 @@
class ItemClass;
+struct EquipSlotInfo
+{
+ EquipSlotInfo():
+ slotId(0), slotCapacity(0), visibleSlot(false)
+ {}
+
+ EquipSlotInfo(unsigned int id, const std::string &name,
+ unsigned int capacity, bool visible):
+ slotId(id), slotName(name), slotCapacity(capacity), visibleSlot(visible)
+ {}
+
+ unsigned int slotId;
+ std::string slotName;
+ unsigned int slotCapacity;
+ bool visibleSlot;
+};
+
+
class ItemManager
{
public:
@@ -73,13 +91,12 @@ class ItemManager
*/
unsigned int getDatabaseVersion() const;
- const std::string &getEquipNameFromId(unsigned int id) const;
-
- unsigned int getEquipIdFromName(const std::string &name) const;
+ unsigned int getEquipSlotIdFromName(const std::string &name) const;
- unsigned int getMaxSlotsFromId(unsigned int id) const;
+ unsigned int getEquipSlotCapacity(unsigned int id) const;
- unsigned int getVisibleSlotCount() const;
+ unsigned int getVisibleEquipSlotCount() const
+ { return mVisibleEquipSlotCount; }
bool isEquipSlotVisible(unsigned int id) const;
@@ -94,19 +111,22 @@ class ItemManager
void readEffectNode(xmlNodePtr effectNode, ItemClass *item);
typedef std::map< int, ItemClass * > ItemClasses;
- // Map a string (name of slot) with (str-id, max-per-equip-slot)
- typedef std::vector< std::pair< std::string, unsigned int > > EquipSlots;
+ ItemClasses mItemClasses; /**< Item reference */
+ utils::NameMap<ItemClass*> mItemClassesByName;
+
+ // Map an equip slot id with the equip slot info.
+ typedef std::map< unsigned int, EquipSlotInfo > EquipSlotsInfo;
// Reference to the vector position of equipSlots
typedef std::vector< unsigned int > VisibleEquipSlots;
- ItemClasses mItemClasses; /**< Item reference */
- utils::NameMap<ItemClass*> mItemClassesByName;
- EquipSlots mEquipSlots;
- VisibleEquipSlots mVisibleEquipSlots;
+ EquipSlotsInfo mEquipSlotsInfo;
+ // Map a string (name of slot) with (str-id, max-per-equip-slot)
+ // We only keep a pointer to it: The id map will take care of deletion.
+ utils::NameMap<EquipSlotInfo* > mNamedEquipSlotsInfo;
std::string mItemsFile;
std::string mEquipSlotsFile;
- mutable unsigned int mVisibleEquipSlotCount; // Cache
+ unsigned int mVisibleEquipSlotCount; // Cache
/** Version of the loaded items database file.*/
unsigned int mItemDatabaseVersion;
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 1a9c020..d8f9b18 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -109,7 +109,7 @@ static void updateMap(MapComposite *map)
static void serializeLooks(Character *ch, MessageOut &msg, bool full)
{
const EquipData &equipData = ch->getPossessions().getEquipment();
- unsigned int nb_slots = itemManager->getVisibleSlotCount();
+ unsigned int nb_slots = itemManager->getVisibleEquipSlotCount();
// Bitmask describing the changed entries.
int changed = (1 << nb_slots) - 1;