2011-12-14 00:35:28 +03:00
/*
2022-12-11 23:16:23 +02:00
* BattleInterface . h , part of VCMI engine
2011-12-14 00:35:28 +03:00
*
* 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
*
*/
2017-07-13 10:26:03 +02:00
# pragma once
2022-12-09 13:10:35 +02:00
# include "BattleConstants.h"
2022-11-24 16:30:04 +02:00
# include "../gui/CIntObject.h"
2017-07-13 10:26:03 +02:00
# include "../../lib/spells/CSpellHandler.h" //CSpell::TAnimation
2022-12-10 00:25:11 +02:00
# include "../../lib/CondSh.h"
2011-12-14 00:35:28 +03:00
2022-07-26 15:07:42 +02:00
VCMI_LIB_NAMESPACE_BEGIN
2011-12-14 00:35:28 +03:00
class CCreatureSet ;
class CGHeroInstance ;
class CStack ;
struct BattleResult ;
struct BattleSpellCast ;
struct CObstacleInstance ;
2012-09-15 22:16:16 +03:00
struct SetStackEffect ;
2017-07-20 06:08:49 +02:00
class BattleAction ;
2011-12-14 00:35:28 +03:00
class CGTownInstance ;
struct CatapultAttack ;
struct BattleTriggerEffect ;
2022-07-26 15:07:42 +02:00
struct BattleHex ;
struct InfoAboutHero ;
VCMI_LIB_NAMESPACE_END
2022-12-09 13:26:17 +02:00
class BattleHero ;
2022-12-11 22:09:57 +02:00
class Canvas ;
2022-12-09 13:26:17 +02:00
class BattleResultWindow ;
class StackQueue ;
2011-12-17 21:59:59 +03:00
class CPlayerInterface ;
2017-09-05 16:21:44 +02:00
class CAnimation ;
2022-11-24 16:30:04 +02:00
struct BattleEffect ;
2017-07-20 06:08:49 +02:00
class IImage ;
2022-12-09 13:26:17 +02:00
class StackQueue ;
class BattleProjectileController ;
class BattleSiegeController ;
class BattleObstacleController ;
class BattleFieldController ;
class BattleRenderer ;
2022-12-21 17:06:47 +02:00
class BattleWindow ;
2022-12-09 13:26:17 +02:00
class BattleStacksController ;
class BattleActionsController ;
class BattleEffectsController ;
2022-12-21 17:02:53 +02:00
class BattleConsole ;
2022-11-17 13:21:03 +02:00
2011-12-22 16:05:19 +03:00
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
struct StackAttackedInfo
{
2022-12-09 13:10:35 +02:00
const CStack * defender ;
const CStack * attacker ;
int64_t damageDealt ;
uint32_t amountKilled ;
SpellID spellEffect ;
2013-08-09 20:37:41 +03:00
bool indirectAttack ; //if true, stack was attacked indirectly - spell or ranged attack
2011-12-22 16:05:19 +03:00
bool killed ; //if true, stack has been killed
bool rebirth ; //if true, play rebirth animation after all
2012-02-18 20:39:47 +03:00
bool cloneKilled ;
2022-12-17 17:35:15 +02:00
bool fireShield ;
2011-12-22 16:05:19 +03:00
} ;
2022-12-11 12:29:11 +02:00
struct StackAttackInfo
{
const CStack * attacker ;
const CStack * defender ;
std : : vector < const CStack * > secondaryDefender ;
SpellID spellEffect ;
BattleHex tile ;
bool indirectAttack ;
bool lucky ;
bool unlucky ;
bool deathBlow ;
bool lifeDrain ;
} ;
2022-12-21 17:02:53 +02:00
/// Main class for battles, responsible for relaying information from server to various battle entities
class BattleInterface
2011-12-14 00:35:28 +03:00
{
2022-12-10 00:25:11 +02:00
using AwaitingAnimationAction = std : : function < void ( ) > ;
struct AwaitingAnimationEvents {
AwaitingAnimationAction action ;
EAnimationEvents event ;
bool eventState ;
} ;
/// Conditional variables that are set depending on ongoing animations on the battlefield
std : : array < CondSh < bool > , static_cast < size_t > ( EAnimationEvents : : COUNT ) > animationEvents ;
/// List of events that are waiting to be triggered
std : : vector < AwaitingAnimationEvents > awaitingEvents ;
2022-12-25 17:44:40 +02:00
/// used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
std : : shared_ptr < CPlayerInterface > tacticianInterface ;
2013-06-22 17:47:20 +03:00
2022-12-25 17:44:40 +02:00
/// attacker interface, not null if attacker is human in our vcmiclient
std : : shared_ptr < CPlayerInterface > attackerInt ;
2017-07-20 06:08:49 +02:00
2022-12-25 17:44:40 +02:00
/// defender interface, not null if attacker is human in our vcmiclient
std : : shared_ptr < CPlayerInterface > defenderInt ;
2013-07-19 19:35:16 +03:00
2023-02-18 17:35:07 +02:00
void playIntroSoundAndUnlockInterface ( ) ;
2022-12-28 16:51:44 +02:00
void onIntroSoundPlayed ( ) ;
2022-12-25 17:44:40 +02:00
public :
/// copy of initial armies (for result window)
const CCreatureSet * army1 ;
const CCreatureSet * army2 ;
2013-07-19 19:35:16 +03:00
2022-12-25 17:44:40 +02:00
/// ID of channel on which battle opening sound is playing, or -1 if none
int battleIntroSoundChannel ;
2022-12-11 12:29:11 +02:00
2022-12-25 17:44:40 +02:00
std : : shared_ptr < BattleWindow > windowObject ;
std : : shared_ptr < BattleConsole > console ;
2022-12-11 12:29:11 +02:00
2022-12-25 17:44:40 +02:00
/// currently active player interface
std : : shared_ptr < CPlayerInterface > curInt ;
const CGHeroInstance * attackingHeroInstance ;
const CGHeroInstance * defendingHeroInstance ;
bool tacticsMode ;
2022-12-21 17:02:53 +02:00
2022-12-09 13:26:17 +02:00
std : : unique_ptr < BattleProjectileController > projectilesController ;
std : : unique_ptr < BattleSiegeController > siegeController ;
std : : unique_ptr < BattleObstacleController > obstacleController ;
std : : unique_ptr < BattleFieldController > fieldController ;
std : : unique_ptr < BattleStacksController > stacksController ;
std : : unique_ptr < BattleActionsController > actionsController ;
std : : unique_ptr < BattleEffectsController > effectsController ;
2022-11-17 13:21:03 +02:00
2022-12-21 17:02:53 +02:00
std : : shared_ptr < BattleHero > attackingHero ;
std : : shared_ptr < BattleHero > defendingHero ;
2017-06-14 03:53:26 +02:00
static CondSh < BattleAction * > givenCommand ; //data != nullptr if we have i.e. moved current unit
2023-01-21 16:15:20 +02:00
bool makingTurn ( ) const ;
2022-11-20 19:11:34 +02:00
int moveSoundHander ; // sound handler used when moving a unit
2022-12-21 17:02:53 +02:00
BattleInterface ( const CCreatureSet * army1 , const CCreatureSet * army2 , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , std : : shared_ptr < CPlayerInterface > att , std : : shared_ptr < CPlayerInterface > defen , std : : shared_ptr < CPlayerInterface > spectatorInt = nullptr ) ;
~ BattleInterface ( ) ;
2011-12-14 00:35:28 +03:00
2022-12-25 17:44:40 +02:00
void trySetActivePlayer ( PlayerColor player ) ; // if in hotseat, will activate interface of chosen player
void activateStack ( ) ; //sets activeStack to stackToActivate etc. //FIXME: No, it's not clear at all
void requestAutofightingAIToTakeAction ( ) ;
void giveCommand ( EActionType action , BattleHex tile = BattleHex ( ) , si32 additional = - 1 ) ;
void sendCommand ( BattleAction * & command , const CStack * actor = nullptr ) ;
const CGHeroInstance * getActiveHero ( ) ; //returns hero that can currently cast a spell
void showInterface ( SDL_Surface * to ) ;
void setHeroAnimation ( ui8 side , EHeroAnimType phase ) ;
void executeSpellCast ( ) ; //called when a hero casts a spell
void appendBattleLog ( const std : : string & newEntry ) ;
2023-01-30 23:15:37 +02:00
void redrawBattlefield ( ) ; //refresh GUI after changing stack range / grid settings
2016-10-28 23:37:20 +02:00
CPlayerInterface * getCurrentPlayerInterface ( ) const ;
2013-06-23 22:35:54 +03:00
2022-11-18 17:54:10 +02:00
void tacticNextStack ( const CStack * current ) ;
void tacticPhaseEnd ( ) ;
2022-12-10 00:25:11 +02:00
2023-02-15 23:38:41 +02:00
void setBattleQueueVisibility ( bool visible ) ;
2022-12-10 00:25:11 +02:00
/// sets condition to targeted state and executes any awaiting actions
void setAnimationCondition ( EAnimationEvents event , bool state ) ;
/// returns current state of condition
bool getAnimationCondition ( EAnimationEvents event ) ;
/// locks execution until selected condition reached targeted state
void waitForAnimationCondition ( EAnimationEvents event , bool state ) ;
/// adds action that will be executed one selected condition reached targeted state
void executeOnAnimationCondition ( EAnimationEvents event , bool state , const AwaitingAnimationAction & action ) ;
2022-11-18 17:54:10 +02:00
2011-12-14 00:35:28 +03:00
//call-ins
void startAction ( const BattleAction * action ) ;
2022-11-20 19:11:34 +02:00
void stackReset ( const CStack * stack ) ;
void stackAdded ( const CStack * stack ) ; //new stack appeared on battlefield
2017-07-20 06:08:49 +02:00
void stackRemoved ( uint32_t stackID ) ; //stack disappeared from batlefiled
2016-10-28 23:37:20 +02:00
void stackActivated ( const CStack * stack ) ; //active stack has been changed
2022-12-18 18:26:43 +02:00
void stackMoved ( const CStack * stack , std : : vector < BattleHex > destHex , int distance , bool teleport ) ; //stack with id number moved to destHex
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
void stacksAreAttacked ( std : : vector < StackAttackedInfo > attackedInfos ) ; //called when a certain amount of stacks has been attacked
2022-12-11 12:29:11 +02:00
void stackAttacking ( const StackAttackInfo & attackInfo ) ; //called when stack with id ID is attacking something on hex dest
2011-12-14 00:35:28 +03:00
void newRoundFirst ( int round ) ;
void newRound ( int number ) ; //caled when round is ended; number is the number of round
void stackIsCatapulting ( const CatapultAttack & ca ) ; //called when a stack is attacking walls
void battleFinished ( const BattleResult & br ) ; //called when battle is finished - battleresult window should be printed
2016-10-28 23:37:20 +02:00
void spellCast ( const BattleSpellCast * sc ) ; //called when a hero casts a spell
2011-12-14 00:35:28 +03:00
void battleStacksEffectsSet ( const SetStackEffect & sse ) ; //called when a specific effect is set to stacks
2015-01-30 08:39:36 +02:00
void castThisSpell ( SpellID spellID ) ; //called when player has chosen a spell from spellbook
2017-07-20 06:08:49 +02:00
void displayBattleLog ( const std : : vector < MetaString > & battleLog ) ;
2016-03-01 07:16:02 +02:00
2022-12-22 00:25:35 +02:00
void displaySpellAnimationQueue ( const CSpell * spell , const CSpell : : TAnimationQueue & q , BattleHex destinationTile , bool isHit ) ;
void displaySpellCast ( const CSpell * spell , BattleHex destinationTile ) ; //displays spell`s cast animation
void displaySpellEffect ( const CSpell * spell , BattleHex destinationTile ) ; //displays spell`s affected animation
void displaySpellHit ( const CSpell * spell , BattleHex destinationTile ) ; //displays spell`s affected animation
2016-03-01 07:16:02 +02:00
2011-12-14 00:35:28 +03:00
void endAction ( const BattleAction * action ) ;
2016-03-04 16:53:09 +02:00
2022-12-01 22:06:42 +02:00
void obstaclePlaced ( const std : : vector < std : : shared_ptr < const CObstacleInstance > > oi ) ;
2012-05-05 00:16:39 +03:00
2016-02-13 16:40:31 +02:00
void gateStateChanged ( const EGateState state ) ;
2016-02-10 06:10:32 +02:00
2016-10-28 23:37:20 +02:00
const CGHeroInstance * currentHero ( ) const ;
2012-08-26 12:07:48 +03:00
InfoAboutHero enemyHero ( ) const ;
2011-12-14 00:35:28 +03:00
} ;