diff --git a/Crawler/ATTRIBUTION b/Crawler/ATTRIBUTION
new file mode 100644
index 00000000..e5a21612
--- /dev/null
+++ b/Crawler/ATTRIBUTION
@@ -0,0 +1 @@
+Image by pikisuperstar on Freepik
\ No newline at end of file
diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp
new file mode 100644
index 00000000..f47335aa
--- /dev/null
+++ b/Crawler/Animation.cpp
@@ -0,0 +1,317 @@
+#include "Animation.h"
+#include "Crawler.h"
+#include "DEFINES.h"
+
+INCLUDE_game
+INCLUDE_ANIMATION_DATA
+
+void sig::Animation::InitializeAnimations(){
+ //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;
+ 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++){
+ pl_warrior_swing_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,0}*24,{24,24}}});
+ pl_warrior_sonic_swing_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,4}*24,{24,24}}});
+ }
+ for (int i=0;i<4;i++){
+ pl_warrior_swing_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,1}*24,{24,24}}});
+ pl_warrior_sonic_swing_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,5}*24,{24,24}}});
+ }
+ for (int i=0;i<4;i++){
+ pl_warrior_swing_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,2}*24,{24,24}}});
+ pl_warrior_sonic_swing_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,6}*24,{24,24}}});
+ }
+ for (int i=0;i<4;i++){
+ pl_warrior_swing_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,3}*24,{24,24}}});
+ pl_warrior_sonic_swing_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,7}*24,{24,24}}});
+ }
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_N]=pl_warrior_swing_n;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_E]=pl_warrior_swing_e;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_S]=pl_warrior_swing_s;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_W]=pl_warrior_swing_w;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_N]=pl_warrior_sonic_swing_n;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_E]=pl_warrior_sonic_swing_e;
+ ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_S]=pl_warrior_sonic_swing_s;
+ 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;
+
+ //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;
+ 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;
+ Animate2D::FrameSequence pl_wizard_idle_attack_e;
+ pl_wizard_idle_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}});
+ ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_E]=pl_wizard_idle_attack_e;
+ Animate2D::FrameSequence pl_wizard_idle_attack_w;
+ pl_wizard_idle_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}});
+ ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_W]=pl_wizard_idle_attack_w;
+ Animate2D::FrameSequence pl_wizard_idle_attack_n;
+ pl_wizard_idle_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}});
+ ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_N]=pl_wizard_idle_attack_n;
+ Animate2D::FrameSequence pl_wizard_attack_s(0.2);
+ for(int i=0;i<3;i++){
+ pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,0}*24,{24,24}}});
+ if(i==1){
+ pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}});
+ }
+ }
+ ANIMATION_DATA[AnimationState::WIZARD_ATTACK_S]=pl_wizard_attack_s;
+ Animate2D::FrameSequence pl_wizard_attack_e(0.2);
+ for(int i=0;i<3;i++){
+ pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,3}*24,{24,24}}});
+ if(i==1){
+ pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}});
+ }
+ }
+ ANIMATION_DATA[AnimationState::WIZARD_ATTACK_E]=pl_wizard_attack_e;
+ Animate2D::FrameSequence pl_wizard_attack_w(0.2);
+ for(int i=0;i<3;i++){
+ pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,2}*24,{24,24}}});
+ if(i==1){
+ pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}});
+ }
+ }
+ ANIMATION_DATA[AnimationState::WIZARD_ATTACK_W]=pl_wizard_attack_w;
+ Animate2D::FrameSequence pl_wizard_attack_n(0.2);
+ for(int i=0;i<3;i++){
+ pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,1}*24,{24,24}}});
+ if(i==1){
+ pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}});
+ }
+ }
+ ANIMATION_DATA[AnimationState::WIZARD_ATTACK_N]=pl_wizard_attack_n;
+
+ //Load slime animations.
+ for(int slime=0;slime<4;slime++){
+ for(int state=0;state<5;state++){
+ Animate2D::FrameSequence anim;
+ if(state==4){//These are death animations.
+ anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot);
+ }
+ if(state==2){//These are death animations.
+ anim=Animate2D::FrameSequence(0.06f);
+ }
+ for (int frame=0;frame<10;frame++){
+ anim.AddFrame({&game->GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}});
+ }
+ 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;
+
+ 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;
+
+ 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;
+
+ Animate2D::FrameSequence dot_particle;
+ dot_particle.AddFrame({&game->GFX_BulletCircle,{{0,0},{3,3}}});
+ ANIMATION_DATA[AnimationState::DOT_PARTICLE]=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;
+
+ 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;
+
+ Animate2D::FrameSequence chainlightning;
+ chainlightning.AddFrame({&game->GFX_ChainLightning,{{0,0},{1,9}}});
+ ANIMATION_DATA[AnimationState::CHAIN_LIGHTNING]=chainlightning;
+
+ 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;
+}
+
+void sig::Animation::SetupPlayerAnimations(){
+ game->player.AddAnimation(AnimationState::WARRIOR_WALK_N);
+ game->player.AddAnimation(AnimationState::WARRIOR_WALK_E);
+ game->player.AddAnimation(AnimationState::WARRIOR_WALK_S);
+ game->player.AddAnimation(AnimationState::WARRIOR_WALK_W);
+ game->player.AddAnimation(AnimationState::WARRIOR_IDLE_N);
+ game->player.AddAnimation(AnimationState::WARRIOR_IDLE_E);
+ game->player.AddAnimation(AnimationState::WARRIOR_IDLE_S);
+ game->player.AddAnimation(AnimationState::WARRIOR_IDLE_W);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_E);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_S);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_N);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_W);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N);
+ game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W);
+ game->player.AddAnimation(AnimationState::RANGER_WALK_N);
+ game->player.AddAnimation(AnimationState::RANGER_WALK_E);
+ game->player.AddAnimation(AnimationState::RANGER_WALK_S);
+ game->player.AddAnimation(AnimationState::RANGER_WALK_W);
+ game->player.AddAnimation(AnimationState::RANGER_IDLE_N);
+ game->player.AddAnimation(AnimationState::RANGER_IDLE_E);
+ game->player.AddAnimation(AnimationState::RANGER_IDLE_S);
+ game->player.AddAnimation(AnimationState::RANGER_IDLE_W);
+ game->player.AddAnimation(AnimationState::WIZARD_WALK_N);
+ game->player.AddAnimation(AnimationState::WIZARD_WALK_E);
+ game->player.AddAnimation(AnimationState::WIZARD_WALK_S);
+ game->player.AddAnimation(AnimationState::WIZARD_WALK_W);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_N);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_E);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_S);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_W);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_N);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_E);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_S);
+ game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_W);
+ game->player.AddAnimation(AnimationState::WIZARD_ATTACK_N);
+ game->player.AddAnimation(AnimationState::WIZARD_ATTACK_E);
+ game->player.AddAnimation(AnimationState::WIZARD_ATTACK_S);
+ game->player.AddAnimation(AnimationState::WIZARD_ATTACK_W);
+}
\ No newline at end of file
diff --git a/Crawler/Animation.h b/Crawler/Animation.h
index d6f3b1ea..e8391861 100644
--- a/Crawler/Animation.h
+++ b/Crawler/Animation.h
@@ -18,4 +18,14 @@ enum AnimationState{
WIZARD_IDLE_ATTACK_S,WIZARD_IDLE_ATTACK_E,WIZARD_IDLE_ATTACK_N,WIZARD_IDLE_ATTACK_W,
WIZARD_ATTACK_S,WIZARD_ATTACK_E,WIZARD_ATTACK_N,WIZARD_ATTACK_W,
ENERGY_BOLT,ENERGY_PARTICLE,SPLASH_EFFECT,DOT_PARTICLE,
-};
\ No newline at end of file
+ LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4,
+ CHAIN_LIGHTNING,LIGHTNING_SPLASH
+};
+
+namespace sig{
+ class Animation{
+ public:
+ static void InitializeAnimations();
+ static void SetupPlayerAnimations();
+ };
+}
\ No newline at end of file
diff --git a/Crawler/BulletTypes.h b/Crawler/BulletTypes.h
index 6fc8e0f2..45a6b3a0 100644
--- a/Crawler/BulletTypes.h
+++ b/Crawler/BulletTypes.h
@@ -15,4 +15,12 @@ struct FireBolt:public Bullet{
void Update(float fElapsedTime)override;
bool PlayerHit(Player&player)override;
bool MonsterHit(Monster&monster)override;
+};
+
+struct LightningBolt:public Bullet{
+ float lastParticleSpawn=0;
+ LightningBolt(vf2d pos,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/Class.cpp b/Crawler/Class.cpp
index ef4095d0..14f61a0c 100644
--- a/Crawler/Class.cpp
+++ b/Crawler/Class.cpp
@@ -295,6 +295,9 @@ bool Wizard::Ability1(){
}
bool Wizard::Ability2(){
+ ACCESS_PLAYER
+ float angleToCursor=atan2(game->GetWorldMousePos().y-p.pos.y,game->GetWorldMousePos().x-p.pos.x);
+ BULLET_LIST.push_back(std::make_unique(LightningBolt(p.pos,{cos(angleToCursor)*230,sin(angleToCursor)*230},12,p.GetAttack()*4,p.upperLevel,true,WHITE)));
return true;
}
diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp
index 7fdc7055..5bdde233 100644
--- a/Crawler/Crawler.cpp
+++ b/Crawler/Crawler.cpp
@@ -13,8 +13,10 @@
#include "utils.h"
#include
#include
+#include "Emitter.h"
INCLUDE_CLASS_DATA
+INCLUDE_EMITTER_LIST
//#define DEBUG_COLLISIONS //Shows collision hitboxes.
//#define DEBUG_POS //Shows player position.
@@ -69,50 +71,18 @@ bool Crawler::OnUserCreate(){
GFX_EnergyBolt.Load("assets/energy_bolt.png");
GFX_EnergyParticle.Load("assets/energy_particle.png");
GFX_Splash_Effect.Load("assets/splash_effect.png");
+ GFX_LightningBolt.Load("assets/lightning_bolt.png");
+ GFX_LightningBoltParticle1.Load("assets/lightning_bolt_part1.png");
+ GFX_LightningBoltParticle2.Load("assets/lightning_bolt_part2.png");
+ GFX_LightningBoltParticle3.Load("assets/lightning_bolt_part3.png");
+ GFX_LightningBoltParticle4.Load("assets/lightning_bolt_part4.png");
+ GFX_ChainLightning.Load("assets/chain_lightning.png");
+ GFX_LightningSplash.Load("assets/lightning_splash_effect.png");
//Animations
- InitializeAnimations();
+ sig::Animation::InitializeAnimations();
- player.AddAnimation(AnimationState::WARRIOR_WALK_N);
- player.AddAnimation(AnimationState::WARRIOR_WALK_E);
- player.AddAnimation(AnimationState::WARRIOR_WALK_S);
- player.AddAnimation(AnimationState::WARRIOR_WALK_W);
- player.AddAnimation(AnimationState::WARRIOR_IDLE_N);
- player.AddAnimation(AnimationState::WARRIOR_IDLE_E);
- player.AddAnimation(AnimationState::WARRIOR_IDLE_S);
- player.AddAnimation(AnimationState::WARRIOR_IDLE_W);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_E);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_S);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_N);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_W);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N);
- player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W);
- player.AddAnimation(AnimationState::RANGER_WALK_N);
- player.AddAnimation(AnimationState::RANGER_WALK_E);
- player.AddAnimation(AnimationState::RANGER_WALK_S);
- player.AddAnimation(AnimationState::RANGER_WALK_W);
- player.AddAnimation(AnimationState::RANGER_IDLE_N);
- player.AddAnimation(AnimationState::RANGER_IDLE_E);
- player.AddAnimation(AnimationState::RANGER_IDLE_S);
- player.AddAnimation(AnimationState::RANGER_IDLE_W);
- player.AddAnimation(AnimationState::WIZARD_WALK_N);
- player.AddAnimation(AnimationState::WIZARD_WALK_E);
- player.AddAnimation(AnimationState::WIZARD_WALK_S);
- player.AddAnimation(AnimationState::WIZARD_WALK_W);
- player.AddAnimation(AnimationState::WIZARD_IDLE_N);
- player.AddAnimation(AnimationState::WIZARD_IDLE_E);
- player.AddAnimation(AnimationState::WIZARD_IDLE_S);
- player.AddAnimation(AnimationState::WIZARD_IDLE_W);
- player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_N);
- player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_E);
- player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_S);
- player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_W);
- player.AddAnimation(AnimationState::WIZARD_ATTACK_N);
- player.AddAnimation(AnimationState::WIZARD_ATTACK_E);
- player.AddAnimation(AnimationState::WIZARD_ATTACK_S);
- player.AddAnimation(AnimationState::WIZARD_ATTACK_W);
+ sig::Animation::SetupPlayerAnimations();
view=TileTransformedView{GetScreenSize(),{1,1}};
LoadLevel(CAMPAIGN_1_1);
@@ -137,245 +107,6 @@ bool Crawler::OnUserUpdate(float fElapsedTime){
return true;
}
-void Crawler::InitializeAnimations(){
- //Warrior animations.
- Animate2D::FrameSequence pl_warrior_walk_s{0.2};
- pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,0}*24,{24,24}}});
- pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_warrior_walk_s.AddFrame({&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({&GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,3}*24,{24,24}}});
- pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_warrior_walk_e.AddFrame({&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({&GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,2}*24,{24,24}}});
- pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_warrior_walk_w.AddFrame({&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({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,1}*24,{24,24}}});
- pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_warrior_walk_n.AddFrame({&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({&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({&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({&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({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WARRIOR_IDLE_N]=pl_warrior_idle_n;
- 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++){
- pl_warrior_swing_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,0}*24,{24,24}}});
- pl_warrior_sonic_swing_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,4}*24,{24,24}}});
- }
- for (int i=0;i<4;i++){
- pl_warrior_swing_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,1}*24,{24,24}}});
- pl_warrior_sonic_swing_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,5}*24,{24,24}}});
- }
- for (int i=0;i<4;i++){
- pl_warrior_swing_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,2}*24,{24,24}}});
- pl_warrior_sonic_swing_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,6}*24,{24,24}}});
- }
- for (int i=0;i<4;i++){
- pl_warrior_swing_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,3}*24,{24,24}}});
- pl_warrior_sonic_swing_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,7}*24,{24,24}}});
- }
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_N]=pl_warrior_swing_n;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_E]=pl_warrior_swing_e;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_S]=pl_warrior_swing_s;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_W]=pl_warrior_swing_w;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_N]=pl_warrior_sonic_swing_n;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_E]=pl_warrior_sonic_swing_e;
- ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_S]=pl_warrior_sonic_swing_s;
- 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({&GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,0}*24,{24,24}}});
- pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_ranger_walk_s.AddFrame({&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({&GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,3}*24,{24,24}}});
- pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_ranger_walk_e.AddFrame({&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({&GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,2}*24,{24,24}}});
- pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_ranger_walk_w.AddFrame({&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({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,1}*24,{24,24}}});
- pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_ranger_walk_n.AddFrame({&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({&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({&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({&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({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::RANGER_IDLE_N]=pl_ranger_idle_n;
-
- //Wizard animations
- Animate2D::FrameSequence pl_wizard_walk_s{0.2};
- pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,0}*24,{24,24}}});
- pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}});
- pl_wizard_walk_s.AddFrame({&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({&GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,3}*24,{24,24}}});
- pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}});
- pl_wizard_walk_e.AddFrame({&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({&GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,2}*24,{24,24}}});
- pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}});
- pl_wizard_walk_w.AddFrame({&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({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,1}*24,{24,24}}});
- pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}});
- pl_wizard_walk_n.AddFrame({&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({&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({&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({&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({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WIZARD_IDLE_N]=pl_wizard_idle_n;
- Animate2D::FrameSequence pl_wizard_idle_attack_s;
- pl_wizard_idle_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_S]=pl_wizard_idle_attack_s;
- Animate2D::FrameSequence pl_wizard_idle_attack_e;
- pl_wizard_idle_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_E]=pl_wizard_idle_attack_e;
- Animate2D::FrameSequence pl_wizard_idle_attack_w;
- pl_wizard_idle_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_W]=pl_wizard_idle_attack_w;
- Animate2D::FrameSequence pl_wizard_idle_attack_n;
- pl_wizard_idle_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}});
- ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_N]=pl_wizard_idle_attack_n;
- Animate2D::FrameSequence pl_wizard_attack_s(0.2);
- for(int i=0;i<3;i++){
- pl_wizard_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,0}*24,{24,24}}});
- if(i==1){
- pl_wizard_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}});
- }
- }
- ANIMATION_DATA[AnimationState::WIZARD_ATTACK_S]=pl_wizard_attack_s;
- Animate2D::FrameSequence pl_wizard_attack_e(0.2);
- for(int i=0;i<3;i++){
- pl_wizard_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,3}*24,{24,24}}});
- if(i==1){
- pl_wizard_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}});
- }
- }
- ANIMATION_DATA[AnimationState::WIZARD_ATTACK_E]=pl_wizard_attack_e;
- Animate2D::FrameSequence pl_wizard_attack_w(0.2);
- for(int i=0;i<3;i++){
- pl_wizard_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,2}*24,{24,24}}});
- if(i==1){
- pl_wizard_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}});
- }
- }
- ANIMATION_DATA[AnimationState::WIZARD_ATTACK_W]=pl_wizard_attack_w;
- Animate2D::FrameSequence pl_wizard_attack_n(0.2);
- for(int i=0;i<3;i++){
- pl_wizard_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,1}*24,{24,24}}});
- if(i==1){
- pl_wizard_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}});
- }
- }
- ANIMATION_DATA[AnimationState::WIZARD_ATTACK_N]=pl_wizard_attack_n;
-
- //Load slime animations.
- for(int slime=0;slime<4;slime++){
- for(int state=0;state<5;state++){
- Animate2D::FrameSequence anim;
- if(state==4){//These are death animations.
- anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot);
- }
- if(state==2){//These are death animations.
- anim=Animate2D::FrameSequence(0.06f);
- }
- for (int frame=0;frame<10;frame++){
- anim.AddFrame({&GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}});
- }
- 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({&GFX_Effect_GroundSlam_Back,{{i*64,0},{64,64}}});
- effect_groundslam_front.AddFrame({&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({&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({&GFX_SonicSlash,{{i*60,0},{60,60}}});
- }
- ANIMATION_DATA[AnimationState::SONICSLASH]=sonicslash_effect;
- Animate2D::FrameSequence energy_bolt;
- energy_bolt.AddFrame({&GFX_EnergyBolt,{{0,0},{24,24}}});
- ANIMATION_DATA[AnimationState::ENERGY_BOLT]=energy_bolt;
-
- Animate2D::FrameSequence energy_particle;
- for(int i=0;i<3;i++){
- energy_particle.AddFrame({&GFX_EnergyParticle,{{i*3,0},{3,3}}});
- }
- ANIMATION_DATA[AnimationState::ENERGY_PARTICLE]=energy_particle;
-
- Animate2D::FrameSequence splash_animation(0.05);
- for(int i=0;i<5;i++){
- splash_animation.AddFrame({&GFX_Splash_Effect,{{i*24,0},{24,24}}});
- }
- ANIMATION_DATA[AnimationState::SPLASH_EFFECT]=splash_animation;
-
- Animate2D::FrameSequence dot_particle;
- dot_particle.AddFrame({&GFX_BulletCircle,{{0,0},{3,3}}});
- ANIMATION_DATA[AnimationState::DOT_PARTICLE]=dot_particle;
-}
-
bool Crawler::LeftHeld(){
return GetKey(LEFT).bHeld||GetKey(A).bHeld;
}
@@ -625,6 +356,15 @@ void Crawler::UpdateCamera(float fElapsedTime){
}
void Crawler::UpdateEffects(float fElapsedTime){
+ for(auto it=EMITTER_LIST.begin();it!=EMITTER_LIST.end();++it){
+ auto ptr=(*it).get();
+ if(!ptr->Update(fElapsedTime)){
+ it=EMITTER_LIST.erase(it);
+ if(it==EMITTER_LIST.end()){
+ break;
+ }
+ }
+ }
for(std::vector::iterator it=backgroundEffects.begin();it!=backgroundEffects.end();++it){
Effect&e=*it;
if(!e.Update(fElapsedTime)){
@@ -650,6 +390,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
b->UpdateFadeTime(fElapsedTime);
b->Update(fElapsedTime);
b->pos+=b->vel*fElapsedTime;
+ b->animation.UpdateState(b->internal_animState,fElapsedTime);
if(!b->deactivated){
if(b->friendly){
for(Monster&m:MONSTER_LIST){
@@ -697,7 +438,6 @@ void Crawler::UpdateBullets(float fElapsedTime){
}
continue;
}
- b->animation.UpdateState(b->internal_animState,fElapsedTime);
continuePlayerBulletLoop:
continue;
}
diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h
index b7527d34..c3fb3e0b 100644
--- a/Crawler/Crawler.h
+++ b/Crawler/Crawler.h
@@ -18,13 +18,16 @@ struct TilesheetData{
class Crawler : public olc::PixelGameEngine
{
+ friend class sig::Animation;
Camera2D camera;
Player player;
Renderable GFX_Warrior_Sheet,GFX_Slime_Sheet,GFX_Circle,
GFX_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front,
GFX_Heart,GFX_BLOCK_BUBBLE,GFX_Ranger_Sheet,GFX_Wizard_Sheet,
GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle,
- GFX_Splash_Effect;
+ GFX_Splash_Effect,GFX_LightningBolt,GFX_LightningBoltParticle1,
+ GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4,
+ GFX_ChainLightning,GFX_LightningSplash;
public:
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt;
Pathfinding pathfinder;
@@ -51,7 +54,6 @@ public:
TileTransformedView view;
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
- void InitializeAnimations();
void InitializeLevel(std::string mapFile,MapName map);
void LoadLevel(MapName map);
void HandleUserInput(float fElapsedTime);
diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj
index bb32f7fc..fd65a0d9 100644
--- a/Crawler/Crawler.vcxproj
+++ b/Crawler/Crawler.vcxproj
@@ -182,6 +182,7 @@
+
@@ -201,13 +202,17 @@
+
+
+
+
diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters
index f56de6c9..2609e37b 100644
--- a/Crawler/Crawler.vcxproj.filters
+++ b/Crawler/Crawler.vcxproj.filters
@@ -19,6 +19,9 @@
{715c64c5-956a-4ed3-9205-64110409fbeb}
+
+ {0f85b918-f194-4114-9a10-803e204faf2e}
+
@@ -99,6 +102,9 @@
Header Files
+
+ Header Files
+
@@ -146,6 +152,18 @@
Source Files
+
+ Source Files
+
+
+ Source Files\Bullet Types
+
+
+ Source Files\Emitters
+
+
+ Source Files
+
diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h
index 14fc2273..5db4cc4d 100644
--- a/Crawler/DEFINES.h
+++ b/Crawler/DEFINES.h
@@ -8,6 +8,7 @@
#define INCLUDE_BULLET_LIST extern std::vector>BULLET_LIST;
#define INCLUDE_CLASS_DATA extern std::map>CLASS_DATA;
#define INCLUDE_PARTICLE_LIST extern std::vectorPARTICLE_LIST;
+#define INCLUDE_EMITTER_LIST extern std::vector>EMITTER_LIST;
#define ACCESS_PLAYER Player&p=game->GetPlayer();
diff --git a/Crawler/Effect.cpp b/Crawler/Effect.cpp
index 64965add..36f14065 100644
--- a/Crawler/Effect.cpp
+++ b/Crawler/Effect.cpp
@@ -5,8 +5,13 @@
INCLUDE_ANIMATION_DATA
INCLUDE_game
-Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col)
- :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadeout(fadeout),original_fadeoutTime(fadeout),spd(spd),col(col){
+Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending)
+ :Effect::Effect(pos,lifetime,animation,upperLevel,{size,size},fadeout,spd,col,rotation,rotationSpd,additiveBlending){
+ this->animation.AddState(animation,ANIMATION_DATA[animation]);
+}
+
+Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,vf2d size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending)
+ :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadeout(fadeout),original_fadeoutTime(fadeout),spd(spd),col(col),rotation(rotation),rotationSpd(rotationSpd),additiveBlending(additiveBlending){
this->animation.AddState(animation,ANIMATION_DATA[animation]);
}
@@ -18,16 +23,19 @@ bool Effect::Update(float fElapsedTime){
return false;
}
}
+ rotation+=rotationSpd*fElapsedTime;
pos+=spd*fElapsedTime;
animation.UpdateState(internal_animState,fElapsedTime);
return true;
}
void Effect::Draw(){
+ if(additiveBlending)game->SetDecalMode(DecalMode::ADDITIVE);
+ else game->SetDecalMode(DecalMode::NORMAL);
if(fadeout==0){
- game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size*size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,{size,size},col);
+ game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,col);
} else {
- game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size*size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,{size,size},{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*255)});
+ game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*255)});
}
}
diff --git a/Crawler/Effect.h b/Crawler/Effect.h
index adb6b614..3dd719e4 100644
--- a/Crawler/Effect.h
+++ b/Crawler/Effect.h
@@ -7,10 +7,14 @@ struct Effect{
vf2d pos={0,0};
float lifetime=0;
float fadeout=0;
- float size=1;
+ vf2d size={1,1};
Pixel col=WHITE;
vf2d spd={};
- Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE);
+ float rotation=0;
+ float rotationSpd=0;
+ bool additiveBlending=false;
+ Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
+ Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
bool Update(float fElapsedTime);
Animate2D::Frame GetFrame();
void Draw();
diff --git a/Crawler/Emitter.cpp b/Crawler/Emitter.cpp
new file mode 100644
index 00000000..f619ff55
--- /dev/null
+++ b/Crawler/Emitter.cpp
@@ -0,0 +1,18 @@
+#include "Emitter.h"
+
+std::vector>EMITTER_LIST;
+
+Emitter::Emitter(float frequency,float timer)
+ :frequency(frequency),timer(timer){}
+
+bool Emitter::Update(float fElapsedTime){
+ lastEmit=std::max(lastEmit-fElapsedTime,0.f);
+ if(lastEmit==0){
+ lastEmit=frequency;
+ Emit();
+ }
+ timer-=fElapsedTime;
+ if(timer<0){
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Crawler/Emitter.h b/Crawler/Emitter.h
new file mode 100644
index 00000000..a6c855fc
--- /dev/null
+++ b/Crawler/Emitter.h
@@ -0,0 +1,20 @@
+#include "olcPixelGameEngine.h"
+#pragma once
+
+struct Emitter{
+ float frequency;
+ float timer;
+ float lastEmit=0;
+ Emitter(float frequency,float timer);
+ bool Update(float fElapsedTime);
+ virtual void Emit()=0;
+};
+
+class LightningBoltEmitter:public Emitter{
+ vf2d startPos,endPos;
+ bool upperLevel;
+ void DrawLightningBolt();
+ void Emit()override;
+public:
+ LightningBoltEmitter(vf2d startPos,vf2d endPos,float frequency,float timer,bool upperLevel);
+};
\ No newline at end of file
diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp
new file mode 100644
index 00000000..00755fb8
--- /dev/null
+++ b/Crawler/LightningBolt.cpp
@@ -0,0 +1,64 @@
+#include "BulletTypes.h"
+#include "Effect.h"
+#include "Crawler.h"
+#include "DEFINES.h"
+#include "Emitter.h"
+#include "utils.h"
+
+INCLUDE_game
+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){}
+
+void LightningBolt::Update(float fElapsedTime){
+ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
+ if(lastParticleSpawn==0){
+ lastParticleSpawn=0.01;
+ uint8_t brightness=uint8_t(util::random(100)+150);
+ switch(rand()%4){
+ case 0:{
+ game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE1,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness}));
+ }break;
+ case 1:{
+ game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE2,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness}));
+ }break;
+ case 2:{
+ game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE3,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness}));
+ }break;
+ case 3:{
+ game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE4,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness}));
+ }break;
+ }
+ }
+}
+
+bool LightningBolt::PlayerHit(Player& player)
+{
+ deactivated=true;
+ fadeOutTime=0.2f;
+ game->AddEffect(Effect(player.GetPos(),0.3,AnimationState::LIGHTNING_SPLASH,upperLevel,player.GetSizeMult(),0.25,{},WHITE,util::random(PI)));
+ return false;
+}
+
+bool LightningBolt::MonsterHit(Monster& monster)
+{
+ deactivated=true;
+ fadeOutTime=0.2f;
+ game->AddEffect(Effect(monster.GetPos(),0.3,AnimationState::LIGHTNING_SPLASH,upperLevel,monster.GetSizeMult(),0.25,{},WHITE,util::random(PI)));
+ int targetsHit=0;
+ for(Monster&m:MONSTER_LIST){
+ if(&m==&monster||monster.OnUpperLevel()!=m.OnUpperLevel())continue;
+ geom2d::linelineToTarget=geom2d::line(monster.GetPos(),m.GetPos());
+ float dist=lineToTarget.length();
+ if(dist<=72){
+ m.Hurt(game->GetPlayer().GetAttack()*2);
+ EMITTER_LIST.push_back(std::make_unique(LightningBoltEmitter(monster.GetPos(),m.GetPos(),0.05,0.25,upperLevel)));
+ game->AddEffect(Effect(m.GetPos(),0.5,AnimationState::LIGHTNING_SPLASH,upperLevel,monster.GetSizeMult(),0.25,{},WHITE,util::random(PI)));
+ targetsHit++;
+ }
+ if(targetsHit>=2)break;
+ }
+ return false;
+}
\ No newline at end of file
diff --git a/Crawler/LightningBoltEmitter.cpp b/Crawler/LightningBoltEmitter.cpp
new file mode 100644
index 00000000..5f222d22
--- /dev/null
+++ b/Crawler/LightningBoltEmitter.cpp
@@ -0,0 +1,38 @@
+#include "Emitter.h"
+#include "olcUTIL_Geometry2D.h"
+#include "utils.h"
+#include "Crawler.h"
+#include "DEFINES.h"
+
+INCLUDE_game
+
+LightningBoltEmitter::LightningBoltEmitter(vf2d startPos,vf2d endPos,float frequency,float timer,bool upperLevel)
+ :startPos(startPos),endPos(endPos),Emitter(frequency,timer),upperLevel(upperLevel){}
+
+
+void LightningBoltEmitter::Emit(){
+ DrawLightningBolt();
+}
+
+void LightningBoltEmitter::DrawLightningBolt(){
+ vf2d currentPos=startPos;
+ const int MAX_ITERATIONS=100;
+ geom2d::linelineToTarget=geom2d::line(startPos,endPos);
+ float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x);
+ float targetDist=lineToTarget.length()*util::random(0.5);
+ targetAngle+=util::random((PI/2))-PI/4;
+ geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
+ game->AddEffect(Effect(lightningLine.upoint(0),0,AnimationState::CHAIN_LIGHTNING,upperLevel,{lightningLine.length(),0.2},0.2,{},WHITE,targetAngle,0,true));
+ int iterations=1;
+ currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist};
+ while(iterations(currentPos,endPos).length()>1){
+ geom2d::linelineToTarget=geom2d::line(currentPos,endPos);
+ float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x);
+ float targetDist=lineToTarget.length()*util::random(0.5);
+ targetAngle+=util::random((PI/2))-PI/4;
+ geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
+ game->AddEffect(Effect(lightningLine.upoint(0),0,AnimationState::CHAIN_LIGHTNING,upperLevel,{lightningLine.length(),0.2},0.2,{},WHITE,targetAngle,0,true));
+ currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist};
+ iterations++;
+ }
+}
\ No newline at end of file
diff --git a/Crawler/Player.h b/Crawler/Player.h
index 0b9252e3..91d4db45 100644
--- a/Crawler/Player.h
+++ b/Crawler/Player.h
@@ -16,6 +16,7 @@ struct Player{
friend class Bard;
friend class Wizard;
friend class Witch;
+ friend class sig::Animation;
private:
Class cl=WARRIOR;
int hp=100,maxhp=hp;
diff --git a/Crawler/Version.h b/Crawler/Version.h
index b138a2c8..bceb5a85 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 594
+#define VERSION_BUILD 639
#define stringify(a) stringify_(a)
#define stringify_(a) #a
diff --git a/Crawler/assets/chain_lightning.png b/Crawler/assets/chain_lightning.png
new file mode 100644
index 00000000..bb7caf9b
Binary files /dev/null and b/Crawler/assets/chain_lightning.png differ
diff --git a/Crawler/assets/lightning_bolt.png b/Crawler/assets/lightning_bolt.png
new file mode 100644
index 00000000..3dba9d72
Binary files /dev/null and b/Crawler/assets/lightning_bolt.png differ
diff --git a/Crawler/assets/lightning_bolt_part1.png b/Crawler/assets/lightning_bolt_part1.png
new file mode 100644
index 00000000..e12f14fa
Binary files /dev/null and b/Crawler/assets/lightning_bolt_part1.png differ
diff --git a/Crawler/assets/lightning_bolt_part2.png b/Crawler/assets/lightning_bolt_part2.png
new file mode 100644
index 00000000..53a7c058
Binary files /dev/null and b/Crawler/assets/lightning_bolt_part2.png differ
diff --git a/Crawler/assets/lightning_bolt_part3.png b/Crawler/assets/lightning_bolt_part3.png
new file mode 100644
index 00000000..a33c68f3
Binary files /dev/null and b/Crawler/assets/lightning_bolt_part3.png differ
diff --git a/Crawler/assets/lightning_bolt_part4.png b/Crawler/assets/lightning_bolt_part4.png
new file mode 100644
index 00000000..56bcce76
Binary files /dev/null and b/Crawler/assets/lightning_bolt_part4.png differ
diff --git a/Crawler/assets/lightning_splash_effect.png b/Crawler/assets/lightning_splash_effect.png
new file mode 100644
index 00000000..d62e96bc
Binary files /dev/null and b/Crawler/assets/lightning_splash_effect.png differ
diff --git a/Crawler/olcUTIL_Animate2D.h b/Crawler/olcUTIL_Animate2D.h
index e56dece7..7da9ce4c 100644
--- a/Crawler/olcUTIL_Animate2D.h
+++ b/Crawler/olcUTIL_Animate2D.h
@@ -140,9 +140,10 @@ namespace olc::utils::Animate2D
case Style::OneShot:
return std::clamp(size_t(fTime * m_fFrameRate), size_t(0), m_vFrames.size() - 1);
break;
- case Style::PingPong:
- // TODO
- break;
+ case Style::PingPong:{
+ size_t frame=size_t(m_fFrameRate*fTime) % (m_vFrames.size()*2-1);
+ return frame>=m_vFrames.size()?m_vFrames.size()-frame%m_vFrames.size()-1:frame;
+ }break;
case Style::Reverse:
return (m_vFrames.size() - 1) - (size_t(fTime * m_fFrameRate) % m_vFrames.size());
break;