bool Container::unserializeItemNode(OTB::Loader& loader, const OTB::Node& node, PropStream& propStream) { bool ret = Item::unserializeItemNode(loader, node, propStream); if (!ret) { return false; } for (auto& itemNode : node.children) { //load container items if (itemNode.type != OTBM_ITEM) { // unknown type return false; } PropStream itemPropStream; if (!loader.getProps(itemNode, itemPropStream)) { return false; } Item* item = Item::CreateItem(itemPropStream); if (!item) { return false; } if (!item->unserializeItemNode(loader, itemNode, itemPropStream)) { return false; } addItem(item); updateItemWeight(item->getWeight()); } return true; }
bool IOMap::parseWaypoints(OTB::Loader& loader, const OTB::Node& waypointsNode, Map& map) { PropStream propStream; for (auto& node : waypointsNode.children) { if (node.type != OTBM_WAYPOINT) { setLastErrorString("Unknown waypoint node."); return false; } if (!loader.getProps(node, propStream)) { setLastErrorString("Could not read waypoint data."); return false; } std::string name; if (!propStream.readString(name)) { setLastErrorString("Could not read waypoint name."); return false; } OTBM_Destination_coords waypoint_coords; if (!propStream.read(waypoint_coords)) { setLastErrorString("Could not read waypoint coordinates."); return false; } map.waypoints[name] = Position(waypoint_coords.x, waypoint_coords.y, waypoint_coords.z); } return true; }
bool IOMap::parseMapDataAttributes(OTB::Loader& loader, const OTB::Node& mapNode, Map& map, const std::string& fileName) { PropStream propStream; if (!loader.getProps(mapNode, propStream)) { setLastErrorString("Could not read map data attributes."); return false; } std::string mapDescription; std::string tmp; uint8_t attribute; while (propStream.read<uint8_t>(attribute)) { switch (attribute) { case OTBM_ATTR_DESCRIPTION: if (!propStream.readString(mapDescription)) { setLastErrorString("Invalid description tag."); return false; } break; case OTBM_ATTR_EXT_SPAWN_FILE: if (!propStream.readString(tmp)) { setLastErrorString("Invalid spawn tag."); return false; } map.spawnfile = fileName.substr(0, fileName.rfind('/') + 1); map.spawnfile += tmp; break; case OTBM_ATTR_EXT_HOUSE_FILE: if (!propStream.readString(tmp)) { setLastErrorString("Invalid house tag."); return false; } map.housefile = fileName.substr(0, fileName.rfind('/') + 1); map.housefile += tmp; break; default: setLastErrorString("Unknown header node."); return false; } } return true; }
bool IOMap::parseTowns(OTB::Loader& loader, const OTB::Node& townsNode, Map& map) { for (auto& townNode : townsNode.children) { PropStream propStream; if (townNode.type != OTBM_TOWN) { setLastErrorString("Unknown town node."); return false; } if (!loader.getProps(townNode, propStream)) { setLastErrorString("Could not read town data."); return false; } uint32_t townId; if (!propStream.read<uint32_t>(townId)) { setLastErrorString("Could not read town id."); return false; } Town* town = map.towns.getTown(townId); if (!town) { town = new Town(townId); map.towns.addTown(townId, town); } std::string townName; if (!propStream.readString(townName)) { setLastErrorString("Could not read town name."); return false; } town->setName(townName); OTBM_Destination_coords town_coords; if (!propStream.read(town_coords)) { setLastErrorString("Could not read town coordinates."); return false; } town->setTemplePos(Position(town_coords.x, town_coords.y, town_coords.z)); } return true; }
bool IOMap::parseTileArea(OTB::Loader& loader, const OTB::Node& tileAreaNode, Map& map) { PropStream propStream; if (!loader.getProps(tileAreaNode, propStream)) { setLastErrorString("Invalid map node."); return false; } OTBM_Destination_coords area_coord; if (!propStream.read(area_coord)) { setLastErrorString("Invalid map node."); return false; } uint16_t base_x = area_coord.x; uint16_t base_y = area_coord.y; uint16_t z = area_coord.z; for (auto& tileNode : tileAreaNode.children) { if (tileNode.type != OTBM_TILE && tileNode.type != OTBM_HOUSETILE) { setLastErrorString("Unknown tile node."); return false; } if (!loader.getProps(tileNode, propStream)) { setLastErrorString("Could not read node data."); return false; } OTBM_Tile_coords tile_coord; if (!propStream.read(tile_coord)) { setLastErrorString("Could not read tile position."); return false; } uint16_t x = base_x + tile_coord.x; uint16_t y = base_y + tile_coord.y; bool isHouseTile = false; House* house = nullptr; Tile* tile = nullptr; Item* ground_item = nullptr; uint32_t tileflags = TILESTATE_NONE; if (tileNode.type == OTBM_HOUSETILE) { uint32_t houseId; if (!propStream.read<uint32_t>(houseId)) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Could not read house id."; setLastErrorString(ss.str()); return false; } house = map.houses.addHouse(houseId); if (!house) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Could not create house id: " << houseId; setLastErrorString(ss.str()); return false; } tile = new HouseTile(x, y, z, house); house->addTile(static_cast<HouseTile*>(tile)); isHouseTile = true; } uint8_t attribute; //read tile attributes while (propStream.read<uint8_t>(attribute)) { switch (attribute) { case OTBM_ATTR_TILE_FLAGS: { uint32_t flags; if (!propStream.read<uint32_t>(flags)) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Failed to read tile flags."; setLastErrorString(ss.str()); return false; } if ((flags & OTBM_TILEFLAG_PROTECTIONZONE) != 0) { tileflags |= TILESTATE_PROTECTIONZONE; } else if ((flags & OTBM_TILEFLAG_NOPVPZONE) != 0) { tileflags |= TILESTATE_NOPVPZONE; } else if ((flags & OTBM_TILEFLAG_PVPZONE) != 0) { tileflags |= TILESTATE_PVPZONE; } if ((flags & OTBM_TILEFLAG_NOLOGOUT) != 0) { tileflags |= TILESTATE_NOLOGOUT; } break; } case OTBM_ATTR_ITEM: { Item* item = Item::CreateItem(propStream); if (!item) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Failed to create item."; setLastErrorString(ss.str()); return false; } if (isHouseTile && item->isMoveable()) { std::cout << "[Warning - IOMap::loadMap] Moveable item with ID: " << item->getID() << ", in house: " << house->getId() << ", at position [x: " << x << ", y: " << y << ", z: " << z << "]." << std::endl; delete item; } else { if (item->getItemCount() <= 0) { item->setItemCount(1); } if (tile) { tile->internalAddThing(item); item->startDecaying(); item->setLoadedFromMap(true); } else if (item->isGroundTile()) { delete ground_item; ground_item = item; } else { tile = createTile(ground_item, item, x, y, z); tile->internalAddThing(item); item->startDecaying(); item->setLoadedFromMap(true); } } break; } default: std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Unknown tile attribute."; setLastErrorString(ss.str()); return false; } } for (auto& itemNode : tileNode.children) { if (itemNode.type != OTBM_ITEM) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Unknown node type."; setLastErrorString(ss.str()); return false; } PropStream stream; if (!loader.getProps(itemNode, stream)) { setLastErrorString("Invalid item node."); return false; } Item* item = Item::CreateItem(stream); if (!item) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Failed to create item."; setLastErrorString(ss.str()); return false; } if (!item->unserializeItemNode(loader, itemNode, stream)) { std::ostringstream ss; ss << "[x:" << x << ", y:" << y << ", z:" << z << "] Failed to load item " << item->getID() << '.'; setLastErrorString(ss.str()); delete item; return false; } if (isHouseTile && item->isMoveable()) { std::cout << "[Warning - IOMap::loadMap] Moveable item with ID: " << item->getID() << ", in house: " << house->getId() << ", at position [x: " << x << ", y: " << y << ", z: " << z << "]." << std::endl; delete item; } else { if (item->getItemCount() <= 0) { item->setItemCount(1); } if (tile) { tile->internalAddThing(item); item->startDecaying(); item->setLoadedFromMap(true); } else if (item->isGroundTile()) { delete ground_item; ground_item = item; } else { tile = createTile(ground_item, item, x, y, z); tile->internalAddThing(item); item->startDecaying(); item->setLoadedFromMap(true); } } } if (!tile) { tile = createTile(ground_item, nullptr, x, y, z); } tile->setFlag(static_cast<tileflags_t>(tileflags)); map.setTile(x, y, z, tile); } return true; }