CMapGenerator.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*
  2. * CMapGenerator.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "../GameConstants.h"
  12. #include "../CRandomGenerator.h"
  13. class CMap;
  14. class CTerrainViewPatternConfig;
  15. class CMapEditManager;
  16. class JsonNode;
  17. typedef std::vector<JsonNode> JsonVector;
  18. namespace ETemplateZoneType
  19. {
  20. enum ETemplateZoneType
  21. {
  22. PLAYER_START,
  23. CPU_START,
  24. TREASURE,
  25. JUNCTION
  26. };
  27. }
  28. typedef int TRmgTemplateZoneId;
  29. /// The CRmgTemplateZone describes a zone in a template.
  30. class DLL_LINKAGE CRmgTemplateZone
  31. {
  32. public:
  33. class DLL_LINKAGE CTownInfo
  34. {
  35. public:
  36. CTownInfo();
  37. int getTownCount() const; /// Default: 0
  38. void setTownCount(int value);
  39. int getCastleCount() const; /// Default: 0
  40. void setCastleCount(int value);
  41. int getTownDensity() const; /// Default: 0
  42. void setTownDensity(int value);
  43. int getCastleDensity() const; /// Default: 0
  44. void setCastleDensity(int value);
  45. private:
  46. int townCount, castleCount, townDensity, castleDensity;
  47. };
  48. CRmgTemplateZone();
  49. TRmgTemplateZoneId getId() const; /// Default: 0
  50. void setId(TRmgTemplateZoneId value);
  51. ETemplateZoneType::ETemplateZoneType getType() const; /// Default: ETemplateZoneType::PLAYER_START
  52. void setType(ETemplateZoneType::ETemplateZoneType value);
  53. int getSize() const; /// Default: 1
  54. void setSize(int value);
  55. boost::optional<int> getOwner() const;
  56. void setOwner(boost::optional<int> value);
  57. const CTownInfo & getPlayerTowns() const;
  58. void setPlayerTowns(const CTownInfo & value);
  59. const CTownInfo & getNeutralTowns() const;
  60. void setNeutralTowns(const CTownInfo & value);
  61. bool getTownsAreSameType() const; /// Default: false
  62. void setTownsAreSameType(bool value);
  63. const std::set<TFaction> & getTownTypes() const; /// Default: all
  64. void setTownTypes(const std::set<TFaction> & value);
  65. std::set<TFaction> getDefaultTownTypes() const;
  66. bool getMatchTerrainToTown() const; /// Default: true
  67. void setMatchTerrainToTown(bool value);
  68. const std::set<ETerrainType> & getTerrainTypes() const; /// Default: all
  69. void setTerrainTypes(const std::set<ETerrainType> & value);
  70. std::set<ETerrainType> getDefaultTerrainTypes() const;
  71. boost::optional<TRmgTemplateZoneId> getTerrainTypeLikeZone() const;
  72. void setTerrainTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
  73. boost::optional<TRmgTemplateZoneId> getTownTypeLikeZone() const;
  74. void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
  75. private:
  76. TRmgTemplateZoneId id;
  77. ETemplateZoneType::ETemplateZoneType type;
  78. int size;
  79. boost::optional<int> owner;
  80. CTownInfo playerTowns, neutralTowns;
  81. bool townsAreSameType;
  82. std::set<TFaction> townTypes;
  83. bool matchTerrainToTown;
  84. std::set<ETerrainType> terrainTypes;
  85. boost::optional<TRmgTemplateZoneId> terrainTypeLikeZone, townTypeLikeZone;
  86. };
  87. /// The CRmgTemplateZoneConnection describes the connection between two zones.
  88. class DLL_LINKAGE CRmgTemplateZoneConnection
  89. {
  90. public:
  91. CRmgTemplateZoneConnection();
  92. TRmgTemplateZoneId getZoneA() const; /// Default: 0
  93. void setZoneA(TRmgTemplateZoneId value);
  94. TRmgTemplateZoneId getZoneB() const; /// Default: 0
  95. void setZoneB(TRmgTemplateZoneId value);
  96. int getGuardStrength() const; /// Default: 0
  97. void setGuardStrength(int value);
  98. private:
  99. TRmgTemplateZoneId zoneA, zoneB;
  100. int guardStrength;
  101. };
  102. /// The CRmgTemplate describes a random map template.
  103. class DLL_LINKAGE CRmgTemplate
  104. {
  105. public:
  106. class CSize
  107. {
  108. public:
  109. CSize();
  110. CSize(int width, int height, bool under);
  111. int getWidth() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
  112. void setWidth(int value);
  113. int getHeight() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
  114. void setHeight(int value);
  115. bool getUnder() const; /// Default: true
  116. void setUnder(bool value);
  117. bool operator<=(const CSize & value) const;
  118. bool operator>=(const CSize & value) const;
  119. private:
  120. int width, height;
  121. bool under;
  122. };
  123. class CPlayerCountRange
  124. {
  125. public:
  126. void addRange(int lower, int upper);
  127. void addNumber(int value);
  128. bool isInRange(int count) const;
  129. std::set<int> getNumbers() const;
  130. private:
  131. std::list<std::pair<int, int> > range;
  132. };
  133. CRmgTemplate();
  134. const std::string & getName() const;
  135. void setName(const std::string & value);
  136. const CSize & getMinSize() const;
  137. void setMinSize(const CSize & value);
  138. const CSize & getMaxSize() const;
  139. void setMaxSize(const CSize & value);
  140. const CPlayerCountRange & getPlayers() const;
  141. void setPlayers(const CPlayerCountRange & value);
  142. const CPlayerCountRange & getCpuPlayers() const;
  143. void setCpuPlayers(const CPlayerCountRange & value);
  144. const std::map<TRmgTemplateZoneId, CRmgTemplateZone> & getZones() const;
  145. void setZones(const std::map<TRmgTemplateZoneId, CRmgTemplateZone> & value);
  146. const std::list<CRmgTemplateZoneConnection> & getConnections() const;
  147. void setConnections(const std::list<CRmgTemplateZoneConnection> & value);
  148. void validate() const; /// Tests template on validity and throws exception on failure
  149. private:
  150. std::string name;
  151. CSize minSize, maxSize;
  152. CPlayerCountRange players, cpuPlayers;
  153. std::map<TRmgTemplateZoneId, CRmgTemplateZone> zones;
  154. std::list<CRmgTemplateZoneConnection> connections;
  155. };
  156. namespace EWaterContent
  157. {
  158. enum EWaterContent
  159. {
  160. RANDOM = -1,
  161. NONE,
  162. NORMAL,
  163. ISLANDS
  164. };
  165. }
  166. namespace EMonsterStrength
  167. {
  168. enum EMonsterStrength
  169. {
  170. RANDOM = -1,
  171. WEAK,
  172. NORMAL,
  173. STRONG
  174. };
  175. }
  176. namespace EPlayerType
  177. {
  178. enum EPlayerType
  179. {
  180. HUMAN,
  181. AI,
  182. COMP_ONLY
  183. };
  184. }
  185. /// The map gen options class holds values about general map generation settings
  186. /// e.g. the size of the map, the count of players,...
  187. class DLL_LINKAGE CMapGenOptions
  188. {
  189. public:
  190. /// The player settings class maps the player color, starting town and human player flag.
  191. class DLL_LINKAGE CPlayerSettings
  192. {
  193. public:
  194. CPlayerSettings();
  195. /// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1.
  196. /// The default value is 0.
  197. PlayerColor getColor() const;
  198. void setColor(PlayerColor value);
  199. /// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
  200. /// The default value is RANDOM_TOWN.
  201. si32 getStartingTown() const;
  202. void setStartingTown(si32 value);
  203. /// The default value is EPlayerType::AI.
  204. EPlayerType::EPlayerType getPlayerType() const;
  205. void setPlayerType(EPlayerType::EPlayerType value);
  206. /// Constant for a random town selection.
  207. static const si32 RANDOM_TOWN = -1;
  208. private:
  209. PlayerColor color;
  210. si32 startingTown;
  211. EPlayerType::EPlayerType playerType;
  212. public:
  213. template <typename Handler>
  214. void serialize(Handler & h, const int version)
  215. {
  216. h & color & startingTown & playerType;
  217. }
  218. };
  219. CMapGenOptions();
  220. si32 getWidth() const;
  221. void setWidth(si32 value);
  222. si32 getHeight() const;
  223. void setHeight(si32 value);
  224. bool getHasTwoLevels() const;
  225. void setHasTwoLevels(bool value);
  226. /// The count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call
  227. /// this method, all player settings are reset to default settings.
  228. si8 getPlayerCount() const;
  229. void setPlayerCount(si8 value);
  230. /// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random.
  231. si8 getTeamCount() const;
  232. void setTeamCount(si8 value);
  233. /// The count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random.
  234. /// If you call this method, all player settings are reset to default settings.
  235. si8 getCompOnlyPlayerCount() const;
  236. void setCompOnlyPlayerCount(si8 value);
  237. /// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random.
  238. si8 getCompOnlyTeamCount() const;
  239. void setCompOnlyTeamCount(si8 value);
  240. EWaterContent::EWaterContent getWaterContent() const;
  241. void setWaterContent(EWaterContent::EWaterContent value);
  242. EMonsterStrength::EMonsterStrength getMonsterStrength() const;
  243. void setMonsterStrength(EMonsterStrength::EMonsterStrength value);
  244. /// The first player colors belong to standard players and the last player colors belong to comp only players.
  245. /// All standard players are by default of type EPlayerType::AI.
  246. const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
  247. void setStartingTownForPlayer(PlayerColor color, si32 town);
  248. /// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
  249. /// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
  250. void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType);
  251. /// The random map template to generate the map with or empty/not set if the template should be chosen randomly.
  252. /// Default: Not set/random.
  253. const CRmgTemplate * getMapTemplate() const;
  254. void setMapTemplate(const CRmgTemplate * value);
  255. const std::map<std::string, CRmgTemplate> & getAvailableTemplates() const;
  256. /// Finalizes the options. All random sizes for various properties will be overwritten by numbers from
  257. /// a random number generator by keeping the options in a valid state. Check options should return true, otherwise
  258. /// this function fails.
  259. void finalize();
  260. void finalize(CRandomGenerator & gen);
  261. /// Returns false if there is no template available which fits to the currently selected options.
  262. bool checkOptions() const;
  263. static const si8 RANDOM_SIZE = -1;
  264. private:
  265. void resetPlayersMap();
  266. int countHumanPlayers() const;
  267. PlayerColor getNextPlayerColor() const;
  268. void updateCompOnlyPlayers();
  269. void updatePlayers();
  270. const CRmgTemplate * getPossibleTemplate(CRandomGenerator & gen) const;
  271. si32 width, height;
  272. bool hasTwoLevels;
  273. si8 playerCount, teamCount, compOnlyPlayerCount, compOnlyTeamCount;
  274. EWaterContent::EWaterContent waterContent;
  275. EMonsterStrength::EMonsterStrength monsterStrength;
  276. std::map<PlayerColor, CPlayerSettings> players;
  277. const CRmgTemplate * mapTemplate;
  278. public:
  279. template <typename Handler>
  280. void serialize(Handler & h, const int version)
  281. {
  282. h & width & height & hasTwoLevels & playerCount & teamCount & compOnlyPlayerCount;
  283. h & compOnlyTeamCount & waterContent & monsterStrength & players;
  284. //TODO add name of template to class, enables selection of a template by a user
  285. }
  286. };
  287. /// The map generator creates a map randomly.
  288. class DLL_LINKAGE CMapGenerator
  289. {
  290. public:
  291. explicit CMapGenerator(const CMapGenOptions & mapGenOptions, int randomSeed = std::time(nullptr));
  292. ~CMapGenerator(); // required due to unique_ptr
  293. std::unique_ptr<CMap> generate();
  294. private:
  295. /// Generation methods
  296. std::string getMapDescription() const;
  297. void addPlayerInfo();
  298. void addHeaderInfo();
  299. void genTerrain();
  300. void genTowns();
  301. CMapGenOptions mapGenOptions;
  302. std::unique_ptr<CMap> map;
  303. CRandomGenerator gen;
  304. int randomSeed;
  305. CMapEditManager * editManager;
  306. };
  307. /* ---------------------------------------------------------------------------- */
  308. /* Implementation/Detail classes, Private API */
  309. /* ---------------------------------------------------------------------------- */
  310. /// The CRmgTemplateLoader is a abstract base class for loading templates.
  311. class DLL_LINKAGE CRmgTemplateLoader
  312. {
  313. public:
  314. virtual ~CRmgTemplateLoader() { };
  315. virtual void loadTemplates() = 0;
  316. const std::map<std::string, CRmgTemplate> & getTemplates() const;
  317. protected:
  318. std::map<std::string, CRmgTemplate> templates;
  319. };
  320. /// The CJsonRmgTemplateLoader loads templates from a JSON file.
  321. class DLL_LINKAGE CJsonRmgTemplateLoader : public CRmgTemplateLoader
  322. {
  323. public:
  324. void loadTemplates() override;
  325. private:
  326. CRmgTemplate::CSize parseMapTemplateSize(const std::string & text) const;
  327. CRmgTemplateZone::CTownInfo parseTemplateZoneTowns(const JsonNode & node) const;
  328. ETemplateZoneType::ETemplateZoneType parseZoneType(const std::string & type) const;
  329. std::set<TFaction> parseTownTypes(const JsonVector & townTypesVector, const std::set<TFaction> & defaultTownTypes) const;
  330. std::set<ETerrainType> parseTerrainTypes(const JsonVector & terTypeStrings, const std::set<ETerrainType> & defaultTerrainTypes) const;
  331. CRmgTemplate::CPlayerCountRange parsePlayers(const std::string & players) const;
  332. };
  333. /// The CRmgTemplateStorage is a singleton object where templates are stored and which can be accessed from anywhere.
  334. class DLL_LINKAGE CRmgTemplateStorage
  335. {
  336. public:
  337. static CRmgTemplateStorage & get();
  338. const std::map<std::string, CRmgTemplate> & getTemplates() const;
  339. private:
  340. CRmgTemplateStorage();
  341. ~CRmgTemplateStorage();
  342. static boost::mutex smx;
  343. std::map<std::string, CRmgTemplate> templates; /// Key: Template name
  344. };