Bonus.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Bonus.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 "BonusEnum.h"
  12. #include "BonusCustomTypes.h"
  13. #include "Limiters.h"
  14. #include "../serializer/Serializeable.h"
  15. #include "../texts/MetaString.h"
  16. #include "../filesystem/ResourcePath.h"
  17. VCMI_LIB_NAMESPACE_BEGIN
  18. class IBonusBearer;
  19. class IPropagator;
  20. class IUpdater;
  21. class CSelector;
  22. class IGameInfoCallback;
  23. using TBonusListPtr = std::shared_ptr<BonusList>;
  24. using TConstBonusListPtr = std::shared_ptr<const BonusList>;
  25. using TPropagatorPtr = std::shared_ptr<const IPropagator>;
  26. using TUpdaterPtr = std::shared_ptr<const IUpdater>;
  27. class DLL_LINKAGE CAddInfo final
  28. {
  29. public:
  30. using container = std::vector<si32>;
  31. using size_type = container::size_type;
  32. enum { NONE = -1 };
  33. CAddInfo();
  34. CAddInfo(si32 value);
  35. // Inline definitions in the header to avoid missing symbols across TUs
  36. bool operator==(const CAddInfo& other) const noexcept {
  37. return data_ == other.data_;
  38. }
  39. bool operator!=(const CAddInfo& other) const noexcept {
  40. return !(*this == other);
  41. }
  42. bool operator==(si32 value) const
  43. {
  44. switch(data_.size())
  45. {
  46. case 0:
  47. return value == CAddInfo::NONE;
  48. case 1:
  49. return data_[0] == value;
  50. default:
  51. return false;
  52. }
  53. }
  54. bool operator!=(si32 value) const
  55. {
  56. return !(*this == value);
  57. }
  58. si32 & operator[](size_type pos)
  59. {
  60. if(pos >= data_.size())
  61. data_.resize(pos + 1, CAddInfo::NONE);
  62. return data_[pos];
  63. }
  64. si32 operator[](size_type pos) const
  65. {
  66. return pos < data_.size() ? data_[pos] : CAddInfo::NONE;
  67. }
  68. std::string toString() const;
  69. JsonNode toJsonNode() const;
  70. // Minimal vector-like facade
  71. size_type size() const noexcept { return data_.size(); }
  72. bool empty() const noexcept { return data_.empty(); }
  73. void push_back(si32 v) { data_.push_back(v); }
  74. void resize(size_type n, si32 fill = CAddInfo::NONE) { data_.resize(n, fill); }
  75. container::iterator begin() noexcept { return data_.begin(); }
  76. container::iterator end() noexcept { return data_.end(); }
  77. container::const_iterator begin() const noexcept { return data_.begin(); }
  78. container::const_iterator end() const noexcept { return data_.end(); }
  79. // expose const view for free operators
  80. const container& data() const noexcept { return data_; }
  81. template <class H>
  82. void serialize(H& h) { h & data_; }
  83. private:
  84. container data_;
  85. };
  86. /// Struct for handling bonuses of several types. Can be transferred to any hero
  87. struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable
  88. {
  89. BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values - 2 bytes
  90. si32 val = 0;
  91. si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
  92. BonusValueType valType = BonusValueType::ADDITIVE_VALUE; // 1 byte
  93. BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus - 1 byte
  94. BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE. - 1 byte
  95. BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT; // 1 byte
  96. BonusType type = BonusType::NONE; //uses BonusType values - says to what is this bonus - 2 bytes
  97. BonusSubtypeID subtype;
  98. BonusSourceID sid; //source id: id of object/artifact/spell
  99. std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
  100. CAddInfo additionalInfo;
  101. TLimiterPtr limiter;
  102. TPropagatorPtr propagator;
  103. TUpdaterPtr updater;
  104. TUpdaterPtr propagationUpdater;
  105. ImagePath customIconPath;
  106. MetaString description;
  107. PlayerColor bonusOwner = PlayerColor::CANNOT_DETERMINE;
  108. bool hidden = false;
  109. Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID);
  110. Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID, BonusSubtypeID subtype);
  111. Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID, BonusSubtypeID subtype, BonusValueType ValType);
  112. Bonus(const Bonus & inst, const BonusSourceID & sourceId);
  113. Bonus() = default;
  114. template <typename Handler> void serialize(Handler &h)
  115. {
  116. h & duration;
  117. h & type;
  118. h & subtype;
  119. h & source;
  120. h & val;
  121. h & sid;
  122. h & description;
  123. if (h.hasFeature(Handler::Version::CUSTOM_BONUS_ICONS))
  124. h & customIconPath;
  125. if (h.hasFeature(Handler::Version::BONUS_HIDDEN))
  126. h & hidden;
  127. h & additionalInfo;
  128. h & turnsRemain;
  129. h & valType;
  130. h & stacking;
  131. h & effectRange;
  132. h & limiter;
  133. h & propagator;
  134. h & updater;
  135. h & propagationUpdater;
  136. h & targetSourceType;
  137. }
  138. template <typename Ptr>
  139. static bool compareByAdditionalInfo(const Ptr& a, const Ptr& b)
  140. {
  141. return a->additionalInfo < b->additionalInfo;
  142. }
  143. static bool NDays(const Bonus *hb)
  144. {
  145. auto set = hb->duration & BonusDuration::N_DAYS;
  146. return set != 0;
  147. }
  148. static bool NTurns(const Bonus *hb)
  149. {
  150. auto set = hb->duration & BonusDuration::N_TURNS;
  151. return set != 0;
  152. }
  153. static bool OneDay(const Bonus *hb)
  154. {
  155. auto set = hb->duration & BonusDuration::ONE_DAY;
  156. return set != 0;
  157. }
  158. static bool OneWeek(const Bonus *hb)
  159. {
  160. auto set = hb->duration & BonusDuration::ONE_WEEK;
  161. return set != 0;
  162. }
  163. static bool OneBattle(const Bonus *hb)
  164. {
  165. auto set = hb->duration & BonusDuration::ONE_BATTLE;
  166. return set != 0;
  167. }
  168. static bool Permanent(const Bonus *hb)
  169. {
  170. auto set = hb->duration & BonusDuration::PERMANENT;
  171. return set != 0;
  172. }
  173. static bool UntilGetsTurn(const Bonus *hb)
  174. {
  175. auto set = hb->duration & BonusDuration::STACK_GETS_TURN;
  176. return set != 0;
  177. }
  178. static bool UntilAttack(const Bonus *hb)
  179. {
  180. auto set = hb->duration & BonusDuration::UNTIL_ATTACK;
  181. return set != 0;
  182. }
  183. static bool UntilBeingAttacked(const Bonus *hb)
  184. {
  185. auto set = hb->duration & BonusDuration::UNTIL_BEING_ATTACKED;
  186. return set != 0;
  187. }
  188. static bool UntilCommanderKilled(const Bonus *hb)
  189. {
  190. auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
  191. return set != 0;
  192. }
  193. static bool UntilOwnAttack(const Bonus *hb)
  194. {
  195. auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK;
  196. return set != 0;
  197. }
  198. inline bool operator == (const BonusType & cf) const
  199. {
  200. return type == cf;
  201. }
  202. inline void operator += (const ui32 Val) //no return
  203. {
  204. val += Val;
  205. }
  206. std::string Description(const IGameInfoCallback * cb, std::optional<si32> customValue = {}) const;
  207. JsonNode toJsonNode() const;
  208. std::shared_ptr<Bonus> addLimiter(const TLimiterPtr & Limiter); //returns this for convenient chain-calls
  209. std::shared_ptr<Bonus> addPropagator(const TPropagatorPtr & Propagator); //returns this for convenient chain-calls
  210. std::shared_ptr<Bonus> addUpdater(const TUpdaterPtr & Updater); //returns this for convenient chain-calls
  211. };
  212. DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
  213. VCMI_LIB_NAMESPACE_END