1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Changed logic for zone placement.

Now every zone can be surface, underground, or both. This is separate from water <-> land distinction.

Iand type is now a combination of flags and can take multiple values: "type": ["LAND", "WATER", "SURFACE", "SUB", "ROCK"]. In nothing is specified, terrains get LAND | SURFACE flags by default.

Non-surface zones will default to DIRT, and non-underground zones will default to SUBTERRA.
This commit is contained in:
Tomasz Zieliński 2022-09-22 18:23:31 +02:00
parent e53613caa7
commit 6aaf77812b
8 changed files with 54 additions and 52 deletions

View File

@ -1,9 +1,4 @@
{
"terrain" :
{
"undergroundAllow" : ["lava"], //others to be replaced by subterranena
"groundProhibit" : ["subterra"] //to be replaced by dirt
},
"waterZone" :
{
"treasure" :

View File

@ -103,7 +103,7 @@
"minimapBlocked" : [ 41, 40, 41 ],
"music" : "Lava.mp3",
"tiles" : "LAVATL",
"type" : "SUB",
"type" : ["SUB", "SURFACE"],
"code" : "lv",
"river" : "rl",
"battleFields" : ["lava"],

View File

@ -57,15 +57,29 @@ TerrainTypeHandler::TerrainTypeHandler()
if(terr.second["type"].isNull())
{
info->passabilityType = TerrainType::PassabilityType::LAND;
info->passabilityType = TerrainType::PassabilityType::LAND | TerrainType::PassabilityType::SURFACE;
}
else
else if (terr.second["type"].getType() == JsonNode::JsonType::DATA_VECTOR)
{
for (const auto& node : terr.second["type"].Vector())
{
//Set bits
auto s = node.String();
if (s == "LAND") info->passabilityType |= TerrainType::PassabilityType::LAND;
if (s == "WATER") info->passabilityType |= TerrainType::PassabilityType::WATER;
if (s == "ROCK") info->passabilityType |= TerrainType::PassabilityType::ROCK;
if (s == "SURFACE") info->passabilityType |= TerrainType::PassabilityType::SURFACE;
if (s == "SUB") info->passabilityType |= TerrainType::PassabilityType::SUBTERRANEAN;
}
}
else //should be string - one option only
{
auto s = terr.second["type"].String();
if(s == "LAND") info->passabilityType = TerrainType::PassabilityType::LAND;
if(s == "WATER") info->passabilityType = TerrainType::PassabilityType::WATER;
if(s == "ROCK") info->passabilityType = TerrainType::PassabilityType::ROCK;
if(s == "SUB") info->passabilityType = TerrainType::PassabilityType::SUBTERRANEAN;
if (s == "LAND") info->passabilityType = TerrainType::PassabilityType::LAND;
if (s == "WATER") info->passabilityType = TerrainType::PassabilityType::WATER;
if (s == "ROCK") info->passabilityType = TerrainType::PassabilityType::ROCK;
if (s == "SURFACE") info->passabilityType = TerrainType::PassabilityType::SURFACE;
if (s == "SUB") info->passabilityType = TerrainType::PassabilityType::SUBTERRANEAN;
}
if(terr.second["rockTerrain"].isNull())
@ -223,7 +237,7 @@ TerrainType::TerrainType(const std::string& _name):
rockTerrain(Terrain::ROCK),
moveCost(100),
horseSoundId(0),
passabilityType(PassabilityType::LAND),
passabilityType(0),
transitionRequired(false)
{
}
@ -257,17 +271,22 @@ bool TerrainType::isLand() const
bool TerrainType::isWater() const
{
return passabilityType == PassabilityType::WATER;
return passabilityType & PassabilityType::WATER;
}
bool TerrainType::isPassable() const
{
return passabilityType != PassabilityType::ROCK;
return !(passabilityType & PassabilityType::ROCK);
}
bool TerrainType::isSurface() const
{
return passabilityType & PassabilityType::SURFACE;
}
bool TerrainType::isUnderground() const
{
return passabilityType == PassabilityType::SUBTERRANEAN;
return passabilityType & PassabilityType::SUBTERRANEAN;
}
bool TerrainType::isTransitionRequired() const

View File

@ -19,12 +19,13 @@ class DLL_LINKAGE TerrainType
{
public:
enum class PassabilityType
enum PassabilityType : ui8
{
LAND,
WATER,
SUBTERRANEAN,
ROCK
LAND = 1,
WATER = 2,
SURFACE = 4,
SUBTERRANEAN = 8,
ROCK = 16
};
std::vector<std::string> battleFields;
@ -43,7 +44,7 @@ public:
TTerrain rockTerrain;
int moveCost;
int horseSoundId;
PassabilityType passabilityType;
ui8 passabilityType;
bool transitionRequired;
TerrainType(const std::string & name = "");
@ -56,7 +57,8 @@ public:
bool isLand() const;
bool isWater() const;
bool isPassable() const; //ROCK
bool isPassable() const;
bool isSurface() const;
bool isUnderground() const;
bool isTransitionRequired() const;

View File

@ -46,16 +46,7 @@ void CMapGenerator::loadConfig()
{
static const ResourceID path("config/randomMap.json");
JsonNode randomMapJson(path);
for(auto& s : randomMapJson["terrain"]["undergroundAllow"].Vector())
{
if(!s.isNull())
config.terrainUndergroundAllowed.emplace_back(VLC->terrainTypeHandler->getInfoByName(s.String())->id);
}
for(auto& s : randomMapJson["terrain"]["groundProhibit"].Vector())
{
if(!s.isNull())
config.terrainGroundProhibit.emplace_back(VLC->terrainTypeHandler->getInfoByName(s.String())->id);
}
config.shipyardGuard = randomMapJson["waterZone"]["shipyard"]["value"].Integer();
for(auto & treasure : randomMapJson["waterZone"]["treasure"].Vector())
{

View File

@ -32,8 +32,6 @@ class DLL_LINKAGE CMapGenerator: public Load::Progress
public:
struct Config
{
std::vector<TTerrain> terrainUndergroundAllowed;
std::vector<TTerrain> terrainGroundProhibit;
std::vector<CTreasureInfo> waterTreasure;
int shipyardGuard;
int mineExtraResources;

View File

@ -198,9 +198,10 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
}
else
{
if(VLC->terrainTypeHandler->terrains()[tt]->isUnderground())
const auto * terrainType = VLC->terrainTypeHandler->terrains()[tt];
if(terrainType->isUnderground() && !terrainType->isSurface())
{
//underground
//underground only
zonesOnLevel[1]++;
levels[zone.first] = 1;
}

View File

@ -134,26 +134,22 @@ void initTerrainType(Zone & zone, CMapGenerator & gen)
zone.setTerrainType(*RandomGeneratorUtil::nextItem(zone.getTerrainTypes(), gen.rand));
}
//Now, replace disallowed terrains on surface and in the underground
//TODO: allow new types of terrain?
const auto* terrainType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()];
if(zone.isUnderground())
{
if(zone.isUnderground())
if(!terrainType->isUnderground())
{
if(!vstd::contains(gen.getConfig().terrainUndergroundAllowed, zone.getTerrainType()))
{
//collect all underground terrain types
std::vector<TTerrain> undegroundTerrains;
for(const auto * terrain : VLC->terrainTypeHandler->terrains())
if(terrain->isUnderground())
undegroundTerrains.push_back(terrain->id);
zone.setTerrainType(*RandomGeneratorUtil::nextItem(undegroundTerrains, gen.rand));
}
zone.setTerrainType(Terrain::SUBTERRANEAN);
}
else
}
else
{
if (!terrainType->isSurface())
{
const auto* terrainType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()];
if(vstd::contains(gen.getConfig().terrainGroundProhibit, zone.getTerrainType()) || terrainType->isUnderground())
zone.setTerrainType(Terrain::DIRT);
zone.setTerrainType(Terrain::DIRT);
}
}
}