From 700d8459ac61c3f81b184bb0ab29bd68107fc535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Sun, 9 Jul 2023 11:16:36 +0200 Subject: [PATCH] Checking flags and conditions --- lib/CHeroHandler.cpp | 3 +++ lib/CHeroHandler.h | 4 ++++ lib/mapping/CMap.cpp | 26 ++++++++++++++++++++++++++ lib/mapping/CMap.h | 4 ++++ lib/mapping/MapFormatH3M.cpp | 1 + lib/mapping/MapFormatJson.cpp | 1 + lib/rmg/CMapGenerator.cpp | 15 ++++++++++++++- 7 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 9623a3b77..bb688b39d 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -424,6 +424,9 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n hero->modScope = scope; hero->gender = node["female"].Bool() ? EHeroGender::FEMALE : EHeroGender::MALE; hero->special = node["special"].Bool(); + //Default - both false + hero->onlyOnWaterMap = node["onlyOnWaterMap"].Bool(); + hero->onlyOnMapWithoutWater = node["onlyOnMapWithoutWater"].Bool(); VLC->generaltexth->registerString(scope, hero->getNameTextID(), node["texts"]["name"].String()); VLC->generaltexth->registerString(scope, hero->getBiographyTextID(), node["texts"]["biography"].String()); diff --git a/lib/CHeroHandler.h b/lib/CHeroHandler.h index 88f8808af..3f11968fb 100644 --- a/lib/CHeroHandler.h +++ b/lib/CHeroHandler.h @@ -69,6 +69,8 @@ public: std::set spells; bool haveSpellBook = false; bool special = false; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes + bool onlyOnWaterMap; // hero will be placed only if the map contains water + bool onlyOnMapWithoutWater; // hero will be placed only if the map does not contain water EHeroGender gender = EHeroGender::MALE; // default sex: 0=male, 1=female /// Graphics @@ -114,6 +116,8 @@ public: h & haveSpellBook; h & gender; h & special; + h & onlyOnWaterMap; + h & onlyOnMapWithoutWater; h & iconSpecSmall; h & iconSpecLarge; h & portraitSmall; diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index 1533bdfbf..56792ddb5 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -554,6 +554,32 @@ void CMap::removeObject(CGObjectInstance * obj) //TOOD: Clean artifact instances (mostly worn by hero?) and quests related to this object } +bool CMap::isWaterMap() const +{ + return waterMap; +} + +bool CMap::calculateWaterContent() +{ + size_t totalTiles = height * width * levels(); + size_t waterTiles = 0; + + for(auto tile = terrain.origin(); tile < (terrain.origin() + terrain.num_elements()); ++tile) + { + if (tile->isWater()) + { + waterTiles++; + } + } + + if (waterTiles >= totalTiles / 100) //At least 1% of area is water + { + waterMap = true; + } + + return waterMap; +} + void CMap::initTerrain() { terrain.resize(boost::extents[levels()][width][height]); diff --git a/lib/mapping/CMap.h b/lib/mapping/CMap.h index 58a3568d2..7aedfad98 100644 --- a/lib/mapping/CMap.h +++ b/lib/mapping/CMap.h @@ -106,6 +106,8 @@ public: void moveObject(CGObjectInstance * obj, const int3 & dst); void removeObject(CGObjectInstance * obj); + bool isWaterMap() const; + bool calculateWaterContent(); /// Gets object of specified type on requested position const CGObjectInstance * getObjectiveObjectFrom(const int3 & pos, Obj::EObj type); @@ -146,6 +148,8 @@ public: std::map > instanceNames; + bool waterMap; + private: /// a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground boost::multi_array terrain; diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 665e38339..881dcd84e 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -969,6 +969,7 @@ void CMapLoaderH3M::readTerrain() } } } + map->calculateWaterContent(); } void CMapLoaderH3M::readObjectTemplates() diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index b25b8d758..82458b0b5 100644 --- a/lib/mapping/MapFormatJson.cpp +++ b/lib/mapping/MapFormatJson.cpp @@ -1115,6 +1115,7 @@ void CMapLoaderJson::readTerrain() readTerrainLevel(underground, 1); } + map->calculateWaterContent(); } CMapLoaderJson::MapObjectLoader::MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json): diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 2960632cf..dfed9f952 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -18,6 +18,7 @@ #include "../mapObjectConstructors/CObjectClassesHandler.h" #include "../mapping/CMapEditManager.h" #include "../CTownHandler.h" +#include "../CHeroHandler.h" #include "../StringConstants.h" #include "../filesystem/Filesystem.h" #include "CZonePlacer.h" @@ -411,6 +412,7 @@ void CMapGenerator::addHeaderInfo() m.description = getMapDescription(); m.difficulty = 1; addPlayerInfo(); + m.waterMap = (mapGenOptions.getWaterContent() != EWaterContent::EWaterContent::NONE); } int CMapGenerator::getNextMonlithIndex() @@ -452,12 +454,23 @@ const std::vector & CMapGenerator::getAllPossibleQuestArtifacts() co const std::vector CMapGenerator::getAllPossibleHeroes() const { + auto isWaterMap = map->getMap(this).isWaterMap(); //Skip heroes that were banned, including the ones placed in prisons std::vector ret; for (int j = 0; j < map->getMap(this).allowedHeroes.size(); j++) { if (map->getMap(this).allowedHeroes[j]) - ret.push_back(HeroTypeID(j)); + { + auto * h = dynamic_cast(VLC->heroTypes()->getByIndex(j)); + if ((h->onlyOnWaterMap && !isWaterMap) || (h->onlyOnMapWithoutWater && isWaterMap)) + { + continue; + } + else + { + ret.push_back(HeroTypeID(j)); + } + } } return ret; }