Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool IOMap::loadMap(Map* map, const std::string& identifier)
- {
- FileLoader f;
- if(!f.openFile(identifier.c_str(), false, true))
- {
- std::stringstream ss;
- ss << "Could not open the file " << identifier << ".";
- setLastErrorString(ss.str());
- return false;
- }
- uint32_t type = 0;
- NODE root = f.getChildNode((NODE)NULL, type);
- PropStream propStream;
- if(!f.getProps(root, propStream))
- {
- setLastErrorString("Could not read root property.");
- return false;
- }
- OTBM_root_header* rootHeader;
- if(!propStream.getStruct(rootHeader))
- {
- setLastErrorString("Could not read header.");
- return false;
- }
- uint32_t headerVersion = rootHeader->version;
- if(headerVersion <= 0)
- {
- //In otbm version 1 the count variable after splashes/fluidcontainers and stackables
- //are saved as attributes instead, this solves alot of problems with items
- //that is changed (stackable/charges/fluidcontainer/splash) during an update.
- setLastErrorString("This map needs to be upgraded by using the latest map editor version to be able to load correctly.");
- return false;
- }
- if(headerVersion > 3)
- {
- setLastErrorString("Unknown OTBM version detected.");
- return false;
- }
- uint32_t headerMajorItems = rootHeader->majorVersionItems;
- if(headerMajorItems < 3)
- {
- setLastErrorString("This map needs to be upgraded by using the latest map editor version to be able to load correctly.");
- return false;
- }
- if(headerMajorItems > (uint32_t)Items::dwMajorVersion)
- {
- setLastErrorString("The map was saved with a different items.otb version, an upgraded items.otb is required.");
- return false;
- }
- uint32_t headerMinorItems = rootHeader->minorVersionItems;
- if(headerMinorItems < CLIENT_VERSION_810)
- {
- setLastErrorString("This map needs an updated items.otb.");
- return false;
- }
- if(headerMinorItems > (uint32_t)Items::dwMinorVersion)
- setLastErrorString("This map needs an updated items.otb.");
- std::clog << "> Map size: " << rootHeader->width << "x" << rootHeader->height << "." << std::endl;
- map->mapWidth = rootHeader->width;
- map->mapHeight = rootHeader->height;
- NODE nodeMap = f.getChildNode(root, type);
- if(type != OTBM_MAP_DATA)
- {
- setLastErrorString("Could not read data node.");
- return false;
- }
- if(!f.getProps(nodeMap, propStream))
- {
- setLastErrorString("Could not read map data attributes.");
- return false;
- }
- std::string tmp;
- uint8_t attribute;
- while(propStream.getByte(attribute))
- {
- switch(attribute)
- {
- case OTBM_ATTR_DESCRIPTION:
- {
- if(!propStream.getString(tmp))
- {
- setLastErrorString("Invalid description tag.");
- return false;
- }
- map->descriptions.push_back(tmp);
- break;
- }
- case OTBM_ATTR_EXT_SPAWN_FILE:
- {
- if(!propStream.getString(tmp))
- {
- setLastErrorString("Invalid spawnfile tag.");
- return false;
- }
- map->spawnfile = identifier.substr(0, identifier.rfind('/') + 1);
- map->spawnfile += tmp;
- break;
- }
- case OTBM_ATTR_EXT_HOUSE_FILE:
- {
- if(!propStream.getString(tmp))
- {
- setLastErrorString("Invalid housefile tag.");
- return false;
- }
- map->housefile = identifier.substr(0, identifier.rfind('/') + 1);
- map->housefile += tmp;
- break;
- }
- default:
- {
- setLastErrorString("Unknown header node.");
- return false;
- }
- }
- }
- std::clog << "> Map descriptions: " << std::endl;
- for(StringVec::iterator it = map->descriptions.begin(); it != map->descriptions.end(); ++it)
- std::clog << "\"" << (*it) << "\"" << std::endl;
- NODE nodeMapData = f.getChildNode(nodeMap, type);
- while(nodeMapData != NO_NODE)
- {
- if(f.getError() != ERROR_NONE)
- {
- setLastErrorString("Invalid map node.");
- return false;
- }
- if(type == OTBM_TILE_AREA)
- {
- if(!f.getProps(nodeMapData, propStream))
- {
- setLastErrorString("Invalid map node.");
- return false;
- }
- OTBM_Destination_coords* area_coord;
- if(!propStream.getStruct(area_coord))
- {
- setLastErrorString("Invalid map node.");
- return false;
- }
- int32_t base_x = area_coord->_x, base_y = area_coord->_y, base_z = area_coord->_z;
- NODE nodeTile = f.getChildNode(nodeMapData, type);
- while(nodeTile != NO_NODE)
- {
- if(f.getError() != ERROR_NONE)
- {
- setLastErrorString("Could not read node data.");
- return false;
- }
- if(type == OTBM_TILE || type == OTBM_HOUSETILE)
- {
- if(!f.getProps(nodeTile, propStream))
- {
- setLastErrorString("Could not read node data.");
- return false;
- }
- OTBM_Tile_coords* tileCoord;
- if(!propStream.getStruct(tileCoord))
- {
- setLastErrorString("Could not read tile position.");
- return false;
- }
- Tile* tile = NULL;
- Item* ground = NULL;
- uint32_t tileflags = 0;
- uint16_t px = base_x + tileCoord->_x, py = base_y + tileCoord->_y, pz = base_z;
- House* house = NULL;
- if(type == OTBM_HOUSETILE)
- {
- uint32_t _houseid;
- if(!propStream.getLong(_houseid))
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Could not read house id.";
- setLastErrorString(ss.str());
- return false;
- }
- house = Houses::getInstance()->getHouse(_houseid, true);
- if(!house)
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Could not create house id: " << _houseid;
- setLastErrorString(ss.str());
- return false;
- }
- tile = new HouseTile(px, py, pz, house);
- house->addTile(static_cast<HouseTile*>(tile));
- }
- //read tile attributes
- uint8_t attribute;
- while(propStream.getByte(attribute))
- {
- switch(attribute)
- {
- case OTBM_ATTR_TILE_FLAGS:
- {
- uint32_t flags;
- if(!propStream.getLong(flags))
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to read tile flags.";
- setLastErrorString(ss.str());
- return false;
- }
- if((flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
- tileflags |= TILESTATE_PROTECTIONZONE;
- else if((flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
- tileflags |= TILESTATE_OPTIONALZONE;
- else if((flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
- tileflags |= TILESTATE_HARDCOREZONE;
- if((flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
- tileflags |= TILESTATE_NOLOGOUT;
- if((flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
- {
- if(house)
- std::clog << "[x:" << px << ", y:" << py << ", z:" << pz << "] House tile flagged as refreshing!";
- tileflags |= TILESTATE_REFRESH;
- }
- break;
- }
- case OTBM_ATTR_ITEM:
- {
- Item* item = Item::CreateItem(propStream);
- if(!item)
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to create item.";
- setLastErrorString(ss.str());
- return false;
- }
- if(item->getItemCount() <= 0)
- item->setItemCount(1);
- if(house && item->isMoveable())
- {
- std::clog << "[Warning - IOMap::loadMap] Movable item in house: " << house->getId();
- std::clog << ", item type: " << item->getID() << ", at position " << px << "/" << py << "/";
- std::clog << pz << std::endl;
- delete item;
- item = NULL;
- }
- else if(tile)
- {
- tile->__internalAddThing(item);
- item->__startDecaying();
- item->setLoadedFromMap(true);
- }
- else if(item->isGroundTile())
- {
- if(ground)
- delete ground;
- ground = item;
- }
- else
- {
- tile = createTile(ground, item, px, py, pz);
- tile->__internalAddThing(item);
- item->__startDecaying();
- item->setLoadedFromMap(true);
- }
- break;
- }
- default:
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Unknown tile attribute.";
- setLastErrorString(ss.str());
- return false;
- }
- }
- }
- NODE nodeItem = f.getChildNode(nodeTile, type);
- while(nodeItem)
- {
- if(type == OTBM_ITEM)
- {
- PropStream propStream;
- f.getProps(nodeItem, propStream);
- Item* item = Item::CreateItem(propStream);
- if(!item)
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to create item.";
- setLastErrorString(ss.str());
- return false;
- }
- if(item->unserializeItemNode(f, nodeItem, propStream))
- {
- if(item->getItemCount() <= 0)
- item->setItemCount(1);
- if(house && item->isMoveable())
- {
- std::clog << "[Warning - IOMap::loadMap] Movable item in house: ";
- std::clog << house->getId() << ", item type: " << item->getID();
- std::clog << ", pos " << px << "/" << py << "/" << pz << std::endl;
- delete item;
- item = NULL;
- }
- else if(tile)
- {
- tile->__internalAddThing(item);
- item->__startDecaying();
- item->setLoadedFromMap(true);
- }
- else if(item->isGroundTile())
- {
- if(ground)
- delete ground;
- ground = item;
- }
- else
- {
- tile = createTile(ground, item, px, py, pz);
- tile->__internalAddThing(item);
- item->__startDecaying();
- item->setLoadedFromMap(true);
- }
- }
- else
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to load item " << item->getID() << ".";
- setLastErrorString(ss.str());
- delete item;
- item = NULL;
- return false;
- }
- }
- else
- {
- std::stringstream ss;
- ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Unknown node type.";
- setLastErrorString(ss.str());
- }
- nodeItem = f.getNextNode(nodeItem, type);
- }
- if(!tile)
- tile = createTile(ground, NULL, px, py, pz);
- tile->setFlag((tileflags_t)tileflags);
- map->setTile(px, py, pz, tile);
- }
- else
- {
- setLastErrorString("Unknown tile node.");
- return false;
- }
- nodeTile = f.getNextNode(nodeTile, type);
- }
- }
- else if(type == OTBM_TOWNS)
- {
- NODE nodeTown = f.getChildNode(nodeMapData, type);
- while(nodeTown != NO_NODE)
- {
- if(type == OTBM_TOWN)
- {
- if(!f.getProps(nodeTown, propStream))
- {
- setLastErrorString("Could not read town data.");
- return false;
- }
- uint32_t townId = 0;
- if(!propStream.getLong(townId))
- {
- setLastErrorString("Could not read town id.");
- return false;
- }
- Town* town = Towns::getInstance()->getTown(townId);
- if(!town)
- {
- town = new Town(townId);
- Towns::getInstance()->addTown(townId, town);
- }
- std::string townName;
- if(!propStream.getString(townName))
- {
- setLastErrorString("Could not read town name.");
- return false;
- }
- town->setName(townName);
- OTBM_Destination_coords *townCoords;
- if(!propStream.getStruct(townCoords))
- {
- setLastErrorString("Could not read town coordinates.");
- return false;
- }
- town->setPosition(Position(townCoords->_x, townCoords->_y, townCoords->_z));
- }
- else
- {
- setLastErrorString("Unknown town node.");
- return false;
- }
- nodeTown = f.getNextNode(nodeTown, type);
- }
- }
- else if(type == OTBM_WAYPOINTS && headerVersion > 1)
- {
- NODE nodeWaypoint = f.getChildNode(nodeMapData, type);
- while(nodeWaypoint != NO_NODE)
- {
- if(type == OTBM_WAYPOINT)
- {
- if(!f.getProps(nodeWaypoint, propStream))
- {
- setLastErrorString("Could not read waypoint data.");
- return false;
- }
- std::string name;
- if(!propStream.getString(name))
- {
- setLastErrorString("Could not read waypoint name.");
- return false;
- }
- OTBM_Destination_coords* waypoint_coords;
- if(!propStream.getStruct(waypoint_coords))
- {
- setLastErrorString("Could not read waypoint coordinates.");
- return false;
- }
- map->waypoints.addWaypoint(WaypointPtr(new Waypoint(name,
- Position(waypoint_coords->_x, waypoint_coords->_y, waypoint_coords->_z))));
- }
- else
- {
- setLastErrorString("Unknown waypoint node.");
- return false;
- }
- nodeWaypoint = f.getNextNode(nodeWaypoint, type);
- }
- }
- else
- {
- setLastErrorString("Unknown map node.");
- return false;
- }
- nodeMapData = f.getNextNode(nodeMapData, type);
- }
- return true;
- }
- bool IOMap::loadSpawns(Map* map)
- {
- if(map->spawnfile.empty())
- map->spawnfile = g_config.getString(ConfigManager::MAP_NAME) + "-spawn.xml";
- return Spawns::getInstance()->loadFromXml(map->spawnfile);
- }
- bool IOMap::loadHouses(Map* map)
- {
- if(map->housefile.empty())
- map->housefile = g_config.getString(ConfigManager::MAP_NAME) + "-house.xml";
- return Houses::getInstance()->loadFromXml(map->housefile);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement