File: BattleStacksController.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 (149 lines) | stat: -rw-r--r-- 5,263 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
/*
 * BattleStacksController.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 "../render/ColorFilter.h"

VCMI_LIB_NAMESPACE_BEGIN

class BattleHex;
class BattleHexArray;
class BattleAction;
class CStack;
class CSpell;
class SpellID;
class Point;

VCMI_LIB_NAMESPACE_END

struct StackAttackedInfo;
struct StackAttackInfo;

class ColorFilter;
class Canvas;
class BattleInterface;
class BattleAnimation;
class CreatureAnimation;
class BattleAnimation;
class BattleRenderer;
class IImage;

struct BattleStackFilterEffect
{
	ColorFilter effect;
	const CStack * target;
	const CSpell * source;
	bool persistent;
};

/// Class responsible for handling stacks in battle
/// Handles ordering of stacks animation
/// As well as rendering of stacks, their amount boxes
/// And any other effect applied to stacks
class BattleStacksController
{
	BattleInterface & owner;

	std::shared_ptr<IImage> amountNormal;
	std::shared_ptr<IImage> amountNegative;
	std::shared_ptr<IImage> amountPositive;
	std::shared_ptr<IImage> amountEffNeutral;

	/// currently displayed animations <anim, initialized>
	std::vector<BattleAnimation *> currentAnimations;

	/// currently active color effects on stacks, in order of their addition (which corresponds to their apply order)
	std::vector<BattleStackFilterEffect> stackFilterEffects;

	/// animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
	std::map<int32_t, std::shared_ptr<CreatureAnimation>> stackAnimation;

	/// <creatureID, if false reverse creature's animation> //TODO: move it to battle callback
	std::map<int, bool> stackFacingRight;

	/// Stacks have amount box hidden due to ongoing animations
	std::set<int> stackAmountBoxHidden;

	/// currently active stack; nullptr - no one
	const CStack *activeStack;

	/// stacks or their battle queue images below mouse pointer (multiple stacks possible while spellcasting), used for border animation
	std::vector<const CStack *> mouseHoveredStacks;

	///when animation is playing, we should wait till the end to make the next stack active; nullptr of none
	const CStack *stackToActivate;

	/// for giving IDs for animations
	ui32 animIDhelper;

	bool stackNeedsAmountBox(const CStack * stack) const;
	void showStackAmountBox(Canvas & canvas, const CStack * stack);
	BattleHex getStackCurrentPosition(const CStack * stack) const;

	std::shared_ptr<IImage> getStackAmountBox(const CStack * stack);

	void removeExpiredColorFilters();

	void initializeBattleAnimations();
	void tickFrameBattleAnimations(uint32_t msPassed);

	void updateBattleAnimations(uint32_t msPassed);

	std::vector<const CStack *> selectHoveredStacks();

	bool shouldAttackFacingRight(const CStack * attacker, const CStack * defender);

public:
	BattleStacksController(BattleInterface & owner);

	bool shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex) const;
	bool facingRight(const CStack * stack) const;

	void stackReset(const CStack * stack);
	void stackAdded(const CStack * stack, bool instant); //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); //stack with id number moved to destHex
	void stackTeleported(const CStack *stack, const BattleHexArray & destHex, int distance); //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 & info); //called when stack with id ID is attacking something on hex dest

	void startAction(const BattleAction & action);
	void endAction(const BattleAction & action);

	void deactivateStack(); //copy activeStack to stackToActivate, then set activeStack to nullptr to temporary disable current stack

	void activateStack(); //copy stackToActivate to activeStack to enable controls of the stack

	void setActiveStack(const CStack *stack);

	void showAliveStack(Canvas & canvas, const CStack * stack);
	void showStack(Canvas & canvas, const CStack * stack);

	void updateHoveredStacks();

	void collectRenderableObjects(BattleRenderer & renderer);

	/// Adds new color filter effect targeting stack
	/// Effect will last as long as stack is affected by specified spell (unless effect is persistent)
	/// If effect from same (target, source) already exists, it will be updated
	void setStackColorFilter(const ColorFilter & effect, const CStack * target, const CSpell *source, bool persistent);
	void addNewAnim(BattleAnimation *anim); //adds new anim to pendingAnims

	const CStack* getActiveStack() const;
	const std::vector<uint32_t> getHoveredStacksUnitIds() const;

	void tick(uint32_t msPassed);

	/// returns position of animation needed to place stack in specific hex
	Point getStackPositionAtHex(const BattleHex & hexNum, const CStack * creature) const;

	friend class BattleAnimation; // for exposing pendingAnims/creAnims/creDir to animations
};