CampaignBonus.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * CampaignBonus.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 "CampaignConstants.h"
  12. #include "../constants/EntityIdentifiers.h"
  13. VCMI_LIB_NAMESPACE_BEGIN
  14. class CBinaryReader;
  15. class MapIdentifiersH3M;
  16. class JsonNode;
  17. struct CampaignBonusSpell
  18. {
  19. HeroTypeID hero;
  20. SpellID spell;
  21. template <typename Handler> void serialize(Handler &h)
  22. {
  23. h & hero;
  24. h & spell;
  25. }
  26. };
  27. struct CampaignBonusCreatures
  28. {
  29. HeroTypeID hero;
  30. CreatureID creature;
  31. int32_t amount = 0;
  32. template <typename Handler> void serialize(Handler &h)
  33. {
  34. h & hero;
  35. h & creature;
  36. h & amount;
  37. }
  38. };
  39. struct CampaignBonusBuilding
  40. {
  41. BuildingID buildingH3M;
  42. BuildingID buildingDecoded;
  43. template <typename Handler> void serialize(Handler &h)
  44. {
  45. h & buildingH3M;
  46. h & buildingDecoded;
  47. }
  48. };
  49. struct CampaignBonusArtifact
  50. {
  51. HeroTypeID hero;
  52. ArtifactID artifact;
  53. template <typename Handler> void serialize(Handler &h)
  54. {
  55. h & hero;
  56. h & artifact;
  57. }
  58. };
  59. struct CampaignBonusSpellScroll
  60. {
  61. HeroTypeID hero;
  62. SpellID spell;
  63. template <typename Handler> void serialize(Handler &h)
  64. {
  65. h & hero;
  66. h & spell;
  67. }
  68. };
  69. struct CampaignBonusPrimarySkill
  70. {
  71. HeroTypeID hero;
  72. std::array<uint8_t, 4> amounts = {};
  73. template <typename Handler> void serialize(Handler &h)
  74. {
  75. h & hero;
  76. h & amounts;
  77. }
  78. };
  79. struct CampaignBonusSecondarySkill
  80. {
  81. HeroTypeID hero;
  82. SecondarySkill skill;
  83. int32_t mastery = 0;
  84. template <typename Handler> void serialize(Handler &h)
  85. {
  86. h & hero;
  87. h & skill;
  88. h & mastery;
  89. }
  90. };
  91. struct CampaignBonusStartingResources
  92. {
  93. GameResID resource;
  94. int32_t amount = 0;
  95. template <typename Handler> void serialize(Handler &h)
  96. {
  97. h & resource;
  98. h & amount;
  99. }
  100. };
  101. struct CampaignBonusHeroesFromScenario
  102. {
  103. PlayerColor startingPlayer;
  104. CampaignScenarioID scenario;
  105. template <typename Handler> void serialize(Handler &h)
  106. {
  107. h & startingPlayer;
  108. h & scenario;
  109. }
  110. };
  111. struct CampaignBonusStartingHero
  112. {
  113. PlayerColor startingPlayer;
  114. HeroTypeID hero;
  115. template <typename Handler> void serialize(Handler &h)
  116. {
  117. h & startingPlayer;
  118. h & hero;
  119. }
  120. };
  121. class CampaignBonus
  122. {
  123. using Variant = std::variant<
  124. CampaignBonusSpell, // UNTESTED
  125. CampaignBonusCreatures,
  126. CampaignBonusBuilding, // UNTESTED - broken, Long Live the King, Liberation last
  127. CampaignBonusArtifact,
  128. CampaignBonusSpellScroll,
  129. CampaignBonusPrimarySkill,
  130. CampaignBonusSecondarySkill,
  131. CampaignBonusStartingResources,
  132. CampaignBonusHeroesFromScenario,
  133. CampaignBonusStartingHero>;
  134. Variant data;
  135. template<typename T, typename = void>
  136. struct HasHero : std::false_type { };
  137. template<typename T>
  138. struct HasHero<T, decltype(std::declval<T>().hero, void())> : std::true_type { };
  139. public:
  140. CampaignBonus() = default;
  141. template<typename BonusType>
  142. CampaignBonus(const BonusType & value)
  143. :data(value)
  144. {}
  145. DLL_LINKAGE CampaignBonus(CBinaryReader & reader, const MapIdentifiersH3M & remapper, CampaignStartOptions mode);
  146. DLL_LINKAGE CampaignBonus(const JsonNode & json, CampaignStartOptions mode);
  147. template<typename T>
  148. const T & getValue() const
  149. {
  150. return std::get<T>(data);
  151. }
  152. HeroTypeID getTargetedHero() const
  153. {
  154. HeroTypeID result;
  155. std::visit([&result](const auto & bonusValue){
  156. if constexpr (HasHero<decltype(bonusValue)>::value)
  157. {
  158. result = bonusValue.hero;
  159. }
  160. else
  161. throw std::runtime_error("Attempt to get targeted hero on invalid type!");
  162. }, data);
  163. return result;
  164. }
  165. bool isBonusForHero() const
  166. {
  167. auto type = getType();
  168. return type == CampaignBonusType::SPELL ||
  169. type == CampaignBonusType::MONSTER ||
  170. type == CampaignBonusType::ARTIFACT ||
  171. type == CampaignBonusType::SPELL_SCROLL ||
  172. type == CampaignBonusType::PRIMARY_SKILL ||
  173. type == CampaignBonusType::SECONDARY_SKILL;
  174. }
  175. CampaignBonusType getType() const
  176. {
  177. return static_cast<CampaignBonusType>(data.index());
  178. }
  179. DLL_LINKAGE JsonNode toJson() const;
  180. template <typename Handler> void serialize(Handler &h)
  181. {
  182. h & data;
  183. }
  184. };
  185. VCMI_LIB_NAMESPACE_END