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; }
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; }
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 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; }
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; }
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; }