Пример #1
0
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;
}
Пример #2
0
void IOMapBin::loadOTM(Map* map)
{
  int op;
  bool end = false;
  while(!feof(fh) || !end)
  {
		op = fgetc(fh);
		switch(op) 
		{
			case 0x10: // Information of the map
			{
				char name[100], author[100];
				int pos;
				int len;

				// Map Name
				len = fgetc(fh);
				for (pos = 0; pos < len; pos++)
					name[pos] = fgetc(fh);
				name[pos] = '\0';
				std::cout << ":: Map Name: " << name << std::endl;
				
				// Map Author
				len = fgetc(fh);
				for (pos = 0; pos < len; pos++)
					author[pos] = fgetc(fh);
				author[pos] = '\0';
				std::cout << ":: Map Author: " << author << std::endl;
				
				
			} break;
			case 0x20: // Map dimensions
			{
				int width, height;
				width = fgetc(fh);
				width += fgetc(fh)<<8;
				height = fgetc(fh);
				height += fgetc(fh)<<8;
				map->mapwidth = width;
				map->mapheight = height;
				std::cout << ":: Map dimensions: " << width << "x" << height << std::endl;
			} break; 
			case 0x30: // Global Temple Position
			{
				PositionEx templePos;

				templePos.x = fgetc(fh);
				templePos.x += fgetc(fh);	// X
				templePos.y = fgetc(fh);
				templePos.y += fgetc(fh);	// Y
				templePos.z = fgetc(fh);	// Z
				int radius = fgetc(fh);						// Radius

				// TODO: use the temple point and radius
				std::cout << ":: Global Temple Position: " << templePos.x << " " << templePos.y << " " << templePos.z << " Radius: " << radius << std::endl;
			} break; 
			case 0x40: // Tiles and items
			{
				Tile *t;
				int x, y, z, id, total = 0;
				while(true)
				{
					// tile pos
					x = fgetc(fh); x += fgetc(fh) << 8;    
					y = fgetc(fh); y += fgetc(fh) << 8;    
					z = fgetc(fh);
					
					// end the loop
					if (x == 0xFFFF && y == 0xFFFF && z == 0xFF) 
						break;
		           			             
					id = fgetc(fh) + 100; 
					id += fgetc(fh) << 8; 
			        total += 1;
			        
					map->setTile(x, y, z, id);
					t = map->getTile(x, y, z);
					
					// check if the tile is pz
					if (fgetc(fh) == 1)
						t->setPz();
					
					int op2;
					int tmpid;
					do 
					{
						op2 = fgetc(fh);  
						switch (op2)
						{
							case 0x10: // Action Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								// t->ground->setActionId(tmpid);
								break;
							case 0x20: // Unique Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								//t ->ground->setUniqueId(tmpid);
								break; 
							case 0x30: // Target Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								// TODO: implement target ids
								break; 
							case 0xA0: // Item
							{
								int itemcount = fgetc(fh);
								for (int count = 0; count < itemcount; count++)
								{
									int itemid = fgetc(fh) + 100;
									itemid += fgetc(fh) << 8;
									
									Item *item = Item::CreateItem(itemid);
									int op3;
									do
									{
										op3 = fgetc(fh);
										switch (op3)
										{
											case 0x10: // Count
												fgetc(fh); //len
									   			item->setItemCountOrSubtype((unsigned char)fgetc(fh));
												break;                 
											case 0x20: // Action Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setActionId(tmpid);
												break; 
											case 0x30: // Unique Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setUniqueId(tmpid);
												break; 
											case 0x40: // Target Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setTargetId(tmpid);
												break; 
											case 0x70: //Teleport
											{
												Teleport *tele = dynamic_cast<Teleport*>(item);
												Position toPos;
												fgetc(fh); //len

												toPos.x = fgetc(fh); toPos.x += fgetc(fh)<<8;
												toPos.y = fgetc(fh); toPos.y += fgetc(fh)<<8;
												toPos.z = fgetc(fh);

												if (tele)
													tele->setDestPos(toPos);
											} break;
											case 0x80: // Fluids
												fgetc(fh);
												if (item->isFluidContainer())
													item->setItemCountOrSubtype((unsigned char)fgetc(fh));
												else
													fgetc(fh);
											break;                      
											case 0xFF: // End
												break;
											default: // Unknow/New operators
											{
												printf("WARNING: Unknown operator loading items: 0x%X!\n",op3);
												int len = fgetc(fh);
												for (int i = 0; i < len; i++)
													fgetc(fh);     
											} break;
										}                             
									} while (op3 < 0xFF);
									
									//item->pos.x = x;
									//item->pos.y = y;
									//item->pos.z = z;

									if (item->isAlwaysOnTop())
										t->topItems.push_back(item);
									else
										t->downItems.push_back(item);
								}
							} break;
							case 0xFF: // End
								break;
							default: // Unknow/New operators
							{
								printf("WARNING: Unknown operator loading tiles: 0x%X!\n",op2);
								int len = fgetc(fh);
								for (int i = 0;i < len; i++)
									fgetc(fh);  
							} break;
						}
					} while (op2 < 0xFF);
				}
				std::cout << ":: Total of tiles loaded is " << total << std::endl;
			} break;
			case 0x50: // Spawns
			{
				SpawnManager::initialize(&g_game);
				Position pos;
				int cx, cy, radius, total=0;
				long int secs;
				std::string cname;
				int num = fgetc(fh); num+=fgetc(fh)<<8;

				for (int i = 0; i < num; i++)
				{
					int len = fgetc(fh);
					int count;
					cname = "";

					for (int j = 0;j < len; j++)
						cname.push_back(fgetc(fh)); // get the creature name

					//std::cout << cname.c_str() << std::endl;

					pos.x = fgetc(fh); pos.x += fgetc(fh) << 8;
					pos.y = fgetc(fh); pos.y += fgetc(fh) << 8;
					pos.z = fgetc(fh); 
					radius = fgetc(fh) + 1;
			             
					count = fgetc(fh); // number of creatures in this respawn
					total += count;
					secs = fgetc(fh); secs += fgetc(fh) << 8;
			             
					Spawn *spawn = new Spawn(&g_game, pos, radius);
					SpawnManager::instance()->addSpawn(spawn);
		             
					for (int j = 0; j < count; j++)
					{
						cx = (rand() % (radius * 2)) - radius;
						cy = (rand() % (radius * 2)) - radius;
						spawn->addMonster(cname, NORTH, cx, cy, secs * 1000);
					}

					fgetc(fh); // 1 = check for players near, 0 = dont check
				}
		           
				std::cout << ":: Loaded spawns: " << total << std::endl;
				SpawnManager::instance()->startup();
			} break;
			case 0xF0:
				end = true;
				break;
		}
  }
  fclose(fh);
  return;
}
Пример #3
0
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;
}
Пример #4
0
bool SpawnManager::loadSpawnsXML(std::string filename)
{
	std::transform(filename.begin(), filename.end(), filename.begin(), tolower);
	xmlDocPtr doc = xmlParseFile(filename.c_str());

	if (doc){
		xmlNodePtr root, p;
		char* nodeValue = NULL;
		root = xmlDocGetRootElement(doc);
		
		root = xmlDocGetRootElement(doc);
		
		if (xmlStrcmp(root->name,(const xmlChar*) "spawns")){			
			xmlFreeDoc(doc);
			return false;
		}

		p = root->children;
            
		while (p) {
			const char* str = (char*)p->name;
			
			if (strcmp(str, "spawn") == 0) {
				Position centerpos;
				int radius;

				nodeValue = (char*)xmlGetProp(p, (const xmlChar *)"centerx");
				if(nodeValue) {
					centerpos.x = atoi(nodeValue);
					xmlFreeOTSERV(nodeValue);
				}
				else {
					xmlFreeOTSERV(nodeValue);
					return false;
				}

				nodeValue = (char*)xmlGetProp(p, (const xmlChar *)"centery");
				if(nodeValue) {
					centerpos.y = atoi(nodeValue);
					xmlFreeOTSERV(nodeValue);
				}
				else {
					xmlFreeOTSERV(nodeValue);
					xmlFreeDoc(doc);
					return false;
				}

				nodeValue = (char*)xmlGetProp(p, (const xmlChar *)"centerz");
				if(nodeValue) {
					centerpos.z = atoi(nodeValue);
					xmlFreeOTSERV(nodeValue);
				}
				else {
					xmlFreeOTSERV(nodeValue);
					xmlFreeDoc(doc);
					return false;
				}

				nodeValue = (char*)xmlGetProp(p, (const xmlChar *)"radius");
				if(nodeValue) {
					radius = atoi(nodeValue);
					xmlFreeOTSERV(nodeValue);
				}
				else {
					xmlFreeOTSERV(nodeValue);
					xmlFreeDoc(doc);
					return false;
				}

				Spawn *spawn = new Spawn(game, centerpos, radius);
				spawns.push_back(spawn);

				std::string name;
				int x, y, spawntime;
				Direction direction = NORTH;
				int rawdir = 0; //NORTH

				xmlNodePtr tmp = p->children;
				while (tmp) {
					str = (char*)tmp->name;
					if (strcmp(str, "monster") == 0) {
						nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *)"name");
						if(nodeValue) {
							name = nodeValue;
							xmlFreeOTSERV(nodeValue);
						}
						else {
							tmp = tmp->next;
							break;
						}

						nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *)"direction");
						if(nodeValue) {
							rawdir = atoi(nodeValue);
							xmlFreeOTSERV(nodeValue);
						}

						nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *)"x");
						if(nodeValue) {
							x = atoi(nodeValue);
							xmlFreeOTSERV(nodeValue);
						}
						else {
							tmp = tmp->next;
							break;
						}

						nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *)"y");
						if(nodeValue) {
							y = atoi(nodeValue);
							xmlFreeOTSERV(nodeValue);
						}
						else {
							tmp = tmp->next;
							break;
						}

						nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *)"spawntime");
						if(nodeValue) {
							spawntime = atoi(nodeValue);
							xmlFreeOTSERV(nodeValue);
						}
						else {
							tmp = tmp->next;
							break;
						}

						switch(rawdir) {
							case 0: direction = NORTH; break;
							case 1: direction = EAST; break;
							case 2: direction = SOUTH; break;
							case 3: direction = WEST; break;

							default:
								direction = NORTH;
								break;
						}

						spawn->addMonster(name, direction, x, y, spawntime * 1000);
					}

					tmp = tmp->next;
				}
			}

			p = p->next;
		}

		xmlFreeDoc(doc);
		return true;
	}

	return false;
}
Пример #5
0
bool SpawnManager::loadSpawnsSQL(std::string identifier)
{
	std::string host = g_config.getGlobalString("map_host");
	std::string user = g_config.getGlobalString("map_user");
	std::string pass = g_config.getGlobalString("map_pass");
	std::string db   = g_config.getGlobalString("map_db");

#ifdef __DEBUG__
	std::cout "host" << host << "user" << user << "pass" << pass << "db" << db << std::endl;
#endif     
	mysqlpp::Connection con;

	try{
		con.connect(db.c_str(), host.c_str(), user.c_str(), pass.c_str()); 
	}
	catch(mysqlpp::BadQuery e){
		std::cout << "MYSQL-ERROR: " << e.error << std::endl;
		return false;
	}
	
	mysqlpp::Result res;
	
	//Monsters

	//Try & Find the Monter's	
	try{
     mysqlpp::Query query = con.query();
		query << "SELECT * FROM " << identifier << "_monsters WHERE name !=''";
	 
#ifdef __DEBUG__
	std::cout << query.preview() << std::endl;
#endif	
	
	 res = query.store();
	} //End Try
	catch(mysqlpp::BadQuery e){
		std::cout << "MYSQL-ERROR: " << e.error << std::endl;
		return false;
	}

	std::cout << ":: Found: " << res.size() << " Monsters(s)/Spawn(s)" << std::endl;
    if(res.size() < 1){//No Monsters
       std::cout << "No Monsters found" << std::endl;
       return false;
    }
		//if there are any monster spawns to load
    else{
       //Load Monsters
			try{
        mysqlpp::Result Monster;
        mysqlpp::Query query = con.query();

        for(int i=1; i <= res.size(); ++i){
          query.reset();
          query << "SELECT * FROM " << identifier << "_monsters WHERE id = '" << i <<"' and id != ''";
          Monster = query.store();
          mysqlpp::Row row = *Monster.begin();          
          //Get the Monster's Position on Map
          std::string pos = std::string(row.lookup_by_name("spawnpos"));
          boost::char_separator<char> sep(";");
          tokenizer spawnpostokens(pos, sep);
          tokenizer::iterator spawnposit = spawnpostokens.begin();
					Position spawnpos;
          spawnpos.x=atoi(spawnposit->c_str()); spawnposit++;
					spawnpos.y=atoi(spawnposit->c_str()); spawnposit++;
					spawnpos.z=atoi(spawnposit->c_str());
					std::string name;
          if(std::string(row.lookup_by_name("name")) != ""){name = std::string(row.lookup_by_name("name"));}
          int time = row.lookup_by_name("time");

          Spawn *spawn = new Spawn(game, spawnpos, 1);
					spawns.push_back(spawn);
          spawn->addMonster(name, NORTH, 0, 0, time * 1000);
        }//End For Loop
			}//End Try
			catch(mysqlpp::BadQuery e){
				std::cout << "MYSQL-ERROR: " << e.error << std::endl;
				return false;
			}//End Catch    
		}
	
	//NPC's	
	//Try & Find the NPC's	
	try{
		mysqlpp::Query query = con.query();
		query << "SELECT * FROM " << identifier << "_npcs WHERE name !=''";
	 
#ifdef __DEBUG__
		std::cout << query.preview() << std::endl;
#endif	
	
	 res = query.store();
	}//End Try
	catch(mysqlpp::BadQuery e){
		std::cout << "MYSQL-ERROR: " << e.error << std::endl;
		return false;
	}

	std::cout << ":: Found: " << res.size() << " NPC(s)" << std::endl;
    if(res.size() < 1){//No NPC's
       std::cout << "No NPC's found" << std::endl;
       return false;
		}
		//if there are any NPC's to load
    else{
       //Load Monsters
			try{
        mysqlpp::Result Monster;
        mysqlpp::Query query = con.query();

        for(int i=1; i <= res.size(); ++i){
          query.reset();
          query << "SELECT * FROM " << identifier << "_npcs WHERE id = '" << i <<"' and id != ''";
          Monster = query.store();
          mysqlpp::Row row = *Monster.begin();          
          //Get the NPC's Position on Map
          std::string pos = std::string(row.lookup_by_name("pos"));
          boost::char_separator<char> sep(";");
          tokenizer postokens(pos, sep);
          tokenizer::iterator posit = postokens.begin();
					Position npcpos;
          npcpos.x=atoi(posit->c_str()); posit++;
					npcpos.y=atoi(posit->c_str()); posit++;
					npcpos.z=atoi(posit->c_str());
					std::string name;
          if(std::string(row.lookup_by_name("name")) != ""){name = std::string(row.lookup_by_name("name"));}
          int dir = row.lookup_by_name("dir");
          Npc* npc = new Npc(name, game);
          
          npc->pos = npcpos;
          switch(dir){
             case 1:
                npc->direction=(NORTH);
                break;
             
             case 2:
                npc->direction=(SOUTH);
                break;
             
             case 3:
                npc->direction=(WEST);
                break;
             
             case 4:
                npc->direction=(EAST);
                break;
             
             default:
              //  std::cout << "Invalid direction for " << name << "  " <<x<<" "<<y<<" "<<z<<".";
                return false;
                break;
          }
					
					if(!game->placeCreature(npc->pos, npc)){
						delete npc;
					}
				}//End For Loop
        return true;
			}//End Try
			catch(mysqlpp::BadQuery e){
				std::cout << "MYSQL-ERROR: " << e.error << std::endl;
				return false;
			}//End Catch    
    
		}
    return true;
}
Пример #6
0
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;
}