CBattleCallback.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #pragma once
  2. #include "BattleHex.h"
  3. /*
  4. * CBattleCallback.h, part of VCMI engine
  5. *
  6. * Authors: listed in file AUTHORS in main folder
  7. *
  8. * License: GNU General Public License v2.0 or later
  9. * Full text of license available in license.txt file, in main folder
  10. *
  11. */
  12. class CGameState;
  13. class CGTownInstance;
  14. class CGHeroInstance;
  15. class CStack;
  16. class CSpell;
  17. struct BattleInfo;
  18. struct CObstacleInstance;
  19. class IBonusBearer;
  20. struct InfoAboutHero;
  21. namespace boost
  22. {class shared_mutex;}
  23. namespace BattleSide
  24. {
  25. enum {ATTACKER = 0, DEFENDER = 1};
  26. }
  27. typedef std::vector<const CStack*> TStacks;
  28. class CBattleInfoEssentials;
  29. //Basic class for various callbacks (interfaces called by players to get info about game and so forth)
  30. class DLL_LINKAGE CCallbackBase
  31. {
  32. const BattleInfo *battle; //battle to which the player is engaged, NULL if none or not applicable
  33. const BattleInfo * getBattle() const
  34. {
  35. return battle;
  36. }
  37. protected:
  38. CGameState *gs;
  39. int player; // -1 gives access to all information, otherwise callback provides only information "visible" for player
  40. CCallbackBase(CGameState *GS, int Player)
  41. : battle(nullptr), gs(GS), player(Player)
  42. {}
  43. CCallbackBase()
  44. : battle(nullptr), gs(nullptr), player(-1)
  45. {}
  46. void setBattle(const BattleInfo *B);
  47. bool duringBattle() const;
  48. public:
  49. boost::shared_mutex &getGsMutex(); //just return a reference to mutex, does not lock nor anything
  50. int getPlayerID() const;
  51. friend class CBattleInfoEssentials;
  52. };
  53. struct DLL_LINKAGE AttackableTiles
  54. {
  55. std::set<BattleHex> hostileCreaturePositions;
  56. std::set<BattleHex> friendlyCreaturePositions; //for Dragon Breath
  57. template <typename Handler> void serialize(Handler &h, const int version)
  58. {
  59. h & hostileCreaturePositions & friendlyCreaturePositions;
  60. }
  61. };
  62. //Accessibility is property of hex in battle. It doesn't depend on stack, side's perspective and so on.
  63. namespace EAccessibility
  64. {
  65. enum EAccessibility
  66. {
  67. ACCESSIBLE,
  68. ALIVE_STACK,
  69. OBSTACLE,
  70. DESTRUCTIBLE_WALL,
  71. GATE, //sieges -> gate opens only for defender stacks
  72. UNAVAILABLE, //indestructible wall parts, special battlefields (like boat-to-boat)
  73. SIDE_COLUMN //used for first and last columns of hexes that are unavailable but wat machines can stand there
  74. };
  75. }
  76. typedef std::array<EAccessibility::EAccessibility, GameConstants::BFIELD_SIZE> TAccessibilityArray;
  77. struct DLL_LINKAGE AccessibilityInfo : TAccessibilityArray
  78. {
  79. bool occupiable(const CStack *stack, BattleHex tile) const;
  80. bool accessible(BattleHex tile, const CStack *stack) const; //checks for both tiles if stack is double wide
  81. bool accessible(BattleHex tile, bool doubleWide, bool attackerOwned) const; //checks for both tiles if stack is double wide
  82. };
  83. namespace BattlePerspective
  84. {
  85. enum BattlePerspective
  86. {
  87. INVALID = -2,
  88. ALL_KNOWING = -1,
  89. LEFT_SIDE,
  90. RIGHT_SIDE
  91. };
  92. }
  93. // Reachability info is result of BFS calculation. It's dependant on stack (it's owner, whether it's flying),
  94. // startPosition and perpective.
  95. struct DLL_LINKAGE ReachabilityInfo
  96. {
  97. typedef std::array<int, GameConstants::BFIELD_SIZE> TDistances;
  98. typedef std::array<BattleHex, GameConstants::BFIELD_SIZE> TPredecessors;
  99. enum { INFINITE_DIST = 1000000 };
  100. struct DLL_LINKAGE Parameters
  101. {
  102. const CStack *stack; //stack for which calculation is mage => not required (kept for debugging mostly), following variables are enough
  103. bool attackerOwned;
  104. bool doubleWide;
  105. bool flying;
  106. std::vector<BattleHex> knownAccessible; //hexes that will be treated as accessible, even if they're occupied by stack (by default - tiles occupied by stack we do reachability for, so it doesn't block itself)
  107. BattleHex startPosition; //assumed position of stack
  108. BattlePerspective::BattlePerspective perspective; //some obstacles (eg. quicksands) may be invisible for some side
  109. Parameters();
  110. Parameters(const CStack *Stack);
  111. };
  112. Parameters params;
  113. AccessibilityInfo accessibility;
  114. TDistances distances;
  115. TPredecessors predecessors;
  116. ReachabilityInfo()
  117. {
  118. distances.fill(INFINITE_DIST);
  119. predecessors.fill(BattleHex::INVALID);
  120. }
  121. bool isReachable(BattleHex hex) const
  122. {
  123. return distances[hex] < INFINITE_DIST;
  124. }
  125. };
  126. class DLL_LINKAGE CBattleInfoEssentials : public virtual CCallbackBase
  127. {
  128. protected:
  129. bool battleDoWeKnowAbout(ui8 side) const;
  130. public:
  131. enum EStackOwnership
  132. {
  133. ONLY_MINE, ONLY_ENEMY, MINE_AND_ENEMY
  134. };
  135. BattlePerspective::BattlePerspective battleGetMySide() const;
  136. ui8 battleTerrainType() const;
  137. int battleGetBattlefieldType() const; // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
  138. std::vector<shared_ptr<const CObstacleInstance> > battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective = boost::none) const; //returns all obstacles on the battlefield
  139. TStacks battleGetAllStacks() const; //returns all stacks, alive or dead or undead or mechanical :)
  140. bool battleHasNativeStack(ui8 side) const;
  141. ui8 battleGetWallState(int partOfWall) const; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
  142. int battleGetMoatDmg() const; //what dmg unit will suffer if ending turn in the moat
  143. const CGTownInstance * battleGetDefendedTown() const; //returns defended town if current battle is a siege, NULL instead
  144. const CStack *battleActiveStack() const;
  145. si8 battleTacticDist() const; //returns tactic distance in current tactics phase; 0 if not in tactics phase
  146. si8 battleGetTacticsSide() const; //returns which side is in tactics phase, undefined if none (?)
  147. bool battleCanFlee(int player) const;
  148. bool battleCanSurrender(int player) const;
  149. ui8 playerToSide(int player) const;
  150. ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
  151. bool battleHasHero(ui8 side) const;
  152. int battleCastSpells(ui8 side) const; //how many spells has given side casted
  153. const CGHeroInstance * battleGetFightingHero(ui8 side) const;
  154. //helpers
  155. TStacks battleAliveStacks() const;
  156. TStacks battleAliveStacks(ui8 side) const;
  157. const CStack * battleGetStackByID(int ID, bool onlyAlive = true) const; //returns stack info by given ID
  158. bool battleIsObstacleVisibleForSide(const CObstacleInstance & coi, BattlePerspective::BattlePerspective side) const;
  159. //ESpellCastProblem::ESpellCastProblem battleCanCastSpell(int player, ECastingMode::ECastingMode mode) const; //Checks if player is able to cast spells (at all) at the moment
  160. };
  161. struct DLL_LINKAGE BattleAttackInfo
  162. {
  163. const IBonusBearer *attackerBonuses, *defenderBonuses;
  164. const CStack *attacker, *defender;
  165. BattleHex attackerPosition, defenderPosition;
  166. int attackerCount;
  167. bool shooting;
  168. int chargedFields;
  169. bool luckyHit;
  170. bool deathBlow;
  171. bool ballistaDoubleDamage;
  172. BattleAttackInfo(const CStack *Attacker, const CStack *Defender, bool Shooting = false);
  173. BattleAttackInfo reverse() const;
  174. };
  175. class DLL_LINKAGE CBattleInfoCallback : public virtual CBattleInfoEssentials
  176. {
  177. public:
  178. enum ERandomSpell
  179. {
  180. RANDOM_GENIE, RANDOM_AIMED
  181. };
  182. //battle
  183. shared_ptr<const CObstacleInstance> battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking = true) const; //blocking obstacles makes tile inaccessible, others cause special effects (like Land Mines, Moat, Quicksands)
  184. const CStack * battleGetStackByPos(BattleHex pos, bool onlyAlive = true) const; //returns stack info by given pos
  185. void battleGetStackQueue(std::vector<const CStack *> &out, const int howMany, const int turn = 0, int lastMoved = -1) const;
  186. void battleGetStackCountOutsideHexes(bool *ac) const; // returns hexes which when in front of a stack cause us to move the amount box back
  187. std::vector<BattleHex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL) const; //returns hexes reachable by creature with id ID (valid movement destinations), DOES contain stack current position
  188. int battleGetSurrenderCost(int Player) const; //returns cost of surrendering battle, -1 if surrendering is not possible
  189. ReachabilityInfo::TDistances battleGetDistances(const CStack * stack, BattleHex hex = BattleHex::INVALID, BattleHex * predecessors = NULL) const; //returns vector of distances to [dest hex number]
  190. std::set<BattleHex> battleGetAttackedHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID) const;
  191. bool battleCanShoot(const CStack * stack, BattleHex dest) const; //determines if stack with given ID shoot at the selected destination
  192. bool battleIsStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack
  193. std::set<const CStack*> batteAdjacentCreatures (const CStack * stack) const;
  194. TDmgRange calculateDmgRange(const BattleAttackInfo &info) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
  195. TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, TQuantity attackerCount, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
  196. TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
  197. //hextowallpart //int battleGetWallUnderHex(BattleHex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
  198. std::pair<ui32, ui32> battleEstimateDamage(const BattleAttackInfo &bai, std::pair<ui32, ui32> * retaliationDmg = NULL) const; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg>
  199. std::pair<ui32, ui32> battleEstimateDamage(const CStack * attacker, const CStack * defender, std::pair<ui32, ui32> * retaliationDmg = NULL) const; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg>
  200. si8 battleHasDistancePenalty( const CStack * stack, BattleHex destHex ) const;
  201. si8 battleHasDistancePenalty(const IBonusBearer *bonusBearer, BattleHex shooterPosition, BattleHex destHex ) const;
  202. si8 battleHasWallPenalty(const CStack * stack, BattleHex destHex) const; //checks if given stack has wall penalty
  203. si8 battleHasWallPenalty(const IBonusBearer *bonusBearer, BattleHex shooterPosition, BattleHex destHex) const; //checks if given stack has wall penalty
  204. EWallParts::EWallParts battleHexToWallPart(BattleHex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
  205. //*** MAGIC
  206. si8 battleMaxSpellLevel() const; //calculates minimum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned
  207. ui32 battleGetSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
  208. ESpellCastProblem::ESpellCastProblem battleCanCastSpell(int player, ECastingMode::ECastingMode mode) const; //returns true if there are no general issues preventing from casting a spell
  209. ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(int player, const CSpell * spell, ECastingMode::ECastingMode mode) const; //checks if given player can cast given spell
  210. ESpellCastProblem::ESpellCastProblem battleCanCastThisSpellHere(int player, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const; //checks if given player can cast given spell at given tile in given mode
  211. ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination) const; //determines if creature can cast a spell here
  212. std::vector<BattleHex> battleGetPossibleTargets(int player, const CSpell *spell) const;
  213. ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const;
  214. ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
  215. std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
  216. si32 battleGetRandomStackSpell(const CStack * stack, ERandomSpell mode) const;
  217. TSpell getRandomBeneficialSpell(const CStack * subject) const;
  218. TSpell getRandomCastedSpell(const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
  219. //checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
  220. ESpellCastProblem::ESpellCastProblem battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const;
  221. const CStack * getStackIf(boost::function<bool(const CStack*)> pred) const;
  222. si8 battleHasShootingPenalty(const CStack * stack, BattleHex destHex)
  223. {
  224. return battleHasDistancePenalty(stack, destHex) || battleHasWallPenalty(stack, destHex);
  225. }
  226. si8 battleCanTeleportTo(const CStack * stack, BattleHex destHex, int telportLevel) const; //checks if teleportation of given stack to given position can take place
  227. //convenience methods using the ones above
  228. bool isInTacticRange( BattleHex dest ) const;
  229. si8 battleGetTacticDist() const; //returns tactic distance for calling player or 0 if this player is not in tactic phase (for ALL_KNOWING actual distance for tactic side)
  230. AttackableTiles getPotentiallyAttackableHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos) const; //TODO: apply rotation to two-hex attacker
  231. std::set<const CStack*> getAttackedCreatures(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID) const; //calculates range of multi-hex attacks
  232. bool isToReverse(BattleHex hexFrom, BattleHex hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir) const; //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo)
  233. bool isToReverseHlp(BattleHex hexFrom, BattleHex hexTo, bool curDir) const; //helper for isToReverse
  234. ReachabilityInfo getReachability(const CStack *stack) const;
  235. ReachabilityInfo getReachability(const ReachabilityInfo::Parameters &params) const;
  236. AccessibilityInfo getAccesibility() const;
  237. AccessibilityInfo getAccesibility(const CStack *stack) const; //Hexes ocupied by stack will be marked as accessible.
  238. AccessibilityInfo getAccesibility(const std::vector<BattleHex> &accessibleHexes) const; //given hexes will be marked as accessible
  239. std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const;
  240. protected:
  241. ReachabilityInfo getFlyingReachability(const ReachabilityInfo::Parameters params) const;
  242. ReachabilityInfo makeBFS(const AccessibilityInfo &accessibility, const ReachabilityInfo::Parameters params) const;
  243. ReachabilityInfo makeBFS(const CStack *stack) const; //uses default parameters -> stack position and owner's perspective
  244. std::set<BattleHex> getStoppers(BattlePerspective::BattlePerspective whichSidePerspective) const; //get hexes with stopping obstacles (quicksands)
  245. };
  246. class DLL_LINKAGE CPlayerBattleCallback : public CBattleInfoCallback
  247. {
  248. public:
  249. bool battleCanFlee() const; //returns true if caller can flee from the battle
  250. TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true) const; //returns stacks on battlefield
  251. ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell) const; //determines if given spell can be casted (and returns problem description)
  252. ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell, BattleHex destination) const; //if hero can cast spell here
  253. ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination) const; //determines if creature can cast a spell here
  254. int battleGetSurrenderCost() const; //returns cost of surrendering battle, -1 if surrendering is not possible
  255. bool battleCanCastSpell(ESpellCastProblem::ESpellCastProblem *outProblem = nullptr) const; //returns true, if caller can cast a spell. If not, if pointer is given via arg, the reason will be written.
  256. const CGHeroInstance * battleGetMyHero() const;
  257. InfoAboutHero battleGetEnemyHero() const;
  258. };