Change old references of facing direction using the Key enum to use the Direction enum. Release Build 13875.
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Failing after 1m32s
Emscripten Build / UnitTesting (push) Failing after 1m8s

This commit is contained in:
AMay 2026-06-04 15:34:14 -05:00
parent a1bbe563b3
commit 23bec5059e
15 changed files with 114 additions and 104 deletions

View File

@ -720,14 +720,14 @@ void AiL::HandleUserInput(float fElapsedTime){
if(player->movementVelocity.x!=0.f||player->movementVelocity.y!=0.f){
if(abs(player->movementVelocity.x)>abs(player->movementVelocity.y)){ //Greater Horizontal movement.
if(player->movementVelocity.x!=0.f){
player->SetFacingDirection(player->movementVelocity.x>0?RIGHT:LEFT);
player->SetFacingDirection(player->movementVelocity.x>0?Direction::EAST:Direction::WEST);
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
player->UpdateWalkingAnimation(player->GetFacingDirection(),animationSpd);
}
}
}else{ //Greater Vertical movement.
if(player->movementVelocity.y!=0.f){
player->SetFacingDirection(player->movementVelocity.y>0?DOWN:UP);
player->SetFacingDirection(player->movementVelocity.y>0?Direction::SOUTH:Direction::NORTH);
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
player->UpdateWalkingAnimation(player->GetFacingDirection(),animationSpd);
}
@ -747,52 +747,52 @@ void AiL::HandleUserInput(float fElapsedTime){
if(UpReleased()){
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT);
player->UpdateWalkingAnimation(Direction::EAST);
} else
if(DownHeld()){
player->UpdateWalkingAnimation(DOWN);
player->UpdateWalkingAnimation(Direction::SOUTH);
} else
if(LeftHeld()){
player->UpdateWalkingAnimation(LEFT);
player->UpdateWalkingAnimation(Direction::WEST);
}
}
}
if(RightReleased()){
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(UpHeld()){
player->UpdateWalkingAnimation(UP);
player->UpdateWalkingAnimation(Direction::NORTH);
} else
if(DownHeld()){
player->UpdateWalkingAnimation(DOWN);
player->UpdateWalkingAnimation(Direction::SOUTH);
} else
if(LeftHeld()){
player->UpdateWalkingAnimation(LEFT);
player->UpdateWalkingAnimation(Direction::WEST);
}
}
}
if(LeftReleased()){
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT);
player->UpdateWalkingAnimation(Direction::EAST);
} else
if(DownHeld()){
player->UpdateWalkingAnimation(DOWN);
player->UpdateWalkingAnimation(Direction::SOUTH);
} else
if(UpHeld()){
player->UpdateWalkingAnimation(UP);
player->UpdateWalkingAnimation(Direction::NORTH);
}
}
}
if(DownReleased()){
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT);
player->UpdateWalkingAnimation(Direction::EAST);
} else
if(UpHeld()){
player->UpdateWalkingAnimation(UP);
player->UpdateWalkingAnimation(Direction::NORTH);
} else
if(LeftHeld()){
player->UpdateWalkingAnimation(LEFT);
player->UpdateWalkingAnimation(Direction::WEST);
}
}
}
@ -802,23 +802,8 @@ void AiL::HandleUserInput(float fElapsedTime){
}
if(setIdleAnimation){
switch(player->GetFacingDirection()){
case UP:{
player->UpdateIdleAnimation(UP);
}break;
case DOWN:{
player->UpdateIdleAnimation(DOWN);
}break;
case LEFT:{
player->UpdateIdleAnimation(LEFT);
}break;
case RIGHT:{
player->UpdateIdleAnimation(RIGHT);
}break;
default:{
player->UpdateIdleAnimation(DOWN);
}
}
player->UpdateIdleAnimation(player->GetFacingDirection());
}
}
@ -2929,7 +2914,7 @@ void AiL::ResetPlayerAndChangeClass(Class cl){
game->healthCounter.UpdateNumberPointer(&player->hp);
game->manaCounter.UpdateNumberPointer(&player->mana);
sig::Animation::SetupPlayerAnimations();
GetPlayer()->UpdateIdleAnimation(DOWN);
GetPlayer()->UpdateIdleAnimation(Direction::SOUTH);
GetPlayer()->SetItem1UseFunc(itemAbility1);
GetPlayer()->SetItem2UseFunc(itemAbility2);
GetPlayer()->SetItem3UseFunc(itemAbility3);

View File

@ -165,4 +165,12 @@ void Entity::Spin(float duration,float spinSpd){
void Entity::Knockback(vf2d vel){
CallClassFunc(Knockback(vel));
}
Direction Entity::GetFacingDirection()const{
CallClassFunc(GetFacingDirection());
}
void Entity::SetVelocity(vf2d vel){
CallClassFunc(SetVelocity(vel));
}

View File

@ -44,6 +44,7 @@ All rights reserved.
#include"FriendlyType.h"
#include"DEFINES.h"
#include"State.h"
#include"Direction.h"
class Player;
class Monster;
@ -85,6 +86,8 @@ public:
Buff&AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr);
void Spin(float duration,float spinSpd);
void Knockback(vf2d vel);
Direction GetFacingDirection()const;
void SetVelocity(vf2d vel);
private:
mutableconst std::variant<Monster*,Player*>entity;
inline bool operator==(const Entity&rhs){return entity==rhs.entity;}

View File

@ -860,8 +860,8 @@ bool Monster::_Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag da
if(DisplayDamageNumber){
if(IsDOT){
if(lastDotTimer>0){
dotNumberPtr.get()->AddDamage(int(mod_dmg));
}else{
dotNumberPtr.get()->AddDamage(int(mod_dmg));
dotNumberPtr=DamageNumber::AddDamageNumber(pos+vf2d{0,8.f},int(mod_dmg),NON_FRIENDLY,DamageNumberType::DOT);
}
lastDotTimer=0.05f;

View File

@ -90,13 +90,13 @@ InputGroup Player::KEY_ITEM3;
std::vector<std::weak_ptr<MenuComponent>>Player::moneyListeners;
Player::Player()
:facingDirection(DOWN),state(State::NORMAL){
:facingDirection(Direction::SOUTH),state(State::NORMAL){
Initialize();
}
Player::Player(Player*player)
:pos(player->GetPos()),vel(player->GetVelocity()),iframe_time(player->iframe_time),
facingDirection(DOWN),state(State::NORMAL){
facingDirection(Direction::SOUTH),state(State::NORMAL){
Initialize();
}
@ -441,22 +441,22 @@ void Player::Update(float fElapsedTime){
switch(state){
case State::SPIN:{
switch(facingDirection){
case UP:{
case Direction::NORTH:{
if(lastAnimationFlip==0){
lastAnimationFlip=0.03f;
facingDirection=DOWN;
facingDirection=Direction::SOUTH;
UpdateAnimation("WARRIOR_WALK_S");
}
}break;
case DOWN:{
case Direction::SOUTH:{
if(lastAnimationFlip==0){
lastAnimationFlip=0.03f;
facingDirection=UP;
facingDirection=Direction::NORTH;
UpdateAnimation("WARRIOR_WALK_N");
}
}break;
}
if(facingDirection==RIGHT){
if(facingDirection==Direction::EAST){
spin_angle+=spin_spd*fElapsedTime;
} else {
spin_angle-=spin_spd*fElapsedTime;
@ -501,16 +501,16 @@ void Player::Update(float fElapsedTime){
if(ability3.GetCooldownTime()-ability3.cooldown>0.5){
SetState(State::NORMAL);
switch(facingDirection){
case DOWN:{
case Direction::SOUTH:{
UpdateAnimation("WARRIOR_IDLE_S");
}break;
case RIGHT:{
case Direction::EAST:{
UpdateAnimation("WARRIOR_IDLE_E");
}break;
case LEFT:{
case Direction::WEST:{
UpdateAnimation("WARRIOR_IDLE_W");
}break;
case UP:{
case Direction::NORTH:{
UpdateAnimation("WARRIOR_IDLE_N");
}break;
}
@ -527,7 +527,7 @@ void Player::Update(float fElapsedTime){
}break;
case State::ROLL:{
footstepTimer-=fElapsedTime;
if(facingDirection==RIGHT)spin_angle+=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime;
if(facingDirection==Direction::EAST)spin_angle+=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime;
else spin_angle-=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime;
ySquishFactor=0.5f*sin((PI*fElapsedTime)/"Thief.Right Click Ability.Bounce Period Time"_F)+0.5f;
if(rolling_timer<=0.f){
@ -1022,11 +1022,11 @@ const Animate2D::Frame&Player::GetCatFrame()const{
return animation.GetFrame(internal_catAnimState);
}
void Player::SetFacingDirection(Key direction){
void Player::SetFacingDirection(Direction direction){
facingDirection=direction;
}
Key Player::GetFacingDirection()const{
Direction Player::GetFacingDirection()const{
return facingDirection;
}
@ -1099,25 +1099,25 @@ void Player::Spin(float duration,float spinSpd){
spin_angle=0;
}
void Player::UpdateWalkingAnimation(Key direction, const float frameMult){
void Player::UpdateWalkingAnimation(Direction direction, const float frameMult){
std::string anim;
switch(direction){
case UP:anim=GetWalkNAnimation();break;
case RIGHT:anim=GetWalkEAnimation();break;
case DOWN:anim=GetWalkSAnimation();break;
case LEFT:anim=GetWalkWAnimation();break;
case Direction::NORTH:anim=GetWalkNAnimation();break;
case Direction::EAST:anim=GetWalkEAnimation();break;
case Direction::SOUTH:anim=GetWalkSAnimation();break;
case Direction::WEST:anim=GetWalkWAnimation();break;
}
SetFacingDirection(direction);
UpdateAnimation(anim,0,frameMult);
}
void Player::UpdateIdleAnimation(Key direction){
void Player::UpdateIdleAnimation(Direction direction){
std::string anim;
switch(direction){
case UP:anim=GetIdleNAnimation();break;
case RIGHT:anim=GetIdleEAnimation();break;
case DOWN:anim=GetIdleSAnimation();break;
case LEFT:anim=GetIdleWAnimation();break;
case Direction::NORTH:anim=GetIdleNAnimation();break;
case Direction::EAST:anim=GetIdleEAnimation();break;
case Direction::SOUTH:anim=GetIdleSAnimation();break;
case Direction::WEST:anim=GetIdleWAnimation();break;
}
SetFacingDirection(direction);
UpdateAnimation(anim);
@ -1259,7 +1259,7 @@ void Player::SetAnimationBasedOnTargetingDirection(const std::string_view animat
//Assume facing North.
char facingChar{'N'};
Key facingKey{UP};
Direction facingKey{Direction::NORTH};
auto Capitalize=[](const std::string_view str){
std::string newStr;
@ -1270,15 +1270,15 @@ void Player::SetAnimationBasedOnTargetingDirection(const std::string_view animat
if(FacingSouth()){
facingChar='S';
facingKey=DOWN;
facingKey=Direction::SOUTH;
}
if(FacingEast()){
facingChar='E';
facingKey=RIGHT;
facingKey=Direction::EAST;
}
if(FacingWest()){
facingChar='W';
facingKey=LEFT;
facingKey=Direction::WEST;
}
SetFacingDirection(facingKey);
@ -2136,16 +2136,16 @@ const bool Player::PoisonArrowAutoAttackReady()const{
const vf2d Player::GetFacingDirVector()const{
switch(GetFacingDirection()){
case UP:{
case Direction::NORTH:{
return {0,-1};
}break;
case DOWN:{
case Direction::SOUTH:{
return {0,1};
}break;
case LEFT:{
case Direction::WEST:{
return {-1,0};
}break;
case RIGHT:{
case Direction::EAST:{
return {1,0};
}break;
default:{

View File

@ -135,12 +135,12 @@ public:
float GetAttackRange(); //Returns the player's attack range in units. Divide by 100 for number of tiles.
float GetSpinAngle();
State::State GetState();
Key GetFacingDirection()const;
Direction GetFacingDirection()const;
vf2d GetVelocity();
bool HasIframes();
void Update(float fElapsedTime);
void UpdateWalkingAnimation(Key direction, const float frameMult=1.f);
void UpdateIdleAnimation(Key direction);
void UpdateWalkingAnimation(Direction direction, const float frameMult=1.f);
void UpdateIdleAnimation(Direction direction);
//The range is the search range in tiles.
bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8);
bool CanMove();
@ -436,7 +436,7 @@ protected:
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
float ARROW_ATTACK_COOLDOWN="Ranger.Auto Attack.Cooldown"_F;
void SetSwordSwingTimer(float val);
void SetFacingDirection(Key direction);
void SetFacingDirection(Direction direction);
void Spin(float duration,float spinSpd);
float friction="Player.Friction"_F;
float attack_cooldown_timer=0;
@ -446,7 +446,7 @@ protected:
std::pair<std::string,float> notificationDisplay={"",0.f};
bool upperLevel=false;
vf2d vel={0,0};
Key facingDirection=DOWN;
Direction facingDirection=Direction::SOUTH;
float swordSwingTimer=0;
Ability*castPrepAbility;
vf2d precastLocation={};

View File

@ -70,7 +70,7 @@ void State_OverworldMap::OnLevelLoad(){
if(Menu::IsMenuOpen())Menu::CloseAllMenus();
game->GetPlayer()->ForceSetPos(currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16});
playerTargetPos=currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16};
game->GetPlayer()->UpdateWalkingAnimation(DOWN);
game->GetPlayer()->UpdateWalkingAnimation(Direction::SOUTH);
game->GetPlayer()->SetState(State::FORCE_WALK);
game->GetPlayer()->SetSizeMult(1);
game->camera.MoveCamera(currentConnectionPoint->rect.middle()+vf2d{game->GetScreenSize().x/6.0f,0});

View File

@ -119,7 +119,7 @@ void Trapper::InitializeClassAbilities(){
[](Entity e,vf2d pos={}){Player*p=e.ToPlayer(); //TODO
CreateBullet(BearTrap)(p->GetPos(),"Trapper.Ability 2.Trap Radius"_I,"Trapper.Ability 2.DamageMult"_F*p->GetAttack(),0.2f,0.5f,p->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,{1.f,1.f})EndBullet;
SoundEffect::PlaySFX("Place Down Trap",p->GetPos());
p->SetAnimationBasedOnTargetingDirection("SETTRAP",p->GetFacingDirection());
p->UpdateAnimation("SETTRAP");
return true;
};
#pragma endregion
@ -130,7 +130,7 @@ void Trapper::InitializeClassAbilities(){
if(p->HasEnchant("Concussive Trap"))trapDamage+=p->GetAttack()*"Concussive Trap"_ENC["ADDITIONAL EXPLOSION DAMAGE"]/100.f;
CreateBullet(ExplosiveTrap)(p->GetPos(),"Trapper.Ability 3.Trap Radius"_I,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,"Trapper.Ability 3.Trap Auto Detonate Time"_F,trapDamage,0.2f,0.5f,"Trapper.Ability 3.Trap Activation Time"_F,p->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,{1.f,1.f})EndBullet;
SoundEffect::PlaySFX("Place Down Trap",p->GetPos());
p->SetAnimationBasedOnTargetingDirection("SETTRAP",p->GetFacingDirection());
p->UpdateAnimation("SETTRAP");
return true;
};
#pragma endregion

View File

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 13868
#define VERSION_BUILD 13875
#define stringify(a) stringify_(a)
#define stringify_(a) #a

View File

@ -59,7 +59,7 @@ DEFINE_STRATEGY(WARRIORTHIEF)
const float distToPlayer{util::distance(m.GetPos(),game->GetPlayer()->GetPos())};
if(distToPlayer<100.f&&m.F(A::DEFENSIVE_COOLDOWN)<=0.f){
m.F(A::DEFENSIVE_COOLDOWN)=ConfigFloat("Warrior.Right Click Ability.Cooldown");
Warrior::ability2.action(&m,m.GetPos());
Warrior::ability3.action(&m,m.GetPos());
}
}break;
case SPIN:{

View File

@ -149,37 +149,37 @@ void Warrior::InitializeClassAbilities(){
#pragma endregion
#pragma region Warrior Ability 3 (Sonic Slash)
Warrior::ability3.action=
[](Entity e,vf2d pos={}){Player*p=e.ToPlayer(); //TODO
p->SetState(State::SWING_SONIC_SWORD);
p->AddBuff(BuffType::SLOWDOWN,"Warrior.Ability 3.StuckTime"_F,1);
[](Entity e,vf2d pos={}){
IFPLAYER{p.SetState(State::SWING_SONIC_SWORD);}ENDIF
e.AddBuff(BuffType::SLOWDOWN,CONFIG_F("Warrior.Ability 3.StuckTime"),1);
vf2d bulletVel={};
switch(p->GetFacingDirection()){
case UP:{
p->vel.y="Warrior.Ability 3.AbilityPushback"_F;
switch(e.GetFacingDirection()){
case Direction::NORTH:{
e.SetVelocity({0.f,CONFIG_F("Warrior.Ability 3.AbilityPushback")});
bulletVel.y=-"Warrior.Ability 3.BulletSpd"_F;
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_N",WARRIOR);
IFPLAYER{p.UpdateAnimation("WARRIOR_SWINGSONICSWORD_N",WARRIOR);}ENDIF
}break;
case LEFT:{
p->vel.x="Warrior.Ability 3.AbilityPushback"_F;
case Direction::WEST:{
e.SetVelocity({CONFIG_F("Warrior.Ability 3.AbilityPushback"),0.f});
bulletVel.x=-"Warrior.Ability 3.BulletSpd"_F;
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_W",WARRIOR);
IFPLAYER{p.UpdateAnimation("WARRIOR_SWINGSONICSWORD_W",WARRIOR);}ENDIF
}break;
case RIGHT:{
p->vel.x=-"Warrior.Ability 3.AbilityPushback"_F;
case Direction::EAST:{
e.SetVelocity({-CONFIG_F("Warrior.Ability 3.AbilityPushback"),0.f});
bulletVel.x="Warrior.Ability 3.BulletSpd"_F;
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_E",WARRIOR);
IFPLAYER{p.UpdateAnimation("WARRIOR_SWINGSONICSWORD_E",WARRIOR);}ENDIF
}break;
case DOWN:{
p->vel.y=-"Warrior.Ability 3.AbilityPushback"_F;
case Direction::SOUTH:{
e.SetVelocity({0.f,-CONFIG_F("Warrior.Ability 3.AbilityPushback")});
bulletVel.y="Warrior.Ability 3.BulletSpd"_F;
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_S",WARRIOR);
IFPLAYER{p.UpdateAnimation("WARRIOR_SWINGSONICSWORD_S",WARRIOR);}ENDIF
}break;
}
int sonicSlashDamage{int(p->GetAttack()*"Warrior.Ability 3.DamageMult"_F)};
if(p->HasEnchant("Sonic Upgrade"))sonicSlashDamage+=p->GetMaxHealth()*"Sonic Upgrade"_ENC["ADDITIONAL DMG PCT"]/100.f;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,sonicSlashDamage,"assets/sonicslash.png",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,FRIENDLY,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30}));
int sonicSlashDamage{int(e.GetAttack()*CONFIG_F("Warrior.Ability 3.DamageMult"))};
IFPLAYER{if(p.HasEnchant("Sonic Upgrade"))sonicSlashDamage+=p.GetMaxHealth()*"Sonic Upgrade"_ENC["ADDITIONAL DMG PCT"]/100.f;}ENDIF
BULLET_LIST.emplace_back(std::make_unique<Bullet>(e.GetPos(),bulletVel,CONFIG_F("Warrior.Ability 3.Radius"),sonicSlashDamage,"assets/sonicslash.png",e.OnUpperLevel(),true,CONFIG_F("Warrior.Ability 3.Lifetime"),true,e.IsFriendly(),WHITE,vf2d{CONFIG_F("Warrior.Ability 3.Radius")/30.f,CONFIG_F("Warrior.Ability 3.Radius")/30.f}));
game->SetupWorldShake("Warrior.Ability 3.ShakeTime"_F);
if(p->HasEnchant("Sword Enchantment"))p->AddBuff(BuffType::SWORD_ENCHANTMENT,"Sword Enchantment"_ENC["INCREASE DURATION"],1);
if(e.HasEnchant("Sword Enchantment"))e.AddBuff(BuffType::SWORD_ENCHANTMENT,"Sword Enchantment"_ENC["INCREASE DURATION"],1);
SoundEffect::PlaySFX("Warrior Sonic Slash",SoundEffect::CENTERED);
return true;
};

View File

@ -87,16 +87,16 @@ void Witch::OnUpdate(float fElapsedTime){
}
if(GetState()==State::CASTING){
switch(GetFacingDirection()){
case UP:{
case Direction::NORTH:{
UpdateAnimation("WITCH_CAST_N",WIZARD|WITCH);
}break;
case DOWN:{
case Direction::SOUTH:{
UpdateAnimation("WITCH_CAST_S",WIZARD|WITCH);
}break;
case LEFT:{
case Direction::WEST:{
UpdateAnimation("WITCH_CAST_W",WIZARD|WITCH);
}break;
case RIGHT:{
case Direction::EAST:{
UpdateAnimation("WITCH_CAST_E",WIZARD|WITCH);
}break;
}

View File

@ -85,17 +85,17 @@ void Wizard::OnUpdate(float fElapsedTime){
walk_w="WIZARD_WALK_W";
}
if(GetState()==State::CASTING){
switch(GetFacingDirection()){
case UP:{
switch(GetFacingDirection()){
case Direction::NORTH:{
UpdateAnimation("WIZARD_CAST_N",WIZARD|WITCH);
}break;
case DOWN:{
case Direction::SOUTH:{
UpdateAnimation("WIZARD_CAST_S",WIZARD|WITCH);
}break;
case LEFT:{
case Direction::WEST:{
UpdateAnimation("WIZARD_CAST_W",WIZARD|WITCH);
}break;
case RIGHT:{
case Direction::EAST:{
UpdateAnimation("WIZARD_CAST_E",WIZARD|WITCH);
}break;
}

View File

@ -1532,5 +1532,19 @@ MonsterStrategy
# How much knockback is reduced per 100% larger size.
Warrior.Ability 2.KnockbackWeightFactor = 25
# Speed of the sonic slash.
Warrior.Ability 3.BulletSpd = 400
Warrior.Ability 3.Radius = 30
Warrior.Ability 3.DamageMult = 8
Warrior.Ability 3.Lifetime = 2.25
# Amount of seconds the player will be unable to move when using this ability.
Warrior.Ability 3.StuckTime = 0.5
# How far the player gets pushed back when using this ability.
Warrior.Ability 3.AbilityPushback = 70
Warrior.Ability 3.ShakeTime = 0.5
}
}