2023-06-11 22:57:43 -05:00
# pragma once
# include "olcUTIL_Animate2D.h"
# include "Animation.h"
# include "Monster.h"
2023-06-12 18:14:22 -05:00
# include "State.h"
2023-06-17 21:19:08 -05:00
# include "Ability.h"
2023-06-17 22:03:20 -05:00
# include "Class.h"
2023-06-19 03:25:01 -05:00
# include "Buff.h"
2023-07-05 21:14:36 +00:00
# include "Pathfinding.h"
2023-07-25 19:48:24 -05:00
# include "DamageNumber.h"
2023-07-27 21:21:39 +00:00
# include "config.h"
2023-06-11 22:57:43 -05:00
2023-07-18 19:43:51 +00:00
struct CastInfo {
std : : string name ;
float castTimer ;
float castTotalTime ;
2023-07-20 20:46:25 +00:00
vf2d castPos ;
2023-07-18 19:43:51 +00:00
} ;
2023-06-11 22:57:43 -05:00
struct Player {
2023-06-17 19:34:16 -05:00
friend class Crawler ;
2023-07-12 00:23:36 -05:00
friend class sig : : Animation ;
2023-07-22 04:21:10 -05:00
friend class Warrior ;
friend class Thief ;
friend class Ranger ;
friend class Trapper ;
friend class Wizard ;
friend class Witch ;
2023-07-28 03:28:42 -05:00
private :
2023-06-11 22:57:43 -05:00
int hp = 100 , maxhp = hp ;
2023-06-19 04:03:04 -05:00
int mana = 100 , maxmana = mana ;
2023-06-11 22:57:43 -05:00
int atk = 10 ;
vf2d pos ;
2023-06-12 19:23:43 +00:00
float z = 0 ;
2023-06-11 22:57:43 -05:00
float moveSpd = 1.0f ;
float size = 1.0f ;
2023-06-12 18:14:22 -05:00
float spin_attack_timer = 0 ;
float spin_spd = 0 ;
float spin_angle = 0 ;
float lastAnimationFlip = 0 ;
2023-06-19 04:03:04 -05:00
float manaTickTimer = 0 ;
std : : pair < std : : string , float > notEnoughManaDisplay = { " " , 0 } ;
2023-07-06 03:22:05 -05:00
float teleportAttemptWaitTime = 0 ; //If a teleport fails, we wait awhile before trying again, it's expensive.
2023-06-16 02:33:12 -05:00
State state = State : : NORMAL ;
2023-06-11 22:57:43 -05:00
Animate2D : : Animation < AnimationState > animation ;
Animate2D : : AnimationState internal_animState ;
Key lastReleasedMovementKey ;
2023-06-17 19:34:16 -05:00
void Update ( float fElapsedTime ) ;
2023-07-14 15:44:17 +00:00
void AddAnimation ( AnimationState state ) ;
2023-07-13 17:46:01 +00:00
std : : vector < Buff > buffList ;
2023-07-18 19:43:51 +00:00
CastInfo castInfo = { " " , 0 } ;
2023-07-23 08:13:40 -05:00
vf2d movementVelocity = { } ; //This tells us if the player is moving (mostly controlled by user input) since their velocity is not used for regular movement.
2023-07-25 19:48:24 -05:00
float lastHitTimer = 0 ; //When this is greater than zero, if we get hit again it adds to our displayed combo number.
std : : shared_ptr < DamageNumber > damageNumberPtr ;
2023-07-28 03:28:42 -05:00
void Initialize ( ) ;
2023-07-13 17:46:01 +00:00
protected :
2023-07-27 21:21:39 +00:00
const float ATTACK_COOLDOWN = " Warrior.Auto Attack.Cooldown " _F ;
2023-07-28 04:41:18 -05:00
const float MAGIC_ATTACK_COOLDOWN = " Wizard.Auto Attack.Cooldown " _F ;
2023-07-23 08:13:40 -05:00
const float ARROW_ATTACK_COOLDOWN = 0.6f ;
2023-06-17 19:34:16 -05:00
void SetSwordSwingTimer ( float val ) ;
void SetState ( State newState ) ;
void SetFacingDirection ( Key direction ) ;
void SetLastReleasedMovementKey ( Key k ) ;
void Spin ( float duration , float spinSpd ) ;
2023-07-05 04:31:31 -05:00
//Returns true if the move was valid and successful.
bool SetX ( float x ) ;
//Returns true if the move was valid and successful.
bool SetY ( float y ) ;
2023-06-17 19:34:16 -05:00
void SetZ ( float z ) ;
2023-07-05 04:31:31 -05:00
//Returns true if the move was valid and successful.
bool SetPos ( vf2d pos ) ;
2023-07-24 20:58:29 +00:00
float friction = 400 ;
2023-07-13 20:24:47 +00:00
float attack_cooldown_timer = 0 ;
float iframe_time = 0 ;
float teleportAnimationTimer = 0 ;
vf2d teleportTarget = { } ;
vf2d teleportStartPosition = { } ;
std : : pair < std : : string , float > notificationDisplay = { " " , 0 } ;
bool upperLevel = false ;
vf2d vel = { 0 , 0 } ;
2023-07-27 21:21:39 +00:00
float attack_range = " Warrior.Auto Attack.Range " _F / 100.f ;
2023-07-21 15:20:56 -05:00
Key facingDirection = DOWN ;
2023-07-13 20:24:47 +00:00
float swordSwingTimer = 0 ;
2023-07-19 20:36:01 +00:00
void CastSpell ( Ability & ability ) ;
Ability * castPrepAbility ;
void PrepareCast ( Ability & ability ) ;
vf2d precastLocation = { } ;
2023-07-24 20:58:29 +00:00
void SetVelocity ( vf2d vel ) ;
const float RETREAT_DISTANCE = 24 * 2.5 ;
const float RETREAT_TIME = 0.2 ; //How long the Retreat ability takes.
const int RETREAT_GHOST_FRAMES = 8 ;
const float RETREAT_GHOST_FRAME_DELAY = 0.025 ;
float ghostFrameTimer = 0 ;
float ghostRemoveTimer = 0 ;
float retreatTimer = 0 ;
std : : vector < vf2d > ghostPositions ;
2023-07-25 20:32:29 +00:00
float rapidFireTimer = 0 ;
int remainingRapidFireShots = 0 ;
const float RAPID_FIRE_SHOOT_DELAY = 0.1 ;
const int RAPID_FIRE_SHOOT_AMOUNT = 4 ;
2023-07-13 17:46:01 +00:00
public :
2023-06-11 22:57:43 -05:00
Player ( ) ;
2023-07-14 19:14:04 +00:00
//So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class
//using a new object type... Because of that we'll take the pointer reference to the old object and copy some of its properties to this new
//one. It's hackish but it means we can reduce the amount of extra boilerplate when class changing...I don't know how to feel about this.
Player ( Player * player ) ;
2023-07-28 03:28:42 -05:00
static float GROUND_SLAM_SPIN_TIME ;
2023-06-11 22:57:43 -05:00
vf2d & GetPos ( ) ;
float GetX ( ) ;
float GetY ( ) ;
2023-06-12 20:22:40 +00:00
float GetZ ( ) ;
2023-06-11 22:57:43 -05:00
int GetHealth ( ) ;
int GetMaxHealth ( ) ;
2023-06-19 04:03:04 -05:00
int GetMana ( ) ;
int GetMaxMana ( ) ;
2023-06-11 22:57:43 -05:00
int GetAttack ( ) ;
float GetMoveSpdMult ( ) ;
float GetSizeMult ( ) ;
float GetAttackRangeMult ( ) ;
2023-06-12 18:14:22 -05:00
float GetSpinAngle ( ) ;
State GetState ( ) ;
2023-06-13 06:29:32 -05:00
Key GetFacingDirection ( ) ;
2023-06-15 23:44:34 -05:00
vf2d GetVelocity ( ) ;
2023-06-17 19:51:56 -05:00
bool HasIframes ( ) ;
2023-06-17 23:07:26 -05:00
void UpdateWalkingAnimation ( Key direction ) ;
void UpdateIdleAnimation ( Key direction ) ;
2023-07-06 03:22:05 -05:00
//The range is the search range in tiles.
bool CanPathfindTo ( vf2d pos , vf2d targetPos , float range = 8 ) ;
2023-07-13 01:35:51 -05:00
bool CanMove ( ) ;
2023-06-11 22:57:43 -05:00
2023-06-19 03:25:01 -05:00
void AddBuff ( BuffType type , float duration , float intensity ) ;
std : : vector < Buff > GetBuffs ( BuffType buff ) ;
2023-07-22 03:19:52 -05:00
bool Hurt ( int damage , bool onUpperLevel ) ;
2023-07-14 15:44:17 +00:00
//specificClass is a bitwise-combination of classes from the Class enum. It makes sure certain animations only play if you are a certain class.
void UpdateAnimation ( AnimationState animState , int specificClass = ANY ) ;
2023-06-11 22:57:43 -05:00
Animate2D : : Frame GetFrame ( ) ;
Key GetLastReleasedMovementKey ( ) ;
2023-06-17 19:34:16 -05:00
float GetSwordSwingTimer ( ) ;
2023-07-07 19:48:45 +00:00
bool OnUpperLevel ( ) ;
2023-06-11 22:57:43 -05:00
//Triggers when the player has moved.
void Moved ( ) ;
2023-07-13 17:46:01 +00:00
virtual ~ Player ( ) = default ;
2023-07-13 20:24:47 +00:00
virtual Class GetClass ( ) = 0 ;
virtual bool AutoAttack ( ) = 0 ;
2023-07-14 15:44:17 +00:00
virtual void OnUpdate ( float fElapsedTime ) = 0 ;
2023-07-13 20:24:47 +00:00
virtual std : : string GetClassName ( ) = 0 ;
virtual Ability & GetRightClickAbility ( ) = 0 ;
virtual Ability & GetAbility1 ( ) = 0 ;
virtual Ability & GetAbility2 ( ) = 0 ;
virtual Ability & GetAbility3 ( ) = 0 ;
virtual Ability & GetAbility4 ( ) = 0 ;
2023-07-14 15:44:17 +00:00
virtual AnimationState & GetWalkNAnimation ( ) = 0 ;
virtual AnimationState & GetWalkEAnimation ( ) = 0 ;
virtual AnimationState & GetWalkSAnimation ( ) = 0 ;
virtual AnimationState & GetWalkWAnimation ( ) = 0 ;
virtual AnimationState & GetIdleNAnimation ( ) = 0 ;
virtual AnimationState & GetIdleEAnimation ( ) = 0 ;
virtual AnimationState & GetIdleSAnimation ( ) = 0 ;
virtual AnimationState & GetIdleWAnimation ( ) = 0 ;
2023-07-18 19:43:51 +00:00
CastInfo & GetCastInfo ( ) ;
2023-07-24 23:20:28 -05:00
void SetAnimationBasedOnTargetingDirection ( float targetDirection ) ;
2023-07-13 20:24:47 +00:00
} ;
struct Warrior : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Warrior ( ) ;
2023-07-14 19:14:04 +00:00
Warrior ( Player * player ) ;
2023-07-14 15:44:17 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only WARRIOR-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-14 15:44:17 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
} ;
struct Thief : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Thief ( ) ;
2023-07-14 19:14:04 +00:00
Thief ( Player * player ) ;
2023-07-14 15:44:17 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only THIEF-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-14 15:44:17 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
} ;
struct Ranger : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Ranger ( ) ;
2023-07-14 19:14:04 +00:00
Ranger ( Player * player ) ;
2023-07-14 15:44:17 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only RANGER-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-14 15:44:17 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
} ;
struct Trapper : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Trapper ( ) ;
2023-07-14 19:14:04 +00:00
Trapper ( Player * player ) ;
2023-07-14 15:44:17 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only TRAPPER-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-14 15:44:17 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
} ;
struct Wizard : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Wizard ( ) ;
2023-07-14 19:14:04 +00:00
Wizard ( Player * player ) ;
2023-07-14 15:44:17 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only WIZARD-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-14 15:44:17 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
} ;
struct Witch : Player {
static std : : string name ;
static Class cl ;
static Ability rightClickAbility , ability1 , ability2 , ability3 , ability4 ;
static AnimationState walk_n , walk_e , walk_s , walk_w , idle_n , idle_e , idle_s , idle_w ;
2023-07-26 21:08:17 +00:00
static void Initialize ( ) ;
2023-07-14 15:44:17 +00:00
Witch ( ) ;
2023-07-14 19:14:04 +00:00
Witch ( Player * player ) ;
2023-07-13 20:24:47 +00:00
Class GetClass ( ) override ;
bool AutoAttack ( ) override ;
2023-07-25 17:34:53 -05:00
//Include only WITCHs-specific implementations!
2023-07-14 15:44:17 +00:00
void OnUpdate ( float fElapsedTime ) override ;
2023-07-22 04:21:10 -05:00
static void InitializeClassAbilities ( ) ;
2023-07-13 20:24:47 +00:00
std : : string GetClassName ( ) override ;
Ability & GetRightClickAbility ( ) override ;
Ability & GetAbility1 ( ) override ;
Ability & GetAbility2 ( ) override ;
Ability & GetAbility3 ( ) override ;
Ability & GetAbility4 ( ) override ;
2023-07-14 15:44:17 +00:00
AnimationState & GetWalkNAnimation ( ) override ;
AnimationState & GetWalkEAnimation ( ) override ;
AnimationState & GetWalkSAnimation ( ) override ;
AnimationState & GetWalkWAnimation ( ) override ;
AnimationState & GetIdleNAnimation ( ) override ;
AnimationState & GetIdleEAnimation ( ) override ;
AnimationState & GetIdleSAnimation ( ) override ;
AnimationState & GetIdleWAnimation ( ) override ;
2023-07-26 20:22:33 -05:00
} ;
# define READFROMCONFIG(class,enum) \
class : : name = # class " .ClassName " _S ; \
class : : cl = enum ; \
class : : rightClickAbility = { \
# class".Right Click Ability.Name"_S, \
# class".Right Click Ability.Cooldown"_F, \
# class".Right Click Ability.Mana Cost"_I, \
{ uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 1 " _f [ 0 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 1 " _f [ 1 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 1 " _f [ 2 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 1 " _f [ 3 ] = = 0 ? 255 : # class " .Right Click Ability.Cooldown Bar Color 1 " _f [ 3 ] ) } , \
{ uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 2 " _f [ 0 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 2 " _f [ 1 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 2 " _f [ 2 ] ) , uint8_t ( # class " .Right Click Ability.Cooldown Bar Color 2 " _f [ 3 ] = = 0 ? 255 : # class " .Right Click Ability.Cooldown Bar Color 2 " _f [ 3 ] ) } , \
2023-07-26 20:51:07 -05:00
{ # class " .Right Click Ability.Precast Time " _F , # class " .Right Click Ability.Casting Range " _I / 100.f * 24 , # class " .Right Click Ability.Casting Size " _I / 100.f * 24 } \
2023-07-26 20:22:33 -05:00
} ; \
class : : ability1 = { \
# class".Ability 1.Name"_S, \
# class".Ability 1.Cooldown"_F, \
# class".Ability 1.Mana Cost"_I, \
{ uint8_t ( # class " .Ability 1.Cooldown Bar Color 1 " _f [ 0 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 1 " _f [ 1 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 1 " _f [ 2 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 1 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 1.Cooldown Bar Color 1 " _f [ 3 ] ) } , \
{ uint8_t ( # class " .Ability 1.Cooldown Bar Color 2 " _f [ 0 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 2 " _f [ 1 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 2 " _f [ 2 ] ) , uint8_t ( # class " .Ability 1.Cooldown Bar Color 2 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 1.Cooldown Bar Color 2 " _f [ 3 ] ) } , \
2023-07-26 20:51:07 -05:00
{ # class " .Ability 1.Precast Time " _F , # class " .Ability 1.Casting Range " _I / 100.f * 24 , # class " .Ability 1.Casting Size " _I / 100.f * 24 } \
2023-07-26 20:22:33 -05:00
} ; \
class : : ability2 = { \
# class".Ability 2.Name"_S, \
# class".Ability 2.Cooldown"_F, \
# class".Ability 2.Mana Cost"_I, \
{ uint8_t ( # class " .Ability 2.Cooldown Bar Color 1 " _f [ 0 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 1 " _f [ 1 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 1 " _f [ 2 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 1 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 2.Cooldown Bar Color 1 " _f [ 3 ] ) } , \
{ uint8_t ( # class " .Ability 2.Cooldown Bar Color 2 " _f [ 0 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 2 " _f [ 1 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 2 " _f [ 2 ] ) , uint8_t ( # class " .Ability 2.Cooldown Bar Color 2 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 2.Cooldown Bar Color 2 " _f [ 3 ] ) } , \
2023-07-26 20:51:07 -05:00
{ # class " .Ability 2.Precast Time " _F , # class " .Ability 2.Casting Range " _I / 100.f * 24 , # class " .Ability 2.Casting Size " _I / 100.f * 24 } \
2023-07-26 20:22:33 -05:00
} ; \
class : : ability3 = { \
# class".Ability 3.Name"_S, \
# class".Ability 3.Cooldown"_F, \
# class".Ability 3.Mana Cost"_I, \
{ uint8_t ( # class " .Ability 3.Cooldown Bar Color 1 " _f [ 0 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 1 " _f [ 1 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 1 " _f [ 2 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 1 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 3.Cooldown Bar Color 1 " _f [ 3 ] ) } , \
{ uint8_t ( # class " .Ability 3.Cooldown Bar Color 2 " _f [ 0 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 2 " _f [ 1 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 2 " _f [ 2 ] ) , uint8_t ( # class " .Ability 3.Cooldown Bar Color 2 " _f [ 3 ] = = 0 ? 255 : # class " .Ability 3.Cooldown Bar Color 2 " _f [ 3 ] ) } , \
2023-07-26 20:51:07 -05:00
{ # class " .Ability 3.Precast Time " _F , # class " .Ability 3.Casting Range " _I / 100.f * 24 , # class " .Ability 3.Casting Size " _I / 100.f * 24 } \
2023-07-26 20:22:33 -05:00
} ; \
class : : ability4 = { " ??? " , 0 , 0 } ;