CRewardableObject.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * CRewardableObject.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 "CObjectHandler.h"
  12. #include "CArmedInstance.h"
  13. #include "../NetPacksBase.h"
  14. #include "../ResourceSet.h"
  15. VCMI_LIB_NAMESPACE_BEGIN
  16. class CRandomRewardObjectInfo;
  17. class CRewardLimiter;
  18. using TRewardLimitersList = std::vector<std::shared_ptr<CRewardLimiter>>;
  19. /// Limiters of rewards. Rewards will be granted to hero only if he satisfies requirements
  20. /// Note: for this is only a test - it won't remove anything from hero (e.g. artifacts or creatures)
  21. /// NOTE: in future should (partially) replace seer hut/quest guard quests checks
  22. class DLL_LINKAGE CRewardLimiter
  23. {
  24. public:
  25. /// day of week, unused if 0, 1-7 will test for current day of week
  26. si32 dayOfWeek;
  27. /// level that hero needs to have
  28. si32 minLevel;
  29. /// mana points that hero needs to have
  30. si32 manaPoints;
  31. /// percentage of mana points that hero needs to have
  32. si32 manaPercentage;
  33. /// resources player needs to have in order to trigger reward
  34. TResources resources;
  35. /// skills hero needs to have
  36. std::vector<si32> primary;
  37. std::map<SecondarySkill, si32> secondary;
  38. /// artifacts that hero needs to have (equipped or in backpack) to trigger this
  39. /// Note: does not checks for multiple copies of the same arts
  40. std::vector<ArtifactID> artifacts;
  41. /// creatures that hero needs to have
  42. std::vector<CStackBasicDescriptor> creatures;
  43. /// sub-limiters, all must pass for this limiter to pass
  44. TRewardLimitersList allOf;
  45. /// sub-limiters, at least one should pass for this limiter to pass
  46. TRewardLimitersList anyOf;
  47. /// sub-limiters, none should pass for this limiter to pass
  48. TRewardLimitersList noneOf;
  49. CRewardLimiter():
  50. dayOfWeek(0),
  51. minLevel(0),
  52. primary(4, 0)
  53. {}
  54. bool heroAllowed(const CGHeroInstance * hero) const;
  55. template <typename Handler> void serialize(Handler &h, const int version)
  56. {
  57. h & dayOfWeek;
  58. h & minLevel;
  59. h & manaPoints;
  60. h & manaPercentage;
  61. h & resources;
  62. h & primary;
  63. h & secondary;
  64. h & artifacts;
  65. h & creatures;
  66. h & allOf;
  67. h & anyOf;
  68. h & noneOf;
  69. }
  70. };
  71. class DLL_LINKAGE CRewardResetInfo
  72. {
  73. public:
  74. CRewardResetInfo()
  75. : period(0)
  76. , visitors(false)
  77. , grants(false)
  78. , rewards(false)
  79. {}
  80. /// if above zero, object state will be reset each resetDuration days
  81. ui32 period;
  82. /// if true - reset list of visitors (heroes & players) on reset
  83. bool visitors;
  84. /// if true - reset number of grants of rewards on reset
  85. bool grants;
  86. /// if true - re-randomize rewards on a new week
  87. bool rewards;
  88. template <typename Handler> void serialize(Handler &h, const int version)
  89. {
  90. h & period;
  91. h & visitors;
  92. h & grants;
  93. h & rewards;
  94. }
  95. };
  96. /// Reward that can be granted to a hero
  97. /// NOTE: eventually should replace seer hut rewards and events/pandoras
  98. class DLL_LINKAGE CRewardInfo
  99. {
  100. public:
  101. /// resources that will be given to player
  102. TResources resources;
  103. /// received experience
  104. ui32 gainedExp;
  105. /// received levels (converted into XP during grant)
  106. ui32 gainedLevels;
  107. /// mana given to/taken from hero, fixed value
  108. si32 manaDiff;
  109. /// if giving mana points puts hero above mana pool, any overflow will be multiplied by specified percentage
  110. si32 manaOverflowFactor;
  111. /// fixed value, in form of percentage from max
  112. si32 manaPercentage;
  113. /// movement points, only for current day. Bonuses should be used to grant MP on any other day
  114. si32 movePoints;
  115. /// fixed value, in form of percentage from max
  116. si32 movePercentage;
  117. /// list of bonuses, e.g. morale/luck
  118. std::vector<Bonus> bonuses;
  119. /// skills that hero may receive or lose
  120. std::vector<si32> primary;
  121. std::map<SecondarySkill, si32> secondary;
  122. /// creatures that will be changed in hero's army
  123. std::map<CreatureID, CreatureID> creaturesChange;
  124. /// objects that hero may receive
  125. std::vector<ArtifactID> artifacts;
  126. std::vector<SpellID> spells;
  127. std::vector<CStackBasicDescriptor> creatures;
  128. /// list of components that will be added to reward description. First entry in list will override displayed component
  129. std::vector<Component> extraComponents;
  130. /// if set to true, object will be removed after granting reward
  131. bool removeObject;
  132. /// Generates list of components that describes reward for a specific hero
  133. virtual void loadComponents(std::vector<Component> & comps,
  134. const CGHeroInstance * h) const;
  135. Component getDisplayedComponent(const CGHeroInstance * h) const;
  136. CRewardInfo() :
  137. gainedExp(0),
  138. gainedLevels(0),
  139. manaDiff(0),
  140. manaPercentage(-1),
  141. movePoints(0),
  142. movePercentage(-1),
  143. primary(4, 0),
  144. removeObject(false)
  145. {}
  146. template <typename Handler> void serialize(Handler &h, const int version)
  147. {
  148. h & resources;
  149. h & extraComponents;
  150. h & removeObject;
  151. h & manaPercentage;
  152. h & movePercentage;
  153. h & gainedExp;
  154. h & gainedLevels;
  155. h & manaDiff;
  156. h & manaOverflowFactor;
  157. h & movePoints;
  158. h & primary;
  159. h & secondary;
  160. h & bonuses;
  161. h & artifacts;
  162. h & spells;
  163. h & creatures;
  164. h & creaturesChange;
  165. }
  166. };
  167. class DLL_LINKAGE CRewardVisitInfo
  168. {
  169. public:
  170. CRewardLimiter limiter;
  171. CRewardInfo reward;
  172. /// Message that will be displayed on granting of this reward, if not empty
  173. MetaString message;
  174. /// Chance for this reward to be selected in case of random choice
  175. si32 selectChance;
  176. /// How many times this reward can be granted between two resets
  177. si32 numOfGrantsAllowed;
  178. /// How many times this reward has been granted since last reset
  179. si32 numOfGrantsPerformed;
  180. CRewardVisitInfo():
  181. selectChance(0),
  182. numOfGrantsAllowed(0),
  183. numOfGrantsPerformed(0)
  184. {}
  185. template <typename Handler> void serialize(Handler &h, const int version)
  186. {
  187. h & limiter;
  188. h & reward;
  189. h & message;
  190. h & selectChance;
  191. h & numOfGrantsAllowed;
  192. h & numOfGrantsPerformed;
  193. }
  194. };
  195. namespace Rewardable
  196. {
  197. const std::array<std::string, 3> SelectModeString{"selectFirst", "selectPlayer", "selectRandom"};
  198. const std::array<std::string, 5> VisitModeString{"unlimited", "once", "hero", "bonus", "player"};
  199. }
  200. /// Base class that can handle granting rewards to visiting heroes.
  201. /// Inherits from CArmedInstance for proper trasfer of armies
  202. class DLL_LINKAGE CRewardableObject : public CArmedInstance
  203. {
  204. /// function that must be called if hero got level-up during grantReward call
  205. void grantRewardAfterLevelup(const CRewardVisitInfo & reward, const CGHeroInstance * hero) const;
  206. /// grants reward to hero
  207. void grantRewardBeforeLevelup(const CRewardVisitInfo & reward, const CGHeroInstance * hero) const;
  208. public:
  209. enum EVisitMode
  210. {
  211. VISIT_UNLIMITED, // any number of times. Side effect - object hover text won't contain visited/not visited text
  212. VISIT_ONCE, // only once, first to visit get all the rewards
  213. VISIT_HERO, // every hero can visit object once
  214. VISIT_BONUS, // can be visited by any hero that don't have bonus from this object
  215. VISIT_PLAYER // every player can visit object once
  216. };
  217. protected:
  218. /// controls selection of reward granted to player
  219. enum ESelectMode
  220. {
  221. SELECT_FIRST, // first reward that matches limiters
  222. SELECT_PLAYER, // player can select from all allowed rewards
  223. SELECT_RANDOM // reward will be selected from allowed randomly
  224. };
  225. /// filters list of visit info and returns rewards that can be granted to current hero
  226. virtual std::vector<ui32> getAvailableRewards(const CGHeroInstance * hero) const;
  227. virtual void grantReward(ui32 rewardID, const CGHeroInstance * hero) const;
  228. virtual CRewardVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const;
  229. virtual void triggerReset() const;
  230. /// Rewards that can be granted by an object
  231. std::vector<CRewardVisitInfo> info;
  232. /// MetaString's that contain text for messages for specific situations
  233. MetaString onSelect;
  234. MetaString onVisited;
  235. MetaString onEmpty;
  236. /// how reward will be selected, uses ESelectMode enum
  237. ui8 selectMode;
  238. /// contols who can visit an object, uses EVisitMode enum
  239. ui8 visitMode;
  240. /// reward selected by player
  241. ui16 selectedReward;
  242. /// how and when should the object be reset
  243. CRewardResetInfo resetParameters;
  244. /// if true - player can refuse visiting an object (e.g. Tomb)
  245. bool canRefuse;
  246. public:
  247. EVisitMode getVisitMode() const;
  248. ui16 getResetDuration() const;
  249. void setPropertyDer(ui8 what, ui32 val) override;
  250. std::string getHoverText(PlayerColor player) const override;
  251. std::string getHoverText(const CGHeroInstance * hero) const override;
  252. /// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player)
  253. bool wasVisited(PlayerColor player) const override;
  254. bool wasVisited(const CGHeroInstance * h) const override;
  255. /// gives reward to player or ask for choice in case of multiple rewards
  256. void onHeroVisit(const CGHeroInstance *h) const override;
  257. ///possibly resets object state
  258. void newTurn(CRandomGenerator & rand) const override;
  259. /// gives second part of reward after hero level-ups for proper granting of spells/mana
  260. void heroLevelUpDone(const CGHeroInstance *hero) const override;
  261. /// applies player selection of reward
  262. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  263. /// function that will be called once reward is fully granted to hero
  264. virtual void onRewardGiven(const CGHeroInstance * hero) const;
  265. void initObj(CRandomGenerator & rand) override;
  266. CRewardableObject();
  267. template <typename Handler> void serialize(Handler &h, const int version)
  268. {
  269. h & static_cast<CArmedInstance&>(*this);
  270. h & info;
  271. h & canRefuse;
  272. h & resetParameters;
  273. h & onSelect;
  274. h & onVisited;
  275. h & onEmpty;
  276. h & visitMode;
  277. h & selectMode;
  278. h & selectedReward;
  279. }
  280. // for configuration/object setup
  281. friend class CRandomRewardObjectInfo;
  282. };
  283. //TODO:
  284. // MAX
  285. // class DLL_LINKAGE CGPandoraBox : public CArmedInstance
  286. // class DLL_LINKAGE CGEvent : public CGPandoraBox //event objects
  287. // class DLL_LINKAGE CGSeerHut : public CArmedInstance, public IQuestObject //army is used when giving reward
  288. // class DLL_LINKAGE CGQuestGuard : public CGSeerHut
  289. // class DLL_LINKAGE CBank : public CArmedInstance
  290. // class DLL_LINKAGE CGPyramid : public CBank
  291. // EXTRA
  292. // class DLL_LINKAGE COPWBonus : public CGTownBuilding
  293. // class DLL_LINKAGE CTownBonus : public CGTownBuilding
  294. // class DLL_LINKAGE CGKeys : public CGObjectInstance //Base class for Keymaster and guards
  295. // class DLL_LINKAGE CGKeymasterTent : public CGKeys
  296. // class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject
  297. // POSSIBLE
  298. // class DLL_LINKAGE CGSignBottle : public CGObjectInstance //signs and ocean bottles
  299. // class DLL_LINKAGE CGWitchHut : public CPlayersVisited
  300. // class DLL_LINKAGE CGScholar : public CGObjectInstance
  301. VCMI_LIB_NAMESPACE_END