|
|
@@ -942,96 +942,107 @@ void CMapLoaderJson::readHeader(const bool complete)
|
|
|
|
|
|
void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile)
|
|
|
{
|
|
|
- using namespace TerrainDetail;
|
|
|
- {//terrain type
|
|
|
- const std::string typeCode = src.substr(0, 2);
|
|
|
- tile.terType = const_cast<TerrainType *>(VLC->terrainTypeHandler->getInfoByCode(typeCode));
|
|
|
- }
|
|
|
- int startPos = 2; //0+typeCode fixed length
|
|
|
- {//terrain view
|
|
|
- int pos = startPos;
|
|
|
- while(isdigit(src.at(pos)))
|
|
|
- pos++;
|
|
|
- int len = pos - startPos;
|
|
|
- if(len<=0)
|
|
|
- throw std::runtime_error("Invalid terrain view in "+src);
|
|
|
- const std::string rawCode = src.substr(startPos, len);
|
|
|
- tile.terView = atoi(rawCode.c_str());
|
|
|
- startPos+=len;
|
|
|
- }
|
|
|
- {//terrain flip
|
|
|
- int terrainFlip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
- if(terrainFlip < 0)
|
|
|
- throw std::runtime_error("Invalid terrain flip in "+src);
|
|
|
- else
|
|
|
- tile.extTileFlags = terrainFlip;
|
|
|
- }
|
|
|
- if(startPos >= src.size())
|
|
|
- return;
|
|
|
- bool hasRoad = true;
|
|
|
- {//road type
|
|
|
- const std::string typeCode = src.substr(startPos, 2);
|
|
|
- startPos+=2;
|
|
|
- if(vstd::find_pos(ROAD_NAMES, typeCode) < 0)
|
|
|
- {
|
|
|
- if(vstd::find_pos(RIVER_NAMES, typeCode) < 0)
|
|
|
- throw std::runtime_error("Invalid river type in "+src);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using namespace TerrainDetail;
|
|
|
+ {//terrain type
|
|
|
+ const std::string typeCode = src.substr(0, 2);
|
|
|
+ tile.terType = const_cast<TerrainType*>(VLC->terrainTypeHandler->getInfoByCode(typeCode));
|
|
|
+ }
|
|
|
+ int startPos = 2; //0+typeCode fixed length
|
|
|
+ {//terrain view
|
|
|
+ int pos = startPos;
|
|
|
+ while (isdigit(src.at(pos)))
|
|
|
+ pos++;
|
|
|
+ int len = pos - startPos;
|
|
|
+ if (len <= 0)
|
|
|
+ throw std::runtime_error("Invalid terrain view in " + src);
|
|
|
+ const std::string rawCode = src.substr(startPos, len);
|
|
|
+ tile.terView = atoi(rawCode.c_str());
|
|
|
+ startPos += len;
|
|
|
+ }
|
|
|
+ {//terrain flip
|
|
|
+ int terrainFlip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
+ if (terrainFlip < 0)
|
|
|
+ throw std::runtime_error("Invalid terrain flip in " + src);
|
|
|
else
|
|
|
+ tile.extTileFlags = terrainFlip;
|
|
|
+ }
|
|
|
+ if (startPos >= src.size())
|
|
|
+ return;
|
|
|
+ bool hasRoad = true;
|
|
|
+ //FIXME: check without exceptions?
|
|
|
+ {//road type
|
|
|
+ const std::string typeCode = src.substr(startPos, 2);
|
|
|
+ startPos += 2;
|
|
|
+ try
|
|
|
{
|
|
|
- tile.riverType = typeCode;
|
|
|
- hasRoad = false;
|
|
|
+ tile.roadType = const_cast<RoadType*>(VLC->terrainTypeHandler->getRoadByCode(typeCode));
|
|
|
}
|
|
|
+ catch (const std::exception& e) //it's not a road, it's a river
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ tile.riverType = const_cast<RiverType*>(VLC->terrainTypeHandler->getRiverByCode(typeCode));
|
|
|
+ hasRoad = false;
|
|
|
+ }
|
|
|
+ catch (const std::exception& e)
|
|
|
+ {
|
|
|
+ throw std::runtime_error("Invalid river type in " + src);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (hasRoad)
|
|
|
+ {//road dir
|
|
|
+ int pos = startPos;
|
|
|
+ while (isdigit(src.at(pos)))
|
|
|
+ pos++;
|
|
|
+ int len = pos - startPos;
|
|
|
+ if (len <= 0)
|
|
|
+ throw std::runtime_error("Invalid road dir in " + src);
|
|
|
+ const std::string rawCode = src.substr(startPos, len);
|
|
|
+ tile.roadDir = atoi(rawCode.c_str());
|
|
|
+ startPos += len;
|
|
|
+ }
|
|
|
+ if (hasRoad)
|
|
|
+ {//road flip
|
|
|
+ int flip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
+ if (flip < 0)
|
|
|
+ throw std::runtime_error("Invalid road flip in " + src);
|
|
|
+ else
|
|
|
+ tile.extTileFlags |= (flip << 4);
|
|
|
+ }
|
|
|
+ if (startPos >= src.size())
|
|
|
+ return;
|
|
|
+ if (hasRoad)
|
|
|
+ {//river type
|
|
|
+ const std::string typeCode = src.substr(startPos, 2);
|
|
|
+ startPos += 2;
|
|
|
+ tile.riverType = const_cast<RiverType*>(VLC->terrainTypeHandler->getRiverByCode(typeCode));
|
|
|
+ }
|
|
|
+ {//river dir
|
|
|
+ int pos = startPos;
|
|
|
+ while (isdigit(src.at(pos)))
|
|
|
+ pos++;
|
|
|
+ int len = pos - startPos;
|
|
|
+ if (len <= 0)
|
|
|
+ throw std::runtime_error("Invalid river dir in " + src);
|
|
|
+ const std::string rawCode = src.substr(startPos, len);
|
|
|
+ tile.riverDir = atoi(rawCode.c_str());
|
|
|
+ startPos += len;
|
|
|
+ }
|
|
|
+ {//river flip
|
|
|
+ int flip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
+ if (flip < 0)
|
|
|
+ throw std::runtime_error("Invalid road flip in " + src);
|
|
|
+ else
|
|
|
+ tile.extTileFlags |= (flip << 2);
|
|
|
}
|
|
|
- else
|
|
|
- tile.roadType = typeCode;
|
|
|
- }
|
|
|
- if(hasRoad)
|
|
|
- {//road dir
|
|
|
- int pos = startPos;
|
|
|
- while(isdigit(src.at(pos)))
|
|
|
- pos++;
|
|
|
- int len = pos - startPos;
|
|
|
- if(len<=0)
|
|
|
- throw std::runtime_error("Invalid road dir in "+src);
|
|
|
- const std::string rawCode = src.substr(startPos, len);
|
|
|
- tile.roadDir = atoi(rawCode.c_str());
|
|
|
- startPos+=len;
|
|
|
- }
|
|
|
- if(hasRoad)
|
|
|
- {//road flip
|
|
|
- int flip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
- if(flip < 0)
|
|
|
- throw std::runtime_error("Invalid road flip in "+src);
|
|
|
- else
|
|
|
- tile.extTileFlags |= (flip<<4);
|
|
|
- }
|
|
|
- if(startPos >= src.size())
|
|
|
- return;
|
|
|
- if(hasRoad)
|
|
|
- {//river type
|
|
|
- const std::string typeCode = src.substr(startPos, 2);
|
|
|
- startPos+=2;
|
|
|
- if(vstd::find_pos(RIVER_NAMES, typeCode) < 0)
|
|
|
- throw std::runtime_error("Invalid river type in "+src);
|
|
|
- tile.riverType = typeCode;
|
|
|
- }
|
|
|
- {//river dir
|
|
|
- int pos = startPos;
|
|
|
- while(isdigit(src.at(pos)))
|
|
|
- pos++;
|
|
|
- int len = pos - startPos;
|
|
|
- if(len<=0)
|
|
|
- throw std::runtime_error("Invalid river dir in "+src);
|
|
|
- const std::string rawCode = src.substr(startPos, len);
|
|
|
- tile.riverDir = atoi(rawCode.c_str());
|
|
|
- startPos+=len;
|
|
|
}
|
|
|
- {//river flip
|
|
|
- int flip = vstd::find_pos(flipCodes, src.at(startPos++));
|
|
|
- if(flip < 0)
|
|
|
- throw std::runtime_error("Invalid road flip in "+src);
|
|
|
- else
|
|
|
- tile.extTileFlags |= (flip<<2);
|
|
|
+ catch (const std::exception & e)
|
|
|
+ {
|
|
|
+ logGlobal->error("Failed to read terrain tile: %s");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1278,10 +1289,10 @@ std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile)
|
|
|
|
|
|
out << tile.terType->typeCode << (int)tile.terView << flipCodes[tile.extTileFlags % 4];
|
|
|
|
|
|
- if(tile.roadType != ROAD_NAMES[0])
|
|
|
+ if(tile.roadType->id != Road::NO_ROAD)
|
|
|
out << tile.roadType << (int)tile.roadDir << flipCodes[(tile.extTileFlags >> 4) % 4];
|
|
|
|
|
|
- if(tile.riverType != RIVER_NAMES[0])
|
|
|
+ if(tile.riverType->id != River::NO_RIVER)
|
|
|
out << tile.riverType << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
|
|
|
|
|
|
return out.str();
|