All animation references now auto-generate from gfx.txt. All animation references in code have been updated. Safemaps now have the ability to reset their contents (currently used for GFX map unloading) since Renderables must be deleted before the engine uninitializes. Slime King jump now has knockback.

pull/28/head
sigonasr2 2 years ago
parent ba8a1bd091
commit 465fb0b6c2
  1. 119
      Crawler/Animation.cpp
  2. 6
      Crawler/Arrow.cpp
  3. 5
      Crawler/Bullet.cpp
  4. 4
      Crawler/ChargedArrow.cpp
  5. 71
      Crawler/Crawler.cpp
  6. 10
      Crawler/Crawler.h
  7. 2
      Crawler/DEFINES.h
  8. 10
      Crawler/Effect.cpp
  9. 8
      Crawler/Effect.h
  10. 8
      Crawler/EnergyBolt.cpp
  11. 10
      Crawler/FireBolt.cpp
  12. 16
      Crawler/LightningBolt.cpp
  13. 4
      Crawler/LightningBoltEmitter.cpp
  14. 14
      Crawler/Meteor.cpp
  15. 5
      Crawler/Monster.cpp
  16. 2
      Crawler/Player.cpp
  17. 2
      Crawler/Player.h
  18. 14
      Crawler/PulsatingFire.cpp
  19. 20
      Crawler/SlimeKing.cpp
  20. 2
      Crawler/Version.h
  21. 4
      Crawler/Warrior.cpp
  22. 4
      Crawler/Wizard.cpp
  23. 19
      Crawler/assets/Campaigns/1_1_v2.tmx
  24. 3
      Crawler/assets/config/MonsterStrategies.txt
  25. 2
      Crawler/assets/config/configuration.txt
  26. 35
      Crawler/assets/config/gfx/gfx.txt
  27. BIN
      Crawler/assets/fire_ring0.png
  28. BIN
      Crawler/assets/fire_ring1.png
  29. BIN
      Crawler/assets/fire_ring2.png
  30. BIN
      Crawler/assets/fire_ring3.png
  31. BIN
      Crawler/assets/fire_ring4.png
  32. 4
      Crawler/olcUTIL_DataFile.h
  33. 8
      Crawler/safemap.h

@ -6,21 +6,22 @@
INCLUDE_game INCLUDE_game
INCLUDE_ANIMATION_DATA INCLUDE_ANIMATION_DATA
INCLUDE_DATA INCLUDE_DATA
INCLUDE_GFX
void sig::Animation::InitializeAnimations(){ void sig::Animation::InitializeAnimations(){
auto CreateStillAnimation=[&](Renderable&img,vf2d size,std::string state,AnimationData data={}){ auto CreateStillAnimation=[&](std::string imgName,vf2d size,AnimationData data={}){
Animate2D::FrameSequence anim(data.frameDuration,data.style); Animate2D::FrameSequence anim(data.frameDuration,data.style);
anim.AddFrame({&img,{{0,0},size}}); anim.AddFrame({&GFX[imgName],{{0,0},size}});
ANIMATION_DATA[state]=anim; ANIMATION_DATA[imgName]=anim;
}; };
auto CreateHorizontalAnimationSequence=[&](Renderable&img,int frameCount,vf2d size,std::string state,AnimationData data={}){ auto CreateHorizontalAnimationSequence=[&](std::string imgName,int frameCount,vf2d size,AnimationData data={}){
Animate2D::FrameSequence anim(data.frameDuration,data.style); Animate2D::FrameSequence anim(data.frameDuration,data.style);
for(int i=0;i<frameCount;i++){ for(int i=0;i<frameCount;i++){
anim.AddFrame({&img,{{int(i*size.x),0},size}}); anim.AddFrame({&GFX[imgName],{{int(i*size.x),0},size}});
} }
ANIMATION_DATA[state]=anim; ANIMATION_DATA[imgName]=anim;
}; };
auto SetupClassWalkIdleAnimations=[&](Renderable&sheet,std::string className){ auto SetupClassWalkIdleAnimations=[&](Renderable&sheet,std::string className){
@ -63,24 +64,24 @@ void sig::Animation::InitializeAnimations(){
}; };
//Warrior animations. //Warrior animations.
SetupClassWalkIdleAnimations(game->GFX_Warrior_Sheet,"WARRIOR"); SetupClassWalkIdleAnimations(GFX["nico-warrior.png"],"WARRIOR");
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_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); 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++){ 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_swing_s.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,0}*24,{24,24}}});
pl_warrior_sonic_swing_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,4}*24,{24,24}}}); pl_warrior_sonic_swing_s.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,4}*24,{24,24}}});
} }
for (int i=0;i<4;i++){ 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_swing_n.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,1}*24,{24,24}}});
pl_warrior_sonic_swing_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,5}*24,{24,24}}}); pl_warrior_sonic_swing_n.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,5}*24,{24,24}}});
} }
for (int i=0;i<4;i++){ 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_swing_w.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,2}*24,{24,24}}});
pl_warrior_sonic_swing_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,6}*24,{24,24}}}); pl_warrior_sonic_swing_w.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,6}*24,{24,24}}});
} }
for (int i=0;i<4;i++){ 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_swing_e.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,3}*24,{24,24}}});
pl_warrior_sonic_swing_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,7}*24,{24,24}}}); pl_warrior_sonic_swing_e.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,7}*24,{24,24}}});
} }
ANIMATION_DATA["WARRIOR_SWINGSWORD_N"]=pl_warrior_swing_n; ANIMATION_DATA["WARRIOR_SWINGSWORD_N"]=pl_warrior_swing_n;
ANIMATION_DATA["WARRIOR_SWINGSWORD_E"]=pl_warrior_swing_e; ANIMATION_DATA["WARRIOR_SWINGSWORD_E"]=pl_warrior_swing_e;
@ -92,13 +93,13 @@ void sig::Animation::InitializeAnimations(){
ANIMATION_DATA["WARRIOR_SWINGSONICSWORD_W"]=pl_warrior_sonic_swing_w; ANIMATION_DATA["WARRIOR_SWINGSONICSWORD_W"]=pl_warrior_sonic_swing_w;
//Ranger animations //Ranger animations
SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,"RANGER"); SetupClassWalkIdleAnimations(GFX["nico-ranger.png"],"RANGER");
Animate2D::FrameSequence pl_ranger_shoot_s,pl_ranger_shoot_n,pl_ranger_shoot_e,pl_ranger_shoot_w; 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++){ 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_s.AddFrame({&GFX["nico-ranger.png"],{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_n.AddFrame({&GFX["nico-ranger.png"],{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_e.AddFrame({&GFX["nico-ranger.png"],{vi2d{3+i,3}*24,{24,24}}});
pl_ranger_shoot_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,2}*24,{24,24}}}); pl_ranger_shoot_w.AddFrame({&GFX["nico-ranger.png"],{vi2d{3+i,2}*24,{24,24}}});
} }
ANIMATION_DATA["RANGER_SHOOT_S"]=pl_ranger_shoot_s; ANIMATION_DATA["RANGER_SHOOT_S"]=pl_ranger_shoot_s;
ANIMATION_DATA["RANGER_SHOOT_N"]=pl_ranger_shoot_n; ANIMATION_DATA["RANGER_SHOOT_N"]=pl_ranger_shoot_n;
@ -106,107 +107,107 @@ void sig::Animation::InitializeAnimations(){
ANIMATION_DATA["RANGER_SHOOT_W"]=pl_ranger_shoot_w; ANIMATION_DATA["RANGER_SHOOT_W"]=pl_ranger_shoot_w;
//Wizard animations //Wizard animations
SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,"WIZARD"); SetupClassWalkIdleAnimations(GFX["nico-wizard.png"],"WIZARD");
Animate2D::FrameSequence pl_wizard_idle_attack_s; Animate2D::FrameSequence pl_wizard_idle_attack_s;
pl_wizard_idle_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); pl_wizard_idle_attack_s.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,0}*24,{24,24}}});
ANIMATION_DATA["WIZARD_IDLE_ATTACK_S"]=pl_wizard_idle_attack_s; ANIMATION_DATA["WIZARD_IDLE_ATTACK_S"]=pl_wizard_idle_attack_s;
Animate2D::FrameSequence pl_wizard_idle_attack_e; Animate2D::FrameSequence pl_wizard_idle_attack_e;
pl_wizard_idle_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); pl_wizard_idle_attack_e.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,3}*24,{24,24}}});
ANIMATION_DATA["WIZARD_IDLE_ATTACK_E"]=pl_wizard_idle_attack_e; ANIMATION_DATA["WIZARD_IDLE_ATTACK_E"]=pl_wizard_idle_attack_e;
Animate2D::FrameSequence pl_wizard_idle_attack_w; Animate2D::FrameSequence pl_wizard_idle_attack_w;
pl_wizard_idle_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); pl_wizard_idle_attack_w.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,2}*24,{24,24}}});
ANIMATION_DATA["WIZARD_IDLE_ATTACK_W"]=pl_wizard_idle_attack_w; ANIMATION_DATA["WIZARD_IDLE_ATTACK_W"]=pl_wizard_idle_attack_w;
Animate2D::FrameSequence pl_wizard_idle_attack_n; Animate2D::FrameSequence pl_wizard_idle_attack_n;
pl_wizard_idle_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); pl_wizard_idle_attack_n.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,1}*24,{24,24}}});
ANIMATION_DATA["WIZARD_IDLE_ATTACK_N"]=pl_wizard_idle_attack_n; ANIMATION_DATA["WIZARD_IDLE_ATTACK_N"]=pl_wizard_idle_attack_n;
Animate2D::FrameSequence pl_wizard_attack_s(0.2); Animate2D::FrameSequence pl_wizard_attack_s(0.2);
for(int i=0;i<3;i++){ for(int i=0;i<3;i++){
pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,0}*24,{24,24}}}); pl_wizard_attack_s.AddFrame({&GFX["nico-wizard.png"],{vi2d{4+i,0}*24,{24,24}}});
if(i==1){ if(i==1){
pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); pl_wizard_attack_s.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,0}*24,{24,24}}});
} }
} }
ANIMATION_DATA["WIZARD_ATTACK_S"]=pl_wizard_attack_s; ANIMATION_DATA["WIZARD_ATTACK_S"]=pl_wizard_attack_s;
Animate2D::FrameSequence pl_wizard_attack_e(0.2); Animate2D::FrameSequence pl_wizard_attack_e(0.2);
for(int i=0;i<3;i++){ for(int i=0;i<3;i++){
pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,3}*24,{24,24}}}); pl_wizard_attack_e.AddFrame({&GFX["nico-wizard.png"],{vi2d{4+i,3}*24,{24,24}}});
if(i==1){ if(i==1){
pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); pl_wizard_attack_e.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,3}*24,{24,24}}});
} }
} }
ANIMATION_DATA["WIZARD_ATTACK_E"]=pl_wizard_attack_e; ANIMATION_DATA["WIZARD_ATTACK_E"]=pl_wizard_attack_e;
Animate2D::FrameSequence pl_wizard_attack_w(0.2); Animate2D::FrameSequence pl_wizard_attack_w(0.2);
for(int i=0;i<3;i++){ for(int i=0;i<3;i++){
pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,2}*24,{24,24}}}); pl_wizard_attack_w.AddFrame({&GFX["nico-wizard.png"],{vi2d{4+i,2}*24,{24,24}}});
if(i==1){ if(i==1){
pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); pl_wizard_attack_w.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,2}*24,{24,24}}});
} }
} }
ANIMATION_DATA["WIZARD_ATTACK_W"]=pl_wizard_attack_w; ANIMATION_DATA["WIZARD_ATTACK_W"]=pl_wizard_attack_w;
Animate2D::FrameSequence pl_wizard_attack_n(0.2); Animate2D::FrameSequence pl_wizard_attack_n(0.2);
for(int i=0;i<3;i++){ for(int i=0;i<3;i++){
pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,1}*24,{24,24}}}); pl_wizard_attack_n.AddFrame({&GFX["nico-wizard.png"],{vi2d{4+i,1}*24,{24,24}}});
if(i==1){ if(i==1){
pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); pl_wizard_attack_n.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,1}*24,{24,24}}});
} }
} }
ANIMATION_DATA["WIZARD_ATTACK_N"]=pl_wizard_attack_n; ANIMATION_DATA["WIZARD_ATTACK_N"]=pl_wizard_attack_n;
Animate2D::FrameSequence pl_wizard_cast_s(0.1); Animate2D::FrameSequence pl_wizard_cast_s(0.1);
for(int i=0;i<2;i++){ for(int i=0;i<2;i++){
pl_wizard_cast_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{7+i,0}*24,{24,24}}}); pl_wizard_cast_s.AddFrame({&GFX["nico-wizard.png"],{vi2d{7+i,0}*24,{24,24}}});
} }
ANIMATION_DATA["WIZARD_CAST_S"]=pl_wizard_cast_s; ANIMATION_DATA["WIZARD_CAST_S"]=pl_wizard_cast_s;
Animate2D::FrameSequence pl_wizard_cast_e(0.1); Animate2D::FrameSequence pl_wizard_cast_e(0.1);
for(int i=0;i<2;i++){ for(int i=0;i<2;i++){
pl_wizard_cast_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{7+i,3}*24,{24,24}}}); pl_wizard_cast_e.AddFrame({&GFX["nico-wizard.png"],{vi2d{7+i,3}*24,{24,24}}});
} }
ANIMATION_DATA["WIZARD_CAST_E"]=pl_wizard_cast_e; ANIMATION_DATA["WIZARD_CAST_E"]=pl_wizard_cast_e;
Animate2D::FrameSequence pl_wizard_cast_n(0.1); Animate2D::FrameSequence pl_wizard_cast_n(0.1);
for(int i=0;i<2;i++){ for(int i=0;i<2;i++){
pl_wizard_cast_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{7+i,1}*24,{24,24}}}); pl_wizard_cast_n.AddFrame({&GFX["nico-wizard.png"],{vi2d{7+i,1}*24,{24,24}}});
} }
ANIMATION_DATA["WIZARD_CAST_N"]=pl_wizard_cast_n; ANIMATION_DATA["WIZARD_CAST_N"]=pl_wizard_cast_n;
Animate2D::FrameSequence pl_wizard_cast_w(0.1); Animate2D::FrameSequence pl_wizard_cast_w(0.1);
for(int i=0;i<2;i++){ for(int i=0;i<2;i++){
pl_wizard_cast_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{7+i,2}*24,{24,24}}}); pl_wizard_cast_w.AddFrame({&GFX["nico-wizard.png"],{vi2d{7+i,2}*24,{24,24}}});
} }
ANIMATION_DATA["WIZARD_CAST_W"]=pl_wizard_cast_w; ANIMATION_DATA["WIZARD_CAST_W"]=pl_wizard_cast_w;
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Back,5,{64,64},"GROUND_SLAM_ATTACK_BACK",{0.02,Animate2D::Style::OneShot}); CreateHorizontalAnimationSequence("ground-slam-attack-back.png",5,{64,64},{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Front,5,{64,64},"GROUND_SLAM_ATTACK_FRONT",{0.02,Animate2D::Style::OneShot}); CreateHorizontalAnimationSequence("ground-slam-attack-front.png",5,{64,64},{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_Battlecry_Effect,5,{84,84},"BATTLECRY_EFFECT",{0.02,Animate2D::Style::OneShot}); CreateHorizontalAnimationSequence("battlecry_effect.png",5,{84,84},{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_SonicSlash,4,{60,60},"SONICSLASH",{0.04,Animate2D::Style::OneShot}); CreateHorizontalAnimationSequence("sonicslash.png",4,{60,60},{0.04,Animate2D::Style::OneShot});
CreateStillAnimation(game->GFX_EnergyBolt,{24,24},"ENERGY_BOLT"); CreateStillAnimation("energy_bolt.png",{24,24});
CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},"ENERGY_PARTICLE"); CreateHorizontalAnimationSequence("energy_particle.png",3,{3,3});
CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},"SPLASH_EFFECT",{0.05}); CreateHorizontalAnimationSequence("splash_effect.png",5,{24,24},{0.05});
CreateStillAnimation(game->GFX_BulletCircle,{3,3},"DOT_PARTICLE"); CreateStillAnimation("circle.png",{3,3});
CreateHorizontalAnimationSequence(game->GFX_LightningBolt,5,{24,24},"LIGHTNING_BOLT",{0.03,Animate2D::Style::PingPong}); CreateHorizontalAnimationSequence("lightning_bolt.png",5,{24,24},{0.03,Animate2D::Style::PingPong});
CreateStillAnimation(game->GFX_LightningBoltParticle1,{5,5},"LIGHTNING_BOLT_PARTICLE1"); CreateStillAnimation("lightning_bolt_part1.png",{5,5});
CreateStillAnimation(game->GFX_LightningBoltParticle2,{5,5},"LIGHTNING_BOLT_PARTICLE2"); CreateStillAnimation("lightning_bolt_part2.png",{5,5});
CreateStillAnimation(game->GFX_LightningBoltParticle3,{5,5},"LIGHTNING_BOLT_PARTICLE3"); CreateStillAnimation("lightning_bolt_part3.png",{5,5});
CreateStillAnimation(game->GFX_LightningBoltParticle4,{5,5},"LIGHTNING_BOLT_PARTICLE4"); CreateStillAnimation("lightning_bolt_part4.png",{5,5});
CreateStillAnimation(game->GFX_ChainLightning,{1,9},"CHAIN_LIGHTNING"); CreateStillAnimation("chain_lightning.png",{1,9});
CreateHorizontalAnimationSequence(game->GFX_LightningSplash,5,{24,24},"LIGHTNING_SPLASH"); CreateHorizontalAnimationSequence("lightning_splash_effect.png",5,{24,24});
CreateStillAnimation(game->GFX_Meteor,{192,192},"METEOR"); CreateStillAnimation("meteor.png",{192,192});
for(int i=0;i<5;i++){ for(int i=0;i<5;i++){
Animate2D::FrameSequence firering; Animate2D::FrameSequence firering;
firering.AddFrame({&game->GFX_LightningSplash,{{i*24,0},{24,24}}}); firering.AddFrame({&GFX["fire_ring"+std::to_string(i)+".png"],{{0,0},{24,24}}});
ANIMATION_DATA["FIRE_RING"+std::to_string(i+1)]=firering; ANIMATION_DATA["fire_ring"+std::to_string(i)+".png"]=firering;
} }
CreateStillAnimation(game->GFX_Arrow,{24,24},"ARROW"); CreateStillAnimation("arrow.png",{24,24});
CreateStillAnimation(game->GFX_ChargedArrow,{48,48},"CHARGED_ARROW"); CreateStillAnimation("charged_shot_arrow.png",{48,48});
CreateStillAnimation(game->GFX_Laser,{5,1},"LASER"); CreateStillAnimation("laser.png",{5,1});
CreateStillAnimation(game->GFX_RangeIndicator,{24,24},"RANGE_INDICATOR"); CreateStillAnimation("range_indicator.png",{24,24});
} }
void sig::Animation::SetupPlayerAnimations(){ void sig::Animation::SetupPlayerAnimations(){

@ -10,7 +10,7 @@ INCLUDE_game
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:finalDistance(geom2d::line(pos,targetPos).length()),acc(PI/2*"Ranger.Auto Attack.ArrowSpd"_F), :finalDistance(geom2d::line(pos,targetPos).length()),acc(PI/2*"Ranger.Auto Attack.ArrowSpd"_F),
Bullet(pos,vel,radius,damage, Bullet(pos,vel,radius,damage,
"ARROW",upperLevel,false,INFINITE,true,friendly,col){} "arrow.png",upperLevel,false,INFINITE,true,friendly,col){}
void Arrow::Update(float fElapsedTime){ void Arrow::Update(float fElapsedTime){
float speed=vel.mag(); float speed=vel.mag();
@ -26,7 +26,7 @@ bool Arrow::PlayerHit(Player*player)
{ {
deactivated=true; deactivated=true;
fadeOutTime=0.2f; fadeOutTime=0.2f;
game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"SPLASH_EFFECT",upperLevel,player->GetSizeMult(),0.25)); game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"splash_effect.png",upperLevel,player->GetSizeMult(),0.25));
return false; return false;
} }
@ -34,6 +34,6 @@ bool Arrow::MonsterHit(Monster& monster)
{ {
deactivated=true; deactivated=true;
fadeOutTime=0.2f; fadeOutTime=0.2f;
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"SPLASH_EFFECT",upperLevel,monster.GetSizeMult(),0.25)); game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"splash_effect.png",upperLevel,monster.GetSizeMult(),0.25));
return false; return false;
} }

@ -5,6 +5,7 @@
INCLUDE_ANIMATION_DATA INCLUDE_ANIMATION_DATA
INCLUDE_game INCLUDE_game
INCLUDE_GFX
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale) Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale)
:pos(pos),vel(vel),radius(radius),damage(damage),col(col),friendly(friendly),upperLevel(upperLevel),scale(scale){}; :pos(pos),vel(vel),radius(radius),damage(damage),col(col),friendly(friendly),upperLevel(upperLevel),scale(scale){};
@ -36,8 +37,8 @@ void Bullet::Draw(){
if(animated){ if(animated){
game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotates?atan2(vel.y,vel.x)-PI/2:0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,lerp(col.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))}); game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotates?atan2(vel.y,vel.x)-PI/2:0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,lerp(col.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))});
} else { } else {
game->view.DrawDecal(pos-game->GFX_BulletCircle.Sprite()->Size()*scale/2,game->GFX_BulletCircle.Decal(),scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,lerp(col.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))}); game->view.DrawDecal(pos-GFX["circle.png"].Sprite()->Size()*scale/2,GFX["circle.png"].Decal(),scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,lerp(col.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))});
game->view.DrawDecal(pos-game->GFX_BulletCircle.Sprite()->Size()*scale/2,game->GFX_BulletCircleOutline.Decal(),scale,fadeOutTime==0?WHITE:Pixel{WHITE.r,WHITE.g,WHITE.b,lerp(WHITE.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))}); game->view.DrawDecal(pos-GFX["circle.png"].Sprite()->Size()*scale/2,GFX["circle_outline.png"].Decal(),scale,fadeOutTime==0?WHITE:Pixel{WHITE.r,WHITE.g,WHITE.b,lerp(WHITE.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime))});
} }
} }

@ -10,14 +10,14 @@ INCLUDE_game
ChargedArrow::ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) ChargedArrow::ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:lastLaserPos(pos), :lastLaserPos(pos),
Bullet(pos,vel,radius,damage, Bullet(pos,vel,radius,damage,
"CHARGED_ARROW",upperLevel,true,INFINITE,true,friendly,col){} "charged_shot_arrow.png",upperLevel,true,INFINITE,true,friendly,col){}
void ChargedArrow::Update(float fElapsedTime){ void ChargedArrow::Update(float fElapsedTime){
geom2d::line lineToCurrentPos(geom2d::line(lastLaserPos,pos)); geom2d::line lineToCurrentPos(geom2d::line(lastLaserPos,pos));
float dist=lineToCurrentPos.length(); float dist=lineToCurrentPos.length();
if(dist>=1){ if(dist>=1){
vf2d midpoint(lineToCurrentPos.rpoint(0.5)); vf2d midpoint(lineToCurrentPos.rpoint(0.5));
game->AddEffect(std::make_unique<Effect>(midpoint,0.1,"LASER",upperLevel,vf2d{1,dist},0.3,vf2d{},Pixel{192,128,238},atan2(pos.y-lastLaserPos.y,pos.x-lastLaserPos.x)+PI/2,0,true)); game->AddEffect(std::make_unique<Effect>(midpoint,0.1,"laser.png",upperLevel,vf2d{1,dist},0.3,vf2d{},Pixel{192,128,238},atan2(pos.y-lastLaserPos.y,pos.x-lastLaserPos.x)+PI/2,0,true));
lastLaserPos=pos; lastLaserPos=pos;
} }
} }

@ -26,6 +26,7 @@ std::vector<Monster>MONSTER_LIST;
std::vector<MonsterSpawner>SPAWNER_LIST; std::vector<MonsterSpawner>SPAWNER_LIST;
std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST; std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
std::vector<std::unique_ptr<Bullet>>BULLET_LIST; std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
safemap<std::string,Renderable>GFX;
safemap<std::string,MapName>LEVEL_NAMES; safemap<std::string,MapName>LEVEL_NAMES;
utils::datafile DATA; utils::datafile DATA;
Crawler*game; Crawler*game;
@ -83,41 +84,18 @@ bool Crawler::OnUserCreate(){
camera.SetWorldBoundary({0,0},WORLD_SIZE*24); camera.SetWorldBoundary({0,0},WORLD_SIZE*24);
camera.EnableWorldBoundary(false); camera.EnableWorldBoundary(false);
#undef LoadImage //Dumb Windows. for(auto&val:DATA["Images"].GetKeys()){
auto LoadImage=[&](Renderable&r,std::string key){ std::string key=val.first;
r.Load(GetString("GFX_Prefix")+GetString(key)); std::string imgFile=DATA["Images"][key].GetString();
}; std::cout<<"Loading image "+imgFile+"..."<<std::endl;
#define LOADIMG(name) LoadImage(name,"Images."#name); GFX[imgFile];
if(GFX[imgFile].Load("GFX_Prefix"_S+imgFile)!=rcode::OK){
//Graphics std::cout<<" WARNING! Failed to load "+imgFile+"!";
LOADIMG(GFX_Warrior_Sheet) throw;
LOADIMG(GFX_Circle) }
LOADIMG(GFX_Effect_GroundSlam_Back) }
LOADIMG(GFX_Effect_GroundSlam_Front) GFX.SetInitialized();
LOADIMG(GFX_Heart) std::cout<<GFX.size()<<" images have been loaded."<<std::endl;
LOADIMG(GFX_BLOCK_BUBBLE)
LOADIMG(GFX_Ranger_Sheet)
LOADIMG(GFX_Wizard_Sheet)
LOADIMG(GFX_Battlecry_Effect)
LOADIMG(GFX_Mana)
LOADIMG(GFX_SonicSlash)
LOADIMG(GFX_BulletCircle)
LOADIMG(GFX_BulletCircleOutline)
LOADIMG(GFX_EnergyBolt)
LOADIMG(GFX_EnergyParticle)
LOADIMG(GFX_Splash_Effect)
LOADIMG(GFX_LightningBolt)
LOADIMG(GFX_LightningBoltParticle1)
LOADIMG(GFX_LightningBoltParticle2)
LOADIMG(GFX_LightningBoltParticle3)
LOADIMG(GFX_LightningBoltParticle4)
LOADIMG(GFX_ChainLightning)
LOADIMG(GFX_LightningSplash)
LOADIMG(GFX_Meteor)
LOADIMG(GFX_Arrow)
LOADIMG(GFX_Laser)
LOADIMG(GFX_ChargedArrow)
LOADIMG(GFX_RangeIndicator)
Monster::InitializeStrategies(); Monster::InitializeStrategies();
//Animations //Animations
@ -698,7 +676,7 @@ void Crawler::RenderWorld(float fElapsedTime){
if(player->GetZ()>0){ if(player->GetZ()>0){
vf2d shadowScale=vf2d{8*player->GetSizeMult()/3.f,1}/std::max(1.f,player->GetZ()/24); vf2d shadowScale=vf2d{8*player->GetSizeMult()/3.f,1}/std::max(1.f,player->GetZ()/24);
view.DrawDecal(player->GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*player->GetSizeMult()},GFX_Circle.Decal(),shadowScale,BLACK); view.DrawDecal(player->GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*player->GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
} }
for(Effect*e:backgroundEffectsLower){ for(Effect*e:backgroundEffectsLower){
e->Draw(); e->Draw();
@ -710,7 +688,7 @@ void Crawler::RenderWorld(float fElapsedTime){
RenderPlayer(player->GetPos(),{1,1}); RenderPlayer(player->GetPos(),{1,1});
} }
if(player->GetState()==State::BLOCK){ if(player->GetState()==State::BLOCK){
view.DrawDecal(player->GetPos()-vf2d{12,12},GFX_BLOCK_BUBBLE.Decal()); view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal());
} }
for(Monster*m:monstersAfterLower){ for(Monster*m:monstersAfterLower){
m->Draw(); m->Draw();
@ -726,15 +704,15 @@ void Crawler::RenderWorld(float fElapsedTime){
float precastSize=GetPlayer()->castPrepAbility->precastInfo.size; float precastSize=GetPlayer()->castPrepAbility->precastInfo.size;
float precastRange=GetPlayer()->castPrepAbility->precastInfo.range; float precastRange=GetPlayer()->castPrepAbility->precastInfo.range;
vf2d scale=vf2d{precastSize,precastSize}*2/3.f; vf2d scale=vf2d{precastSize,precastSize}*2/3.f;
vf2d centerPoint=GetWorldMousePos()-vf2d{game->GFX_Circle.Sprite()->width*scale.x/2,game->GFX_Circle.Sprite()->height*scale.y/2}; vf2d centerPoint=GetWorldMousePos()-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
float distance=sqrt(pow(player->GetX()-GetWorldMousePos().x,2)+pow(player->GetY()-GetWorldMousePos().y,2)); float distance=sqrt(pow(player->GetX()-GetWorldMousePos().x,2)+pow(player->GetY()-GetWorldMousePos().y,2));
if(distance>precastRange){//Clamp the distance. if(distance>precastRange){//Clamp the distance.
vf2d pointToCursor = {GetWorldMousePos().x-player->GetX(),GetWorldMousePos().y-player->GetY()}; vf2d pointToCursor = {GetWorldMousePos().x-player->GetX(),GetWorldMousePos().y-player->GetY()};
pointToCursor=pointToCursor.norm()*precastRange; pointToCursor=pointToCursor.norm()*precastRange;
vf2d centerPoint=player->GetPos()+pointToCursor-vf2d{game->GFX_Circle.Sprite()->width*scale.x/2,game->GFX_Circle.Sprite()->height*scale.y/2}; vf2d centerPoint=player->GetPos()+pointToCursor-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
view.DrawDecal(centerPoint,GFX_Circle.Decal(),scale,{255,0,0,96}); view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
} else { } else {
view.DrawDecal(centerPoint,GFX_Circle.Decal(),scale,{255,0,0,96}); view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
} }
} }
}; };
@ -903,8 +881,8 @@ void Crawler::RenderHud(){
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},2.f); DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},2.f);
} }
DrawDecal({2,2},GFX_Heart.Decal()); DrawDecal({2,2},GFX["heart.png"].Decal());
DrawDecal({2,20},GFX_Mana.Decal()); DrawDecal({2,20},GFX["mana.png"].Decal());
std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X"; std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X";
std::string text_mana=std::to_string(player->GetMana()); std::string text_mana=std::to_string(player->GetMana());
DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2}); DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2});
@ -1307,7 +1285,7 @@ datafiledoubledata Crawler::GetDoubleList(std::string key){
int main() int main()
{ {
Crawler demo; Crawler demo;
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4, false, true)) if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4, false))
demo.Start(); demo.Start();
return 0; return 0;
@ -1381,6 +1359,11 @@ bool Crawler::IsReflectiveTile(TilesheetData tileSheet,int tileID){
return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end(); return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end();
} }
bool Crawler::OnUserDestroy(){
GFX.Reset();
return true;
}
void Crawler::InitializeLevels(){ void Crawler::InitializeLevels(){
#define INITLEVEL(map) \ #define INITLEVEL(map) \
InitializeLevel("map_path"_S + "Levels."#map ## _S,map); \ InitializeLevel("map_path"_S + "Levels."#map ## _S,map); \

@ -17,16 +17,7 @@ class Crawler : public olc::PixelGameEngine
friend class sig::Animation; friend class sig::Animation;
Camera2D camera; Camera2D camera;
std::unique_ptr<Player>player; std::unique_ptr<Player>player;
Renderable GFX_Warrior_Sheet,
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_LightningBolt,GFX_LightningBoltParticle1,
GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4,
GFX_ChainLightning,GFX_LightningSplash,GFX_Meteor,GFX_Arrow,
GFX_Laser,GFX_ChargedArrow,GFX_RangeIndicator;
public: public:
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt,GFX_Circle;
Pathfinding pathfinder; Pathfinding pathfinder;
static Key KEY_ABILITY1; static Key KEY_ABILITY1;
static Key KEY_ABILITY2; static Key KEY_ABILITY2;
@ -60,6 +51,7 @@ public:
Crawler(); Crawler();
bool OnUserCreate() override; bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override; bool OnUserUpdate(float fElapsedTime) override;
bool OnUserDestroy() override;
public: public:
geom2d::rect<int>NO_COLLISION={}; geom2d::rect<int>NO_COLLISION={};
vi2d WORLD_SIZE={120,8}; vi2d WORLD_SIZE={120,8};

@ -6,12 +6,12 @@
#define INCLUDE_game extern Crawler*game; #define INCLUDE_game extern Crawler*game;
#define INCLUDE_MONSTER_DATA extern std::map<int,MonsterData>MONSTER_DATA; #define INCLUDE_MONSTER_DATA extern std::map<int,MonsterData>MONSTER_DATA;
#define INCLUDE_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>BULLET_LIST; #define INCLUDE_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
#define INCLUDE_PARTICLE_LIST extern std::vector<Particle>PARTICLE_LIST;
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST; #define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
#define INCLUDE_DATA extern utils::datafile DATA; #define INCLUDE_DATA extern utils::datafile DATA;
#define INCLUDE_STRATEGY_DATA extern safemap<std::string,int>STRATEGY_DATA; #define INCLUDE_STRATEGY_DATA extern safemap<std::string,int>STRATEGY_DATA;
#define INCLUDE_STRATEGY_ID_DATA extern safemap<std::string,int>STRATEGY_ID_DATA; #define INCLUDE_STRATEGY_ID_DATA extern safemap<std::string,int>STRATEGY_ID_DATA;
#define INCLUDE_TILE_ANIMATION_DATA extern std::map<int,std::vector<std::pair<int,float>>>TILE_ANIMATION_DATA; #define INCLUDE_TILE_ANIMATION_DATA extern std::map<int,std::vector<std::pair<int,float>>>TILE_ANIMATION_DATA;
#define INCLUDE_GFX extern safemap<std::string,Renderable>GFX;
#define ACCESS_PLAYER Player*p=game->GetPlayer(); #define ACCESS_PLAYER Player*p=game->GetPlayer();

@ -6,14 +6,14 @@
INCLUDE_ANIMATION_DATA INCLUDE_ANIMATION_DATA
INCLUDE_game INCLUDE_game
Effect::Effect(vf2d pos,float lifetime,std::string animation,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending) Effect::Effect(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending)
:Effect::Effect(pos,lifetime,animation,upperLevel,vf2d{size,size},fadeout,spd,col,rotation,rotationSpd,additiveBlending){ :Effect::Effect(pos,lifetime,imgFile,upperLevel,vf2d{size,size},fadeout,spd,col,rotation,rotationSpd,additiveBlending){
this->animation.AddState(animation,ANIMATION_DATA[animation]); this->animation.AddState(imgFile,ANIMATION_DATA[imgFile]);
} }
Effect::Effect(vf2d pos,float lifetime,std::string animation,bool upperLevel,vf2d size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending) Effect::Effect(vf2d pos,float lifetime,std::string imgFile,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){ :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]); this->animation.AddState(imgFile,ANIMATION_DATA[imgFile]);
} }
bool Effect::Update(float fElapsedTime){ bool Effect::Update(float fElapsedTime){

@ -17,8 +17,8 @@ struct Effect{
private: private:
bool dead=false; bool dead=false;
public: public:
Effect(vf2d pos,float lifetime,std::string 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,std::string imgFile,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,std::string 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); Effect(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
virtual bool Update(float fElapsedTime); virtual bool Update(float fElapsedTime);
Animate2D::Frame GetFrame(); Animate2D::Frame GetFrame();
virtual void Draw(); virtual void Draw();
@ -32,7 +32,7 @@ private:
}; };
struct Meteor:Effect{ struct Meteor:Effect{
Meteor(vf2d pos,float lifetime,std::string 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); Meteor(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
float startLifetime=0; float startLifetime=0;
bool shakeField=false; bool shakeField=false;
bool Update(float fElapsedTime)override; bool Update(float fElapsedTime)override;
@ -40,7 +40,7 @@ struct Meteor:Effect{
}; };
struct PulsatingFire:Effect{ struct PulsatingFire:Effect{
PulsatingFire(vf2d pos,float lifetime,std::string 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); PulsatingFire(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
std::vector<float>pulsatingFireValues; std::vector<float>pulsatingFireValues;
float lastParticleTimer=0; float lastParticleTimer=0;
float lastDamageTimer=0; float lastDamageTimer=0;

@ -8,13 +8,13 @@ INCLUDE_game
EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage, :Bullet(pos,vel,radius,damage,
"ENERGY_BOLT",upperLevel,false,INFINITE,true,friendly,col){} "energy_bolt.png",upperLevel,false,INFINITE,true,friendly,col){}
void EnergyBolt::Update(float fElapsedTime){ void EnergyBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
if(lastParticleSpawn==0){ if(lastParticleSpawn==0){
lastParticleSpawn="Wizard.Auto Attack.ParticleFrequency"_F; lastParticleSpawn="Wizard.Auto Attack.ParticleFrequency"_F;
game->AddEffect(std::make_unique<Effect>(pos,"Wizard.Auto Attack.ParticleLifetimeRange"_FRange,"ENERGY_PARTICLE",upperLevel,"Wizard.Auto Attack.ParticleSizeRange"_FRange,"Wizard.Auto Attack.ParticleFadeoutTime"_F,vf2d{"Wizard.Auto Attack.ParticleSpeedRange"_FRange,"Wizard.Auto Attack.ParticleSpeedRange"_FRange})); game->AddEffect(std::make_unique<Effect>(pos,"Wizard.Auto Attack.ParticleLifetimeRange"_FRange,"energy_particle.png",upperLevel,"Wizard.Auto Attack.ParticleSizeRange"_FRange,"Wizard.Auto Attack.ParticleFadeoutTime"_F,vf2d{"Wizard.Auto Attack.ParticleSpeedRange"_FRange,"Wizard.Auto Attack.ParticleSpeedRange"_FRange}));
} }
} }
@ -22,7 +22,7 @@ bool EnergyBolt::PlayerHit(Player*player)
{ {
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Auto Attack.BulletHitFadeoutTime"_F; fadeOutTime="Wizard.Auto Attack.BulletHitFadeoutTime"_F;
game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"SPLASH_EFFECT",upperLevel,player->GetSizeMult(),"Wizard.Auto Attack.SplashEffectFadeoutTime"_F)); game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"splash_effect.png",upperLevel,player->GetSizeMult(),"Wizard.Auto Attack.SplashEffectFadeoutTime"_F));
return false; return false;
} }
@ -30,6 +30,6 @@ bool EnergyBolt::MonsterHit(Monster& monster)
{ {
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Auto Attack.BulletHitFadeoutTime"_F; fadeOutTime="Wizard.Auto Attack.BulletHitFadeoutTime"_F;
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"SPLASH_EFFECT",upperLevel,monster.GetSizeMult(),"Wizard.Auto Attack.SplashEffectFadeoutTime"_F)); game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"splash_effect.png",upperLevel,monster.GetSizeMult(),"Wizard.Auto Attack.SplashEffectFadeoutTime"_F));
return false; return false;
} }

@ -9,13 +9,13 @@ INCLUDE_MONSTER_LIST
FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage, :Bullet(pos,vel,radius,damage,
"ENERGY_BOLT",upperLevel,false,INFINITE,true,friendly,col){} "energy_bolt.png",upperLevel,false,INFINITE,true,friendly,col){}
void FireBolt::Update(float fElapsedTime){ void FireBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
if(lastParticleSpawn==0){ if(lastParticleSpawn==0){
lastParticleSpawn="Wizard.Ability 1.ParticleFrequency"_F; lastParticleSpawn="Wizard.Ability 1.ParticleFrequency"_F;
game->AddEffect(std::make_unique<Effect>(pos,"Wizard.Ability 1.ParticleLifetimeRange"_FRange,"ENERGY_PARTICLE",upperLevel,"Wizard.Ability 1.ParticleSizeRange"_FRange,"Wizard.Ability 1.ParticleFadeoutTime"_F,vf2d{"Wizard.Ability 1.ParticleXSpeedRange"_FRange,"Wizard.Ability 1.ParticleYSpeedRange"_FRange},Pixel{uint8_t("Wizard.Ability 1.ParticleRedRange"_FRange),uint8_t("Wizard.Ability 1.ParticleGreenRange"_FRange),uint8_t("Wizard.Ability 1.ParticleBlueRange"_FRange),uint8_t("Wizard.Ability 1.ParticleAlphaRange"_FRange)})); game->AddEffect(std::make_unique<Effect>(pos,"Wizard.Ability 1.ParticleLifetimeRange"_FRange,"energy_particle.png",upperLevel,"Wizard.Ability 1.ParticleSizeRange"_FRange,"Wizard.Ability 1.ParticleFadeoutTime"_F,vf2d{"Wizard.Ability 1.ParticleXSpeedRange"_FRange,"Wizard.Ability 1.ParticleYSpeedRange"_FRange},Pixel{uint8_t("Wizard.Ability 1.ParticleRedRange"_FRange),uint8_t("Wizard.Ability 1.ParticleGreenRange"_FRange),uint8_t("Wizard.Ability 1.ParticleBlueRange"_FRange),uint8_t("Wizard.Ability 1.ParticleAlphaRange"_FRange)}));
} }
} }
@ -23,7 +23,7 @@ bool FireBolt::PlayerHit(Player*player)
{ {
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Ability 1.BulletHitFadeoutTime"_F; fadeOutTime="Wizard.Ability 1.BulletHitFadeoutTime"_F;
game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"SPLASH_EFFECT",upperLevel,5,0.25,vf2d{},Pixel{240,120,60})); game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,"splash_effect.png",upperLevel,5,0.25,vf2d{},Pixel{240,120,60}));
return false; return false;
} }
@ -32,10 +32,10 @@ bool FireBolt::MonsterHit(Monster& monster)
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Ability 1.BulletHitFadeoutTime"_F; fadeOutTime="Wizard.Ability 1.BulletHitFadeoutTime"_F;
for(int i=0;i<"Wizard.Ability 1.BulletHitExplosionParticleCount"_I;i++){ for(int i=0;i<"Wizard.Ability 1.BulletHitExplosionParticleCount"_I;i++){
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),"Wizard.Ability 1.BulletHitExplosionParticleLifetimeRange"_FRange,"DOT_PARTICLE",upperLevel,"Wizard.Ability 1.BulletHitExplosionParticleSizeRange"_FRange,"Wizard.Ability 1.BulletHitExplosionParticleFadeoutTimeRange"_FRange,vf2d{"Wizard.Ability 1.BulletHitExplosionParticleSpeedRange"_FRange,"Wizard.Ability 1.BulletHitExplosionParticleSpeedRange"_FRange},Pixel{uint8_t("Wizard.Ability 1.BulletHitExplosionParticleRedRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleGreenRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleBlueRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleAlphaRange"_FRange)})); game->AddEffect(std::make_unique<Effect>(monster.GetPos(),"Wizard.Ability 1.BulletHitExplosionParticleLifetimeRange"_FRange,"circle.png",upperLevel,"Wizard.Ability 1.BulletHitExplosionParticleSizeRange"_FRange,"Wizard.Ability 1.BulletHitExplosionParticleFadeoutTimeRange"_FRange,vf2d{"Wizard.Ability 1.BulletHitExplosionParticleSpeedRange"_FRange,"Wizard.Ability 1.BulletHitExplosionParticleSpeedRange"_FRange},Pixel{uint8_t("Wizard.Ability 1.BulletHitExplosionParticleRedRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleGreenRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleBlueRange"_FRange),uint8_t("Wizard.Ability 1.BulletHitExplosionParticleAlphaRange"_FRange)}));
} }
game->SetupWorldShake("Wizard.Ability 1.WorldShakeTime"_F); game->SetupWorldShake("Wizard.Ability 1.WorldShakeTime"_F);
game->HurtEnemies(monster.GetPos(),"Wizard.Ability 1.BulletHitExplosionRange"_F/100*12,"Wizard.Ability 1.BulletHitExplosionDamageMult"_F*game->GetPlayer()->GetAttack(),OnUpperLevel(),0); game->HurtEnemies(monster.GetPos(),"Wizard.Ability 1.BulletHitExplosionRange"_F/100*12,"Wizard.Ability 1.BulletHitExplosionDamageMult"_F*game->GetPlayer()->GetAttack(),OnUpperLevel(),0);
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"SPLASH_EFFECT",upperLevel,"Wizard.Ability 1.BulletHitExplosionRange"_F/100*2,"Wizard.Ability 1.BulletHitExplosionFadeoutTime"_F,vf2d{},"Wizard.Ability 1.BulletHitExplosionColor"_Pixel)); game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,"splash_effect.png",upperLevel,"Wizard.Ability 1.BulletHitExplosionRange"_F/100*2,"Wizard.Ability 1.BulletHitExplosionFadeoutTime"_F,vf2d{},"Wizard.Ability 1.BulletHitExplosionColor"_Pixel));
return false; return false;
} }

@ -11,7 +11,7 @@ INCLUDE_EMITTER_LIST
LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage, :Bullet(pos,vel,radius,damage,
"LIGHTNING_BOLT",upperLevel,false,INFINITE,true,friendly,col){} "lightning_bolt.png",upperLevel,false,INFINITE,true,friendly,col){}
void LightningBolt::Update(float fElapsedTime){ void LightningBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
@ -21,16 +21,16 @@ void LightningBolt::Update(float fElapsedTime){
uint8_t brightness=uint8_t("Wizard.Ability 2.ParticleColorRange"_FRange); uint8_t brightness=uint8_t("Wizard.Ability 2.ParticleColorRange"_FRange);
switch(rand()%4){ switch(rand()%4){
case 0:{ case 0:{
game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"LIGHTNING_BOLT_PARTICLE1",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness})); game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part1.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness}));
}break; }break;
case 1:{ case 1:{
game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"LIGHTNING_BOLT_PARTICLE2",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness})); game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part2.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness}));
}break; }break;
case 2:{ case 2:{
game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"LIGHTNING_BOLT_PARTICLE3",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness})); game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part3.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness}));
}break; }break;
case 3:{ case 3:{
game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"LIGHTNING_BOLT_PARTICLE4",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness})); game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part4.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness}));
}break; }break;
} }
} }
@ -40,7 +40,7 @@ bool LightningBolt::PlayerHit(Player*player)
{ {
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Ability 2.BulletFadeoutTime"_F; fadeOutTime="Wizard.Ability 2.BulletFadeoutTime"_F;
game->AddEffect(std::make_unique<Effect>(player->GetPos(),"Wizard.Ability 2.SplashLifetime"_F,"LIGHTNING_SPLASH",upperLevel,player->GetSizeMult(),"Wizard.Ability 2.SplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.SplashRotationRange"_FRange)); game->AddEffect(std::make_unique<Effect>(player->GetPos(),"Wizard.Ability 2.SplashLifetime"_F,"lightning_splash_effect.png",upperLevel,player->GetSizeMult(),"Wizard.Ability 2.SplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.SplashRotationRange"_FRange));
return false; return false;
} }
@ -48,7 +48,7 @@ bool LightningBolt::MonsterHit(Monster& monster)
{ {
deactivated=true; deactivated=true;
fadeOutTime="Wizard.Ability 2.BulletFadeoutTime"_F; fadeOutTime="Wizard.Ability 2.BulletFadeoutTime"_F;
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),"Wizard.Ability 2.SplashLifetime"_F,"LIGHTNING_SPLASH",upperLevel,monster.GetSizeMult(),"Wizard.Ability 2.SplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.SplashRotationRange"_FRange)); game->AddEffect(std::make_unique<Effect>(monster.GetPos(),"Wizard.Ability 2.SplashLifetime"_F,"lightning_splash_effect.png",upperLevel,monster.GetSizeMult(),"Wizard.Ability 2.SplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.SplashRotationRange"_FRange));
int targetsHit=0; int targetsHit=0;
for(Monster&m:MONSTER_LIST){ for(Monster&m:MONSTER_LIST){
if(&m==&monster||monster.OnUpperLevel()!=m.OnUpperLevel())continue; if(&m==&monster||monster.OnUpperLevel()!=m.OnUpperLevel())continue;
@ -57,7 +57,7 @@ bool LightningBolt::MonsterHit(Monster& monster)
if(dist<="Wizard.Ability 2.LightningChainRadius"_F/100*24){ if(dist<="Wizard.Ability 2.LightningChainRadius"_F/100*24){
if(m.Hurt(game->GetPlayer()->GetAttack()*"Wizard.Ability 2.LightningChainDamageMult"_F,OnUpperLevel(),0)){ if(m.Hurt(game->GetPlayer()->GetAttack()*"Wizard.Ability 2.LightningChainDamageMult"_F,OnUpperLevel(),0)){
EMITTER_LIST.push_back(std::make_unique<LightningBoltEmitter>(LightningBoltEmitter(monster.GetPos(),m.GetPos(),"Wizard.Ability 2.LightningChainFrequency"_F,"Wizard.Ability 2.LightningChainLifetime"_F,upperLevel))); EMITTER_LIST.push_back(std::make_unique<LightningBoltEmitter>(LightningBoltEmitter(monster.GetPos(),m.GetPos(),"Wizard.Ability 2.LightningChainFrequency"_F,"Wizard.Ability 2.LightningChainLifetime"_F,upperLevel)));
game->AddEffect(std::make_unique<Effect>(m.GetPos(),"Wizard.Ability 2.LightningChainSplashLifetime"_F,"LIGHTNING_SPLASH",upperLevel,monster.GetSizeMult(),"Wizard.Ability 2.LightningChainSplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.LightningChainSplashRotationRange"_FRange)); game->AddEffect(std::make_unique<Effect>(m.GetPos(),"Wizard.Ability 2.LightningChainSplashLifetime"_F,"lightning_splash_effect.png",upperLevel,monster.GetSizeMult(),"Wizard.Ability 2.LightningChainSplashFadeoutTime"_F,vf2d{},WHITE,"Wizard.Ability 2.LightningChainSplashRotationRange"_FRange));
targetsHit++; targetsHit++;
} }
} }

@ -22,7 +22,7 @@ void LightningBoltEmitter::DrawLightningBolt(){
float targetDist=lineToTarget.length()*util::random(0.5); float targetDist=lineToTarget.length()*util::random(0.5);
targetAngle+=util::random((PI/2))-PI/4; targetAngle+=util::random((PI/2))-PI/4;
geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"CHAIN_LIGHTNING",upperLevel,vf2d{lightningLine.length(),0.2},0.2,vf2d{},WHITE,targetAngle,0,true)); game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2},0.2,vf2d{},WHITE,targetAngle,0,true));
int iterations=1; int iterations=1;
currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}; currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist};
while(iterations<MAX_ITERATIONS&&geom2d::line<float>(currentPos,endPos).length()>1){ while(iterations<MAX_ITERATIONS&&geom2d::line<float>(currentPos,endPos).length()>1){
@ -31,7 +31,7 @@ void LightningBoltEmitter::DrawLightningBolt(){
float targetDist=lineToTarget.length()*util::random(0.5); float targetDist=lineToTarget.length()*util::random(0.5);
targetAngle+=util::random((PI/2))-PI/4; targetAngle+=util::random((PI/2))-PI/4;
geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"CHAIN_LIGHTNING",upperLevel,vf2d{lightningLine.length(),0.2},0.2,vf2d{},WHITE,targetAngle,0,true)); game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2},0.2,vf2d{},WHITE,targetAngle,0,true));
currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}; currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist};
iterations++; iterations++;
} }

@ -2,12 +2,14 @@
#include "DEFINES.h" #include "DEFINES.h"
#include "Crawler.h" #include "Crawler.h"
#include "utils.h" #include "utils.h"
#include "safemap.h"
INCLUDE_game INCLUDE_game
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
INCLUDE_GFX
Meteor::Meteor(vf2d pos, float lifetime, std::string animation, bool upperLevel, vf2d size, float fadeout, vf2d spd, Pixel col, float rotation, float rotationSpd, bool additiveBlending) Meteor::Meteor(vf2d pos, float lifetime, std::string imgFile, bool upperLevel, vf2d size, float fadeout, vf2d spd, Pixel col, float rotation, float rotationSpd, bool additiveBlending)
:Effect(pos,lifetime,animation,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending),startLifetime(lifetime){ :Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending),startLifetime(lifetime){
} }
@ -22,10 +24,10 @@ bool Meteor::Update(float fElapsedTime){
float randomColorTintG=256*(1-util::random("Wizard.Ability 3.MeteorImpactParticleColorGVariance"_F))*(1-util::random("Wizard.Ability 3.MeteorImpactParticleColorGVariance"_F)); float randomColorTintG=256*(1-util::random("Wizard.Ability 3.MeteorImpactParticleColorGVariance"_F))*(1-util::random("Wizard.Ability 3.MeteorImpactParticleColorGVariance"_F));
float randomColorTintB="Wizard.Ability 3.MeteorImpactParticleColorBlueRange"_FRange; float randomColorTintB="Wizard.Ability 3.MeteorImpactParticleColorBlueRange"_FRange;
vf2d effectPos=vf2d{cos(randomAngle),sin(randomAngle)}*randomRange+meteorOffset; vf2d effectPos=vf2d{cos(randomAngle),sin(randomAngle)}*randomRange+meteorOffset;
game->AddEffect(std::make_unique<Effect>(effectPos,0,"DOT_PARTICLE",OnUpperLevel(),vf2d{util::random(2)+1,util::random(3)+1},util::random(3)+1,vf2d{util::random(10)-5,-util::random(20)-5},Pixel{255,uint8_t(randomColorTintG),uint8_t(randomColorTintB),uint8_t("Wizard.Ability 3.MeteorImpactParticleAlphaRange"_FRange)},0,0,true),effectPos.y<meteorOffset.y); game->AddEffect(std::make_unique<Effect>(effectPos,0,"circle.png",OnUpperLevel(),vf2d{util::random(2)+1,util::random(3)+1},util::random(3)+1,vf2d{util::random(10)-5,-util::random(20)-5},Pixel{255,uint8_t(randomColorTintG),uint8_t(randomColorTintB),uint8_t("Wizard.Ability 3.MeteorImpactParticleAlphaRange"_FRange)},0,0,true),effectPos.y<meteorOffset.y);
} }
game->HurtEnemies(pos,"Wizard.Ability 3.MeteorRadius"_F/100*24,game->GetPlayer()->GetAttack()*"Wizard.Ability 3.MeteorDamageMult"_F,OnUpperLevel(),0); game->HurtEnemies(pos,"Wizard.Ability 3.MeteorRadius"_F/100*24,game->GetPlayer()->GetAttack()*"Wizard.Ability 3.MeteorDamageMult"_F,OnUpperLevel(),0);
game->AddEffect(std::make_unique<PulsatingFire>(pos,"Wizard.Ability 3.FireRingLifetime"_F,"FIRE_RING1",OnUpperLevel(),vf2d{"Wizard.Ability 3.MeteorRadius"_F/100*2,"Wizard.Ability 3.MeteorRadius"_F/100*2},"Wizard.Ability 3.FireRingFadeoutTime"_F),true); game->AddEffect(std::make_unique<PulsatingFire>(pos,"Wizard.Ability 3.FireRingLifetime"_F,"fire_ring1.png",OnUpperLevel(),vf2d{"Wizard.Ability 3.MeteorRadius"_F/100*2,"Wizard.Ability 3.MeteorRadius"_F/100*2},"Wizard.Ability 3.FireRingFadeoutTime"_F),true);
} }
return Effect::Update(fElapsedTime); return Effect::Update(fElapsedTime);
} }
@ -34,8 +36,8 @@ void Meteor::Draw(){
if(lifetime>0){ if(lifetime>0){
vf2d scale=vf2d{192,64}/3.f*(startLifetime+1-lifetime)*0.25*size; vf2d scale=vf2d{192,64}/3.f*(startLifetime+1-lifetime)*0.25*size;
vf2d meteorOffset=vf2d{lifetime*"Wizard.Ability 3.MeteorXMovementMult"_I,0}*"Wizard.Ability 3.MeteorShadowStartingDist"_F; vf2d meteorOffset=vf2d{lifetime*"Wizard.Ability 3.MeteorXMovementMult"_I,0}*"Wizard.Ability 3.MeteorShadowStartingDist"_F;
vf2d centerPoint=pos-vf2d{game->GFX_Circle.Sprite()->width*scale.x/2,game->GFX_Circle.Sprite()->height*scale.y/2}; vf2d centerPoint=pos-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
game->view.DrawDecal(centerPoint+meteorOffset,game->GFX_Circle.Decal(),scale,{0,0,0,192}); game->view.DrawDecal(centerPoint+meteorOffset,GFX["circle.png"].Decal(),scale,{0,0,0,192});
} }
vf2d meteorOffset=pos+vf2d{lifetime*"Wizard.Ability 3.MeteorXMovementMult"_I,lifetime*"Wizard.Ability 3.MeteorYMovementMult"_I}*"Wizard.Ability 3.MeteorStartingDist"_F-vf2d{0,GetFrame().GetSourceRect().size.y/4.f}*size; vf2d meteorOffset=pos+vf2d{lifetime*"Wizard.Ability 3.MeteorXMovementMult"_I,lifetime*"Wizard.Ability 3.MeteorYMovementMult"_I}*"Wizard.Ability 3.MeteorStartingDist"_F-vf2d{0,GetFrame().GetSourceRect().size.y/4.f}*size;
if(lifetime<=0){ if(lifetime<=0){

@ -14,6 +14,7 @@ INCLUDE_game
INCLUDE_BULLET_LIST INCLUDE_BULLET_LIST
INCLUDE_DATA INCLUDE_DATA
INCLUDE_STRATEGY_DATA INCLUDE_STRATEGY_DATA
INCLUDE_GFX
safemap<std::string,int>STRATEGY_DATA; safemap<std::string,int>STRATEGY_DATA;
safemap<int,std::string>STRATEGY_ID_DATA; safemap<int,std::string>STRATEGY_ID_DATA;
@ -139,7 +140,7 @@ bool Monster::Update(float fElapsedTime){
} }
} }
} }
if(!game->GetPlayer()->HasIframes()&&game->GetPlayer()->OnUpperLevel()==OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer()->GetPos(),12*game->GetPlayer()->GetSizeMult()/2))){ if(!game->GetPlayer()->HasIframes()&&abs(game->GetPlayer()->GetZ()-GetZ())<=1&&game->GetPlayer()->OnUpperLevel()==OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer()->GetPos(),12*game->GetPlayer()->GetSizeMult()/2))){
geom2d::line line(pos,game->GetPlayer()->GetPos()); geom2d::line line(pos,game->GetPlayer()->GetPos());
float dist = line.length(); float dist = line.length();
SetPos(line.rpoint(-0.1)); SetPos(line.rpoint(-0.1));
@ -186,7 +187,7 @@ void Monster::Draw(){
strategyDraw(game); strategyDraw(game);
if(GetZ()>0){ if(GetZ()>0){
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24); vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},game->GFX_Circle.Decal(),shadowScale,BLACK); game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
} }
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE); game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE);
} }

@ -238,7 +238,7 @@ void Player::Update(float fElapsedTime){
z=0; z=0;
float numb=4; float numb=4;
game->HurtEnemies(pos,"Warrior.Ability 2.Range"_F/100*12,GetAttack()*"Warrior.Ability 2.DamageMult"_F,OnUpperLevel(),0); game->HurtEnemies(pos,"Warrior.Ability 2.Range"_F/100*12,GetAttack()*"Warrior.Ability 2.DamageMult"_F,OnUpperLevel(),0);
game->AddEffect(std::make_unique<Effect>(GetPos(),"Warrior.Ability 2.EffectLifetime"_F,"GROUND_SLAM_ATTACK_FRONT",upperLevel,"Warrior.Ability 2.Range"_F/300*1.33f,"Warrior.Ability 2.EffectFadetime"_F),std::make_unique<Effect>(GetPos(),"Warrior.Ability 2.EffectLifetime"_F,"GROUND_SLAM_ATTACK_BACK",upperLevel,"Warrior.Ability 2.Range"_F/300*1.33f,"Warrior.Ability 2.EffectFadetime"_F)); game->AddEffect(std::make_unique<Effect>(GetPos(),"Warrior.Ability 2.EffectLifetime"_F,"ground-slam-attack-front.png",upperLevel,"Warrior.Ability 2.Range"_F/300*1.33f,"Warrior.Ability 2.EffectFadetime"_F),std::make_unique<Effect>(GetPos(),"Warrior.Ability 2.EffectLifetime"_F,"ground-slam-attack-back.png",upperLevel,"Warrior.Ability 2.Range"_F/300*1.33f,"Warrior.Ability 2.EffectFadetime"_F));
} }
if(lastAnimationFlip>0){ if(lastAnimationFlip>0){
lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime); lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime);

@ -69,7 +69,6 @@ protected:
void SetZ(float z); void SetZ(float z);
//Returns true if the move was valid and successful. //Returns true if the move was valid and successful.
bool SetPos(vf2d pos); bool SetPos(vf2d pos);
void Knockback(vf2d vel);
float friction="Player.Friction"_F; float friction="Player.Friction"_F;
float attack_cooldown_timer=0; float attack_cooldown_timer=0;
float iframe_time=0; float iframe_time=0;
@ -131,6 +130,7 @@ public:
bool CanMove(); bool CanMove();
bool CanAct(); bool CanAct();
bool CanAct(Ability&ability); bool CanAct(Ability&ability);
void Knockback(vf2d vel);
void AddBuff(BuffType type,float duration,float intensity); void AddBuff(BuffType type,float duration,float intensity);
std::vector<Buff>GetBuffs(BuffType buff); std::vector<Buff>GetBuffs(BuffType buff);

@ -25,7 +25,7 @@ bool PulsatingFire::Update(float fElapsedTime){
float randomRange=12*size.x*(1-util::random("Wizard.Ability 3.FireRingParticleRandomVariance"_F))*(1-util::random("Wizard.Ability 3.FireRingParticleRandomVariance"_F)); float randomRange=12*size.x*(1-util::random("Wizard.Ability 3.FireRingParticleRandomVariance"_F))*(1-util::random("Wizard.Ability 3.FireRingParticleRandomVariance"_F));
float randomColorTintG=128*(1-util::random("Wizard.Ability 3.FireRingParticleColorGVariance"_F))*(1-util::random("Wizard.Ability 3.FireRingParticleColorGVariance"_F)); float randomColorTintG=128*(1-util::random("Wizard.Ability 3.FireRingParticleColorGVariance"_F))*(1-util::random("Wizard.Ability 3.FireRingParticleColorGVariance"_F));
float randomColorTint="Wizard.Ability 3.FireRingParticleColorBlueRange"_FRange; float randomColorTint="Wizard.Ability 3.FireRingParticleColorBlueRange"_FRange;
game->AddEffect(std::make_unique<Effect>(pos+vf2d{cos(randomAngle),sin(randomAngle)}*randomRange,0,"DOT_PARTICLE",OnUpperLevel(),vf2d{"Wizard.Ability 3.FireRingParticleXSizeRange"_FRange,"Wizard.Ability 3.FireRingParticleYSizeRange"_FRange},"Wizard.Ability 3.FireRingParticleFadeoutTimeRange"_FRange,vf2d{"Wizard.Ability 3.FireRingParticleXSpeedRange"_FRange,"Wizard.Ability 3.FireRingParticleYSpeedRange"_FRange},Pixel{128,uint8_t(randomColorTintG),uint8_t(randomColorTint),uint8_t("Wizard.Ability 3.FireRingParticleAlphaRange"_FRange)})); game->AddEffect(std::make_unique<Effect>(pos+vf2d{cos(randomAngle),sin(randomAngle)}*randomRange,0,"circle.png",OnUpperLevel(),vf2d{"Wizard.Ability 3.FireRingParticleXSizeRange"_FRange,"Wizard.Ability 3.FireRingParticleYSizeRange"_FRange},"Wizard.Ability 3.FireRingParticleFadeoutTimeRange"_FRange,vf2d{"Wizard.Ability 3.FireRingParticleXSpeedRange"_FRange,"Wizard.Ability 3.FireRingParticleYSpeedRange"_FRange},Pixel{128,uint8_t(randomColorTintG),uint8_t(randomColorTint),uint8_t("Wizard.Ability 3.FireRingParticleAlphaRange"_FRange)}));
} }
lastParticleTimer="Wizard.Ability 3.FireRingParticleFreqRange"_FRange; lastParticleTimer="Wizard.Ability 3.FireRingParticleFreqRange"_FRange;
} }
@ -41,22 +41,22 @@ void PulsatingFire::Draw(){
Animate2D::FrameSequence*effectSpr=nullptr; Animate2D::FrameSequence*effectSpr=nullptr;
switch(int(pulsatingFireValues[i]*5)){ switch(int(pulsatingFireValues[i]*5)){
case 0:{ case 0:{
effectSpr=&ANIMATION_DATA["FIRE_RING1"]; effectSpr=&ANIMATION_DATA["fire_ring0.png"];
}break; }break;
case 1:{ case 1:{
effectSpr=&ANIMATION_DATA["FIRE_RING2"]; effectSpr=&ANIMATION_DATA["fire_ring1.png"];
}break; }break;
case 2:{ case 2:{
effectSpr=&ANIMATION_DATA["FIRE_RING3"]; effectSpr=&ANIMATION_DATA["fire_ring2.png"];
}break; }break;
case 3:{ case 3:{
effectSpr=&ANIMATION_DATA["FIRE_RING4"]; effectSpr=&ANIMATION_DATA["fire_ring3.png"];
}break; }break;
case 4:{ case 4:{
effectSpr=&ANIMATION_DATA["FIRE_RING5"]; effectSpr=&ANIMATION_DATA["fire_ring4.png"];
}break; }break;
default: default:
effectSpr=&ANIMATION_DATA["FIRE_RING1"]; effectSpr=&ANIMATION_DATA["fire_ring0.png"];
} }
const Renderable*img=effectSpr->GetFrame(0).GetSourceImage(); const Renderable*img=effectSpr->GetFrame(0).GetSourceImage();
game->view.DrawPartialDecal(pos-effectSpr->GetFrame(0).GetSourceRect().size/2*size,img->Decal(),effectSpr->GetFrame(0).GetSourceRect().pos,effectSpr->GetFrame(0).GetSourceRect().size,size,{255,uint8_t(pulsatingFireValues[i]*256),0,uint8_t((63*(sin("Wizard.Ability 3.FireRingOscillatingFrequency"_F*lifetime+PI*pulsatingFireValues[i]))+63)*(fadeout/original_fadeoutTime))}); game->view.DrawPartialDecal(pos-effectSpr->GetFrame(0).GetSourceRect().size/2*size,img->Decal(),effectSpr->GetFrame(0).GetSourceRect().pos,effectSpr->GetFrame(0).GetSourceRect().size,size,{255,uint8_t(pulsatingFireValues[i]*256),0,uint8_t((63*(sin("Wizard.Ability 3.FireRingOscillatingFrequency"_F*lifetime+PI*pulsatingFireValues[i]))+63)*(fadeout/original_fadeoutTime))});

@ -4,6 +4,7 @@
#include "Crawler.h" #include "Crawler.h"
#include "utils.h" #include "utils.h"
#include "safemap.h" #include "safemap.h"
#include "Effect.h"
INCLUDE_game INCLUDE_game
INCLUDE_BULLET_LIST INCLUDE_BULLET_LIST
@ -44,7 +45,6 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
if(m.state==State::JUMP){ if(m.state==State::JUMP){
float jumpLandingTimerRatio=m.F(A::JUMP_LANDING_TIMER)/m.F(A::JUMP_ORIGINAL_LANDING_TIMER); float jumpLandingTimerRatio=m.F(A::JUMP_LANDING_TIMER)/m.F(A::JUMP_ORIGINAL_LANDING_TIMER);
vf2d moveVel;
if(m.GetPos().x>game->GetPlayer()->GetPos().x){ if(m.GetPos().x>game->GetPlayer()->GetPos().x){
m.SetX(std::max(game->GetPlayer()->GetPos().x,m.GetPos().x-ConfigInt("JumpMoveSpd")*game->GetElapsedTime())); m.SetX(std::max(game->GetPlayer()->GetPos().x,m.GetPos().x-ConfigInt("JumpMoveSpd")*game->GetElapsedTime()));
} else } else
@ -65,12 +65,26 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
if(m.F(A::JUMP_LANDING_TIMER)==0){ if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY; m.state=State::RECOVERY;
game->SetupWorldShake(0.6); game->SetupWorldShake(0.6);
geom2d::line<float>lineToPlayer(m.GetPos(),game->GetPlayer()->GetPos());
float dist=lineToPlayer.length();
for(int i=0;i<200;i++){
float randomDir=util::random(2*PI);
//game->AddEffect(Effect{vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),})
}
if(dist<12*m.GetSizeMult()){
game->GetPlayer()->Hurt(ConfigInt("JumpAttackDamage"),m.OnUpperLevel(),m.GetZ());
if(dist<0.001){
float randomDir=util::random(2*PI);
lineToPlayer={m.GetPos(),m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*1};
}
game->GetPlayer()->Knockback(lineToPlayer.vector().norm()*ConfigInt("JumpKnockbackFactor"));
}
m.SetStrategyDrawFunction([](Crawler*game){}); m.SetStrategyDrawFunction([](Crawler*game){});
} else } else
if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){ if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){
m.SetStrategyDrawFunction([&](Crawler*game){ m.SetStrategyDrawFunction([&](Crawler*game){
Decal*dec=ANIMATION_DATA["RANGE_INDICATOR"].GetFrame(game->GetElapsedTime()).GetSourceImage()->Decal(); Decal*dec=ANIMATION_DATA["range_indicator.png"].GetFrame(game->GetElapsedTime()).GetSourceImage()->Decal();
game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()}/2,RED); game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()},RED);
}); });
} }
return; return;

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

@ -80,7 +80,7 @@ void Warrior::InitializeClassAbilities(){
#pragma region Warrior Ability 1 (Battlecry) #pragma region Warrior Ability 1 (Battlecry)
Warrior::ability1.action= Warrior::ability1.action=
[](Player*p,vf2d pos={}){ [](Player*p,vf2d pos={}){
game->AddEffect(std::make_unique<Effect>(p->GetPos(),"Warrior.Ability 1.EffectLifetime"_F,"BATTLECRY_EFFECT",p->upperLevel,"Warrior.Ability 1.Range"_F/350,"Warrior.Ability 1.EffectFadetime"_F)); game->AddEffect(std::make_unique<Effect>(p->GetPos(),"Warrior.Ability 1.EffectLifetime"_F,"battlecry_effect.png",p->upperLevel,"Warrior.Ability 1.Range"_F/350,"Warrior.Ability 1.EffectFadetime"_F));
p->AddBuff(BuffType::ATTACK_UP,"Warrior.Ability 1.AttackUpDuration"_F,"Warrior.Ability 1.AttackIncrease"_F); p->AddBuff(BuffType::ATTACK_UP,"Warrior.Ability 1.AttackUpDuration"_F,"Warrior.Ability 1.AttackIncrease"_F);
p->AddBuff(BuffType::DAMAGE_REDUCTION,"Warrior.Ability 1.DamageReductionDuration"_F,"Warrior.Ability 1.DamageReduction"_F); p->AddBuff(BuffType::DAMAGE_REDUCTION,"Warrior.Ability 1.DamageReductionDuration"_F,"Warrior.Ability 1.DamageReduction"_F);
for(Monster&m:MONSTER_LIST){ for(Monster&m:MONSTER_LIST){
@ -127,7 +127,7 @@ void Warrior::InitializeClassAbilities(){
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_S",WARRIOR); p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_S",WARRIOR);
}break; }break;
} }
BULLET_LIST.push_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,p->GetAttack()*"Warrior.Ability 3.DamageMult"_F,"SONICSLASH",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,true,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30})); BULLET_LIST.push_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,p->GetAttack()*"Warrior.Ability 3.DamageMult"_F,"sonicslash.png",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,true,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30}));
game->SetupWorldShake("Warrior.Ability 3.ShakeTime"_F); game->SetupWorldShake("Warrior.Ability 3.ShakeTime"_F);
return true; return true;
}; };

@ -90,7 +90,7 @@ void Wizard::InitializeClassAbilities(){
p->teleportStartPosition=p->GetPos(); p->teleportStartPosition=p->GetPos();
p->iframe_time="Wizard.Right Click Ability.IframeTime"_F; p->iframe_time="Wizard.Right Click Ability.IframeTime"_F;
for(int i=0;i<"Wizard.Right Click Ability.ParticleCount"_I;i++){ for(int i=0;i<"Wizard.Right Click Ability.ParticleCount"_I;i++){
game->AddEffect(std::make_unique<Effect>(p->GetPos()+vf2d{(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12,(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12},util::random("Wizard.Right Click Ability.ParticleLifetimeMax"_F)+"Wizard.Right Click Ability.ParticleLifetimeMin"_F,"DOT_PARTICLE",p->upperLevel,"Wizard.Right Click Ability.ParticleSize"_F,"Wizard.Right Click Ability.ParticleFadetime"_F,vf2d{util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F,util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F},"Wizard.Right Click Ability.ParticleColor"_Pixel)); game->AddEffect(std::make_unique<Effect>(p->GetPos()+vf2d{(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12,(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12},util::random("Wizard.Right Click Ability.ParticleLifetimeMax"_F)+"Wizard.Right Click Ability.ParticleLifetimeMin"_F,"circle.png",p->upperLevel,"Wizard.Right Click Ability.ParticleSize"_F,"Wizard.Right Click Ability.ParticleFadetime"_F,vf2d{util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F,util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F},"Wizard.Right Click Ability.ParticleColor"_Pixel));
} }
return true; return true;
} else { } else {
@ -119,7 +119,7 @@ void Wizard::InitializeClassAbilities(){
Wizard::ability3.action= Wizard::ability3.action=
[](Player*p,vf2d pos={}){ [](Player*p,vf2d pos={}){
p->CastSpell(Wizard::ability3); p->CastSpell(Wizard::ability3);
game->AddEffect(std::make_unique<Meteor>(pos,3,"METEOR",p->OnUpperLevel(),vf2d{"Wizard.Ability 3.MeteorRadius"_F/100/4,"Wizard.Ability 3.MeteorRadius"_F/100/4},"Wizard.Ability 3.MeteorFadeoutTime"_F)); game->AddEffect(std::make_unique<Meteor>(pos,3,"meteor.png",p->OnUpperLevel(),vf2d{"Wizard.Ability 3.MeteorRadius"_F/100/4,"Wizard.Ability 3.MeteorRadius"_F/100/4},"Wizard.Ability 3.MeteorFadeoutTime"_F));
return true; return true;
}; };
#pragma endregion #pragma endregion

@ -1961,23 +1961,6 @@
</properties> </properties>
<point/> <point/>
</object> </object>
<object id="130" name="Player Spawn" type="PlayerSpawnLocation" x="3192" y="4248" width="24" height="24"/> <object id="129" name="Player Spawn" type="PlayerSpawnLocation" x="600" y="4248" width="24" height="24"/>
<object id="131" name="Temporary" type="SpawnGroup" x="3150" y="4188" width="114" height="246">
<ellipse/>
</object>
<object id="132" type="Monster" x="3174" y="4350">
<properties>
<property name="Type" type="int" propertytype="MonsterName" value="1"/>
<property name="spawner" type="object" value="131"/>
</properties>
<point/>
</object>
<object id="133" type="Monster" x="3240" y="4302">
<properties>
<property name="Type" type="int" propertytype="MonsterName" value="3"/>
<property name="spawner" type="object" value="131"/>
</properties>
<point/>
</object>
</objectgroup> </objectgroup>
</map> </map>

@ -78,7 +78,8 @@ MonsterStrategy
JumpHeight = 2400 JumpHeight = 2400
ProjectileDamage = 10 ProjectileDamage = 10
JumpAttackDamage = 20 JumpAttackDamage = 20
JumpMoveSpd = 95 JumpMoveSpd = 75
JumpKnockbackFactor = 250
BulletSpd = 250 BulletSpd = 250

@ -10,7 +10,7 @@ gfx_config = gfx/gfx.txt
map_config = levels.txt map_config = levels.txt
# Starting map when loading the game. # Starting map when loading the game.
starting_map = CAMPAIGN_1_1 starting_map = BOSS_1
# Player Properties Loading Config # Player Properties Loading Config
player_config = Player.txt player_config = Player.txt

@ -2,32 +2,37 @@ GFX_Prefix = assets/
Images Images
{ {
GFX_Warrior_Sheet = nico-warrior.png GFX_Arrow = arrow.png
GFX_Circle = circle.png
GFX_Effect_GroundSlam_Back = ground-slam-attack-back.png
GFX_Effect_GroundSlam_Front = ground-slam-attack-front.png
GFX_Heart = heart.png
GFX_BLOCK_BUBBLE = block.png
GFX_Ranger_Sheet = nico-ranger.png
GFX_Wizard_Sheet = nico-wizard.png
GFX_Battlecry_Effect = battlecry_effect.png GFX_Battlecry_Effect = battlecry_effect.png
GFX_Mana = mana.png GFX_BLOCK_BUBBLE = block.png
GFX_SonicSlash = sonicslash.png
GFX_BulletCircle = circle.png GFX_BulletCircle = circle.png
GFX_BulletCircleOutline = circle_outline.png GFX_BulletCircleOutline = circle_outline.png
GFX_ChainLightning = chain_lightning.png
GFX_ChargedArrow = charged_shot_arrow.png
GFX_Circle = circle.png
GFX_Effect_GroundSlam_Back = ground-slam-attack-back.png
GFX_Effect_GroundSlam_Front = ground-slam-attack-front.png
GFX_EnergyBolt = energy_bolt.png GFX_EnergyBolt = energy_bolt.png
GFX_EnergyParticle = energy_particle.png GFX_EnergyParticle = energy_particle.png
GFX_Splash_Effect = splash_effect.png GFX_FireRing0 = fire_ring0.png
GFX_FireRing1 = fire_ring1.png
GFX_FireRing2 = fire_ring2.png
GFX_FireRing3 = fire_ring3.png
GFX_FireRing4 = fire_ring4.png
GFX_Heart = heart.png
GFX_Laser = laser.png
GFX_LightningBolt = lightning_bolt.png GFX_LightningBolt = lightning_bolt.png
GFX_LightningBoltParticle1 = lightning_bolt_part1.png GFX_LightningBoltParticle1 = lightning_bolt_part1.png
GFX_LightningBoltParticle2 = lightning_bolt_part2.png GFX_LightningBoltParticle2 = lightning_bolt_part2.png
GFX_LightningBoltParticle3 = lightning_bolt_part3.png GFX_LightningBoltParticle3 = lightning_bolt_part3.png
GFX_LightningBoltParticle4 = lightning_bolt_part4.png GFX_LightningBoltParticle4 = lightning_bolt_part4.png
GFX_ChainLightning = chain_lightning.png
GFX_LightningSplash = lightning_splash_effect.png GFX_LightningSplash = lightning_splash_effect.png
GFX_Mana = mana.png
GFX_Meteor = meteor.png GFX_Meteor = meteor.png
GFX_Arrow = arrow.png
GFX_Laser = laser.png
GFX_ChargedArrow = charged_shot_arrow.png
GFX_RangeIndicator = range_indicator.png GFX_RangeIndicator = range_indicator.png
GFX_Ranger_Sheet = nico-ranger.png
GFX_SonicSlash = sonicslash.png
GFX_Splash_Effect = splash_effect.png
GFX_Warrior_Sheet = nico-warrior.png
GFX_Wizard_Sheet = nico-wizard.png
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

@ -130,6 +130,10 @@ namespace olc::utils
return m_vContent; return m_vContent;
} }
inline std::unordered_map<std::string,size_t> GetKeys() const{
return m_mapObjects;
}
// Checks if a property exists - useful to avoid creating properties // Checks if a property exists - useful to avoid creating properties
// via reading them, though non-essential // via reading them, though non-essential
inline bool HasProperty(const std::string& sName) const inline bool HasProperty(const std::string& sName) const

@ -17,4 +17,12 @@ public:
void SetInitialized(){ void SetInitialized(){
initialized=true; initialized=true;
} }
size_t size(){
return map.size();
}
//Clears the entire map and unlocks the map so items can be added to it again.
void Reset(){
initialized=false;
map.clear();
}
}; };
Loading…
Cancel
Save