sigonasr2 1 year ago
commit 97e2804a6a
  1. 4
      Crawler/Ability.h
  2. 259
      Crawler/Animation.cpp
  3. 11
      Crawler/Animation.h
  4. 39
      Crawler/Arrow.cpp
  5. 9
      Crawler/Bullet.h
  6. 11
      Crawler/BulletTypes.h
  7. 59
      Crawler/Crawler.cpp
  8. 8
      Crawler/Crawler.h
  9. 1
      Crawler/Crawler.vcxproj
  10. 3
      Crawler/Crawler.vcxproj.filters
  11. 5
      Crawler/DEFINES.h
  12. 3
      Crawler/EnergyBolt.cpp
  13. 3
      Crawler/FireBolt.cpp
  14. 3
      Crawler/LightningBolt.cpp
  15. 3
      Crawler/Meteor.cpp
  16. 51
      Crawler/Player.cpp
  17. 37
      Crawler/Player.h
  18. 101
      Crawler/Ranger.cpp
  19. 3
      Crawler/State.h
  20. 8
      Crawler/Thief.cpp
  21. 8
      Crawler/Trapper.cpp
  22. 2
      Crawler/Version.h
  23. 50
      Crawler/Warrior.cpp
  24. 8
      Crawler/Witch.cpp
  25. 47
      Crawler/Wizard.cpp
  26. BIN
      Crawler/assets/arrow.png
  27. 3
      Crawler/test

@ -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::function<bool(vf2d)>action=[&](vf2d){return false;};
std::function<bool(Player*,vf2d)>action=[](Player*,vf2d){return false;};
Ability();
Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={});
};

@ -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;i<frameCount;i++){
anim.AddFrame({&img,{{int(i*size.x),0},size}});
}
ANIMATION_DATA[state]=anim;
};
auto SetupClassWalkIdleAnimations=[&](Renderable&sheet,AnimationState WALK_S_ANIMATION){
Animate2D::FrameSequence pl_walk_s{0.2};
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
pl_walk_s.AddFrame({&sheet,{vi2d{1,0}*24,{24,24}}});
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
pl_walk_s.AddFrame({&sheet,{vi2d{2,0}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+0)]=pl_walk_s;
Animate2D::FrameSequence pl_walk_e{0.2};
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
pl_walk_e.AddFrame({&sheet,{vi2d{1,3}*24,{24,24}}});
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
pl_walk_e.AddFrame({&sheet,{vi2d{2,3}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+1)]=pl_walk_e;
Animate2D::FrameSequence pl_walk_w{0.2};
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
pl_walk_w.AddFrame({&sheet,{vi2d{1,2}*24,{24,24}}});
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
pl_walk_w.AddFrame({&sheet,{vi2d{2,2}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+3)]=pl_walk_w;
Animate2D::FrameSequence pl_walk_n{0.2};
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
pl_walk_n.AddFrame({&sheet,{vi2d{1,1}*24,{24,24}}});
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
pl_walk_n.AddFrame({&sheet,{vi2d{2,1}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+2)]=pl_walk_n;
Animate2D::FrameSequence pl_idle_s;
pl_idle_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+4)]=pl_idle_s;
Animate2D::FrameSequence pl_idle_e;
pl_idle_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+5)]=pl_idle_e;
Animate2D::FrameSequence pl_idle_w;
pl_idle_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+7)]=pl_idle_w;
Animate2D::FrameSequence pl_idle_n;
pl_idle_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
ANIMATION_DATA[AnimationState(WALK_S_ANIMATION+6)]=pl_idle_n;
};
//Warrior animations.
Animate2D::FrameSequence pl_warrior_walk_s{0.2};
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{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,21 @@ 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);
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
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 +186,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::SPLASH_EFFECT,{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(){
@ -328,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);

@ -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,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,
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{
@ -30,4 +32,9 @@ namespace sig{
static void InitializeAnimations();
static void SetupPlayerAnimations();
};
}
}
struct AnimationData{
float frameDuration=0.1f;
Animate2D::Style style=Animate2D::Style::Repeat;
};

@ -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<Effect>(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<Effect>(monster.GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,monster.GetSizeMult(),0.25));
return false;
}

@ -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::Animation<AnimationState>animation;
@ -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();
};

@ -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;
};

@ -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();
@ -87,13 +88,15 @@ 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;
}
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);
@ -179,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){
@ -193,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);
@ -209,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){
@ -219,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){
@ -230,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);
@ -244,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);
@ -258,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);
@ -272,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);
@ -554,15 +569,23 @@ 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=[&](){
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);
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());
@ -646,7 +669,7 @@ void Crawler::RenderWorld(float fElapsedTime){
m->Draw();
}
if(player->upperLevel){
RENDER_PLAYER
RenderPlayer();
}
for(Monster*m:monstersAfterUpper){
m->Draw();
@ -712,16 +735,16 @@ void Crawler::RenderHud(){
player->GetAbility3(),
player->GetAbility4(),
};
std::vector<Ability>activeCooldowns;
std::copy_if(cooldowns.begin(),cooldowns.end(),std::back_inserter(activeCooldowns),[](Ability a){
std::vector<Ability>activeCooldowns{};
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.cooldown<a2.cooldown;
});
int offset=6*activeCooldowns.size();
for(Ability&a:activeCooldowns){
if(a.cooldown>0){
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);
@ -1040,10 +1063,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;

@ -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;
@ -49,15 +49,15 @@ private:
std::vector<TileGroup>upperForegroundTileGroups;
int bridgeLayerIndex=-1;
float bridgeFadeFactor=0.f;
void InitializeClassAbilities();
public:
Crawler();
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
public:
geom2d::rect<int>NO_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);

@ -203,6 +203,7 @@
<ItemGroup>
<ClCompile Include="Ability.cpp" />
<ClCompile Include="Animation.cpp" />
<ClCompile Include="Arrow.cpp" />
<ClCompile Include="Bullet.cpp" />
<ClCompile Include="Crawler.cpp" />
<ClCompile Include="DamageNumber.cpp" />

@ -191,6 +191,9 @@
<ClCompile Include="PulsatingFire.cpp">
<Filter>Source Files\Effects</Filter>
</ClCompile>
<ClCompile Include="Arrow.cpp">
<Filter>Source Files\Bullet Types</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

@ -14,9 +14,10 @@
#define INFINITE 999999
#define SETUP_CLASS(class) \
class::class(){InitializeClassAbilities();} \
class::class() \
:Player::Player(){} \
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;}; \

@ -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);

@ -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);

@ -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);

@ -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){

@ -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;
}
@ -265,10 +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);
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()){
@ -303,13 +319,13 @@ 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!="???"){
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
@ -386,7 +402,7 @@ vf2d Player::GetVelocity(){
}
bool Player::CanMove(){
return state!=State::CASTING;
return state!=State::CASTING&&state!=State::ANIMATION_LOCK;
}
bool Player::HasIframes(){
@ -521,4 +537,23 @@ 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;
}
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);
}
}

@ -19,12 +19,17 @@ 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;
int atk=10;
vf2d pos;
float friction=400;
float z=0;
float moveSpd=1.0f;
float size=1.0f;
@ -43,9 +48,11 @@ struct Player{
void AddAnimation(AnimationState state);
std::vector<Buff>buffList;
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);
@ -58,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;
@ -73,6 +81,19 @@ 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::vector<vf2d>ghostPositions;
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
@ -119,7 +140,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;
@ -136,6 +156,7 @@ public:
virtual AnimationState&GetIdleWAnimation()=0;
CastInfo&GetCastInfo();
void SetAnimationBasedOnTargetingDirection(float targetDirection);
};
struct Warrior:Player{
@ -148,7 +169,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 +196,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 +223,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 +250,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 +277,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 +304,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;

@ -4,6 +4,7 @@
#include "Player.h"
#include "Effect.h"
#include "Crawler.h"
#include "BulletTypes.h"
INCLUDE_MONSTER_LIST
INCLUDE_BULLET_LIST
@ -11,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;
@ -28,34 +29,104 @@ 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);
}
}
if(retreatTimer>0){
SetZ(6*sin(PI/RETREAT_TIME*retreatTimer));
retreatTimer-=fElapsedTime;
if(retreatTimer<=0){
SetVelocity({});
SetZ(0);
SetState(State::NORMAL);
}
}
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;
}
}
}
}
if(ghostFrameTimer>0){
ghostFrameTimer-=fElapsedTime;
if(ghostFrameTimer<=0&&GetState()==State::RETREAT){
ghostPositions.push_back(GetPos()+vf2d{0,-GetZ()});
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>(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(){
return false;
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>(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 true;
}
void Ranger::InitializeClassAbilities(){
#pragma region Ranger Right-click Ability (???)
#pragma region Ranger Right-click Ability (Retreat)
Ranger::rightClickAbility.action=
[&](vf2d pos={}){
return false;
[](Player*p,vf2d pos={}){
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()+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
#pragma region Ranger Ability 1 (???)
#pragma region Ranger Ability 1 (Rapid Fire)
Ranger::ability1.action=
[&](vf2d pos={}){
return false;
[](Player*p,vf2d pos={}){
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 (???)
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

@ -12,4 +12,7 @@ enum State{
PATH_AROUND,
CASTING,
PREP_CAST,
SHOOT_ARROW,
RETREAT,
ANIMATION_LOCK,
};

@ -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

@ -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

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 747
#define VERSION_BUILD 832
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -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<Effect>(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<Effect>(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<float>(GetPos(),12*3.5),geom2d::circle<float>(m.GetPos(),m.GetSizeMult()*12))){
if(m.GetSizeMult()<=1&&geom2d::overlaps(geom2d::circle<float>(p->GetPos(),12*3.5),geom2d::circle<float>(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<Bullet>(GetPos(),bulletVel,30,GetAttack()*8,AnimationState::SONICSLASH,upperLevel,true,2.25,true,true,WHITE));
BULLET_LIST.push_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,30,p->GetAttack()*8,AnimationState::SONICSLASH,p->upperLevel,true,2.25,true,true,WHITE));
game->SetupWorldShake(0.5);
return true;
};

@ -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

@ -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<float>{GetPos(),game->GetWorldMousePos()}.length(),0.f,6.5f*24);
float dist=std::clamp(geom2d::line<float>{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<Effect>(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<Effect>(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>(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>(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>(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>(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<Meteor>(pos,3,AnimationState::METEOR,OnUpperLevel(),vf2d{1,1},2));
[](Player*p,vf2d pos={}){
p->CastSpell(Wizard::ability3);
game->AddEffect(std::make_unique<Meteor>(pos,3,AnimationState::METEOR,p->OnUpperLevel(),vf2d{1,1},2));
return true;
};
#pragma endregion

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

@ -0,0 +1,3 @@
test 1
test 2
test 3
Loading…
Cancel
Save