47 if(fin->
read(identifier, 1, 4) < 4)
50 if(memcmp(identifier,
"OTBM", 4) != 0 && memcmp(identifier,
"\0\0\0\0", 4) != 0)
57 uint32 headerVersion = root->getU32();
64 uint32 headerMajorItems = root->getU8();
71 uint32 headerMinorItems = root->getU32();
81 while(node->canRead()) {
82 uint8 attribute = node->getU8();
83 std::string tmp = node->getString();
89 setSpawnFile(fileName.substr(0, fileName.rfind(
'/') + 1) + tmp);
92 setHouseFile(fileName.substr(0, fileName.rfind(
'/') + 1) + tmp);
100 uint8 mapDataType = nodeMapData->getU8();
103 basePos.
x = nodeMapData->getU16();
104 basePos.
y = nodeMapData->getU16();
105 basePos.
z = nodeMapData->getU8();
107 for(
const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
108 uint8 type = nodeTile->getU8();
114 Position pos = basePos + nodeTile->getPoint();
117 uint32 hId = nodeTile->getU32();
123 house->setTile(tile);
126 while(nodeTile->canRead()) {
127 uint8 tileAttr = nodeTile->getU8();
130 uint32 _flags = nodeTile->getU32();
156 for(
const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
164 for(
const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
185 tile->setFlag(flags);
190 for(
const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
194 uint32 townId = nodeTown->getU32();
195 std::string townName = nodeTown->getString();
198 townCoords.
x = nodeTown->getU16();
199 townCoords.
y = nodeTown->getU16();
200 townCoords.
z = nodeTown->getU8();
207 for(
const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
211 std::string name = nodeWaypoint->getString();
214 waypointPos.
x = nodeWaypoint->getU16();
215 waypointPos.
y = nodeWaypoint->getU16();
216 waypointPos.
z = nodeWaypoint->getU8();
218 if(waypointPos.
isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
219 m_waypoints.insert(std::make_pair(waypointPos, name));
226 }
catch(std::exception& e) {
240 if(fileName.find_last_of(
'/') == std::string::npos)
243 dir = fileName.substr(0, fileName.find_last_of(
'/'));
253 std::string::size_type sep_pos;
258 if((sep_pos = fileName.rfind(
'.')) != std::string::npos &&
stdext::ends_with(fileName,
".otbm"))
259 cpyf = fileName.substr(0, sep_pos);
261 if(houseFile.empty())
262 houseFile = cpyf +
"-houses.xml";
264 if(spawnFile.empty())
265 spawnFile = cpyf +
"-spawns.xml";
268 if((sep_pos = spawnFile.rfind(
'/')) != std::string::npos)
269 spawnFile = spawnFile.substr(sep_pos + 1);
271 if((sep_pos = houseFile.rfind(
'/')) != std::string::npos)
272 houseFile = houseFile.substr(sep_pos + 1);
277 root->addU32(version);
280 root->addU16(mapSize.
width());
281 root->addU16(mapSize.
height());
292 root->addString(spawnFile);
295 root->addString(houseFile);
297 int px = -1, py = -1, pz =-1;
298 bool firstNode =
true;
301 for(
const auto& it : m_tileBlocks[
z]) {
304 if(
unlikely(!tile || tile->isEmpty()))
307 const Position& pos = tile->getPosition();
311 if(pos.
x < px || pos.
x >= px + 256
312 || pos.
y < py || pos.
y >= py + 256
323 root->addPos(px, py, pz);
327 root->addPoint(
Point(pos.
x, pos.
y) & 0xFF);
328 if(tile->isHouseTile())
329 root->addU32(tile->getHouseId());
331 if(tile->getFlags()) {
333 root->addU32(tile->getFlags());
336 const auto& itemList = tile->getItems();
337 const ItemPtr& ground = tile->getGround();
348 for(
const ItemPtr& item : itemList)
349 if(!item->isGround())
350 item->serializeItem(root);
364 root->addU32(town->getId());
365 root->addString(town->getName());
368 root->addPos(townPos.
x, townPos.
y, townPos.
z);
375 for(
const auto& it : m_waypoints) {
377 root->addString(it.second);
380 root->addPos(pos.
x, pos.
y, pos.
z);
392 }
catch(std::exception& e) {
422 g_logger.
warning(
"otcm map loaded was created with a different dat signature");
453 int countOrSubType = fin->
getU8();
504 for(
const auto& it : m_tileBlocks[
z]) {
507 if(!tile || tile->isEmpty())
515 for(
const ThingPtr& thing : tile->getThings()) {
516 if(thing->isItem()) {