CBattleAnimations.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * CBattleAnimations.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 "../../lib/battle/BattleHex.h"
  12. #include "../../lib/CSoundBase.h"
  13. #include "../widgets/Images.h"
  14. VCMI_LIB_NAMESPACE_BEGIN
  15. class CStack;
  16. VCMI_LIB_NAMESPACE_END
  17. class CBattleInterface;
  18. class CCreatureAnimation;
  19. class CBattleAnimation;
  20. struct CatapultProjectileInfo;
  21. struct StackAttackedInfo;
  22. /// Base class of battle animations
  23. class CBattleAnimation
  24. {
  25. protected:
  26. CBattleInterface * owner;
  27. bool initialized;
  28. std::vector<CBattleAnimation *> & pendingAnimations();
  29. std::shared_ptr<CCreatureAnimation> stackAnimation(const CStack * stack);
  30. bool stackFacingRight(const CStack * stack);
  31. void setStackFacingRight(const CStack * stack, bool facingRight);
  32. virtual bool init() = 0; //to be called - if returned false, call again until returns true
  33. bool checkInitialConditions(); //determines if this animation is earliest of all
  34. public:
  35. ui32 ID; //unique identifier
  36. bool isInitialized();
  37. bool tryInitialize();
  38. virtual void nextFrame() {} //call every new frame
  39. virtual ~CBattleAnimation();
  40. CBattleAnimation(CBattleInterface * _owner);
  41. };
  42. /// Sub-class which is responsible for managing the battle stack animation.
  43. class CBattleStackAnimation : public CBattleAnimation
  44. {
  45. public:
  46. std::shared_ptr<CCreatureAnimation> myAnim; //animation for our stack, managed by CBattleInterface
  47. const CStack * stack; //id of stack whose animation it is
  48. CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack);
  49. void shiftColor(const ColorShifter * shifter);
  50. void rotateStack(BattleHex hex);
  51. };
  52. /// This class is responsible for managing the battle attack animation
  53. class CAttackAnimation : public CBattleStackAnimation
  54. {
  55. bool soundPlayed;
  56. protected:
  57. BattleHex dest; //attacked hex
  58. bool shooting;
  59. CCreatureAnim::EAnimType group; //if shooting is true, print this animation group
  60. const CStack *attackedStack;
  61. const CStack *attackingStack;
  62. int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
  63. const CCreature * getCreature();
  64. public:
  65. void nextFrame() override;
  66. bool checkInitialConditions();
  67. CAttackAnimation(CBattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender);
  68. ~CAttackAnimation();
  69. };
  70. /// Animation of a defending unit
  71. class CDefenceAnimation : public CBattleStackAnimation
  72. {
  73. CCreatureAnim::EAnimType getMyAnimType();
  74. std::string getMySound();
  75. void startAnimation();
  76. const CStack * attacker; //attacking stack
  77. bool rangedAttack; //if true, stack has been attacked by shooting
  78. bool killed; //if true, stack has been killed
  79. float timeToWait; // for how long this animation should be paused
  80. public:
  81. bool init() override;
  82. void nextFrame() override;
  83. CDefenceAnimation(StackAttackedInfo _attackedInfo, CBattleInterface * _owner);
  84. ~CDefenceAnimation();
  85. };
  86. class CDummyAnimation : public CBattleAnimation
  87. {
  88. private:
  89. int counter;
  90. int howMany;
  91. public:
  92. bool init() override;
  93. void nextFrame() override;
  94. CDummyAnimation(CBattleInterface * _owner, int howManyFrames);
  95. };
  96. /// Hand-to-hand attack
  97. class CMeleeAttackAnimation : public CAttackAnimation
  98. {
  99. public:
  100. bool init() override;
  101. CMeleeAttackAnimation(CBattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked);
  102. };
  103. /// Base class for all animations that play during stack movement
  104. class CStackMoveAnimation : public CBattleStackAnimation
  105. {
  106. public:
  107. BattleHex currentHex;
  108. protected:
  109. CStackMoveAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex _currentHex);
  110. };
  111. /// Move animation of a creature
  112. class CMovementAnimation : public CStackMoveAnimation
  113. {
  114. private:
  115. std::vector<BattleHex> destTiles; //full path, includes already passed hexes
  116. ui32 curentMoveIndex; // index of nextHex in destTiles
  117. BattleHex oldPos; //position of stack before move
  118. double begX, begY; // starting position
  119. double distanceX, distanceY; // full movement distance, may be negative if creture moves topleft
  120. double timeToMove; // full length of movement animation
  121. double progress; // range 0 -> 1, indicates move progrees. 0 = movement starts, 1 = move ends
  122. public:
  123. bool init() override;
  124. void nextFrame() override;
  125. CMovementAnimation(CBattleInterface *_owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance);
  126. ~CMovementAnimation();
  127. };
  128. /// Move end animation of a creature
  129. class CMovementEndAnimation : public CStackMoveAnimation
  130. {
  131. public:
  132. bool init() override;
  133. CMovementEndAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex destTile);
  134. ~CMovementEndAnimation();
  135. };
  136. /// Move start animation of a creature
  137. class CMovementStartAnimation : public CStackMoveAnimation
  138. {
  139. public:
  140. bool init() override;
  141. CMovementStartAnimation(CBattleInterface * _owner, const CStack * _stack);
  142. };
  143. /// Class responsible for animation of stack chaning direction (left <-> right)
  144. class CReverseAnimation : public CStackMoveAnimation
  145. {
  146. public:
  147. bool priority; //true - high, false - low
  148. bool init() override;
  149. void setupSecondPart();
  150. CReverseAnimation(CBattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority);
  151. ~CReverseAnimation();
  152. };
  153. class CRangedAttackAnimation : public CAttackAnimation
  154. {
  155. void setAnimationGroup();
  156. void initializeProjectile();
  157. void emitProjectile();
  158. void emitExplosion();
  159. protected:
  160. bool projectileEmitted;
  161. virtual CCreatureAnim::EAnimType getUpwardsGroup() const = 0;
  162. virtual CCreatureAnim::EAnimType getForwardGroup() const = 0;
  163. virtual CCreatureAnim::EAnimType getDownwardsGroup() const = 0;
  164. virtual void createProjectile(const Point & from, const Point & dest) const = 0;
  165. public:
  166. CRangedAttackAnimation(CBattleInterface * owner_, const CStack * attacker, BattleHex dest, const CStack * defender);
  167. ~CRangedAttackAnimation();
  168. bool init() override;
  169. void nextFrame() override;
  170. };
  171. /// Shooting attack
  172. class CShootingAnimation : public CRangedAttackAnimation
  173. {
  174. CCreatureAnim::EAnimType getUpwardsGroup() const override;
  175. CCreatureAnim::EAnimType getForwardGroup() const override;
  176. CCreatureAnim::EAnimType getDownwardsGroup() const override;
  177. void createProjectile(const Point & from, const Point & dest) const override;
  178. public:
  179. CShootingAnimation(CBattleInterface * _owner, const CStack * attacker, BattleHex dest, const CStack * defender);
  180. };
  181. /// Catapult attack
  182. class CCatapultAnimation : public CShootingAnimation
  183. {
  184. private:
  185. bool explosionEmitted;
  186. int catapultDamage;
  187. public:
  188. CCatapultAnimation(CBattleInterface * _owner, const CStack * attacker, BattleHex dest, const CStack * defender, int _catapultDmg = 0);
  189. void createProjectile(const Point & from, const Point & dest) const override;
  190. void nextFrame() override;
  191. };
  192. class CCastAnimation : public CRangedAttackAnimation
  193. {
  194. const CSpell * spell;
  195. CCreatureAnim::EAnimType findValidGroup( const std::vector<CCreatureAnim::EAnimType> candidates ) const;
  196. CCreatureAnim::EAnimType getUpwardsGroup() const override;
  197. CCreatureAnim::EAnimType getForwardGroup() const override;
  198. CCreatureAnim::EAnimType getDownwardsGroup() const override;
  199. void createProjectile(const Point & from, const Point & dest) const override;
  200. public:
  201. CCastAnimation(CBattleInterface * owner_, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell);
  202. };
  203. struct CPointEffectParameters
  204. {
  205. std::vector<Point> positions;
  206. std::vector<BattleHex> tiles;
  207. std::string animation;
  208. soundBase::soundID sound = soundBase::invalid;
  209. BattleHex boundHex = BattleHex::INVALID;
  210. bool aligntoBottom = false;
  211. bool waitForSound = false;
  212. bool screenFill = false;
  213. };
  214. /// Class that plays effect at one or more positions along with (single) sound effect
  215. class CPointEffectAnimation : public CBattleAnimation
  216. {
  217. soundBase::soundID sound;
  218. bool soundPlayed;
  219. bool soundFinished;
  220. bool effectFinished;
  221. int effectFlags;
  222. std::shared_ptr<CAnimation> animation;
  223. std::vector<Point> positions;
  224. std::vector<BattleHex> battlehexes;
  225. bool alignToBottom() const;
  226. bool waitForSound() const;
  227. bool forceOnTop() const;
  228. bool screenFill() const;
  229. void onEffectFinished();
  230. void onSoundFinished();
  231. void clearEffect();
  232. void playSound();
  233. void playEffect();
  234. public:
  235. enum EEffectFlags
  236. {
  237. ALIGN_TO_BOTTOM = 1,
  238. WAIT_FOR_SOUND = 2,
  239. FORCE_ON_TOP = 4,
  240. SCREEN_FILL = 8,
  241. };
  242. /// Create animation with screen-wide effect
  243. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, int effects = 0);
  244. /// Create animation positioned at point(s). Note that positions must be are absolute, including battleint position offset
  245. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos , int effects = 0);
  246. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos , int effects = 0);
  247. /// Create animation positioned at certain hex(es)
  248. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, BattleHex hex , int effects = 0);
  249. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects = 0);
  250. CPointEffectAnimation(CBattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex, int effects = 0);
  251. ~CPointEffectAnimation();
  252. bool init() override;
  253. void nextFrame() override;
  254. };
  255. /// Base class (e.g. for use in dynamic_cast's) for "animations" that wait for certain event
  256. class CWaitingAnimation : public CBattleAnimation
  257. {
  258. protected:
  259. CWaitingAnimation(CBattleInterface * owner_);
  260. public:
  261. void nextFrame() override;
  262. };
  263. /// Class that waits till projectile of certain shooter hits a target
  264. class CWaitingProjectileAnimation : public CWaitingAnimation
  265. {
  266. const CStack * shooter;
  267. public:
  268. CWaitingProjectileAnimation(CBattleInterface * owner_, const CStack * shooter);
  269. bool init() override;
  270. };