mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Moved roads and rivers to TerrainTypeHandler, by analogy to TerrainType.
This commit is contained in:
@@ -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, riverFiles);
|
||||||
loadFlipped(riverAnimations, riverImages, RIVER_FILES);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
139
lib/Terrain.cpp
139
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
ret = std::max(dest.roadType->movementCost, from.roadType->movementCost);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
try
|
||||||
{//terrain type
|
{
|
||||||
const std::string typeCode = src.substr(0, 2);
|
using namespace TerrainDetail;
|
||||||
tile.terType = const_cast<TerrainType *>(VLC->terrainTypeHandler->getInfoByCode(typeCode));
|
{//terrain type
|
||||||
}
|
const std::string typeCode = src.substr(0, 2);
|
||||||
int startPos = 2; //0+typeCode fixed length
|
tile.terType = const_cast<TerrainType*>(VLC->terrainTypeHandler->getInfoByCode(typeCode));
|
||||||
{//terrain view
|
}
|
||||||
int pos = startPos;
|
int startPos = 2; //0+typeCode fixed length
|
||||||
while(isdigit(src.at(pos)))
|
{//terrain view
|
||||||
pos++;
|
int pos = startPos;
|
||||||
int len = pos - startPos;
|
while (isdigit(src.at(pos)))
|
||||||
if(len<=0)
|
pos++;
|
||||||
throw std::runtime_error("Invalid terrain view in "+src);
|
int len = pos - startPos;
|
||||||
const std::string rawCode = src.substr(startPos, len);
|
if (len <= 0)
|
||||||
tile.terView = atoi(rawCode.c_str());
|
throw std::runtime_error("Invalid terrain view in " + src);
|
||||||
startPos+=len;
|
const std::string rawCode = src.substr(startPos, len);
|
||||||
}
|
tile.terView = atoi(rawCode.c_str());
|
||||||
{//terrain flip
|
startPos += len;
|
||||||
int terrainFlip = vstd::find_pos(flipCodes, src.at(startPos++));
|
}
|
||||||
if(terrainFlip < 0)
|
{//terrain flip
|
||||||
throw std::runtime_error("Invalid terrain flip in "+src);
|
int terrainFlip = vstd::find_pos(flipCodes, src.at(startPos++));
|
||||||
else
|
if (terrainFlip < 0)
|
||||||
tile.extTileFlags = terrainFlip;
|
throw std::runtime_error("Invalid terrain flip in " + src);
|
||||||
}
|
else
|
||||||
if(startPos >= src.size())
|
tile.extTileFlags = terrainFlip;
|
||||||
return;
|
}
|
||||||
bool hasRoad = true;
|
if (startPos >= src.size())
|
||||||
{//road type
|
return;
|
||||||
const std::string typeCode = src.substr(startPos, 2);
|
bool hasRoad = true;
|
||||||
startPos+=2;
|
//FIXME: check without exceptions?
|
||||||
if(vstd::find_pos(ROAD_NAMES, typeCode) < 0)
|
{//road type
|
||||||
{
|
const std::string typeCode = src.substr(startPos, 2);
|
||||||
if(vstd::find_pos(RIVER_NAMES, typeCode) < 0)
|
startPos += 2;
|
||||||
throw std::runtime_error("Invalid river type in "+src);
|
try
|
||||||
else
|
{
|
||||||
{
|
tile.roadType = const_cast<RoadType*>(VLC->terrainTypeHandler->getRoadByCode(typeCode));
|
||||||
tile.riverType = typeCode;
|
}
|
||||||
hasRoad = false;
|
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)
|
catch (const std::exception & e)
|
||||||
{//road dir
|
{
|
||||||
int pos = startPos;
|
logGlobal->error("Failed to read terrain tile: %s");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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;
|
auto riverType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()]->river;
|
||||||
if(river.empty() || river == RIVER_NAMES[0])
|
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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user