From 30426b6a44e703987ec60eee6c803e308c46d589 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 24 Sep 2020 10:10:32 +0300 Subject: [PATCH] Fix: Random map generator crashes when nativeTerrain is not specified in the mod --- lib/CTownHandler.cpp | 29 ++++++++++++++++++++++++++--- lib/CTownHandler.h | 7 +++++++ lib/GameConstants.h | 6 ++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 41e6357c2..e974f1995 100644 --- a/lib/CTownHandler.cpp +++ b/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(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(terrainNum); + if (!source["town"].isNull()) { faction->town = new CTown(); diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 492e3cddd..435b8a5a5 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -298,6 +298,11 @@ class DLL_LINKAGE CTownHandler : public IHandlerBase std::map warMachinesToLoad; std::vector 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(); diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 52bf15b50..f2d80904d 100644 --- a/lib/GameConstants.h +++ b/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;