File: BattleInterface.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (232 lines) | stat: -rw-r--r-- 8,270 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * BattleInterface.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 "BattleConstants.h"
#include "../lib/battle/BattleHex.h"
#include "../gui/CIntObject.h"
#include "../../lib/spells/CSpellHandler.h" //CSpell::TAnimation
#include "../ConditionalWait.h"

VCMI_LIB_NAMESPACE_BEGIN

class CCreatureSet;
class CGHeroInstance;
class CStack;
struct BattleResult;
struct BattleSpellCast;
struct CObstacleInstance;
struct SetStackEffect;
class BattleAction;
class CGTownInstance;
struct CatapultAttack;
struct BattleTriggerEffect;
struct InfoAboutHero;
class ObstacleChanges;
class CPlayerBattleCallback;

VCMI_LIB_NAMESPACE_END

class BattleHero;
class Canvas;
class BattleResultWindow;
class StackQueue;
class CPlayerInterface;
struct BattleEffect;
class IImage;
class StackQueue;

class BattleProjectileController;
class BattleSiegeController;
class BattleObstacleController;
class BattleFieldController;
class BattleRenderer;
class BattleWindow;
class BattleStacksController;
class BattleActionsController;
class BattleEffectsController;
class BattleConsole;

/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
struct StackAttackedInfo
{
	const CStack *defender;
	const CStack *attacker;

	int64_t  damageDealt;
	uint32_t amountKilled;
	SpellID spellEffect;

	bool indirectAttack; //if true, stack was attacked indirectly - spell or ranged attack
	bool killed; //if true, stack has been killed
	bool rebirth; //if true, play rebirth animation after all
	bool cloneKilled;
	bool fireShield;
};

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;
};

/// Main class for battles, responsible for relaying information from server to various battle entities
class BattleInterface
{
	using AwaitingAnimationAction = std::function<void()>;

	struct AwaitingAnimationEvents {
		AwaitingAnimationAction action;
		EAnimationEvents event;
	};

	/// Conditional variables that are set depending on ongoing animations on the battlefield
	ConditionalWait ongoingAnimationsState;

	/// List of events that are waiting to be triggered
	std::vector<AwaitingAnimationEvents> awaitingEvents;

	/// 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;

	/// attacker interface, not null if attacker is human in our vcmiclient
	std::shared_ptr<CPlayerInterface> attackerInt;

	/// defender interface, not null if attacker is human in our vcmiclient
	std::shared_ptr<CPlayerInterface> defenderInt;

	/// if set to true, battle is still starting and waiting for intro sound to end / key press from player
	bool battleOpeningDelayActive;

	/// ID of ongoing battle
	BattleID battleID;

	void playIntroSoundAndUnlockInterface();
	void onIntroSoundPlayed();
public:
	/// copy of initial armies (for result window)
	const CCreatureSet *army1;
	const CCreatureSet *army2;

	std::shared_ptr<BattleWindow> windowObject;
	std::shared_ptr<BattleConsole> console;

	/// currently active player interface
	std::shared_ptr<CPlayerInterface> curInt;

	const CGHeroInstance *attackingHeroInstance;
	const CGHeroInstance *defendingHeroInstance;

	bool tacticsMode;
	ui32 round;

	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;

	std::shared_ptr<BattleHero> attackingHero;
	std::shared_ptr<BattleHero> defendingHero;

	bool openingPlaying() const;
	void openingEnd();

	bool makingTurn() const;

	BattleID getBattleID() const;
	std::shared_ptr<CPlayerBattleCallback> getBattle() const;

	BattleInterface(const BattleID & battleID, 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();

	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, const BattleHex & tile = BattleHex(), SpellID spell = SpellID::NONE);
	void sendCommand(BattleAction command, const CStack * actor = nullptr);

	const CGHeroInstance *getActiveHero(); //returns hero that can currently cast a spell

	void showInterface(Canvas & to);

	void setHeroAnimation(BattleSide side, EHeroAnimType phase);

	void executeSpellCast(); //called when a hero casts a spell

	void appendBattleLog(const std::string & newEntry);

	void redrawBattlefield(); //refresh GUI after changing stack range / grid settings
	CPlayerInterface *getCurrentPlayerInterface() const;

	void tacticNextStack(const CStack *current);
	void tacticPhaseEnd();

	void setBattleQueueVisibility(bool visible);
	void setStickyHeroWindowsVisibility(bool visible);
	void setStickyQuickSpellWindowVisibility(bool visible);

	void endNetwork();
	void executeStagedAnimations();
	void executeAnimationStage( EAnimationEvents event);
	void onAnimationsStarted();
	void onAnimationsFinished();
	void waitForAnimations();
	bool hasAnimations();
	void checkForAnimations();
	void addToAnimationStage( EAnimationEvents event, const AwaitingAnimationAction & action);

	//call-ins
	void startAction(const BattleAction & action);
	void stackReset(const CStack * stack);
	void stackAdded(const CStack * stack); //new stack appeared on battlefield
	void stackRemoved(uint32_t stackID); //stack disappeared from batlefiled
	void stackActivated(const CStack *stack); //active stack has been changed
	void stackMoved(const CStack *stack, const BattleHexArray & destHex, int distance, bool teleport); //stack with id number moved to destHex
	void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
	void stackAttacking(const StackAttackInfo & attackInfo); //called when stack with id ID is attacking something on hex dest
	void newRoundFirst();
	void newRound(); //called when round is ended;
	void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
	void battleFinished(const BattleResult& br, QueryID queryID); //called when battle is finished - battleresult window should be printed
	void spellCast(const BattleSpellCast *sc); //called when a hero casts a spell
	void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
	void castThisSpell(SpellID spellID); //called when player has chosen a spell from spellbook

	void displayBattleLog(const std::vector<MetaString> & battleLog);

	void displaySpellAnimationQueue(const CSpell * spell, const CSpell::TAnimationQueue & q, const BattleHex & destinationTile, bool isHit);
	void displaySpellCast(const CSpell * spell, const BattleHex & destinationTile); //displays spell`s cast animation
	void displaySpellEffect(const CSpell * spell, const BattleHex & destinationTile); //displays spell`s affected animation
	void displaySpellHit(const CSpell * spell, const BattleHex & destinationTile); //displays spell`s affected animation

	void endAction(const BattleAction & action);

	void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> oi);
	void obstacleRemoved(const std::vector<ObstacleChanges> & obstacles);

	void gateStateChanged(const EGateState state);

	const CGHeroInstance *currentHero() const;
	InfoAboutHero enemyHero() const;
};