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 1 year 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_ANIMATION_DATA
INCLUDE_DATA
INCLUDE_GFX
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);
anim.AddFrame({&img,{{0,0},size}});
ANIMATION_DATA[state]=anim;
anim.AddFrame({&GFX[imgName],{{0,0},size}});
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);
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){
@ -63,24 +64,24 @@ void sig::Animation::InitializeAnimations(){
};
//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_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}}});
pl_warrior_swing_s.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,0}*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++){
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}}});
pl_warrior_swing_n.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,1}*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++){
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}}});
pl_warrior_swing_w.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,2}*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++){
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}}});
pl_warrior_swing_e.AddFrame({&GFX["nico-warrior.png"],{vi2d{4+i,3}*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_E"]=pl_warrior_swing_e;
@ -92,13 +93,13 @@ void sig::Animation::InitializeAnimations(){
ANIMATION_DATA["WARRIOR_SWINGSONICSWORD_W"]=pl_warrior_sonic_swing_w;
//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;
for(int i=0;i<3;i++){
pl_ranger_shoot_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,0}*24,{24,24}}});
pl_ranger_shoot_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,1}*24,{24,24}}});
pl_ranger_shoot_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,3}*24,{24,24}}});
pl_ranger_shoot_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,2}*24,{24,24}}});
pl_ranger_shoot_s.AddFrame({&GFX["nico-ranger.png"],{vi2d{3+i,0}*24,{24,24}}});
pl_ranger_shoot_n.AddFrame({&GFX["nico-ranger.png"],{vi2d{3+i,1}*24,{24,24}}});
pl_ranger_shoot_e.AddFrame({&GFX["nico-ranger.png"],{vi2d{3+i,3}*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_N"]=pl_ranger_shoot_n;
@ -106,107 +107,107 @@ void sig::Animation::InitializeAnimations(){
ANIMATION_DATA["RANGER_SHOOT_W"]=pl_ranger_shoot_w;
//Wizard animations
SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,"WIZARD");
SetupClassWalkIdleAnimations(GFX["nico-wizard.png"],"WIZARD");
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;
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;
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;
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;
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}}});
pl_wizard_attack_s.AddFrame({&GFX["nico-wizard.png"],{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}}});
pl_wizard_attack_s.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,0}*24,{24,24}}});
}
}
ANIMATION_DATA["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}}});
pl_wizard_attack_e.AddFrame({&GFX["nico-wizard.png"],{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}}});
pl_wizard_attack_e.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,3}*24,{24,24}}});
}
}
ANIMATION_DATA["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}}});
pl_wizard_attack_w.AddFrame({&GFX["nico-wizard.png"],{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}}});
pl_wizard_attack_w.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,2}*24,{24,24}}});
}
}
ANIMATION_DATA["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}}});
pl_wizard_attack_n.AddFrame({&GFX["nico-wizard.png"],{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}}});
pl_wizard_attack_n.AddFrame({&GFX["nico-wizard.png"],{vi2d{4,1}*24,{24,24}}});
}
}
ANIMATION_DATA["WIZARD_ATTACK_N"]=pl_wizard_attack_n;
Animate2D::FrameSequence pl_wizard_cast_s(0.1);
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;
Animate2D::FrameSequence pl_wizard_cast_e(0.1);
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;
Animate2D::FrameSequence pl_wizard_cast_n(0.1);
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;
Animate2D::FrameSequence pl_wizard_cast_w(0.1);
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;
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Back,5,{64,64},"GROUND_SLAM_ATTACK_BACK",{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Front,5,{64,64},"GROUND_SLAM_ATTACK_FRONT",{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_Battlecry_Effect,5,{84,84},"BATTLECRY_EFFECT",{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence(game->GFX_SonicSlash,4,{60,60},"SONICSLASH",{0.04,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence("ground-slam-attack-back.png",5,{64,64},{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence("ground-slam-attack-front.png",5,{64,64},{0.02,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence("battlecry_effect.png",5,{84,84},{0.02,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(game->GFX_LightningBoltParticle2,{5,5},"LIGHTNING_BOLT_PARTICLE2");
CreateStillAnimation(game->GFX_LightningBoltParticle3,{5,5},"LIGHTNING_BOLT_PARTICLE3");
CreateStillAnimation(game->GFX_LightningBoltParticle4,{5,5},"LIGHTNING_BOLT_PARTICLE4");
CreateStillAnimation("lightning_bolt_part1.png",{5,5});
CreateStillAnimation("lightning_bolt_part2.png",{5,5});
CreateStillAnimation("lightning_bolt_part3.png",{5,5});
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++){
Animate2D::FrameSequence firering;
firering.AddFrame({&game->GFX_LightningSplash,{{i*24,0},{24,24}}});
ANIMATION_DATA["FIRE_RING"+std::to_string(i+1)]=firering;
firering.AddFrame({&GFX["fire_ring"+std::to_string(i)+".png"],{{0,0},{24,24}}});
ANIMATION_DATA["fire_ring"+std::to_string(i)+".png"]=firering;
}
CreateStillAnimation(game->GFX_Arrow,{24,24},"ARROW");
CreateStillAnimation(game->GFX_ChargedArrow,{48,48},"CHARGED_ARROW");
CreateStillAnimation(game->GFX_Laser,{5,1},"LASER");
CreateStillAnimation(game->GFX_RangeIndicator,{24,24},"RANGE_INDICATOR");
CreateStillAnimation("arrow.png",{24,24});
CreateStillAnimation("charged_shot_arrow.png",{48,48});
CreateStillAnimation("laser.png",{5,1});
CreateStillAnimation("range_indicator.png",{24,24});
}
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)
:finalDistance(geom2d::line(pos,targetPos).length()),acc(PI/2*"Ranger.Auto Attack.ArrowSpd"_F),
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){
float speed=vel.mag();
@ -26,7 +26,7 @@ bool Arrow::PlayerHit(Player*player)
{
deactivated=true;
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;
}
@ -34,6 +34,6 @@ bool Arrow::MonsterHit(Monster& monster)
{
deactivated=true;
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;
}

@ -5,6 +5,7 @@
INCLUDE_ANIMATION_DATA
INCLUDE_game
INCLUDE_GFX
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){};
@ -36,8 +37,8 @@ void Bullet::Draw(){
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))});
} 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-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.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-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)
:lastLaserPos(pos),
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){
geom2d::line lineToCurrentPos(geom2d::line(lastLaserPos,pos));
float dist=lineToCurrentPos.length();
if(dist>=1){
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;
}
}

@ -26,6 +26,7 @@ std::vector<Monster>MONSTER_LIST;
std::vector<MonsterSpawner>SPAWNER_LIST;
std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
safemap<std::string,Renderable>GFX;
safemap<std::string,MapName>LEVEL_NAMES;
utils::datafile DATA;
Crawler*game;
@ -83,41 +84,18 @@ bool Crawler::OnUserCreate(){
camera.SetWorldBoundary({0,0},WORLD_SIZE*24);
camera.EnableWorldBoundary(false);
#undef LoadImage //Dumb Windows.
auto LoadImage=[&](Renderable&r,std::string key){
r.Load(GetString("GFX_Prefix")+GetString(key));
};
#define LOADIMG(name) LoadImage(name,"Images."#name);
//Graphics
LOADIMG(GFX_Warrior_Sheet)
LOADIMG(GFX_Circle)
LOADIMG(GFX_Effect_GroundSlam_Back)
LOADIMG(GFX_Effect_GroundSlam_Front)
LOADIMG(GFX_Heart)
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)
for(auto&val:DATA["Images"].GetKeys()){
std::string key=val.first;
std::string imgFile=DATA["Images"][key].GetString();
std::cout<<"Loading image "+imgFile+"..."<<std::endl;
GFX[imgFile];
if(GFX[imgFile].Load("GFX_Prefix"_S+imgFile)!=rcode::OK){
std::cout<<" WARNING! Failed to load "+imgFile+"!";
throw;
}
}
GFX.SetInitialized();
std::cout<<GFX.size()<<" images have been loaded."<<std::endl;
Monster::InitializeStrategies();
//Animations
@ -698,7 +676,7 @@ void Crawler::RenderWorld(float fElapsedTime){
if(player->GetZ()>0){
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){
e->Draw();
@ -710,7 +688,7 @@ void Crawler::RenderWorld(float fElapsedTime){
RenderPlayer(player->GetPos(),{1,1});
}
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){
m->Draw();
@ -726,15 +704,15 @@ void Crawler::RenderWorld(float fElapsedTime){
float precastSize=GetPlayer()->castPrepAbility->precastInfo.size;
float precastRange=GetPlayer()->castPrepAbility->precastInfo.range;
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));
if(distance>precastRange){//Clamp the distance.
vf2d pointToCursor = {GetWorldMousePos().x-player->GetX(),GetWorldMousePos().y-player->GetY()};
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};
view.DrawDecal(centerPoint,GFX_Circle.Decal(),scale,{255,0,0,96});
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.png"].Decal(),scale,{255,0,0,96});
} 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);
}
DrawDecal({2,2},GFX_Heart.Decal());
DrawDecal({2,20},GFX_Mana.Decal());
DrawDecal({2,2},GFX["heart.png"].Decal());
DrawDecal({2,20},GFX["mana.png"].Decal());
std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X";
std::string text_mana=std::to_string(player->GetMana());
DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2});
@ -1307,7 +1285,7 @@ datafiledoubledata Crawler::GetDoubleList(std::string key){
int main()
{
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();
return 0;
@ -1381,6 +1359,11 @@ bool Crawler::IsReflectiveTile(TilesheetData tileSheet,int tileID){
return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end();
}
bool Crawler::OnUserDestroy(){
GFX.Reset();
return true;
}
void Crawler::InitializeLevels(){
#define INITLEVEL(map) \
InitializeLevel("map_path"_S + "Levels."#map ## _S,map); \

@ -17,16 +17,7 @@ class Crawler : public olc::PixelGameEngine
friend class sig::Animation;
Camera2D camera;
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:
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt,GFX_Circle;
Pathfinding pathfinder;
static Key KEY_ABILITY1;
static Key KEY_ABILITY2;
@ -60,6 +51,7 @@ public:
Crawler();
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
bool OnUserDestroy() override;
public:
geom2d::rect<int>NO_COLLISION={};
vi2d WORLD_SIZE={120,8};

@ -6,12 +6,12 @@
#define INCLUDE_game extern Crawler*game;
#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_PARTICLE_LIST extern std::vector<Particle>PARTICLE_LIST;
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
#define INCLUDE_DATA extern utils::datafile 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_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();

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

@ -17,8 +17,8 @@ struct Effect{
private:
bool dead=false;
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 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,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,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);
Animate2D::Frame GetFrame();
virtual void Draw();
@ -32,7 +32,7 @@ private:
};
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;
bool shakeField=false;
bool Update(float fElapsedTime)override;
@ -40,7 +40,7 @@ struct Meteor: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;
float lastParticleTimer=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)
: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){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
if(lastParticleSpawn==0){
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;
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;
}
@ -30,6 +30,6 @@ bool EnergyBolt::MonsterHit(Monster& monster)
{
deactivated=true;
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;
}

@ -9,13 +9,13 @@ INCLUDE_MONSTER_LIST
FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
: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){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);
if(lastParticleSpawn==0){
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;
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;
}
@ -32,10 +32,10 @@ bool FireBolt::MonsterHit(Monster& monster)
deactivated=true;
fadeOutTime="Wizard.Ability 1.BulletHitFadeoutTime"_F;
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->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;
}

@ -11,7 +11,7 @@ INCLUDE_EMITTER_LIST
LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
: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){
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);
switch(rand()%4){
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;
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;
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;
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;
}
}
@ -40,7 +40,7 @@ bool LightningBolt::PlayerHit(Player*player)
{
deactivated=true;
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;
}
@ -48,7 +48,7 @@ bool LightningBolt::MonsterHit(Monster& monster)
{
deactivated=true;
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;
for(Monster&m:MONSTER_LIST){
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(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)));
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++;
}
}

@ -22,7 +22,7 @@ void LightningBoltEmitter::DrawLightningBolt(){
float targetDist=lineToTarget.length()*util::random(0.5);
targetAngle+=util::random((PI/2))-PI/4;
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;
currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist};
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);
targetAngle+=util::random((PI/2))-PI/4;
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};
iterations++;
}

@ -2,12 +2,14 @@
#include "DEFINES.h"
#include "Crawler.h"
#include "utils.h"
#include "safemap.h"
INCLUDE_game
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)
:Effect(pos,lifetime,animation,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending),startLifetime(lifetime){
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,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 randomColorTintB="Wizard.Ability 3.MeteorImpactParticleColorBlueRange"_FRange;
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->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);
}
@ -34,8 +36,8 @@ void Meteor::Draw(){
if(lifetime>0){
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 centerPoint=pos-vf2d{game->GFX_Circle.Sprite()->width*scale.x/2,game->GFX_Circle.Sprite()->height*scale.y/2};
game->view.DrawDecal(centerPoint+meteorOffset,game->GFX_Circle.Decal(),scale,{0,0,0,192});
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,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;
if(lifetime<=0){

@ -14,6 +14,7 @@ INCLUDE_game
INCLUDE_BULLET_LIST
INCLUDE_DATA
INCLUDE_STRATEGY_DATA
INCLUDE_GFX
safemap<std::string,int>STRATEGY_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());
float dist = line.length();
SetPos(line.rpoint(-0.1));
@ -186,7 +187,7 @@ void Monster::Draw(){
strategyDraw(game);
if(GetZ()>0){
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);
}

@ -238,7 +238,7 @@ void Player::Update(float fElapsedTime){
z=0;
float numb=4;
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){
lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime);

@ -69,7 +69,6 @@ protected:
void SetZ(float z);
//Returns true if the move was valid and successful.
bool SetPos(vf2d pos);
void Knockback(vf2d vel);
float friction="Player.Friction"_F;
float attack_cooldown_timer=0;
float iframe_time=0;
@ -131,6 +130,7 @@ public:
bool CanMove();
bool CanAct();
bool CanAct(Ability&ability);
void Knockback(vf2d vel);
void AddBuff(BuffType type,float duration,float intensity);
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 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;
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;
}
@ -41,22 +41,22 @@ void PulsatingFire::Draw(){
Animate2D::FrameSequence*effectSpr=nullptr;
switch(int(pulsatingFireValues[i]*5)){
case 0:{
effectSpr=&ANIMATION_DATA["FIRE_RING1"];
effectSpr=&ANIMATION_DATA["fire_ring0.png"];
}break;
case 1:{
effectSpr=&ANIMATION_DATA["FIRE_RING2"];
effectSpr=&ANIMATION_DATA["fire_ring1.png"];
}break;
case 2:{
effectSpr=&ANIMATION_DATA["FIRE_RING3"];
effectSpr=&ANIMATION_DATA["fire_ring2.png"];
}break;
case 3:{
effectSpr=&ANIMATION_DATA["FIRE_RING4"];
effectSpr=&ANIMATION_DATA["fire_ring3.png"];
}break;
case 4:{
effectSpr=&ANIMATION_DATA["FIRE_RING5"];
effectSpr=&ANIMATION_DATA["fire_ring4.png"];
}break;
default:
effectSpr=&ANIMATION_DATA["FIRE_RING1"];
effectSpr=&ANIMATION_DATA["fire_ring0.png"];
}
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))});

@ -4,6 +4,7 @@
#include "Crawler.h"
#include "utils.h"
#include "safemap.h"
#include "Effect.h"
INCLUDE_game
INCLUDE_BULLET_LIST
@ -44,7 +45,6 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
if(m.state==State::JUMP){
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){
m.SetX(std::max(game->GetPlayer()->GetPos().x,m.GetPos().x-ConfigInt("JumpMoveSpd")*game->GetElapsedTime()));
} else
@ -65,12 +65,26 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY;
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){});
} else
if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){
m.SetStrategyDrawFunction([&](Crawler*game){
Decal*dec=ANIMATION_DATA["RANGE_INDICATOR"].GetFrame(game->GetElapsedTime()).GetSourceImage()->Decal();
game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()}/2,RED);
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()},RED);
});
}
return;

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

@ -80,7 +80,7 @@ void Warrior::InitializeClassAbilities(){
#pragma region Warrior Ability 1 (Battlecry)
Warrior::ability1.action=
[](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::DAMAGE_REDUCTION,"Warrior.Ability 1.DamageReductionDuration"_F,"Warrior.Ability 1.DamageReduction"_F);
for(Monster&m:MONSTER_LIST){
@ -127,7 +127,7 @@ void Warrior::InitializeClassAbilities(){
p->UpdateAnimation("WARRIOR_SWINGSONICSWORD_S",WARRIOR);
}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);
return true;
};

@ -90,7 +90,7 @@ void Wizard::InitializeClassAbilities(){
p->teleportStartPosition=p->GetPos();
p->iframe_time="Wizard.Right Click Ability.IframeTime"_F;
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;
} else {
@ -119,7 +119,7 @@ void Wizard::InitializeClassAbilities(){
Wizard::ability3.action=
[](Player*p,vf2d pos={}){
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;
};
#pragma endregion

@ -1961,23 +1961,6 @@
</properties>
<point/>
</object>
<object id="130" name="Player Spawn" type="PlayerSpawnLocation" x="3192" 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>
<object id="129" name="Player Spawn" type="PlayerSpawnLocation" x="600" y="4248" width="24" height="24"/>
</objectgroup>
</map>

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

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

@ -2,32 +2,37 @@ GFX_Prefix = assets/
Images
{
GFX_Warrior_Sheet = nico-warrior.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_Arrow = arrow.png
GFX_Battlecry_Effect = battlecry_effect.png
GFX_Mana = mana.png
GFX_SonicSlash = sonicslash.png
GFX_BLOCK_BUBBLE = block.png
GFX_BulletCircle = circle.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_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_LightningBoltParticle1 = lightning_bolt_part1.png
GFX_LightningBoltParticle2 = lightning_bolt_part2.png
GFX_LightningBoltParticle3 = lightning_bolt_part3.png
GFX_LightningBoltParticle4 = lightning_bolt_part4.png
GFX_ChainLightning = chain_lightning.png
GFX_LightningSplash = lightning_splash_effect.png
GFX_Mana = mana.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_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;
}
inline std::unordered_map<std::string,size_t> GetKeys() const{
return m_mapObjects;
}
// Checks if a property exists - useful to avoid creating properties
// via reading them, though non-essential
inline bool HasProperty(const std::string& sName) const

@ -17,4 +17,12 @@ public:
void SetInitialized(){
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