From 405cd32a4bd788a64a31758f5d94cbde49542413 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sat, 22 Jul 2023 04:21:10 -0500 Subject: [PATCH 1/8] Class abilities are statically set so they are initialized on load to allow for proper swapping. --- Crawler/Ability.h | 4 +++- Crawler/Crawler.cpp | 12 ++++++++++- Crawler/Crawler.h | 1 + Crawler/DEFINES.h | 4 ++-- Crawler/Player.cpp | 5 +++-- Crawler/Player.h | 19 ++++++++++------- Crawler/Ranger.cpp | 8 ++++---- Crawler/Thief.cpp | 8 ++++---- Crawler/Trapper.cpp | 8 ++++---- Crawler/Version.h | 2 +- Crawler/Warrior.cpp | 50 ++++++++++++++++++++++----------------------- Crawler/Witch.cpp | 8 ++++---- Crawler/Wizard.cpp | 47 +++++++++++++++++++++--------------------- 13 files changed, 98 insertions(+), 78 deletions(-) diff --git a/Crawler/Ability.h b/Crawler/Ability.h index ab36841a..9c12c35d 100644 --- a/Crawler/Ability.h +++ b/Crawler/Ability.h @@ -1,6 +1,8 @@ #pragma once #include "olcPixelGameEngine.h" +struct Player; + struct PrecastData{ float castTime; float range; @@ -19,7 +21,7 @@ struct Ability{ int manaCost=0; Pixel barColor1,barColor2; PrecastData precastInfo; - std::functionaction=[&](vf2d){return false;}; + std::functionaction=[](Player*,vf2d){return false;}; Ability(); Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={}); }; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index af889341..867d12e0 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -87,7 +87,9 @@ bool Crawler::OnUserCreate(){ view=TileTransformedView{GetScreenSize(),{1,1}}; LoadLevel(CAMPAIGN_1_1); + InitializeClassAbilities(); ChangePlayerClass(WARRIOR); + //Warrior::ability4=Wizard::ability3; //Class ability swapping demonstration. return true; } @@ -1040,10 +1042,18 @@ void Crawler::ChangePlayerClass(Class cl){ }break; } sig::Animation::SetupPlayerAnimations(); - GetPlayer()->InitializeClassAbilities(); GetPlayer()->UpdateIdleAnimation(DOWN); } +void Crawler::InitializeClassAbilities(){ + Warrior::InitializeClassAbilities(); + Thief::InitializeClassAbilities(); + Ranger::InitializeClassAbilities(); + Trapper::InitializeClassAbilities(); + Wizard::InitializeClassAbilities(); + Witch::InitializeClassAbilities(); +} + int main() { Crawler demo; diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index ad7a9fc7..291c8fb5 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -49,6 +49,7 @@ private: std::vectorupperForegroundTileGroups; int bridgeLayerIndex=-1; float bridgeFadeFactor=0.f; + void InitializeClassAbilities(); public: Crawler(); diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h index 3b2bdf7b..f39a61a4 100644 --- a/Crawler/DEFINES.h +++ b/Crawler/DEFINES.h @@ -14,9 +14,9 @@ #define INFINITE 999999 #define SETUP_CLASS(class) \ -class::class(){InitializeClassAbilities();} \ +class::class(){} \ class::class(Player*player) \ - :Player::Player(player){InitializeClassAbilities();} \ + :Player::Player(player){} \ Class class::GetClass(){return cl;} \ std::string class::GetClassName(){return name;} \ Ability&class::GetRightClickAbility(){return rightClickAbility;}; \ diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index fe782da1..d41eb9a3 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -166,7 +166,7 @@ void Player::Update(float fElapsedTime){ if(castInfo.castTimer>0){ castInfo.castTimer-=fElapsedTime; if(castInfo.castTimer<=0){ - if(castPrepAbility->action(castInfo.castPos)){ + if(castPrepAbility->action(this,castInfo.castPos)){ castPrepAbility->cooldown=castPrepAbility->COOLDOWN_TIME; mana-=castPrepAbility->manaCost; } @@ -269,6 +269,7 @@ void Player::Update(float fElapsedTime){ ability.cooldown=std::max(0.f,ability.cooldown-fElapsedTime); ability2.cooldown=std::max(0.f,ability2.cooldown-fElapsedTime); ability3.cooldown=std::max(0.f,ability3.cooldown-fElapsedTime); + ability4.cooldown=std::max(0.f,ability4.cooldown-fElapsedTime); for(Monster&m:MONSTER_LIST){ if(iframe_time==0&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ if(m.IsAlive()){ @@ -309,7 +310,7 @@ void Player::Update(float fElapsedTime){ if(ability.name!="???"){ if(ability.cooldown==0&&GetMana()>=ability.manaCost){ if(key.bHeld||key.bReleased&&&ability==castPrepAbility&&GetState()==State::PREP_CAST){ - if(AllowedToCast(ability)&&ability.action({})){ + if(AllowedToCast(ability)&&ability.action(this,{})){ ability.cooldown=ability.COOLDOWN_TIME; mana-=ability.manaCost; }else diff --git a/Crawler/Player.h b/Crawler/Player.h index b9710195..7ee1e4bf 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -19,6 +19,12 @@ struct CastInfo{ struct Player{ friend class Crawler; friend class sig::Animation; + friend class Warrior; + friend class Thief; + friend class Ranger; + friend class Trapper; + friend class Wizard; + friend class Witch; private: int hp=100,maxhp=hp; int mana=100,maxmana=mana; @@ -119,7 +125,6 @@ public: virtual Class GetClass()=0; virtual bool AutoAttack()=0; virtual void OnUpdate(float fElapsedTime)=0; - virtual void InitializeClassAbilities()=0; virtual std::string GetClassName()=0; virtual Ability&GetRightClickAbility()=0; virtual Ability&GetAbility1()=0; @@ -148,7 +153,7 @@ struct Warrior:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; @@ -175,7 +180,7 @@ struct Thief:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; @@ -202,7 +207,7 @@ struct Ranger:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; @@ -229,7 +234,7 @@ struct Trapper:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; @@ -256,7 +261,7 @@ struct Wizard:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; @@ -283,7 +288,7 @@ struct Witch:Player{ Class GetClass()override; bool AutoAttack()override; void OnUpdate(float fElapsedTime)override; - void InitializeClassAbilities()override; + static void InitializeClassAbilities(); std::string GetClassName()override; Ability&GetRightClickAbility()override; Ability&GetAbility1()override; diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 11db4bb8..56833a13 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -37,25 +37,25 @@ bool Ranger::AutoAttack(){ void Ranger::InitializeClassAbilities(){ #pragma region Ranger Right-click Ability (???) Ranger::rightClickAbility.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Ranger Ability 1 (???) Ranger::ability1.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Ranger Ability 2 (???) Ranger::ability2.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Ranger Ability 3 (???) Ranger::ability3.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion diff --git a/Crawler/Thief.cpp b/Crawler/Thief.cpp index f84439c0..74f77001 100644 --- a/Crawler/Thief.cpp +++ b/Crawler/Thief.cpp @@ -37,25 +37,25 @@ bool Thief::AutoAttack(){ void Thief::InitializeClassAbilities(){ #pragma region Thief Right-click Ability (???) Thief::rightClickAbility.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Thief Ability 1 (???) Thief::ability1.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Thief Ability 2 (???) Thief::ability2.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Thief Ability 3 (???) Thief::ability3.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion diff --git a/Crawler/Trapper.cpp b/Crawler/Trapper.cpp index 6d15206e..b08f4aed 100644 --- a/Crawler/Trapper.cpp +++ b/Crawler/Trapper.cpp @@ -37,25 +37,25 @@ bool Trapper::AutoAttack(){ void Trapper::InitializeClassAbilities(){ #pragma region Trapper Right-click Ability (???) Trapper::rightClickAbility.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Trapper Ability 1 (???) Trapper::ability1.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Trapper Ability 2 (???) Trapper::ability2.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Trapper Ability 3 (???) Trapper::ability3.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion diff --git a/Crawler/Version.h b/Crawler/Version.h index 46bda7ea..33c6147c 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 747 +#define VERSION_BUILD 759 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/Warrior.cpp b/Crawler/Warrior.cpp index d0d95ecf..d421fa19 100644 --- a/Crawler/Warrior.cpp +++ b/Crawler/Warrior.cpp @@ -70,11 +70,11 @@ bool Warrior::AutoAttack(){ void Warrior::InitializeClassAbilities(){ #pragma region Warrior Right-click Ability (Block) Warrior::rightClickAbility.action= - [&](vf2d pos={}){ - if(GetState()==State::NORMAL){ + [](Player*p,vf2d pos={}){ + if(p->GetState()==State::NORMAL){ rightClickAbility.cooldown=rightClickAbility.COOLDOWN_TIME; - SetState(State::BLOCK); - AddBuff(BuffType::SLOWDOWN,3,0.3); + p->SetState(State::BLOCK); + p->AddBuff(BuffType::SLOWDOWN,3,0.3); return true; } return false; @@ -82,12 +82,12 @@ void Warrior::InitializeClassAbilities(){ #pragma endregion #pragma region Warrior Ability 1 (Battlecry) Warrior::ability1.action= - [&](vf2d pos={}){ - game->AddEffect(std::make_unique(GetPos(),0.1,AnimationState::BATTLECRY_EFFECT,upperLevel,1,0.3)); - AddBuff(BuffType::ATTACK_UP,10,0.1); - AddBuff(BuffType::DAMAGE_REDUCTION,10,0.1); + [](Player*p,vf2d pos={}){ + game->AddEffect(std::make_unique(p->GetPos(),0.1,AnimationState::BATTLECRY_EFFECT,p->upperLevel,1,0.3)); + p->AddBuff(BuffType::ATTACK_UP,10,0.1); + p->AddBuff(BuffType::DAMAGE_REDUCTION,10,0.1); for(Monster&m:MONSTER_LIST){ - if(m.GetSizeMult()<=1&&geom2d::overlaps(geom2d::circle(GetPos(),12*3.5),geom2d::circle(m.GetPos(),m.GetSizeMult()*12))){ + if(m.GetSizeMult()<=1&&geom2d::overlaps(geom2d::circle(p->GetPos(),12*3.5),geom2d::circle(m.GetPos(),m.GetSizeMult()*12))){ m.AddBuff(BuffType::SLOWDOWN,5,0.3); } } @@ -96,41 +96,41 @@ void Warrior::InitializeClassAbilities(){ #pragma endregion #pragma region Warrior Ability 2 (Ground Slam) Warrior::ability2.action= - [&](vf2d pos={}){ - Spin(GROUND_SLAM_SPIN_TIME,14*PI); - iframe_time=GROUND_SLAM_SPIN_TIME+0.1; + [](Player*p,vf2d pos={}){ + p->Spin(GROUND_SLAM_SPIN_TIME,14*PI); + p->iframe_time=GROUND_SLAM_SPIN_TIME+0.1; return true; }; #pragma endregion #pragma region Warrior Ability 3 (Sonic Slash) Warrior::ability3.action= - [&](vf2d pos={}){ - SetState(State::SWING_SONIC_SWORD); - AddBuff(BuffType::SLOWDOWN,0.5,1); + [](Player*p,vf2d pos={}){ + p->SetState(State::SWING_SONIC_SWORD); + p->AddBuff(BuffType::SLOWDOWN,0.5,1); vf2d bulletVel={}; - switch(GetFacingDirection()){ + switch(p->GetFacingDirection()){ case UP:{ - vel.y=70; + p->vel.y=70; bulletVel.y=-400; - UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N,WARRIOR); + p->UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N,WARRIOR); }break; case LEFT:{ - vel.x=70; + p->vel.x=70; bulletVel.x=-400; - UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W,WARRIOR); + p->UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W,WARRIOR); }break; case RIGHT:{ - vel.x=-70; + p->vel.x=-70; bulletVel.x=400; - UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E,WARRIOR); + p->UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E,WARRIOR); }break; case DOWN:{ - vel.y=-70; + p->vel.y=-70; bulletVel.y=400; - UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S,WARRIOR); + p->UpdateAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S,WARRIOR); }break; } - BULLET_LIST.push_back(std::make_unique(GetPos(),bulletVel,30,GetAttack()*8,AnimationState::SONICSLASH,upperLevel,true,2.25,true,true,WHITE)); + BULLET_LIST.push_back(std::make_unique(p->GetPos(),bulletVel,30,p->GetAttack()*8,AnimationState::SONICSLASH,p->upperLevel,true,2.25,true,true,WHITE)); game->SetupWorldShake(0.5); return true; }; diff --git a/Crawler/Witch.cpp b/Crawler/Witch.cpp index 0f5d9e20..813aa601 100644 --- a/Crawler/Witch.cpp +++ b/Crawler/Witch.cpp @@ -37,25 +37,25 @@ bool Witch::AutoAttack(){ void Witch::InitializeClassAbilities(){ #pragma region Witch Right-click Ability (???) Witch::rightClickAbility.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Witch Ability 1 (???) Witch::ability1.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Witch Ability 2 (???) Witch::ability2.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion #pragma region Witch Ability 3 (???) Witch::ability3.action= - [&](vf2d pos={}){ + [](Player*p,vf2d pos={}){ return false; }; #pragma endregion diff --git a/Crawler/Wizard.cpp b/Crawler/Wizard.cpp index 69077baf..2f9dfa67 100644 --- a/Crawler/Wizard.cpp +++ b/Crawler/Wizard.cpp @@ -75,53 +75,54 @@ bool Wizard::AutoAttack(){ void Wizard::InitializeClassAbilities(){ #pragma region Wizard Right-click Ability (Teleport) Wizard::rightClickAbility.action= - [&](vf2d pos={}){ - float pointMouseDirection=atan2(game->GetWorldMousePos().y-GetPos().y,game->GetWorldMousePos().x-GetPos().x); + [](Player*p,vf2d pos={}){ + if(p->GetState()==State::CASTING)return false; + float pointMouseDirection=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x); vf2d pointTowardsMouse={cos(pointMouseDirection),sin(pointMouseDirection)}; - float dist=std::clamp(geom2d::line{GetPos(),game->GetWorldMousePos()}.length(),0.f,6.5f*24); + float dist=std::clamp(geom2d::line{p->GetPos(),game->GetWorldMousePos()}.length(),0.f,6.5f*24); if(dist<12)return false; - vf2d teleportPoint=GetPos()+pointTowardsMouse*dist; - while(dist>0&&game->HasTileCollision(game->GetCurrentLevel(),teleportPoint)&&CanPathfindTo(GetPos(),teleportPoint)){ + vf2d teleportPoint=p->GetPos()+pointTowardsMouse*dist; + while(dist>0&&game->HasTileCollision(game->GetCurrentLevel(),teleportPoint)&&p->CanPathfindTo(p->GetPos(),teleportPoint)){ dist-=24; - teleportPoint=GetPos()+pointTowardsMouse*dist; + teleportPoint=p->GetPos()+pointTowardsMouse*dist; } - if(dist>0&&CanPathfindTo(GetPos(),teleportPoint)){ - SetState(State::TELEPORT); - teleportAnimationTimer=0.35; - teleportTarget=teleportPoint; - teleportStartPosition=GetPos(); - iframe_time=0.35; + if(dist>0&&p->CanPathfindTo(p->GetPos(),teleportPoint)){ + p->SetState(State::TELEPORT); + p->teleportAnimationTimer=0.35; + p->teleportTarget=teleportPoint; + p->teleportStartPosition=p->GetPos(); + p->iframe_time=0.35; for(int i=0;i<16;i++){ - game->AddEffect(std::make_unique(GetPos()+vf2d{(rand()%160-80)/10.f,(rand()%160-80)/10.f},float(rand()%300)/1000,AnimationState::DOT_PARTICLE,upperLevel,0.3,0.2,vf2d{float(rand()%1000-500)/100,float(rand()%1000-500)/100},BLACK)); + game->AddEffect(std::make_unique(p->GetPos()+vf2d{(rand()%160-80)/10.f,(rand()%160-80)/10.f},float(rand()%300)/1000,AnimationState::DOT_PARTICLE,p->upperLevel,0.3,0.2,vf2d{float(rand()%1000-500)/100,float(rand()%1000-500)/100},BLACK)); } return true; } else { - notificationDisplay={"Cannot Teleport to that location!",0.5}; + p->notificationDisplay={"Cannot Teleport to that location!",0.5}; return false; } }; #pragma endregion #pragma region Wizard Ability 1 (Fire Bolt) Wizard::ability1.action= - [&](vf2d pos={}){ - float angleToCursor=atan2(game->GetWorldMousePos().y-GetPos().y,game->GetWorldMousePos().x-GetPos().x); - BULLET_LIST.push_back(std::make_unique(FireBolt(GetPos(),{cos(angleToCursor)*275,sin(angleToCursor)*275},12,GetAttack(),upperLevel,true,{240,120,60}))); + [](Player*p,vf2d pos={}){ + float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x); + BULLET_LIST.push_back(std::make_unique(FireBolt(p->GetPos(),{cos(angleToCursor)*275,sin(angleToCursor)*275},12,p->GetAttack(),p->upperLevel,true,{240,120,60}))); return true; }; #pragma endregion #pragma region Wizard Ability 2 (Lightning Bolt) Wizard::ability2.action= - [&](vf2d pos={}){ - float angleToCursor=atan2(game->GetWorldMousePos().y-GetPos().y,game->GetWorldMousePos().x-GetPos().x); - BULLET_LIST.push_back(std::make_unique(LightningBolt(GetPos(),{cos(angleToCursor)*230,sin(angleToCursor)*230},12,GetAttack()*4,upperLevel,true,WHITE))); + [](Player*p,vf2d pos={}){ + float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x); + BULLET_LIST.push_back(std::make_unique(LightningBolt(p->GetPos(),{cos(angleToCursor)*230,sin(angleToCursor)*230},12,p->GetAttack()*4,p->upperLevel,true,WHITE))); return true; }; #pragma endregion #pragma region Wizard Ability 3 (Meteor) Wizard::ability3.action= - [&](vf2d pos={}){ - CastSpell(Wizard::ability3); - game->AddEffect(std::make_unique(pos,3,AnimationState::METEOR,OnUpperLevel(),vf2d{1,1},2)); + [](Player*p,vf2d pos={}){ + p->CastSpell(Wizard::ability3); + game->AddEffect(std::make_unique(pos,3,AnimationState::METEOR,p->OnUpperLevel(),vf2d{1,1},2)); return true; }; #pragma endregion From fad343bde3ebe1860785a793d7315e245a748714 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 23 Jul 2023 06:12:19 -0500 Subject: [PATCH 2/8] Refactor Animation loading to reduce repetition. --- Crawler/Animation.cpp | 244 ++++++++++++--------------------------- Crawler/Animation.h | 10 +- Crawler/Crawler.cpp | 1 + Crawler/Crawler.h | 2 +- Crawler/Version.h | 2 +- Crawler/assets/arrow.png | Bin 0 -> 670 bytes 6 files changed, 86 insertions(+), 173 deletions(-) create mode 100644 Crawler/assets/arrow.png diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp index 52c0b1af..8961bc4d 100644 --- a/Crawler/Animation.cpp +++ b/Crawler/Animation.cpp @@ -6,43 +6,62 @@ INCLUDE_game INCLUDE_ANIMATION_DATA void sig::Animation::InitializeAnimations(){ + + auto CreateStillAnimation=[&](Renderable&img,vf2d size,AnimationState state,AnimationData data={}){ + Animate2D::FrameSequence anim(data.frameDuration,data.style); + anim.AddFrame({&img,{{0,0},size}}); + ANIMATION_DATA[state]=anim; + }; + + auto CreateHorizontalAnimationSequence=[&](Renderable&img,int frameCount,vf2d size,AnimationState state,AnimationData data={}){ + Animate2D::FrameSequence anim(data.frameDuration,data.style); + for(int i=0;iGFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_S]=pl_warrior_walk_s; - Animate2D::FrameSequence pl_warrior_walk_e{0.2}; - pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_E]=pl_warrior_walk_e; - Animate2D::FrameSequence pl_warrior_walk_w{0.2}; - pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_W]=pl_warrior_walk_w; - Animate2D::FrameSequence pl_warrior_walk_n{0.2}; - pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_N]=pl_warrior_walk_n; - Animate2D::FrameSequence pl_warrior_idle_s; - pl_warrior_idle_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_S]=pl_warrior_idle_s; - Animate2D::FrameSequence pl_warrior_idle_e; - pl_warrior_idle_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_E]=pl_warrior_idle_e; - Animate2D::FrameSequence pl_warrior_idle_w; - pl_warrior_idle_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_W]=pl_warrior_idle_w; - Animate2D::FrameSequence pl_warrior_idle_n; - pl_warrior_idle_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_N]=pl_warrior_idle_n; + SetupClassWalkIdleAnimations(game->GFX_Warrior_Sheet,AnimationState::WARRIOR_WALK_S); Animate2D::FrameSequence pl_warrior_swing_s(0.05),pl_warrior_swing_n(0.05),pl_warrior_swing_e(0.05),pl_warrior_swing_w(0.05); Animate2D::FrameSequence pl_warrior_sonic_swing_s(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_n(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_e(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_w(0.1,Animate2D::Style::OneShot); for (int i=0;i<4;i++){ @@ -71,80 +90,10 @@ void sig::Animation::InitializeAnimations(){ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_W]=pl_warrior_sonic_swing_w; //Ranger animations - Animate2D::FrameSequence pl_ranger_walk_s{0.2}; - pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_S]=pl_ranger_walk_s; - Animate2D::FrameSequence pl_ranger_walk_e{0.2}; - pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_E]=pl_ranger_walk_e; - Animate2D::FrameSequence pl_ranger_walk_w{0.2}; - pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_W]=pl_ranger_walk_w; - Animate2D::FrameSequence pl_ranger_walk_n{0.2}; - pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_N]=pl_ranger_walk_n; - Animate2D::FrameSequence pl_ranger_idle_s; - pl_ranger_idle_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_S]=pl_ranger_idle_s; - Animate2D::FrameSequence pl_ranger_idle_e; - pl_ranger_idle_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_E]=pl_ranger_idle_e; - Animate2D::FrameSequence pl_ranger_idle_w; - pl_ranger_idle_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_W]=pl_ranger_idle_w; - Animate2D::FrameSequence pl_ranger_idle_n; - pl_ranger_idle_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_N]=pl_ranger_idle_n; + SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,AnimationState::RANGER_WALK_S); //Wizard animations - Animate2D::FrameSequence pl_wizard_walk_s{0.2}; - pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_S]=pl_wizard_walk_s; - Animate2D::FrameSequence pl_wizard_walk_e{0.2}; - pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_E]=pl_wizard_walk_e; - Animate2D::FrameSequence pl_wizard_walk_w{0.2}; - pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_W]=pl_wizard_walk_w; - Animate2D::FrameSequence pl_wizard_walk_n{0.2}; - pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_N]=pl_wizard_walk_n; - Animate2D::FrameSequence pl_wizard_idle_s; - pl_wizard_idle_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_S]=pl_wizard_idle_s; - Animate2D::FrameSequence pl_wizard_idle_e; - pl_wizard_idle_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_E]=pl_wizard_idle_e; - Animate2D::FrameSequence pl_wizard_idle_w; - pl_wizard_idle_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_W]=pl_wizard_idle_w; - Animate2D::FrameSequence pl_wizard_idle_n; - pl_wizard_idle_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_N]=pl_wizard_idle_n; + SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,AnimationState::WIZARD_WALK_S); Animate2D::FrameSequence pl_wizard_idle_attack_s; pl_wizard_idle_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_S]=pl_wizard_idle_attack_s; @@ -226,81 +175,38 @@ void sig::Animation::InitializeAnimations(){ ANIMATION_DATA[AnimationState(AnimationState::GREEN_SLIME_IDLE+state+slime*5)]=anim; } } - Animate2D::FrameSequence effect_groundslam_back(0.02f,Animate2D::Style::OneShot),effect_groundslam_front(0.02f,Animate2D::Style::OneShot); - for(int i=0;i<5;i++){ - effect_groundslam_back.AddFrame({&game->GFX_Effect_GroundSlam_Back,{{i*64,0},{64,64}}}); - effect_groundslam_front.AddFrame({&game->GFX_Effect_GroundSlam_Front,{{i*64,0},{64,64}}}); - } - ANIMATION_DATA[AnimationState::GROUND_SLAM_ATTACK_BACK]=effect_groundslam_back; - ANIMATION_DATA[AnimationState::GROUND_SLAM_ATTACK_FRONT]=effect_groundslam_front; - Animate2D::FrameSequence battlecry_effect(0.02f,Animate2D::Style::OneShot); - for(int i=0;i<5;i++){ - battlecry_effect.AddFrame({&game->GFX_Battlecry_Effect,{{i*84,0},{84,84}}}); - } - ANIMATION_DATA[AnimationState::BATTLECRY_EFFECT]=battlecry_effect; - Animate2D::FrameSequence sonicslash_effect(0.04f,Animate2D::Style::OneShot); - for(int i=0;i<4;i++){ - sonicslash_effect.AddFrame({&game->GFX_SonicSlash,{{i*60,0},{60,60}}}); - } - ANIMATION_DATA[AnimationState::SONICSLASH]=sonicslash_effect; - Animate2D::FrameSequence energy_bolt; - energy_bolt.AddFrame({&game->GFX_EnergyBolt,{{0,0},{24,24}}}); - ANIMATION_DATA[AnimationState::ENERGY_BOLT]=energy_bolt; + CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Back,5,{64,64},AnimationState::GROUND_SLAM_ATTACK_BACK,{0.02,Animate2D::Style::OneShot}); + CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Front,5,{64,64},AnimationState::GROUND_SLAM_ATTACK_FRONT,{0.02,Animate2D::Style::OneShot}); + CreateHorizontalAnimationSequence(game->GFX_Battlecry_Effect,5,{84,84},AnimationState::BATTLECRY_EFFECT,{0.02,Animate2D::Style::OneShot}); + CreateHorizontalAnimationSequence(game->GFX_SonicSlash,4,{60,60},AnimationState::SONICSLASH,{0.04,Animate2D::Style::OneShot}); - Animate2D::FrameSequence energy_particle; - for(int i=0;i<3;i++){ - energy_particle.AddFrame({&game->GFX_EnergyParticle,{{i*3,0},{3,3}}}); - } - ANIMATION_DATA[AnimationState::ENERGY_PARTICLE]=energy_particle; + CreateStillAnimation(game->GFX_EnergyBolt,{24,24},AnimationState::ENERGY_BOLT); - Animate2D::FrameSequence splash_animation(0.05); - for(int i=0;i<5;i++){ - splash_animation.AddFrame({&game->GFX_Splash_Effect,{{i*24,0},{24,24}}}); - } - ANIMATION_DATA[AnimationState::SPLASH_EFFECT]=splash_animation; + CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},AnimationState::ENERGY_PARTICLE); - Animate2D::FrameSequence dot_particle; - dot_particle.AddFrame({&game->GFX_BulletCircle,{{0,0},{3,3}}}); - ANIMATION_DATA[AnimationState::DOT_PARTICLE]=dot_particle; + CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::LIGHTNING_BOLT,{0.05}); + + CreateStillAnimation(game->GFX_BulletCircle,{3,3},AnimationState::DOT_PARTICLE); - Animate2D::FrameSequence lightningbolt(0.03,Animate2D::Style::PingPong); - for(int i=0;i<5;i++){ - lightningbolt.AddFrame({&game->GFX_LightningBolt,{{i*24,0},{24,24}}}); - } - ANIMATION_DATA[AnimationState::LIGHTNING_BOLT]=lightningbolt; + CreateHorizontalAnimationSequence(game->GFX_LightningBolt,5,{24,24},AnimationState::LIGHTNING_BOLT,{0.03,Animate2D::Style::PingPong}); - Animate2D::FrameSequence lightningboltpart1; - lightningboltpart1.AddFrame({&game->GFX_LightningBoltParticle1,{{0,0},{5,5}}}); - ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE1]=lightningboltpart1; - Animate2D::FrameSequence lightningboltpart2; - lightningboltpart2.AddFrame({&game->GFX_LightningBoltParticle2,{{0,0},{5,5}}}); - ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE2]=lightningboltpart2; - Animate2D::FrameSequence lightningboltpart3; - lightningboltpart3.AddFrame({&game->GFX_LightningBoltParticle3,{{0,0},{5,5}}}); - ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE3]=lightningboltpart3; - Animate2D::FrameSequence lightningboltpart4; - lightningboltpart4.AddFrame({&game->GFX_LightningBoltParticle4,{{0,0},{5,5}}}); - ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE4]=lightningboltpart4; + CreateStillAnimation(game->GFX_LightningBoltParticle1,{5,5},AnimationState::LIGHTNING_BOLT_PARTICLE1); + CreateStillAnimation(game->GFX_LightningBoltParticle2,{5,5},AnimationState::LIGHTNING_BOLT_PARTICLE2); + CreateStillAnimation(game->GFX_LightningBoltParticle3,{5,5},AnimationState::LIGHTNING_BOLT_PARTICLE3); + CreateStillAnimation(game->GFX_LightningBoltParticle4,{5,5},AnimationState::LIGHTNING_BOLT_PARTICLE4); - Animate2D::FrameSequence chainlightning; - chainlightning.AddFrame({&game->GFX_ChainLightning,{{0,0},{1,9}}}); - ANIMATION_DATA[AnimationState::CHAIN_LIGHTNING]=chainlightning; + CreateStillAnimation(game->GFX_ChainLightning,{1,9},AnimationState::CHAIN_LIGHTNING); - Animate2D::FrameSequence lightningsplash; - for(int i=0;i<5;i++){ - lightningsplash.AddFrame({&game->GFX_LightningSplash,{{i*24,0},{24,24}}}); - } - ANIMATION_DATA[AnimationState::LIGHTNING_SPLASH]=lightningsplash; + CreateHorizontalAnimationSequence(game->GFX_LightningSplash,5,{24,24},AnimationState::LIGHTNING_SPLASH); - Animate2D::FrameSequence meteor; - meteor.AddFrame({&game->GFX_Meteor,{{0,0},{192,192}}}); - ANIMATION_DATA[AnimationState::METEOR]=meteor; + CreateStillAnimation(game->GFX_Meteor,{192,192},AnimationState::METEOR); for(int i=0;i<5;i++){ Animate2D::FrameSequence firering; firering.AddFrame({&game->GFX_LightningSplash,{{i*24,0},{24,24}}}); ANIMATION_DATA[AnimationState(AnimationState::FIRE_RING1+i)]=firering; } + CreateStillAnimation(game->GFX_Arrow,{24,24},AnimationState::ARROW); } void sig::Animation::SetupPlayerAnimations(){ diff --git a/Crawler/Animation.h b/Crawler/Animation.h index 9b0fff55..ec908283 100644 --- a/Crawler/Animation.h +++ b/Crawler/Animation.h @@ -1,4 +1,5 @@ #pragma once +#include "olcUTIL_Animate2D.h" enum AnimationState{ WARRIOR_WALK_S,WARRIOR_WALK_E,WARRIOR_WALK_N,WARRIOR_WALK_W, @@ -21,7 +22,7 @@ enum AnimationState{ LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4, CHAIN_LIGHTNING,LIGHTNING_SPLASH, WIZARD_CAST_S,WIZARD_CAST_N,WIZARD_CAST_E,WIZARD_CAST_W,METEOR, - FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5, + FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW }; namespace sig{ @@ -30,4 +31,9 @@ namespace sig{ static void InitializeAnimations(); static void SetupPlayerAnimations(); }; -} \ No newline at end of file +} + +struct AnimationData{ + float frameDuration=0.1f; + Animate2D::Style style=Animate2D::Style::Repeat; +}; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 867d12e0..935874dd 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -79,6 +79,7 @@ bool Crawler::OnUserCreate(){ GFX_ChainLightning.Load("assets/chain_lightning.png"); GFX_LightningSplash.Load("assets/lightning_splash_effect.png"); GFX_Meteor.Load("assets/meteor.png"); + GFX_Arrow.Load("assets/arrow.png"); //Animations sig::Animation::InitializeAnimations(); diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index 291c8fb5..bd15d938 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -27,7 +27,7 @@ class Crawler : public olc::PixelGameEngine GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle, GFX_Splash_Effect,GFX_LightningBolt,GFX_LightningBoltParticle1, GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4, - GFX_ChainLightning,GFX_LightningSplash,GFX_Meteor; + GFX_ChainLightning,GFX_LightningSplash,GFX_Meteor,GFX_Arrow; public: Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt,GFX_Circle; Pathfinding pathfinder; diff --git a/Crawler/Version.h b/Crawler/Version.h index 33c6147c..3efcae18 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 759 +#define VERSION_BUILD 769 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/arrow.png b/Crawler/assets/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..88e746f4939030ec54f0179daec8da2d4536425e GIT binary patch literal 670 zcmV;P0%84$P)EX>4Tx04R}tkv&MmKpe$iQ>7{u2MdZgWT;LS#4jABibb$c+6t{Ym|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx6k5c1aNLh~_a1le0HI!Hs@X9PsG4OY zV^J}aT@?eb2w(u+2xD4erXEi%rr|lh?&0I>U4&4rtTK|Hf* z>74h8L#!w%#OK6g23?T&k?XR{Z=4Gb3p_Jqq?7Z+A!4!6#&R38qM;H`5r-93qkJLb zvch?bvs$jQ<~{ifgE?&_#dVs)h+zqFBp^aY6(y8mAwsK0iisrcM?L&Qjz2*znOr3> zax9<%6_Voz|AXJ%n)%5IHz^neI$v!2V+0870*#t&e;?a+;{@ zj20++-Q(R|?Y;ebrrF;Q(Q|Um)%?c@00006VoOIv08RkE06hQgnEe0%010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=LZ)FDjFrDJaGU302y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{004GLL_t(Y$75g^1*0H7Km9)g0|UeQ Date: Sun, 23 Jul 2023 08:13:40 -0500 Subject: [PATCH 3/8] Implemented Ranger auto attack plus animations. --- Crawler/Animation.cpp | 17 +++++++++++++- Crawler/Animation.h | 3 ++- Crawler/Arrow.cpp | 39 +++++++++++++++++++++++++++++++++ Crawler/Bullet.h | 9 ++++---- Crawler/BulletTypes.h | 11 ++++++++++ Crawler/Crawler.cpp | 12 ++++++++++ Crawler/Crawler.vcxproj | 1 + Crawler/Crawler.vcxproj.filters | 3 +++ Crawler/EnergyBolt.cpp | 3 ++- Crawler/FireBolt.cpp | 3 ++- Crawler/LightningBolt.cpp | 3 ++- Crawler/Player.h | 2 ++ Crawler/Ranger.cpp | 26 +++++++++++++++++++++- Crawler/State.h | 1 + Crawler/Version.h | 2 +- 15 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 Crawler/Arrow.cpp diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp index 8961bc4d..97ad6b15 100644 --- a/Crawler/Animation.cpp +++ b/Crawler/Animation.cpp @@ -91,6 +91,17 @@ void sig::Animation::InitializeAnimations(){ //Ranger animations SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,AnimationState::RANGER_WALK_S); + Animate2D::FrameSequence pl_ranger_shoot_s,pl_ranger_shoot_n,pl_ranger_shoot_e,pl_ranger_shoot_w; + for(int i=0;i<3;i++){ + pl_ranger_shoot_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,0}*24,{24,24}}}); + pl_ranger_shoot_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,1}*24,{24,24}}}); + pl_ranger_shoot_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,3}*24,{24,24}}}); + pl_ranger_shoot_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,2}*24,{24,24}}}); + } + ANIMATION_DATA[AnimationState::RANGER_SHOOT_S]=pl_ranger_shoot_s; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_N]=pl_ranger_shoot_n; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_E]=pl_ranger_shoot_e; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_W]=pl_ranger_shoot_w; //Wizard animations SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,AnimationState::WIZARD_WALK_S); @@ -184,7 +195,7 @@ void sig::Animation::InitializeAnimations(){ CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},AnimationState::ENERGY_PARTICLE); - CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::LIGHTNING_BOLT,{0.05}); + CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::SPLASH_EFFECT,{0.05}); CreateStillAnimation(game->GFX_BulletCircle,{3,3},AnimationState::DOT_PARTICLE); @@ -234,6 +245,10 @@ void sig::Animation::SetupPlayerAnimations(){ game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_E); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_S); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_W); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_S); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_N); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_W); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_E); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_N); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_E); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_S); diff --git a/Crawler/Animation.h b/Crawler/Animation.h index ec908283..29895d95 100644 --- a/Crawler/Animation.h +++ b/Crawler/Animation.h @@ -22,7 +22,8 @@ enum AnimationState{ LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4, CHAIN_LIGHTNING,LIGHTNING_SPLASH, WIZARD_CAST_S,WIZARD_CAST_N,WIZARD_CAST_E,WIZARD_CAST_W,METEOR, - FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW + FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW, + RANGER_SHOOT_S,RANGER_SHOOT_N,RANGER_SHOOT_E,RANGER_SHOOT_W, }; namespace sig{ diff --git a/Crawler/Arrow.cpp b/Crawler/Arrow.cpp new file mode 100644 index 00000000..8e7acb57 --- /dev/null +++ b/Crawler/Arrow.cpp @@ -0,0 +1,39 @@ +#include "BulletTypes.h" +#include "Effect.h" +#include "Crawler.h" +#include "DEFINES.h" +#include "utils.h" +#include "olcUTIL_Geometry2D.h" + +INCLUDE_game + +Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) + :finalDistance(geom2d::line(pos,targetPos).length()), + Bullet(pos,vel,radius,damage, + AnimationState::ARROW,upperLevel,false,INFINITE,true,friendly,col){} + +void Arrow::Update(float fElapsedTime){ + float speed=vel.mag(); + travelDistance+=speed*fElapsedTime; + vel.y+=acc*fElapsedTime; + if(!deactivated&&travelDistance>=finalDistance){ + deactivated=true; + fadeOutTime=0.2f; + } +} + +bool Arrow::PlayerHit(Player*player) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(std::make_unique(player->GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,player->GetSizeMult(),0.25)); + return false; +} + +bool Arrow::MonsterHit(Monster& monster) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(std::make_unique(monster.GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,monster.GetSizeMult(),0.25)); + return false; +} \ No newline at end of file diff --git a/Crawler/Bullet.h b/Crawler/Bullet.h index 25ce5023..df959d6d 100644 --- a/Crawler/Bullet.h +++ b/Crawler/Bullet.h @@ -7,8 +7,8 @@ struct Bullet{ friend class Crawler; - vf2d pos; vf2d vel; + vf2d pos; float radius; int damage; Pixel col; @@ -17,11 +17,12 @@ struct Bullet{ bool rotates=false; bool animated=false; bool deactivated=false; //A deactivated bullet no longer interacts with the world. It's just a visual. - float fadeOutTime=0; + float fadeOutTime=0; //Setting the fade out time causes the bullet's lifetime to be set to the fadeout time as well, as that's when the bullet's alpha will reach 0, so it dies. bool friendly=false; //Whether or not it's a player bullet or enemy bullet. bool upperLevel=false; -private: +protected: float fadeOutTimer=0; +private: void UpdateFadeTime(float fElapsedTime); public: Animate2D::Animationanimation; @@ -38,6 +39,6 @@ public: //Return true when the bullet should be destroyed. Return false to handle it otherwise (like deactivating it instead). You become responsible for getting rid of the bullet. virtual bool MonsterHit(Monster&monster); Animate2D::Frame GetFrame(); - void Draw(); + virtual void Draw(); bool OnUpperLevel(); }; \ No newline at end of file diff --git a/Crawler/BulletTypes.h b/Crawler/BulletTypes.h index f14d4e0d..f8443c46 100644 --- a/Crawler/BulletTypes.h +++ b/Crawler/BulletTypes.h @@ -1,5 +1,6 @@ #pragma once #include "Bullet.h" +#include "olcPixelGameEngine.h" struct EnergyBolt:public Bullet{ float lastParticleSpawn=0; @@ -23,4 +24,14 @@ struct LightningBolt:public Bullet{ void Update(float fElapsedTime)override; bool PlayerHit(Player*player)override; bool MonsterHit(Monster&monster)override; +}; + +struct Arrow:public Bullet{ + float travelDistance=0; + float finalDistance=0; + float acc=PI/2*250; + Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE); + void Update(float fElapsedTime)override; + bool PlayerHit(Player*player)override; + bool MonsterHit(Monster&monster)override; }; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 935874dd..5e16e755 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -182,11 +182,14 @@ void Crawler::HandleUserInput(float fElapsedTime){ std::string staircaseDirection=GetPlayerStaircaseDirection(); if(RightHeld()){ player->SetX(player->GetX()+fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.x=100; if(staircaseDirection=="RIGHT"){ player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=-60; } else if(staircaseDirection=="LEFT"){ player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=60; } player->SetFacingDirection(RIGHT); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -196,11 +199,14 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(LeftHeld()){ player->SetX(player->GetX()-fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.x=-100; if(staircaseDirection=="RIGHT"){ player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=60; } else if(staircaseDirection=="LEFT"){ player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=-60; } if(setIdleAnimation){ player->SetFacingDirection(LEFT); @@ -212,6 +218,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(UpHeld()){ player->SetY(player->GetY()-fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.y=-100*fElapsedTime; if(setIdleAnimation){ player->SetFacingDirection(UP); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -222,6 +229,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(DownHeld()){ player->SetY(player->GetY()+fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.y=100*fElapsedTime; if(setIdleAnimation){ player->SetFacingDirection(DOWN); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -233,6 +241,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(UpReleased()){ player->SetLastReleasedMovementKey(UP); + player->movementVelocity.y=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); @@ -247,6 +256,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(RightReleased()){ player->SetLastReleasedMovementKey(RIGHT); + player->movementVelocity.x=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(UpHeld()){ player->UpdateWalkingAnimation(UP); @@ -261,6 +271,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(LeftReleased()){ player->SetLastReleasedMovementKey(LEFT); + player->movementVelocity.x=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); @@ -275,6 +286,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(DownReleased()){ player->SetLastReleasedMovementKey(DOWN); + player->movementVelocity.y=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 14353092..7352a8a7 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -203,6 +203,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index ed9898bc..0d282523 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -191,6 +191,9 @@ Source Files\Effects + + Source Files\Bullet Types + diff --git a/Crawler/EnergyBolt.cpp b/Crawler/EnergyBolt.cpp index fe8f787d..30374f4c 100644 --- a/Crawler/EnergyBolt.cpp +++ b/Crawler/EnergyBolt.cpp @@ -7,7 +7,8 @@ INCLUDE_game EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) -:Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} +:Bullet(pos,vel,radius,damage, + AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void EnergyBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/FireBolt.cpp b/Crawler/FireBolt.cpp index 6ab437a5..277b5809 100644 --- a/Crawler/FireBolt.cpp +++ b/Crawler/FireBolt.cpp @@ -8,7 +8,8 @@ INCLUDE_game INCLUDE_MONSTER_LIST FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) - :Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} + :Bullet(pos,vel,radius,damage, + AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void FireBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp index b6430001..69cb861d 100644 --- a/Crawler/LightningBolt.cpp +++ b/Crawler/LightningBolt.cpp @@ -10,7 +10,8 @@ INCLUDE_MONSTER_LIST INCLUDE_EMITTER_LIST LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) - :Bullet(pos,vel,radius,damage,AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){} + :Bullet(pos,vel,radius,damage, + AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void LightningBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/Player.h b/Crawler/Player.h index 7ee1e4bf..74cd8f71 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -49,9 +49,11 @@ struct Player{ void AddAnimation(AnimationState state); std::vectorbuffList; CastInfo castInfo={"",0}; + vf2d movementVelocity={};//This tells us if the player is moving (mostly controlled by user input) since their velocity is not used for regular movement. protected: const float ATTACK_COOLDOWN=0.35f; const float MAGIC_ATTACK_COOLDOWN=0.85f; + const float ARROW_ATTACK_COOLDOWN=0.6f; void SetSwordSwingTimer(float val); void SetState(State newState); void SetFacingDirection(Key direction); diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 56833a13..e2744a3b 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -4,6 +4,7 @@ #include "Player.h" #include "Effect.h" #include "Crawler.h" +#include "BulletTypes.h" INCLUDE_MONSTER_LIST INCLUDE_BULLET_LIST @@ -28,12 +29,35 @@ AnimationState Ranger::walk_w=RANGER_WALK_W; SETUP_CLASS(Ranger) void Ranger::OnUpdate(float fElapsedTime){ - + if(GetState()==SHOOT_ARROW){ + if(attack_cooldown_timer<=ARROW_ATTACK_COOLDOWN-0.3){ + SetState(NORMAL); + } + } } bool Ranger::AutoAttack(){ + attack_cooldown_timer=ARROW_ATTACK_COOLDOWN; + geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos()); + vf2d extendedLine=pointTowardsCursor.upoint(1.1); + float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x); + BULLET_LIST.push_back(std::make_unique(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true))); + SetState(State::SHOOT_ARROW); + if(angleToCursor<=PI/4&&angleToCursor>-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_E); + } else + if(angleToCursor>=3*PI/4||angleToCursor<-3*PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_W); + } else + if(angleToCursor<=3*PI/4&&angleToCursor>PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_S); + } else + if(angleToCursor>=-3*PI/4&&angleToCursor<-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_N); + } return false; } + void Ranger::InitializeClassAbilities(){ #pragma region Ranger Right-click Ability (???) Ranger::rightClickAbility.action= diff --git a/Crawler/State.h b/Crawler/State.h index 1f73640d..4e253205 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -12,4 +12,5 @@ enum State{ PATH_AROUND, CASTING, PREP_CAST, + SHOOT_ARROW, }; \ No newline at end of file diff --git a/Crawler/Version.h b/Crawler/Version.h index 3efcae18..9a75624e 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 769 +#define VERSION_BUILD 803 #define stringify(a) stringify_(a) #define stringify_(a) #a From 82d58a6dd1feabcd5deabce0f6effd1eac29516c Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 23 Jul 2023 12:33:20 -0500 Subject: [PATCH 4/8] Fixed fElapsedTime bug going negative seemingly randomly. Thank std::chrono::library::that::is::way::too::annoying::to::use::and::apparently::is::not::ultra::accurate --- Crawler/Crawler.cpp | 10 +++++----- Crawler/DEFINES.h | 3 ++- Crawler/Player.cpp | 25 ++++++++++++++++++++----- Crawler/Ranger.cpp | 10 +++++----- Crawler/Version.h | 2 +- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 5e16e755..3a453bde 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -96,7 +96,7 @@ bool Crawler::OnUserCreate(){ } bool Crawler::OnUserUpdate(float fElapsedTime){ - fElapsedTime=std::min(1/60.f,fElapsedTime); + fElapsedTime=std::clamp(fElapsedTime,0.f,1/60.f); HandleUserInput(fElapsedTime); UpdateEffects(fElapsedTime); player->Update(fElapsedTime); @@ -727,16 +727,16 @@ void Crawler::RenderHud(){ player->GetAbility3(), player->GetAbility4(), }; - std::vectoractiveCooldowns; - std::copy_if(cooldowns.begin(),cooldowns.end(),std::back_inserter(activeCooldowns),[](Ability a){ + std::vectoractiveCooldowns{}; + std::copy_if(cooldowns.begin(),cooldowns.end(),std::back_inserter(activeCooldowns),[](Ability&a){ return a.cooldown>0; }); - std::sort(activeCooldowns.begin(),activeCooldowns.end(),[](Ability&a1,Ability&a2){ + std::sort(activeCooldowns.begin(),activeCooldowns.end(),[&](Ability&a1,Ability&a2){ return a1.cooldown0){ + if(a.cooldown>0.1){ FillRectDecal(vf2d{10,ScreenHeight()-22.f}-vf2d{0,float(offset)},{64,6},BLACK); FillRectDecal(vf2d{11,ScreenHeight()-21.f}-vf2d{0,float(offset)},{62,4},DARK_GREY); GradientFillRectDecal(vf2d{10,ScreenHeight()-22.f}-vf2d{0,float(offset)},{(a.cooldown/a.COOLDOWN_TIME)*64,6},a.barColor1,a.barColor1,a.barColor2,a.barColor2); diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h index f39a61a4..1e5d5730 100644 --- a/Crawler/DEFINES.h +++ b/Crawler/DEFINES.h @@ -14,7 +14,8 @@ #define INFINITE 999999 #define SETUP_CLASS(class) \ -class::class(){} \ +class::class() \ + :Player::Player(){} \ class::class(Player*player) \ :Player::Player(player){} \ Class class::GetClass(){return cl;} \ diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index d41eb9a3..ae65932f 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -265,11 +265,26 @@ void Player::Update(float fElapsedTime){ animation.UpdateState(internal_animState,fElapsedTime); } } - rightClickAbility.cooldown=std::max(0.f,rightClickAbility.cooldown-fElapsedTime); - ability.cooldown=std::max(0.f,ability.cooldown-fElapsedTime); - ability2.cooldown=std::max(0.f,ability2.cooldown-fElapsedTime); - ability3.cooldown=std::max(0.f,ability3.cooldown-fElapsedTime); - ability4.cooldown=std::max(0.f,ability4.cooldown-fElapsedTime); + rightClickAbility.cooldown-=fElapsedTime; + ability.cooldown-=fElapsedTime; + ability2.cooldown-=fElapsedTime; + ability3.cooldown-=fElapsedTime; + ability4.cooldown-=fElapsedTime; + if(rightClickAbility.cooldown<0){ + rightClickAbility.cooldown=0; + } + if(ability.cooldown<0){ + ability.cooldown=0; + } + if(ability2.cooldown<0){ + ability2.cooldown=0; + } + if(ability3.cooldown<0){ + ability3.cooldown=0; + } + if(ability4.cooldown<0){ + ability4.cooldown=0; + } for(Monster&m:MONSTER_LIST){ if(iframe_time==0&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ if(m.IsAlive()){ diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index e2744a3b..52b3a40c 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -12,11 +12,11 @@ INCLUDE_game std::string Ranger::name="Ranger"; Class Ranger::cl=RANGER; -Ability Ranger::rightClickAbility={"Retreat",7,0,VERY_DARK_BLUE,DARK_BLUE}; -Ability Ranger::ability1={"Rapid Fire",12,35}; -Ability Ranger::ability2={"Charged Shot",15,40}; -Ability Ranger::ability3={"Multishot",25,50}; -Ability Ranger::ability4={"???",0,0}; +Ability Ranger::rightClickAbility=Ability("Retreat",7,0,VERY_DARK_BLUE,DARK_BLUE); +Ability Ranger::ability1=Ability("Rapid Fire",12,35); +Ability Ranger::ability2=Ability("Charged Shot",15,40); +Ability Ranger::ability3=Ability("Multishot",25,50); +Ability Ranger::ability4=Ability("???",0,0); AnimationState Ranger::idle_n=RANGER_IDLE_N; AnimationState Ranger::idle_e=RANGER_IDLE_E; AnimationState Ranger::idle_s=RANGER_IDLE_S; diff --git a/Crawler/Version.h b/Crawler/Version.h index 9a75624e..5bafc01a 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 803 +#define VERSION_BUILD 810 #define stringify(a) stringify_(a) #define stringify_(a) #a From 8685e3b5ef78a4a0b8b4f119895f9b989e4ec0ec Mon Sep 17 00:00:00 2001 From: Nic0Nic0Nii Date: Mon, 24 Jul 2023 20:58:29 +0000 Subject: [PATCH 5/8] Retreat dash back code completed Co-authored-by: sigonasr2 --- Crawler/Crawler.cpp | 19 +++++++++++-------- Crawler/Player.cpp | 4 ++++ Crawler/Player.h | 11 ++++++++++- Crawler/Ranger.cpp | 29 ++++++++++++++++++++++++++++- Crawler/State.h | 1 + 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 3a453bde..7ded8558 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -569,15 +569,18 @@ void Crawler::RenderWorld(float fElapsedTime){ } vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult()); vf2d playerPosition=player->GetPos(); - #define RENDER_PLAYER \ - if(player->teleportAnimationTimer>0){ \ - playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3)); \ - playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); \ - view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); \ - } else {view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);} + auto RenderPlayer=[&](){ + if(player->teleportAnimationTimer>0){ + playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3)); + playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); + view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); + } else { + view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); + } + } //define end if(!player->upperLevel){ - RENDER_PLAYER + RenderPlayer(); } if(player->GetState()==State::BLOCK){ view.DrawDecal(player->GetPos()-vf2d{12,12},GFX_BLOCK_BUBBLE.Decal()); @@ -661,7 +664,7 @@ void Crawler::RenderWorld(float fElapsedTime){ m->Draw(); } if(player->upperLevel){ - RENDER_PLAYER + RenderPlayer(); } for(Monster*m:monstersAfterUpper){ m->Draw(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index ae65932f..77f3c29a 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -537,4 +537,8 @@ bool Player::CanPathfindTo(vf2d pos,vf2d targetPos,float range){ void Player::PrepareCast(Ability&ability){ castPrepAbility=&ability; SetState(State::PREP_CAST); +} + +void Player::SetVelocity(vf2d vel){ + this->vel=vel; } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 74cd8f71..8243267d 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -30,7 +30,6 @@ struct Player{ int mana=100,maxmana=mana; int atk=10; vf2d pos; - float friction=400; float z=0; float moveSpd=1.0f; float size=1.0f; @@ -66,6 +65,7 @@ protected: void SetZ(float z); //Returns true if the move was valid and successful. bool SetPos(vf2d pos); + float friction=400; float attack_cooldown_timer=0; float iframe_time=0; float teleportAnimationTimer=0; @@ -81,6 +81,15 @@ protected: Ability*castPrepAbility; void PrepareCast(Ability&ability); vf2d precastLocation={}; + 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::vectorghostPositions; public: Player(); //So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 52b3a40c..2b56e890 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -34,6 +34,25 @@ void Ranger::OnUpdate(float fElapsedTime){ SetState(NORMAL); } } + if(retreatTimer>0){ + SetZ(6*sin(PI/RETREAT_TIME*retreatTimer)); + retreatTimer-=fElapsedTime; + if(retreatTimer<=0){ + SetVelocity({}); + SetZ(0); + } + } + if(ghostRemoveTimer>0){ + ghostRemoveTimer-=fElapsedTime; + if(ghostRemoveTimer<=0){ + if(ghostPositions.size()>0){ + ghostPositions.erase(ghostPositions.begin()); + if(ghostPositions.size()>0){ + ghostRemoveTimer=RETREAT_GHOST_FRAME_DELAY; + } + } + } + } } bool Ranger::AutoAttack(){ @@ -62,7 +81,15 @@ void Ranger::InitializeClassAbilities(){ #pragma region Ranger Right-click Ability (???) Ranger::rightClickAbility.action= [](Player*p,vf2d pos={}){ - return false; + geom2d::line mouseDir{game->GetWorldMousePos(),p->GetPos()}; + float velocity=(0.5*-p->friction*p->RETREAT_TIME*p->RETREAT_TIME-p->RETREAT_DISTANCE)/-p->RETREAT_TIME; //Derived from kinetic motion formula. + p->SetVelocity(mouseDir.vector().norm()*velocity); + p->retreatTimer=p->RETREAT_TIME; + p->iframe_time=p->RETREAT_TIME; + p->ghostPositions.push_back(p->GetPos()); + p->ghostFrameTimer=p->RETREAT_GHOST_FRAME_DELAY; + p->ghostRemoveTimer=p->RETREAT_GHOST_FRAMES*p->RETREAT_GHOST_FRAME_DELAY; + return true; }; #pragma endregion #pragma region Ranger Ability 1 (???) diff --git a/Crawler/State.h b/Crawler/State.h index 4e253205..5cdcec7e 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -13,4 +13,5 @@ enum State{ CASTING, PREP_CAST, SHOOT_ARROW, + RETREAT, }; \ No newline at end of file From a8f83dfec8c48775e34eb32a8e42bec15c2c2211 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Mon, 24 Jul 2023 23:20:28 -0500 Subject: [PATCH 6/8] Added ghost fading images for retreat ability and facing direction implemented. --- Crawler/Crawler.cpp | 7 ++++++- Crawler/Player.cpp | 15 +++++++++++++++ Crawler/Player.h | 1 + Crawler/Ranger.cpp | 28 ++++++++++++++-------------- Crawler/Version.h | 2 +- Crawler/test | 3 +++ 6 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 Crawler/test diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 7ded8558..1d1b0424 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -570,6 +570,11 @@ void Crawler::RenderWorld(float fElapsedTime){ vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult()); vf2d playerPosition=player->GetPos(); auto RenderPlayer=[&](){ + int count=0; + for(vf2d&pos:player->ghostPositions){ + view.DrawPartialRotatedDecal(pos,player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,{0,0,0,uint8_t(float(count)/player->RETREAT_GHOST_FRAMES*255)}); + count++; + } if(player->teleportAnimationTimer>0){ playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3)); playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); @@ -577,7 +582,7 @@ void Crawler::RenderWorld(float fElapsedTime){ } else { view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); } - } + }; //define end if(!player->upperLevel){ RenderPlayer(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 77f3c29a..e7f5be5f 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -541,4 +541,19 @@ void Player::PrepareCast(Ability&ability){ void Player::SetVelocity(vf2d vel){ this->vel=vel; +} + +void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){ + if(targetDirection<=PI/4&&targetDirection>-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_E); + } else + if(targetDirection>=3*PI/4||targetDirection<-3*PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_W); + } else + if(targetDirection<=3*PI/4&&targetDirection>PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_S); + } else + if(targetDirection>=-3*PI/4&&targetDirection<-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_N); + } } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 8243267d..3681714c 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -152,6 +152,7 @@ public: virtual AnimationState&GetIdleWAnimation()=0; CastInfo&GetCastInfo(); + void SetAnimationBasedOnTargetingDirection(float targetDirection); }; struct Warrior:Player{ diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 2b56e890..423883b8 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -40,6 +40,7 @@ void Ranger::OnUpdate(float fElapsedTime){ if(retreatTimer<=0){ SetVelocity({}); SetZ(0); + SetState(State::NORMAL); } } if(ghostRemoveTimer>0){ @@ -53,27 +54,23 @@ void Ranger::OnUpdate(float fElapsedTime){ } } } + if(ghostFrameTimer>0){ + ghostFrameTimer-=fElapsedTime; + if(ghostFrameTimer<=0&&GetState()==State::RETREAT){ + ghostPositions.push_back(GetPos()+vf2d{0,-GetZ()}); + ghostFrameTimer=RETREAT_GHOST_FRAME_DELAY; + } + } } bool Ranger::AutoAttack(){ - attack_cooldown_timer=ARROW_ATTACK_COOLDOWN; geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos()); vf2d extendedLine=pointTowardsCursor.upoint(1.1); float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x); + attack_cooldown_timer=ARROW_ATTACK_COOLDOWN; BULLET_LIST.push_back(std::make_unique(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true))); SetState(State::SHOOT_ARROW); - if(angleToCursor<=PI/4&&angleToCursor>-PI/4){ - UpdateAnimation(AnimationState::RANGER_SHOOT_E); - } else - if(angleToCursor>=3*PI/4||angleToCursor<-3*PI/4){ - UpdateAnimation(AnimationState::RANGER_SHOOT_W); - } else - if(angleToCursor<=3*PI/4&&angleToCursor>PI/4){ - UpdateAnimation(AnimationState::RANGER_SHOOT_S); - } else - if(angleToCursor>=-3*PI/4&&angleToCursor<-PI/4){ - UpdateAnimation(AnimationState::RANGER_SHOOT_N); - } + SetAnimationBasedOnTargetingDirection(angleToCursor); return false; } @@ -86,9 +83,12 @@ void Ranger::InitializeClassAbilities(){ p->SetVelocity(mouseDir.vector().norm()*velocity); p->retreatTimer=p->RETREAT_TIME; p->iframe_time=p->RETREAT_TIME; - p->ghostPositions.push_back(p->GetPos()); + p->ghostPositions.push_back(p->GetPos()+vf2d{0,-p->GetZ()}); p->ghostFrameTimer=p->RETREAT_GHOST_FRAME_DELAY; p->ghostRemoveTimer=p->RETREAT_GHOST_FRAMES*p->RETREAT_GHOST_FRAME_DELAY; + float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x); + p->SetAnimationBasedOnTargetingDirection(angleToCursor); + p->SetState(State::RETREAT); return true; }; #pragma endregion diff --git a/Crawler/Version.h b/Crawler/Version.h index 5bafc01a..21917f3d 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 810 +#define VERSION_BUILD 828 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/test b/Crawler/test new file mode 100644 index 00000000..8bed73c2 --- /dev/null +++ b/Crawler/test @@ -0,0 +1,3 @@ +test 1 +test 2 +test 3 \ No newline at end of file From 4c43eb7757db75b1009d250576ed1e54619a9c0a Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Tue, 25 Jul 2023 00:03:28 -0500 Subject: [PATCH 7/8] Meteor shadow is now following the world~ --- Crawler/Meteor.cpp | 3 ++- Crawler/Version.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Crawler/Meteor.cpp b/Crawler/Meteor.cpp index 86cc2546..b7155251 100644 --- a/Crawler/Meteor.cpp +++ b/Crawler/Meteor.cpp @@ -33,8 +33,9 @@ bool Meteor::Update(float fElapsedTime){ void Meteor::Draw(){ if(lifetime>0){ vf2d scale=vf2d{192,64}/3.f*(startLifetime+1-lifetime)*0.25*size; + vf2d meteorOffset=vf2d{lifetime,0}*120; vf2d centerPoint=pos-vf2d{game->GFX_Circle.Sprite()->width*scale.x/2,game->GFX_Circle.Sprite()->height*scale.y/2}; - game->view.DrawDecal(centerPoint,game->GFX_Circle.Decal(),scale,{0,0,0,192}); + game->view.DrawDecal(centerPoint+meteorOffset,game->GFX_Circle.Decal(),scale,{0,0,0,192}); } vf2d meteorOffset=pos+vf2d{lifetime,-lifetime}*320-vf2d{0,GetFrame().GetSourceRect().size.y/4.f}*size; if(lifetime<=0){ diff --git a/Crawler/Version.h b/Crawler/Version.h index 21917f3d..f0fb0cd9 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 828 +#define VERSION_BUILD 832 #define stringify(a) stringify_(a) #define stringify_(a) #a From cf51ad539ce4331c06f07cbb5f1fd8dc62ec2126 Mon Sep 17 00:00:00 2001 From: Nic0Nic0Nii Date: Tue, 25 Jul 2023 20:32:29 +0000 Subject: [PATCH 8/8] Rapid Fire ranger ability implemented. Co-authored-by: sigonasr2 --- Crawler/Crawler.h | 5 ++--- Crawler/Player.cpp | 4 ++-- Crawler/Player.h | 4 ++++ Crawler/Ranger.cpp | 28 ++++++++++++++++++++++++---- Crawler/State.h | 1 + 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index bd15d938..45397d91 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -52,13 +52,12 @@ private: void InitializeClassAbilities(); public: Crawler(); - + bool OnUserCreate() override; + bool OnUserUpdate(float fElapsedTime) override; public: geom2d::rectNO_COLLISION={}; vi2d WORLD_SIZE={120,8}; TileTransformedView view; - bool OnUserCreate() override; - bool OnUserUpdate(float fElapsedTime) override; void InitializeLevel(std::string mapFile,MapName map); void LoadLevel(MapName map); void HandleUserInput(float fElapsedTime); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index e7f5be5f..a01e14d8 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -319,7 +319,7 @@ void Player::Update(float fElapsedTime){ } - auto AllowedToCast=[&](Ability&ability){return !ability.precastInfo.precastTargetingRequired;}; + auto AllowedToCast=[&](Ability&ability){return !ability.precastInfo.precastTargetingRequired&&GetState()!=State::ANIMATION_LOCK;}; //If pressed is set to false, uses held instead. auto CheckAndPerformAbility=[&](Ability&ability,HWButton key){ if(ability.name!="???"){ @@ -402,7 +402,7 @@ vf2d Player::GetVelocity(){ } bool Player::CanMove(){ - return state!=State::CASTING; + return state!=State::CASTING&&state!=State::ANIMATION_LOCK; } bool Player::HasIframes(){ diff --git a/Crawler/Player.h b/Crawler/Player.h index 3681714c..d8b6ba7d 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -90,6 +90,10 @@ protected: float ghostRemoveTimer=0; float retreatTimer=0; std::vectorghostPositions; + float rapidFireTimer=0; + int remainingRapidFireShots=0; + const float RAPID_FIRE_SHOOT_DELAY=0.1; + const int RAPID_FIRE_SHOOT_AMOUNT=4; public: Player(); //So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 423883b8..b836f822 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -61,6 +61,23 @@ void Ranger::OnUpdate(float fElapsedTime){ ghostFrameTimer=RETREAT_GHOST_FRAME_DELAY; } } + if(rapidFireTimer>0){ + rapidFireTimer-=fElapsedTime; + if(rapidFireTimer<=0){ + if(remainingRapidFireShots>0){ + remainingRapidFireShots--; + rapidFireTimer=RAPID_FIRE_SHOOT_DELAY; + geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos()); + vf2d extendedLine=pointTowardsCursor.upoint(1.1); + float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x); + attack_cooldown_timer=ARROW_ATTACK_COOLDOWN; + BULLET_LIST.push_back(std::make_unique(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true))); + SetAnimationBasedOnTargetingDirection(angleToCursor); + }else{ + SetState(State::NORMAL); + } + } + } } bool Ranger::AutoAttack(){ @@ -71,11 +88,11 @@ bool Ranger::AutoAttack(){ BULLET_LIST.push_back(std::make_unique(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true))); SetState(State::SHOOT_ARROW); SetAnimationBasedOnTargetingDirection(angleToCursor); - return false; + return true; } void Ranger::InitializeClassAbilities(){ - #pragma region Ranger Right-click Ability (???) + #pragma region Ranger Right-click Ability (Retreat) Ranger::rightClickAbility.action= [](Player*p,vf2d pos={}){ geom2d::line mouseDir{game->GetWorldMousePos(),p->GetPos()}; @@ -92,10 +109,13 @@ void Ranger::InitializeClassAbilities(){ return true; }; #pragma endregion - #pragma region Ranger Ability 1 (???) + #pragma region Ranger Ability 1 (Rapid Fire) Ranger::ability1.action= [](Player*p,vf2d pos={}){ - return false; + p->remainingRapidFireShots=p->RAPID_FIRE_SHOOT_AMOUNT; + p->rapidFireTimer=p->RAPID_FIRE_SHOOT_DELAY; + p->SetState(State::ANIMATION_LOCK); + return true; }; #pragma endregion #pragma region Ranger Ability 2 (???) diff --git a/Crawler/State.h b/Crawler/State.h index 5cdcec7e..3191179a 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -14,4 +14,5 @@ enum State{ PREP_CAST, SHOOT_ARROW, RETREAT, + ANIMATION_LOCK, }; \ No newline at end of file