CampaignState.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * CampaignState.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 "../filesystem/ResourcePath.h"
  13. #include "../serializer/Serializeable.h"
  14. #include "../texts/TextLocalizationContainer.h"
  15. #include "CampaignConstants.h"
  16. #include "CampaignScenarioPrologEpilog.h"
  17. #include "../gameState/HighScore.h"
  18. #include "../Point.h"
  19. VCMI_LIB_NAMESPACE_BEGIN
  20. struct StartInfo;
  21. class CGHeroInstance;
  22. class CBinaryReader;
  23. class CInputStream;
  24. class CMap;
  25. class CMapHeader;
  26. class CMapInfo;
  27. class JsonNode;
  28. class CPrivilegedInfoCallback;
  29. class DLL_LINKAGE CampaignRegions
  30. {
  31. // Campaign editor
  32. friend class CampaignEditor;
  33. friend class CampaignProperties;
  34. friend class ScenarioProperties;
  35. std::string campPrefix;
  36. std::vector<std::string> campSuffix;
  37. std::string campBackground;
  38. int colorSuffixLength;
  39. struct DLL_LINKAGE RegionDescription
  40. {
  41. std::string infix;
  42. Point pos;
  43. std::optional<Point> labelPos;
  44. template <typename Handler> void serialize(Handler &h)
  45. {
  46. h & infix;
  47. h & pos;
  48. h & labelPos;
  49. }
  50. static CampaignRegions::RegionDescription fromJson(const JsonNode & node);
  51. static JsonNode toJson(CampaignRegions::RegionDescription & rd);
  52. };
  53. std::vector<RegionDescription> regions;
  54. ImagePath getNameFor(CampaignScenarioID which, int color, std::string type) const;
  55. public:
  56. ImagePath getBackgroundName() const;
  57. Point getPosition(CampaignScenarioID which) const;
  58. std::optional<Point> getLabelPosition(CampaignScenarioID which) const;
  59. ImagePath getAvailableName(CampaignScenarioID which, int color) const;
  60. ImagePath getSelectedName(CampaignScenarioID which, int color) const;
  61. ImagePath getConqueredName(CampaignScenarioID which, int color) const;
  62. template <typename Handler> void serialize(Handler &h)
  63. {
  64. h & campPrefix;
  65. h & colorSuffixLength;
  66. h & regions;
  67. h & campSuffix;
  68. h & campBackground;
  69. }
  70. static CampaignRegions fromJson(const JsonNode & node);
  71. static JsonNode toJson(CampaignRegions cr);
  72. static CampaignRegions getLegacy(int campId);
  73. };
  74. class DLL_LINKAGE CampaignHeader : public boost::noncopyable
  75. {
  76. friend class CampaignHandler;
  77. friend class Campaign;
  78. // Campaign editor
  79. friend class CampaignEditor;
  80. friend class CampaignProperties;
  81. friend class ScenarioProperties;
  82. CampaignVersion version = CampaignVersion::NONE;
  83. CampaignRegions campaignRegions;
  84. MetaString name;
  85. MetaString description;
  86. MetaString author;
  87. MetaString authorContact;
  88. MetaString campaignVersion;
  89. std::time_t creationDateTime;
  90. AudioPath music;
  91. std::string filename;
  92. std::string modName;
  93. std::string encoding;
  94. ImagePath loadingBackground;
  95. ImagePath videoRim;
  96. VideoPath introVideo;
  97. VideoPath outroVideo;
  98. int numberOfScenarios = 0;
  99. bool difficultyChosenByPlayer = false;
  100. void loadLegacyData(ui8 campId);
  101. void loadLegacyData(CampaignRegions regions, int numOfScenario);
  102. TextContainerRegistrable textContainer;
  103. public:
  104. bool playerSelectedDifficulty() const;
  105. bool formatVCMI() const;
  106. std::string getDescriptionTranslated() const;
  107. std::string getNameTranslated() const;
  108. std::string getAuthor() const;
  109. std::string getAuthorContact() const;
  110. std::string getCampaignVersion() const;
  111. time_t getCreationDateTime() const;
  112. std::string getFilename() const;
  113. std::string getModName() const;
  114. std::string getEncoding() const;
  115. AudioPath getMusic() const;
  116. ImagePath getLoadingBackground() const;
  117. ImagePath getVideoRim() const;
  118. VideoPath getIntroVideo() const;
  119. VideoPath getOutroVideo() const;
  120. const CampaignRegions & getRegions() const;
  121. TextContainerRegistrable & getTexts();
  122. template <typename Handler> void serialize(Handler &h)
  123. {
  124. h & version;
  125. h & campaignRegions;
  126. h & numberOfScenarios;
  127. h & name;
  128. h & description;
  129. h & author;
  130. h & authorContact;
  131. h & campaignVersion;
  132. h & creationDateTime;
  133. h & difficultyChosenByPlayer;
  134. h & filename;
  135. h & modName;
  136. h & music;
  137. h & encoding;
  138. h & textContainer;
  139. h & loadingBackground;
  140. h & videoRim;
  141. h & introVideo;
  142. h & outroVideo;
  143. }
  144. };
  145. struct DLL_LINKAGE CampaignBonus
  146. {
  147. CampaignBonusType type = CampaignBonusType::NONE;
  148. //purpose depends on type
  149. int32_t info1 = 0;
  150. int32_t info2 = 0;
  151. int32_t info3 = 0;
  152. bool isBonusForHero() const;
  153. template <typename Handler> void serialize(Handler &h)
  154. {
  155. h & type;
  156. h & info1;
  157. h & info2;
  158. h & info3;
  159. }
  160. };
  161. struct DLL_LINKAGE CampaignTravel
  162. {
  163. struct DLL_LINKAGE WhatHeroKeeps
  164. {
  165. bool experience = false;
  166. bool primarySkills = false;
  167. bool secondarySkills = false;
  168. bool spells = false;
  169. bool artifacts = false;
  170. template <typename Handler> void serialize(Handler &h)
  171. {
  172. h & experience;
  173. h & primarySkills;
  174. h & secondarySkills;
  175. h & spells;
  176. h & artifacts;
  177. }
  178. };
  179. std::set<CreatureID> monstersKeptByHero;
  180. std::set<ArtifactID> artifactsKeptByHero;
  181. std::vector<CampaignBonus> bonusesToChoose;
  182. WhatHeroKeeps whatHeroKeeps;
  183. CampaignStartOptions startOptions = CampaignStartOptions::NONE; //1 - start bonus, 2 - traveling hero, 3 - hero options
  184. PlayerColor playerColor = PlayerColor::NEUTRAL; //only for startOptions == 1
  185. template <typename Handler> void serialize(Handler &h)
  186. {
  187. h & whatHeroKeeps;
  188. h & monstersKeptByHero;
  189. h & artifactsKeptByHero;
  190. h & startOptions;
  191. h & playerColor;
  192. h & bonusesToChoose;
  193. }
  194. };
  195. struct DLL_LINKAGE CampaignScenario
  196. {
  197. std::string mapName; //*.h3m
  198. MetaString scenarioName; //from header
  199. std::set<CampaignScenarioID> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
  200. ui8 regionColor = 0;
  201. ui8 difficulty = 0;
  202. MetaString regionText;
  203. CampaignScenarioPrologEpilog prolog;
  204. CampaignScenarioPrologEpilog epilog;
  205. CampaignTravel travelOptions;
  206. void loadPreconditionRegions(ui32 regions);
  207. bool isNotVoid() const;
  208. template <typename Handler> void serialize(Handler &h)
  209. {
  210. h & mapName;
  211. h & scenarioName;
  212. h & preconditionRegions;
  213. h & regionColor;
  214. h & difficulty;
  215. h & regionText;
  216. h & prolog;
  217. h & epilog;
  218. h & travelOptions;
  219. }
  220. };
  221. /// Class that represents loaded campaign information
  222. class DLL_LINKAGE Campaign : public CampaignHeader, public Serializeable
  223. {
  224. friend class CampaignHandler;
  225. // Campaign editor
  226. friend class CampaignEditor;
  227. friend class CampaignProperties;
  228. friend class ScenarioProperties;
  229. std::map<CampaignScenarioID, CampaignScenario> scenarios;
  230. public:
  231. const CampaignScenario & scenario(CampaignScenarioID which) const;
  232. std::set<CampaignScenarioID> allScenarios() const;
  233. int scenariosCount() const;
  234. void overrideCampaign();
  235. void overrideCampaignScenarios();
  236. template <typename Handler> void serialize(Handler &h)
  237. {
  238. h & static_cast<CampaignHeader&>(*this);
  239. h & scenarios;
  240. }
  241. };
  242. /// Class that represent campaign that is being played at
  243. /// Contains campaign itself as well as current state of the campaign
  244. class DLL_LINKAGE CampaignState : public Campaign
  245. {
  246. friend class CampaignHandler;
  247. // Campaign editor
  248. friend class CampaignEditor;
  249. friend class CampaignProperties;
  250. friend class ScenarioProperties;
  251. using ScenarioPoolType = std::vector<JsonNode>;
  252. using CampaignPoolType = std::map<CampaignScenarioID, ScenarioPoolType>;
  253. using GlobalPoolType = std::map<HeroTypeID, JsonNode>;
  254. /// List of all maps completed by player, in order of their completion
  255. std::vector<CampaignScenarioID> mapsConquered;
  256. /// List of previously loaded campaign maps, to prevent translation of transferred hero names getting lost after their original map has been completed
  257. std::map<CampaignScenarioID, TextContainerRegistrable> mapTranslations;
  258. std::map<CampaignScenarioID, std::vector<uint8_t> > mapPieces; //binary h3ms, scenario number -> map data
  259. std::map<CampaignScenarioID, ui8> chosenCampaignBonuses;
  260. std::optional<CampaignScenarioID> currentMap;
  261. /// Heroes from specific scenario, ordered by descending strength
  262. CampaignPoolType scenarioHeroPool;
  263. /// Pool of heroes currently reserved for usage in campaign
  264. GlobalPoolType globalHeroPool;
  265. public:
  266. CampaignState() = default;
  267. /// Returns last completed scenario, if any
  268. std::optional<CampaignScenarioID> lastScenario() const;
  269. std::optional<CampaignScenarioID> currentScenario() const;
  270. std::set<CampaignScenarioID> conqueredScenarios() const;
  271. /// Returns bonus selected for specific scenario
  272. std::optional<CampaignBonus> getBonus(CampaignScenarioID which) const;
  273. /// Returns index of selected bonus for specified scenario
  274. std::optional<ui8> getBonusID(CampaignScenarioID which) const;
  275. /// Returns true if selected scenario can be selected and started by player
  276. bool isAvailable(CampaignScenarioID whichScenario) const;
  277. /// Returns true if selected scenario has been already completed by player
  278. bool isConquered(CampaignScenarioID whichScenario) const;
  279. /// Returns true if all available scenarios have been completed and campaign is finished
  280. bool isCampaignFinished() const;
  281. std::unique_ptr<CMap> getMap(CampaignScenarioID scenarioId, CPrivilegedInfoCallback * cb);
  282. std::unique_ptr<CMapHeader> getMapHeader(CampaignScenarioID scenarioId) const;
  283. std::shared_ptr<CMapInfo> getMapInfo(CampaignScenarioID scenarioId) const;
  284. void setCurrentMap(CampaignScenarioID which);
  285. void setCurrentMapBonus(ui8 which);
  286. void setCurrentMapAsConquered(std::vector<CGHeroInstance*> heroes);
  287. /// Returns list of heroes that must be reserved for campaign and can only be used for hero placeholders
  288. std::set<HeroTypeID> getReservedHeroes() const;
  289. /// Returns strongest hero from specified scenario, or null if none found
  290. std::shared_ptr<CGHeroInstance> strongestHero(CampaignScenarioID scenarioId, const PlayerColor & owner) const;
  291. /// Returns heroes that can be instantiated as hero placeholders by power
  292. const std::vector<JsonNode> & getHeroesByPower(CampaignScenarioID scenarioId) const;
  293. /// Returns hero for instantiation as placeholder by type
  294. /// May return empty JsonNode if such hero was not found
  295. const JsonNode & getHeroByType(HeroTypeID heroID) const;
  296. JsonNode crossoverSerialize(CGHeroInstance * hero) const;
  297. std::shared_ptr<CGHeroInstance> crossoverDeserialize(const JsonNode & node, CMap * map) const;
  298. std::string campaignSet;
  299. std::vector<HighScoreParameter> highscoreParameters;
  300. template <typename Handler> void serialize(Handler &h)
  301. {
  302. h & static_cast<Campaign&>(*this);
  303. h & scenarioHeroPool;
  304. h & globalHeroPool;
  305. h & mapPieces;
  306. h & mapsConquered;
  307. h & currentMap;
  308. h & chosenCampaignBonuses;
  309. h & campaignSet;
  310. h & mapTranslations;
  311. h & highscoreParameters;
  312. }
  313. };
  314. VCMI_LIB_NAMESPACE_END