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_actors.h 12 *** \author Viljami Korhonen, mindflayer@allacrost.org 13 *** \author Corey Hoffstein, visage@allacrost.org 14 *** \author Andy Gardner, chopperdave@allacrost.org 15 *** \brief Header file for actors present in battles. 16 *** 17 *** This code contains the implementation of battle actors (characters and 18 *** enemies) whom are represented on the field of battle. 19 *** ***************************************************************************/ 20 21 #ifndef __BATTLE_ACTORS_HEADER__ 22 #define __BATTLE_ACTORS_HEADER__ 23 24 #include "defs.h" 25 #include "utils.h" 26 27 #include "global_skills.h" 28 #include "global_actors.h" 29 #include "global_effects.h" 30 31 #include "battle_utils.h" 32 33 namespace hoa_battle { 34 35 namespace private_battle { 36 37 /** **************************************************************************** 38 *** \brief An abstract class for representing an actor in the battle 39 *** 40 *** An "actor" is a term used to represent both characters and enemies in battle. 41 *** This abstract class contains members and methods that are common to both types of 42 *** actors. As such, many of the implemented methods in this class are virtual. 43 *** 44 *** The BattleActor class contains a pointer to a GlobalActor object that represents 45 *** the character or enemy. BattleActor contains its own members for all actor stats such 46 *** as HP, strength, evade rating, etc. There are two reasons why BattleActor uses its own 47 *** members instead of directly accessing and modifying the members of the GlobalActor pointer. 48 *** First, various effects can occur in battle which can modify otherwise static stats such as 49 *** agility. We need the ability to restore each stat to its base value, and the GlobalActor 50 *** class retains that unaltered value. Second, if the player loses the battle and chooses to 51 *** retry, we need to restore all actors back to their original state before the battle began. 52 *** Retreiving the values of the GlobalActor class allows us to do so. 53 *** 54 *** Throughout the battle, actors progress through a series of states. The 55 *** standard set of states that an actor cylces through while they are "alive" 56 *** and participating in the battle are as follows. 57 *** 58 *** -# ACTOR_STATE_IDLE 59 *** -# ACTOR_STATE_COMMAND 60 *** -# ACTOR_STATE_WARM_UP 61 *** -# ACTOR_STATE_READY 62 *** -# ACTOR_STATE_ACTING 63 *** -# ACTOR_STATE_COOL_DOWN 64 *** 65 *** Throughout each cycle, the actor will select or be given an action to execute. 66 *** This action may be to attack an actor on the opposing team, heal a teammate, 67 *** use an item, or perform some sort of skill. Each actor is responsible for the 68 *** management of the action that they intend to take. 69 *** ***************************************************************************/ 70 class BattleActor : public hoa_global::GlobalActor { 71 public: 72 BattleActor(hoa_global::GlobalActor* actor); 73 74 virtual ~BattleActor(); 75 76 //! \brief Returns true if the actor is considered an enemy of the character party 77 virtual bool IsEnemy() const = 0; 78 79 //! \brief Returns true so long as the actor is not in the "dead" state IsAlive()80 bool IsAlive() const 81 { return (_state != ACTOR_STATE_DEAD); } 82 83 //! \brief Empty method. Required because this is a pure virtual method of GlobalActor AddSkill(uint32 skill_id)84 void AddSkill(uint32 skill_id) 85 {} 86 87 /** \brief Changes the state of the actor and modifies the actor's properties accordingly 88 *** \param new_state The state to set the actor to 89 **/ 90 virtual void ChangeState(ACTOR_STATE new_state); 91 92 //! \brief Returns the width of the actor's sprite image 93 virtual float GetSpriteWidth() const = 0; 94 95 //! \brief Returns the height of the actor's sprite image 96 virtual float GetSpriteHeight() const = 0; 97 98 /** \brief Changes the actor's current sprite animation image 99 *** \param alias The alias text used to identify the animation to change 100 *** 101 *** \note Not all forms of battle sprites have multiple animations or any animations at all. For 102 *** example, enemies typically only have a standard set of unanimated damage frames for their 103 *** sprites. The reason this method is defined for all actors is so that the same skills may be 104 *** reused for both characters and enemies, since some skill implementations will wish to call 105 *** this method on the actor performing the skill. 106 **/ 107 virtual void ChangeSpriteAnimation(const std::string& alias) = 0; 108 109 /** \brief Deals damage to the actor by reducing its hit points by a certain amount 110 *** \param amount The number of hit points to decrease on the actor 111 *** 112 *** If the state of the actor is ACTOR_STATE_DEAD, this function will print a warning and change nothing. 113 *** If the amount of damage dealt is greater than the actor's current hit points, the actor will be placed 114 *** in the ACTOR_STATE_DEAD state. 115 **/ 116 void RegisterDamage(uint32 amount); 117 118 /** \brief Heals the actor by restoring a certain amount of hit points 119 *** \param amount The number of hit points to add to the actor 120 *** 121 *** If the state of the actor is ACTOR_STATE_DEAD, this function will print a warning and change nothing. 122 *** The number of hit points on the actor are not allowed to increase beyond the actor's maximum hit 123 *** points. 124 **/ 125 void RegisterHealing(uint32 amount); 126 127 //! \brief Indicates that an action failed to connect on this target 128 void RegisterMiss(); 129 130 /** \brief Causes a change in a character's status 131 *** \param status The type of status to change 132 *** \param intensity The intensity of the change 133 *** 134 *** This is the single method for registering a change in status for an actor. It can be used to add 135 *** a new status, remove an existing status, or change the intensity level of an existing status. A 136 *** positive intensity argument will increase the intensity while a negative intensity will decrease 137 *** the intensity. Many different changes can occur depending upon the current state of the actor and 138 *** any active status effects when this function is called, as the list below describes. 139 *** 140 *** - If this status is not already active on the character and the intensity argument is positive, 141 *** the actor will have the new status added at that intensity. 142 *** - If this status is not already active on the character and the intensity argument is negative, 143 *** no change will occur. 144 *** - If this status is active and intensity is positive, intensity will be increased but will not 145 *** exceed the maximum intensity level. 146 *** - If this status is active, the intensity is positive, and the current intensity of the status 147 *** is already at the maximum level, the status timer will be reset and the intensity will not change. 148 *** - If this status is active and intensity is negative, intensity will be decreased but not allowed 149 *** to go lower than the neutral level. If the neutral level is reached, the status will be removed. 150 *** - If this status is active and the intensity is GLOBAL_INTENSITY_NEG_EXTREME, the status will be 151 *** removed regardless of its current intensity level. 152 *** - If this status has an opposite status type that is active on the actor and the intensity argument 153 *** is positive, this will decrease the intensity of the opposite status by the degree of intensity. 154 *** This may cause that opposite status to be removed and this new status to be added if the intensity 155 *** change is significantly high. 156 **/ 157 void RegisterStatusChange(hoa_global::GLOBAL_STATUS status, hoa_global::GLOBAL_INTENSITY intensity); 158 159 /** \brief Increases or decreases the current skill points of the actor 160 *** \param amount The number of skill points to increase or decrease 161 *** 162 *** If the actor is dead, no change will take place. If the amount is positive, the actor will 163 *** not be allowed to exceed above their maximum skill points. 164 *** 165 *** Any non-zero change in skill points will be reflected via increase/decrease text that will 166 *** be drawn to the screen near the actor's sprite. If the value of the amount argument is zero, 167 *** the word "Miss" will be drawn instead; 168 **/ 169 void ChangeSkillPoints(int32 amount); 170 171 //! \brief Updates the state of the actor 172 virtual void Update(); 173 174 //! \brief Draws the actor's current sprite animation frame 175 virtual void DrawSprite() = 0; 176 177 //! \brief Draws all active indicator text and graphics for the actor 178 void DrawIndicators() const; 179 180 /** \brief Sets the action that the actor should execute next 181 *** \param action A pointer to the action that the actor should execute 182 *** 183 *** The actor assumes responsibility for the memory management of the action that is given to it with 184 *** this method and will delete the object at the appropriate time. You should only call the method 185 *** when the actor is in the state ACTOR_STATE_COMMAND. Invoking it at any other time will result in a 186 *** warning and no operation, and the action object will be deleted immediately. A warning is also 187 *** printed in the case where the actor has another action prepared. 188 **/ 189 void SetAction(BattleAction* action); 190 191 //! \brief Resets actor stats to their original values 192 //@{ ResetHitPoints()193 void ResetHitPoints() 194 { SetHitPoints(_global_actor->GetHitPoints()); } 195 ResetMaxHitPoints()196 void ResetMaxHitPoints() 197 { SetMaxHitPoints(_global_actor->GetMaxHitPoints()); } 198 ResetSkillPoints()199 void ResetSkillPoints() 200 { SetSkillPoints(_global_actor->GetSkillPoints()); } 201 ResetMaxSkillPoints()202 void ResetMaxSkillPoints() 203 { SetMaxSkillPoints(_global_actor->GetMaxSkillPoints()); } 204 ResetStrength()205 void ResetStrength() 206 { SetStrength(_global_actor->GetStrength()); } 207 ResetVigor()208 void ResetVigor() 209 { SetVigor(_global_actor->GetVigor()); } 210 ResetFortitude()211 void ResetFortitude() 212 { SetFortitude(_global_actor->GetFortitude()); } 213 ResetProtection()214 void ResetProtection() 215 { SetProtection(_global_actor->GetProtection()); } 216 ResetAgility()217 void ResetAgility() 218 { SetAgility(_global_actor->GetAgility()); } 219 ResetEvade()220 void ResetEvade() 221 { SetEvade(_global_actor->GetEvade()); } 222 //@} 223 224 //! \brief Returns the average defense/evasion totals of all of the actor's attack points 225 //@{ 226 uint32 TotalPhysicalDefense(); 227 228 uint32 TotalMetaphysicalDefense(); 229 230 float TotalEvadeRating(); 231 //@} 232 233 //! \name Class member access methods 234 //@{ GetState()235 ACTOR_STATE GetState() const 236 { return _state; } 237 GetGlobalActor()238 hoa_global::GlobalActor* GetGlobalActor() 239 { return _global_actor; } 240 GetAction()241 BattleAction* GetAction() 242 { return _action; } 243 GetXOrigin()244 float GetXOrigin() const 245 { return _x_origin; } 246 GetYOrigin()247 float GetYOrigin() const 248 { return _y_origin; } 249 GetXLocation()250 float GetXLocation() const 251 { return _x_location; } 252 GetYLocation()253 float GetYLocation() const 254 { return _y_location; } 255 GetIdleStateTime()256 uint32 GetIdleStateTime() const 257 { return _idle_state_time; } 258 GetStaminaIcon()259 hoa_video::StillImage& GetStaminaIcon() 260 { return _stamina_icon; } 261 GetStateTimer()262 hoa_system::SystemTimer& GetStateTimer() 263 { return _state_timer; } 264 SetXOrigin(float x_origin)265 void SetXOrigin(float x_origin) 266 { _x_origin = x_origin; } 267 SetYOrigin(float y_origin)268 void SetYOrigin(float y_origin) 269 { _y_origin = y_origin; } 270 SetXLocation(float x_location)271 void SetXLocation(float x_location) 272 { _x_location = x_location; } 273 SetYLocation(float y_location)274 void SetYLocation(float y_location) 275 { _y_location = y_location; } 276 277 //! \note If the actor is in the idle state, this will not affect the state timer SetIdleStateTime(uint32 time)278 void SetIdleStateTime(uint32 time) 279 { _idle_state_time = time; } 280 //@} 281 282 protected: 283 //! \brief The state that the actor is currently in 284 ACTOR_STATE _state; 285 286 //! \brief A pointer to the global actor object which the battle actor represents 287 hoa_global::GlobalActor* _global_actor; 288 289 //! \brief A pointer to the action that the actor is preparing to perform or is currently performing 290 BattleAction* _action; 291 292 //! \brief The "home" coordinates for the actor's default location on the battle field 293 float _x_origin, _y_origin; 294 295 //! \brief The x and y coordinates of the actor's current location on the battle field 296 float _x_location, _y_location; 297 298 //! \brief Set to true when the actor is in the ACTING state and the execution of the action is complete 299 bool _execution_finished; 300 301 //! \brief The amount of time (in milliseconds) that the actor needs to wait to pass through the idle state 302 uint32 _idle_state_time; 303 304 //! \brief A timer used as the character progresses through the standard series of actor states 305 hoa_system::SystemTimer _state_timer; 306 307 //! \brief The actor's icon for the stamina meter 308 hoa_video::StillImage _stamina_icon; 309 310 //! \brief An assistant class to the actor that manages all the actor's status and elemental effects 311 EffectsSupervisor* _effects_supervisor; 312 313 //! \brief An assistant class to the actor that manages all the actor's indicator text and graphics 314 IndicatorSupervisor* _indicator_supervisor; 315 }; // class BattleActor 316 317 318 /** **************************************************************************** 319 *** \brief Represents a player-controlled character in the battle 320 *** 321 *** Character actors have a series of animated images that reflect their current 322 *** state and actions. Each character also has a custom set of progressive damage 323 *** battle portraits (5 in total) that are drawn when the character is selected. 324 *** ***************************************************************************/ 325 class BattleCharacter : public BattleActor { 326 public: 327 BattleCharacter(hoa_global::GlobalCharacter* character); 328 329 ~BattleCharacter(); 330 IsEnemy()331 bool IsEnemy() const 332 { return false; } 333 334 void ChangeState(ACTOR_STATE new_state); 335 GetSpriteWidth()336 float GetSpriteWidth() const 337 { return 0.0f; } // TEMP: should retrieve width of current sprite animation 338 GetSpriteHeight()339 float GetSpriteHeight() const 340 { return 0.0f; } // TEMP: should retrieve height of current sprite animation 341 342 void ChangeSpriteAnimation(const std::string& alias); 343 344 //! \brief Updates the state of the character. Must be called every frame! 345 void Update(); 346 347 //! \brief Draws the character's current sprite animation frame 348 void DrawSprite(); 349 350 //! \brief Draws the character's damage-blended face portrait 351 void DrawPortrait(); 352 353 /** \brief Draws the character's status in the bottom area of the screen 354 *** \param order The order position of the character [0-3] used to determine draw positions 355 **/ 356 void DrawStatus(uint32 order); 357 GetGlobalCharacter()358 hoa_global::GlobalCharacter* GetGlobalCharacter() 359 { return _global_character; } 360 GetSpriteAnimationAlias()361 const std::string& GetSpriteAnimationAlias() const 362 { return _sprite_animation_alias; } 363 364 protected: 365 //! \brief A pointer to the global character object which the battle character represents 366 hoa_global::GlobalCharacter* _global_character; 367 368 //! \brief Contains the identifier text of the current sprite animation 369 std::string _sprite_animation_alias; 370 371 //! \brief Contains countdown timer of current animation 372 hoa_system::SystemTimer _animation_timer; 373 374 //! \brief Rendered text of the character's name 375 hoa_video::TextImage _name_text; 376 377 //! \brief Rendered text of the character's current hit points 378 hoa_video::TextImage _hit_points_text; 379 380 //! \brief Rendered text of the character's current skill points 381 hoa_video::TextImage _skill_points_text; 382 }; // class BattleCharacter 383 384 385 /** **************************************************************************** 386 *** \brief Represents the entity for an enemy in the battle 387 *** 388 *** This class is a wrapper around a GlobalEnemy object. 389 *** ***************************************************************************/ 390 class BattleEnemy : public BattleActor { 391 public: 392 BattleEnemy(hoa_global::GlobalEnemy* enemy); 393 394 ~BattleEnemy(); 395 IsEnemy()396 bool IsEnemy() const 397 { return true; } 398 399 void ChangeState(ACTOR_STATE new_state); 400 GetSpriteWidth()401 float GetSpriteWidth() const 402 { return _global_enemy->GetBattleSpriteFrames()->at(0).GetWidth(); } 403 GetSpriteHeight()404 float GetSpriteHeight() const 405 { return _global_enemy->GetBattleSpriteFrames()->at(0).GetHeight(); } 406 407 //! \note Enemies do not have animations so calling this function will achieve nothing ChangeSpriteAnimation(const std::string & alias)408 void ChangeSpriteAnimation(const std::string& alias) 409 { return; } 410 411 void Update(); 412 413 //! \brief Draws the damage blended enemy sprite image on to the battle field 414 void DrawSprite(); 415 GetGlobalEnemy()416 hoa_global::GlobalEnemy* GetGlobalEnemy() 417 { return _global_enemy; } 418 419 //! \brief Compares the Y-coordinates of the actors, used for sorting the actors up-down when drawing 420 bool operator<(const BattleEnemy & other) const; 421 422 protected: 423 //! \brief A pointer to the global enemy object which the battle enemy represents 424 hoa_global::GlobalEnemy* _global_enemy; 425 426 /** \brief Decides what action that the enemy should execute and the target 427 *** \todo This function is extremely rudimentary right now. Later, it should be given a more complete 428 *** AI decision making algorithm 429 **/ 430 void _DecideAction(); 431 }; // class BattleEnemy 432 433 } // namespace private_battle 434 435 } // namespace hoa_battle 436 437 #endif // __BATTLE_ACTORS_HEADER__ 438