void parse_predicates(pugi::xml_node node, config::config & conf) { size_t size = node.child("size").text().as_uint(); //cout << "predicates size: " << size << endl; conf.predicates.resize(size); conf.predicate_distribution = parse_distribution(node.child("distribution")); for (pugi::xml_node alias_node : node.children("alias")) { size_t id = alias_node.attribute("symbol").as_uint();// string name = alias_node.text().get(); //cout << "alias " << id << ", " << name << endl; if (id < 0 || id >= size) { cerr << "id " << id << " is out of range" << endl; continue; } conf.predicates[id].alias = name; } for (pugi::xml_node proportion_node : node.children("proportion")) { size_t id = proportion_node.attribute("symbol").as_uint(); double proportion = proportion_node.text().as_double(); if (id < 0 || id >= size) { cerr << "id " << id << " is out of range" << endl; continue; } conf.predicates[id].proportion = proportion; conf.predicates[id].size = (size_t) (proportion * conf.nb_edges); } }
void parseAtomAuthor(FeedAuthor& author, const pugi::xml_node &authorNode) { string nodeName = authorNode.name(); if (nodeName != "author") { throw ParseError("expected author node."); } bool haveDetailedAuthor = false; for (auto child: authorNode.children()) { haveDetailedAuthor = true; nodeName = child.name(); if (nodeName == "name") { getNodeContent(author.name, child); } else if (nodeName == "email") { getNodeContent(author.email, child); } else if (nodeName == "uri") { getNodeContent(author.link.url, child); } else if (nodeName == "link") { if (author.link.url.empty()) { getNodeContent(author.link.url, child); } } } if (!haveDetailedAuthor) { // the node is just a bare <author>NAME</author> element. getNodeContent(author.name, authorNode); } }
void parse_schema(pugi::xml_node node, config::config & conf) { for (pugi::xml_node source_node : node.children("source")) { size_t source_type = source_node.attribute("type").as_uint(); for (pugi::xml_node target_node : source_node.children("target")) { char multiplicity = '*'; size_t target_type = target_node.attribute("type").as_uint(); size_t symbol = target_node.attribute("symbol").as_uint(); string mult_string = target_node.attribute("multiplicity").value(); if (mult_string.size() > 0 && (mult_string[0] == '?' || mult_string[0] == '+' || mult_string[0] == '1')) { multiplicity = mult_string[0]; } pugi::xml_node outdistribution_node = target_node.child("outdistribution"); distribution outdistribution = parse_distribution(outdistribution_node); pugi::xml_node indistribution_node = target_node.child("indistribution"); distribution indistribution = parse_distribution(indistribution_node); if (multiplicity == '1') { // && outdistribution.type == DISTRIBUTION::UNDEFINED) { outdistribution = distribution(DISTRIBUTION::UNIFORM, 1, 1); } else if (multiplicity == '?') {// && outdistribution.type == DISTRIBUTION::UNDEFINED) { outdistribution = distribution(DISTRIBUTION::UNIFORM, 0, 1); } if(outdistribution.type == DISTRIBUTION::UNDEFINED) { outdistribution = distribution(DISTRIBUTION::ZIPFIAN, 0, 2.5); } conf.schema.add_edge(source_type, symbol, target_type, multiplicity, outdistribution, indistribution); //cout << "conf.add_edge " << source_type << " " << symbol << " " << target_type << " " << multiplicity << " " << outdistribution << " " << indistribution <<endl; } } }
std::unordered_map<std::string, gal::SensorResource> load_sensors(const pugi::xml_node& root) { std::unordered_map<std::string, gal::SensorResource> sensors; for (const auto& r : root.children("SensorResource")) { gal::SensorResource res; res.id = r.attribute("id").as_string(); res.type = static_cast<gal::EntitySensorDataType>(r.attribute("type").as_int()); res.description = r.child("Description").child_value(); res.scale = static_cast<gal::EntitySensorDataScale>(r.attribute("scale").as_int()); res.precision = static_cast<gal::EntitySensorPrecision>(r.attribute("precision").as_int()); res.refresh_rate = static_cast<gal::EntitySensorValueUpdateRate>(r.attribute("refresh_rate").as_int()); try { res.max_value = std::stoll(r.attribute("max").as_string()); } catch (std::exception& ex) { tnt::Log::error("load_sensors error (", res.id, "): ", ex.what(), " - attribute: ==>", r.attribute("max").as_string(), "<=="); } sensors.emplace(res.id, res); } return sensors; }
void Tileset::parseTerrainNode(const pugi::xml_node& node) { const auto& children = node.children(); for (const auto& child : children) { std::string name = child.name(); if (name == "terrain") { m_terrainTypes.emplace_back(); auto& terrain = m_terrainTypes.back(); terrain.name = child.attribute("name").as_string(); terrain.tileID = child.attribute("tile").as_int(); auto properties = child.child("properties"); if (properties) { for (const auto& p : properties) { name = p.name(); if (name == "property") { terrain.properties.emplace_back(); terrain.properties.back().parse(p); } } } } } }
bool GraphMLParser::readNodes( Graph &G, GraphAttributes *GA, const pugi::xml_node rootTag) { for(pugi::xml_node nodeTag : rootTag.children("node")) { pugi::xml_attribute idAttr = nodeTag.attribute("id"); if(!idAttr) { GraphIO::logger.lout() << "Node is missing id attribute." << endl; return false; } const node v = G.newNode(); m_nodeId[idAttr.value()] = v; // Search for data-key attributes if GA given. if(GA && !readAttributes(*GA, v, nodeTag)) { return false; } pugi::xml_node clusterTag = nodeTag.child("graph"); if (clusterTag) { GraphIO::logger.lout(Logger::LL_MINOR) << "Nested graphs are not fully supported." << endl; return readNodes(G, GA, clusterTag); } } return readEdges(G, GA, rootTag); }
void parseAtomFeed(Feed &feed, const pugi::xml_node &rootNode) { getNodeAttr(feed.metadata.language.name, rootNode, "lang"); string globalBase = getNodeAttr(rootNode, "base"); string name; for (auto node: rootNode.children()) { name = node.name(); if (name == "title") { feed.metadata.title = std::move(FeedData::fromXmlNode(node)); } else if (name == "id") { getNodeContent(feed.metadata.guid.id, node); } else if (name == "author") { parseAtomAuthor(feed.metadata.author, node); } else if (name == "subtitle") { feed.metadata.description = std::move(FeedData::fromXmlNode(node)); } else if (name == "link") { string rel = getNodeAttr(node, "rel"); if (rel == "alternate") { feed.metadata.link.url = url_util::make_absolute_url(globalBase, getNodeAttr(node, "href")); } } else if (name == "updated") { feed.metadata.pubDate = FeedDateTime::fromW3cDtf(node); } else if (name == "modified" || name == "created" || name == "issued") { if (feed.metadata.pubDate.empty()) { feed.metadata.pubDate = FeedDateTime::fromRfc822(node); } } else if (name == "entry") { feed.items.push_back(parseAtomFeedItem(node, globalBase)); } } }
void XMLSerializer::accept(std::function<void(const Node &)> visitor, const pugi::xml_node &node) { XMLNode xmlnode{node}; visitor(xmlnode); for (const auto &child : node.children()) { accept(visitor, child); } }
void Tileset::parsePropertyNode(const pugi::xml_node& node) { const auto& children = node.children(); for (const auto& child : children) { m_properties.emplace_back(); m_properties.back().parse(child); } }
void Monsters::loadLootContainer(const pugi::xml_node& node, LootBlock& lBlock) { for (auto subNode : node.children()) { LootBlock lootBlock; if (loadLootItem(subNode, lootBlock)) { lBlock.childLoot.emplace_back(std::move(lootBlock)); } } }
void parse_types(pugi::xml_node node, config::config & conf) { size_t size = node.child("size").text().as_uint(); //cout << "type size: " << size << endl; conf.types.resize(size); for (pugi::xml_node alias_node : node.children("alias")) { size_t id = alias_node.attribute("type").as_uint();// string name = alias_node.text().get(); //cout << "alias " << id << ", " << name << endl; if (id < 0 || id >= size) { cerr << "id " << id << " is out of range" << endl; continue; } conf.types[id].alias = name; } for (pugi::xml_node proportion_node : node.children("proportion")) { size_t id = proportion_node.attribute("type").as_uint(); double proportion = proportion_node.text().as_double(); //cout << "proportion " << id << ", " << proportion << endl; if (id < 0 || id >= size) { cerr << "id " << id << " is out of range" << endl; continue; } conf.types[id].size = (size_t) (proportion * conf.nb_nodes); conf.types[id].scalable = true; if (proportion * conf.nb_nodes > 0 && conf.types[id].size == 0) { conf.types[id].size = 1; } } for (pugi::xml_node fixed_node : node.children("fixed")) { size_t id = fixed_node.attribute("type").as_uint(); size_t size2 = fixed_node.text().as_uint(); //cout << "fixed " << id << ", " << size << endl; if (id < 0 || id >= size) { cerr << "id " << id << " is out of range" << endl; continue; } conf.types[id].size = size2; conf.types[id].scalable = false; } }
void ParseKeyRemapData( pugi::xml_node curnode, SMDLPresetConversionInfo::PresetConvData & pconv, dsepresetid_t preset, const string & trkname ) { using namespace pugi; using namespace cvinfoXML; for( auto & keyremap : curnode.children() ) { if( keyremap.name() == NODE_KeyRemap ) ParseAKeyRemap( keyremap, pconv, preset, trkname ); } }
void ParsePrograms( pugi::xml_node curnode, SMDLPresetConversionInfo & convinf, const string & trkname ) { using namespace pugi; using namespace cvinfoXML; for( auto & prgnode : curnode.children() ) { if( prgnode.name() == NODE_Program ) ParseAProgram( prgnode, convinf, trkname ); } }
void ParseAKeyRemap( pugi::xml_node curnode, SMDLPresetConversionInfo::PresetConvData & pconv, dsepresetid_t preset, const string & trkname ) { using namespace pugi; using namespace cvinfoXML; midinote_t inkey = InvalidMIDIKey; midinote_t outkey = InvalidMIDIKey; presetid_t midprg = InvalidPresetID; bankid_t midbnk = InvalidBankID; uint8_t idealchan = UCHAR_MAX; for( auto & keyprop : curnode.children() ) { if( keyprop.name() == PROP_InKey ) inkey = utils::parseByte( keyprop.child_value() ); else if( keyprop.name() == PROP_OutKey ) outkey = utils::parseByte( keyprop.child_value() ); else if( keyprop.name() == PROP_MIDIPrg ) midprg = utils::parseByte( keyprop.child_value() ) - 1; //Bring back onto 0-127 else if( keyprop.name() == PROP_MIDIBnk ) utils::parseHexaValToValue( keyprop.child_value(), midbnk ); else if( keyprop.name() == PROP_ForceChan ) idealchan = ( utils::parseByte( keyprop.child_value() ) - 1); //Bring back to 0-15 } if( inkey != InvalidMIDIKey && outkey != InvalidMIDIKey ) { SMDLPresetConversionInfo::NoteRemapData rmap; rmap.destnote = outkey; if( midprg != InvalidPresetID ) { if( midprg >= 0 && midprg <= CHAR_MAX ) rmap.destpreset = midprg; else clog << "#CVInfoParser : Forced preset for preset " <<preset <<" for key " <<inkey << " for track " <<trkname << " was not one of the valid 127 MIDI presets! Ignoring!\n"; } if( midbnk != InvalidBankID ) { rmap.destbank = midbnk; } if( idealchan != UCHAR_MAX ) { if( idealchan < NbMidiChannels ) rmap.idealchan = idealchan; else clog << "#CVInfoParser : Forced channel for preset " <<preset <<" for key " <<inkey <<" for track " <<trkname << " was not one of the valid 16 MIDI channel! Ignoring!\n"; } pconv.remapnotes.insert( make_pair( inkey, rmap ) ); } }
void ParseAProgram( pugi::xml_node curnode, SMDLPresetConversionInfo & convinf, const string & trkname ) { using namespace pugi; using namespace cvinfoXML; SMDLPresetConversionInfo::PresetConvData pconv; stringstream sstrparse; dsepresetid_t dseid = InvalidDSEPresetID; for( auto & progprop : curnode.children() ) { if( progprop.name() == PROP_DSEID ) utils::parseHexaValToValue( progprop.child_value(), dseid ); else if( progprop.name() == PROP_MIDIPrg ) pconv.midipres = utils::parseByte( progprop.child_value() ) - 1; //Bring back onto 0-127 else if( progprop.name() == PROP_MIDIBnk ) utils::parseHexaValToValue( progprop.child_value(), pconv.midibank ); else if( progprop.name() == PROP_MaxKeyDown ) utils::parseHexaValToValue( progprop.child_value(), pconv.maxkeydowndur ); else if( progprop.name() == PROP_Transpose ) pconv.transpose = utils::parseSignedByte( progprop.child_value() ); else if( progprop.name() == PROP_ForceChan ) pconv.idealchan = (utils::parseByte( progprop.child_value() ) - 1); //Bring back to 0-15 from 1-16 else if( progprop.name() == NODE_KeyRemaps ) { ParseKeyRemapData( progprop, pconv, dseid, trkname ); } } if( dseid != InvalidDSEPresetID ) { if( pconv.midipres != InvalidPresetID && pconv.midipres > CHAR_MAX ) { clog << "#CVInfoParser : Forced preset for preset " <<dseid << " for track " <<trkname << " was not one of the valid 127 MIDI presets! Ignoring!\n"; pconv.midipres = InvalidPresetID; } if( pconv.idealchan != UCHAR_MAX && pconv.idealchan >= NbMidiChannels ) { clog << "#CVInfoParser : Forced channel for preset " <<dseid <<" for track " <<trkname << " was not one of the valid 16 MIDI channel! Ignoring!\n"; pconv.idealchan = UCHAR_MAX; } } if( dseid != InvalidDSEPresetID ) convinf.AddPresetConvInfo( dseid, move(pconv) ); else clog << "<!>- Ignored a " <<NODE_Program <<" node because there was no DSE program ID specified!\n"; }
void parse_workloads(pugi::xml_node node, config::config & conf) { for (pugi::xml_node workload_node : node.children("workload")) { config::workload workload; workload.id = workload_node.attribute("id").as_uint(); workload.size = workload_node.attribute("size").as_uint(); pugi::xml_node arity_node = workload_node.child("arity"); size_t arity_min = arity_node.attribute("min").as_uint(); size_t arity_max = arity_node.attribute("max").as_uint(); workload.arity = make_pair(arity_min, arity_max); workload.multiplicity = workload_node.child("multiplicity").attribute("star").as_double(); pugi::xml_node size_node = workload_node.child("size"); pugi::xml_node conjuncts_node = size_node.child("conjuncts"); size_t conjuncts_min = conjuncts_node.attribute("min").as_uint(); size_t conjuncts_max = conjuncts_node.attribute("max").as_uint(); workload.conjuncts = make_pair(conjuncts_min, conjuncts_max); pugi::xml_node disjuncts_node = size_node.child("disjuncts"); size_t disjuncts_min = disjuncts_node.attribute("min").as_uint(); size_t disjuncts_max = disjuncts_node.attribute("max").as_uint(); workload.disjuncts = make_pair(disjuncts_min, disjuncts_max); pugi::xml_node length_node = size_node.child("length"); size_t length_min = length_node.attribute("min").as_uint(); size_t length_max = length_node.attribute("max").as_uint(); workload.length = make_pair(length_min, length_max); pugi::xml_node type_node = workload_node.child("type"); workload.type.chain = type_node.attribute("chain").as_bool(); workload.type.star = type_node.attribute("star").as_bool(); workload.type.cycle = type_node.attribute("cycle").as_bool(); workload.type.starchain = type_node.attribute("starchain").as_bool(); pugi::xml_node output_node = workload_node.child("output"); workload.output.sparql = output_node.attribute("sparql").as_bool(); workload.output.postgres = output_node.attribute("postgres").as_bool(); workload.output.cypher = output_node.attribute("cypher").as_bool(); pugi::xml_node selectivity_node = workload_node.child("selectivity"); workload.selectivity.constant = selectivity_node.attribute("constant").as_bool(); workload.selectivity.linear = selectivity_node.attribute("linear").as_bool(); workload.selectivity.quadratic = selectivity_node.attribute("quadratic").as_bool(); conf.workloads.push_back(workload); } }
void XmlTools::CopyXmlNode(const pugi::xml_node& srcNode, pugi::xml_node& dstNode) { for (const pugi::xml_attribute& attr : srcNode.attributes()) { auto attrCopy = dstNode.append_attribute(attr.name()); attrCopy.set_value(attr.value()); } for (const pugi::xml_node& node : srcNode.children()) { auto nodeCopy = dstNode.append_child(node.name()); CopyXmlNode(node, nodeCopy); } auto nodeText = srcNode.text(); dstNode.text().set(nodeText.as_string()); }
void Material::Parse( pugi::xml_node Node ) { //Node -> <material name="Nazwa_Mat" > for( const auto &Child : Node.children() ) { if( !strcmp( Child.name(), "pass" ) ) { // tworz nowy pass RenderPass *Pass = new RenderPass(); Pass->Parse( Child ); pRenderPass = Pass; } } }
CXmlNode::CXmlNode(CXmlNode* _parent , const pugi::xml_node& rowData ) { this->nodeData.parent=NULL; if(rowData!=NULL) { nodeData.nodeName=rowData.name(); for (auto &&item : rowData.attributes()) { AddProperty(item.name(), item.value()); } for (auto &&child : rowData.children()) { CXmlNode* newChild = new CXmlNode(this, child); this->nodeData.children.push_back(newChild); } } this->nodeData.parent=_parent; }
bool Path::Load(pugi::xml_node const& aPathNode) { mName = aPathNode.attribute("name").value(); mStartPosition.x = static_cast<float>(aPathNode.child("start_point").attribute("x").as_float()); mStartPosition.y = static_cast<float>(aPathNode.child("start_point").attribute("y").as_int()); for(pugi::xml_node const& aOrderNode : aPathNode.children("order")) { Order o; if(!o.Load(aOrderNode)) { std::cout << "Could not load order on path" << std::endl; assert(0); return false; } mOrders.push_back(o); } return true; }
DebuggerRoot::DebuggerRoot(Emulator *emu, const pugi::xml_node &node) : _emu(emu), _widget(NULL) { wxASSERT(emu != NULL); pugi::xml_object_range<pugi::xml_node_iterator> children = node.children(); int pos = 0; for (pugi::xml_node_iterator iChild = children.begin(); iChild != children.end(); ++iChild) { Item item; item.element = GetElement(emu, *iChild); item.proportion = iChild->attribute("prop").as_int(0); if (item.element != NULL) { _items.push_back(item); } } }
bool GraphMLParser::readEdges( Graph &G, GraphAttributes *GA, const pugi::xml_node rootTag) { for (pugi::xml_node edgeTag : rootTag.children("edge")) { pugi::xml_attribute sourceId = edgeTag.attribute("source"); pugi::xml_attribute targetId = edgeTag.attribute("target"); if (!sourceId) { GraphIO::logger.lout() << "Edge is missing source node." << endl; return false; } if (!targetId) { GraphIO::logger.lout() << "Edge is missing target node." << endl; return false; } auto sourceIt = m_nodeId.find(sourceId.value()); if (sourceIt == std::end(m_nodeId)) { GraphIO::logger.lout() << "Edge source node \"" << sourceId.value() << "\" is incorrect.\n" << endl; return false; } auto targetIt = m_nodeId.find(targetId.value()); if (targetIt == std::end(m_nodeId)) { GraphIO::logger.lout() << "Edge source node \"" << targetId.value() << "\" is incorrect.\n" << endl; return false; } const edge e = G.newEdge(sourceIt->second, targetIt->second); // Search for data-key attributes if GA given, return false on error. if(GA && !readAttributes(*GA, e, edgeTag)) { return false; } } return true; }
FeedItem parseAtomFeedItem(const pugi::xml_node &entryNode, const std::string &defaultGlobalBase) { FeedItem feedItem; std::string base = getNodeAttr(entryNode, "base"); if (base == "") { base = defaultGlobalBase; } string name; for (auto node: entryNode.children()) { name = node.name(); if (name == "author") { parseAtomAuthor(feedItem.author, node); } else if (name == "title") { feedItem.title = FeedData::fromXmlNode(node); } else if (name == "content") { feedItem.description = FeedData::fromXmlNode(node); } else if (name == "id") { getNodeContent(feedItem.guid.guid.id, node); feedItem.guid.isPermaLink = false; } else if (name == "published") { feedItem.pubDate = FeedDateTime::fromW3cDtf(node); } else if (name == "updated" || name == "created" || name == "issued" || name == "modified") { if (feedItem.pubDate.empty()) { feedItem.pubDate = FeedDateTime::fromRfc822(node); } } else if (name == "link") { string rel = getNodeAttr(node, "rel"); if (rel == "" || rel == "alternate") { feedItem.link.url = url_util::make_absolute_url(base, getNodeAttr(node, "href")); } else if (rel == "enclosure") { getNodeAttr(feedItem.enclosure.link.url, node, "href"); getNodeAttr(feedItem.enclosure.link.dtype, node, "type"); } } else if (name == "summary") { feedItem.summary = FeedData::fromXmlNode(node); } else if (name == "category") { if (getNodeAttr(node, "scheme") == "http://www.google.com/reader/") { feedItem.labels.push_back(getNodeAttr(node, "label")); } } } return feedItem; }
bool GraphMLParser::readClusters( Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, const cluster &rootCluster, const pugi::xml_node rootTag) { for(pugi::xml_node nodeTag : rootTag.children("node")) { pugi::xml_attribute idAttr = nodeTag.attribute("id"); pugi::xml_node clusterTag = nodeTag.child("graph"); if (clusterTag == nullptr) { // Got normal node then, add it to the graph - id is required. if (!idAttr) { GraphIO::logger.lout() << "Node is missing id attribute." << endl; return false; } const node v = G.newNode(); m_nodeId[idAttr.value()] = v; C.reassignNode(v, rootCluster); // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, v, nodeTag)) { return false; } } else { // Got a cluster node - read it recursively. const cluster c = C.newCluster(rootCluster); if (!readClusters(G, C, CA, c, clusterTag)) { return false; } // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, c, nodeTag)) { return false; } } } return readEdges(G, CA, rootTag); }
void ParseRemapEntry( pugi::xml_node curnode ) { using namespace pugi; using namespace cvinfoXML; SMDLPresetConversionInfo info; string pairname; for( auto & propnode : curnode.children() ) { if( propnode.name() == PROP_PairName ) pairname = propnode.child_value(); else if( propnode.name() == PROP_OutName ) info.SetOutputName( propnode.child_value() ); else if( propnode.name() == NODE_Programs ) ParsePrograms( propnode, info, pairname ); } if( !pairname.empty() ) m_curdb.AddConversionInfo( pairname, move(info) ); else clog <<"<!>- Ignored a remap entry while parsing the XML conversion info, because the name of the pair was empty or not specified!\n"; }
void RenderPass::Parse( pugi::xml_node Node ) { //parasowanie pass for( const auto &Child : Node.children() ) { if( !strcmp( Child.name(), "shader" ) ) { //wyszukaj shader i jak go nie ma ³aduj z pliku itp std::string ShaderName = Child.attribute( "name" ).as_string(); cProgramShader *Shader = cShaderManager::GetInstance()->GetProgram( ShaderName ); if( Shader == nullptr ) { Shader = cShaderManager::GetInstance()->Parse( Child ); } pShader = Shader; }else if( !strcmp( Child.name(), "sampler" ) ) { //sampler z tekstury std::string TextureName = Child.attribute( "texture").as_string(); uint Sampler = Child.attribute( "sampler" ).as_uint(); TEXTUREFILTER TfMin = CheckTextureFilter( Child.attribute( "min_filter" ).as_string() ); TEXTUREFILTER TfMag = CheckTextureFilter( Child.attribute( "mag_filter" ).as_string( ) ); WRAPMODE WmS = CheckWrapMode( Child.attribute( "wrap_s" ).as_string() ); WRAPMODE WmT = CheckWrapMode( Child.attribute( "wrap_t" ).as_string() ); TextureManager *TexMgr = TextureManager::GetSingletonPtr(); Texture2D *Tex = TexMgr->GetTexturePtr( TextureName ); if( Tex == nullptr ) { std::cerr << "blad"; } TextureSampler *TexSampler = new TextureSampler( Tex, Sampler, TfMin, TfMag, WmS, WmT ); TexSampler->Update(); mTextures.push_back( TexSampler ); } } }
void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) { if (id > 30000 && id < 30100) { id -= 30000; if (id >= items.size()) { items.resize(id + 1); } ItemType& iType = items[id]; iType.id = id; } ItemType& it = getItemType(id); if (it.id == 0) { return; } it.name = itemNode.attribute("name").as_string(); pugi::xml_attribute articleAttribute = itemNode.attribute("article"); if (articleAttribute) { it.article = articleAttribute.as_string(); } pugi::xml_attribute pluralAttribute = itemNode.attribute("plural"); if (pluralAttribute) { it.pluralName = pluralAttribute.as_string(); } for (auto attributeNode : itemNode.children()) { pugi::xml_attribute keyAttribute = attributeNode.attribute("key"); if (!keyAttribute) { continue; } pugi::xml_attribute valueAttribute = attributeNode.attribute("value"); if (!valueAttribute) { continue; } std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string()); if (tmpStrValue == "type") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "key") { it.type = ITEM_TYPE_KEY; } else if (tmpStrValue == "magicfield") { it.type = ITEM_TYPE_MAGICFIELD; } else if (tmpStrValue == "container") { it.group = ITEM_GROUP_CONTAINER; it.type = ITEM_TYPE_CONTAINER; } else if (tmpStrValue == "depot") { it.type = ITEM_TYPE_DEPOT; } else if (tmpStrValue == "mailbox") { it.type = ITEM_TYPE_MAILBOX; } else if (tmpStrValue == "trashholder") { it.type = ITEM_TYPE_TRASHHOLDER; } else if (tmpStrValue == "teleport") { it.type = ITEM_TYPE_TELEPORT; } else if (tmpStrValue == "door") { it.type = ITEM_TYPE_DOOR; } else if (tmpStrValue == "bed") { it.type = ITEM_TYPE_BED; } else if (tmpStrValue == "rune") { it.type = ITEM_TYPE_RUNE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "description") { it.description = valueAttribute.as_string(); } else if (tmpStrValue == "runespellname") { it.runeSpellName = valueAttribute.as_string(); } else if (tmpStrValue == "weight") { it.weight = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showcount") { it.showCount = valueAttribute.as_bool(); } else if (tmpStrValue == "armor") { it.armor = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "defense") { it.defense = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "extradef") { it.extraDefense = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "attack") { it.attack = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "rotateto") { it.rotateTo = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "moveable" || tmpStrValue == "movable") { it.moveable = valueAttribute.as_bool(); } else if (tmpStrValue == "blockprojectile") { it.blockProjectile = valueAttribute.as_bool(); } else if (tmpStrValue == "allowpickupable" || tmpStrValue == "pickupable") { it.allowPickupable = valueAttribute.as_bool(); } else if (tmpStrValue == "floorchange") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "down") { it.floorChange = TILESTATE_FLOORCHANGE_DOWN; } else if (tmpStrValue == "north") { it.floorChange = TILESTATE_FLOORCHANGE_NORTH; } else if (tmpStrValue == "south") { it.floorChange = TILESTATE_FLOORCHANGE_SOUTH; } else if (tmpStrValue == "southalt") { it.floorChange = TILESTATE_FLOORCHANGE_SOUTH_ALT; } else if (tmpStrValue == "west") { it.floorChange = TILESTATE_FLOORCHANGE_WEST; } else if (tmpStrValue == "east") { it.floorChange = TILESTATE_FLOORCHANGE_EAST; } else if (tmpStrValue == "eastalt") { it.floorChange = TILESTATE_FLOORCHANGE_EAST_ALT; } else { std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "corpsetype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "venom") { it.corpseType = RACE_VENOM; } else if (tmpStrValue == "blood") { it.corpseType = RACE_BLOOD; } else if (tmpStrValue == "undead") { it.corpseType = RACE_UNDEAD; } else if (tmpStrValue == "fire") { it.corpseType = RACE_FIRE; } else if (tmpStrValue == "energy") { it.corpseType = RACE_ENERGY; } else { std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "containersize") { it.maxItems = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "fluidsource") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "water") { it.fluidSource = FLUID_WATER; } else if (tmpStrValue == "blood") { it.fluidSource = FLUID_BLOOD; } else if (tmpStrValue == "beer") { it.fluidSource = FLUID_BEER; } else if (tmpStrValue == "slime") { it.fluidSource = FLUID_SLIME; } else if (tmpStrValue == "lemonade") { it.fluidSource = FLUID_LEMONADE; } else if (tmpStrValue == "milk") { it.fluidSource = FLUID_MILK; } else if (tmpStrValue == "mana") { it.fluidSource = FLUID_MANA; } else if (tmpStrValue == "life") { it.fluidSource = FLUID_LIFE; } else if (tmpStrValue == "oil") { it.fluidSource = FLUID_OIL; } else if (tmpStrValue == "urine") { it.fluidSource = FLUID_URINE; } else if (tmpStrValue == "coconut") { it.fluidSource = FLUID_COCONUTMILK; } else if (tmpStrValue == "wine") { it.fluidSource = FLUID_WINE; } else if (tmpStrValue == "mud") { it.fluidSource = FLUID_MUD; } else if (tmpStrValue == "fruitjuice") { it.fluidSource = FLUID_FRUITJUICE; } else if (tmpStrValue == "lava") { it.fluidSource = FLUID_LAVA; } else if (tmpStrValue == "rum") { it.fluidSource = FLUID_RUM; } else if (tmpStrValue == "swamp") { it.fluidSource = FLUID_SWAMP; } else if (tmpStrValue == "tea") { it.fluidSource = FLUID_TEA; } else if (tmpStrValue == "mead") { it.fluidSource = FLUID_MEAD; } else { std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "readable") { it.canReadText = valueAttribute.as_bool(); } else if (tmpStrValue == "writeable") { it.canWriteText = valueAttribute.as_bool(); it.canReadText = it.canWriteText; } else if (tmpStrValue == "maxtextlen") { it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "writeonceitemid") { it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "weapontype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "sword") { it.weaponType = WEAPON_SWORD; } else if (tmpStrValue == "club") { it.weaponType = WEAPON_CLUB; } else if (tmpStrValue == "axe") { it.weaponType = WEAPON_AXE; } else if (tmpStrValue == "shield") { it.weaponType = WEAPON_SHIELD; } else if (tmpStrValue == "distance") { it.weaponType = WEAPON_DISTANCE; } else if (tmpStrValue == "wand") { it.weaponType = WEAPON_WAND; } else if (tmpStrValue == "ammunition") { it.weaponType = WEAPON_AMMO; } else { std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "slottype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "head") { it.slotPosition |= SLOTP_HEAD; } else if (tmpStrValue == "body") { it.slotPosition |= SLOTP_ARMOR; } else if (tmpStrValue == "legs") { it.slotPosition |= SLOTP_LEGS; } else if (tmpStrValue == "feet") { it.slotPosition |= SLOTP_FEET; } else if (tmpStrValue == "backpack") { it.slotPosition |= SLOTP_BACKPACK; } else if (tmpStrValue == "two-handed") { it.slotPosition |= SLOTP_TWO_HAND; } else if (tmpStrValue == "right-hand") { it.slotPosition &= ~SLOTP_LEFT; } else if (tmpStrValue == "left-hand") { it.slotPosition &= ~SLOTP_RIGHT; } else if (tmpStrValue == "necklace") { it.slotPosition |= SLOTP_NECKLACE; } else if (tmpStrValue == "ring") { it.slotPosition |= SLOTP_RING; } else if (tmpStrValue == "ammo") { it.slotPosition |= SLOTP_AMMO; } else if (tmpStrValue == "hand") { it.slotPosition |= SLOTP_HAND; } else { std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "ammotype") { it.ammoType = getAmmoType(valueAttribute.as_string()); if (it.ammoType == AMMO_NONE) { std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "shoottype") { ShootType_t shoot = getShootType(valueAttribute.as_string()); if (shoot != CONST_ANI_NONE) { it.shootType = shoot; } else { std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "effect") { MagicEffectClasses effect = getMagicEffect(valueAttribute.as_string()); if (effect != CONST_ME_NONE) { it.magicEffect = effect; } else { std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "range") { it.shootRange = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "stopduration") { it.stopTime = valueAttribute.as_bool(); } else if (tmpStrValue == "decayto") { it.decayTo = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "transformequipto") { it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "transformdeequipto") { it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "duration") { it.decayTime = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showduration") { it.showDuration = valueAttribute.as_bool(); } else if (tmpStrValue == "charges") { it.charges = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showcharges") { it.showCharges = valueAttribute.as_bool(); } else if (tmpStrValue == "showattributes") { it.showAttributes = valueAttribute.as_bool(); } else if (tmpStrValue == "hitchance") { it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value()))); } else if (tmpStrValue == "maxhitchance") { it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value())); } else if (tmpStrValue == "invisible") { it.getAbilities().invisible = valueAttribute.as_bool(); } else if (tmpStrValue == "speed") { it.getAbilities().speed = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "healthgain") { Abilities& abilities = it.getAbilities(); abilities.regeneration = true; abilities.healthGain = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "healthticks") { Abilities& abilities = it.getAbilities(); abilities.regeneration = true; abilities.healthTicks = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "managain") { Abilities& abilities = it.getAbilities(); abilities.regeneration = true; abilities.manaGain = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "manaticks") { Abilities& abilities = it.getAbilities(); abilities.regeneration = true; abilities.manaTicks = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "manashield") { it.getAbilities().manaShield = valueAttribute.as_bool(); } else if (tmpStrValue == "skillsword") { it.getAbilities().skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillaxe") { it.getAbilities().skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillclub") { it.getAbilities().skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skilldist") { it.getAbilities().skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillfish") { it.getAbilities().skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillshield") { it.getAbilities().skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillfist") { it.getAbilities().skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxhitpoints") { it.getAbilities().stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxhitpointspercent") { it.getAbilities().statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxmanapoints") { it.getAbilities().stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxmanapointspercent") { it.getAbilities().statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "magicpoints" || tmpStrValue == "magiclevelpoints") { it.getAbilities().stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "magicpointspercent") { it.getAbilities().statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentenergy") { it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentfire") { it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentpoison" || tmpStrValue == "fieldabsorpercentearth") { it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentall" || tmpStrValue == "absorbpercentallelements") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities& abilities = it.getAbilities(); for (size_t i = 0; i < COMBAT_COUNT; ++i) { abilities.absorbPercent[i] += value; } } else if (tmpStrValue == "absorbpercentelements") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities& abilities = it.getAbilities(); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; } else if (tmpStrValue == "absorbpercentmagic") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities& abilities = it.getAbilities(); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; } else if (tmpStrValue == "absorbpercentenergy") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentfire") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentpoison" || tmpStrValue == "absorbpercentearth") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentlifedrain") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentmanadrain") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentdrown") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentphysical") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercenthealing") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentundefined") { it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "suppressdrunk") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_DRUNK; } } else if (tmpStrValue == "suppressenergy") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_ENERGY; } } else if (tmpStrValue == "suppressfire") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_FIRE; } } else if (tmpStrValue == "suppresspoison") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_POISON; } } else if (tmpStrValue == "suppressdrown") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_DROWN; } } else if (tmpStrValue == "suppressphysical") { if (valueAttribute.as_bool()) { it.getAbilities().conditionSuppressions |= CONDITION_BLEEDING; } } else if (tmpStrValue == "field") { it.group = ITEM_GROUP_MAGICFIELD; it.type = ITEM_TYPE_MAGICFIELD; CombatType_t combatType = COMBAT_NONE; ConditionDamage* conditionDamage = nullptr; tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "fire") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE); combatType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "energy") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY); combatType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "poison") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON); combatType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "drown") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN); combatType = COMBAT_DROWNDAMAGE; } else if (tmpStrValue == "physical") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING); combatType = COMBAT_PHYSICALDAMAGE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl; } if (combatType != COMBAT_NONE) { it.combatType = combatType; it.conditionDamage.reset(conditionDamage); uint32_t ticks = 0; int32_t damage = 0; int32_t start = 0; int32_t count = 1; for (auto subAttributeNode : attributeNode.children()) { pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key"); if (!subKeyAttribute) { continue; } pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value"); if (!subValueAttribute) { continue; } tmpStrValue = asLowerCaseString(subKeyAttribute.as_string()); if (tmpStrValue == "ticks") { ticks = pugi::cast<uint32_t>(subValueAttribute.value()); } else if (tmpStrValue == "count") { count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "start") { start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "damage") { damage = -pugi::cast<int32_t>(subValueAttribute.value()); if (start > 0) { std::list<int32_t> damageList; ConditionDamage::generateDamageList(damage, start, damageList); for (int32_t damageValue : damageList) { conditionDamage->addDamage(1, ticks, -damageValue); } start = 0; } else { conditionDamage->addDamage(count, ticks, damage); } } } conditionDamage->setParam(CONDITION_PARAM_FIELD, 1); if (conditionDamage->getTotalDamage() > 0) { conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1); } } } else if (tmpStrValue == "replaceable") { it.replaceable = valueAttribute.as_bool(); } else if (tmpStrValue == "partnerdirection") { it.bedPartnerDir = getDirection(valueAttribute.as_string()); } else if (tmpStrValue == "leveldoor") { it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "maletransformto" || tmpStrValue == "malesleeper") { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_MALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) { it.transformToOnUse[PLAYERSEX_FEMALE] = value; } } else if (tmpStrValue == "femaletransformto" || tmpStrValue == "femalesleeper") { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_FEMALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_MALE] == 0) { it.transformToOnUse[PLAYERSEX_MALE] = value; } } else if (tmpStrValue == "transformto") { it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "destroyto") { it.destroyTo = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "elementearth") { Abilities& abilities = it.getAbilities(); abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "elementfire") { Abilities& abilities = it.getAbilities(); abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "elementenergy") { Abilities& abilities = it.getAbilities(); abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "walkstack") { it.walkStack = valueAttribute.as_bool(); } else if (tmpStrValue == "blocking") { it.blockSolid = valueAttribute.as_bool(); } else if (tmpStrValue == "allowdistread") { it.allowDistRead = booleanString(valueAttribute.as_string()); } else { std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl; } } //check bed items if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) { std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl; } }
bool Weapon::configureEvent(const pugi::xml_node& node) { pugi::xml_attribute attr; if (!(attr = node.attribute("id"))) { std::cout << "[Error - Weapon::configureEvent] Weapon without id." << std::endl; return false; } id = pugi::cast<uint16_t>(attr.value()); if ((attr = node.attribute("level"))) { level = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("maglv")) || (attr = node.attribute("maglevel"))) { magLevel = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("mana"))) { mana = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("manapercent"))) { manaPercent = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("soul"))) { soul = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("prem"))) { premium = attr.as_bool(); } if ((attr = node.attribute("breakchance"))) { breakChance = std::min<uint8_t>(100, pugi::cast<uint16_t>(attr.value())); } if ((attr = node.attribute("action"))) { action = getWeaponAction(attr.as_string()); if (action == WEAPONACTION_NONE) { std::cout << "[Warning - Weapon::configureEvent] Unknown action " << attr.as_string() << std::endl; } } if ((attr = node.attribute("enabled"))) { enabled = attr.as_bool(); } if ((attr = node.attribute("unproperly"))) { wieldUnproperly = attr.as_bool(); } if ((attr = node.attribute("swing"))) { swing = attr.as_bool(); } std::list<std::string> vocStringList; for (auto vocationNode : node.children()) { if (!(attr = vocationNode.attribute("name"))) { continue; } int32_t vocationId = g_vocations.getVocationId(attr.as_string()); if (vocationId != -1) { vocWeaponMap[vocationId] = true; int32_t promotedVocation = g_vocations.getPromotedVocation(vocationId); if (promotedVocation != VOCATION_NONE) { vocWeaponMap[promotedVocation] = true; } if (vocationNode.attribute("showInDescription").as_bool(true)) { vocStringList.push_back(asLowerCaseString(attr.as_string())); } } } std::string vocationString; for (const std::string& str : vocStringList) { if (!vocationString.empty()) { if (str != vocStringList.back()) { vocationString.push_back(','); vocationString.push_back(' '); } else { vocationString += " and "; } } vocationString += str; vocationString.push_back('s'); } uint32_t wieldInfo = 0; if (getReqLevel() > 0) { wieldInfo |= WIELDINFO_LEVEL; } if (getReqMagLv() > 0) { wieldInfo |= WIELDINFO_MAGLV; } if (!vocationString.empty()) { wieldInfo |= WIELDINFO_VOCREQ; } if (isPremium()) { wieldInfo |= WIELDINFO_PREMIUM; } if (wieldInfo != 0) { ItemType& it = Item::items.getItemType(id); it.wieldInfo = wieldInfo; it.vocationString = vocationString; it.minReqLevel = getReqLevel(); it.minReqMagicLevel = getReqMagLv(); } configureWeapon(Item::items[id]); return true; }
bool Spell::configureSpell(const pugi::xml_node& node) { pugi::xml_attribute nameAttribute = node.attribute("name"); if (!nameAttribute) { std::cout << "[Error - Spell::configureSpell] Spell without name" << std::endl; return false; } name = nameAttribute.as_string(); static const char* reservedList[] = { "melee", "physical", "poison", "fire", "energy", "drown", "lifedrain", "manadrain", "healing", "speed", "outfit", "invisible", "drunk", "firefield", "poisonfield", "energyfield", "firecondition", "poisoncondition", "energycondition", "drowncondition", "freezecondition", "cursecondition", "dazzlecondition" }; //static size_t size = sizeof(reservedList) / sizeof(const char*); //for (size_t i = 0; i < size; ++i) { for (const char* reserved : reservedList) { if (strcasecmp(reserved, name.c_str()) == 0) { std::cout << "[Error - Spell::configureSpell] Spell is using a reserved name: " << reserved << std::endl; return false; } } pugi::xml_attribute attr; if ((attr = node.attribute("spellid"))) { spellId = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("group"))) { std::string tmpStr = asLowerCaseString(attr.as_string()); if (tmpStr == "none" || tmpStr == "0") { group = SPELLGROUP_NONE; } else if (tmpStr == "attack" || tmpStr == "1") { group = SPELLGROUP_ATTACK; } else if (tmpStr == "healing" || tmpStr == "2") { group = SPELLGROUP_HEALING; } else if (tmpStr == "support" || tmpStr == "3") { group = SPELLGROUP_SUPPORT; } else if (tmpStr == "special" || tmpStr == "4") { group = SPELLGROUP_SPECIAL; } else { std::cout << "[Warning - Spell::configureSpell] Unknown group: " << attr.as_string() << std::endl; } } if ((attr = node.attribute("groupcooldown"))) { groupCooldown = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("secondarygroup"))) { std::string tmpStr = asLowerCaseString(attr.as_string()); if (tmpStr == "none" || tmpStr == "0") { secondaryGroup = SPELLGROUP_NONE; } else if (tmpStr == "attack" || tmpStr == "1") { secondaryGroup = SPELLGROUP_ATTACK; } else if (tmpStr == "healing" || tmpStr == "2") { secondaryGroup = SPELLGROUP_HEALING; } else if (tmpStr == "support" || tmpStr == "3") { secondaryGroup = SPELLGROUP_SUPPORT; } else if (tmpStr == "special" || tmpStr == "4") { secondaryGroup = SPELLGROUP_SPECIAL; } else { std::cout << "[Warning - Spell::configureSpell] Unknown secondarygroup: " << attr.as_string() << std::endl; } } if ((attr = node.attribute("secondarygroupcooldown"))) { secondaryGroupCooldown = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("level")) || (attr = node.attribute("lvl"))) { level = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("magiclevel")) || (attr = node.attribute("maglv"))) { magLevel = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("mana"))) { mana = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("manapercent"))) { manaPercent = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("soul"))) { soul = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("range"))) { range = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("cooldown")) || (attr = node.attribute("exhaustion"))) { cooldown = pugi::cast<uint32_t>(attr.value()); } if ((attr = node.attribute("premium")) || (attr = node.attribute("prem"))) { premium = attr.as_bool(); } if ((attr = node.attribute("enabled"))) { enabled = attr.as_bool(); } if ((attr = node.attribute("needtarget"))) { needTarget = attr.as_bool(); } if ((attr = node.attribute("needweapon"))) { needWeapon = attr.as_bool(); } if ((attr = node.attribute("selftarget"))) { selfTarget = attr.as_bool(); } if ((attr = node.attribute("needlearn"))) { learnable = attr.as_bool(); } if ((attr = node.attribute("blocking"))) { blockingSolid = attr.as_bool(); blockingCreature = blockingSolid; } if ((attr = node.attribute("blocktype"))) { std::string tmpStrValue = asLowerCaseString(attr.as_string()); if (tmpStrValue == "all") { blockingSolid = true; blockingCreature = true; } else if (tmpStrValue == "solid") { blockingSolid = true; } else if (tmpStrValue == "creature") { blockingCreature = true; } else { std::cout << "[Warning - Spell::configureSpell] Blocktype \"" << attr.as_string() << "\" does not exist." << std::endl; } } if ((attr = node.attribute("aggressive"))) { aggressive = booleanString(attr.as_string()); } if (group == SPELLGROUP_NONE) { group = (aggressive ? SPELLGROUP_ATTACK : SPELLGROUP_HEALING); } for (auto vocationNode : node.children()) { if (!(attr = vocationNode.attribute("name"))) { continue; } int32_t vocationId = g_vocations.getVocationId(attr.as_string()); if (vocationId != -1) { attr = vocationNode.attribute("showInDescription"); vocSpellMap[vocationId] = !attr || attr.as_bool(); } else { std::cout << "[Warning - Spell::configureSpell] Wrong vocation name: " << attr.as_string() << std::endl; } } return true; }
void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) { if (id > 30000 && id < 30100) { id -= 30000; if (id >= items.size()) { items.resize(id + 1); } ItemType& iType = items[id]; iType.id = id; } ItemType& it = getItemType(id); if (it.id == 0) { return; } it.name = itemNode.attribute("name").as_string(); nameToItems.insert({ asLowerCaseString(it.name), id }); pugi::xml_attribute articleAttribute = itemNode.attribute("article"); if (articleAttribute) { it.article = articleAttribute.as_string(); } pugi::xml_attribute pluralAttribute = itemNode.attribute("plural"); if (pluralAttribute) { it.pluralName = pluralAttribute.as_string(); } Abilities& abilities = it.getAbilities(); for (auto attributeNode : itemNode.children()) { pugi::xml_attribute keyAttribute = attributeNode.attribute("key"); if (!keyAttribute) { continue; } pugi::xml_attribute valueAttribute = attributeNode.attribute("value"); if (!valueAttribute) { continue; } std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string()); auto parseAttribute = ItemParseAttributesMap.find(tmpStrValue); if (parseAttribute != ItemParseAttributesMap.end()) { ItemParseAttributes_t parseType = parseAttribute->second; switch (parseType) { case ITEM_PARSE_TYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = ItemTypesMap.find(tmpStrValue); if (it2 != ItemTypesMap.end()) { it.type = it2->second; if (it.type == ITEM_TYPE_CONTAINER) { it.group = ITEM_GROUP_CONTAINER; } } else { std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_DESCRIPTION: { it.description = valueAttribute.as_string(); break; } case ITEM_PARSE_RUNESPELLNAME: { it.runeSpellName = valueAttribute.as_string(); break; } case ITEM_PARSE_WEIGHT: { it.weight = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWCOUNT: { it.showCount = valueAttribute.as_bool(); break; } case ITEM_PARSE_ARMOR: { it.armor = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_DEFENSE: { it.defense = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_EXTRADEF: { it.extraDefense = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_ATTACK: { it.attack = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_ROTATETO: { it.rotateTo = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MOVEABLE: { it.moveable = valueAttribute.as_bool(); break; } case ITEM_PARSE_BLOCKPROJECTILE: { it.blockProjectile = valueAttribute.as_bool(); break; } case ITEM_PARSE_PICKUPABLE: { it.allowPickupable = valueAttribute.as_bool(); break; } case ITEM_PARSE_FORCESERIALIZE: { it.forceSerialize = valueAttribute.as_bool(); break; } case ITEM_PARSE_FLOORCHANGE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = TileStatesMap.find(tmpStrValue); if (it2 != TileStatesMap.end()) { it.floorChange = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_CORPSETYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = RaceTypesMap.find(tmpStrValue); if (it2 != RaceTypesMap.end()) { it.corpseType = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_CONTAINERSIZE: { it.maxItems = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FLUIDSOURCE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = FluidTypesMap.find(tmpStrValue); if (it2 != FluidTypesMap.end()) { it.fluidSource = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_READABLE: { it.canReadText = valueAttribute.as_bool(); break; } case ITEM_PARSE_WRITEABLE: { it.canWriteText = valueAttribute.as_bool(); it.canReadText = it.canWriteText; break; } case ITEM_PARSE_MAXTEXTLEN: { it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_WRITEONCEITEMID: { it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_WEAPONTYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = WeaponTypesMap.find(tmpStrValue); if (it2 != WeaponTypesMap.end()) { it.weaponType = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_SLOTTYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "head") { it.slotPosition |= SLOTP_HEAD; } else if (tmpStrValue == "body") { it.slotPosition |= SLOTP_ARMOR; } else if (tmpStrValue == "legs") { it.slotPosition |= SLOTP_LEGS; } else if (tmpStrValue == "feet") { it.slotPosition |= SLOTP_FEET; } else if (tmpStrValue == "backpack") { it.slotPosition |= SLOTP_BACKPACK; } else if (tmpStrValue == "two-handed") { it.slotPosition |= SLOTP_TWO_HAND; } else if (tmpStrValue == "right-hand") { it.slotPosition &= ~SLOTP_LEFT; } else if (tmpStrValue == "left-hand") { it.slotPosition &= ~SLOTP_RIGHT; } else if (tmpStrValue == "necklace") { it.slotPosition |= SLOTP_NECKLACE; } else if (tmpStrValue == "ring") { it.slotPosition |= SLOTP_RING; } else if (tmpStrValue == "ammo") { it.slotPosition |= SLOTP_AMMO; } else if (tmpStrValue == "hand") { it.slotPosition |= SLOTP_HAND; } else { std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_AMMOTYPE: { it.ammoType = getAmmoType(asLowerCaseString(valueAttribute.as_string())); if (it.ammoType == AMMO_NONE) { std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_SHOOTTYPE: { ShootType_t shoot = getShootType(asLowerCaseString(valueAttribute.as_string())); if (shoot != CONST_ANI_NONE) { it.shootType = shoot; } else { std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_EFFECT: { MagicEffectClasses effect = getMagicEffect(asLowerCaseString(valueAttribute.as_string())); if (effect != CONST_ME_NONE) { it.magicEffect = effect; } else { std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_RANGE: { it.shootRange = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_STOPDURATION: { it.stopTime = valueAttribute.as_bool(); break; } case ITEM_PARSE_DECAYTO: { it.decayTo = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_TRANSFORMEQUIPTO: { it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_TRANSFORMDEEQUIPTO: { it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_DURATION: { it.decayTime = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWDURATION: { it.showDuration = valueAttribute.as_bool(); break; } case ITEM_PARSE_CHARGES: { it.charges = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWCHARGES: { it.showCharges = valueAttribute.as_bool(); break; } case ITEM_PARSE_SHOWATTRIBUTES: { it.showAttributes = valueAttribute.as_bool(); break; } case ITEM_PARSE_HITCHANCE: { it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value()))); break; } case ITEM_PARSE_MAXHITCHANCE: { it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value())); break; } case ITEM_PARSE_INVISIBLE: { abilities.invisible = valueAttribute.as_bool(); break; } case ITEM_PARSE_SPEED: { abilities.speed = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_HEALTHGAIN: { abilities.regeneration = true; abilities.healthGain = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_HEALTHTICKS: { abilities.regeneration = true; abilities.healthTicks = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANAGAIN: { abilities.regeneration = true; abilities.manaGain = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANATICKS: { abilities.regeneration = true; abilities.manaTicks = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANASHIELD: { abilities.manaShield = valueAttribute.as_bool(); break; } case ITEM_PARSE_SKILLSWORD: { abilities.skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLAXE: { abilities.skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLCLUB: { abilities.skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLDIST: { abilities.skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLFISH: { abilities.skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLSHIELD: { abilities.skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLFIST: { abilities.skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXHITPOINTS: { abilities.stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXHITPOINTSPERCENT: { abilities.statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXMANAPOINTS: { abilities.stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXMANAPOINTSPERCENT: { abilities.statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAGICPOINTS: { abilities.stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAGICPOINTSPERCENT: { abilities.statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTENERGY: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTFIRE: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTPOISON: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTALL: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); for (auto& i : abilities.absorbPercent) { i += value; } break; } case ITEM_PARSE_ABSORBPERCENTELEMENTS: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; break; } case ITEM_PARSE_ABSORBPERCENTMAGIC: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value; break; } case ITEM_PARSE_ABSORBPERCENTENERGY: { abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTFIRE: { abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTPOISON: { abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTICE: { abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTHOLY: { abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTDEATH: { abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTLIFEDRAIN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTMANADRAIN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTDROWN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTPHYSICAL: { abilities.absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTHEALING: { abilities.absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTUNDEFINED: { abilities.absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_SUPPRESSDRUNK: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DRUNK; } break; } case ITEM_PARSE_SUPPRESSENERGY: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_ENERGY; } break; } case ITEM_PARSE_SUPPRESSFIRE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_FIRE; } break; } case ITEM_PARSE_SUPPRESSPOISON: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_POISON; } break; } case ITEM_PARSE_SUPPRESSDROWN: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DROWN; } break; } case ITEM_PARSE_SUPPRESSPHYSICAL: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_BLEEDING; } break; } case ITEM_PARSE_SUPPRESSFREEZE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_FREEZING; } break; } case ITEM_PARSE_SUPPRESSDAZZLE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DAZZLED; } break; } case ITEM_PARSE_SUPPRESSCURSE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_CURSED; } break; } case ITEM_PARSE_FIELD: { it.group = ITEM_GROUP_MAGICFIELD; it.type = ITEM_TYPE_MAGICFIELD; CombatType_t combatType = COMBAT_NONE; ConditionDamage* conditionDamage = nullptr; tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "fire") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE); combatType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "energy") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY); combatType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "poison") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON); combatType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "drown") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN); combatType = COMBAT_DROWNDAMAGE; } else if (tmpStrValue == "physical") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING); combatType = COMBAT_PHYSICALDAMAGE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl; } if (combatType != COMBAT_NONE) { it.combatType = combatType; it.conditionDamage.reset(conditionDamage); uint32_t ticks = 0; int32_t start = 0; int32_t count = 1; for (auto subAttributeNode : attributeNode.children()) { pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key"); if (!subKeyAttribute) { continue; } pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value"); if (!subValueAttribute) { continue; } tmpStrValue = asLowerCaseString(subKeyAttribute.as_string()); if (tmpStrValue == "ticks") { ticks = pugi::cast<uint32_t>(subValueAttribute.value()); } else if (tmpStrValue == "count") { count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "start") { start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "damage") { int32_t damage = -pugi::cast<int32_t>(subValueAttribute.value()); if (start > 0) { std::list<int32_t> damageList; ConditionDamage::generateDamageList(damage, start, damageList); for (int32_t damageValue : damageList) { conditionDamage->addDamage(1, ticks, -damageValue); } start = 0; } else { conditionDamage->addDamage(count, ticks, damage); } } } conditionDamage->setParam(CONDITION_PARAM_FIELD, 1); if (conditionDamage->getTotalDamage() > 0) { conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1); } } break; } case ITEM_PARSE_REPLACEABLE: { it.replaceable = valueAttribute.as_bool(); break; } case ITEM_PARSE_PARTNERDIRECTION: { it.bedPartnerDir = getDirection(valueAttribute.as_string()); break; } case ITEM_PARSE_LEVELDOOR: { it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MALETRANSFORMTO: { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_MALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) { it.transformToOnUse[PLAYERSEX_FEMALE] = value; } break; } case ITEM_PARSE_FEMALETRANSFORMTO: { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_FEMALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_MALE] == 0) { it.transformToOnUse[PLAYERSEX_MALE] = value; } break; } case ITEM_PARSE_TRANSFORMTO: { it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_DESTROYTO: { it.destroyTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ELEMENTICE: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_ICEDAMAGE; break; } case ITEM_PARSE_ELEMENTEARTH: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_EARTHDAMAGE; break; } case ITEM_PARSE_ELEMENTFIRE: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_FIREDAMAGE; break; } case ITEM_PARSE_ELEMENTENERGY: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_ENERGYDAMAGE; break; } case ITEM_PARSE_WALKSTACK: { it.walkStack = valueAttribute.as_bool(); break; } case ITEM_PARSE_BLOCKING: { it.blockSolid = valueAttribute.as_bool(); break; } case ITEM_PARSE_ALLOWDISTREAD: { it.allowDistRead = booleanString(valueAttribute.as_string()); break; } default: { // It should not ever get to here, only if you add a new key to the map and don't configure a case for it. std::cout << "[Warning - Items::parseItemNode] Not configured key value: " << keyAttribute.as_string() << std::endl; break; } } } else { std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl; } } //check bed items if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) { std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl; } }