diff options
Diffstat (limited to 'src/game-server/itemmanager.cpp')
-rw-r--r-- | src/game-server/itemmanager.cpp | 146 |
1 files changed, 81 insertions, 65 deletions
diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index d21c791c..ac7f13c8 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -51,6 +51,14 @@ void ItemManager::deinitialize() { delete i->second; } + + for (std::map< unsigned int, EquipSlotInfo* >::iterator it = + mEquipSlotsInfo.begin(), it_end = mEquipSlotsInfo.end(); it != it_end; + ++it) + { + delete it->second; + } + mItemClasses.clear(); mItemClassesByName.clear(); } @@ -71,52 +79,22 @@ unsigned int ItemManager::getDatabaseVersion() const return mItemDatabaseVersion; } -const std::string &ItemManager::getEquipNameFromId(unsigned int id) const -{ - return mEquipSlots.at(id).first; -} - -unsigned int ItemManager::getEquipIdFromName(const std::string &name) const +unsigned int ItemManager::getEquipSlotIdFromName(const std::string &name) 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; + EquipSlotInfo *slotInfo = mNamedEquipSlotsInfo.find(name); + return slotInfo ? slotInfo->slotId : 0; } -unsigned int ItemManager::getMaxSlotsFromId(unsigned int id) const +unsigned int ItemManager::getEquipSlotCapacity(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 +111,63 @@ 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 + + if (slotId > 255) + { + LOG_WARN("Item Manager: equip slot " << slotId + << ": (" << name << ") is superior to 255 " + "and has been ignored."); + continue; + } + + bool visible = XML::getBoolProperty(node, "visible", false); + if (visible) + ++mVisibleEquipSlotCount; + + EquipSlotsInfo::iterator i = mEquipSlotsInfo.find(slotId); + + if (i != mEquipSlotsInfo.end()) { - bool visible = XML::getProperty(node, "visible", "false") != "false"; - if (visible) - { - 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!"); - } - mEquipSlots.push_back(std::pair<std::string, unsigned int> - (name, count)); - totalCount += count; - ++slotCount; + LOG_WARN("Item Manager: Ignoring duplicate definition " + "of equip slot '" << slotId << "'!"); + continue; } + + LOG_DEBUG("Adding equip slot, id: " << slotId << ", name: " << name + << ", capacity: " << capacity << ", visible? " << visible); + EquipSlotInfo *equipSlotInfo = + new EquipSlotInfo(slotId, name, capacity, visible); + mEquipSlotsInfo.insert( + std::make_pair<unsigned int, EquipSlotInfo*>(slotId, equipSlotInfo)); + mNamedEquipSlotsInfo.insert(name, equipSlotInfo); + + totalCapacity += capacity; + ++slotCount; } } LOG_INFO("Loaded '" << slotCount << "' slot types with '" - << totalCount << "' slots."); + << totalCapacity << "' slots."); } void ItemManager::readItemsFile() @@ -263,28 +262,45 @@ void ItemManager::readItemNode(xmlNodePtr itemNode) void ItemManager::readEquipNode(xmlNodePtr equipNode, ItemClass *item) { - ItemEquipInfo req; for_each_xml_child_node(subNode, equipNode) { if (xmlStrEqual(subNode->name, BAD_CAST "slot")) { + if (item->mEquipReq.equipSlotId) + { + LOG_WARN("Item Manager: duplicate equip slot definitions!" + " Only the first will apply."); + break; + } + std::string slot = XML::getProperty(subNode, "type", std::string()); if (slot.empty()) { LOG_WARN("Item Manager: empty equip slot definition!"); continue; } - req.push_back(std::make_pair(getEquipIdFromName(slot), - XML::getProperty(subNode, "required", 1))); + if (utils::isNumeric(slot)) + { + // When the slot id is given + item->mEquipReq.equipSlotId = utils::stringToInt(slot); + } + else + { + // When its name is given + item->mEquipReq.equipSlotId = getEquipSlotIdFromName(slot); + } + item->mEquipReq.capacityRequired = + XML::getProperty(subNode, "required", 1); } } - if (req.empty()) + + if (!item->mEquipReq.equipSlotId) { LOG_WARN("Item Manager: empty equip requirement " - "definition for item " << item->getDatabaseID() << "!"); + "definition for item " << item->getDatabaseID() << "!" + " The item will be unequippable."); return; } - item->mEquip.push_back(req); } void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item) @@ -309,8 +325,8 @@ void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item) * trigger, and the second defines the default * trigger to use for dispelling. */ - triggerTable["existence"].first = ITT_IN_INVY; - triggerTable["existence"].second = ITT_LEAVE_INVY; + triggerTable["in-inventory"].first = ITT_IN_INVY; + triggerTable["in-inventory"].second = ITT_LEAVE_INVY; triggerTable["activation"].first = ITT_ACTIVATE; triggerTable["activation"].second = ITT_NULL; triggerTable["equip"].first = ITT_EQUIP; |