mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #3902 from vcmi/underground_biomes
Option to define surface or underground level for obstacle set
This commit is contained in:
commit
4769c86c82
@ -10,6 +10,7 @@ If not enough biomes are defined for [terrain type](Terrain_Format.md), map gene
|
|||||||
"obstacleSetId" : {
|
"obstacleSetId" : {
|
||||||
"biome" : {
|
"biome" : {
|
||||||
"terrain" : "grass", // Id or vector of Ids this obstacle set can spawn at
|
"terrain" : "grass", // Id or vector of Ids this obstacle set can spawn at
|
||||||
|
"level" : "underground", // or "surface", by default both
|
||||||
"faction" : ["castle", "rampart"], //Id or vector of faction Ids. Set will only be used if zone belongs to this faction
|
"faction" : ["castle", "rampart"], //Id or vector of faction Ids. Set will only be used if zone belongs to this faction
|
||||||
"alignment" : ["good", "evil", "neutral"], //Alignment of the zone. Set will only be used if zone has this alignment
|
"alignment" : ["good", "evil", "neutral"], //Alignment of the zone. Set will only be used if zone has this alignment
|
||||||
"objectType": "mountain"
|
"objectType": "mountain"
|
||||||
|
@ -19,13 +19,15 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
ObstacleSet::ObstacleSet():
|
ObstacleSet::ObstacleSet():
|
||||||
type(INVALID),
|
type(INVALID),
|
||||||
allowedTerrains({TerrainId::NONE})
|
allowedTerrains({TerrainId::NONE}),
|
||||||
|
level(EMapLevel::ANY)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleSet::ObstacleSet(EObstacleType type, TerrainId terrain):
|
ObstacleSet::ObstacleSet(EObstacleType type, TerrainId terrain):
|
||||||
type(type),
|
type(type),
|
||||||
allowedTerrains({terrain})
|
allowedTerrains({terrain}),
|
||||||
|
level(EMapLevel::ANY)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,17 +49,27 @@ void ObstacleSet::removeEmptyTemplates()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleSetFilter::ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY):
|
ObstacleSetFilter::ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes,
|
||||||
|
TerrainId terrain = TerrainId::ANY_TERRAIN,
|
||||||
|
ObstacleSet::EMapLevel level = ObstacleSet::EMapLevel::ANY,
|
||||||
|
FactionID faction = FactionID::ANY,
|
||||||
|
EAlignment alignment = EAlignment::ANY):
|
||||||
allowedTypes(allowedTypes),
|
allowedTypes(allowedTypes),
|
||||||
terrain(terrain),
|
terrain(terrain),
|
||||||
|
level(level),
|
||||||
faction(faction),
|
faction(faction),
|
||||||
alignment(alignment)
|
alignment(alignment)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY):
|
ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType,
|
||||||
|
TerrainId terrain = TerrainId::ANY_TERRAIN,
|
||||||
|
ObstacleSet::EMapLevel level = ObstacleSet::EMapLevel::ANY,
|
||||||
|
FactionID faction = FactionID::ANY,
|
||||||
|
EAlignment alignment = EAlignment::ANY):
|
||||||
allowedTypes({allowedType}),
|
allowedTypes({allowedType}),
|
||||||
terrain(terrain),
|
terrain(terrain),
|
||||||
|
level(level),
|
||||||
faction(faction),
|
faction(faction),
|
||||||
alignment(alignment)
|
alignment(alignment)
|
||||||
{
|
{
|
||||||
@ -70,6 +82,14 @@ bool ObstacleSetFilter::filter(const ObstacleSet &set) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (level != ObstacleSet::EMapLevel::ANY && set.getLevel() != ObstacleSet::EMapLevel::ANY)
|
||||||
|
{
|
||||||
|
if (level != set.getLevel())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (faction != FactionID::ANY)
|
if (faction != FactionID::ANY)
|
||||||
{
|
{
|
||||||
auto factions = set.getFactions();
|
auto factions = set.getFactions();
|
||||||
@ -117,6 +137,16 @@ void ObstacleSet::addTerrain(TerrainId terrain)
|
|||||||
this->allowedTerrains.insert(terrain);
|
this->allowedTerrains.insert(terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObstacleSet::EMapLevel ObstacleSet::getLevel() const
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObstacleSet::setLevel(ObstacleSet::EMapLevel newLevel)
|
||||||
|
{
|
||||||
|
level = newLevel;
|
||||||
|
}
|
||||||
|
|
||||||
std::set<FactionID> ObstacleSet::getFactions() const
|
std::set<FactionID> ObstacleSet::getFactions() const
|
||||||
{
|
{
|
||||||
return allowedFactions;
|
return allowedFactions;
|
||||||
@ -248,6 +278,22 @@ std::string ObstacleSet::toString() const
|
|||||||
return OBSTACLE_TYPE_STRINGS.at(type);
|
return OBSTACLE_TYPE_STRINGS.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObstacleSet::EMapLevel ObstacleSet::levelFromString(const std::string &str)
|
||||||
|
{
|
||||||
|
static const std::map<std::string, EMapLevel> LEVEL_NAMES =
|
||||||
|
{
|
||||||
|
{"surface", SURFACE},
|
||||||
|
{"underground", UNDERGROUND}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (LEVEL_NAMES.find(str) != LEVEL_NAMES.end())
|
||||||
|
{
|
||||||
|
return LEVEL_NAMES.at(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Invalid map level: " + str);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ObstacleSet::EObstacleType> ObstacleSetFilter::getAllowedTypes() const
|
std::vector<ObstacleSet::EObstacleType> ObstacleSetFilter::getAllowedTypes() const
|
||||||
{
|
{
|
||||||
return allowedTypes;
|
return allowedTypes;
|
||||||
@ -325,6 +371,12 @@ std::shared_ptr<ObstacleSet> ObstacleSetHandler::loadFromJson(const std::string
|
|||||||
logMod->error("No terrain specified for obstacle set %s", name);
|
logMod->error("No terrain specified for obstacle set %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (biome["level"].isString())
|
||||||
|
{
|
||||||
|
auto level = biome["level"].String();
|
||||||
|
os->setLevel(ObstacleSet::levelFromString(level));
|
||||||
|
}
|
||||||
|
|
||||||
auto handleFaction = [os, scope](const std::string & str)
|
auto handleFaction = [os, scope](const std::string & str)
|
||||||
{
|
{
|
||||||
VLC->identifiers()->requestIdentifier(scope, "faction", str, [os](si32 id)
|
VLC->identifiers()->requestIdentifier(scope, "faction", str, [os](si32 id)
|
||||||
|
@ -37,6 +37,14 @@ public:
|
|||||||
ANIMALS, // Living, or bones
|
ANIMALS, // Living, or bones
|
||||||
OTHER // Crystals, shipwrecks, barrels, etc.
|
OTHER // Crystals, shipwrecks, barrels, etc.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EMapLevel // TODO: Move somewhere to map definitions
|
||||||
|
{
|
||||||
|
ANY = -1,
|
||||||
|
SURFACE = 0,
|
||||||
|
UNDERGROUND = 1
|
||||||
|
};
|
||||||
|
|
||||||
ObstacleSet();
|
ObstacleSet();
|
||||||
explicit ObstacleSet(EObstacleType type, TerrainId terrain);
|
explicit ObstacleSet(EObstacleType type, TerrainId terrain);
|
||||||
|
|
||||||
@ -51,6 +59,8 @@ public:
|
|||||||
void setTerrain(TerrainId terrain);
|
void setTerrain(TerrainId terrain);
|
||||||
void setTerrains(const std::set<TerrainId> & terrains);
|
void setTerrains(const std::set<TerrainId> & terrains);
|
||||||
void addTerrain(TerrainId terrain);
|
void addTerrain(TerrainId terrain);
|
||||||
|
EMapLevel getLevel() const;
|
||||||
|
void setLevel(EMapLevel level);
|
||||||
std::set<EAlignment> getAlignments() const;
|
std::set<EAlignment> getAlignments() const;
|
||||||
void addAlignment(EAlignment alignment);
|
void addAlignment(EAlignment alignment);
|
||||||
std::set<FactionID> getFactions() const;
|
std::set<FactionID> getFactions() const;
|
||||||
@ -58,12 +68,14 @@ public:
|
|||||||
|
|
||||||
static EObstacleType typeFromString(const std::string &str);
|
static EObstacleType typeFromString(const std::string &str);
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
static EMapLevel levelFromString(const std::string &str);
|
||||||
|
|
||||||
si32 id;
|
si32 id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EObstacleType type;
|
EObstacleType type;
|
||||||
|
EMapLevel level;
|
||||||
std::set<TerrainId> allowedTerrains; // Empty means all terrains
|
std::set<TerrainId> allowedTerrains; // Empty means all terrains
|
||||||
std::set<FactionID> allowedFactions; // Empty means all factions
|
std::set<FactionID> allowedFactions; // Empty means all factions
|
||||||
std::set<EAlignment> allowedAlignments; // Empty means all alignments
|
std::set<EAlignment> allowedAlignments; // Empty means all alignments
|
||||||
@ -75,8 +87,8 @@ typedef std::vector<std::shared_ptr<ObstacleSet>> TObstacleTypes;
|
|||||||
class DLL_LINKAGE ObstacleSetFilter
|
class DLL_LINKAGE ObstacleSetFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain, FactionID faction, EAlignment alignment);
|
ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain, ObstacleSet::EMapLevel level, FactionID faction, EAlignment alignment);
|
||||||
ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain, FactionID faction, EAlignment alignment);
|
ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain, ObstacleSet::EMapLevel level, FactionID faction, EAlignment alignment);
|
||||||
|
|
||||||
bool filter(const ObstacleSet &set) const;
|
bool filter(const ObstacleSet &set) const;
|
||||||
|
|
||||||
@ -93,6 +105,7 @@ private:
|
|||||||
EAlignment alignment;
|
EAlignment alignment;
|
||||||
// TODO: Filter by faction, surface/underground, etc.
|
// TODO: Filter by faction, surface/underground, etc.
|
||||||
const TerrainId terrain;
|
const TerrainId terrain;
|
||||||
|
ObstacleSet::EMapLevel level;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Instantiate ObstacleSetHandler
|
// TODO: Instantiate ObstacleSetHandler
|
||||||
|
@ -38,7 +38,11 @@ void ObstaclePlacer::process()
|
|||||||
|
|
||||||
auto faction = zone.getTownType().toFaction();
|
auto faction = zone.getTownType().toFaction();
|
||||||
|
|
||||||
ObstacleSetFilter filter(ObstacleSet::EObstacleType::INVALID, zone.getTerrainType(), faction->getId(), faction->alignment);
|
ObstacleSetFilter filter(ObstacleSet::EObstacleType::INVALID,
|
||||||
|
zone.getTerrainType(),
|
||||||
|
static_cast<ObstacleSet::EMapLevel>(zone.isUnderground()),
|
||||||
|
faction->getId(),
|
||||||
|
faction->alignment);
|
||||||
|
|
||||||
if (!prepareBiome(filter, zone.getRand()))
|
if (!prepareBiome(filter, zone.getRand()))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user