2023-10-19 16:19:09 +02:00
/*
* CBattleInfoCallback . h , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# pragma once
# include <vcmi/spells/Magic.h>
# include "ReachabilityInfo.h"
# include "BattleAttackInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGHeroInstance ;
class CStack ;
class ISpellCaster ;
class SpellCastEnvironment ;
class CSpell ;
struct CObstacleInstance ;
class IBonusBearer ;
class PossiblePlayerBattleAction ;
2024-06-01 17:28:17 +02:00
namespace vstd
{
class RNG ;
}
2023-10-19 16:19:09 +02:00
namespace spells
{
class Caster ;
class Spell ;
}
struct DLL_LINKAGE AttackableTiles
{
std : : set < BattleHex > hostileCreaturePositions ;
std : : set < BattleHex > friendlyCreaturePositions ; //for Dragon Breath
2024-01-20 20:34:51 +02:00
template < typename Handler > void serialize ( Handler & h )
2023-10-19 16:19:09 +02:00
{
h & hostileCreaturePositions ;
h & friendlyCreaturePositions ;
}
} ;
struct DLL_LINKAGE BattleClientInterfaceData
{
std : : vector < SpellID > creatureSpellsToCast ;
ui8 tacticsMode ;
} ;
class DLL_LINKAGE CBattleInfoCallback : public virtual CBattleInfoEssentials
{
public :
2024-08-11 22:22:35 +02:00
std : : optional < BattleSide > battleIsFinished ( ) const override ; //return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
2023-10-19 16:19:09 +02:00
std : : vector < std : : shared_ptr < const CObstacleInstance > > battleGetAllObstaclesOnPos ( BattleHex tile , bool onlyBlocking = true ) const override ;
std : : vector < std : : shared_ptr < const CObstacleInstance > > getAllAffectedObstaclesByStack ( const battle : : Unit * unit , const std : : set < BattleHex > & passed ) const override ;
//Handle obstacle damage here, requires SpellCastEnvironment
bool handleObstacleTriggersForUnit ( SpellCastEnvironment & spellEnv , const battle : : Unit & unit , const std : : set < BattleHex > & passed = { } ) const ;
const CStack * battleGetStackByPos ( BattleHex pos , bool onlyAlive = true ) const ;
const battle : : Unit * battleGetUnitByPos ( BattleHex pos , bool onlyAlive = true ) const override ;
///returns all alive units excluding turrets
battle : : Units battleAliveUnits ( ) const ;
///returns all alive units from particular side excluding turrets
2024-08-11 22:22:35 +02:00
battle : : Units battleAliveUnits ( BattleSide side ) const ;
2023-10-19 16:19:09 +02:00
2024-08-11 22:22:35 +02:00
void battleGetTurnOrder ( std : : vector < battle : : Units > & out , const size_t maxUnits , const int maxTurns , const int turn = 0 , BattleSide lastMoved = BattleSide : : NONE ) const ;
2023-10-19 16:19:09 +02:00
///returns reachable hexes (valid movement destinations), DOES contain stack current position
std : : vector < BattleHex > battleGetAvailableHexes ( const battle : : Unit * unit , bool obtainMovementRange , bool addOccupiable , std : : vector < BattleHex > * attackable ) const ;
///returns reachable hexes (valid movement destinations), DOES contain stack current position (lite version)
std : : vector < BattleHex > battleGetAvailableHexes ( const battle : : Unit * unit , bool obtainMovementRange ) const ;
std : : vector < BattleHex > battleGetAvailableHexes ( const ReachabilityInfo & cache , const battle : : Unit * unit , bool obtainMovementRange ) const ;
int battleGetSurrenderCost ( const PlayerColor & Player ) const ; //returns cost of surrendering battle, -1 if surrendering is not possible
ReachabilityInfo : : TDistances battleGetDistances ( const battle : : Unit * unit , BattleHex assumedPosition ) const ;
std : : set < BattleHex > battleGetAttackedHexes ( const battle : : Unit * attacker , BattleHex destinationTile , BattleHex attackerPos = BattleHex : : INVALID ) const ;
bool isEnemyUnitWithinSpecifiedRange ( BattleHex attackerPosition , const battle : : Unit * defenderUnit , unsigned int range ) const ;
2024-09-22 15:07:44 +02:00
bool isHexWithinSpecifiedRange ( BattleHex attackerPosition , BattleHex targetPosition , unsigned int range ) const ;
2023-10-19 16:19:09 +02:00
std : : pair < std : : vector < BattleHex > , int > getPath ( BattleHex start , BattleHex dest , const battle : : Unit * stack ) const ;
2024-09-22 15:07:44 +02:00
bool battleCanTargetEmptyHex ( const battle : : Unit * attacker ) const ; //determines of stack with given ID can target empty hex to attack - currently used only for SPELL_LIKE_ATTACK shooting
2023-10-19 16:19:09 +02:00
bool battleCanAttack ( const battle : : Unit * stack , const battle : : Unit * target , BattleHex dest ) const ; //determines if stack with given ID can attack target at the selected destination
bool battleCanShoot ( const battle : : Unit * attacker , BattleHex dest ) const ; //determines if stack with given ID shoot at the selected destination
bool battleCanShoot ( const battle : : Unit * attacker ) const ; //determines if stack with given ID shoot in principle
bool battleIsUnitBlocked ( const battle : : Unit * unit ) const ; //returns true if there is neighboring enemy stack
std : : set < const battle : : Unit * > battleAdjacentUnits ( const battle : : Unit * unit ) const ;
DamageEstimation calculateDmgRange ( const BattleAttackInfo & info ) const ;
/// estimates damage dealt by attacker to defender;
/// only non-random bonuses are considered in estimation
/// returns pair <min dmg, max dmg>
DamageEstimation battleEstimateDamage ( const BattleAttackInfo & bai , DamageEstimation * retaliationDmg = nullptr ) const ;
DamageEstimation battleEstimateDamage ( const battle : : Unit * attacker , const battle : : Unit * defender , BattleHex attackerPosition , DamageEstimation * retaliationDmg = nullptr ) const ;
2024-01-14 17:14:36 +02:00
DamageEstimation battleEstimateDamage ( const battle : : Unit * attacker , const battle : : Unit * defender , int getMovementRange , DamageEstimation * retaliationDmg = nullptr ) const ;
2023-10-19 16:19:09 +02:00
2024-07-20 20:27:02 +02:00
bool battleIsInsideWalls ( BattleHex from ) const ;
2023-10-19 16:19:09 +02:00
bool battleHasPenaltyOnLine ( BattleHex from , BattleHex dest , bool checkWall , bool checkMoat ) const ;
bool battleHasDistancePenalty ( const IBonusBearer * shooter , BattleHex shooterPosition , BattleHex destHex ) const ;
bool battleHasWallPenalty ( const IBonusBearer * shooter , BattleHex shooterPosition , BattleHex destHex ) const ;
bool battleHasShootingPenalty ( const battle : : Unit * shooter , BattleHex destHex ) const ;
BattleHex wallPartToBattleHex ( EWallPart part ) const ;
EWallPart battleHexToWallPart ( BattleHex hex ) const ; //returns part of destructible wall / gate / keep under given hex or -1 if not found
bool isWallPartPotentiallyAttackable ( EWallPart wallPart ) const ; // returns true if the wall part is potentially attackable (independent of wall state), false if not
bool isWallPartAttackable ( EWallPart wallPart ) const ; // returns true if the wall part is actually attackable, false if not
std : : vector < BattleHex > getAttackableBattleHexes ( ) const ;
2024-08-11 22:22:35 +02:00
si8 battleMinSpellLevel ( BattleSide side ) const ; //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned
si8 battleMaxSpellLevel ( BattleSide side ) 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
2023-10-19 16:19:09 +02:00
int32_t battleGetSpellCost ( const spells : : Spell * sp , const CGHeroInstance * caster ) const ; //returns cost of given spell
ESpellCastProblem battleCanCastSpell ( const spells : : Caster * caster , spells : : Mode mode ) const ; //returns true if there are no general issues preventing from casting a spell
2024-06-01 17:28:17 +02:00
SpellID getRandomBeneficialSpell ( vstd : : RNG & rand , const battle : : Unit * caster , const battle : : Unit * target ) const ;
SpellID getRandomCastedSpell ( vstd : : RNG & rand , const CStack * caster ) const ; //called at the beginning of turn for Faerie Dragon
2023-10-19 16:19:09 +02:00
std : : vector < PossiblePlayerBattleAction > getClientActionsForStack ( const CStack * stack , const BattleClientInterfaceData & data ) ;
PossiblePlayerBattleAction getCasterAction ( const CSpell * spell , const spells : : Caster * caster , spells : : Mode mode ) const ;
//convenience methods using the ones above
bool isInTacticRange ( BattleHex dest ) const ;
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)
2024-07-28 13:41:21 +02:00
AttackableTiles getPotentiallyAttackableHexes (
const battle : : Unit * attacker ,
const battle : : Unit * defender ,
BattleHex destinationTile ,
BattleHex attackerPos ,
BattleHex defenderPos ) const ; //TODO: apply rotation to two-hex attacker
AttackableTiles getPotentiallyAttackableHexes (
const battle : : Unit * attacker ,
BattleHex destinationTile ,
BattleHex attackerPos ) const ;
2023-10-19 16:19:09 +02:00
AttackableTiles getPotentiallyShootableHexes ( const battle : : Unit * attacker , BattleHex destinationTile , BattleHex attackerPos ) const ;
2024-07-28 13:41:21 +02:00
std : : vector < const battle : : Unit * > getAttackedBattleUnits (
const battle : : Unit * attacker ,
const battle : : Unit * defender ,
BattleHex destinationTile ,
bool rangedAttack ,
BattleHex attackerPos = BattleHex : : INVALID ,
BattleHex defenderPos = BattleHex : : INVALID ) const ; //calculates range of multi-hex attacks
2023-10-19 16:19:09 +02:00
std : : set < const CStack * > getAttackedCreatures ( const CStack * attacker , BattleHex destinationTile , bool rangedAttack , BattleHex attackerPos = BattleHex : : INVALID ) const ; //calculates range of multi-hex attacks
2024-07-22 19:34:28 +02:00
bool isToReverse ( const battle : : Unit * attacker , const battle : : Unit * defender , BattleHex attackerHex = BattleHex : : INVALID , BattleHex defenderHex = BattleHex : : INVALID ) const ; //determines if attacker standing at attackerHex should reverse in order to attack defender
2023-10-19 16:19:09 +02:00
ReachabilityInfo getReachability ( const battle : : Unit * unit ) const ;
ReachabilityInfo getReachability ( const ReachabilityInfo : : Parameters & params ) const ;
2024-06-24 03:23:26 +02:00
AccessibilityInfo getAccessibility ( ) const ;
AccessibilityInfo getAccessibility ( const battle : : Unit * stack ) const ; //Hexes occupied by stack will be marked as accessible.
AccessibilityInfo getAccessibility ( const std : : vector < BattleHex > & accessibleHexes ) const ; //given hexes will be marked as accessible
2023-10-19 16:19:09 +02:00
std : : pair < const battle : : Unit * , BattleHex > getNearestStack ( const battle : : Unit * closest ) const ;
2024-08-11 22:22:35 +02:00
BattleHex getAvailableHex ( const CreatureID & creID , BattleSide side , int initialPos = - 1 ) const ; //find place for adding new stack
2023-10-19 16:19:09 +02:00
protected :
ReachabilityInfo getFlyingReachability ( const ReachabilityInfo : : Parameters & params ) const ;
ReachabilityInfo makeBFS ( const AccessibilityInfo & accessibility , const ReachabilityInfo : : Parameters & params ) const ;
bool isInObstacle ( BattleHex hex , const std : : set < BattleHex > & obstacles , const ReachabilityInfo : : Parameters & params ) const ;
2024-08-11 22:22:35 +02:00
std : : set < BattleHex > getStoppers ( BattleSide whichSidePerspective ) const ; //get hexes with stopping obstacles (quicksands)
2023-10-19 16:19:09 +02:00
} ;
VCMI_LIB_NAMESPACE_END