浏览代码

Allow multiple terrains per biome

Tomasz Zieliński 1 年之前
父节点
当前提交
6c9d18a85c
共有 3 个文件被更改,包括 49 次插入18 次删除
  1. 12 3
      config/schemas/biome.json
  2. 33 13
      lib/mapObjects/ObstacleSetHandler.cpp
  3. 4 2
      lib/mapObjects/ObstacleSetHandler.h

+ 12 - 3
config/schemas/biome.json

@@ -15,9 +15,18 @@
 					"description" : "Type of the obstacle set"
 				},
 				"terrain" : {
-					// TODO: Allow multiple terrains
-					"type" : "string",
-					"description" : "Terrain of the obstacle set"
+					"anyOf": [
+						{
+							"type" : "string",
+							"description" : "Terrain of the obstacle set"
+						},
+						{
+							"type" : "array",
+							"items" : { "type" : "string" },
+							"description" : "Terrains of the obstacle set"
+						}
+					]
+					
 				}
 			}
 		},

+ 33 - 13
lib/mapObjects/ObstacleSetHandler.cpp

@@ -17,13 +17,13 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 ObstacleSet::ObstacleSet():
 	type(INVALID),
-	terrain(TerrainId::NONE)
+	allowedTerrains({TerrainId::NONE})
 {
 }
 
 ObstacleSet::ObstacleSet(EObstacleType type, TerrainId terrain):
 	type(type),
-	terrain(terrain)
+	allowedTerrains({terrain})
 {
 }
 
@@ -46,22 +46,27 @@ ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, Ter
 
 bool ObstacleSetFilter::filter(const ObstacleSet &set) const
 {
-	return (set.getTerrain() == terrain) || (terrain == TerrainId::ANY_TERRAIN);
+	return (vstd::contains(set.getTerrains(), terrain) || terrain == TerrainId::ANY_TERRAIN);
 }
 
-TerrainId ObstacleSetFilter::getTerrain() const
+std::set<TerrainId> ObstacleSet::getTerrains() const
 {
-	return terrain;
+	return allowedTerrains;
 }
 
-TerrainId ObstacleSet::getTerrain() const
+void ObstacleSet::setTerrain(TerrainId terrain)
 {
-	return terrain;
+	this->allowedTerrains = {terrain};
 }
 
-void ObstacleSet::setTerrain(TerrainId terrain)
+void ObstacleSet::setTerrains(const std::set<TerrainId> & terrains)
+{
+	this->allowedTerrains = terrains;
+}
+
+void ObstacleSet::addTerrain(TerrainId terrain)
 {
-	this->terrain = terrain;
+	this->allowedTerrains.insert(terrain);
 }
 
 ObstacleSet::EObstacleType ObstacleSet::getType() const
@@ -221,12 +226,27 @@ std::shared_ptr<ObstacleSet> ObstacleSetHandler::loadFromJson(const std::string
 	auto biome = json["biome"].Struct();
 	os->setType(ObstacleSet::typeFromString(biome["objectType"].String()));
 
-	auto terrainName = biome["terrain"].String();
+	if (biome["terrain"].isString())
+	{
+		auto terrainName = biome["terrain"].String();
 
-	VLC->identifiers()->requestIdentifier(scope, "terrain", terrainName, [os](si32 id)
+		VLC->identifiers()->requestIdentifier(scope, "terrain", terrainName, [os](si32 id)
+		{
+			os->setTerrain(TerrainId(id));
+		});
+	}
+	else // Other cases won't pass validation
 	{
-		os->setTerrain(TerrainId(id));
-	});
+		auto terrains = biome["terrain"].Vector();
+
+		for (const auto & terrain : terrains)
+		{
+			VLC->identifiers()->requestIdentifier(scope, "terrain", terrain.String(), [os](si32 id)
+			{
+				os->addTerrain(TerrainId(id));
+			});
+		}
+	}
 
 	auto templates = json["templates"].Vector();
 	for (const auto & node : templates)

+ 4 - 2
lib/mapObjects/ObstacleSetHandler.h

@@ -46,8 +46,10 @@ public:
 	EObstacleType getType() const;
 	void setType(EObstacleType type);
 
-	TerrainId getTerrain() const;
+	std::set<TerrainId> getTerrains() const;
 	void setTerrain(TerrainId terrain);
+	void setTerrains(const std::set<TerrainId> & terrains);
+	void addTerrain(TerrainId terrain);
 
 	static EObstacleType typeFromString(const std::string &str);
 	std::string toString() const;
@@ -56,7 +58,7 @@ public:
 
 private:
 	EObstacleType type;
-	TerrainId terrain;
+	std::set<TerrainId> allowedTerrains;
 	std::vector<std::shared_ptr<const ObjectTemplate>> obstacles;
 };