2013-08-17 15:46:48 +03:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
#include "../int3.h"
|
2013-08-17 15:46:48 +03:00
|
|
|
#include "../GameConstants.h"
|
2018-03-05 16:05:17 +02:00
|
|
|
#include "../ResourceSet.h"
|
2024-08-21 20:16:41 +02:00
|
|
|
#include "ObjectInfo.h"
|
2024-09-14 08:41:00 +02:00
|
|
|
#include "ObjectConfig.h"
|
2024-08-21 20:16:41 +02:00
|
|
|
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2022-07-26 15:07:42 +02:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
class JsonSerializeFormat;
|
2024-08-21 20:16:41 +02:00
|
|
|
struct CompoundMapObjectID;
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2023-05-20 13:29:55 +02:00
|
|
|
enum class ETemplateZoneType
|
2018-03-05 16:05:17 +02:00
|
|
|
{
|
2023-05-20 13:29:55 +02:00
|
|
|
PLAYER_START,
|
|
|
|
CPU_START,
|
|
|
|
TREASURE,
|
|
|
|
JUNCTION,
|
2024-11-23 13:19:25 +02:00
|
|
|
WATER,
|
|
|
|
SEALED
|
2023-05-20 13:29:55 +02:00
|
|
|
};
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2023-05-20 13:29:55 +02:00
|
|
|
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
|
2022-12-14 02:37:11 +02:00
|
|
|
{
|
|
|
|
RANDOM = -1,
|
|
|
|
NONE,
|
|
|
|
NORMAL,
|
|
|
|
ISLANDS
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-05-20 17:28:25 +02:00
|
|
|
namespace EMonsterStrength // used as int in monster generation procedure and in map description for the generated random map
|
2022-12-14 02:37:11 +02:00
|
|
|
{
|
|
|
|
enum EMonsterStrength
|
|
|
|
{
|
2023-05-20 17:28:25 +02:00
|
|
|
ZONE_NONE = -3,
|
|
|
|
RANDOM = -2,
|
2022-12-14 02:37:11 +02:00
|
|
|
ZONE_WEAK = -1,
|
|
|
|
ZONE_NORMAL = 0,
|
|
|
|
ZONE_STRONG = 1,
|
|
|
|
GLOBAL_WEAK = 2,
|
|
|
|
GLOBAL_NORMAL = 3,
|
|
|
|
GLOBAL_STRONG = 4
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
class DLL_LINKAGE CTreasureInfo
|
2013-08-17 15:46:48 +03:00
|
|
|
{
|
|
|
|
public:
|
2018-03-05 16:05:17 +02:00
|
|
|
ui32 min;
|
|
|
|
ui32 max;
|
|
|
|
ui16 density;
|
2018-03-09 20:11:20 +02:00
|
|
|
CTreasureInfo();
|
2022-05-31 11:25:39 +02:00
|
|
|
CTreasureInfo(ui32 min, ui32 max, ui16 density);
|
2018-03-09 20:11:20 +02:00
|
|
|
|
|
|
|
bool operator ==(const CTreasureInfo & other) const;
|
|
|
|
|
|
|
|
void serializeJson(JsonSerializeFormat & handler);
|
2018-03-05 16:05:17 +02:00
|
|
|
};
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2023-07-07 16:32:17 +02:00
|
|
|
namespace rmg
|
2023-06-17 19:09:38 +02:00
|
|
|
{
|
|
|
|
|
2023-07-07 16:32:17 +02:00
|
|
|
enum class EConnectionType
|
2023-07-06 22:15:00 +02:00
|
|
|
{
|
2023-07-07 16:32:17 +02:00
|
|
|
GUARDED = 0, //default
|
|
|
|
FICTIVE,
|
|
|
|
REPULSIVE,
|
2024-07-29 20:36:23 +02:00
|
|
|
WIDE,
|
|
|
|
FORCE_PORTAL
|
2023-07-07 16:32:17 +02:00
|
|
|
};
|
2023-07-06 22:15:00 +02:00
|
|
|
|
2023-07-07 16:32:17 +02:00
|
|
|
enum class ERoadOption
|
2018-03-05 16:05:17 +02:00
|
|
|
{
|
2023-07-07 16:32:17 +02:00
|
|
|
ROAD_TRUE,
|
|
|
|
ROAD_FALSE,
|
|
|
|
ROAD_RANDOM
|
|
|
|
};
|
2018-03-05 16:05:17 +02:00
|
|
|
|
|
|
|
class DLL_LINKAGE ZoneConnection
|
|
|
|
{
|
|
|
|
public:
|
2023-06-17 19:09:38 +02:00
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
ZoneConnection();
|
|
|
|
|
|
|
|
TRmgTemplateZoneId getZoneA() const;
|
|
|
|
TRmgTemplateZoneId getZoneB() const;
|
2023-06-17 19:09:38 +02:00
|
|
|
TRmgTemplateZoneId getOtherZoneId(TRmgTemplateZoneId id) const;
|
2018-03-09 20:11:20 +02:00
|
|
|
int getGuardStrength() const;
|
2023-07-07 16:32:17 +02:00
|
|
|
rmg::EConnectionType getConnectionType() const;
|
|
|
|
rmg::ERoadOption getRoadOption() const;
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
void serializeJson(JsonSerializeFormat & handler);
|
2022-08-09 07:54:32 +02:00
|
|
|
|
|
|
|
friend bool operator==(const ZoneConnection &, const ZoneConnection &);
|
2013-08-17 15:46:48 +03:00
|
|
|
private:
|
2018-03-05 16:05:17 +02:00
|
|
|
TRmgTemplateZoneId zoneA;
|
|
|
|
TRmgTemplateZoneId zoneB;
|
2013-08-17 15:46:48 +03:00
|
|
|
int guardStrength;
|
2023-07-07 16:32:17 +02:00
|
|
|
rmg::EConnectionType connectionType;
|
|
|
|
rmg::ERoadOption hasRoad;
|
2013-08-17 15:46:48 +03:00
|
|
|
};
|
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
class DLL_LINKAGE ZoneOptions
|
|
|
|
{
|
|
|
|
public:
|
2018-03-09 20:11:20 +02:00
|
|
|
static const TRmgTemplateZoneId NO_ZONE;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
|
|
|
class DLL_LINKAGE CTownInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CTownInfo();
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
int getTownCount() const;
|
|
|
|
int getCastleCount() const;
|
|
|
|
int getTownDensity() const;
|
|
|
|
int getCastleDensity() const;
|
|
|
|
|
|
|
|
void serializeJson(JsonSerializeFormat & handler);
|
2018-03-05 16:05:17 +02:00
|
|
|
|
|
|
|
private:
|
2018-03-09 20:11:20 +02:00
|
|
|
int townCount;
|
|
|
|
int castleCount;
|
|
|
|
int townDensity;
|
|
|
|
int castleDensity;
|
2024-08-21 20:16:41 +02:00
|
|
|
|
|
|
|
// TODO: Copy from another zone once its randomized
|
|
|
|
TRmgTemplateZoneId sourceZone = NO_ZONE;
|
|
|
|
};
|
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
ZoneOptions();
|
|
|
|
|
|
|
|
TRmgTemplateZoneId getId() const;
|
|
|
|
void setId(TRmgTemplateZoneId value);
|
|
|
|
|
2023-05-20 13:29:55 +02:00
|
|
|
ETemplateZoneType getType() const;
|
|
|
|
void setType(ETemplateZoneType value);
|
2022-05-31 11:25:39 +02:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
int getSize() const;
|
2018-03-05 16:05:17 +02:00
|
|
|
void setSize(int value);
|
2023-04-16 19:42:56 +02:00
|
|
|
std::optional<int> getOwner() const;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2024-08-24 20:18:36 +02:00
|
|
|
std::set<TerrainId> getTerrainTypes() const;
|
2022-09-29 11:44:46 +02:00
|
|
|
void setTerrainTypes(const std::set<TerrainId> & value);
|
2023-07-06 17:30:23 +02:00
|
|
|
std::set<TerrainId> getDefaultTerrainTypes() const;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2022-08-09 07:54:32 +02:00
|
|
|
const CTownInfo & getPlayerTowns() const;
|
|
|
|
const CTownInfo & getNeutralTowns() const;
|
2023-04-09 17:26:32 +02:00
|
|
|
std::set<FactionID> getDefaultTownTypes() const;
|
2024-08-24 20:18:36 +02:00
|
|
|
std::set<FactionID> getTownTypes() const;
|
|
|
|
std::set<FactionID> getMonsterTypes() const;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2023-04-09 17:26:32 +02:00
|
|
|
void setTownTypes(const std::set<FactionID> & value);
|
|
|
|
void setMonsterTypes(const std::set<FactionID> & value);
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
void setMinesInfo(const std::map<TResource, ui16> & value);
|
2018-03-05 16:05:17 +02:00
|
|
|
std::map<TResource, ui16> getMinesInfo() const;
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
void setTreasureInfo(const std::vector<CTreasureInfo> & value);
|
2022-05-31 11:25:39 +02:00
|
|
|
void addTreasureInfo(const CTreasureInfo & value);
|
2024-08-24 20:18:36 +02:00
|
|
|
std::vector<CTreasureInfo> getTreasureInfo() const;
|
2023-03-27 17:29:46 +02:00
|
|
|
ui32 getMaxTreasureValue() const;
|
2023-03-28 17:13:24 +02:00
|
|
|
void recalculateMaxTreasureValue();
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
TRmgTemplateZoneId getMinesLikeZone() const;
|
|
|
|
TRmgTemplateZoneId getTerrainTypeLikeZone() const;
|
|
|
|
TRmgTemplateZoneId getTreasureLikeZone() const;
|
|
|
|
|
2023-06-17 19:09:38 +02:00
|
|
|
void addConnection(const ZoneConnection & connection);
|
|
|
|
std::vector<ZoneConnection> getConnections() const;
|
|
|
|
std::vector<TRmgTemplateZoneId> getConnectedZoneIds() const;
|
2018-03-09 20:11:20 +02:00
|
|
|
|
|
|
|
void serializeJson(JsonSerializeFormat & handler);
|
2022-08-09 07:54:32 +02:00
|
|
|
|
2023-05-21 00:13:45 +02:00
|
|
|
EMonsterStrength::EMonsterStrength monsterStrength;
|
2022-08-09 07:54:32 +02:00
|
|
|
|
|
|
|
bool areTownsSameType() const;
|
|
|
|
bool isMatchTerrainToTown() const;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
2024-08-24 20:18:36 +02:00
|
|
|
// Get a group of configured objects
|
2024-08-21 20:16:41 +02:00
|
|
|
const std::vector<CompoundMapObjectID> & getBannedObjects() const;
|
2024-08-24 15:12:22 +02:00
|
|
|
const std::vector<ObjectConfig::EObjectCategory> & getBannedObjectCategories() const;
|
2024-08-24 20:18:36 +02:00
|
|
|
const std::vector<ObjectInfo> & getConfiguredObjects() const;
|
|
|
|
|
|
|
|
// Copy whole custom object config from another zone
|
|
|
|
ObjectConfig getCustomObjects() const;
|
|
|
|
void setCustomObjects(const ObjectConfig & value);
|
|
|
|
TRmgTemplateZoneId getCustomObjectsLikeZone() const;
|
2024-08-21 20:16:41 +02:00
|
|
|
|
2018-03-05 16:05:17 +02:00
|
|
|
protected:
|
|
|
|
TRmgTemplateZoneId id;
|
2023-05-20 13:29:55 +02:00
|
|
|
ETemplateZoneType type;
|
2018-03-05 16:05:17 +02:00
|
|
|
int size;
|
2023-03-27 17:29:46 +02:00
|
|
|
ui32 maxTreasureValue;
|
2023-04-16 19:42:56 +02:00
|
|
|
std::optional<int> owner;
|
2024-08-21 20:16:41 +02:00
|
|
|
|
|
|
|
ObjectConfig objectConfig;
|
2018-03-05 16:05:17 +02:00
|
|
|
CTownInfo playerTowns;
|
|
|
|
CTownInfo neutralTowns;
|
|
|
|
bool matchTerrainToTown;
|
2022-09-29 11:44:46 +02:00
|
|
|
std::set<TerrainId> terrainTypes;
|
2023-07-06 17:30:23 +02:00
|
|
|
std::set<TerrainId> bannedTerrains;
|
2018-03-05 16:05:17 +02:00
|
|
|
bool townsAreSameType;
|
|
|
|
|
2023-04-09 17:26:32 +02:00
|
|
|
std::set<FactionID> townTypes;
|
2023-07-02 11:41:47 +02:00
|
|
|
std::set<FactionID> bannedTownTypes;
|
2023-04-09 17:26:32 +02:00
|
|
|
std::set<FactionID> monsterTypes;
|
2023-07-06 17:30:23 +02:00
|
|
|
std::set<FactionID> bannedMonsters;
|
2018-03-05 16:05:17 +02:00
|
|
|
|
|
|
|
std::map<TResource, ui16> mines; //obligatory mines to spawn in this zone
|
|
|
|
|
|
|
|
std::vector<CTreasureInfo> treasureInfo;
|
|
|
|
|
2023-06-17 19:09:38 +02:00
|
|
|
std::vector<TRmgTemplateZoneId> connectedZoneIds; //list of adjacent zone ids
|
|
|
|
std::vector<ZoneConnection> connectionDetails; //list of connections linked to that zone
|
2018-03-09 20:11:20 +02:00
|
|
|
|
|
|
|
TRmgTemplateZoneId minesLikeZone;
|
|
|
|
TRmgTemplateZoneId terrainTypeLikeZone;
|
|
|
|
TRmgTemplateZoneId treasureLikeZone;
|
2024-08-24 20:18:36 +02:00
|
|
|
TRmgTemplateZoneId customObjectsLikeZone;
|
2018-03-05 16:05:17 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-08-17 15:46:48 +03:00
|
|
|
/// The CRmgTemplate describes a random map template.
|
2024-09-04 20:18:10 +02:00
|
|
|
class DLL_LINKAGE CRmgTemplate : boost::noncopyable
|
2013-08-17 15:46:48 +03:00
|
|
|
{
|
|
|
|
public:
|
2018-03-09 20:11:20 +02:00
|
|
|
using Zones = std::map<TRmgTemplateZoneId, std::shared_ptr<rmg::ZoneOptions>>;
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
class DLL_LINKAGE CPlayerCountRange
|
2013-08-17 15:46:48 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
void addRange(int lower, int upper);
|
|
|
|
void addNumber(int value);
|
|
|
|
bool isInRange(int count) const;
|
|
|
|
std::set<int> getNumbers() const;
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
std::string toString() const;
|
|
|
|
void fromString(const std::string & value);
|
|
|
|
|
2023-10-29 22:25:39 +02:00
|
|
|
int maxValue() const;
|
|
|
|
int minValue() const;
|
|
|
|
|
2013-08-17 15:46:48 +03:00
|
|
|
private:
|
2018-03-09 20:11:20 +02:00
|
|
|
std::vector<std::pair<int, int> > range;
|
2013-08-17 15:46:48 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
CRmgTemplate();
|
2024-09-04 20:18:10 +02:00
|
|
|
~CRmgTemplate();
|
2013-08-17 15:46:48 +03:00
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
bool matchesSize(const int3 & value) const;
|
2022-05-31 11:25:39 +02:00
|
|
|
bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const;
|
2022-06-05 08:02:58 +02:00
|
|
|
const std::set<EWaterContent::EWaterContent> & getWaterContentAllowed() const;
|
2018-03-09 20:11:20 +02:00
|
|
|
|
|
|
|
void setId(const std::string & value);
|
2022-12-14 02:37:11 +02:00
|
|
|
void setName(const std::string & value);
|
|
|
|
const std::string & getId() const;
|
2013-08-17 15:46:48 +03:00
|
|
|
const std::string & getName() const;
|
2024-02-03 17:23:56 +02:00
|
|
|
const std::string & getDescription() const;
|
2018-03-09 20:11:20 +02:00
|
|
|
|
2013-08-17 15:46:48 +03:00
|
|
|
const CPlayerCountRange & getPlayers() const;
|
2023-10-29 22:25:39 +02:00
|
|
|
const CPlayerCountRange & getHumanPlayers() const;
|
2022-12-14 02:37:11 +02:00
|
|
|
std::pair<int3, int3> getMapSizes() const;
|
2018-03-09 20:11:20 +02:00
|
|
|
const Zones & getZones() const;
|
2024-09-04 20:18:10 +02:00
|
|
|
const JsonNode & getMapSettings() const;
|
2023-06-17 19:09:38 +02:00
|
|
|
const std::vector<rmg::ZoneConnection> & getConnectedZoneIds() const;
|
2013-08-17 15:46:48 +03:00
|
|
|
|
|
|
|
void validate() const; /// Tests template on validity and throws exception on failure
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
void serializeJson(JsonSerializeFormat & handler);
|
2023-07-02 09:28:51 +02:00
|
|
|
void afterLoad();
|
2018-03-09 20:11:20 +02:00
|
|
|
|
2013-08-17 15:46:48 +03:00
|
|
|
private:
|
2018-03-09 20:11:20 +02:00
|
|
|
std::string id;
|
2013-08-17 15:46:48 +03:00
|
|
|
std::string name;
|
2024-02-03 17:23:56 +02:00
|
|
|
std::string description;
|
2024-01-10 00:38:54 +02:00
|
|
|
int3 minSize;
|
|
|
|
int3 maxSize;
|
|
|
|
CPlayerCountRange players;
|
|
|
|
CPlayerCountRange humanPlayers;
|
2018-03-09 20:11:20 +02:00
|
|
|
Zones zones;
|
2023-06-17 19:09:38 +02:00
|
|
|
std::vector<rmg::ZoneConnection> connectedZoneIds;
|
2022-05-31 11:25:39 +02:00
|
|
|
std::set<EWaterContent::EWaterContent> allowedWaterContent;
|
2024-09-04 20:18:10 +02:00
|
|
|
std::unique_ptr<JsonNode> mapSettings;
|
2018-03-09 20:11:20 +02:00
|
|
|
|
2023-03-19 10:51:37 +02:00
|
|
|
std::set<TerrainId> inheritTerrainType(std::shared_ptr<rmg::ZoneOptions> zone, uint32_t iteration = 0);
|
|
|
|
std::map<TResource, ui16> inheritMineTypes(std::shared_ptr<rmg::ZoneOptions> zone, uint32_t iteration = 0);
|
|
|
|
std::vector<CTreasureInfo> inheritTreasureInfo(std::shared_ptr<rmg::ZoneOptions> zone, uint32_t iteration = 0);
|
2024-08-21 20:16:41 +02:00
|
|
|
|
|
|
|
// TODO: Copy custom object settings
|
|
|
|
// TODO: Copy town type after source town is actually randomized
|
|
|
|
|
2018-03-09 20:11:20 +02:00
|
|
|
void serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName);
|
|
|
|
void serializePlayers(JsonSerializeFormat & handler, CPlayerCountRange & value, const std::string & fieldName);
|
2024-08-24 20:18:36 +02:00
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T inheritZoneProperty(std::shared_ptr<rmg::ZoneOptions> zone,
|
|
|
|
T (rmg::ZoneOptions::*getter)() const,
|
|
|
|
void (rmg::ZoneOptions::*setter)(const T&),
|
|
|
|
TRmgTemplateZoneId (rmg::ZoneOptions::*inheritFrom)() const,
|
|
|
|
const std::string& propertyString,
|
|
|
|
uint32_t iteration = 0);
|
|
|
|
|
2013-08-17 15:46:48 +03:00
|
|
|
};
|
2022-07-26 15:07:42 +02:00
|
|
|
|
2024-08-24 20:18:36 +02:00
|
|
|
VCMI_LIB_NAMESPACE_END
|