// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. //////////////////////////////////////////////////////////////////////// #include "otpch.h" #include <iostream> #include <libxml/xmlmemory.h> #include <libxml/parser.h> #include "vocation.h" #include "tools.h" Vocation Vocations::defVoc = Vocation(); void Vocations::clear() { for(VocationsMap::iterator it = vocationsMap.begin(); it != vocationsMap.end(); ++it) delete it->second; vocationsMap.clear(); } bool Vocations::reload() { clear(); return loadFromXml(); }
bool Vocations::loadFromXml() { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("data/XML/vocations.xml"); if (!result) { std::cout << "[Error - Vocations::loadFromXml] Failed to load data/XML/vocations.xml: " << result.description() << std::endl; return false; } for (pugi::xml_node vocationNode = doc.child("vocations").first_child(); vocationNode; vocationNode = vocationNode.next_sibling()) { pugi::xml_attribute attr; if (!(attr = vocationNode.attribute("id"))) { std::cout << "[Warning - Vocations::loadFromXml] Missing vocation id" << std::endl; continue; } uint16_t id = pugi::cast<uint16_t>(attr.value()); // TODO: Use emplace ( auto res = vocationsMap.emplace(id, id); Vocation& voc = res.first->second; ) vocationsMap[id] = Vocation(id); Vocation& voc = vocationsMap[id]; if ((attr = vocationNode.attribute("name"))) { voc.name = attr.as_string(); } if ((attr = vocationNode.attribute("clientid"))) { voc.clientId = pugi::cast<uint16_t>(attr.value()); } if ((attr = vocationNode.attribute("description"))) { voc.description = attr.as_string(); } if ((attr = vocationNode.attribute("gaincap"))) { voc.gainCap = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainhp"))) { voc.gainHP = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainmana"))) { voc.gainMana = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainhpticks"))) { voc.gainHealthTicks = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainhpamount"))) { voc.gainHealthAmount = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainmanaticks"))) { voc.gainManaTicks = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("gainmanaamount"))) { voc.gainManaAmount = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("manamultiplier"))) { voc.manaMultiplier = pugi::cast<float>(attr.value()); } if ((attr = vocationNode.attribute("attackspeed"))) { voc.attackSpeed = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("basespeed"))) { voc.baseSpeed = pugi::cast<uint32_t>(attr.value()); } if ((attr = vocationNode.attribute("soulmax"))) { voc.soulMax = pugi::cast<uint16_t>(attr.value()); } if ((attr = vocationNode.attribute("gainsoulticks"))) { voc.gainSoulTicks = pugi::cast<uint16_t>(attr.value()); } if ((attr = vocationNode.attribute("fromvoc"))) { voc.fromVocation = pugi::cast<uint32_t>(attr.value()); } for (pugi::xml_node childNode = vocationNode.first_child(); childNode; childNode = childNode.next_sibling()) { if (strcasecmp(childNode.name(), "skill") == 0) { pugi::xml_attribute skillIdAttribute = childNode.attribute("id"); if (skillIdAttribute) { uint16_t skill_id = pugi::cast<uint16_t>(skillIdAttribute.value()); if (skill_id <= SKILL_LAST) { voc.skillMultipliers[skill_id] = pugi::cast<float>(childNode.attribute("multiplier").value()); } else { std::cout << "[Notice - Vocations::loadFromXml] No valid skill id: " << skill_id << " for vocation: " << voc.id << std::endl; } } else { std::cout << "[Notice - Vocations::loadFromXml] Missing skill id for vocation: " << voc.id << std::endl; } } else if (strcasecmp(childNode.name(), "formula") == 0) { pugi::xml_attribute meleeDamageAttribute = childNode.attribute("meleeDamage"); if (meleeDamageAttribute) { voc.meleeDamageMultiplier = pugi::cast<float>(meleeDamageAttribute.value()); } pugi::xml_attribute distDamageAttribute = childNode.attribute("distDamage"); if (distDamageAttribute) { voc.distDamageMultiplier = pugi::cast<float>(distDamageAttribute.value()); } pugi::xml_attribute defenseAttribute = childNode.attribute("defense"); if (defenseAttribute) { voc.defenseMultiplier = pugi::cast<float>(defenseAttribute.value()); } pugi::xml_attribute armorAttribute = childNode.attribute("armor"); if (armorAttribute) { voc.armorMultiplier = pugi::cast<float>(armorAttribute.value()); } } } } return true; }