/* * CRmgTemplate.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "../int3.h" #include "../GameConstants.h" #include "../ResourceSet.h" VCMI_LIB_NAMESPACE_BEGIN class JsonSerializeFormat; enum class ETemplateZoneType { PLAYER_START, CPU_START, TREASURE, JUNCTION, WATER }; namespace EWaterContent // Not enum class, because it's used in method RandomMapTab::setMapGenOptions { // defined in client\lobby\RandomMapTab.cpp and probably in other similar places enum EWaterContent // as an argument of CToggleGroup::setSelected(int id) from \client\widgets\Buttons.cpp { RANDOM = -1, NONE, NORMAL, ISLANDS }; } namespace EMonsterStrength // used as int in monster generation procedure and in map description for the generated random map { enum EMonsterStrength { ZONE_NONE = -3, RANDOM = -2, ZONE_WEAK = -1, ZONE_NORMAL = 0, ZONE_STRONG = 1, GLOBAL_WEAK = 2, GLOBAL_NORMAL = 3, GLOBAL_STRONG = 4 }; } class DLL_LINKAGE CTreasureInfo { public: ui32 min; ui32 max; ui16 density; CTreasureInfo(); CTreasureInfo(ui32 min, ui32 max, ui16 density); bool operator ==(const CTreasureInfo & other) const; void serializeJson(JsonSerializeFormat & handler); }; namespace rmg { enum class EConnectionType { GUARDED = 0, //default FICTIVE, REPULSIVE, WIDE }; enum class ERoadOption { ROAD_TRUE, ROAD_FALSE, ROAD_RANDOM }; class DLL_LINKAGE ZoneConnection { public: ZoneConnection(); TRmgTemplateZoneId getZoneA() const; TRmgTemplateZoneId getZoneB() const; TRmgTemplateZoneId getOtherZoneId(TRmgTemplateZoneId id) const; int getGuardStrength() const; rmg::EConnectionType getConnectionType() const; rmg::ERoadOption getRoadOption() const; void serializeJson(JsonSerializeFormat & handler); friend bool operator==(const ZoneConnection &, const ZoneConnection &); private: TRmgTemplateZoneId zoneA; TRmgTemplateZoneId zoneB; int guardStrength; rmg::EConnectionType connectionType; rmg::ERoadOption hasRoad; }; class DLL_LINKAGE ZoneOptions { public: static const TRmgTemplateZoneId NO_ZONE; class DLL_LINKAGE CTownInfo { public: CTownInfo(); int getTownCount() const; int getCastleCount() const; int getTownDensity() const; int getCastleDensity() const; void serializeJson(JsonSerializeFormat & handler); private: int townCount; int castleCount; int townDensity; int castleDensity; }; ZoneOptions(); TRmgTemplateZoneId getId() const; void setId(TRmgTemplateZoneId value); ETemplateZoneType getType() const; void setType(ETemplateZoneType value); int getSize() const; void setSize(int value); std::optional getOwner() const; const std::set getTerrainTypes() const; void setTerrainTypes(const std::set & value); std::set getDefaultTerrainTypes() const; const CTownInfo & getPlayerTowns() const; const CTownInfo & getNeutralTowns() const; std::set getDefaultTownTypes() const; const std::set getTownTypes() const; const std::set getMonsterTypes() const; void setTownTypes(const std::set & value); void setMonsterTypes(const std::set & value); void setMinesInfo(const std::map & value); std::map getMinesInfo() const; void setTreasureInfo(const std::vector & value); void addTreasureInfo(const CTreasureInfo & value); const std::vector & getTreasureInfo() const; ui32 getMaxTreasureValue() const; void recalculateMaxTreasureValue(); TRmgTemplateZoneId getMinesLikeZone() const; TRmgTemplateZoneId getTerrainTypeLikeZone() const; TRmgTemplateZoneId getTreasureLikeZone() const; void addConnection(const ZoneConnection & connection); std::vector getConnections() const; std::vector getConnectedZoneIds() const; void serializeJson(JsonSerializeFormat & handler); EMonsterStrength::EMonsterStrength monsterStrength; bool areTownsSameType() const; bool isMatchTerrainToTown() const; protected: TRmgTemplateZoneId id; ETemplateZoneType type; int size; ui32 maxTreasureValue; std::optional owner; CTownInfo playerTowns; CTownInfo neutralTowns; bool matchTerrainToTown; std::set terrainTypes; std::set bannedTerrains; bool townsAreSameType; std::set townTypes; std::set bannedTownTypes; std::set monsterTypes; std::set bannedMonsters; std::map mines; //obligatory mines to spawn in this zone std::vector treasureInfo; std::vector connectedZoneIds; //list of adjacent zone ids std::vector connectionDetails; //list of connections linked to that zone TRmgTemplateZoneId minesLikeZone; TRmgTemplateZoneId terrainTypeLikeZone; TRmgTemplateZoneId treasureLikeZone; }; } /// The CRmgTemplate describes a random map template. class DLL_LINKAGE CRmgTemplate { public: using Zones = std::map>; class DLL_LINKAGE CPlayerCountRange { public: void addRange(int lower, int upper); void addNumber(int value); bool isInRange(int count) const; std::set getNumbers() const; std::string toString() const; void fromString(const std::string & value); int maxValue() const; int minValue() const; private: std::vector > range; }; CRmgTemplate(); bool matchesSize(const int3 & value) const; bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const; const std::set & getWaterContentAllowed() const; void setId(const std::string & value); void setName(const std::string & value); const std::string & getId() const; const std::string & getName() const; const CPlayerCountRange & getPlayers() const; const CPlayerCountRange & getHumanPlayers() const; std::pair getMapSizes() const; const Zones & getZones() const; const std::vector & getConnectedZoneIds() const; void validate() const; /// Tests template on validity and throws exception on failure void serializeJson(JsonSerializeFormat & handler); void afterLoad(); private: std::string id; std::string name; int3 minSize, maxSize; CPlayerCountRange players, humanPlayers; Zones zones; std::vector connectedZoneIds; std::set allowedWaterContent; std::set inheritTerrainType(std::shared_ptr zone, uint32_t iteration = 0); std::map inheritMineTypes(std::shared_ptr zone, uint32_t iteration = 0); std::vector inheritTreasureInfo(std::shared_ptr zone, uint32_t iteration = 0); void serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName); void serializePlayers(JsonSerializeFormat & handler, CPlayerCountRange & value, const std::string & fieldName); }; VCMI_LIB_NAMESPACE_END