Răsfoiți Sursa

Fix: Random map generator crashes when nativeTerrain is not specified in the mod

Dmitry Orlov 5 ani în urmă
părinte
comite
30426b6a44
3 a modificat fișierele cu 39 adăugiri și 3 ștergeri
  1. 26 3
      lib/CTownHandler.cpp
  2. 7 0
      lib/CTownHandler.h
  3. 6 0
      lib/GameConstants.h

+ 26 - 3
lib/CTownHandler.cpp

@@ -708,6 +708,22 @@ void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source)
 	assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
 }
 
+ETerrainType::EETerrainType CTownHandler::getDefaultTerrainForAlignment(EAlignment::EAlignment alignment) const
+{
+	ETerrainType::EETerrainType terrain = defaultGoodTerrain;
+
+	switch(alignment)
+	{
+	case EAlignment::EAlignment::EVIL:
+		terrain = defaultEvilTerrain;
+		break;
+	case EAlignment::EAlignment::NEUTRAL:
+		terrain = defaultNeutralTerrain;
+		break;
+	}
+	return terrain;
+}
+
 CFaction * CTownHandler::loadFromJson(const JsonNode &source, const std::string & identifier)
 {
 	auto  faction = new CFaction();
@@ -718,15 +734,22 @@ CFaction * CTownHandler::loadFromJson(const JsonNode &source, const std::string
 	faction->creatureBg120 = source["creatureBackground"]["120px"].String();
 	faction->creatureBg130 = source["creatureBackground"]["130px"].String();
 
-
-	faction->nativeTerrain = ETerrainType(vstd::find_pos(GameConstants::TERRAIN_NAMES,
-		source["nativeTerrain"].String()));
 	int alignment = vstd::find_pos(EAlignment::names, source["alignment"].String());
 	if (alignment == -1)
 		faction->alignment = EAlignment::NEUTRAL;
 	else
 		faction->alignment = static_cast<EAlignment::EAlignment>(alignment);
 
+	auto nativeTerrain = source["nativeTerrain"];
+	int terrainNum = nativeTerrain.isNull()
+		? -1
+		: vstd::find_pos(GameConstants::TERRAIN_NAMES, nativeTerrain.String());
+
+	//Contructor is not called here, but operator=
+	faction->nativeTerrain = terrainNum < 0
+		? getDefaultTerrainForAlignment(faction->alignment)
+		: static_cast<ETerrainType::EETerrainType>(terrainNum);
+
 	if (!source["town"].isNull())
 	{
 		faction->town = new CTown();

+ 7 - 0
lib/CTownHandler.h

@@ -298,6 +298,11 @@ class DLL_LINKAGE CTownHandler : public IHandlerBase
 
 	std::map<CTown *, JsonNode> warMachinesToLoad;
 	std::vector<BuildingRequirementsHelper> requirementsToLoad;
+
+	const static ETerrainType::EETerrainType defaultGoodTerrain = ETerrainType::EETerrainType::GRASS;
+	const static ETerrainType::EETerrainType defaultEvilTerrain = ETerrainType::EETerrainType::LAVA;
+	const static ETerrainType::EETerrainType defaultNeutralTerrain = ETerrainType::EETerrainType::ROUGH;
+
 	void initializeRequirements();
 	void initializeWarMachines();
 
@@ -320,6 +325,8 @@ class DLL_LINKAGE CTownHandler : public IHandlerBase
 
 	void loadPuzzle(CFaction & faction, const JsonNode & source);
 
+	ETerrainType::EETerrainType getDefaultTerrainForAlignment(EAlignment::EAlignment aligment) const;
+
 	CFaction * loadFromJson(const JsonNode & data, const std::string & identifier);
 
 	void loadRandomFaction();

+ 6 - 0
lib/GameConstants.h

@@ -776,6 +776,12 @@ public:
 	ETerrainType(EETerrainType _num = WRONG) : num(_num)
 	{}
 
+	ETerrainType& operator=(EETerrainType _num)
+	{
+		num = _num;
+		return *this;
+	}
+
 	ID_LIKE_CLASS_COMMON(ETerrainType, EETerrainType)
 
 	EETerrainType num;