浏览代码

Moved roads and rivers to TerrainTypeHandler, by analogy to TerrainType.

Tomasz Zieliński 3 年之前
父节点
当前提交
ebe45d512d

+ 18 - 24
client/mapHandler.cpp

@@ -135,22 +135,6 @@ EMapAnimRedrawStatus CMapHandler::drawTerrainRectNew(SDL_Surface * targetSurface
 
 
 void CMapHandler::initTerrainGraphics()
 void CMapHandler::initTerrainGraphics()
 {
 {
-	static const std::map<std::string, std::string> ROAD_FILES =
-	{
-		{ROAD_NAMES[1], "dirtrd"},
-		{ROAD_NAMES[2], "gravrd"},
-		{ROAD_NAMES[3], "cobbrd"}
-	};
-
-	static const std::map<std::string, std::string> RIVER_FILES =
-	{
-		{RIVER_NAMES[1], "clrrvr"},
-		{RIVER_NAMES[2], "icyrvr"},
-		{RIVER_NAMES[3], "mudrvr"},
-		{RIVER_NAMES[4], "lavrvr"}
-	};
-	
-
 	auto loadFlipped = [](TFlippedAnimations & animation, TFlippedCache & cache, const std::map<std::string, std::string> & files)
 	auto loadFlipped = [](TFlippedAnimations & animation, TFlippedCache & cache, const std::map<std::string, std::string> & files)
 	{
 	{
 		//no rotation and basic setup
 		//no rotation and basic setup
@@ -190,14 +174,24 @@ void CMapHandler::initTerrainGraphics()
 	
 	
 	//TODO: use if as a key
 	//TODO: use if as a key
 	std::map<std::string, std::string> terrainFiles;
 	std::map<std::string, std::string> terrainFiles;
+	std::map<std::string, std::string> riverFiles;
+	std::map<std::string, std::string> roadFiles;
 	for(const auto * terrain : VLC->terrainTypeHandler->terrains())
 	for(const auto * terrain : VLC->terrainTypeHandler->terrains())
 	{
 	{
 		terrainFiles[terrain->name] = terrain->tilesFilename;
 		terrainFiles[terrain->name] = terrain->tilesFilename;
 	}
 	}
+	for(const auto * river : VLC->terrainTypeHandler->rivers())
+	{
+		riverFiles[river->fileName] = river->fileName;
+	}
+	for(const auto * road : VLC->terrainTypeHandler->roads())
+	{
+		roadFiles[road->fileName] = road->fileName;
+	}
 	
 	
 	loadFlipped(terrainAnimations, terrainImages, terrainFiles);
 	loadFlipped(terrainAnimations, terrainImages, terrainFiles);
-	loadFlipped(roadAnimations, roadImages, ROAD_FILES);
-	loadFlipped(riverAnimations, riverImages, RIVER_FILES);
+	loadFlipped(riverAnimations, riverImages, riverFiles);
+	loadFlipped(roadAnimations, roadImages, roadFiles);
 
 
 	// Create enough room for the whole map and its frame
 	// Create enough room for the whole map and its frame
 
 
@@ -791,21 +785,21 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra
 
 
 void CMapHandler::CMapBlitter::drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const
 void CMapHandler::CMapBlitter::drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const
 {
 {
-	if (tinfoUpper && tinfoUpper->roadType != ROAD_NAMES[0])
+	if (tinfoUpper && tinfoUpper->roadType->id != Road::NO_ROAD)
 	{
 	{
 		ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
 		ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
 		Rect source(0, tileSize / 2, tileSize, tileSize / 2);
 		Rect source(0, tileSize / 2, tileSize, tileSize / 2);
 		Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
 		Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
-		drawElement(EMapCacheType::ROADS, parent->roadImages[tinfoUpper->roadType][tinfoUpper->roadDir][rotation],
+		drawElement(EMapCacheType::ROADS, parent->roadImages[tinfoUpper->roadType->fileName][tinfoUpper->roadDir][rotation],
 				&source, targetSurf, &dest);
 				&source, targetSurf, &dest);
 	}
 	}
 
 
-	if(tinfo.roadType != ROAD_NAMES[0]) //print road from this tile
+	if(tinfo.roadType->id != Road::NO_ROAD) //print road from this tile
 	{
 	{
 		ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
 		ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
 		Rect source(0, 0, tileSize, halfTileSizeCeil);
 		Rect source(0, 0, tileSize, halfTileSizeCeil);
 		Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
 		Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
-		drawElement(EMapCacheType::ROADS, parent->roadImages[tinfo.roadType][tinfo.roadDir][rotation],
+		drawElement(EMapCacheType::ROADS, parent->roadImages[tinfo.roadType->fileName][tinfo.roadDir][rotation],
 				&source, targetSurf, &dest);
 				&source, targetSurf, &dest);
 	}
 	}
 }
 }
@@ -814,7 +808,7 @@ void CMapHandler::CMapBlitter::drawRiver(SDL_Surface * targetSurf, const Terrain
 {
 {
 	Rect destRect(realTileRect);
 	Rect destRect(realTileRect);
 	ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
 	ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
-	drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType][tinfo.riverDir][rotation], nullptr, targetSurf, &destRect);
+	drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType->fileName][tinfo.riverDir][rotation], nullptr, targetSurf, &destRect);
 }
 }
 
 
 void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
 void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
@@ -865,7 +859,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 			if(isVisible || info->showAllTerrain)
 			if(isVisible || info->showAllTerrain)
 			{
 			{
 				drawTileTerrain(targetSurf, tinfo, tile);
 				drawTileTerrain(targetSurf, tinfo, tile);
-				if(tinfo.riverType != RIVER_NAMES[0])
+				if(tinfo.riverType->id != River::NO_RIVER)
 					drawRiver(targetSurf, tinfo);
 					drawRiver(targetSurf, tinfo);
 				drawRoad(targetSurf, tinfo, tinfoUpper);
 				drawRoad(targetSurf, tinfo, tinfoUpper);
 			}
 			}

+ 27 - 4
lib/GameConstants.h

@@ -676,10 +676,6 @@ enum class ETeleportChannelType
 	MIXED
 	MIXED
 };
 };
 
 
-
-static std::vector<std::string> RIVER_NAMES {"", "rw", "ri", "rm", "rl"};
-static std::vector<std::string> ROAD_NAMES {"", "pd", "pg", "pc"};
-
 class Obj
 class Obj
 {
 {
 public:
 public:
@@ -855,6 +851,31 @@ namespace Terrain
 	};
 	};
 }
 }
 
 
+namespace Road
+{
+	enum ERoad : ui8
+	{
+		NO_ROAD = 0,
+		DIRT_ROAD = 1,
+		GRAVEL_ROAD = 2,
+		COBBLESTONE_ROAD = 3,
+		ORIGINAL_ROAD_COUNT = COBBLESTONE_ROAD
+	};
+}
+
+namespace River
+{
+	enum ERiver : ui8
+	{
+		NO_RIVER = 0,
+		WATER_RIVER = 1,
+		ICY_RIVER = 2,
+		MUD_RIVER = 3,
+		LAVA_RIVER = 4,
+		ORIGINAL_RIVER_COUNT = LAVA_RIVER
+	};
+}
+
 namespace SecSkillLevel
 namespace SecSkillLevel
 {
 {
 	enum SecSkillLevel
 	enum SecSkillLevel
@@ -1207,6 +1228,8 @@ typedef std::pair<si64, si64> TDmgRange;
 typedef si32 TBonusSubtype;
 typedef si32 TBonusSubtype;
 typedef si32 TQuantity;
 typedef si32 TQuantity;
 typedef si8 TTerrain;
 typedef si8 TTerrain;
+typedef si8 TRoad;
+typedef si8 TRiver;
 
 
 typedef int TRmgTemplateZoneId;
 typedef int TRmgTemplateZoneId;
 
 

+ 136 - 3
lib/Terrain.cpp

@@ -19,6 +19,9 @@
 
 
 TerrainTypeHandler::TerrainTypeHandler()
 TerrainTypeHandler::TerrainTypeHandler()
 {
 {
+	initRivers();
+	initRoads();
+
 	auto allConfigs = VLC->modh->getActiveMods();
 	auto allConfigs = VLC->modh->getActiveMods();
 	allConfigs.insert(allConfigs.begin(), "core");
 	allConfigs.insert(allConfigs.begin(), "core");
 
 
@@ -97,16 +100,16 @@ TerrainTypeHandler::TerrainTypeHandler()
 			
 			
 			if(terr.second["river"].isNull())
 			if(terr.second["river"].isNull())
 			{
 			{
-				info->river = RIVER_NAMES[0];
+				info->river = River::NO_RIVER;
 			}
 			}
 			else
 			else
 			{
 			{
-				info->river = terr.second["river"].String();
+				info->river = getRiverByCode(terr.second["river"].String())->id;
 			}
 			}
 			
 			
 			if(terr.second["horseSoundId"].isNull())
 			if(terr.second["horseSoundId"].isNull())
 			{
 			{
-				info->horseSoundId = 9; //rock sound as default
+				info->horseSoundId = Terrain::ROCK; //rock sound as default
 			}
 			}
 			else
 			else
 			{
 			{
@@ -191,6 +194,61 @@ TerrainTypeHandler::TerrainTypeHandler()
 	}
 	}
 }
 }
 
 
+void TerrainTypeHandler::initRivers()
+{
+	//TODO: load from file?
+
+	const std::vector<std::string> RIVER_DELTA_TEMPLATE_NAME
+	{
+		{""},
+		{"clrdelt"},
+		{"icedelt"},
+		{"muddelt"},
+		{"lavdelt"}
+	};
+
+	const std::vector<std::pair<std::string, std::string>> RIVER_CONSTANTS =
+	{
+		{"", ""},
+		{"clrrvr", "rw"},
+		{"icyrvr", "ri"},
+		{"mudrvr", "rm"},
+		{"lavrvr", "rl"}
+	};
+
+	for (size_t i = 0; i < std::size(RIVER_CONSTANTS); i++)
+	{
+		riverTypes.emplace_back(new RiverType(RIVER_CONSTANTS[i].first, RIVER_CONSTANTS[i].second, i));
+		riverTypes[i]->deltaName = RIVER_DELTA_TEMPLATE_NAME[i];
+	}
+
+	recreateRiverMaps();
+}
+
+void TerrainTypeHandler::initRoads()
+{
+	//TODO: read from config
+
+	const std::vector<std::pair<std::string, std::string>> ROAD_CONSTANTS =
+	{
+		{"", ""},
+		{"dirtrd", "pd"},
+		{"gravrd", "pg"},
+		{"cobbrd", "pc"}
+	};
+
+	for (size_t i = 0; i < std::size(ROAD_CONSTANTS); i++)
+	{
+		roadTypes.emplace_back(new RoadType(ROAD_CONSTANTS[i].first, ROAD_CONSTANTS[i].second, i));
+	}
+	
+	roadTypes[1]->movementCost = 75;
+	roadTypes[2]->movementCost = 65;
+	roadTypes[3]->movementCost = 50;
+
+	recreateRoadMaps();
+}
+
 void TerrainTypeHandler::recreateTerrainMaps()
 void TerrainTypeHandler::recreateTerrainMaps()
 {
 {
 	for (const TerrainType * terrainInfo : objects)
 	for (const TerrainType * terrainInfo : objects)
@@ -201,11 +259,41 @@ void TerrainTypeHandler::recreateTerrainMaps()
 	}
 	}
 }
 }
 
 
+void TerrainTypeHandler::recreateRiverMaps()
+{
+	for (const RiverType * riverInfo : riverTypes)
+	{
+		riverInfoByName[riverInfo->fileName] = riverInfo;
+		riverInfoByCode[riverInfo->code] = riverInfo;
+		riverInfoById[riverInfo->id] = riverInfo;
+	}
+}
+
+void TerrainTypeHandler::recreateRoadMaps()
+{
+	for (const RoadType * roadInfo : roadTypes)
+	{
+		roadInfoByName[roadInfo->fileName] = roadInfo;
+		roadInfoByCode[roadInfo->code] = roadInfo;
+		roadInfoById[roadInfo->id] = roadInfo;
+	}
+}
+
 const std::vector<TerrainType *> & TerrainTypeHandler::terrains() const
 const std::vector<TerrainType *> & TerrainTypeHandler::terrains() const
 {
 {
 	return objects;
 	return objects;
 }
 }
 
 
+const std::vector<RiverType*>& TerrainTypeHandler::rivers() const
+{
+	return riverTypes;
+}
+
+const std::vector<RoadType*>& TerrainTypeHandler::roads() const
+{
+	return roadTypes;
+}
+
 const TerrainType* TerrainTypeHandler::getInfoByName(const std::string& terrainName) const
 const TerrainType* TerrainTypeHandler::getInfoByName(const std::string& terrainName) const
 {
 {
 	return terrainInfoByName.at(terrainName);
 	return terrainInfoByName.at(terrainName);
@@ -221,6 +309,36 @@ const TerrainType* TerrainTypeHandler::getInfoById(TTerrain id) const
 	return terrainInfoById.at(id);
 	return terrainInfoById.at(id);
 }
 }
 
 
+const RiverType* TerrainTypeHandler::getRiverByName(const std::string& riverName) const
+{
+	return riverInfoByName.at(riverName);
+}
+
+const RiverType* TerrainTypeHandler::getRiverByCode(const std::string& riverCode) const
+{
+	return riverInfoByCode.at(riverCode);
+}
+
+const RiverType* TerrainTypeHandler::getRiverById(TRiver id) const
+{
+	return riverInfoById.at(id);
+}
+
+const RoadType* TerrainTypeHandler::getRoadByName(const std::string& roadName) const
+{
+	return roadInfoByName.at(roadName);
+}
+
+const RoadType* TerrainTypeHandler::getRoadByCode(const std::string& roadCode) const
+{
+	return roadInfoByCode.at(roadCode);
+}
+
+const RoadType* TerrainTypeHandler::getRoadById(TRoad id) const
+{
+	return roadInfoById.at(id);
+}
+
 std::ostream & operator<<(std::ostream & os, const TerrainType & terrainType)
 std::ostream & operator<<(std::ostream & os, const TerrainType & terrainType)
 {
 {
 	return os << static_cast<const std::string &>(terrainType);
 	return os << static_cast<const std::string &>(terrainType);
@@ -293,3 +411,18 @@ bool TerrainType::isTransitionRequired() const
 {
 {
 	return transitionRequired;
 	return transitionRequired;
 }
 }
+
+RiverType::RiverType(const std::string & fileName, const std::string & code, TRiver id):
+	fileName(fileName),
+	code(code),
+	id(id)
+{
+}
+
+RoadType::RoadType(const std::string& fileName, const std::string& code, TRoad id):
+	fileName(fileName),
+	code(code),
+	id(id),
+	movementCost(GameConstants::BASE_MOVEMENT_COST)
+{
+}

+ 67 - 2
lib/Terrain.h

@@ -38,7 +38,7 @@ public:
 	std::string terrainText;
 	std::string terrainText;
 	std::string typeCode;
 	std::string typeCode;
 	std::string terrainViewPatterns;
 	std::string terrainViewPatterns;
-	std::string river;
+	TRiver river;
 
 
 	TTerrain id;
 	TTerrain id;
 	TTerrain rockTerrain;
 	TTerrain rockTerrain;
@@ -87,6 +87,45 @@ public:
 	}
 	}
 };
 };
 
 
+class DLL_LINKAGE RiverType
+{
+public:
+
+	std::string fileName;
+	std::string code;
+	std::string deltaName;
+	TRiver id;
+
+	RiverType(const std::string & fileName = "", const std::string& code = "", TRiver id = River::NO_RIVER);
+
+	template <typename Handler> void serialize(Handler& h, const int version)
+	{
+		h & fileName;
+		h & code;
+		h & deltaName;
+		h & id;
+	}
+};
+
+class DLL_LINKAGE RoadType
+{
+public:
+	std::string fileName;
+	std::string code;
+	TRoad id;
+	ui8 movementCost;
+
+	RoadType(const std::string & fileName = "", const std::string& code = "", TRoad id = Road::NO_ROAD);
+
+	template <typename Handler> void serialize(Handler& h, const int version)
+	{
+		h & fileName;
+		h & code;
+		h & id;
+		h & movementCost;
+	}
+};
+
 DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const TerrainType & terrainType);
 DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const TerrainType & terrainType);
 
 
 class DLL_LINKAGE TerrainTypeHandler //TODO: public IHandlerBase ?
 class DLL_LINKAGE TerrainTypeHandler //TODO: public IHandlerBase ?
@@ -94,32 +133,58 @@ class DLL_LINKAGE TerrainTypeHandler //TODO: public IHandlerBase ?
 public:
 public:
 
 
 	TerrainTypeHandler();
 	TerrainTypeHandler();
+	void initRivers();
+	void initRoads();
 
 
 	const std::vector<TerrainType *> & terrains() const;
 	const std::vector<TerrainType *> & terrains() const;
 	const TerrainType * getInfoByName(const std::string & terrainName) const;
 	const TerrainType * getInfoByName(const std::string & terrainName) const;
 	const TerrainType * getInfoByCode(const std::string & terrainCode) const;
 	const TerrainType * getInfoByCode(const std::string & terrainCode) const;
 	const TerrainType * getInfoById(TTerrain id) const;
 	const TerrainType * getInfoById(TTerrain id) const;
 
 
-	//TODO: road, river types?
+	const std::vector<RiverType *> & rivers() const;
+	const RiverType * getRiverByName(const std::string & riverName) const;
+	const RiverType * getRiverByCode(const std::string & riverCode) const;
+	const RiverType * getRiverById(TRiver id) const;
+
+	const std::vector<RoadType *> & roads() const;
+	const RoadType * getRoadByName(const std::string & roadName) const;
+	const RoadType * getRoadByCode(const std::string & roadCode) const;
+	const RoadType * getRoadById(TRoad id) const;
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & objects;
 		h & objects;
+		h & riverTypes;
+		h & roadTypes;
 
 
 		if (!h.saving)
 		if (!h.saving)
 		{
 		{
 			recreateTerrainMaps();
 			recreateTerrainMaps();
+			recreateRiverMaps();
+			recreateRoadMaps();
 		}
 		}
 	}
 	}
 
 
 private:
 private:
 
 
 	std::vector<TerrainType *> objects;
 	std::vector<TerrainType *> objects;
+	std::vector<RiverType *> riverTypes;
+	std::vector<RoadType *> roadTypes;
 
 
 	std::unordered_map<std::string, const TerrainType*> terrainInfoByName;
 	std::unordered_map<std::string, const TerrainType*> terrainInfoByName;
 	std::unordered_map<std::string, const TerrainType*> terrainInfoByCode;
 	std::unordered_map<std::string, const TerrainType*> terrainInfoByCode;
 	std::unordered_map<TTerrain, const TerrainType*> terrainInfoById;
 	std::unordered_map<TTerrain, const TerrainType*> terrainInfoById;
 
 
+	std::unordered_map<std::string, const RiverType*> riverInfoByName;
+	std::unordered_map<std::string, const RiverType*> riverInfoByCode;
+	std::unordered_map<TRiver, const RiverType*> riverInfoById;
+
+	std::unordered_map<std::string, const RoadType*> roadInfoByName;
+	std::unordered_map<std::string, const RoadType*> roadInfoByCode;
+	std::unordered_map<TRoad, const RoadType*> roadInfoById;
+
 	void recreateTerrainMaps();
 	void recreateTerrainMaps();
+	void recreateRiverMaps();
+	void recreateRoadMaps();
 
 
 };
 };

+ 2 - 17
lib/mapObjects/CGHeroInstance.cpp

@@ -79,24 +79,9 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile & dest, const TerrainTile & f
 	int64_t ret = GameConstants::BASE_MOVEMENT_COST;
 	int64_t ret = GameConstants::BASE_MOVEMENT_COST;
 
 
 	//if there is road both on dest and src tiles - use road movement cost
 	//if there is road both on dest and src tiles - use road movement cost
-	if(dest.roadType != ROAD_NAMES[0] && from.roadType != ROAD_NAMES[0])
+	if(dest.roadType->id && from.roadType->id)
 	{
 	{
-		int roadPos = std::min(vstd::find_pos(ROAD_NAMES, dest.roadType), vstd::find_pos(ROAD_NAMES, from.roadType)); //used road ID
-		switch(roadPos)
-		{
-		case 1:
-			ret = 75;
-			break;
-		case 2:
-			ret = 65;
-			break;
-		case 3:
-			ret = 50;
-			break;
-		default:
-			logGlobal->error("Unknown road type: %d", roadPos);
-			break;
-		}
+		ret = std::max(dest.roadType->movementCost, from.roadType->movementCost);
 	}
 	}
 	else if(ti->nativeTerrain != from.terType->id &&//the terrain is not native
 	else if(ti->nativeTerrain != from.terType->id &&//the terrain is not native
 			ti->nativeTerrain != Terrain::ANY_TERRAIN && //no special creature bonus
 			ti->nativeTerrain != Terrain::ANY_TERRAIN && //no special creature bonus

+ 8 - 8
lib/mapping/CDrawRoadsOperation.cpp

@@ -156,14 +156,14 @@ CDrawLinesOperation::CDrawLinesOperation(CMap * map, const CTerrainSelection & t
 }
 }
 
 
 ///CDrawRoadsOperation
 ///CDrawRoadsOperation
-CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & roadType, CRandomGenerator * gen):
+CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, TRoad roadType, CRandomGenerator * gen):
 	CDrawLinesOperation(map, terrainSel,gen),
 	CDrawLinesOperation(map, terrainSel,gen),
 	roadType(roadType)
 	roadType(roadType)
 {
 {
 }
 }
 
 
 ///CDrawRiversOperation
 ///CDrawRiversOperation
-CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & riverType, CRandomGenerator * gen):
+CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, TRiver riverType, CRandomGenerator * gen):
 	CDrawLinesOperation(map, terrainSel, gen),
 	CDrawLinesOperation(map, terrainSel, gen),
 	riverType(riverType)
 	riverType(riverType)
 {
 {
@@ -336,12 +336,12 @@ std::string CDrawRiversOperation::getLabel() const
 
 
 void CDrawRoadsOperation::executeTile(TerrainTile & tile)
 void CDrawRoadsOperation::executeTile(TerrainTile & tile)
 {
 {
-	tile.roadType = roadType;
+	tile.roadType = VLC->terrainTypeHandler->roads()[roadType];
 }
 }
 
 
 void CDrawRiversOperation::executeTile(TerrainTile & tile)
 void CDrawRiversOperation::executeTile(TerrainTile & tile)
 {
 {
-	tile.riverType = riverType;
+	tile.riverType = VLC->terrainTypeHandler->rivers()[riverType];
 }
 }
 
 
 bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const
 bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const
@@ -356,22 +356,22 @@ bool CDrawRiversOperation::canApplyPattern(const LinePattern & pattern) const
 
 
 bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
 bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
 {
 {
-	return tile.roadType != ROAD_NAMES[0];
+	return tile.roadType->id != Road::NO_ROAD;
 }
 }
 
 
 bool CDrawRiversOperation::needUpdateTile(const TerrainTile & tile) const
 bool CDrawRiversOperation::needUpdateTile(const TerrainTile & tile) const
 {
 {
-	return tile.riverType != RIVER_NAMES[0];
+	return tile.riverType->id != River::NO_RIVER;
 }
 }
 
 
 bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const
 bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const
 {
 {
-	return map->getTile(pos).roadType != ROAD_NAMES[0];
+	return map->getTile(pos).roadType->id != Road::NO_ROAD;
 }
 }
 
 
 bool CDrawRiversOperation::tileHasSomething(const int3& pos) const
 bool CDrawRiversOperation::tileHasSomething(const int3& pos) const
 {
 {
-	return map->getTile(pos).riverType != RIVER_NAMES[0];
+	return map->getTile(pos).riverType->id != River::NO_RIVER;
 }
 }
 
 
 void CDrawRoadsOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip)
 void CDrawRoadsOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip)

+ 4 - 4
lib/mapping/CDrawRoadsOperation.h

@@ -61,7 +61,7 @@ protected:
 class CDrawRoadsOperation : public CDrawLinesOperation
 class CDrawRoadsOperation : public CDrawLinesOperation
 {
 {
 public:
 public:
-	CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & roadType, CRandomGenerator * gen);
+	CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, TRoad roadType, CRandomGenerator * gen);
 	std::string getLabel() const override;
 	std::string getLabel() const override;
 	
 	
 protected:
 protected:
@@ -72,13 +72,13 @@ protected:
 	void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override;
 	void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override;
 	
 	
 private:
 private:
-	std::string roadType;
+	TRoad roadType;
 };
 };
 
 
 class CDrawRiversOperation : public CDrawLinesOperation
 class CDrawRiversOperation : public CDrawLinesOperation
 {
 {
 public:
 public:
-	CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & roadType, CRandomGenerator * gen);
+	CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, TRoad roadType, CRandomGenerator * gen);
 	std::string getLabel() const override;
 	std::string getLabel() const override;
 	
 	
 protected:
 protected:
@@ -89,5 +89,5 @@ protected:
 	void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override;
 	void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override;
 	
 	
 private:
 private:
-	std::string riverType;
+	TRiver riverType;
 };
 };

+ 2 - 3
lib/mapping/CMap.cpp

@@ -126,15 +126,14 @@ CCastleEvent::CCastleEvent() : town(nullptr)
 TerrainTile::TerrainTile():
 TerrainTile::TerrainTile():
 	terType(nullptr),
 	terType(nullptr),
 	terView(0),
 	terView(0),
-	riverType(RIVER_NAMES[0]),
 	riverDir(0),
 	riverDir(0),
-	roadType(ROAD_NAMES[0]),
 	roadDir(0),
 	roadDir(0),
 	extTileFlags(0),
 	extTileFlags(0),
 	visitable(false),
 	visitable(false),
 	blocked(false)
 	blocked(false)
 {
 {
-
+	riverType = VLC->terrainTypeHandler->rivers()[0];
+	roadType = VLC->terrainTypeHandler->roads()[0];
 }
 }
 
 
 bool TerrainTile::entrableTerrain(const TerrainTile * from) const
 bool TerrainTile::entrableTerrain(const TerrainTile * from) const

+ 2 - 2
lib/mapping/CMapDefines.h

@@ -82,9 +82,9 @@ struct DLL_LINKAGE TerrainTile
 
 
 	TerrainType * terType;
 	TerrainType * terType;
 	ui8 terView;
 	ui8 terView;
-	std::string riverType;
+	RiverType * riverType;
 	ui8 riverDir;
 	ui8 riverDir;
-	std::string roadType; //TODO: switch to ui8
+	RoadType * roadType;
 	ui8 roadDir;
 	ui8 roadDir;
 	/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
 	/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
 	///	7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect
 	///	7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect

+ 2 - 2
lib/mapping/CMapEditManager.cpp

@@ -130,13 +130,13 @@ void CMapEditManager::drawTerrain(TTerrain terType, CRandomGenerator * gen)
 	terrainSel.clearSelection();
 	terrainSel.clearSelection();
 }
 }
 
 
-void CMapEditManager::drawRoad(const std::string & roadType, CRandomGenerator* gen)
+void CMapEditManager::drawRoad(TRoad roadType, CRandomGenerator* gen)
 {
 {
 	execute(make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : &(this->gen)));
 	execute(make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : &(this->gen)));
 	terrainSel.clearSelection();
 	terrainSel.clearSelection();
 }
 }
 
 
-void CMapEditManager::drawRiver(const std::string & riverType, CRandomGenerator* gen)
+void CMapEditManager::drawRiver(TRiver riverType, CRandomGenerator* gen)
 {
 {
 	execute(make_unique<CDrawRiversOperation>(map, terrainSel, riverType, gen ? gen : &(this->gen)));
 	execute(make_unique<CDrawRiversOperation>(map, terrainSel, riverType, gen ? gen : &(this->gen)));
 	terrainSel.clearSelection();
 	terrainSel.clearSelection();

+ 2 - 2
lib/mapping/CMapEditManager.h

@@ -73,10 +73,10 @@ public:
 	void drawTerrain(TTerrain terType, CRandomGenerator * gen = nullptr);
 	void drawTerrain(TTerrain terType, CRandomGenerator * gen = nullptr);
 
 
 	/// Draws roads at the current terrain selection. The selection will be cleared automatically.
 	/// Draws roads at the current terrain selection. The selection will be cleared automatically.
-	void drawRoad(const std::string & roadType, CRandomGenerator * gen = nullptr);
+	void drawRoad(TRoad roadType, CRandomGenerator * gen = nullptr);
 	
 	
 	/// Draws rivers at the current terrain selection. The selection will be cleared automatically.
 	/// Draws rivers at the current terrain selection. The selection will be cleared automatically.
-	void drawRiver(const std::string & riverType, CRandomGenerator * gen = nullptr);
+	void drawRiver(TRiver riverType, CRandomGenerator * gen = nullptr);
 
 
 	void insertObject(CGObjectInstance * obj);
 	void insertObject(CGObjectInstance * obj);
 	void insertObjects(std::set<CGObjectInstance *> & objects);
 	void insertObjects(std::set<CGObjectInstance *> & objects);

+ 5 - 8
lib/mapping/MapFormatH3M.cpp

@@ -922,16 +922,13 @@ void CMapLoaderH3M::readTerrain()
 {
 {
 	map->initTerrain();
 	map->initTerrain();
 	const auto terrains = VLC->terrainTypeHandler->terrains();
 	const auto terrains = VLC->terrainTypeHandler->terrains();
+	const auto rivers = VLC->terrainTypeHandler->rivers();
+	const auto roads = VLC->terrainTypeHandler->roads();
 
 
 	// Read terrain
 	// Read terrain
 	int3 pos;
 	int3 pos;
-	for(pos.z = 0; pos.z < 2; ++pos.z)
+	for(pos.z = 0; pos.z < map->levels(); ++pos.z)
 	{
 	{
-		if(pos.z == 1 && !map->twoLevel)
-		{
-			break;
-		}
-
 		//OH3 format is [z][y][x]
 		//OH3 format is [z][y][x]
 		for(pos.y = 0; pos.y < map->height; pos.y++)
 		for(pos.y = 0; pos.y < map->height; pos.y++)
 		{
 		{
@@ -940,9 +937,9 @@ void CMapLoaderH3M::readTerrain()
 				auto & tile = map->getTile(pos);
 				auto & tile = map->getTile(pos);
 				tile.terType = terrains[reader.readUInt8()];
 				tile.terType = terrains[reader.readUInt8()];
 				tile.terView = reader.readUInt8();
 				tile.terView = reader.readUInt8();
-				tile.riverType = RIVER_NAMES[reader.readUInt8()];
+				tile.riverType = rivers[reader.readUInt8()];
 				tile.riverDir = reader.readUInt8();
 				tile.riverDir = reader.readUInt8();
-				tile.roadType = ROAD_NAMES[reader.readUInt8()];
+				tile.roadType = roads[reader.readUInt8()];
 				tile.roadDir = reader.readUInt8();
 				tile.roadDir = reader.readUInt8();
 				tile.extTileFlags = reader.readUInt8();
 				tile.extTileFlags = reader.readUInt8();
 				tile.blocked = ((!tile.terType->isPassable() || tile.terType->id == Terrain::BORDER ) ? true : false); //underground tiles are always blocked
 				tile.blocked = ((!tile.terType->isPassable() || tile.terType->id == Terrain::BORDER ) ? true : false); //underground tiles are always blocked

+ 98 - 87
lib/mapping/MapFormatJson.cpp

@@ -942,96 +942,107 @@ void CMapLoaderJson::readHeader(const bool complete)
 
 
 void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile)
 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
 			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];
 	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];
 		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];
 		out << tile.riverType << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
 
 
 	return out.str();
 	return out.str();

+ 0 - 1
lib/rmg/Functions.cpp

@@ -135,7 +135,6 @@ void initTerrainType(Zone & zone, CMapGenerator & gen)
 		}
 		}
 		
 		
 		//Now, replace disallowed terrains on surface and in the underground
 		//Now, replace disallowed terrains on surface and in the underground
-		//TODO: allow new types of terrain?
 		const auto* terrainType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()];
 		const auto* terrainType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()];
 
 
 		if(zone.isUnderground())
 		if(zone.isUnderground())

+ 7 - 12
lib/rmg/RiverPlacer.cpp

@@ -22,15 +22,9 @@
 #include "WaterProxy.h"
 #include "WaterProxy.h"
 #include "RoadPlacer.h"
 #include "RoadPlacer.h"
 
 
+//TODO: move to Obj:: ?
 const int RIVER_DELTA_ID = 143;
 const int RIVER_DELTA_ID = 143;
 const int RIVER_DELTA_SUBTYPE = 0;
 const int RIVER_DELTA_SUBTYPE = 0;
-const std::map<std::string, std::string> RIVER_DELTA_TEMPLATE_NAME
-{
-	{RIVER_NAMES[1], "clrdelt"},
-	{RIVER_NAMES[2], "icedelt"},
-	{RIVER_NAMES[3], "muddelt"},
-	{RIVER_NAMES[4], "lavdelt"}
-};
 
 
 const std::array<std::array<int, 25>, 4> deltaTemplates
 const std::array<std::array<int, 25>, 4> deltaTemplates
 {
 {
@@ -238,7 +232,7 @@ void RiverPlacer::preprocess()
 						deltaOrientations[p] = templateId + 1;
 						deltaOrientations[p] = templateId + 1;
 						
 						
 						//specific case: deltas for ice rivers amd mud rivers are messed :(
 						//specific case: deltas for ice rivers amd mud rivers are messed :(
-						if(river == RIVER_NAMES[2])
+						if(river == River::ICY_RIVER)
 						{
 						{
 							switch(deltaOrientations[p])
 							switch(deltaOrientations[p])
 							{
 							{
@@ -256,7 +250,7 @@ void RiverPlacer::preprocess()
 									break;
 									break;
 							}
 							}
 						}
 						}
-						if(river == RIVER_NAMES[3])
+						if(river == River::MUD_RIVER)
 						{
 						{
 							switch(deltaOrientations[p])
 							switch(deltaOrientations[p])
 							{
 							{
@@ -326,8 +320,9 @@ void RiverPlacer::preprocess()
 
 
 void RiverPlacer::connectRiver(const int3 & tile)
 void RiverPlacer::connectRiver(const int3 & tile)
 {
 {
-	auto river = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()]->river;
-	if(river.empty() || river == RIVER_NAMES[0])
+	auto riverType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()]->river;
+	auto river = VLC->terrainTypeHandler->rivers()[riverType];
+	if(river->id == River::NO_RIVER)
 		return;
 		return;
 	
 	
 	rmg::Area roads;
 	rmg::Area roads;
@@ -386,7 +381,7 @@ void RiverPlacer::connectRiver(const int3 & tile)
 			if(tmplates.size() % 4 != 0)
 			if(tmplates.size() % 4 != 0)
 				throw rmgException(boost::to_string(boost::format("River templates for (%d,%d) at terrain %s, river %s are incorrect") % RIVER_DELTA_ID % RIVER_DELTA_SUBTYPE % zone.getTerrainType() % river));
 				throw rmgException(boost::to_string(boost::format("River templates for (%d,%d) at terrain %s, river %s are incorrect") % RIVER_DELTA_ID % RIVER_DELTA_SUBTYPE % zone.getTerrainType() % river));
 			
 			
-			std::string targetTemplateName = RIVER_DELTA_TEMPLATE_NAME.at(river) + std::to_string(deltaOrientations[pos]) + ".def";
+			std::string targetTemplateName = river->deltaName + std::to_string(deltaOrientations[pos]) + ".def";
 			for(auto & templ : tmplates)
 			for(auto & templ : tmplates)
 			{
 			{
 				if(templ->animationFile == targetTemplateName)
 				if(templ->animationFile == targetTemplateName)

+ 1 - 1
lib/rmg/RmgMap.cpp

@@ -229,7 +229,7 @@ void RmgMap::setOccupied(const int3 &tile, ETileType::ETileType state)
 	tiles[tile.x][tile.y][tile.z].setOccupied(state);
 	tiles[tile.x][tile.y][tile.z].setOccupied(state);
 }
 }
 
 
-void RmgMap::setRoad(const int3& tile, const std::string & roadType)
+void RmgMap::setRoad(const int3& tile, TRoad roadType)
 {
 {
 	assertOnMap(tile);
 	assertOnMap(tile);
 	
 	

+ 1 - 1
lib/rmg/RmgMap.h

@@ -44,7 +44,7 @@ public:
 	bool isOnMap(const int3 & tile) const;
 	bool isOnMap(const int3 & tile) const;
 	
 	
 	void setOccupied(const int3 &tile, ETileType::ETileType state);
 	void setOccupied(const int3 &tile, ETileType::ETileType state);
-	void setRoad(const int3 &tile, const std::string & roadType);
+	void setRoad(const int3 &tile, TRoad roadType);
 	
 	
 	TileInfo getTile(const int3 & tile) const;
 	TileInfo getTile(const int3 & tile) const;
 		
 		

+ 2 - 1
lib/rmg/RoadPlacer.cpp

@@ -69,7 +69,8 @@ void RoadPlacer::drawRoads(bool secondary)
 	zone.areaPossible().subtract(roads);
 	zone.areaPossible().subtract(roads);
 	zone.freePaths().unite(roads);
 	zone.freePaths().unite(roads);
 	map.getEditManager()->getTerrainSelection().setSelection(roads.getTilesVector());
 	map.getEditManager()->getTerrainSelection().setSelection(roads.getTilesVector());
-	std::string roadType = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
+	std::string roadCode = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
+	TRoad roadType = VLC->terrainTypeHandler->getRoadByCode(roadCode)->id;
 	map.getEditManager()->drawRoad(roadType, &generator.rand);
 	map.getEditManager()->drawRoad(roadType, &generator.rand);
 }
 }
 
 

+ 3 - 3
lib/rmg/TileInfo.cpp

@@ -44,7 +44,7 @@ bool TileInfo::isFree() const
 
 
 bool TileInfo::isRoad() const
 bool TileInfo::isRoad() const
 {
 {
-	return roadType != ROAD_NAMES[0];
+	return roadType != Road::NO_ROAD;
 }
 }
 
 
 bool TileInfo::isUsed() const
 bool TileInfo::isUsed() const
@@ -71,8 +71,8 @@ void TileInfo::setTerrainType(TTerrain type)
 	terrain = type;
 	terrain = type;
 }
 }
 
 
-void TileInfo::setRoadType(const std::string & value)
+void TileInfo::setRoadType(TRoad type)
 {
 {
-	roadType = value;
+	roadType = type;
 	//	setOccupied(ETileType::FREE);
 	//	setOccupied(ETileType::FREE);
 }
 }

+ 2 - 2
lib/rmg/TileInfo.h

@@ -32,10 +32,10 @@ public:
 	ETileType::ETileType getTileType() const;
 	ETileType::ETileType getTileType() const;
 	void setTerrainType(TTerrain value);
 	void setTerrainType(TTerrain value);
 	
 	
-	void setRoadType(const std::string & value);
+	void setRoadType(TRoad type);
 private:
 private:
 	float nearestObjectDistance;
 	float nearestObjectDistance;
 	ETileType::ETileType occupied;
 	ETileType::ETileType occupied;
 	TTerrain terrain;
 	TTerrain terrain;
-	std::string roadType;
+	TRoad roadType;
 };
 };