Advertisement
Guest User

Untitled

a guest
Feb 12th, 2019
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.40 KB | None | 0 0
  1. bool IOMap::loadMap(Map* map, const std::string& identifier)
  2. {
  3.     FileLoader f;
  4.     if(!f.openFile(identifier.c_str(), false, true))
  5.     {
  6.         std::stringstream ss;
  7.         ss << "Could not open the file " << identifier << ".";
  8.         setLastErrorString(ss.str());
  9.         return false;
  10.     }
  11.  
  12.     uint32_t type = 0;
  13.     NODE root = f.getChildNode((NODE)NULL, type);
  14.  
  15.     PropStream propStream;
  16.     if(!f.getProps(root, propStream))
  17.     {
  18.         setLastErrorString("Could not read root property.");
  19.         return false;
  20.     }
  21.  
  22.     OTBM_root_header* rootHeader;
  23.     if(!propStream.getStruct(rootHeader))
  24.     {
  25.         setLastErrorString("Could not read header.");
  26.         return false;
  27.     }
  28.  
  29.     uint32_t headerVersion = rootHeader->version;
  30.     if(headerVersion <= 0)
  31.     {
  32.         //In otbm version 1 the count variable after splashes/fluidcontainers and stackables
  33.         //are saved as attributes instead, this solves alot of problems with items
  34.         //that is changed (stackable/charges/fluidcontainer/splash) during an update.
  35.         setLastErrorString("This map needs to be upgraded by using the latest map editor version to be able to load correctly.");
  36.         return false;
  37.     }
  38.  
  39.     if(headerVersion > 3)
  40.     {
  41.         setLastErrorString("Unknown OTBM version detected.");
  42.         return false;
  43.     }
  44.  
  45.     uint32_t headerMajorItems = rootHeader->majorVersionItems;
  46.     if(headerMajorItems < 3)
  47.     {
  48.         setLastErrorString("This map needs to be upgraded by using the latest map editor version to be able to load correctly.");
  49.         return false;
  50.     }
  51.  
  52.     if(headerMajorItems > (uint32_t)Items::dwMajorVersion)
  53.     {
  54.         setLastErrorString("The map was saved with a different items.otb version, an upgraded items.otb is required.");
  55.         return false;
  56.     }
  57.  
  58.     uint32_t headerMinorItems = rootHeader->minorVersionItems;
  59.     if(headerMinorItems < CLIENT_VERSION_810)
  60.     {
  61.         setLastErrorString("This map needs an updated items.otb.");
  62.         return false;
  63.     }
  64.  
  65.     if(headerMinorItems > (uint32_t)Items::dwMinorVersion)
  66.         setLastErrorString("This map needs an updated items.otb.");
  67.  
  68.     std::clog << "> Map size: " << rootHeader->width << "x" << rootHeader->height << "." << std::endl;
  69.     map->mapWidth = rootHeader->width;
  70.     map->mapHeight = rootHeader->height;
  71.  
  72.     NODE nodeMap = f.getChildNode(root, type);
  73.     if(type != OTBM_MAP_DATA)
  74.     {
  75.         setLastErrorString("Could not read data node.");
  76.         return false;
  77.     }
  78.  
  79.     if(!f.getProps(nodeMap, propStream))
  80.     {
  81.         setLastErrorString("Could not read map data attributes.");
  82.         return false;
  83.     }
  84.  
  85.     std::string tmp;
  86.     uint8_t attribute;
  87.     while(propStream.getByte(attribute))
  88.     {
  89.         switch(attribute)
  90.         {
  91.             case OTBM_ATTR_DESCRIPTION:
  92.             {
  93.                 if(!propStream.getString(tmp))
  94.                 {
  95.                     setLastErrorString("Invalid description tag.");
  96.                     return false;
  97.                 }
  98.  
  99.                 map->descriptions.push_back(tmp);
  100.                 break;
  101.             }
  102.             case OTBM_ATTR_EXT_SPAWN_FILE:
  103.             {
  104.                 if(!propStream.getString(tmp))
  105.                 {
  106.                     setLastErrorString("Invalid spawnfile tag.");
  107.                     return false;
  108.                 }
  109.  
  110.                 map->spawnfile = identifier.substr(0, identifier.rfind('/') + 1);
  111.                 map->spawnfile += tmp;
  112.                 break;
  113.             }
  114.             case OTBM_ATTR_EXT_HOUSE_FILE:
  115.             {
  116.                 if(!propStream.getString(tmp))
  117.                 {
  118.                     setLastErrorString("Invalid housefile tag.");
  119.                     return false;
  120.                 }
  121.  
  122.                 map->housefile = identifier.substr(0, identifier.rfind('/') + 1);
  123.                 map->housefile += tmp;
  124.                 break;
  125.             }
  126.             default:
  127.             {
  128.                 setLastErrorString("Unknown header node.");
  129.                 return false;
  130.             }
  131.         }
  132.     }
  133.  
  134.     std::clog << "> Map descriptions: " << std::endl;
  135.     for(StringVec::iterator it = map->descriptions.begin(); it != map->descriptions.end(); ++it)
  136.         std::clog << "\"" << (*it) << "\"" << std::endl;
  137.  
  138.     NODE nodeMapData = f.getChildNode(nodeMap, type);
  139.     while(nodeMapData != NO_NODE)
  140.     {
  141.         if(f.getError() != ERROR_NONE)
  142.         {
  143.             setLastErrorString("Invalid map node.");
  144.             return false;
  145.         }
  146.  
  147.         if(type == OTBM_TILE_AREA)
  148.         {
  149.             if(!f.getProps(nodeMapData, propStream))
  150.             {
  151.                 setLastErrorString("Invalid map node.");
  152.                 return false;
  153.             }
  154.  
  155.             OTBM_Destination_coords* area_coord;
  156.             if(!propStream.getStruct(area_coord))
  157.             {
  158.                 setLastErrorString("Invalid map node.");
  159.                 return false;
  160.             }
  161.  
  162.             int32_t base_x = area_coord->_x, base_y = area_coord->_y, base_z = area_coord->_z;
  163.             NODE nodeTile = f.getChildNode(nodeMapData, type);
  164.             while(nodeTile != NO_NODE)
  165.             {
  166.                 if(f.getError() != ERROR_NONE)
  167.                 {
  168.                     setLastErrorString("Could not read node data.");
  169.                     return false;
  170.                 }
  171.  
  172.                 if(type == OTBM_TILE || type == OTBM_HOUSETILE)
  173.                 {
  174.                     if(!f.getProps(nodeTile, propStream))
  175.                     {
  176.                         setLastErrorString("Could not read node data.");
  177.                         return false;
  178.                     }
  179.  
  180.                     OTBM_Tile_coords* tileCoord;
  181.                     if(!propStream.getStruct(tileCoord))
  182.                     {
  183.                         setLastErrorString("Could not read tile position.");
  184.                         return false;
  185.                     }
  186.  
  187.                     Tile* tile = NULL;
  188.                     Item* ground = NULL;
  189.                     uint32_t tileflags = 0;
  190.  
  191.                     uint16_t px = base_x + tileCoord->_x, py = base_y + tileCoord->_y, pz = base_z;
  192.                     House* house = NULL;
  193.                     if(type == OTBM_HOUSETILE)
  194.                     {
  195.                         uint32_t _houseid;
  196.                         if(!propStream.getLong(_houseid))
  197.                         {
  198.                             std::stringstream ss;
  199.                             ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Could not read house id.";
  200.  
  201.                             setLastErrorString(ss.str());
  202.                             return false;
  203.                         }
  204.  
  205.                         house = Houses::getInstance()->getHouse(_houseid, true);
  206.                         if(!house)
  207.                         {
  208.                             std::stringstream ss;
  209.                             ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Could not create house id: " << _houseid;
  210.  
  211.                             setLastErrorString(ss.str());
  212.                             return false;
  213.                         }
  214.  
  215.                         tile = new HouseTile(px, py, pz, house);
  216.                         house->addTile(static_cast<HouseTile*>(tile));
  217.                     }
  218.  
  219.                     //read tile attributes
  220.                     uint8_t attribute;
  221.                     while(propStream.getByte(attribute))
  222.                     {
  223.                         switch(attribute)
  224.                         {
  225.                             case OTBM_ATTR_TILE_FLAGS:
  226.                             {
  227.                                 uint32_t flags;
  228.                                 if(!propStream.getLong(flags))
  229.                                 {
  230.                                     std::stringstream ss;
  231.                                     ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to read tile flags.";
  232.  
  233.                                     setLastErrorString(ss.str());
  234.                                     return false;
  235.                                 }
  236.  
  237.                                 if((flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
  238.                                     tileflags |= TILESTATE_PROTECTIONZONE;
  239.                                 else if((flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
  240.                                     tileflags |= TILESTATE_OPTIONALZONE;
  241.                                 else if((flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
  242.                                     tileflags |= TILESTATE_HARDCOREZONE;
  243.  
  244.                                 if((flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
  245.                                     tileflags |= TILESTATE_NOLOGOUT;
  246.  
  247.                                 if((flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
  248.                                 {
  249.                                     if(house)
  250.                                         std::clog << "[x:" << px << ", y:" << py << ", z:" << pz << "] House tile flagged as refreshing!";
  251.  
  252.                                     tileflags |= TILESTATE_REFRESH;
  253.                                 }
  254.  
  255.                                 break;
  256.                             }
  257.  
  258.                             case OTBM_ATTR_ITEM:
  259.                             {
  260.                                 Item* item = Item::CreateItem(propStream);
  261.                                 if(!item)
  262.                                 {
  263.                                     std::stringstream ss;
  264.                                     ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to create item.";
  265.  
  266.                                     setLastErrorString(ss.str());
  267.                                     return false;
  268.                                 }
  269.  
  270.                                 if(item->getItemCount() <= 0)
  271.                                     item->setItemCount(1);
  272.  
  273.                                 if(house && item->isMoveable())
  274.                                 {
  275.                                     std::clog << "[Warning - IOMap::loadMap] Movable item in house: " << house->getId();
  276.                                     std::clog << ", item type: " << item->getID() << ", at position " << px << "/" << py << "/";
  277.                                     std::clog << pz << std::endl;
  278.  
  279.                                     delete item;
  280.                                     item = NULL;
  281.                                 }
  282.                                 else if(tile)
  283.                                 {
  284.                                     tile->__internalAddThing(item);
  285.                                     item->__startDecaying();
  286.                                     item->setLoadedFromMap(true);
  287.                                 }
  288.                                 else if(item->isGroundTile())
  289.                                 {
  290.                                     if(ground)
  291.                                         delete ground;
  292.  
  293.                                     ground = item;
  294.                                 }
  295.                                 else
  296.                                 {
  297.                                     tile = createTile(ground, item, px, py, pz);
  298.                                     tile->__internalAddThing(item);
  299.  
  300.                                     item->__startDecaying();
  301.                                     item->setLoadedFromMap(true);
  302.                                 }
  303.  
  304.                                 break;
  305.                             }
  306.  
  307.                             default:
  308.                             {
  309.                                 std::stringstream ss;
  310.                                 ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Unknown tile attribute.";
  311.  
  312.                                 setLastErrorString(ss.str());
  313.                                 return false;
  314.                             }
  315.                         }
  316.                     }
  317.  
  318.                     NODE nodeItem = f.getChildNode(nodeTile, type);
  319.                     while(nodeItem)
  320.                     {
  321.                         if(type == OTBM_ITEM)
  322.                         {
  323.                             PropStream propStream;
  324.                             f.getProps(nodeItem, propStream);
  325.  
  326.                             Item* item = Item::CreateItem(propStream);
  327.                             if(!item)
  328.                             {
  329.                                 std::stringstream ss;
  330.                                 ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to create item.";
  331.  
  332.                                 setLastErrorString(ss.str());
  333.                                 return false;
  334.                             }
  335.  
  336.                             if(item->unserializeItemNode(f, nodeItem, propStream))
  337.                             {
  338.                                 if(item->getItemCount() <= 0)
  339.                                     item->setItemCount(1);
  340.  
  341.                                 if(house && item->isMoveable())
  342.                                 {
  343.                                     std::clog << "[Warning - IOMap::loadMap] Movable item in house: ";
  344.                                     std::clog << house->getId() << ", item type: " << item->getID();
  345.                                     std::clog << ", pos " << px << "/" << py << "/" << pz << std::endl;
  346.  
  347.                                     delete item;
  348.                                     item = NULL;
  349.                                 }
  350.                                 else if(tile)
  351.                                 {
  352.                                     tile->__internalAddThing(item);
  353.                                     item->__startDecaying();
  354.                                     item->setLoadedFromMap(true);
  355.                                 }
  356.                                 else if(item->isGroundTile())
  357.                                 {
  358.                                     if(ground)
  359.                                         delete ground;
  360.  
  361.                                     ground = item;
  362.                                 }
  363.                                 else
  364.                                 {
  365.                                     tile = createTile(ground, item, px, py, pz);
  366.                                     tile->__internalAddThing(item);
  367.  
  368.                                     item->__startDecaying();
  369.                                     item->setLoadedFromMap(true);
  370.                                 }
  371.                             }
  372.                             else
  373.                             {
  374.                                 std::stringstream ss;
  375.                                 ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Failed to load item " << item->getID() << ".";
  376.                                 setLastErrorString(ss.str());
  377.  
  378.                                 delete item;
  379.                                 item = NULL;
  380.                                 return false;
  381.                             }
  382.                         }
  383.                         else
  384.                         {
  385.                             std::stringstream ss;
  386.                             ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] Unknown node type.";
  387.                             setLastErrorString(ss.str());
  388.                         }
  389.  
  390.                         nodeItem = f.getNextNode(nodeItem, type);
  391.                     }
  392.  
  393.                     if(!tile)
  394.                         tile = createTile(ground, NULL, px, py, pz);
  395.  
  396.                     tile->setFlag((tileflags_t)tileflags);
  397.                     map->setTile(px, py, pz, tile);
  398.                 }
  399.                 else
  400.                 {
  401.                     setLastErrorString("Unknown tile node.");
  402.                     return false;
  403.                 }
  404.  
  405.                 nodeTile = f.getNextNode(nodeTile, type);
  406.             }
  407.         }
  408.         else if(type == OTBM_TOWNS)
  409.         {
  410.             NODE nodeTown = f.getChildNode(nodeMapData, type);
  411.             while(nodeTown != NO_NODE)
  412.             {
  413.                 if(type == OTBM_TOWN)
  414.                 {
  415.                     if(!f.getProps(nodeTown, propStream))
  416.                     {
  417.                         setLastErrorString("Could not read town data.");
  418.                         return false;
  419.                     }
  420.  
  421.                     uint32_t townId = 0;
  422.                     if(!propStream.getLong(townId))
  423.                     {
  424.                         setLastErrorString("Could not read town id.");
  425.                         return false;
  426.                     }
  427.  
  428.                     Town* town = Towns::getInstance()->getTown(townId);
  429.                     if(!town)
  430.                     {
  431.                         town = new Town(townId);
  432.                         Towns::getInstance()->addTown(townId, town);
  433.                     }
  434.  
  435.                     std::string townName;
  436.                     if(!propStream.getString(townName))
  437.                     {
  438.                         setLastErrorString("Could not read town name.");
  439.                         return false;
  440.                     }
  441.  
  442.                     town->setName(townName);
  443.                     OTBM_Destination_coords *townCoords;
  444.                     if(!propStream.getStruct(townCoords))
  445.                     {
  446.                         setLastErrorString("Could not read town coordinates.");
  447.                         return false;
  448.                     }
  449.  
  450.                     town->setPosition(Position(townCoords->_x, townCoords->_y, townCoords->_z));
  451.                 }
  452.                 else
  453.                 {
  454.                     setLastErrorString("Unknown town node.");
  455.                     return false;
  456.                 }
  457.  
  458.                 nodeTown = f.getNextNode(nodeTown, type);
  459.             }
  460.         }
  461.         else if(type == OTBM_WAYPOINTS && headerVersion > 1)
  462.         {
  463.             NODE nodeWaypoint = f.getChildNode(nodeMapData, type);
  464.             while(nodeWaypoint != NO_NODE)
  465.             {
  466.                 if(type == OTBM_WAYPOINT)
  467.                 {
  468.                     if(!f.getProps(nodeWaypoint, propStream))
  469.                     {
  470.                         setLastErrorString("Could not read waypoint data.");
  471.                         return false;
  472.                     }
  473.  
  474.                     std::string name;
  475.                     if(!propStream.getString(name))
  476.                     {
  477.                         setLastErrorString("Could not read waypoint name.");
  478.                         return false;
  479.                     }
  480.  
  481.                     OTBM_Destination_coords* waypoint_coords;
  482.                     if(!propStream.getStruct(waypoint_coords))
  483.                     {
  484.                         setLastErrorString("Could not read waypoint coordinates.");
  485.                         return false;
  486.                     }
  487.  
  488.                     map->waypoints.addWaypoint(WaypointPtr(new Waypoint(name,
  489.                         Position(waypoint_coords->_x, waypoint_coords->_y, waypoint_coords->_z))));
  490.                 }
  491.                 else
  492.                 {
  493.                     setLastErrorString("Unknown waypoint node.");
  494.                     return false;
  495.                 }
  496.  
  497.                 nodeWaypoint = f.getNextNode(nodeWaypoint, type);
  498.             }
  499.         }
  500.         else
  501.         {
  502.             setLastErrorString("Unknown map node.");
  503.             return false;
  504.         }
  505.  
  506.         nodeMapData = f.getNextNode(nodeMapData, type);
  507.     }
  508.  
  509.     return true;
  510. }
  511.  
  512. bool IOMap::loadSpawns(Map* map)
  513. {
  514.     if(map->spawnfile.empty())
  515.         map->spawnfile =  g_config.getString(ConfigManager::MAP_NAME) + "-spawn.xml";
  516.  
  517.     return Spawns::getInstance()->loadFromXml(map->spawnfile);
  518. }
  519.  
  520. bool IOMap::loadHouses(Map* map)
  521. {
  522.     if(map->housefile.empty())
  523.         map->housefile = g_config.getString(ConfigManager::MAP_NAME) + "-house.xml";
  524.  
  525.     return Houses::getInstance()->loadFromXml(map->housefile);
  526. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement