diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 24ab80b0..515341d4 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -2360,7 +2360,7 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){ #endif zoomAdjustSpeed="Default Zoom Adjust Speed"_F; targetZoom=1.f; - game->view.SetZoom(1.2f,game->view.WorldToScreen(game->camera.GetViewPosition())); + game->view.SetZoom(0.95f,game->view.WorldToScreen(game->camera.GetViewPosition())); worldColor=WHITE; worldColorFunc=[&](vi2d pos){return game->worldColor;}; levelTime=0; diff --git a/Adventures in Lestoria/Animation.cpp b/Adventures in Lestoria/Animation.cpp index c4b86dd5..c2d57cb6 100644 --- a/Adventures in Lestoria/Animation.cpp +++ b/Adventures in Lestoria/Animation.cpp @@ -214,22 +214,31 @@ void sig::Animation::InitializeAnimations(){ //Thief animations. SetupClassWalkIdleAnimations(GFX["nico-thief.png"],"THIEF"); Animate2D::FrameSequence pl_thief_swing_s(0.05f),pl_thief_swing_n(0.05f),pl_thief_swing_e(0.05f),pl_thief_swing_w(0.05f); + Animate2D::FrameSequence pl_thief_deadlydash_s(0.1f,Animate2D::Style::Repeat),pl_thief_deadlydash_n(0.1f,Animate2D::Style::Repeat),pl_thief_deadlydash_e(0.1f,Animate2D::Style::Repeat),pl_thief_deadlydash_w(0.1f,Animate2D::Style::Repeat); for (int i=0;i<4;i++){ pl_thief_swing_s.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,0}*24,{24,24}}}); + pl_thief_deadlydash_s.AddFrame({&GFX["nico-thief.png"],{vi2d{i,4}*24,{24,24}}}); } for (int i=0;i<4;i++){ pl_thief_swing_n.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,1}*24,{24,24}}}); + pl_thief_deadlydash_n.AddFrame({&GFX["nico-thief.png"],{vi2d{i,5}*24,{24,24}}}); } for (int i=0;i<4;i++){ pl_thief_swing_w.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,2}*24,{24,24}}}); + pl_thief_deadlydash_w.AddFrame({&GFX["nico-thief.png"],{vi2d{i,6}*24,{24,24}}}); } for (int i=0;i<4;i++){ pl_thief_swing_e.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,3}*24,{24,24}}}); + pl_thief_deadlydash_e.AddFrame({&GFX["nico-thief.png"],{vi2d{i,7}*24,{24,24}}}); } ANIMATION_DATA["THIEF_SWINGSWORD_N"]=pl_thief_swing_n; ANIMATION_DATA["THIEF_SWINGSWORD_E"]=pl_thief_swing_e; ANIMATION_DATA["THIEF_SWINGSWORD_S"]=pl_thief_swing_s; ANIMATION_DATA["THIEF_SWINGSWORD_W"]=pl_thief_swing_w; + ANIMATION_DATA["THIEF_DEADLYDASH_N"]=pl_thief_deadlydash_n; + ANIMATION_DATA["THIEF_DEADLYDASH_E"]=pl_thief_deadlydash_e; + ANIMATION_DATA["THIEF_DEADLYDASH_S"]=pl_thief_deadlydash_s; + ANIMATION_DATA["THIEF_DEADLYDASH_W"]=pl_thief_deadlydash_w; CreateHorizontalAnimationSequence("ground-slam-attack-back.png",5,{64,64},{0.02f,Animate2D::Style::OneShot}); CreateHorizontalAnimationSequence("ground-slam-attack-front.png",5,{64,64},{0.02f,Animate2D::Style::OneShot}); diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index a7c149f8..2fc02d60 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -688,7 +688,7 @@ void Player::Update(float fElapsedTime){ 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)*"Ranger.Ability 1.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Ability 1.ArrowSpd"_F-PI/8*"Ranger.Ability 1.ArrowSpd"_F)}+movementVelocity/1.5f,12*"Ranger.Ability 1.ArrowRadius"_F/100,int(GetAttack()*"Ranger.Ability 1.DamageMult"_F),OnUpperLevel(),true))); - SetAnimationBasedOnTargetingDirection(angleToCursor); + SetAnimationBasedOnTargetingDirection("SHOOT",angleToCursor); rapidFireTimer=RAPID_FIRE_SHOOT_DELAY; }else{ SetState(State::NORMAL); @@ -731,7 +731,7 @@ vf2d Player::GetVelocity(){ } bool Player::CanMove(){ - return knockUpTimer==0.f&&state!=State::ANIMATION_LOCK&&(state!=State::CASTING||(castInfo.castTotalTime-castInfo.castTimer>0.2f)); + return knockUpTimer==0.f&&state!=State::ANIMATION_LOCK&&state!=State::DEADLYDASH&&(state!=State::CASTING||(castInfo.castTotalTime-castInfo.castTimer>0.2f)); } bool Player::CanAct(){ @@ -740,7 +740,7 @@ bool Player::CanAct(){ } const bool Player::CanAct(const Ability&ability){ - return knockUpTimer==0&&!ability.waitForRelease&&(ability.canCancelCast||state!=State::CASTING)&&state!=State::ANIMATION_LOCK&& + return knockUpTimer==0&&!ability.waitForRelease&&(ability.canCancelCast||state!=State::CASTING)&&state!=State::ANIMATION_LOCK&&state!=State::DEADLYDASH&& (GameState::STATE==GameState::states[States::GAME_RUN] ||GameState::STATE==GameState::states[States::GAME_HUB]&&!ability.itemAbility); } @@ -1022,57 +1022,30 @@ void Player::SetVelocity(vf2d vel){ this->vel=vel; } -void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){ +void Player::SetAnimationBasedOnTarget(const std::string_view animation_name,const vf2d&target){ + SetAnimationBasedOnTargetingDirection(animation_name,util::pointTo(GetPos(),target).polar().y); +} + +void Player::SetAnimationBasedOnTargetingDirection(const std::string_view animation_name,float targetDirection){ auto FacingEast=[&](){return targetDirection<=PI/4&&targetDirection>-PI/4;}; auto FacingWest=[&](){return targetDirection>=3*PI/4||targetDirection<-3*PI/4;}; auto FacingSouth=[&](){return targetDirection<=3*PI/4&&targetDirection>PI/4;}; - auto FacingNorth=[&](){return targetDirection>=-3*PI/4&&targetDirection<-PI/4;}; + + //Assume facing North. + char facingChar{'N'}; + + auto Capitalize=[](const std::string_view str){ + std::string newStr; + newStr.resize(str.length()); + for(int i=0;const char&c:str)newStr[i++]=toupper(c);\ + return newStr; + }; - switch(GetClass()){ - case Class::WARRIOR:{ - if(FacingNorth()){ - UpdateAnimation("WARRIOR_SWINGSWORD_N"); - }else - if(FacingSouth()){ - UpdateAnimation("WARRIOR_SWINGSWORD_S"); - }else - if(FacingWest()){ - UpdateAnimation("WARRIOR_SWINGSWORD_W"); - }else - if(FacingEast()){ - UpdateAnimation("WARRIOR_SWINGSWORD_E"); - } - }break; - case Class::RANGER: - case Class::TRAPPER:{ - if(FacingNorth()){ - UpdateAnimation("RANGER_SHOOT_N"); - }else - if(FacingSouth()){ - UpdateAnimation("RANGER_SHOOT_S"); - }else - if(FacingWest()){ - UpdateAnimation("RANGER_SHOOT_W"); - }else - if(FacingEast()){ - UpdateAnimation("RANGER_SHOOT_E"); - } - }break; - case Class::THIEF:{ - if(FacingNorth()){ - UpdateAnimation("THIEF_SWINGSWORD_N"); - }else - if(FacingSouth()){ - UpdateAnimation("THIEF_SWINGSWORD_S"); - }else - if(FacingWest()){ - UpdateAnimation("THIEF_SWINGSWORD_W"); - }else - if(FacingEast()){ - UpdateAnimation("THIEF_SWINGSWORD_E"); - } - }break; - } + if(FacingSouth())facingChar='S'; + if(FacingEast())facingChar='E'; + if(FacingWest())facingChar='W'; + + UpdateAnimation(std::format("{}_{}_{}",Capitalize(GetClassName()),animation_name,facingChar)); } void Player::ApplyIframes(float duration){ diff --git a/Adventures in Lestoria/Player.h b/Adventures in Lestoria/Player.h index c67d1aad..be33e1ea 100644 --- a/Adventures in Lestoria/Player.h +++ b/Adventures in Lestoria/Player.h @@ -232,7 +232,9 @@ public: void CheckEndZoneCollision(); CastInfo&GetCastInfo(); - void SetAnimationBasedOnTargetingDirection(float targetDirection); + //Provide the base animation name and this function does the rest. Ex. If you want WARRIOR_SWINGSWORD_S, use SWINGSWORD + void SetAnimationBasedOnTargetingDirection(const std::string_view animation_name,float targetDirection); + void SetAnimationBasedOnTarget(const std::string_view animation_name,const vf2d&target); void SetItem1UseFunc(Ability a); void SetItem2UseFunc(Ability a); diff --git a/Adventures in Lestoria/Ranger.cpp b/Adventures in Lestoria/Ranger.cpp index afca4f02..4cb1c6e8 100644 --- a/Adventures in Lestoria/Ranger.cpp +++ b/Adventures in Lestoria/Ranger.cpp @@ -74,7 +74,7 @@ bool Ranger::AutoAttack(){ CreateBullet(Arrow)(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity/1.5f,"Ranger.Auto Attack.Radius"_F,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),true)EndBullet; BULLET_LIST.back()->SetIsPlayerAutoAttackProjectile(); SetState(State::SHOOT_ARROW); - SetAnimationBasedOnTargetingDirection(angleToCursor); + SetAnimationBasedOnTargetingDirection("SHOOT",angleToCursor); SoundEffect::PlaySFX("Ranger.Auto Attack.Sound"_S,SoundEffect::CENTERED); return true; } @@ -92,7 +92,7 @@ void Ranger::InitializeClassAbilities(){ p->ghostFrameTimer=p->RETREAT_GHOST_FRAME_DELAY; p->ghostRemoveTimer=p->RETREAT_GHOST_FRAMES*p->RETREAT_GHOST_FRAME_DELAY; float angleToCursor=atan2(p->GetWorldAimingLocation(Player::USE_WALK_DIR).y-p->GetPos().y,p->GetWorldAimingLocation(Player::USE_WALK_DIR).x-p->GetPos().x); - p->SetAnimationBasedOnTargetingDirection(angleToCursor); + p->SetAnimationBasedOnTargetingDirection("IDLE",angleToCursor); p->SetState(State::RETREAT); SoundEffect::PlaySFX("Ranger.Right Click Ability.Sound"_S,SoundEffect::CENTERED); return true; @@ -117,7 +117,7 @@ void Ranger::InitializeClassAbilities(){ BULLET_LIST.push_back(std::make_unique(p->GetPos(),arrowVelocity*"Ranger.Ability 2.Speed"_F,12*"Ranger.Ability 2.Radius"_F/100,p->GetAttack()*"Ranger.Ability 2.DamageMult"_F,p->OnUpperLevel(),true)); p->SetState(State::SHOOT_ARROW); p->rangerShootAnimationTimer=0.3f; - p->SetAnimationBasedOnTargetingDirection(atan2(arrowVelocity.y,arrowVelocity.x)); + p->SetAnimationBasedOnTargetingDirection("SHOOT",atan2(arrowVelocity.y,arrowVelocity.x)); game->SetupWorldShake("Ranger.Ability 2.WorldShakeTime"_F); p->Knockback(-1.f*arrowVelocity.norm()*"Ranger.Ability 2.Knockback"_F); SoundEffect::PlaySFX("Ranger.Ability 2.Sound"_S,SoundEffect::CENTERED); @@ -144,7 +144,7 @@ void Ranger::InitializeClassAbilities(){ } p->rangerShootAnimationTimer=0.3f; p->SetState(State::SHOOT_ARROW); - p->SetAnimationBasedOnTargetingDirection(shootingAngle); + p->SetAnimationBasedOnTargetingDirection("SHOOT",shootingAngle); SoundEffect::PlaySFX("Ranger.Ability 3.Sound"_S,SoundEffect::CENTERED); return true; }; diff --git a/Adventures in Lestoria/State.h b/Adventures in Lestoria/State.h index 59ca8930..593f8996 100644 --- a/Adventures in Lestoria/State.h +++ b/Adventures in Lestoria/State.h @@ -58,5 +58,6 @@ namespace State{ FORCE_WALK, DEATH, ROLL, + DEADLYDASH, }; } \ No newline at end of file diff --git a/Adventures in Lestoria/Thief.cpp b/Adventures in Lestoria/Thief.cpp index c76e47a1..9ab2c250 100644 --- a/Adventures in Lestoria/Thief.cpp +++ b/Adventures in Lestoria/Thief.cpp @@ -84,11 +84,11 @@ bool Thief::AutoAttack(){ if(closest!=nullptr){ float dirToEnemy=geom2d::line(GetPos(),closest->GetPos()).vector().polar().y; targetDirection=dirToEnemy; - SetAnimationBasedOnTargetingDirection(dirToEnemy); + SetAnimationBasedOnTargetingDirection("SWINGSWORD",dirToEnemy); }else{ float dirToMouse=geom2d::line(GetPos(),GetWorldAimingLocation()).vector().polar().y; targetDirection=dirToMouse; - SetAnimationBasedOnTargetingDirection(dirToMouse); + SetAnimationBasedOnTargetingDirection("SWINGSWORD",dirToMouse); } attack_cooldown_timer=ATTACK_COOLDOWN-GetAttackRecoveryRateReduction(); @@ -130,7 +130,7 @@ void Thief::InitializeClassAbilities(){ const float daggerLifetime{"Thief.Ability 1.Dagger Range"_F/"Thief.Ability 1.Dagger Speed"_F}; CreateBullet(Bullet)(p->GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor}.cart(),"Thief.Ability 1.Dagger Radius"_F,p->GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",p->OnUpperLevel(),false,daggerLifetime,true,true)EndBullet; - p->SetAnimationBasedOnTargetingDirection(angleToCursor); + p->SetAnimationBasedOnTargetingDirection("IDLE",angleToCursor); p->SetState(State::RETREAT); SoundEffect::PlaySFX("Thief.Ability 1.Sound"_S,SoundEffect::CENTERED); return true; @@ -139,7 +139,11 @@ void Thief::InitializeClassAbilities(){ #pragma region Thief Ability 2 (Deadly Dash) Thief::ability2.action= [](Player*p,vf2d pos={}){ - game->AddEffect(std::make_unique(p->GetPos(),0.5f,0.5f,"shine.png",1.5f,vf2d{},WHITE,util::random(2*PI),PI/2,true)); + game->AddEffect(std::make_unique(p->GetPos()+vf2d{4.f,4.f},0.5f,0.5f,"shine.png",1.5f,vf2d{},WHITE,util::random(2*PI),PI/2,true)); + p->ApplyIframes("Thief.Ability 2.Initial Wait"_F+"Thief.Ability 2.Ending Wait"_F); + geom2d::line mouseDir{p->GetPos(),p->GetWorldAimingLocation()}; + p->SetAnimationBasedOnTargetingDirection("DEADLYDASH",mouseDir.vector().polar().y); + p->SetState(State::DEADLYDASH); return true; }; #pragma endregion diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 7a6b65c8..4740ae7b 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 3 -#define VERSION_BUILD 10097 +#define VERSION_BUILD 10109 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Warrior.cpp b/Adventures in Lestoria/Warrior.cpp index 0d1875bd..9ed6a3c1 100644 --- a/Adventures in Lestoria/Warrior.cpp +++ b/Adventures in Lestoria/Warrior.cpp @@ -84,11 +84,11 @@ bool Warrior::AutoAttack(){ if(closest!=nullptr){ float dirToEnemy=geom2d::line(GetPos(),closest->GetPos()).vector().polar().y; targetDirection=dirToEnemy; - SetAnimationBasedOnTargetingDirection(dirToEnemy); + SetAnimationBasedOnTargetingDirection("SWINGSWORD",dirToEnemy); }else{ float dirToMouse=geom2d::line(GetPos(),GetWorldAimingLocation()).vector().polar().y; targetDirection=dirToMouse; - SetAnimationBasedOnTargetingDirection(dirToMouse); + SetAnimationBasedOnTargetingDirection("SWINGSWORD",dirToMouse); } attack_cooldown_timer=ATTACK_COOLDOWN-GetAttackRecoveryRateReduction(); diff --git a/Adventures in Lestoria/assets/config/Player.txt b/Adventures in Lestoria/assets/config/Player.txt index f8120732..8416f53d 100644 --- a/Adventures in Lestoria/assets/config/Player.txt +++ b/Adventures in Lestoria/assets/config/Player.txt @@ -86,7 +86,7 @@ Player PLAYER_ANIMATION[12] = THIEF_IDLE PLAYER_ANIMATION[13] = THIEF_WALK PLAYER_ANIMATION[14] = THIEF_SWINGSWORD - + PLAYER_ANIMATION[15] = THIEF_DEADLYDASH } PlayerXP diff --git a/Adventures in Lestoria/assets/config/classes/Thief.txt b/Adventures in Lestoria/assets/config/classes/Thief.txt index 27a57275..4ce325a7 100644 --- a/Adventures in Lestoria/assets/config/classes/Thief.txt +++ b/Adventures in Lestoria/assets/config/classes/Thief.txt @@ -98,6 +98,8 @@ Thief Damage = 4x Range = 450 + Initial Wait = 0.2s + Ending Wait = 0.3s #RGB Values. Color 1 is the circle at full cooldown, Color 2 is the color at empty cooldown. Cooldown Bar Color 1 = 64, 0, 0, 192 diff --git a/Adventures in Lestoria/assets/config/configuration.txt b/Adventures in Lestoria/assets/config/configuration.txt index 5cd11c08..c44468db 100644 --- a/Adventures in Lestoria/assets/config/configuration.txt +++ b/Adventures in Lestoria/assets/config/configuration.txt @@ -182,4 +182,4 @@ user_id_message2 = When loading a file, you will need this unique ID. # How large the exit ring is for a boss when it's killed. boss_spawn_ring_radius = 116 -Default Zoom Adjust Speed = 0.1/s \ No newline at end of file +Default Zoom Adjust Speed = 0.25/s \ No newline at end of file diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index e729c6a5..fa561a0c 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/assets/nico-thief.png b/Adventures in Lestoria/assets/nico-thief.png index ca261f2b..a0955803 100644 Binary files a/Adventures in Lestoria/assets/nico-thief.png and b/Adventures in Lestoria/assets/nico-thief.png differ diff --git a/Adventures in Lestoria/assets/nico-thief.xcf b/Adventures in Lestoria/assets/nico-thief.xcf index e8087475..2bb7b30c 100644 Binary files a/Adventures in Lestoria/assets/nico-thief.xcf and b/Adventures in Lestoria/assets/nico-thief.xcf differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 6757b8b1..3ef255cb 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ