1 ////////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software and
6 // you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ////////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    battle_indicators.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Header file for battle indicator displays.
14 ***
15 *** This code contains the implementation of various indicators and indicator
16 *** supporting classes. Indicators are small images and text that appear
17 *** alongside battle sprites to inform the player about status changes such as
18 *** damage, healing, and elemental or status effects.
19 *** ***************************************************************************/
20 
21 #ifndef __BATTLE_INDICATORS_HEADER__
22 #define __BATTLE_INDICATORS_HEADER__
23 
24 #include "defs.h"
25 #include "utils.h"
26 
27 #include "battle_utils.h"
28 
29 namespace hoa_battle {
30 
31 namespace private_battle {
32 
33 /** ****************************************************************************
34 *** \brief An abstract class for displaying information about a change in an actor's state
35 ***
36 *** Indicators are text or graphics that appear next to actor sprites in battle.
37 *** They typically represent changes to the actor such as numeric text representing
38 *** damage or healing, icons representing status effects, etc. The standard draw
39 *** sequence for elements comes in three stages to make the indicators presence and
40 *** disappearance more natural.
41 ***
42 *** -# An initial transparent fade in of element over a short period of time
43 *** -# Element draw at full opacity
44 *** -# Finishing with a brief transparent fade out of the element
45 ***
46 *** \note Indicators are drawn at different orientations for different actors. For
47 *** example, indicator elements and draw to the left of character actors and to
48 *** the right for enemy actors.
49 *** ***************************************************************************/
50 class IndicatorElement {
51 public:
52 	//! \param actor A valid pointer to the actor object this indicator
53 	IndicatorElement(BattleActor* actor);
54 
~IndicatorElement()55 	virtual ~IndicatorElement()
56 		{}
57 
58 	//! \brief Begins the display of the indicator element
59 	void Start();
60 
61 	//! \brief Updates the timer
62 	virtual void Update();
63 
64 	//! \brief Returns a floating point value that represents the height of the element drawn
65 	virtual float ElementHeight() const = 0;
66 
67 	//! \brief Draws the indicator information to the screen
68 	virtual void Draw() = 0;
69 
70 	/** \brief Calculates the standard alpha (transparency) value for drawing the element
71 	*** \return True if the alpha value is 1.0f and thus the indicator should be drawn with no alpha applied
72 	***
73 	*** Calling this function will set the alpha value of the _alpha_color member. Indicator elements
74 	*** generally fade in and fade out to make their appearance more seamless on the battle field.
75 	*** Alpha gradually increases from 0.0f to 1.0f in the first stage, remains at 1.0f for a majority
76 	*** of the time, then gradually decreases back to 0.0f as the display finishes.
77 	**/
78 	bool CalculateDrawAlpha();
79 
80 	//! \brief Returns true when the indicator element has expired and should be removed
IsExpired()81 	bool IsExpired() const
82 		{ return _timer.IsFinished(); }
83 
84 	//! \name Class member accessor methods
85 	//@{
GetActor()86 	const BattleActor* GetActor() const
87 		{ return _actor; }
88 
GetTimer()89 	const hoa_system::SystemTimer& GetTimer() const
90 		{ return _timer; }
91 	//@}
92 
93 protected:
94 	//! \brief The actor that the indicator element
95 	BattleActor* _actor;
96 
97 	//! \brief Used to monitor the display progress
98 	hoa_system::SystemTimer _timer;
99 
100 	//! \brief A modulation color used to modify the alpha (transparency) of the drawn element
101 	hoa_video::Color _alpha_color;
102 }; // class IndicatorElement
103 
104 
105 /** ****************************************************************************
106 *** \brief Displays an item of text next to an actor
107 ***
108 *** Text indicators are normally used to display numeric text representing the
109 *** amount of damage dealt to the actor or the amount of healing performed. Another
110 *** common use is to display the word "Miss" when the actor is a target for a skill
111 *** that did not connect successfully. The style of the rendered text can also be
112 *** varied and is typically used for drawing text in different colors such as red
113 *** for damage and green for healing. The text size may be made larger to indicate
114 *** more powerful or otherwise significant changes as well.
115 *** ***************************************************************************/
116 class IndicatorText : public IndicatorElement {
117 public:
118 	/** \param actor A valid pointer to the actor object
119 	*** \param text The text to use to render the text image
120 	*** \param style The style to use to render the text image
121 	**/
122 	IndicatorText(BattleActor* actor, std::string& text, hoa_video::TextStyle& style);
123 
~IndicatorText()124 	~IndicatorText()
125 		{}
126 
127 	//! \brief Returns the height of the rendered text image
ElementHeight()128 	float ElementHeight() const
129 		{ return _text_image.GetHeight(); }
130 
131 	//! \brief Draws the text image
132 	void Draw();
133 
134 protected:
135 	//! \brief The rendered image of the text to display
136 	hoa_video::TextImage _text_image;
137 }; // class IndicatorText  : public IndicatorElement
138 
139 
140 
141 /** ****************************************************************************
142 *** \brief Displays an image next to an actor
143 ***
144 *** This indicator displays a single image and is typically used for illustrating
145 *** elemental and status effects.
146 *** ***************************************************************************/
147 class IndicatorImage : public IndicatorElement {
148 public:
149 	/** \param actor A valid pointer to the actor object this indicator
150 	*** \param filename The name of the image file to load
151 	**/
152 	IndicatorImage(BattleActor* actor, const std::string& filename);
153 
154 	/** \param actor A valid pointer to the actor object this indicator
155 	*** \param image A const reference to the loaded image object to display
156 	**/
157 	IndicatorImage(BattleActor* actor, const hoa_video::StillImage& image);
158 
~IndicatorImage()159 	~IndicatorImage()
160 		{}
161 
162 	//! \brief Returns the height of the image
ElementHeight()163 	float ElementHeight() const
164 		{ return _image.GetHeight(); }
165 
166 	//! \brief Draws the image
167 	void Draw();
168 
169 	//! \brief Returns a reference to the image use
GetImage()170 	hoa_video::StillImage& GetImage()
171 		{ return _image; }
172 
173 protected:
174 	//! \brief The image to display as an indicator
175 	hoa_video::StillImage _image;
176 }; // class IndicatorImage : public IndicatorElement
177 
178 
179 
180 /** ****************************************************************************
181 *** \brief Displays two images blended together next to an actor
182 ***
183 *** This indicator is similar to the IndicatorImage class in that it displays
184 *** an image. The difference is that it uses two images that blend together to
185 *** indicate some sort of change, usually for a status or elemental effect. It
186 *** uses a modified draw sequence from standard indicator elements in five stages.
187 ***
188 *** -# Transparent fade in of the first image
189 *** -# First image drawn at full opacity
190 *** -# Fade out first image while simultaneously fading in second image
191 *** -# Second image drawn at full opacity
192 *** -# Transparent fade out of the second image
193 ***
194 *** \note Both images should share the same dimensions. If they do not this can
195 *** cause issues as the image height is used to
196 *** ***************************************************************************/
197 class IndicatorBlendedImage : public IndicatorElement {
198 public:
199 	/** \param actor A valid pointer to the actor object this indicator
200 	*** \param first_filename The name of the first image file to load
201 	*** \param second_filename The name of the second image file to load
202 	**/
203 	IndicatorBlendedImage(BattleActor* actor, const std::string& first_filename, const std::string& second_filename);
204 
205 	/** \param actor A valid pointer to the actor object this indicator
206 	*** \param first_image A const reference to the first loaded image to display
207 	*** \param second_image A const reference to the second loaded image to display
208 	**/
209 	IndicatorBlendedImage(BattleActor* actor, const hoa_video::StillImage& first_image, const hoa_video::StillImage& second_image);
210 
~IndicatorBlendedImage()211 	~IndicatorBlendedImage()
212 		{}
213 
214 	//! \brief Returns the height of the blended image
ElementHeight()215 	float ElementHeight() const
216 		{ return _first_image.GetHeight(); }
217 
218 	//! \brief Draws the first and/or second image blended appropriately
219 	void Draw();
220 
221 	//! \brief Returns a reference to the first image
GetFirstImage()222 	hoa_video::StillImage& GetFirstImage()
223 		{ return _first_image; }
224 
225 	//! \brief Returns a reference to the second image
GetSecondImage()226 	hoa_video::StillImage& GetSecondImage()
227 		{ return _second_image; }
228 
229 
230 protected:
231 	//! \brief The first image to display in the blended element
232 	hoa_video::StillImage _first_image;
233 
234 	//! \brief The second image to display in the blended element
235 	hoa_video::StillImage _second_image;
236 
237 	/** \brief A modulation color used to modify the alpha (transparency) of the second image
238 	*** \note This is only used when both the first and second images are beind drawn blended
239 	*** together. The first image will use the inherited _alpha_color member in this case.
240 	*** _alpha_color is also used for both the standard element fade in and fade out effects.
241 	**/
242 	hoa_video::Color _second_alpha_color;
243 }; // class IndicatorBlendedImage : public IndicatorElement
244 
245 
246 /** ****************************************************************************
247 *** \brief Manages all indicator elements for an actor
248 ***
249 *** Text indicators are normally used to display numeric text representing the
250 *** amount of damage dealt to the actor or the amount of healing performed. Another
251 *** common use is to display the word "Miss" when the actor is a target for a skill
252 *** that did not connect successfully. The style of the rendered text can also be
253 *** varied and is typically used for drawing text in different colors such as red
254 *** for damage and green for healing. The text size may be made larger to indicate
255 *** more powerful or otherwise significant changes as well.
256 *** ***************************************************************************/
257 class IndicatorSupervisor {
258 public:
259 	//! \param actor A valid pointer to the actor object that this class is responsible for
260 	IndicatorSupervisor(BattleActor* actor);
261 
262 	~IndicatorSupervisor();
263 
264 	//! \brief Processes the two FIFO queues
265 	void Update();
266 
267 	//! \brief Draws all elements present in the active queue
268 	void Draw();
269 
270 	/** \brief Creates indicator text representing a numeric amount of damage dealt
271 	*** \param amount The amount of damage to display, in hit points. Should be non-zero.
272 	***
273 	*** This function will not actually cause any damage to come to the actor (that is, the actor's
274 	*** hit points are not modified by this function). The degree of damage relative to the character's
275 	*** maximum hit points determines the color and size of the text rendered.
276 	**/
277 	void AddDamageIndicator(uint32 amount);
278 
279 	/** \brief Creates indicator text representing a numeric amount of healing dealt
280 	*** \param amount The amount of healing to display, in hit points. Should be non-zero.
281 	***
282 	*** This function will not actually cause any healing to come to the actor (that is, the actor's
283 	*** hit points are not modified by this function). The degree of healing relative to the character's
284 	*** maximum hit points determines the color and size of the text rendered.
285 	**/
286 	void AddHealingIndicator(uint32 amount);
287 
288 	/** \brief Creates indicator text showing a miss on the actor
289 	*** Miss text is always drawn with the same style in a small font with white text
290 	**/
291 	void AddMissIndicator();
292 
293 	/** \brief Creates an indicator that illustrates a change in an actor's status
294 	*** \param old_status The type of the old status effect
295 	*** \param old_intensity The intensity of the old status effect
296 	*** \param new_status The type of the new status effect
297 	*** \param new_intensity The intensity of the new status effect
298 	***
299 	*** The arguments are used to determine which status icon images to use for the indicator. Most of the time
300 	*** this function will choose two status icons (one old, and one new) for use in the indicator. Occasionally
301 	*** we wish to show an indicator even when the status type and intensity of the effect did not change. For
302 	*** example, when the timer for the status effect is reset. If the status and intensity arguments are equal,
303 	*** only a single icon image will be used in the indicator.
304 	**/
305 	void AddStatusIndicator(hoa_global::GLOBAL_STATUS old_status, hoa_global::GLOBAL_INTENSITY old_intensity,
306 		hoa_global::GLOBAL_STATUS new_status, hoa_global::GLOBAL_INTENSITY new_intensity);
307 
308 private:
309 	//! \brief A pointer to the actor that this class supervises indicator elements for
310 	BattleActor* _actor;
311 
312 	//! \brief A FIFO queue container of elements that are waiting to be started and added to the active elements container
313 	std::deque<IndicatorElement*> _wait_queue;
314 
315 	//! \brief A FIFO queue container of all elements that have begun and are going through their display sequence
316 	std::deque<IndicatorElement*> _active_queue;
317 }; // class IndicatorSupervisor
318 
319 } // namespace private_battle
320 
321 } // namespace hoa_battle
322 
323 #endif // __BATTLE_INDICATORS_HEADER__
324