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
6 // and 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_utils.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Header file for battle mode utility code
14 ***
15 *** This file contains utility code that is shared among the various battle mode
16 *** classes.
17 *** ***************************************************************************/
18 
19 #ifndef __BATTLE_UTILS_HEADER__
20 #define __BATTLE_UTILS_HEADER__
21 
22 #include "defs.h"
23 #include "utils.h"
24 
25 #include "system.h"
26 
27 #include "global_objects.h"
28 #include "global_utils.h"
29 
30 namespace hoa_battle {
31 
32 namespace private_battle {
33 
34 //! \name Screen dimension constants
35 //@{
36 //! \brief Battle scenes are visualized via an invisible grid of 64x64 tiles
37 const uint32 TILE_SIZE     = 64;
38 //! \brief The length of the screen in number of tiles (16 x 64 = 1024)
39 const uint32 SCREEN_LENGTH = 16;
40 //! \brief The height of the screen in number of tiles (12 x 64 = 768)
41 const uint32 SCREEN_HEIGHT = 12;
42 //@}
43 
44 
45 /** \name Action Type Constants
46 *** \brief Identifications for the types of actions a player's characters may perform
47 **/
48 //@{
49 const uint32 CATEGORY_ATTACK    = 0;
50 const uint32 CATEGORY_DEFEND    = 1;
51 const uint32 CATEGORY_SUPPORT   = 2;
52 const uint32 CATEGORY_ITEM      = 3;
53 //@}
54 
55 
56 //! \brief Position constants representing the significant locations along the stamina meter
57 //@{
58 //! \brief The bottom most position of the stamina bar
59 const float STAMINA_LOCATION_BOTTOM = 128.0f;
60 
61 //! \brief The location where each actor is allowed to select a command
62 const float STAMINA_LOCATION_COMMAND = STAMINA_LOCATION_BOTTOM + 354.0f;
63 
64 //! \brief The top most position of the stamina bar where actors are ready to execute their actions
65 const float STAMINA_LOCATION_TOP = STAMINA_LOCATION_BOTTOM + 508.0f;
66 //@}
67 
68 
69 //! \brief Returned as an index when looking for a character or enemy and they do not exist
70 const uint32 INVALID_BATTLE_ACTOR_INDEX = 999;
71 
72 //! \brief When a battle first starts, this is the wait time for the slowest actor
73 const uint32 MAX_INIT_WAIT_TIME = 8000;
74 
75 //! \brief Warm up time for using items (try to keep short, should be constant regardless of item used)
76 const uint32 ITEM_WARM_UP_TIME = 1000;
77 
78 
79 //! \brief Used to indicate what state the overall battle is currently operating in
80 enum BATTLE_STATE {
81 	BATTLE_STATE_INVALID   = -1,
82 	BATTLE_STATE_INITIAL   =  0, //!< Character sprites are running in from off-screen to their battle positions
83 	BATTLE_STATE_NORMAL    =  1, //!< Normal state where player is watching actions play out and waiting for a turn
84 	BATTLE_STATE_COMMAND   =  2, //!< Player is choosing a command for a character
85 	BATTLE_STATE_EVENT     =  3, //!< A scripted event is taking place, suspending all standard action
86 	BATTLE_STATE_VICTORY   =  4, //!< Battle has ended with the characters victorious
87 	BATTLE_STATE_DEFEAT    =  5, //!< Battle has ended with the characters defeated
88 	BATTLE_STATE_TOTAL     =  6
89 };
90 
91 
92 //! \brief Represents the possible states that a BattleActor may be in
93 enum ACTOR_STATE {
94 	ACTOR_STATE_INVALID       = -1,
95 	ACTOR_STATE_IDLE          =  0, //!< Actor is recovering stamina so they can execute another action
96 	ACTOR_STATE_COMMAND       =  1, //!< Actor is finished with the idle state but has not yet selected an action to execute
97 	ACTOR_STATE_WARM_UP       =  2, //!< Actor has selected an action and is preparing to execute it
98 	ACTOR_STATE_READY         =  3, //!< Actor is prepared to execute action and is waiting their turn to act
99 	ACTOR_STATE_ACTING        =  4, //!< Actor is in the process of executing their selected action
100 	ACTOR_STATE_COOL_DOWN     =  5, //!< Actor is finished with previous action execution and recovering
101 	ACTOR_STATE_DEAD          =  6, //!< Actor has perished and is inactive in battle
102 	ACTOR_STATE_PARALYZED     =  7, //!< Actor is in some state of paralysis and can not act nor recover stamina
103 	ACTOR_STATE_TOTAL         =  8
104 };
105 
106 
107 
108 //! \brief Enums for the various states that the CommandSupervisor class may be in
109 enum COMMAND_STATE {
110 	COMMAND_STATE_INVALID = -1,
111 	//! Player is selecting the type of action to execute
112 	COMMAND_STATE_CATEGORY = 0,
113 	//! Player is selecting from a list of actions to execute
114 	COMMAND_STATE_ACTION = 1,
115 	//! Player is selecting the target to execute the action on
116 	COMMAND_STATE_TARGET = 2,
117 	//! Player is viewing information about the selected action
118 	COMMAND_STATE_INFORMATION = 3,
119 	COMMAND_STATE_TOTAL = 4
120 };
121 
122 
123 //! \brief Enums for the various states that the FinishWindow class may be in
124 enum FINISH_STATE {
125 	FINISH_INVALID = -1,
126 	//! Announces that the player is victorious and notes any characters who have gained an experience level
127 	FINISH_WIN_ANNOUNCE = 0,
128 	//! Initial display of character stats
129 	FINISH_WIN_SHOW_GROWTH = 1,
130 	//! Performs countdown of XP (adding it to chars) and triggers level ups
131 	FINISH_WIN_COUNTDOWN_GROWTH = 2,
132 	//! All XP has been added (or should be added instantly), shows final stats
133 	FINISH_WIN_RESOLVE_GROWTH = 3,
134 	//! Display of any skills learned
135 	FINISH_WIN_SHOW_SKILLS = 4,
136 	//! Reports all drunes earned and dropped items obtained
137 	FINISH_WIN_SHOW_SPOILS = 5,
138 	//! Adds $ earned to party's pot
139 	FINISH_WIN_COUNTDOWN_SPOILS = 6,
140 	//! All money and items have been added
141 	FINISH_WIN_RESOLVE_SPOILS = 7,
142 	//! We've gone through all the states of the FinishWindow in Win form
143 	FINISH_WIN_COMPLETE = 8,
144 	//! Announces that the player has lost and queries the player for an action
145 	FINISH_LOSE_ANNOUNCE = 9,
146 	//! Used to double-confirm when the player selects to quit the game or return to the main menu
147 	FINISH_LOSE_CONFIRM = 10,
148 	FINISH_TOTAL = 11
149 };
150 
151 
152 
153 
154 /** \name Command battle calculation functions
155 *** These functions perform many of the common calculations that are needed in battle such as determining
156 *** evasion and the amount of damage dealt. Lua functions that implement the effect of skills and items
157 *** make the most use of these functions. Thus, these functions are specifically designed for that use
158 *** and do not utilize C++ features that Lua can not take advantage of, such as references or default
159 *** values for function arguments.
160 ***
161 *** There are also many functions that share the same name but have a different function signature. These
162 *** functions perform the same task but some take extra arguments to make the calculation more flexible. For
163 *** example, many functions have a version that allows adjustment of the variation by accepting a standard deviation
164 *** argument.
165 ***
166 *** \note These calculations only work for valid non-party type targets. If it is desired to use these methods
167 *** on a party target, a set of targets for each actor in the target party must be extracted and those actor
168 *** targets used individually for these various methods.
169 **/
170 //@{
171 /** \brief Determines if a target has evaded an attack or other action
172 *** \param target A pointer to the target to calculate evasion for
173 *** \return True if the target evasion was successful
174 **/
175 bool CalculateStandardEvasion(BattleTarget* target);
176 
177 /** \brief Determines if a target has evaded an attack or other action
178 *** \param target A pointer to the target to calculate evasion for
179 *** \param add_evasion A modifier value to be added to the standard evasion rating
180 *** \return True if the target evasion was successful
181 ***
182 *** The additional_evasion may be positive or negative. If the total evasion value falls below 0.0f
183 *** the function will return false and if that value exceeds 100.0f it will return true. Otherwise the total
184 *** evade value will serve as a standard probability distribution to determine whether the evasion was
185 *** successful or not.
186 **/
187 bool CalculateStandardEvasion(BattleTarget* target, float add_evasion);
188 
189 /** \brief Determines if a target has evaded an attack or other action
190 *** \param target A pointer to the target to calculate evasion for
191 *** \param mul_evasion A modifier value to be multiplied to the standard evasion rating
192 *** \return True if the target evasion was successful
193 ***
194 *** This function operates the same as the CalculateStandardEvasion(...) functions with the exception that
195 *** its float argument is used as a multiple in the evasion calculation instead of an addition. So for instance
196 *** if the user wants the evasion chance to increase by 20%, 1.2f would be passed in for the multiple_evasion
197 *** argument. Negative values are also accepted, and -1.2f would decrease the evasion chance by 20%.
198 **/
199 bool CalculateStandardEvasionMultiplier(BattleTarget* target, float mul_evasion);
200 
201 /** \brief Determines the amount of damage caused with a standard attack
202 *** \param attacker A pointer to the attacker who is causing the damage
203 *** \param target A pointer to the target that will be receiving the damage
204 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
205 ***
206 *** This function uses both the physical and metaphysical attack/defense ratings to calculate the total
207 *** damage caused. This function uses a gaussian random distribution with a standard deviation of ten percent
208 *** to perform variation in the damage caused. Therefore this function may return different values each time
209 *** it is called with the same arguments. If the amount of damage calculates out to zero, a small random
210 *** non-zero value will be returned instead.
211 **/
212 uint32 CalculateStandardDamage(BattleActor* attacker, BattleTarget* target);
213 
214 /** \brief Determines the amount of damage caused with a standard attack
215 *** \param attacker A pointer to the attacker who is causing the damage
216 *** \param target A pointer to the target that will be receiving the damage
217 *** \param add_phys An additional amount to add to the physical damage dealt
218 *** \param add_meta An additional amount to add to the metaphyiscal damage dealt
219 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
220 ***
221 *** The physical and metaphysical add modifiers may be positive or negative. Large negative values can often
222 *** skew the calculations and cause the calculated damage dealt to drop to zero so be cautious about the
223 *** add modifier values given to this function
224 **/
225 uint32 CalculateStandardDamage(BattleActor* attacker, BattleTarget* target, int32 add_phys, int32 add_meta);
226 
227 /** \brief Determines the amount of damage caused with a standard attack
228 *** \param attacker A pointer to the attacker who is causing the damage
229 *** \param target A pointer to the target that will be receiving the damage
230 *** \param std_dev The standard deviation to use in the gaussian distribution, where "7.5f" would represent 7.5% standard deviation
231 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
232 ***
233 *** The std_dev value is always relative to the amount of absolute damage calculated prior to the gaussian randomization.
234 *** This means you can not use this function to declare an absolute standard deviation, where "20.0f" would correspond to
235 *** a stadnard deviation of 20HP from the absolute damage.
236 **/
237 uint32 CalculateStandardDamage(BattleActor* attacker, BattleTarget* target, float std_dev);
238 
239 /** \brief Determines the amount of damage caused with a standard attack
240 *** \param attacker A pointer to the attacker who is causing the damage
241 *** \param target A pointer to the target that will be receiving the damage
242 *** \param add_phys An additional amount to add to the physical damage dealt
243 *** \param add_meta An additional amount to add to the metaphyiscal damage dealt
244 *** \param std_dev The standard deviation to use in the gaussian distribution, where "7.5f" would represent 7.5% standard deviation
245 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
246 **/
247 uint32 CalculateStandardDamage(BattleActor* attacker, BattleTarget* target, int32 add_phys, int32 add_meta, float std_dev);
248 
249 /** \brief Determines the amount of damage caused with a standard attack
250 *** \param attacker A pointer to the attacker who is causing the damage
251 *** \param target A pointer to the target that will be receiving the damage
252 *** \param mul_phys An additional amount to be multiplied to the physical damage dealt
253 *** \param mul_meta An additional amount to be multiplied to the metaphyiscal damage dealt
254 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
255 ***
256 *** This function operates the same as the CalculateStandardDamage(...) functions with the exception that
257 *** its float arguments are used as multiplers in the damage calculation instead of an addition multipler.
258 *** So for instance if the user wants the physical damage to increase by 20% and the metaphysical damage to
259 *** decrease by 15%, the values of mul_phys and mul_meta would be 1.2f and -1.15f respectively. A zero value
260 *** for the multiplier will have no effect on the damage calculation.
261 **/
262 uint32 CalculateStandardDamageMultiplier(BattleActor* attacker, BattleTarget* target, float mul_phys, float mul_meta);
263 
264 /** \brief Determines the amount of damage caused with a standard attack
265 *** \param attacker A pointer to the attacker who is causing the damage
266 *** \param target A pointer to the target that will be receiving the damage
267 *** \param mul_phys An additional amount to be multiplied to the physical damage dealt
268 *** \param mul_meta An additional amount to be multiplied to the metaphyiscal damage dealt
269 *** \param std_dev The standard deviation to use in the gaussian distribution, where "7.5f" would represent 7.5% standard deviation
270 *** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
271 ***
272 *** This function signature allows the additional option of setting the standard deviation in the gaussian random value calculation.
273 **/
274 uint32 CalculateStandardDamageMultiplier(BattleActor* attacker, BattleTarget* target, float mul_phys, float mul_meta, float std_dev);
275 //@}
276 
277 
278 /** ****************************************************************************
279 *** \brief Builds upon the SystemTimer to provide more flexibility and features
280 ***
281 *** Battle mode timers are a bit more advanced over the standard system engine
282 *** timer to meet the needs of some timers in battle mode. The additional features
283 *** available to battle timers over system timers include the following.
284 ***
285 *** - The ability to set the expiration time of the current loop to any value
286 *** - Apply a floating-point multiplier to speed up or slow down the timer
287 ***
288 *** \note Not all timers in battle mode will require the features of this class.
289 *** Evaluate the needs of a timer in the battle code and determine whether or not
290 *** it should use this class or if the standard SystemTimer will meet its needs.
291 *** ***************************************************************************/
292 class BattleTimer : hoa_system::SystemTimer {
293 	friend class SystemEngine; // For allowing SystemEngine to call the _AutoUpdate() method
294 
295 public:
296 	BattleTimer();
297 
298 	/** \brief Creates and places the timer in the SYSTEM_TIMER_INITIAL state
299 	*** \param duration The duration (in milliseconds) that the timer should count for
300 	*** \param loops The number of times that the timer should loop for. Default value is set to no looping.
301 	**/
302 	BattleTimer(uint32 duration, int32 loops = 0);
303 
~BattleTimer()304 	~BattleTimer()
305 		{}
306 
307 	//! \brief Overrides the SystemTimer::Update() method
308 	void Update();
309 
310 	/** \brief Overrides the SystemTimer::Update(uint32) method
311 	*** \param time The amount of time to increment the timer by
312 	**/
313 	void Update(uint32 time);
314 
315 	/** \brief Sets the time expired member and updates the timer object appropriately
316 	*** \param time The value to set for the expiration time
317 	***
318 	*** This method will do nothing if the state of the object is SYSTEM_TIMER_INVALID or SYSTEM_TIMER_FINISHED.
319 	*** The new expiration time applies only to the current loop. So for example, if the timer is on loop #2
320 	*** of 5 and the loop duration is 1000ms, setting the time to 1500ms will result in the timer
321 	*** state changing to loop #3 and set the expiration time back to zero. Reaching the last loop
322 	*** will set the timer to the FINISHED state. Using a zero value for the time while on the first loop will
323 	*** change the timer to the INITIAL state.
324 	***
325 	*** If you're only looking to increment the expiration time and wish for that increment to take
326 	*** effect for more than just the current loop, use the Update(uint32) method. Although be aware that
327 	*** Update() will take into account any timer multipliers that are active while this method ignores
328 	*** the timer multiplier.
329 	**/
330 	void SetTimeExpired(uint32 time);
331 
332 	/** \brief Activates or deactivates the timer multiplier
333 	*** \param activate True will activate and set the multiplier while false will deactivate.
334 	*** \param multiplier The multiplier value to apply towards the timer, which should be positive.
335 	***
336 	*** If the activate argument is false, the multiplier value will be ignored. The multiplier
337 	*** value is multiplied directly to the raw update time to obtain the actual update time.
338 	*** So for example if the raw update time is 25 and the multiplier value is 0.8f, the actual
339 	*** update time for the class will be 20.
340 	**/
341 	void ActivateTimeMultiplier(bool activate, float multiplier);
342 
343 	//! \name Class member accessor methods
344 	//@{
IsTimeMultiplierActive()345 	bool IsTimeMultiplierActive() const
346 		{ return _time_multiplier_active; }
347 
GetTimeMultiplier()348 	float GetTimeMultiplier() const
349 		{ return _time_multiplier; }
350 	//@}
351 
352 protected:
353 	//! \brief When true the timer multiplier is applied to all timer updates
354 	bool _time_multiplier_active;
355 
356 	//! \brief A zero or positive value that is multiplied to the update time
357 	float _time_multiplier;
358 
359 	//! \brief Overrides the SystemTimer::_AutoUpdate() method
360 	virtual void _AutoUpdate();
361 
362 private:
363 	/** \brief Computes and returns the update time after the multiplier has been applied
364 	*** \param time The raw update time to use in the calculation
365 	*** \return The modified update time
366 	***
367 	*** This method does not do any error checking such as whether the multiplier is a valid number
368 	*** (non-negative) or whether or not the multiplier is active. The code that calls this function
369 	*** is responsible for that condition checking.
370 	**/
371 	uint32 _ApplyMultiplier(uint32 time);
372 }; // class BattleTimer : hoa_system::SystemTimer
373 
374 
375 /** ****************************************************************************
376 *** \brief Container class for representing the target of a battle action
377 ***
378 *** Valid target types include attack points, actors, and parties. This class is
379 *** somewhat of a wrapper and allows a single instance of BattleTarget to represent
380 *** any of these types. It also contains a handful of methods useful in determining
381 *** the validity of a selected target and selecting another target of the same type.
382 ***
383 *** Many of these functions are dependent on receiving a pointer to a BattleActor
384 *** object that is using or intends to use the BattleTarget object. This is necessary
385 *** because the different types of the GLOBAL_TARGET enum are relative and the class
386 *** selects different targets relative to the user. For example, selecting the next
387 *** actor when the target type is GLOBAL_TARGET_ALLY requires knowing whether the user
388 *** is a character or an enemy.
389 *** ***************************************************************************/
390 class BattleTarget {
391 public:
392 	BattleTarget();
393 
~BattleTarget()394 	~BattleTarget()
395 		{}
396 
397 	//! \brief Resets all class members, invalidating the target
398 	void InvalidateTarget();
399 
400 	/** \brief Used to set the initial target
401 	*** \param user A pointer to the actor which will use the target
402 	*** \param type The type of target to set
403 	***
404 	*** If the function fails to find an initial target, the target type will be set to
405 	*** GLOBAL_TARGET_INVALID. The initial attack point is always the first available point on the
406 	*** actor (index 0). The initial actor will always be the first valid actor in their respective
407 	*** party (index 0).
408 	**/
409 	void SetInitialTarget(BattleActor* user, hoa_global::GLOBAL_TARGET type);
410 
411 	/** \brief Sets the target to a specific attack point on an actor
412 	*** \param type The type of target to set, must be one of the point type targets
413 	*** \param attack_point An integer index into the actor's attack points
414 	*** \param actor The actor to set for the target (default value == NULL)
415 	*** A NULL actor simply means that the class should continue pointing to the current actor.
416 	*** This is useful for cycling through the available attack points on an actor. Note that if the
417 	*** actor argument is NULL, the _actor member should not be NULL when the function is called.
418 	*** If both are NULL, calling this method will perform no changes.
419 	**/
420 	void SetPointTarget(hoa_global::GLOBAL_TARGET type, uint32 attack_point, BattleActor* actor = NULL);
421 
422 	/** \brief Sets the target to an actor
423 	*** \param type The type of target to set, must be one of the actor type targets
424 	*** \param actor A pointer to the actor to set for the target
425 	**/
426 	void SetActorTarget(hoa_global::GLOBAL_TARGET type, BattleActor* actor);
427 
428 	/** \brief Sets the target to a party
429 	*** \param type The type of target to set, must be one of the party type targets
430 	*** \param actor A pointer to the party to set for the target
431 	**/
432 	void SetPartyTarget(hoa_global::GLOBAL_TARGET type, std::deque<BattleActor*>* party);
433 
434 	/** \brief Returns true if the target is valid
435 	*** This method assumes that a valid target is one that is alive (non-zero HP). If the target type
436 	*** is an actor or attack point, the function returns true so long as the target actor is alive.
437 	*** If the target type is a party, this method will always return true as parties always have at
438 	*** least one living actor unless the battle has ended.
439 	***
440 	*** Not all actions/skills/items should rely on this method for determining whether or not the
441 	*** target is valid for their particular circumstances. For example, a revive item is only valid
442 	*** to use on a dead actor. Other actions/items may have their own criteria for determining what
443 	*** is a valid target.
444 	**/
445 	bool IsValid();
446 
447 	/** \brief Changes the target attack point to reference the next available attack point target
448 	*** \param user A pointer to the actor which is using this target
449 	*** \param direction Tells the method to look either forward or backward (true/false) for the next target
450 	*** \param valid_criteria When true the method will only select targets determined to be valid by IsValid()
451 	*** \return True if the attack point or actor target was changed, false if no change took place
452 	***
453 	*** This method should only be invoked when the _type member is equal to one of the "POINT" types.
454 	*** Under normal circumstances this method will simply reference the next attack point available on
455 	*** the targeted actor. However, if the actor is deceased and the valid_criteria member is set to true,
456 	*** this will cause the method to look for the next available actor and call the SelectNextActor() method.
457 	***
458 	*** If the action/skill/item has special criteria for determining what type of a target is valid, the valid_criteria
459 	*** member should be set to false. This will ignore whether or not the target actor is deceased and allow external
460 	*** code to determine the validity of the new attack point target itself.
461 	**/
462 	bool SelectNextPoint(BattleActor* user, bool direction = true, bool valid_criteria = true);
463 
464 	/** \brief Changes the target actor to reference the next available actor
465 	*** \param user A pointer tot he actor which is using this target
466 	*** \param direction Tells the method to look either forward or backward (true/false) for the next target
467 	*** \param valid_criteria When true the method will only select actors determined to be valid by IsValid()
468 	*** \return True if the _actor member was changed, false if it was not
469 	***
470 	*** This method should only be called when the target type is not one of the party types.
471 	**/
472 	bool SelectNextActor(BattleActor* user, bool direction = true, bool valid_criteria = true);
473 
474 	//! \name Class member accessor methods
475 	//@{
GetType()476 	hoa_global::GLOBAL_TARGET GetType() const
477 		{ return _type; }
478 
GetPoint()479 	uint32 GetPoint() const
480 		{ return _point; }
481 
GetActor()482 	BattleActor* GetActor() const
483 		{ return _actor; }
484 
GetParty()485 	std::deque<BattleActor*>* GetParty() const
486 		{ return _party; }
487 	//@}
488 
489 private:
490 	//! \brief The type of target this object represents (attack point, actor, or party)
491 	hoa_global::GLOBAL_TARGET _type;
492 
493 	//! \brief The attack point to target, as an index to the proper point on the _actor
494 	uint32 _point;
495 
496 	//! \brief The actor to target
497 	BattleActor* _actor;
498 
499 	//! \brief The party to target
500 	std::deque<BattleActor*>* _party;
501 }; // class BattleTarget
502 
503 
504 /** ****************************************************************************
505 *** \brief A simple container class for items that may be used in battle
506 ***
507 *** This class adds an additional member to be associated with GlobalItem objects
508 *** which keeps track of how many of that item are available to use. This is necessary
509 *** because when an actor selects an item to use, they do not immediately use that
510 *** item and may ultimately not use the item due to the user becoming incapacitated
511 *** or having no valid target for the item. At all times, the available count of an item
512 *** will be less than or equal to the actual count of the item.
513 ***
514 *** The proper way to use this class is to call the following methods for the following
515 *** situations.
516 ***
517 *** - DecrementAvailableCount(): call when an actor has selected to use an item
518 *** - IncrementAvaiableAcount(): call when an actor does not use an item that it selected
519 *** - DecrementCount(): call when the item is actually used
520 ***
521 *** \note Do not call the IncrementCount(), DecrementCount(), or SetCount() methods on the GlobalItem
522 *** pointer. This will circumvent the ability of this class to keep an accurate and correct available
523 *** count. Instead, use the IncrementCount() and DecrementCount() methods of this BattleItem class
524 *** directly.
525 *** ***************************************************************************/
526 class BattleItem {
527 public:
528 	//! \param item A pointer to the item to represent. Should be a non-NULL value.
529 	BattleItem(hoa_global::GlobalItem item);
530 
531 	~BattleItem();
532 
533 	//! \brief Class member accessor methods
534 	//@{
GetItem()535 	hoa_global::GlobalItem& GetItem()
536 		{ return _item; }
537 
GetAvailableCount()538 	uint32 GetAvailableCount() const
539 		{ return _available_count; }
540 	//@}
541 
542 	/** \brief Increases the available count of the item by one
543 	*** The available count will not be allowed to exceed the GlobalItem _count member
544 	**/
545 	void IncrementAvailableCount();
546 
547 	/** \brief Decreases the available count of the item by one
548 	*** The available count will not be allowed to decrement below zero
549 	**/
550 	void DecrementAvailableCount();
551 
552 	/** \brief Increments the count of an item by one
553 	*** \note This method should not be called under normal battle circumstances
554 	**/
555 	void IncrementCount();
556 
557 	/** \brief Decrements the count of the item by one
558 	*** Will also decrement the available count if the two counts are equal
559 	**/
560 	void DecrementCount();
561 
562 	/** \brief A wrapper function that retrieves the actual count of the item
563 	*** \note Calling this function is equivalent to calling GetItem().GetCount()
564 	**/
GetCount()565 	uint32 GetCount() const
566 		{ return _item.GetCount(); }
567 
568 	/** \brief A wrapper function that retrieves the target type of the item
569 	*** \note Calling this function is equivalent to calling GetItem().GetTargetType()
570 	**/
GetTargetType()571 	hoa_global::GLOBAL_TARGET GetTargetType() const
572 		{ return _item.GetTargetType(); }
573 
574 private:
575 	//! \brief The item that this class represents
576 	hoa_global::GlobalItem _item;
577 
578 	//! \brief The number of instances of this item that are available to be selected to be used
579 	uint32 _available_count;
580 }; // class BattleItem
581 
582 } // namespace private_battle
583 
584 } // namespace hoa_battle
585 
586 #endif // __BATTLE_UTILS_HEADER__
587