From 4fa7f0e93df1d7c6ca8346d6e0df61345c5ff19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Fri, 12 Apr 2024 10:25:13 +0200 Subject: [PATCH] Also allow filtering biomes by faction(s) --- config/biomes.json | 57 +++++++++++++++++++------ config/schemas/biome.json | 13 ++++++ config/schemas/mod.json | 5 +++ lib/mapObjects/ObstacleSetHandler.cpp | 47 +++++++++++++++++++- lib/mapObjects/ObstacleSetHandler.h | 8 +++- lib/mapping/ObstacleProxy.cpp | 4 -- lib/rmg/modificators/ObstaclePlacer.cpp | 4 +- 7 files changed, 115 insertions(+), 23 deletions(-) diff --git a/config/biomes.json b/config/biomes.json index 9aeb464b7..cf62a0728 100644 --- a/config/biomes.json +++ b/config/biomes.json @@ -174,7 +174,7 @@ }, "templates" : ["AVXrk0", "AVXrk1", "AVXrk2", "AVXrk3", "AVXrk4", "AVXrk5", "AVXrk6", "AVXrk7"] }, - "templateSet29":{ + "cactus":{ "biome":{ "terrain" : "sand", "objectType" : "plant" @@ -209,12 +209,19 @@ }, "templates" : ["AVLskul0"] }, - "templateSet37":{ + "sandPalms":{ "biome":{ "terrain" : "sand", "objectType" : "tree" }, - "templates" : ["AVLplm10", "AVLplm20", "AVLplm30", "AVLplm40", "AVLplm50", "AVLyuc10", "AVLyuc20", "AVLyuc30"] + "templates" : ["AVLplm10", "AVLplm20", "AVLplm30", "AVLplm40", "AVLplm50"] + }, + "sandYucca":{ + "biome":{ + "terrain" : "sand", + "objectType" : "plant" + }, + "templates" : ["AVLyuc10", "AVLyuc20", "AVLyuc30"] }, "templateSet38":{ "biome":{ @@ -405,9 +412,10 @@ }, "templates" : ["AvLStm1", "AvLStm2", "AvLStm3"] }, - "templateSet64":{ + "swampTreesOnGrass":{ "biome":{ "terrain" : "grass", + "faction" : "fortress", "objectType" : "tree" }, "templates" : ["AVLswmp0", "AVLswmp1", "AVLswmp2", "AVLswmp3", "AVLswmp4", "AVLswmp5", "AVLswmp6", "AVLswmp7", "AVLtr1d0", "AVLtr2d0", "AVLtr3d0", "AVLwlw10", "AVLwlw20", "AVLwlw30"] @@ -650,7 +658,7 @@ }, "templates" : ["AVLmtsw1", "AVLmtsw2", "AVLmtsw3", "AVLmtsw4", "AVLmtsw5", "AVLmtsw6"] }, - "templateSet106":{ + "swampTrees":{ "biome":{ "terrain" : "swamp", "objectType" : "tree" @@ -671,19 +679,33 @@ }, "templates" : ["AVLs01s0", "AVLs02s0", "AVLs03s0", "AVLs04s0", "AVLs05s0", "AVLs06s0", "AVLs07s0", "AVLs08s0", "AVLs09s0", "AVLs10s0", "AVLs11s0", "AVLswp10", "AVLswp20", "AVLswp30", "AVLswp40"] }, - "templateSet110":{ + "floodedPalms":{ "biome":{ "terrain" : "swamp", "objectType" : "tree" }, - "templates" : ["AVLswmp0", "AVLswmp1", "AVLswmp2", "AVLswmp3", "AVLswmp4", "AVLswmp5", "AVLswmp6", "AVLswmp7", "AVLtr1d0", "AVLtr2d0", "AVLtr3d0", "AVLwlw10", "AVLwlw20", "AVLwlw30"] + "templates" : ["AVLswmp0", "AVLswmp1", "AVLswmp2", "AVLswmp3", "AVLswmp4", "AVLswmp5", "AVLswmp6", "AVLswmp7"] }, - "templateSet111":{ + "swampTrees2":{ "biome":{ "terrain" : "swamp", - "objectType" : "other" + "objectType" : "tree" }, - "templates" : ["avlswtr0", "avlswtr1", "avlswtr2", "avlswtr3", "avlswtr4", "avlswtr5", "avlswtr6", "avlswtr7", "avlswtr8", "avlswtr9", "avlswt00", "avlswt01", "avlswt02", "avlswt03", "avlswt04", "avlswt05", "avlswt06", "avlswt07", "avlswt08", "avlswt09", "avlswt10", "avlswt11", "avlswt12", "avlswt13", "avlswt14", "avlswt15", "avlswt16", "avlswt17", "avlswt18", "avlswt19"] + "templates" : ["AVLtr1d0", "AVLtr2d0", "AVLtr3d0", "AVLwlw10", "AVLwlw20", "AVLwlw30"] + }, + "swampPalms":{ + "biome":{ + "terrain" : "swamp", + "objectType" : "tree" + }, + "templates" : ["avlswtr0", "avlswtr1", "avlswtr2", "avlswtr3", "avlswtr4", "avlswtr5", "avlswtr6", "avlswtr7", "avlswtr8", "avlswtr9"] + }, + "swampSinglePalms":{ + "biome":{ + "terrain" : "swamp", + "objectType" : "plant" + }, + "templates" : ["avlswt00", "avlswt01", "avlswt02", "avlswt03", "avlswt04", "avlswt05", "avlswt06", "avlswt07", "avlswt08", "avlswt09", "avlswt10", "avlswt11", "avlswt12", "avlswt13", "avlswt14", "avlswt15", "avlswt16", "avlswt17", "avlswt18", "avlswt19"] }, "templateSet112":{ "biome":{ @@ -818,12 +840,19 @@ }, "templates" : ["AvLdlog", "AvLStm1", "AvLStm2", "AvLStm3"] }, - "templateSet137":{ + "roughSmallTree":{ "biome":{ "terrain" : "rough", - "objectType" : "tree" + "objectType" : "plant" }, - "templates" : ["AVLroug0", "AVLroug1", "AVLroug2", "AVLyuc10", "AVLyuc20", "AVLyuc30"] + "templates" : ["AVLroug0", "AVLroug1", "AVLroug2"] + }, + "roughYucca":{ + "biome":{ + "terrain" : "rough", + "objectType" : "plant" + }, + "templates" : ["AVLyuc10", "AVLyuc20", "AVLyuc30"] }, "roughLake":{ "biome":{ @@ -1070,7 +1099,7 @@ }, "templates" : ["AVLmtvo1", "AVLmtvo2", "AVLmtvo3", "AVLmtvo4", "AVLmtvo5", "AVLmtvo6"] }, - "templateSet182":{ + "volcanos":{ "biome":{ "terrain" : "lava", "objectType" : "mountain" diff --git a/config/schemas/biome.json b/config/schemas/biome.json index 5d6ac6383..54e5906f8 100644 --- a/config/schemas/biome.json +++ b/config/schemas/biome.json @@ -28,6 +28,19 @@ ] }, + "faction" : { + "anyOf": [ + { + "type" : "string", + "description" : "Faction of the zone" + }, + { + "type" : "array", + "items" : { "type" : "string" }, + "description" : "Factions of the zone" + } + ] + }, "alignment" : { "anyOf": [ { diff --git a/config/schemas/mod.json b/config/schemas/mod.json index 36bc7baa8..e9ca88dd2 100644 --- a/config/schemas/mod.json +++ b/config/schemas/mod.json @@ -255,6 +255,11 @@ "description" : "List of configuration files for objects", "items" : { "type" : "string", "format" : "textFile" } }, + "biomes" : { + "type" : "array", + "description" : "List of configuration files for biomes", + "items" : { "type" : "string", "format" : "textFile" } + }, "bonuses" : { "type" : "array", "description" : "List of configuration files for bonuses", diff --git a/lib/mapObjects/ObstacleSetHandler.cpp b/lib/mapObjects/ObstacleSetHandler.cpp index a33b8fda9..7842cd5fd 100644 --- a/lib/mapObjects/ObstacleSetHandler.cpp +++ b/lib/mapObjects/ObstacleSetHandler.cpp @@ -33,16 +33,18 @@ void ObstacleSet::addObstacle(std::shared_ptr obstacle) obstacles.push_back(obstacle); } -ObstacleSetFilter::ObstacleSetFilter(std::vector allowedTypes, TerrainId terrain = TerrainId::ANY_TERRAIN, EAlignment alignment = EAlignment::ANY): +ObstacleSetFilter::ObstacleSetFilter(std::vector allowedTypes, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY): allowedTypes(allowedTypes), terrain(terrain), + faction(faction), alignment(alignment) { } -ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain = TerrainId::ANY_TERRAIN, EAlignment alignment = EAlignment::ANY): +ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY): allowedTypes({allowedType}), terrain(terrain), + faction(faction), alignment(alignment) { } @@ -54,6 +56,15 @@ bool ObstacleSetFilter::filter(const ObstacleSet &set) const return false; } + if (faction != FactionID::ANY) + { + auto factions = set.getFactions(); + if (!factions.empty() && !vstd::contains(factions, faction)) + { + return false; + } + } + // TODO: Also check specific factions if (alignment != EAlignment::ANY) { @@ -92,6 +103,16 @@ void ObstacleSet::addTerrain(TerrainId terrain) this->allowedTerrains.insert(terrain); } +std::set ObstacleSet::getFactions() const +{ + return allowedFactions; +} + +void ObstacleSet::addFaction(FactionID faction) +{ + this->allowedFactions.insert(faction); +} + void ObstacleSet::addAlignment(EAlignment alignment) { this->allowedAlignments.insert(alignment); @@ -295,6 +316,28 @@ std::shared_ptr ObstacleSetHandler::loadFromJson(const std::string } } + auto parseFaction = [os, scope](const std::string & str) -> FactionID + { + VLC->identifiers()->requestIdentifier(scope, "faction", str, [os](si32 id) + { + os->addFaction(FactionID(id)); + }); + }; + + if (biome["faction"].isString()) + { + auto factionName = biome["faction"].String(); + parseFaction(factionName); + } + else if (biome["faction"].isVector()) + { + auto factions = biome["faction"].Vector(); + for (const auto & node : factions) + { + parseFaction(node.String()); + } + } + // TODO: Move this parser to some utils auto parseAlignment = [](const std::string & str) ->EAlignment { diff --git a/lib/mapObjects/ObstacleSetHandler.h b/lib/mapObjects/ObstacleSetHandler.h index c9960d8fe..5f044abcb 100644 --- a/lib/mapObjects/ObstacleSetHandler.h +++ b/lib/mapObjects/ObstacleSetHandler.h @@ -52,6 +52,8 @@ public: void addTerrain(TerrainId terrain); std::set getAlignments() const; void addAlignment(EAlignment alignment); + std::set getFactions() const; + void addFaction(FactionID faction); static EObstacleType typeFromString(const std::string &str); std::string toString() const; @@ -61,6 +63,7 @@ public: private: EObstacleType type; std::set allowedTerrains; + std::set allowedFactions; std::set allowedAlignments; // Empty means all std::vector> obstacles; }; @@ -70,8 +73,8 @@ typedef std::vector> TObstacleTypes; class DLL_LINKAGE ObstacleSetFilter { public: - ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain , EAlignment alignment); - ObstacleSetFilter(std::vector allowedTypes, TerrainId terrain, EAlignment alignment); + ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain, FactionID faction, EAlignment alignment); + ObstacleSetFilter(std::vector allowedTypes, TerrainId terrain, FactionID faction, EAlignment alignment); bool filter(const ObstacleSet &set) const; @@ -84,6 +87,7 @@ public: private: std::vector allowedTypes; + FactionID faction; EAlignment alignment; // TODO: Filter by faction, surface/underground, etc. const TerrainId terrain; diff --git a/lib/mapping/ObstacleProxy.cpp b/lib/mapping/ObstacleProxy.cpp index 1a37a48bb..a61f47b09 100644 --- a/lib/mapping/ObstacleProxy.cpp +++ b/lib/mapping/ObstacleProxy.cpp @@ -54,12 +54,8 @@ void ObstacleProxy::sortObstacles() bool ObstacleProxy::prepareBiome(const ObstacleSetFilter & filter, CRandomGenerator & rand) { - // FIXME: All the mountains have same ID and mostly same subID, how to differentiate them? - possibleObstacles.clear(); - // TODO: Move this logic to ObstacleSetHandler - std::vector> obstacleSets; size_t selectedSets = 0; diff --git a/lib/rmg/modificators/ObstaclePlacer.cpp b/lib/rmg/modificators/ObstaclePlacer.cpp index 40e1156f4..5694ec135 100644 --- a/lib/rmg/modificators/ObstaclePlacer.cpp +++ b/lib/rmg/modificators/ObstaclePlacer.cpp @@ -36,7 +36,9 @@ void ObstaclePlacer::process() if(!manager) return; - ObstacleSetFilter filter(ObstacleSet::EObstacleType::INVALID, zone.getTerrainType(), zone.getTownType().toFaction()->alignment); + auto faction = zone.getTownType().toFaction(); + + ObstacleSetFilter filter(ObstacleSet::EObstacleType::INVALID, zone.getTerrainType(), faction->getId(), faction->alignment); if (!prepareBiome(filter, zone.getRand())) {