MiscObjects.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /*
  2. * MiscObjects.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 "CArmedInstance.h"
  12. #include "../ResourceSet.h"
  13. VCMI_LIB_NAMESPACE_BEGIN
  14. class CMap;
  15. class HillFortInstanceConstructor;
  16. // This one teleport-specific, but has to be available everywhere in callbacks and netpacks
  17. // For now it's will be there till teleports code refactored and moved into own file
  18. using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
  19. /// Legacy class, use CRewardableObject instead
  20. class DLL_LINKAGE CTeamVisited: public CGObjectInstance
  21. {
  22. public:
  23. std::set<PlayerColor> players; //players that visited this object
  24. bool wasVisited (const CGHeroInstance * h) const override;
  25. bool wasVisited(PlayerColor player) const override;
  26. bool wasVisited(const TeamID & team) const;
  27. void setPropertyDer(ui8 what, ui32 val) override;
  28. template <typename Handler> void serialize(Handler &h, const int version)
  29. {
  30. h & static_cast<CGObjectInstance&>(*this);
  31. h & players;
  32. }
  33. static constexpr int OBJPROP_VISITED = 10;
  34. };
  35. class DLL_LINKAGE CGCreature : public CArmedInstance //creatures on map
  36. {
  37. public:
  38. enum Action {
  39. FIGHT = -2, FLEE = -1, JOIN_FOR_FREE = 0 //values > 0 mean gold price
  40. };
  41. enum Character {
  42. COMPLIANT = 0, FRIENDLY = 1, AGRESSIVE = 2, HOSTILE = 3, SAVAGE = 4
  43. };
  44. ui32 identifier; //unique code for this monster (used in missions)
  45. si8 character; //character of this set of creatures (0 - the most friendly, 4 - the most hostile) => on init changed to -4 (compliant) ... 10 value (savage)
  46. std::string message; //message printed for attacking hero
  47. TResources resources; // resources given to hero that has won with monsters
  48. ArtifactID gainedArtifact; //ID of artifact gained to hero, -1 if none
  49. bool neverFlees; //if true, the troops will never flee
  50. bool notGrowingTeam; //if true, number of units won't grow
  51. ui64 temppower; //used to handle fractional stack growth for tiny stacks
  52. bool refusedJoining;
  53. void onHeroVisit(const CGHeroInstance * h) const override;
  54. std::string getHoverText(PlayerColor player) const override;
  55. std::string getHoverText(const CGHeroInstance * hero) const override;
  56. void initObj(CRandomGenerator & rand) override;
  57. void newTurn(CRandomGenerator & rand) const override;
  58. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  59. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  60. //stack formation depends on position,
  61. bool containsUpgradedStack() const;
  62. int getNumberOfStacks(const CGHeroInstance *hero) const;
  63. struct DLL_LINKAGE formationInfo // info about merging stacks after battle back into one
  64. {
  65. si32 basicType;
  66. ui8 upgrade; //random seed used to determine number of stacks and is there's upgraded stack
  67. template <typename Handler> void serialize(Handler &h, const int version)
  68. {
  69. h & basicType;
  70. h & upgrade;
  71. }
  72. } formation;
  73. template <typename Handler> void serialize(Handler &h, const int version)
  74. {
  75. h & static_cast<CArmedInstance&>(*this);
  76. h & identifier;
  77. h & character;
  78. h & message;
  79. h & resources;
  80. h & gainedArtifact;
  81. h & neverFlees;
  82. h & notGrowingTeam;
  83. h & temppower;
  84. h & refusedJoining;
  85. h & formation;
  86. }
  87. protected:
  88. void setPropertyDer(ui8 what, ui32 val) override;
  89. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  90. private:
  91. void fight(const CGHeroInstance *h) const;
  92. void flee( const CGHeroInstance * h ) const;
  93. void fleeDecision(const CGHeroInstance *h, ui32 pursue) const;
  94. void joinDecision(const CGHeroInstance *h, int cost, ui32 accept) const;
  95. int takenAction(const CGHeroInstance *h, bool allowJoin=true) const; //action on confrontation: -2 - fight, -1 - flee, >=0 - will join for given value of gold (may be 0)
  96. void giveReward(const CGHeroInstance * h) const;
  97. };
  98. class DLL_LINKAGE CGSignBottle : public CGObjectInstance //signs and ocean bottles
  99. {
  100. public:
  101. std::string message;
  102. void onHeroVisit(const CGHeroInstance * h) const override;
  103. void initObj(CRandomGenerator & rand) override;
  104. template <typename Handler> void serialize(Handler &h, const int version)
  105. {
  106. h & static_cast<CGObjectInstance&>(*this);
  107. h & message;
  108. }
  109. protected:
  110. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  111. };
  112. class DLL_LINKAGE CGWitchHut : public CTeamVisited
  113. {
  114. public:
  115. std::set<SecondarySkill> allowedAbilities;
  116. SecondarySkill ability;
  117. std::string getHoverText(PlayerColor player) const override;
  118. std::string getHoverText(const CGHeroInstance * hero) const override;
  119. void onHeroVisit(const CGHeroInstance * h) const override;
  120. void initObj(CRandomGenerator & rand) override;
  121. template <typename Handler> void serialize(Handler &h, const int version)
  122. {
  123. h & static_cast<CTeamVisited&>(*this);
  124. h & allowedAbilities;
  125. h & ability;
  126. }
  127. protected:
  128. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  129. };
  130. class DLL_LINKAGE CGScholar : public CGObjectInstance
  131. {
  132. public:
  133. enum EBonusType {PRIM_SKILL, SECONDARY_SKILL, SPELL, RANDOM = 255};
  134. EBonusType bonusType;
  135. ui16 bonusID; //ID of skill/spell
  136. CGScholar() : bonusType(EBonusType::RANDOM),bonusID(0){};
  137. void onHeroVisit(const CGHeroInstance * h) const override;
  138. void initObj(CRandomGenerator & rand) override;
  139. template <typename Handler> void serialize(Handler &h, const int version)
  140. {
  141. h & static_cast<CGObjectInstance&>(*this);
  142. h & bonusType;
  143. h & bonusID;
  144. }
  145. protected:
  146. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  147. };
  148. class DLL_LINKAGE CGGarrison : public CArmedInstance
  149. {
  150. public:
  151. bool removableUnits;
  152. bool passableFor(PlayerColor color) const override;
  153. void onHeroVisit(const CGHeroInstance * h) const override;
  154. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  155. template <typename Handler> void serialize(Handler &h, const int version)
  156. {
  157. h & static_cast<CArmedInstance&>(*this);
  158. h & removableUnits;
  159. }
  160. protected:
  161. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  162. };
  163. class DLL_LINKAGE CGArtifact : public CArmedInstance
  164. {
  165. public:
  166. CArtifactInstance * storedArtifact = nullptr;
  167. std::string message;
  168. void onHeroVisit(const CGHeroInstance * h) const override;
  169. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  170. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  171. std::string getObjectName() const override;
  172. void pick( const CGHeroInstance * h ) const;
  173. void initObj(CRandomGenerator & rand) override;
  174. void afterAddToMap(CMap * map) override;
  175. BattleField getBattlefield() const override;
  176. template <typename Handler> void serialize(Handler &h, const int version)
  177. {
  178. h & static_cast<CArmedInstance&>(*this);
  179. h & message;
  180. h & storedArtifact;
  181. }
  182. protected:
  183. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  184. };
  185. class DLL_LINKAGE CGResource : public CArmedInstance
  186. {
  187. public:
  188. static constexpr ui32 RANDOM_AMOUNT = 0;
  189. ui32 amount = RANDOM_AMOUNT; //0 if random
  190. std::string message;
  191. void onHeroVisit(const CGHeroInstance * h) const override;
  192. void initObj(CRandomGenerator & rand) override;
  193. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  194. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  195. std::string getHoverText(PlayerColor player) const override;
  196. void collectRes(const PlayerColor & player) const;
  197. template <typename Handler> void serialize(Handler &h, const int version)
  198. {
  199. h & static_cast<CArmedInstance&>(*this);
  200. h & amount;
  201. h & message;
  202. }
  203. protected:
  204. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  205. };
  206. class DLL_LINKAGE CGShrine : public CTeamVisited
  207. {
  208. public:
  209. MetaString visitText;
  210. SpellID spell; //id of spell or NONE if random
  211. void onHeroVisit(const CGHeroInstance * h) const override;
  212. void initObj(CRandomGenerator & rand) override;
  213. std::string getHoverText(PlayerColor player) const override;
  214. std::string getHoverText(const CGHeroInstance * hero) const override;
  215. template <typename Handler> void serialize(Handler &h, const int version)
  216. {
  217. h & static_cast<CTeamVisited&>(*this);;
  218. h & spell;
  219. h & visitText;
  220. }
  221. protected:
  222. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  223. };
  224. class DLL_LINKAGE CGMine : public CArmedInstance
  225. {
  226. public:
  227. GameResID producedResource;
  228. ui32 producedQuantity;
  229. std::set<GameResID> abandonedMineResources;
  230. private:
  231. void onHeroVisit(const CGHeroInstance * h) const override;
  232. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  233. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  234. void flagMine(const PlayerColor & player) const;
  235. void newTurn(CRandomGenerator & rand) const override;
  236. void initObj(CRandomGenerator & rand) override;
  237. std::string getObjectName() const override;
  238. std::string getHoverText(PlayerColor player) const override;
  239. bool isAbandoned() const;
  240. public:
  241. template <typename Handler> void serialize(Handler &h, const int version)
  242. {
  243. h & static_cast<CArmedInstance&>(*this);
  244. h & producedResource;
  245. h & producedQuantity;
  246. h & abandonedMineResources;
  247. }
  248. ui32 defaultResProduction() const;
  249. protected:
  250. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  251. };
  252. struct DLL_LINKAGE TeleportChannel
  253. {
  254. enum EPassability {UNKNOWN, IMPASSABLE, PASSABLE};
  255. std::vector<ObjectInstanceID> entrances;
  256. std::vector<ObjectInstanceID> exits;
  257. EPassability passability = EPassability::UNKNOWN;
  258. template <typename Handler> void serialize(Handler &h, const int version)
  259. {
  260. h & entrances;
  261. h & exits;
  262. h & passability;
  263. }
  264. };
  265. class DLL_LINKAGE CGTeleport : public CGObjectInstance
  266. {
  267. bool isChannelEntrance(const ObjectInstanceID & id) const;
  268. bool isChannelExit(const ObjectInstanceID & id) const;
  269. std::vector<ObjectInstanceID> getAllEntrances(bool excludeCurrent = false) const;
  270. protected:
  271. enum EType {UNKNOWN, ENTRANCE, EXIT, BOTH};
  272. EType type = EType::UNKNOWN;
  273. ObjectInstanceID getRandomExit(const CGHeroInstance * h) const;
  274. std::vector<ObjectInstanceID> getAllExits(bool excludeCurrent = false) const;
  275. public:
  276. TeleportChannelID channel;
  277. bool isEntrance() const;
  278. bool isExit() const;
  279. virtual void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const = 0;
  280. static bool isTeleport(const CGObjectInstance * dst);
  281. static bool isConnected(const CGTeleport * src, const CGTeleport * dst);
  282. static bool isConnected(const CGObjectInstance * src, const CGObjectInstance * dst);
  283. static void addToChannel(std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > &channelsList, const CGTeleport * obj);
  284. static std::vector<ObjectInstanceID> getPassableExits(CGameState * gs, const CGHeroInstance * h, std::vector<ObjectInstanceID> exits);
  285. static bool isExitPassable(CGameState * gs, const CGHeroInstance * h, const CGObjectInstance * obj);
  286. template <typename Handler> void serialize(Handler &h, const int version)
  287. {
  288. h & type;
  289. h & channel;
  290. h & static_cast<CGObjectInstance&>(*this);
  291. }
  292. };
  293. class DLL_LINKAGE CGMonolith : public CGTeleport
  294. {
  295. TeleportChannelID findMeChannel(const std::vector<Obj> & IDs, int SubID) const;
  296. protected:
  297. void onHeroVisit(const CGHeroInstance * h) const override;
  298. void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
  299. void initObj(CRandomGenerator & rand) override;
  300. public:
  301. template <typename Handler> void serialize(Handler &h, const int version)
  302. {
  303. h & static_cast<CGTeleport&>(*this);
  304. }
  305. };
  306. class DLL_LINKAGE CGSubterraneanGate : public CGMonolith
  307. {
  308. void onHeroVisit(const CGHeroInstance * h) const override;
  309. void initObj(CRandomGenerator & rand) override;
  310. public:
  311. static void postInit();
  312. template <typename Handler> void serialize(Handler &h, const int version)
  313. {
  314. h & static_cast<CGMonolith&>(*this);
  315. }
  316. };
  317. class DLL_LINKAGE CGWhirlpool : public CGMonolith
  318. {
  319. void onHeroVisit(const CGHeroInstance * h) const override;
  320. void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
  321. static bool isProtected( const CGHeroInstance * h );
  322. public:
  323. template <typename Handler> void serialize(Handler &h, const int version)
  324. {
  325. h & static_cast<CGMonolith&>(*this);
  326. }
  327. };
  328. class DLL_LINKAGE CGSirens : public CGObjectInstance
  329. {
  330. public:
  331. void onHeroVisit(const CGHeroInstance * h) const override;
  332. std::string getHoverText(const CGHeroInstance * hero) const override;
  333. void initObj(CRandomGenerator & rand) override;
  334. template <typename Handler> void serialize(Handler &h, const int version)
  335. {
  336. h & static_cast<CGObjectInstance&>(*this);
  337. }
  338. };
  339. class DLL_LINKAGE CGObservatory : public CGObjectInstance //Redwood observatory
  340. {
  341. public:
  342. void onHeroVisit(const CGHeroInstance * h) const override;
  343. template <typename Handler> void serialize(Handler &h, const int version)
  344. {
  345. h & static_cast<CGObjectInstance&>(*this);
  346. }
  347. };
  348. class DLL_LINKAGE CGBoat : public CGObjectInstance, public CBonusSystemNode
  349. {
  350. public:
  351. ui8 direction;
  352. const CGHeroInstance *hero; //hero on board
  353. bool onboardAssaultAllowed; //if true, hero can attack units from transport
  354. bool onboardVisitAllowed; //if true, hero can visit objects from transport
  355. EPathfindingLayer::EEPathfindingLayer layer;
  356. //animation filenames. If empty - animations won't be used
  357. std::string actualAnimation; //for OH3 boats those have actual animations
  358. std::string overlayAnimation; //waves animations
  359. std::array<std::string, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
  360. void initObj(CRandomGenerator & rand) override;
  361. static int3 translatePos(const int3 &pos, bool reverse = false);
  362. CGBoat()
  363. {
  364. hero = nullptr;
  365. direction = 4;
  366. layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
  367. }
  368. template <typename Handler> void serialize(Handler &h, const int version)
  369. {
  370. h & static_cast<CGObjectInstance&>(*this);
  371. h & static_cast<CBonusSystemNode&>(*this);
  372. h & direction;
  373. h & hero;
  374. h & layer;
  375. h & onboardAssaultAllowed;
  376. h & onboardVisitAllowed;
  377. h & actualAnimation;
  378. h & overlayAnimation;
  379. h & flagAnimations;
  380. }
  381. };
  382. class DLL_LINKAGE CGShipyard : public CGObjectInstance, public IShipyard
  383. {
  384. public:
  385. void getOutOffsets(std::vector<int3> &offsets) const override; //offsets to obj pos when we boat can be placed
  386. CGShipyard();
  387. void onHeroVisit(const CGHeroInstance * h) const override;
  388. template <typename Handler> void serialize(Handler &h, const int version)
  389. {
  390. h & static_cast<CGObjectInstance&>(*this);
  391. h & static_cast<IShipyard&>(*this);
  392. }
  393. protected:
  394. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  395. };
  396. class DLL_LINKAGE CGMagi : public CGObjectInstance
  397. {
  398. public:
  399. static std::map <si32, std::vector<ObjectInstanceID> > eyelist; //[subID][id], supports multiple sets as in H5
  400. static void reset();
  401. void initObj(CRandomGenerator & rand) override;
  402. void onHeroVisit(const CGHeroInstance * h) const override;
  403. template <typename Handler> void serialize(Handler &h, const int version)
  404. {
  405. h & static_cast<CGObjectInstance&>(*this);
  406. }
  407. };
  408. class DLL_LINKAGE CCartographer : public CTeamVisited
  409. {
  410. ///behaviour varies depending on surface and floor
  411. public:
  412. void onHeroVisit(const CGHeroInstance * h) const override;
  413. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  414. template <typename Handler> void serialize(Handler &h, const int version)
  415. {
  416. h & static_cast<CTeamVisited&>(*this);
  417. }
  418. };
  419. class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance
  420. {
  421. void onHeroVisit(const CGHeroInstance * h) const override;
  422. };
  423. class DLL_LINKAGE CGObelisk : public CTeamVisited
  424. {
  425. public:
  426. static constexpr int OBJPROP_INC = 20;
  427. static ui8 obeliskCount; //how many obelisks are on map
  428. static std::map<TeamID, ui8> visited; //map: team_id => how many obelisks has been visited
  429. void onHeroVisit(const CGHeroInstance * h) const override;
  430. void initObj(CRandomGenerator & rand) override;
  431. std::string getHoverText(PlayerColor player) const override;
  432. static void reset();
  433. template <typename Handler> void serialize(Handler &h, const int version)
  434. {
  435. h & static_cast<CTeamVisited&>(*this);
  436. }
  437. protected:
  438. void setPropertyDer(ui8 what, ui32 val) override;
  439. };
  440. class DLL_LINKAGE CGLighthouse : public CGObjectInstance
  441. {
  442. public:
  443. void onHeroVisit(const CGHeroInstance * h) const override;
  444. void initObj(CRandomGenerator & rand) override;
  445. template <typename Handler> void serialize(Handler &h, const int version)
  446. {
  447. h & static_cast<CGObjectInstance&>(*this);
  448. }
  449. void giveBonusTo(const PlayerColor & player, bool onInit = false) const;
  450. protected:
  451. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  452. };
  453. class DLL_LINKAGE CGTerrainPatch : public CGObjectInstance
  454. {
  455. public:
  456. CGTerrainPatch() = default;
  457. virtual bool isTile2Terrain() const override
  458. {
  459. return true;
  460. }
  461. };
  462. class DLL_LINKAGE HillFort : public CGObjectInstance, public ICreatureUpgrader
  463. {
  464. friend class HillFortInstanceConstructor;
  465. std::vector<int> upgradeCostPercentage;
  466. protected:
  467. void initObj(CRandomGenerator & rand) override;
  468. void onHeroVisit(const CGHeroInstance * h) const override;
  469. void fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const override;
  470. public:
  471. template <typename Handler> void serialize(Handler &h, const int version)
  472. {
  473. h & static_cast<CGObjectInstance&>(*this);
  474. h & upgradeCostPercentage;
  475. }
  476. };
  477. VCMI_LIB_NAMESPACE_END