From 26aad172957125e51b781bba009f537bd82d8586 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Mon, 5 Mar 2018 17:05:17 +0300 Subject: [PATCH] Actually copy zone data from map generator template * fixes https://bugs.vcmi.eu/view.php?id=2482 --- lib/rmg/CMapGenerator.cpp | 26 +-- lib/rmg/CMapGenerator.h | 5 +- lib/rmg/CRmgTemplate.cpp | 302 ++++++++++++++++++++++++++++++-- lib/rmg/CRmgTemplate.h | 148 ++++++++++++++-- lib/rmg/CRmgTemplateStorage.cpp | 26 +-- lib/rmg/CRmgTemplateStorage.h | 3 +- lib/rmg/CRmgTemplateZone.cpp | 234 ++----------------------- lib/rmg/CRmgTemplateZone.h | 88 +--------- 8 files changed, 470 insertions(+), 362 deletions(-) diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 897df7f80..f122d5724 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -18,6 +18,7 @@ #include "../StringConstants.h" #include "../filesystem/Filesystem.h" #include "CZonePlacer.h" +#include "CRmgTemplateZone.h" #include "../mapObjects/CObjectClassesHandler.h" static const int3 dirs4[] = {int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0)}; @@ -273,10 +274,15 @@ void CMapGenerator::genZones() editManager->drawTerrain(ETerrainType::GRASS, &rand); auto tmpl = mapGenOptions->getMapTemplate(); - zones = tmpl->getZones(); //copy from template (refactor?) - //immediately set gen pointer before taking any actions on zones - for (auto zone : zones) - zone.second->setGenPtr(this); + zones.clear(); + for(const auto & option : tmpl->getZones()) + { + auto zone = new CRmgTemplateZone(); + zone->setOptions(option.second); + zones[zone->getId()] = zone; + //todo: move to CRmgTemplateZone constructor + zone->setGenPtr(this);//immediately set gen pointer before taking any actions on zones + } CZonePlacer placer(this); placer.placeZones(mapGenOptions, &rand); @@ -474,8 +480,8 @@ void CMapGenerator::findZonesForQuestArts() for (auto connection : mapGenOptions->getMapTemplate()->getConnections()) { - auto zoneA = connection.getZoneA(); - auto zoneB = connection.getZoneB(); + auto zoneA = zones[connection.getZoneA()]; + auto zoneB = zones[connection.getZoneB()]; if (zoneA->getId() > zoneB->getId()) { @@ -492,8 +498,8 @@ void CMapGenerator::createDirectConnections() { for (auto connection : mapGenOptions->getMapTemplate()->getConnections()) { - auto zoneA = connection.getZoneA(); - auto zoneB = connection.getZoneB(); + auto zoneA = zones[connection.getZoneA()]; + auto zoneB = zones[connection.getZoneB()]; //rearrange tiles in random order auto tilesCopy = zoneA->getTileInfo(); @@ -572,8 +578,8 @@ void CMapGenerator::createConnections2() { for (auto & connection : connectionsLeft) { - auto zoneA = connection.getZoneA(); - auto zoneB = connection.getZoneB(); + auto zoneA = zones[connection.getZoneA()]; + auto zoneB = zones[connection.getZoneB()]; int3 guardPos(-1, -1, -1); diff --git a/lib/rmg/CMapGenerator.h b/lib/rmg/CMapGenerator.h index 8ac0a2dc3..ee0627ab5 100644 --- a/lib/rmg/CMapGenerator.h +++ b/lib/rmg/CMapGenerator.h @@ -13,9 +13,8 @@ #include "../GameConstants.h" #include "../CRandomGenerator.h" #include "CMapGenOptions.h" -#include "CRmgTemplateZone.h" #include "../int3.h" -#include "CRmgTemplate.h" //for CRmgTemplateZoneConnection +#include "CRmgTemplate.h" class CMap; class CRmgTemplate; @@ -100,7 +99,7 @@ public: void setZoneID(const int3& tile, TRmgTemplateZoneId zid); private: - std::list connectionsLeft; + std::list connectionsLeft; std::map zones; std::map zonesPerFaction; ui32 zonesTotal; //zones that have their main town only diff --git a/lib/rmg/CRmgTemplate.cpp b/lib/rmg/CRmgTemplate.cpp index 3e80a86ad..1d31b0054 100644 --- a/lib/rmg/CRmgTemplate.cpp +++ b/lib/rmg/CRmgTemplate.cpp @@ -11,45 +11,323 @@ #include "StdInc.h" #include "CRmgTemplate.h" -#include "CRmgTemplateZone.h" #include "../mapping/CMap.h" +#include "../VCMI_Lib.h" +#include "../CTownHandler.h" -CRmgTemplateZoneConnection::CRmgTemplateZoneConnection() : zoneA(nullptr), zoneB(nullptr), guardStrength(0) +namespace rmg +{ + +const std::set ZoneOptions::DEFAULT_TERRAIN_TYPES = +{ + ETerrainType::DIRT, + ETerrainType::SAND, + ETerrainType::GRASS, + ETerrainType::SNOW, + ETerrainType::SWAMP, + ETerrainType::ROUGH, + ETerrainType::SUBTERRANEAN, + ETerrainType::LAVA +}; + +ZoneOptions::CTownInfo::CTownInfo() + : townCount(0), + castleCount(0), + townDensity(0), + castleDensity(0) { } -CRmgTemplateZone * CRmgTemplateZoneConnection::getZoneA() const +int ZoneOptions::CTownInfo::getTownCount() const +{ + return townCount; +} + +void ZoneOptions::CTownInfo::setTownCount(int value) +{ + if(value < 0) + throw std::runtime_error("Negative value for town count not allowed."); + townCount = value; +} + +int ZoneOptions::CTownInfo::getCastleCount() const +{ + return castleCount; +} + +void ZoneOptions::CTownInfo::setCastleCount(int value) +{ + if(value < 0) + throw std::runtime_error("Negative value for castle count not allowed."); + castleCount = value; +} + +int ZoneOptions::CTownInfo::getTownDensity() const +{ + return townDensity; +} + +void ZoneOptions::CTownInfo::setTownDensity(int value) +{ + if(value < 0) + throw std::runtime_error("Negative value for town density not allowed."); + townDensity = value; +} + +int ZoneOptions::CTownInfo::getCastleDensity() const +{ + return castleDensity; +} + +void ZoneOptions::CTownInfo::setCastleDensity(int value) +{ + if(value < 0) + throw std::runtime_error("Negative value for castle density not allowed."); + castleDensity = value; +} + +ZoneOptions::ZoneOptions() + : id(0), + type(ETemplateZoneType::PLAYER_START), + size(1), + owner(boost::none), + playerTowns(), + neutralTowns(), + matchTerrainToTown(true), + terrainTypes(DEFAULT_TERRAIN_TYPES), + townsAreSameType(false), + townTypes(), + monsterTypes(), + zoneMonsterStrength(EMonsterStrength::ZONE_NORMAL), + mines(), + treasureInfo(), + connections() +{ + +} + +ZoneOptions & ZoneOptions::operator=(const ZoneOptions & other) +{ + id = other.id; + type = other.type; + size = other.size; + owner = other.owner; + playerTowns = other.playerTowns; + neutralTowns = other.neutralTowns; + matchTerrainToTown = other.matchTerrainToTown; + terrainTypes = other.terrainTypes; + townsAreSameType = other.townsAreSameType; + townTypes = other.townTypes; + monsterTypes = other.monsterTypes; + zoneMonsterStrength = other.zoneMonsterStrength; + mines = other.mines; + treasureInfo = other.treasureInfo; + connections = other.connections; + return *this; +} + +TRmgTemplateZoneId ZoneOptions::getId() const +{ + return id; +} + +void ZoneOptions::setId(TRmgTemplateZoneId value) +{ + if(value <= 0) + throw std::runtime_error(boost::to_string(boost::format("Zone %d id should be greater than 0.") % id)); + id = value; +} + +ETemplateZoneType::ETemplateZoneType ZoneOptions::getType() const +{ + return type; +} +void ZoneOptions::setType(ETemplateZoneType::ETemplateZoneType value) +{ + type = value; +} + +int ZoneOptions::getSize() const +{ + return size; +} + +void ZoneOptions::setSize(int value) +{ + if(value <= 0) + throw std::runtime_error(boost::to_string(boost::format("Zone %d size needs to be greater than 0.") % id)); + size = value; +} + +boost::optional ZoneOptions::getOwner() const +{ + return owner; +} + +void ZoneOptions::setOwner(boost::optional value) +{ + if(value && !(*value >= 0 && *value <= PlayerColor::PLAYER_LIMIT_I)) + throw std::runtime_error(boost::to_string(boost::format ("Owner of zone %d has to be in range 0 to max player count.") % id)); + owner = value; +} + +const ZoneOptions::CTownInfo & ZoneOptions::getPlayerTowns() const +{ + return playerTowns; +} + +void ZoneOptions::setPlayerTowns(const CTownInfo & value) +{ + playerTowns = value; +} + +const ZoneOptions::CTownInfo & ZoneOptions::getNeutralTowns() const +{ + return neutralTowns; +} + +void ZoneOptions::setNeutralTowns(const CTownInfo & value) +{ + neutralTowns = value; +} + +bool ZoneOptions::getMatchTerrainToTown() const +{ + return matchTerrainToTown; +} + +void ZoneOptions::setMatchTerrainToTown(bool value) +{ + matchTerrainToTown = value; +} + +const std::set & ZoneOptions::getTerrainTypes() const +{ + return terrainTypes; +} + +void ZoneOptions::setTerrainTypes(const std::set & value) +{ + assert(value.find(ETerrainType::WRONG) == value.end() && value.find(ETerrainType::BORDER) == value.end() && + value.find(ETerrainType::WATER) == value.end() && value.find(ETerrainType::ROCK) == value.end()); + terrainTypes = value; +} + +bool ZoneOptions::getTownsAreSameType() const +{ + return townsAreSameType; +} + +void ZoneOptions::setTownsAreSameType(bool value) +{ + townsAreSameType = value; +} + +std::set ZoneOptions::getDefaultTownTypes() const +{ + std::set defaultTowns; + auto towns = VLC->townh->getDefaultAllowed(); + for(int i = 0; i < towns.size(); ++i) + { + if(towns[i]) defaultTowns.insert(i); + } + return defaultTowns; +} + +const std::set & ZoneOptions::getTownTypes() const +{ + return townTypes; +} + +void ZoneOptions::setTownTypes(const std::set & value) +{ + townTypes = value; +} + +void ZoneOptions::setMonsterTypes(const std::set & value) +{ + monsterTypes = value; +} + +void ZoneOptions::setMonsterStrength(EMonsterStrength::EMonsterStrength val) +{ + assert (vstd::iswithin(val, EMonsterStrength::ZONE_WEAK, EMonsterStrength::ZONE_STRONG)); + zoneMonsterStrength = val; +} + +void ZoneOptions::setMinesAmount(TResource res, ui16 amount) +{ + mines[res] = amount; +} + +std::map ZoneOptions::getMinesInfo() const +{ + return mines; +} + +void ZoneOptions::addTreasureInfo(const CTreasureInfo & info) +{ + treasureInfo.push_back(info); +} + +const std::vector & ZoneOptions::getTreasureInfo() const +{ + return treasureInfo; +} + +void ZoneOptions::addConnection(TRmgTemplateZoneId otherZone) +{ + connections.push_back (otherZone); +} + + +ZoneConnection::ZoneConnection() + : zoneA(-1), + zoneB(-1), + guardStrength(0) +{ + +} + + +TRmgTemplateZoneId ZoneConnection::getZoneA() const { return zoneA; } -void CRmgTemplateZoneConnection::setZoneA(CRmgTemplateZone * value) +void ZoneConnection::setZoneA(TRmgTemplateZoneId value) { zoneA = value; } -CRmgTemplateZone * CRmgTemplateZoneConnection::getZoneB() const +TRmgTemplateZoneId ZoneConnection::getZoneB() const { return zoneB; } -void CRmgTemplateZoneConnection::setZoneB(CRmgTemplateZone * value) +void ZoneConnection::setZoneB(TRmgTemplateZoneId value) { zoneB = value; } -int CRmgTemplateZoneConnection::getGuardStrength() const +int ZoneConnection::getGuardStrength() const { return guardStrength; } -void CRmgTemplateZoneConnection::setGuardStrength(int value) +void ZoneConnection::setGuardStrength(int value) { if(value < 0) throw std::runtime_error("Negative value for guard strength not allowed."); guardStrength = value; } +} + + +using namespace rmg;//todo: remove + + CRmgTemplate::CSize::CSize() : width(CMapHeader::MAP_SIZE_MIDDLE), height(CMapHeader::MAP_SIZE_MIDDLE), under(true) { @@ -185,22 +463,22 @@ void CRmgTemplate::setCpuPlayers(const CPlayerCountRange & value) cpuPlayers = value; } -const std::map & CRmgTemplate::getZones() const +const std::map & CRmgTemplate::getZones() const { return zones; } -void CRmgTemplate::setZones(const std::map & value) +void CRmgTemplate::setZones(const std::map & value) { zones = value; } -const std::list & CRmgTemplate::getConnections() const +const std::list & CRmgTemplate::getConnections() const { return connections; } -void CRmgTemplate::setConnections(const std::list & value) +void CRmgTemplate::setConnections(const std::list & value) { connections = value; } diff --git a/lib/rmg/CRmgTemplate.h b/lib/rmg/CRmgTemplate.h index fa74f8599..37e9b8f5d 100644 --- a/lib/rmg/CRmgTemplate.h +++ b/lib/rmg/CRmgTemplate.h @@ -11,27 +11,145 @@ #pragma once #include "../GameConstants.h" +#include "../ResourceSet.h" +#include "CMapGenOptions.h" -class CRmgTemplateZone; +class JsonSerializeFormat; -/// The CRmgTemplateZoneConnection describes the connection between two zones. -class DLL_LINKAGE CRmgTemplateZoneConnection +namespace ETemplateZoneType +{ + enum ETemplateZoneType + { + PLAYER_START, + CPU_START, + TREASURE, + JUNCTION + }; +} + +class DLL_LINKAGE CTreasureInfo { public: - CRmgTemplateZoneConnection(); + ui32 min; + ui32 max; + ui16 density; +}; - CRmgTemplateZone * getZoneA() const; - void setZoneA(CRmgTemplateZone * value); - CRmgTemplateZone * getZoneB() const; - void setZoneB(CRmgTemplateZone * value); +namespace rmg +{ + +class DLL_LINKAGE ZoneConnection +{ +public: + ZoneConnection(); + + TRmgTemplateZoneId getZoneA() const; + void setZoneA(TRmgTemplateZoneId value); + TRmgTemplateZoneId getZoneB() const; + void setZoneB(TRmgTemplateZoneId value); int getGuardStrength() const; /// Default: 0 void setGuardStrength(int value); private: - CRmgTemplateZone * zoneA, * zoneB; + TRmgTemplateZoneId zoneA; + TRmgTemplateZoneId zoneB; int guardStrength; }; +class DLL_LINKAGE ZoneOptions +{ +public: + static const std::set DEFAULT_TERRAIN_TYPES; + + class DLL_LINKAGE CTownInfo + { + public: + CTownInfo(); + + int getTownCount() const; /// Default: 0 + void setTownCount(int value); + int getCastleCount() const; /// Default: 0 + void setCastleCount(int value); + int getTownDensity() const; /// Default: 0 + void setTownDensity(int value); + int getCastleDensity() const; /// Default: 0 + void setCastleDensity(int value); + + private: + int townCount, castleCount, townDensity, castleDensity; + }; + + ZoneOptions(); + + ZoneOptions & operator=(const ZoneOptions & other); + + TRmgTemplateZoneId getId() const; + void setId(TRmgTemplateZoneId value); + + ETemplateZoneType::ETemplateZoneType getType() const; /// Default: ETemplateZoneType::PLAYER_START + void setType(ETemplateZoneType::ETemplateZoneType value); + + int getSize() const; /// Default: 1 + void setSize(int value); + + boost::optional getOwner() const; + void setOwner(boost::optional value); + + const CTownInfo & getPlayerTowns() const; + void setPlayerTowns(const CTownInfo & value); + const CTownInfo & getNeutralTowns() const; + void setNeutralTowns(const CTownInfo & value); + + bool getMatchTerrainToTown() const; /// Default: true + void setMatchTerrainToTown(bool value); + + const std::set & getTerrainTypes() const; /// Default: all + void setTerrainTypes(const std::set & value); + + bool getTownsAreSameType() const; /// Default: false + void setTownsAreSameType(bool value); + + std::set getDefaultTownTypes() const; + + const std::set & getTownTypes() const; /// Default: all + void setTownTypes(const std::set & value); + void setMonsterTypes(const std::set & value); + + void setMonsterStrength(EMonsterStrength::EMonsterStrength val); + + void setMinesAmount (TResource res, ui16 amount); + std::map getMinesInfo() const; + + void addTreasureInfo(const CTreasureInfo & info); + const std::vector & getTreasureInfo() const; + + void addConnection(TRmgTemplateZoneId otherZone); + +protected: + TRmgTemplateZoneId id; + ETemplateZoneType::ETemplateZoneType type; + int size; + boost::optional owner; + CTownInfo playerTowns; + CTownInfo neutralTowns; + bool matchTerrainToTown; + std::set terrainTypes; + bool townsAreSameType; + + std::set townTypes; + std::set monsterTypes; + + EMonsterStrength::EMonsterStrength zoneMonsterStrength; + + std::map mines; //obligatory mines to spawn in this zone + + std::vector treasureInfo; + + std::vector connections; //list of adjacent zones +}; + +} + /// The CRmgTemplate describes a random map template. class DLL_LINKAGE CRmgTemplate { @@ -81,10 +199,10 @@ public: void setPlayers(const CPlayerCountRange & value); const CPlayerCountRange & getCpuPlayers() const; void setCpuPlayers(const CPlayerCountRange & value); - const std::map & getZones() const; - void setZones(const std::map & value); - const std::list & getConnections() const; - void setConnections(const std::list & value); + const std::map & getZones() const; + void setZones(const std::map & value); + const std::list & getConnections() const; + void setConnections(const std::list & value); void validate() const; /// Tests template on validity and throws exception on failure @@ -92,6 +210,6 @@ private: std::string name; CSize minSize, maxSize; CPlayerCountRange players, cpuPlayers; - std::map zones; - std::list connections; + std::map zones; + std::list connections; }; diff --git a/lib/rmg/CRmgTemplateStorage.cpp b/lib/rmg/CRmgTemplateStorage.cpp index 4857928b6..04f0605f7 100644 --- a/lib/rmg/CRmgTemplateStorage.cpp +++ b/lib/rmg/CRmgTemplateStorage.cpp @@ -20,6 +20,8 @@ #include "../GameConstants.h" #include "../StringConstants.h" +using namespace rmg; + const std::map & CRmgTemplateStorage::getTemplates() const { return templates; @@ -49,10 +51,10 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const tpl->setCpuPlayers(parsePlayers(templateNode["cpu"].String())); // Parse zones - std::map zones; + std::map zones; for (const auto & zonePair : templateNode["zones"].Struct()) { - auto zone = new CRmgTemplateZone(); + auto zone = new ZoneOptions(); auto zoneId = boost::lexical_cast(zonePair.first); zone->setId(zoneId); @@ -65,7 +67,7 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const zone->setNeutralTowns(parseTemplateZoneTowns(zoneNode["neutralTowns"])); if (!zoneNode["matchTerrainToTown"].isNull()) //default : true zone->setMatchTerrainToTown(zoneNode["matchTerrainToTown"].Bool()); - zone->setTerrainTypes(parseTerrainTypes(zoneNode["terrainTypes"].Vector(), zone->getDefaultTerrainTypes())); + zone->setTerrainTypes(parseTerrainTypes(zoneNode["terrainTypes"].Vector(), ZoneOptions::DEFAULT_TERRAIN_TYPES)); if (!zoneNode["townsAreSameType"].isNull()) //default : false zone->setTownsAreSameType((zoneNode["townsAreSameType"].Bool())); @@ -119,7 +121,7 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const else { delete zone; - throw (rmgException("incorrect monster power")); + throw (std::runtime_error("incorrect monster power")); } if (!zoneNode["mines"].isNull()) @@ -206,12 +208,12 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const tpl->setZones(zones); // Parse connections - std::list connections; + std::list connections; for(const auto & connPair : templateNode["connections"].Vector()) { - CRmgTemplateZoneConnection conn; - conn.setZoneA(zones.find(boost::lexical_cast(connPair["a"].String()))->second); - conn.setZoneB(zones.find(boost::lexical_cast(connPair["b"].String()))->second); + ZoneConnection conn; + conn.setZoneA(zones.find(boost::lexical_cast(connPair["a"].String()))->second->getId()); + conn.setZoneB(zones.find(boost::lexical_cast(connPair["b"].String()))->second->getId()); conn.setGuardStrength(connPair["guard"].Float()); connections.push_back(conn); } @@ -220,8 +222,8 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const auto zones = tpl->getZones(); for (auto con : tpl->getConnections()) { - auto idA = con.getZoneA()->getId(); - auto idB = con.getZoneB()->getId(); + auto idA = con.getZoneA(); + auto idB = con.getZoneB(); zones[idA]->addConnection(idB); zones[idB]->addConnection(idA); } @@ -284,9 +286,9 @@ ETemplateZoneType::ETemplateZoneType CRmgTemplateStorage::parseZoneType(const st return it->second; } -CRmgTemplateZone::CTownInfo CRmgTemplateStorage::parseTemplateZoneTowns(const JsonNode & node) const +ZoneOptions::CTownInfo CRmgTemplateStorage::parseTemplateZoneTowns(const JsonNode & node) const { - CRmgTemplateZone::CTownInfo towns; + ZoneOptions::CTownInfo towns; towns.setTownCount(node["towns"].Float()); towns.setCastleCount(node["castles"].Float()); towns.setTownDensity(node["townDensity"].Float()); diff --git a/lib/rmg/CRmgTemplateStorage.h b/lib/rmg/CRmgTemplateStorage.h index 2acd92f61..0aba2f250 100644 --- a/lib/rmg/CRmgTemplateStorage.h +++ b/lib/rmg/CRmgTemplateStorage.h @@ -11,7 +11,6 @@ #pragma once #include "CRmgTemplate.h" -#include "CRmgTemplateZone.h" #include "../IHandlerBase.h" class JsonNode; @@ -36,7 +35,7 @@ public: private: CRmgTemplate::CSize parseMapTemplateSize(const std::string & text) const; - CRmgTemplateZone::CTownInfo parseTemplateZoneTowns(const JsonNode & node) const; + rmg::ZoneOptions::CTownInfo parseTemplateZoneTowns(const JsonNode & node) const; ETemplateZoneType::ETemplateZoneType parseZoneType(const std::string & type) const; std::set parseTownTypes(const JsonVector & townTypesVector, const std::set & defaultTownTypes) const; std::set parseTerrainTypes(const JsonVector & terTypeStrings, const std::set & defaultTerrainTypes) const; diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 437db3f99..0bdf0c0e4 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -27,64 +27,15 @@ class CMap; class CMapEditManager; //class CGObjectInstance; -CRmgTemplateZone::CTownInfo::CTownInfo() : townCount(0), castleCount(0), townDensity(0), castleDensity(0) -{ +using namespace rmg; //TODO: move all to namespace + -} void CRmgTemplateZone::addRoadNode(const int3& node) { roadNodes.insert(node); } -int CRmgTemplateZone::CTownInfo::getTownCount() const -{ - return townCount; -} - -void CRmgTemplateZone::CTownInfo::setTownCount(int value) -{ - if(value < 0) - throw rmgException("Negative value for town count not allowed."); - townCount = value; -} - -int CRmgTemplateZone::CTownInfo::getCastleCount() const -{ - return castleCount; -} - -void CRmgTemplateZone::CTownInfo::setCastleCount(int value) -{ - if(value < 0) - throw rmgException("Negative value for castle count not allowed."); - castleCount = value; -} - -int CRmgTemplateZone::CTownInfo::getTownDensity() const -{ - return townDensity; -} - -void CRmgTemplateZone::CTownInfo::setTownDensity(int value) -{ - if(value < 0) - throw rmgException("Negative value for town density not allowed."); - townDensity = value; -} - -int CRmgTemplateZone::CTownInfo::getCastleDensity() const -{ - return castleDensity; -} - -void CRmgTemplateZone::CTownInfo::setCastleDensity(int value) -{ - if(value < 0) - throw rmgException("Negative value for castle density not allowed."); - castleDensity = value; -} - CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG),roadType(ERoadType::NO_ROAD) { occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages @@ -152,21 +103,20 @@ void CTileInfo::setRoadType(ERoadType::ERoadType value) } -CRmgTemplateZone::CRmgTemplateZone() : - id(0), - type(ETemplateZoneType::PLAYER_START), - owner(boost::none), - size(1), - townsAreSameType(false), - matchTerrainToTown(true), +CRmgTemplateZone::CRmgTemplateZone() + : ZoneOptions(), townType(ETownType::NEUTRAL), terrainType (ETerrainType::GRASS), - zoneMonsterStrength(EMonsterStrength::ZONE_NORMAL), minGuardedValue(0), questArtZone(nullptr), gen(nullptr) { - terrainTypes = getDefaultTerrainTypes(); + +} + +void CRmgTemplateZone::setOptions(const ZoneOptions * options) +{ + ZoneOptions::operator=(*options); } void CRmgTemplateZone::setGenPtr(CMapGenerator * Gen) @@ -174,154 +124,6 @@ void CRmgTemplateZone::setGenPtr(CMapGenerator * Gen) gen = Gen; } -TRmgTemplateZoneId CRmgTemplateZone::getId() const -{ - return id; -} - -void CRmgTemplateZone::setId(TRmgTemplateZoneId value) -{ - if(value <= 0) - throw rmgException(boost::to_string(boost::format("Zone %d id should be greater than 0.") %id)); - id = value; -} - -ETemplateZoneType::ETemplateZoneType CRmgTemplateZone::getType() const -{ - return type; -} -void CRmgTemplateZone::setType(ETemplateZoneType::ETemplateZoneType value) -{ - type = value; -} - -int CRmgTemplateZone::getSize() const -{ - return size; -} - -void CRmgTemplateZone::setSize(int value) -{ - if(value <= 0) - throw rmgException(boost::to_string(boost::format("Zone %d size needs to be greater than 0.") % id)); - size = value; -} - -boost::optional CRmgTemplateZone::getOwner() const -{ - return owner; -} - -void CRmgTemplateZone::setOwner(boost::optional value) -{ - if(!(*value >= 0 && *value <= PlayerColor::PLAYER_LIMIT_I)) - throw rmgException(boost::to_string(boost::format ("Owner of zone %d has to be in range 0 to max player count.") %id)); - owner = value; -} - -const CRmgTemplateZone::CTownInfo & CRmgTemplateZone::getPlayerTowns() const -{ - return playerTowns; -} - -void CRmgTemplateZone::setPlayerTowns(const CTownInfo & value) -{ - playerTowns = value; -} - -const CRmgTemplateZone::CTownInfo & CRmgTemplateZone::getNeutralTowns() const -{ - return neutralTowns; -} - -void CRmgTemplateZone::setNeutralTowns(const CTownInfo & value) -{ - neutralTowns = value; -} - -bool CRmgTemplateZone::getTownsAreSameType() const -{ - return townsAreSameType; -} - -void CRmgTemplateZone::setTownsAreSameType(bool value) -{ - townsAreSameType = value; -} - -const std::set & CRmgTemplateZone::getTownTypes() const -{ - return townTypes; -} - -void CRmgTemplateZone::setTownTypes(const std::set & value) -{ - townTypes = value; -} -void CRmgTemplateZone::setMonsterTypes(const std::set & value) -{ - monsterTypes = value; -} - -std::set CRmgTemplateZone::getDefaultTownTypes() const -{ - std::set defaultTowns; - auto towns = VLC->townh->getDefaultAllowed(); - for(int i = 0; i < towns.size(); ++i) - { - if(towns[i]) defaultTowns.insert(i); - } - return defaultTowns; -} - -bool CRmgTemplateZone::getMatchTerrainToTown() const -{ - return matchTerrainToTown; -} - -void CRmgTemplateZone::setMatchTerrainToTown(bool value) -{ - matchTerrainToTown = value; -} - -const std::set & CRmgTemplateZone::getTerrainTypes() const -{ - return terrainTypes; -} - -void CRmgTemplateZone::setTerrainTypes(const std::set & value) -{ - assert(value.find(ETerrainType::WRONG) == value.end() && value.find(ETerrainType::BORDER) == value.end() && - value.find(ETerrainType::WATER) == value.end() && value.find(ETerrainType::ROCK) == value.end()); - terrainTypes = value; -} - -std::set CRmgTemplateZone::getDefaultTerrainTypes() const -{ - std::set terTypes; - static const ETerrainType::EETerrainType allowedTerTypes[] = {ETerrainType::DIRT, ETerrainType::SAND, ETerrainType::GRASS, ETerrainType::SNOW, - ETerrainType::SWAMP, ETerrainType::ROUGH, ETerrainType::SUBTERRANEAN, ETerrainType::LAVA}; - for (auto & allowedTerType : allowedTerTypes) - terTypes.insert(allowedTerType); - - return terTypes; -} - -void CRmgTemplateZone::setMinesAmount (TResource res, ui16 amount) -{ - mines[res] = amount; -} - -std::map CRmgTemplateZone::getMinesInfo() const -{ - return mines; -} - -void CRmgTemplateZone::addConnection(TRmgTemplateZoneId otherZone) -{ - connections.push_back (otherZone); -} - void CRmgTemplateZone::setQuestArtZone(CRmgTemplateZone * otherZone) { questArtZone = otherZone; @@ -332,22 +134,6 @@ std::vector CRmgTemplateZone::getConnections() const return connections; } -void CRmgTemplateZone::setMonsterStrength (EMonsterStrength::EMonsterStrength val) -{ - assert (vstd::iswithin(val, EMonsterStrength::ZONE_WEAK, EMonsterStrength::ZONE_STRONG)); - zoneMonsterStrength = val; -} - -void CRmgTemplateZone::addTreasureInfo(CTreasureInfo & info) -{ - treasureInfo.push_back(info); -} - -std::vector CRmgTemplateZone::getTreasureInfo() -{ - return treasureInfo; -} - std::set* CRmgTemplateZone::getFreePaths() { return &freePaths; diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index a1de9bcd4..bb0d013c1 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -14,7 +14,7 @@ #include "CMapGenerator.h" #include "float3.h" #include "../int3.h" -#include "../ResourceSet.h" //for TResource (?) +#include "CRmgTemplate.h" #include "../mapObjects/ObjectTemplate.h" #include //A* @@ -23,18 +23,7 @@ class CTileInfo; class int3; class CGObjectInstance; class ObjectTemplate; -class CRmgTemplateZoneConnection; -namespace ETemplateZoneType -{ - enum ETemplateZoneType - { - PLAYER_START, - CPU_START, - TREASURE, - JUNCTION - }; -} namespace EObjectPlacingResult { enum EObjectPlacingResult @@ -71,14 +60,6 @@ private: ERoadType::ERoadType roadType; }; -class DLL_LINKAGE CTreasureInfo -{ -public: - ui32 min; - ui32 max; - ui16 density; -}; - struct DLL_LINKAGE ObjectInfo { ObjectTemplate templ; @@ -105,57 +86,14 @@ struct DLL_LINKAGE CTreasurePileInfo }; /// The CRmgTemplateZone describes a zone in a template. -class DLL_LINKAGE CRmgTemplateZone +class DLL_LINKAGE CRmgTemplateZone : public rmg::ZoneOptions { public: - class DLL_LINKAGE CTownInfo - { - public: - CTownInfo(); - - int getTownCount() const; /// Default: 0 - void setTownCount(int value); - int getCastleCount() const; /// Default: 0 - void setCastleCount(int value); - int getTownDensity() const; /// Default: 0 - void setTownDensity(int value); - int getCastleDensity() const; /// Default: 0 - void setCastleDensity(int value); - - private: - int townCount, castleCount, townDensity, castleDensity; - }; - CRmgTemplateZone(); - void setGenPtr(CMapGenerator * Gen); + void setOptions(const rmg::ZoneOptions * options); - TRmgTemplateZoneId getId() const; /// Default: 0 - void setId(TRmgTemplateZoneId value); - ETemplateZoneType::ETemplateZoneType getType() const; /// Default: ETemplateZoneType::PLAYER_START - void setType(ETemplateZoneType::ETemplateZoneType value); - int getSize() const; /// Default: 1 - void setSize(int value); - boost::optional getOwner() const; - void setOwner(boost::optional value); - const CTownInfo & getPlayerTowns() const; - void setPlayerTowns(const CTownInfo & value); - const CTownInfo & getNeutralTowns() const; - void setNeutralTowns(const CTownInfo & value); - bool getTownsAreSameType() const; /// Default: false - void setTownsAreSameType(bool value); - const std::set & getTownTypes() const; /// Default: all - void setTownTypes(const std::set & value); - void setMonsterTypes(const std::set & value); - std::set getDefaultTownTypes() const; - bool getMatchTerrainToTown() const; /// Default: true - void setMatchTerrainToTown(bool value); - const std::set & getTerrainTypes() const; /// Default: all - void setTerrainTypes(const std::set & value); - std::set getDefaultTerrainTypes() const; - void setMinesAmount (TResource res, ui16 amount); - std::map getMinesInfo() const; - void setMonsterStrength (EMonsterStrength::EMonsterStrength val); + void setGenPtr(CMapGenerator * Gen); float3 getCenter() const; void setCenter(const float3 &f); @@ -198,11 +136,8 @@ public: std::vector getAccessibleOffsets (const CGObjectInstance* object); bool areAllTilesAvailable(CGObjectInstance* obj, int3& tile, std::set& tilesBlockedByObject) const; - void addConnection(TRmgTemplateZoneId otherZone); void setQuestArtZone(CRmgTemplateZone * otherZone); std::vector getConnections() const; - void addTreasureInfo(CTreasureInfo & info); - std::vector getTreasureInfo(); std::set* getFreePaths(); ObjectInfo getRandomObject (CTreasurePileInfo &info, ui32 desiredValue, ui32 maxValue, ui32 currentValue); @@ -226,27 +161,13 @@ public: boost::heap::priority_queue> createPiorityQueue(); private: - CMapGenerator * gen; //template info - TRmgTemplateZoneId id; - ETemplateZoneType::ETemplateZoneType type; - int size; - boost::optional owner; - CTownInfo playerTowns, neutralTowns; - bool townsAreSameType; - std::set townTypes; - std::set monsterTypes; - bool matchTerrainToTown; - std::set terrainTypes; - std::map mines; //obligatory mines to spawn in this zone si32 townType; ETerrainType terrainType; CRmgTemplateZone * questArtZone; //artifacts required for Seer Huts will be placed here - or not if null - EMonsterStrength::EMonsterStrength zoneMonsterStrength; - std::vector treasureInfo; std::vector possibleObjects; int minGuardedValue; @@ -260,7 +181,6 @@ private: float3 center; std::set tileinfo; //irregular area assined to zone std::set possibleTiles; //optimization purposes for treasure generation - std::vector connections; //list of adjacent zones std::set freePaths; //core paths of free tiles that all other objects will be linked to std::set roadNodes; //tiles to be connected with roads