CMap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. * CMap.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 "../ConstTransitivePtr.h"
  12. #include "../mapObjects/MiscObjects.h" // To serialize static props
  13. #include "../mapObjects/CQuest.h" // To serialize static props
  14. #include "../mapObjects/CGTownInstance.h" // To serialize static props
  15. #include "../ResourceSet.h"
  16. #include "../int3.h"
  17. #include "../GameConstants.h"
  18. #include "../LogicalExpression.h"
  19. #include "CMapDefines.h"
  20. class CArtifactInstance;
  21. class CGObjectInstance;
  22. class CGHeroInstance;
  23. class CCommanderInstance;
  24. class CGCreature;
  25. class CQuest;
  26. class CGTownInstance;
  27. class IModableArt;
  28. class IQuestObject;
  29. class CInputStream;
  30. class CMapEditManager;
  31. /// The hero name struct consists of the hero id and the hero name.
  32. struct DLL_LINKAGE SHeroName
  33. {
  34. SHeroName();
  35. int heroId;
  36. std::string heroName;
  37. template <typename Handler>
  38. void serialize(Handler & h, const int version)
  39. {
  40. h & heroId & heroName;
  41. }
  42. };
  43. /// The player info constains data about which factions are allowed, AI tactical settings,
  44. /// the main hero name, where to generate the hero, whether the faction should be selected randomly,...
  45. struct DLL_LINKAGE PlayerInfo
  46. {
  47. PlayerInfo();
  48. /// Gets the default faction id or -1 for a random faction.
  49. si8 defaultCastle() const;
  50. /// Gets the default hero id or -1 for a random hero.
  51. si8 defaultHero() const;
  52. bool canAnyonePlay() const;
  53. bool hasCustomMainHero() const;
  54. bool canHumanPlay;
  55. bool canComputerPlay;
  56. EAiTactic::EAiTactic aiTactic; /// The default value is EAiTactic::RANDOM.
  57. std::set<TFaction> allowedFactions;
  58. bool isFactionRandom;
  59. ///main hero instance (VCMI maps only)
  60. std::string mainHeroInstance;
  61. /// Player has a random main hero
  62. bool hasRandomHero;
  63. /// The default value is -1.
  64. si32 mainCustomHeroPortrait;
  65. std::string mainCustomHeroName;
  66. /// ID of custom hero (only if portrait and hero name are set, otherwise unpredicted value), -1 if none (not always -1)
  67. si32 mainCustomHeroId;
  68. std::vector<SHeroName> heroesNames; /// list of placed heroes on the map
  69. bool hasMainTown; /// The default value is false.
  70. bool generateHeroAtMainTown; /// The default value is false.
  71. int3 posOfMainTown;
  72. TeamID team; /// The default value NO_TEAM
  73. bool generateHero; /// Unused.
  74. si32 p7; /// Unknown and unused.
  75. /// Unused. Count of hero placeholders containing hero type.
  76. /// WARNING: powerPlaceholders sometimes gives false 0 (eg. even if there is one placeholder), maybe different meaning ???
  77. ui8 powerPlaceholders;
  78. template <typename Handler>
  79. void serialize(Handler & h, const int version)
  80. {
  81. h & p7 & hasRandomHero & mainCustomHeroId & canHumanPlay & canComputerPlay & aiTactic & allowedFactions & isFactionRandom &
  82. mainCustomHeroPortrait & mainCustomHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
  83. posOfMainTown & team & generateHero;
  84. if(version >= 770)
  85. {
  86. h & mainHeroInstance;
  87. }
  88. }
  89. };
  90. /// The loss condition describes the condition to lose the game. (e.g. lose all own heroes/castles)
  91. struct DLL_LINKAGE EventCondition
  92. {
  93. enum EWinLoseType {
  94. //internal use, deprecated
  95. HAVE_ARTIFACT, // type - required artifact
  96. HAVE_CREATURES, // type - creatures to collect, value - amount to collect
  97. HAVE_RESOURCES, // type - resource ID, value - amount to collect
  98. HAVE_BUILDING, // position - town, optional, type - building to build
  99. CONTROL, // position - position of object, optional, type - type of object
  100. DESTROY, // position - position of object, optional, type - type of object
  101. TRANSPORT, // position - where artifact should be transported, type - type of artifact
  102. //map format version pre 1.0
  103. DAYS_PASSED, // value - number of days from start of the game
  104. IS_HUMAN, // value - 0 = player is AI, 1 = player is human
  105. DAYS_WITHOUT_TOWN, // value - how long player can live without town, 0=instakill
  106. STANDARD_WIN, // normal defeat all enemies condition
  107. CONST_VALUE, // condition that always evaluates to "value" (0 = false, 1 = true)
  108. //map format version 1.0+
  109. HAVE_0,
  110. HAVE_BUILDING_0,
  111. DESTROY_0
  112. };
  113. EventCondition(EWinLoseType condition = STANDARD_WIN);
  114. EventCondition(EWinLoseType condition, si32 value, si32 objectType, int3 position = int3(-1, -1, -1));
  115. const CGObjectInstance * object; // object that was at specified position or with instance name on start
  116. EMetaclass metaType;
  117. si32 value;
  118. si32 objectType;
  119. si32 objectSubtype;
  120. std::string objectInstanceName;
  121. int3 position;
  122. EWinLoseType condition;
  123. template <typename Handler>
  124. void serialize(Handler & h, const int version)
  125. {
  126. h & object;
  127. h & value;
  128. h & objectType;
  129. h & position;
  130. h & condition;
  131. if(version > 759)
  132. {
  133. h & objectSubtype;
  134. h & objectInstanceName;
  135. }
  136. if(version >= 770)
  137. h & metaType;
  138. }
  139. };
  140. typedef LogicalExpression<EventCondition> EventExpression;
  141. struct DLL_LINKAGE EventEffect
  142. {
  143. enum EType
  144. {
  145. VICTORY,
  146. DEFEAT
  147. };
  148. /// effect type, using EType enum
  149. si8 type;
  150. /// message that will be sent to other players
  151. std::string toOtherMessage;
  152. template <typename Handler>
  153. void serialize(Handler & h, const int version)
  154. {
  155. h & type & toOtherMessage;
  156. }
  157. };
  158. struct DLL_LINKAGE TriggeredEvent
  159. {
  160. /// base condition that must be evaluated
  161. EventExpression trigger;
  162. /// string identifier read from config file (e.g. captureKreelah)
  163. std::string identifier;
  164. /// string-description, for use in UI (capture town to win)
  165. std::string description;
  166. /// Message that will be displayed when this event is triggered (You captured town. You won!)
  167. std::string onFulfill;
  168. /// Effect of this event. TODO: refactor into something more flexible
  169. EventEffect effect;
  170. template <typename Handler>
  171. void serialize(Handler & h, const int version)
  172. {
  173. h & identifier;
  174. h & trigger;
  175. h & description;
  176. h & onFulfill & effect;
  177. }
  178. };
  179. /// The rumor struct consists of a rumor name and text.
  180. struct DLL_LINKAGE Rumor
  181. {
  182. std::string name;
  183. std::string text;
  184. Rumor() = default;
  185. ~Rumor() = default;
  186. template <typename Handler>
  187. void serialize(Handler & h, const int version)
  188. {
  189. h & name & text;
  190. }
  191. void serializeJson(JsonSerializeFormat & handler);
  192. };
  193. /// The disposed hero struct describes which hero can be hired from which player.
  194. struct DLL_LINKAGE DisposedHero
  195. {
  196. DisposedHero();
  197. ui32 heroId;
  198. ui16 portrait; /// The portrait id of the hero, 0xFF is default.
  199. std::string name;
  200. ui8 players; /// Who can hire this hero (bitfield).
  201. template <typename Handler>
  202. void serialize(Handler & h, const int version)
  203. {
  204. h & heroId & portrait & name & players;
  205. }
  206. };
  207. namespace EMapFormat
  208. {
  209. enum EMapFormat: ui8
  210. {
  211. INVALID = 0,
  212. // HEX DEC
  213. ROE = 0x0e, // 14
  214. AB = 0x15, // 21
  215. SOD = 0x1c, // 28
  216. // HOTA = 0x1e ... 0x20 // 28 ... 30
  217. WOG = 0x33, // 51
  218. VCMI = 0xF0
  219. };
  220. }
  221. /// The map header holds information about loss/victory condition,map format, version, players, height, width,...
  222. class DLL_LINKAGE CMapHeader
  223. {
  224. void setupEvents();
  225. public:
  226. static const int MAP_SIZE_SMALL;
  227. static const int MAP_SIZE_MIDDLE;
  228. static const int MAP_SIZE_LARGE;
  229. static const int MAP_SIZE_XLARGE;
  230. CMapHeader();
  231. virtual ~CMapHeader();
  232. EMapFormat::EMapFormat version; /// The default value is EMapFormat::SOD.
  233. si32 height; /// The default value is 72.
  234. si32 width; /// The default value is 72.
  235. bool twoLevel; /// The default value is true.
  236. std::string name;
  237. std::string description;
  238. ui8 difficulty; /// The default value is 1 representing a normal map difficulty.
  239. /// Specifies the maximum level to reach for a hero. A value of 0 states that there is no
  240. /// maximum level for heroes. This is the default value.
  241. ui8 levelLimit;
  242. std::string victoryMessage;
  243. std::string defeatMessage;
  244. ui16 victoryIconIndex;
  245. ui16 defeatIconIndex;
  246. std::vector<PlayerInfo> players; /// The default size of the vector is PlayerColor::PLAYER_LIMIT.
  247. ui8 howManyTeams;
  248. std::vector<bool> allowedHeroes;
  249. bool areAnyPlayers; /// Unused. True if there are any playable players on the map.
  250. /// "main quests" of the map that describe victory and loss conditions
  251. std::vector<TriggeredEvent> triggeredEvents;
  252. template <typename Handler>
  253. void serialize(Handler & h, const int Version)
  254. {
  255. h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPlayers;
  256. h & players & howManyTeams & allowedHeroes & triggeredEvents;
  257. h & victoryMessage & victoryIconIndex & defeatMessage & defeatIconIndex;
  258. }
  259. };
  260. /// The map contains the map header, the tiles of the terrain, objects, heroes, towns, rumors...
  261. class DLL_LINKAGE CMap : public CMapHeader
  262. {
  263. public:
  264. CMap();
  265. ~CMap();
  266. void initTerrain();
  267. CMapEditManager * getEditManager();
  268. TerrainTile & getTile(const int3 & tile);
  269. const TerrainTile & getTile(const int3 & tile) const;
  270. bool isCoastalTile(const int3 & pos) const;
  271. bool isInTheMap(const int3 & pos) const;
  272. bool isWaterTile(const int3 & pos) const;
  273. bool canMoveBetween(const int3 &src, const int3 &dst) const;
  274. bool checkForVisitableDir( const int3 & src, const TerrainTile *pom, const int3 & dst ) const;
  275. int3 guardingCreaturePosition (int3 pos) const;
  276. void addBlockVisTiles(CGObjectInstance * obj);
  277. void removeBlockVisTiles(CGObjectInstance * obj, bool total = false);
  278. void calculateGuardingGreaturePositions();
  279. void addNewArtifactInstance(CArtifactInstance * art);
  280. void eraseArtifactInstance(CArtifactInstance * art);
  281. void addNewObject(CGObjectInstance * obj);
  282. /// Gets object of specified type on requested position
  283. const CGObjectInstance * getObjectiveObjectFrom(int3 pos, Obj::EObj type);
  284. CGHeroInstance * getHero(int heroId);
  285. /// Sets the victory/loss condition objectives ??
  286. void checkForObjectives();
  287. ui32 checksum;
  288. std::vector<Rumor> rumors;
  289. std::vector<DisposedHero> disposedHeroes;
  290. std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
  291. std::vector<bool> allowedSpell;
  292. std::vector<bool> allowedArtifact;
  293. std::vector<bool> allowedAbilities;
  294. std::list<CMapEvent> events;
  295. int3 grailPos;
  296. int grailRadius;
  297. //Central lists of items in game. Position of item in the vectors below is their (instance) id.
  298. std::vector< ConstTransitivePtr<CGObjectInstance> > objects;
  299. std::vector< ConstTransitivePtr<CGTownInstance> > towns;
  300. std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances;
  301. std::vector< ConstTransitivePtr<CQuest> > quests;
  302. std::vector< ConstTransitivePtr<CGHeroInstance> > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc.
  303. //Helper lists
  304. std::vector< ConstTransitivePtr<CGHeroInstance> > heroesOnMap;
  305. std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > teleportChannels;
  306. /// associative list to identify which hero/creature id belongs to which object id(index for objects)
  307. std::map<si32, ObjectInstanceID> questIdentifierToId;
  308. std::unique_ptr<CMapEditManager> editManager;
  309. int3 ***guardingCreaturePositions;
  310. std::map<std::string, ConstTransitivePtr<CGObjectInstance> > instanceNames;
  311. private:
  312. /// a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground
  313. TerrainTile*** terrain;
  314. public:
  315. template <typename Handler>
  316. void serialize(Handler &h, const int formatVersion)
  317. {
  318. h & static_cast<CMapHeader&>(*this);
  319. h & rumors & allowedSpell & allowedAbilities & allowedArtifact & events & grailPos;
  320. h & artInstances & quests & allHeroes;
  321. h & questIdentifierToId;
  322. //TODO: viccondetails
  323. int level = twoLevel ? 2 : 1;
  324. if(h.saving)
  325. {
  326. // Save terrain
  327. for(int i = 0; i < width ; ++i)
  328. {
  329. for(int j = 0; j < height ; ++j)
  330. {
  331. for(int k = 0; k < level; ++k)
  332. {
  333. h & terrain[i][j][k];
  334. h & guardingCreaturePositions[i][j][k];
  335. }
  336. }
  337. }
  338. }
  339. else
  340. {
  341. // Load terrain
  342. terrain = new TerrainTile**[width];
  343. guardingCreaturePositions = new int3**[width];
  344. for(int i = 0; i < width; ++i)
  345. {
  346. terrain[i] = new TerrainTile*[height];
  347. guardingCreaturePositions[i] = new int3*[height];
  348. for(int j = 0; j < height; ++j)
  349. {
  350. terrain[i][j] = new TerrainTile[level];
  351. guardingCreaturePositions[i][j] = new int3[level];
  352. }
  353. }
  354. for(int i = 0; i < width ; ++i)
  355. {
  356. for(int j = 0; j < height ; ++j)
  357. {
  358. for(int k = 0; k < level; ++k)
  359. {
  360. h & terrain[i][j][k];
  361. h & guardingCreaturePositions[i][j][k];
  362. }
  363. }
  364. }
  365. }
  366. h & objects;
  367. h & heroesOnMap & teleportChannels & towns & artInstances;
  368. // static members
  369. h & CGKeys::playerKeyMap;
  370. h & CGMagi::eyelist;
  371. h & CGObelisk::obeliskCount & CGObelisk::visited;
  372. h & CGTownInstance::merchantArtifacts;
  373. h & CGTownInstance::universitySkills;
  374. if(formatVersion >= 759)
  375. {
  376. h & instanceNames;
  377. }
  378. }
  379. };