48 if(fin->
read(identifier, 1, 4) < 4)
51 if(memcmp(identifier,
"OTBM", 4) != 0 && memcmp(identifier,
"\0\0\0\0", 4) != 0)
58 const uint32 headerVersion = root->getU32();
65 const uint32 headerMajorItems = root->getU8();
72 const uint32 headerMinorItems = root->getU32();
82 while(node->canRead()) {
83 const uint8 attribute = node->getU8();
84 std::string tmp = node->getString();
90 setSpawnFile(fileName.substr(0, fileName.rfind(
'/') + 1) + tmp);
93 setHouseFile(fileName.substr(0, fileName.rfind(
'/') + 1) + tmp);
100 for(
const BinaryTreePtr& nodeMapData : node->getChildren()) {
101 const uint8 mapDataType = nodeMapData->getU8();
104 basePos.
x = nodeMapData->getU16();
105 basePos.
y = nodeMapData->getU16();
106 basePos.
z = nodeMapData->getU8();
108 for(
const BinaryTreePtr& nodeTile : nodeMapData->getChildren()) {
109 const uint8 type = nodeTile->getU8();
115 Position pos = basePos + nodeTile->getPoint();
118 const uint32 hId = nodeTile->getU32();
124 house->setTile(tile);
127 while(nodeTile->canRead()) {
128 const uint8 tileAttr = nodeTile->getU8();
132 const uint32 _flags = nodeTile->getU32();
160 for(
const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
168 for(
const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
189 tile->setFlag(flags);
194 for(
const BinaryTreePtr& nodeTown : nodeMapData->getChildren()) {
198 const uint32 townId = nodeTown->getU32();
199 std::string townName = nodeTown->getString();
202 townCoords.
x = nodeTown->getU16();
203 townCoords.
y = nodeTown->getU16();
204 townCoords.
z = nodeTown->getU8();
211 for(
const BinaryTreePtr& nodeWaypoint : nodeMapData->getChildren()) {
215 std::string name = nodeWaypoint->getString();
218 waypointPos.
x = nodeWaypoint->getU16();
219 waypointPos.
y = nodeWaypoint->getU16();
220 waypointPos.
z = nodeWaypoint->getU8();
222 if(waypointPos.
isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
223 m_waypoints.insert(std::make_pair(waypointPos, name));
230 }
catch(std::exception& e) {
244 if(fileName.find_last_of(
'/') == std::string::npos)
247 dir = fileName.substr(0, fileName.find_last_of(
'/'));
257 std::string::size_type sep_pos;
262 if((sep_pos = fileName.rfind(
'.')) != std::string::npos &&
stdext::ends_with(fileName,
".otbm"))
263 cpyf = fileName.substr(0, sep_pos);
265 if(houseFile.empty())
266 houseFile = cpyf +
"-houses.xml";
268 if(spawnFile.empty())
269 spawnFile = cpyf +
"-spawns.xml";
272 if((sep_pos = spawnFile.rfind(
'/')) != std::string::npos)
273 spawnFile = spawnFile.substr(sep_pos + 1);
275 if((sep_pos = houseFile.rfind(
'/')) != std::string::npos)
276 houseFile = houseFile.substr(sep_pos + 1);
281 root->addU32(version);
284 root->addU16(mapSize.
width());
285 root->addU16(mapSize.
height());
296 root->addString(spawnFile);
299 root->addString(houseFile);
301 int px = -1, py = -1, pz = -1;
302 bool firstNode =
true;
305 for(
const auto& it : m_tileBlocks[
z]) {
308 if(
unlikely(!tile || tile->isEmpty()))
311 const Position& pos = tile->getPosition();
315 if(pos.
x < px || pos.
x >= px + 256
316 || pos.
y < py || pos.
y >= py + 256
327 root->addPos(px, py, pz);
331 root->addPoint(
Point(pos.
x, pos.
y) & 0xFF);
332 if(tile->isHouseTile())
333 root->addU32(tile->getHouseId());
335 if(tile->getFlags()) {
337 root->addU32(tile->getFlags());
340 const auto& itemList = tile->getItems();
341 const ItemPtr& ground = tile->getGround();
352 for(
const ItemPtr& item : itemList)
353 if(!item->isGround())
354 item->serializeItem(root);
368 root->addU32(town->getId());
369 root->addString(town->getName());
371 const Position townPos = town->getPos();
372 root->addPos(townPos.
x, townPos.
y, townPos.
z);
379 for(
const auto& it : m_waypoints) {
381 root->addString(it.second);
384 root->addPos(pos.
x, pos.
y, pos.
z);
396 }
catch(std::exception& e) {
427 g_logger.
warning(
"otcm map loaded was created with a different dat signature");
452 const int id = fin->
getU16();
458 const int countOrSubType = fin->
getU8();
509 for(
const auto& it : m_tileBlocks[
z]) {
512 if(!tile || tile->isEmpty())
515 const Position pos = tile->getPosition();
520 for(
const ThingPtr& thing : tile->getThings()) {
521 if(thing->isItem()) {