bool Spawns::loadFromXml(const std::string& _filename) { if (isLoaded()) { return true; } filename = _filename; xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc) { xmlNodePtr root, spawnNode; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name, (const xmlChar*)"spawns") != 0) { xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; spawnNode = root->children; while (spawnNode) { if (xmlStrcmp(spawnNode->name, (const xmlChar*)"spawn") == 0) { Position centerPos; int32_t radius = -1; if (readXMLInteger(spawnNode, "centerx", intValue)) { centerPos.x = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "centery", intValue)) { centerPos.y = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "centerz", intValue)) { centerPos.z = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "radius", intValue)) { radius = intValue; } else { xmlFreeDoc(doc); return false; } Spawn* spawn = new Spawn(centerPos, radius); spawnList.push_back(spawn); xmlNodePtr tmpNode = spawnNode->children; while (tmpNode) { if (xmlStrcmp(tmpNode->name, (const xmlChar*)"monster") == 0) { std::string name = ""; Position pos = centerPos; Direction dir = NORTH; uint32_t interval = 0; if (readXMLString(tmpNode, "name", strValue)) { name = strValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "direction", intValue)) { switch (intValue) { case 0: dir = NORTH; break; case 1: dir = EAST; break; case 2: dir = SOUTH; break; case 3: dir = WEST; break; } } if (readXMLInteger(tmpNode, "x", intValue)) { pos.x += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "y", intValue)) { pos.y += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue)) { interval = intValue * 1000; } else { tmpNode = tmpNode->next; continue; } if (interval > MINSPAWN_INTERVAL) { spawn->addMonster(name, pos, dir, interval); } else { std::cout << "[Warning] Spawns::loadFromXml " << name << " " << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (xmlStrcmp(tmpNode->name, (const xmlChar*)"npc") == 0) { Direction direction = NORTH; std::string name = ""; Position placePos = centerPos; if (readXMLString(tmpNode, "name", strValue)) { name = strValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "direction", intValue)) { switch (intValue) { case 0: direction = NORTH; break; case 1: direction = EAST; break; case 2: direction = SOUTH; break; case 3: direction = WEST; break; } } if (readXMLInteger(tmpNode, "x", intValue)) { placePos.x += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "y", intValue)) { placePos.y += intValue; } else { tmpNode = tmpNode->next; continue; } Npc* npc = Npc::createNpc(name); if (!npc) { tmpNode = tmpNode->next; continue; } npc->setDirection(direction); npc->setMasterPos(placePos, radius); npcList.push_back(npc); } tmpNode = tmpNode->next; } } spawnNode = spawnNode->next; } xmlFreeDoc(doc); loaded = true; return true; } return false; }
bool Spawns::parseSpawnNode(xmlNodePtr p, bool checkDuplicate) { if(xmlStrcmp(p->name, (const xmlChar*)"spawn")) return false; int32_t intValue; std::string strValue; Position centerPos; if(!readXMLString(p, "centerpos", strValue)) { if(!readXMLInteger(p, "centerx", intValue)) return false; centerPos.x = intValue; if(!readXMLInteger(p, "centery", intValue)) return false; centerPos.y = intValue; if(!readXMLInteger(p, "centerz", intValue)) return false; centerPos.z = intValue; } else { IntegerVec posVec = vectorAtoi(explodeString(",", strValue)); if(posVec.size() < 3) return false; centerPos = Position(posVec[0], posVec[1], posVec[2]); } if(!readXMLInteger(p, "radius", intValue)) return false; int32_t radius = intValue; Spawn* spawn = new Spawn(centerPos, radius); if(checkDuplicate) { for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it) { if((*it)->getPosition() == centerPos) delete *it; } } spawnList.push_back(spawn); xmlNodePtr tmpNode = p->children; while(tmpNode) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"monster")) { std::string name; if(!readXMLString(tmpNode, "name", strValue)) { tmpNode = tmpNode->next; continue; } name = strValue; int32_t interval = MINSPAWN_INTERVAL / 1000; if(readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue)) { if(intValue <= interval) { std::cout << "[Warning - Spawns::loadFromXml] " << name << " " << centerPos << " spawntime cannot"; std::cout << " be less than " << interval << " seconds." << std::endl; tmpNode = tmpNode->next; continue; } interval = intValue; } interval *= 1000; Position placePos = centerPos; if(readXMLInteger(tmpNode, "x", intValue)) placePos.x += intValue; if(readXMLInteger(tmpNode, "y", intValue)) placePos.y += intValue; if(readXMLInteger(tmpNode, "z", intValue)) placePos.z /*+*/= intValue; Direction direction = NORTH; if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST) direction = (Direction)intValue; spawn->addMonster(name, placePos, direction, interval); } else if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"npc")) { std::string name; if(!readXMLString(tmpNode, "name", strValue)) { tmpNode = tmpNode->next; continue; } name = strValue; Position placePos = centerPos; if(readXMLInteger(tmpNode, "x", intValue)) placePos.x += intValue; if(readXMLInteger(tmpNode, "y", intValue)) placePos.y += intValue; if(readXMLInteger(tmpNode, "z", intValue)) placePos.z /*+*/= intValue; Direction direction = NORTH; if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST) direction = (Direction)intValue; Npc* npc = Npc::createNpc(name); if(!npc) { tmpNode = tmpNode->next; continue; } npc->setMasterPos(placePos, radius); npc->setDirection(direction); npcList.push_back(npc); } tmpNode = tmpNode->next; } return true; }
bool Spawns::loadFromXml(const std::string& filename) { if (loaded) { return true; } pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(filename.c_str()); if (!result) { printXMLError("Error - Spawns::loadFromXml", filename, result); return false; } this->filename = filename; loaded = true; for (auto spawnNode : doc.child("spawns").children()) { Position centerPos( pugi::cast<uint16_t>(spawnNode.attribute("centerx").value()), pugi::cast<uint16_t>(spawnNode.attribute("centery").value()), pugi::cast<uint16_t>(spawnNode.attribute("centerz").value()) ); int32_t radius; pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius"); if (radiusAttribute) { radius = pugi::cast<int32_t>(radiusAttribute.value()); } else { radius = -1; } spawnList.emplace_front(centerPos, radius); Spawn& spawn = spawnList.front(); for (auto childNode : spawnNode.children()) { if (strcasecmp(childNode.name(), "monster") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Direction dir; pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { dir = static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value())); } else { dir = DIRECTION_NORTH; } Position pos( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ); uint32_t interval = pugi::cast<uint32_t>(childNode.attribute("spawntime").value()) * 1000; if (interval > MINSPAWN_INTERVAL) { spawn.addMonster(nameAttribute.as_string(), pos, dir, interval); } else { std::cout << "[Warning - Spawns::loadFromXml] " << nameAttribute.as_string() << ' ' << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (strcasecmp(childNode.name(), "npc") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Npc* npc = Npc::createNpc(nameAttribute.as_string()); if (!npc) { continue; } pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { npc->setDirection(static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value()))); } npc->setMasterPos(Position( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ), radius); npcList.push_front(npc); } } } return true; }
bool Spawns::loadFromXml(const std::string& _filename) { if (loaded) { return true; } pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(_filename.c_str()); if (!result) { std::cout << "[Error - Spawns::loadFromXml] Failed to load " << _filename << ": " << result.description() << std::endl; return false; } filename = _filename; loaded = true; for (pugi::xml_node spawnNode = doc.child("spawns").first_child(); spawnNode; spawnNode = spawnNode.next_sibling()) { Position centerPos( pugi::cast<uint16_t>(spawnNode.attribute("centerx").value()), pugi::cast<uint16_t>(spawnNode.attribute("centery").value()), pugi::cast<uint16_t>(spawnNode.attribute("centerz").value()) ); int32_t radius; pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius"); if (radiusAttribute) { radius = pugi::cast<int32_t>(radiusAttribute.value()); } else { radius = -1; } Spawn* spawn = new Spawn(centerPos, radius); spawnList.push_back(spawn); for (pugi::xml_node childNode = spawnNode.first_child(); childNode; childNode = childNode.next_sibling()) { if (strcasecmp(childNode.name(), "monster") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Direction dir; pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { dir = static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value())); } else { dir = NORTH; } Position pos( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ); uint32_t interval = pugi::cast<uint32_t>(childNode.attribute("spawntime").value()) * 1000; if (interval > MINSPAWN_INTERVAL) { spawn->addMonster(nameAttribute.as_string(), pos, dir, interval); } else { std::cout << "[Warning - Spawns::loadFromXml] " << nameAttribute.as_string() << ' ' << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (strcasecmp(childNode.name(), "npc") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Npc* npc = Npc::createNpc(nameAttribute.as_string()); if (!npc) { continue; } pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { npc->setDirection(static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value()))); } npc->setMasterPos(Position( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ), radius); npcList.push_back(npc); } } } return true; }