Remove the random message
@ -10,5 +10,5 @@ PrecastData::PrecastData(float castTime,float range,float size)
|
||||
};
|
||||
|
||||
Ability::Ability(){};
|
||||
Ability::Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1,Pixel barColor2,PrecastData precastInfo)
|
||||
:name(name),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo){}
|
||||
Ability::Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1,Pixel barColor2,PrecastData precastInfo,bool canCancelCast)
|
||||
:name(name),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo),canCancelCast(canCancelCast){}
|
@ -23,7 +23,8 @@ struct Ability{
|
||||
int manaCost=0;
|
||||
Pixel barColor1,barColor2;
|
||||
PrecastData precastInfo;
|
||||
bool canCancelCast=false;
|
||||
std::function<bool(Player*,vf2d)>action=[](Player*,vf2d){return false;};
|
||||
Ability();
|
||||
Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={});
|
||||
Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={},bool canCancelCast=false);
|
||||
};
|
@ -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,119 @@ 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");
|
||||
CreateHorizontalAnimationSequence("monsters/Slime King - Cast.png",10,{24,24},{0.04});
|
||||
|
||||
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("arrow.png",{24,24});
|
||||
CreateStillAnimation("charged_shot_arrow.png",{48,48});
|
||||
CreateStillAnimation("laser.png",{5,1});
|
||||
CreateStillAnimation("range_indicator.png",{24,24});
|
||||
|
||||
for(auto&dat:GFX){
|
||||
std::string imgFile=dat.first;
|
||||
if(!ANIMATION_DATA.count(imgFile)){
|
||||
std::cout<<"WARNING! Animation data for "<<imgFile<<" not found! Auto-generating..."<<std::endl;
|
||||
CreateStillAnimation(imgFile,GFX[imgFile].Sprite()->Size());
|
||||
std::map<int,int>test;
|
||||
test.begin();
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
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))});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,4 +4,4 @@ debug.sh:8125f303032b6cbc137223df63d10096 -
|
||||
lines.sh:3b907786f7fc9204025993016c9080de -
|
||||
release.sh:b1ce8461a303e8e7aa9ed74259db3873 -
|
||||
temp:d41d8cd98f00b204e9800998ecf8427e -
|
||||
web.sh:e196c0bb38ff4cd9428b4a4e56f500a9 -
|
||||
web.sh:cd3b8a99e208244dee7576bc23c0dc80 -
|
||||
|
@ -12,12 +12,12 @@ source ../emsdk/emsdk_env.sh
|
||||
if [ ! -f "pixelGameEngine_wasm.o" ]
|
||||
then
|
||||
printf "Pixel Game Engine compile object missing. Compiling for the first time..."
|
||||
em++ -std=c++20 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -c pixelGameEngine.cpp -o pixelGameEngine_wasm.o
|
||||
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -c pixelGameEngine.cpp -o pixelGameEngine_wasm.o
|
||||
fi
|
||||
if [ -d "assets" ]; then
|
||||
em++ -std=c++20 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html --preload-file ./assets
|
||||
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html --preload-file ./assets
|
||||
else
|
||||
em++ -std=c++20 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html
|
||||
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html
|
||||
fi
|
||||
|
||||
cp buildtemplate.html ${PROJECT_NAME}.html
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
665
Crawler/ClassDiagram2.cd
Normal file
@ -0,0 +1,665 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="Crawler" Collapsed="true">
|
||||
<Position X="3.5" Y="13.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>OihgwhJkUjgrCYAAVgEdFoQkBECSBhEDncMJIEmEYAg=</HashCode>
|
||||
<FileName>Crawler.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Effect" Collapsed="true">
|
||||
<Position X="13.75" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>BAAAAAQAQAgEAAAEAIBAAAAAAAAEAAAAAAgAgAAACAA=</HashCode>
|
||||
<FileName>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um\gdipluseffects.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="LightningBoltEmitter" Collapsed="true">
|
||||
<Position X="6.5" Y="13.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAEAAIAAABAAABAAAAAAAAAAAAAAEAI=</HashCode>
|
||||
<FileName>Emitter.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Decal" Collapsed="true">
|
||||
<Position X="20.75" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAAAAAAQAAAAAAAAAAAAABAAAAAAUAEAAAAAAgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::GDIPlusStartup" Collapsed="true">
|
||||
<Position X="26" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEBAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::ImageLoader" Collapsed="true">
|
||||
<Position X="11" Y="9.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAIAAAAAAAAAAAACAAAAAAAAAAIAAgAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::ImageLoader_GDIPlus" Collapsed="true">
|
||||
<Position X="13.25" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAIAAAAAAAAAAAAAAAAIAAAAAAAAAgAAAAAAACAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::ImageLoader_LibPNG" Collapsed="true">
|
||||
<Position X="8.75" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::ImageLoader_STB" Collapsed="true">
|
||||
<Position X="11" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAABA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::PGEX" Collapsed="true">
|
||||
<Position X="0.5" Y="12.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gAAAAAAAABAIAACAAAAgAAAAAAAAAAAAAAAAAAAAgAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::PixelGameEngine" Collapsed="true">
|
||||
<Position X="3.5" Y="12.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>S5fpQ8sYZfjd1v02mw8U0Ed9QaLH2ByFmPRdWNHpuzs=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform" Collapsed="true">
|
||||
<Position X="5.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIgAAAEAAAABAAAAAAAACAIAAAAAAAAQAEiAAACAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform_Emscripten" Collapsed="true">
|
||||
<Position X="9.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIgAAAEQACAQAAAAAAhACAIAQAAAAAAYAEiAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform_GLUT" Collapsed="true">
|
||||
<Position X="0.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gAgIgAAAEAQAAAAAAAAAAACAJAAAQAAAAQAEiAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform_Headless" Collapsed="true">
|
||||
<Position X="3" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIgAAAEAAAAAAAAAAAAACAIAAAAAAAAQAEiAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform_Linux" Collapsed="true">
|
||||
<Position X="5.25" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIgSAAEAAAgAAAAAAAAACAICgAAAAAAUAEiAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Platform_Windows" Collapsed="true">
|
||||
<Position X="7.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIgEAAEAAAABAAAAAAAAOAIAAAAAAAAUAEiAAAAQA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Renderable" Collapsed="true">
|
||||
<Position X="17.25" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAgAAAAAQAAAAAAAAAAAgAAAAAAEAQEAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Renderer" Collapsed="true">
|
||||
<Position X="3" Y="9.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>SAAgAAAAAIBASAAACAAAAgAAAAAEAIBAAIBAAAEACgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Renderer_Headless" Collapsed="true">
|
||||
<Position X="0.75" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>SAAAAAAAAIBASAAACAAAAgAAAAAEAIBAAIBAAAEAAgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Renderer_OGL10" Collapsed="true">
|
||||
<Position X="3" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>SAAAASAAQIBASCAACAAAAgAAAAAGAIBAAMJUAAEAAgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Renderer_OGL33" Collapsed="true">
|
||||
<Position X="5.25" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>SCghAyFBQIBWSCIAGAAAIgABQAAGBJhBAsJMEEEACgg=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::ResourcePack" Collapsed="true">
|
||||
<Position X="19" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgAAAAAEAAAIAAIBAIAgAAAAAAAAAAAACgIAIAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::Sprite" Collapsed="true">
|
||||
<Position X="22.5" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAABABBAEAAQgAQBQAAAAABAAAAAIAAQAAEAAgAAEAI=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::TileTransformedView" Collapsed="true">
|
||||
<Position X="0.5" Y="15.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAABAAAAAAAEAAAAAEAAAAAAAIAAAAEAIA=</HashCode>
|
||||
<FileName>olcPGEX_TransformedView.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::TransformedView" Collapsed="true">
|
||||
<Position X="0.5" Y="13.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ABXBQAQAAFAGAzQACAMCyEQSUAAECDAQAsDE4AAIAog=</HashCode>
|
||||
<FileName>olcPGEX_TransformedView.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::Camera2D" Collapsed="true">
|
||||
<Position X="20.75" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>JDQCAAACoCBAAhIBBAAAAAiAAAgAECAAAAIAAXAAARY=</HashCode>
|
||||
<FileName>olcUTIL_Camera2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::datafile" Collapsed="true">
|
||||
<Position X="22.5" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EgACAAIAMCAAAAIIAEAABAAgAQEAACAAAAACCAGAAIA=</HashCode>
|
||||
<FileName>olcUTIL_DataFile.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::datafiledoubledata" Collapsed="true">
|
||||
<Position X="24.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAIAAAAAAAAAAAAAAEAAAAAAEAAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_DataFile.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::datafilefloatdata" Collapsed="true">
|
||||
<Position X="26" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAEAAAAAAECAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_DataFile.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::datafileintdata" Collapsed="true">
|
||||
<Position X="17.25" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAEAAAAAAUAAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_DataFile.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::datafilestringdata" Collapsed="true">
|
||||
<Position X="19" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAgAAAAAAAAAAAAAAAEAAAAAAEAAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_DataFile.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::Animate2D::Animation<StatesEnum>" Collapsed="true">
|
||||
<Position X="19" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAEAAAAAEABAAAgIAAAAAAAAAAAAAAAAAABAAACAA=</HashCode>
|
||||
<FileName>olcUTIL_Animate2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::Animate2D::Frame" Collapsed="true">
|
||||
<Position X="22.5" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAEAAAEAAAAAIE=</HashCode>
|
||||
<FileName>olcUTIL_Animate2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="olc::utils::Animate2D::FrameSequence" Collapsed="true">
|
||||
<Position X="24.25" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAEAAAACAAAAEAAAAABAAAEAAAAAAAAEAAgBAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_Animate2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="safemap<T, O>" Collapsed="true">
|
||||
<Position X="20.75" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAEAAAABAAEAAAAAAAAAAAAAEAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>safemap.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="sig::Animation" Collapsed="true">
|
||||
<Position X="17.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>Animation.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="TMXParser" Collapsed="true">
|
||||
<Position X="24.25" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAEAABYQAAAAAEAAAAACABIAAAKAAAAAAAAAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="TSXParser" Collapsed="true">
|
||||
<Position X="26" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAIAAAAEEAAAAAAAAAAAAAAAAAAAAAAAIgAACAAQAAA=</HashCode>
|
||||
<FileName>TSXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Struct Name="Ability" Collapsed="true">
|
||||
<Position X="17.25" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAABAAAAAAAAwACABAAAAAAACAEAAACAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Ability.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="AnimationData" Collapsed="true">
|
||||
<Position X="19" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Animation.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Arrow" Collapsed="true">
|
||||
<Position X="9.75" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAQAQAAAAAABAAAAAIgAAAAAAAAAAAAAAAgAAAAAAAA=</HashCode>
|
||||
<FileName>BulletTypes.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Buff" Collapsed="true">
|
||||
<Position X="22.5" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAIAAAAAAAAAAAAAAAAAAAABCAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Buff.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Bullet" Collapsed="true">
|
||||
<Position X="5.25" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CgREEAAACAAAggAAIKgABYACAAAAABAMAEAAgQBQAgA=</HashCode>
|
||||
<FileName>Bullet.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="CastInfo" Collapsed="true">
|
||||
<Position X="24.25" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAABAAAEAAAAAIAACAAAAAA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="ChargedArrow" Collapsed="true">
|
||||
<Position X="0.75" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAQAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAABAAAAAAAE=</HashCode>
|
||||
<FileName>BulletTypes.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="DamageNumber" Collapsed="true">
|
||||
<Position X="26" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAgAAAAAIAAAwAAAAAAAAIACAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DamageNumber.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Emitter" Collapsed="true">
|
||||
<Position X="6.5" Y="12.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAgAAAAAAAAAAAAAABAABAAAAACIAAgAAAAAAAA=</HashCode>
|
||||
<FileName>Emitter.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="EnergyBolt" Collapsed="true">
|
||||
<Position X="5.25" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAQAAAAACAAAAAAAAAgAAAAAAAAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>BulletTypes.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="FireBolt" Collapsed="true">
|
||||
<Position X="7.5" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAQAAAAAAAAAAAAAAAgAAAAAAAAEAAAAAAAAAAAQAAA=</HashCode>
|
||||
<FileName>BulletTypes.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="LayerTag" Collapsed="true">
|
||||
<Position X="22.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAACAAAAAAAAAAAAAAAAAAAgAAACAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="LightningBolt" Collapsed="true">
|
||||
<Position X="3" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAQAAAAAAAAAAAAAAAgAAAAAAAAkAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>BulletTypes.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Map" Collapsed="true">
|
||||
<Position X="24.25" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAQAAAAQAAACAAAAAAAAAAAAAAAACACAAEAAAAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="MapTag" Collapsed="true">
|
||||
<Position X="26" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAIAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Meteor" Collapsed="true">
|
||||
<Position X="12.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAAAAAAAQgAAAAEAAAAAAAAAAAAAAAAAAACAAAA=</HashCode>
|
||||
<FileName>Effect.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Monster" Collapsed="true">
|
||||
<Position X="17.25" Y="5.75" Width="1.5" />
|
||||
<Compartments>
|
||||
<Compartment Name="Nested Types" Collapsed="false" />
|
||||
</Compartments>
|
||||
<NestedTypes>
|
||||
<Struct Name="Monster::STRATEGY" Collapsed="true">
|
||||
<TypeIdentifier>
|
||||
<NewMemberFileName>Monster.h</NewMemberFileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
</NestedTypes>
|
||||
<TypeIdentifier>
|
||||
<HashCode>FSSAFFAEAKB4CxYAIKAOBIgBIYYC8gAEikFMCRCwkgE=</HashCode>
|
||||
<FileName>Monster.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="MonsterData" Collapsed="true">
|
||||
<Position X="19" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EAAACGAAsABAAQEQAIAAgAAQAAAEECAQgABAAiAQIkA=</HashCode>
|
||||
<FileName>Monster.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="MonsterSpawner" Collapsed="true">
|
||||
<Position X="20.75" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAIQAAAAAAAAIgIAIgAAAAAAAAAAAgBAgAAgAA=</HashCode>
|
||||
<FileName>Monster.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::DecalInstance" Collapsed="true">
|
||||
<Position X="17.25" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AgAAAACAAAAAAACAAAAAAIAAAAAQBAAAAAgAAAAAAgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::HWButton" Collapsed="true">
|
||||
<Position X="19" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAgAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAgA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::LayerDesc" Collapsed="true">
|
||||
<Position X="20.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AkAIAAAAAAAAABAABQAACAAAAAABQAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::Pixel" Collapsed="true">
|
||||
<Position X="24.25" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAIAAAAAAAAAAAAAABAQAAAAAAAAAAAAAgAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::ResourceBuffer" Collapsed="true">
|
||||
<Position X="17.25" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAIAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="olc::utils::Animate2D::AnimationState" Collapsed="true">
|
||||
<Position X="20.75" Y="3.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
|
||||
<FileName>olcUTIL_Animate2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Pathfinding" Collapsed="true">
|
||||
<Position X="22.5" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAQAEAAgAAAAAAAAAAAAAQAAAAAAAIAA=</HashCode>
|
||||
<FileName>Pathfinding.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Player" Collapsed="true">
|
||||
<Position X="6.5" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EO9g1XQE4IJq4TbQBqAlYY0RO0YCNkh05FFEjTtkojQ=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="PrecastData" Collapsed="true">
|
||||
<Position X="26" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAIAAAAAAAEAIAAAAABAAAAAAAAAAAgAAAAAAA=</HashCode>
|
||||
<FileName>Ability.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="PulsatingFire" Collapsed="true">
|
||||
<Position X="14.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQBAAAAAAAAAgAAAAAAAEAAAAAAAAAAAAAAEAAAAAE=</HashCode>
|
||||
<FileName>Effect.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Ranger" Collapsed="true">
|
||||
<Position X="3.25" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAkAwQEAQAAIqQBQAAAEIAQACAAEMgAABAAEAAkgAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="SpawnerTag" Collapsed="true">
|
||||
<Position X="19" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAQAAIAAAAAIAAAAAAAAAAACAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Thief" Collapsed="true">
|
||||
<Position X="7.75" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAkAwQEAYAAIoQBQAAAEIAQACAAEMgAABAAEAAkgAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="TileCollisionData" Collapsed="true">
|
||||
<Position X="20.75" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Map.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="TileGroup" Collapsed="true">
|
||||
<Position X="22.5" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CDAAAAAISAgAAAAAAAAAAAAAAgAAACAAAAkAADAAQAA=</HashCode>
|
||||
<FileName>Map.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="TileRenderData" Collapsed="true">
|
||||
<Position X="24.25" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAEAAAAAAAAAAAAAIAAQAAAAAAAIAAAAAAAAAA=</HashCode>
|
||||
<FileName>Map.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Tileset" Collapsed="true">
|
||||
<Position X="26" Y="6.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAIAAAgAAAAAAgAAAAIAAAQAAAAAAAAAABAAAAAA=</HashCode>
|
||||
<FileName>TSXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="TilesetData" Collapsed="true">
|
||||
<Position X="17.25" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgAAAAAAAAAAAAAAAAIAAAAAAAAAAIAAEAQIAAAA=</HashCode>
|
||||
<FileName>Map.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="TilesheetData" Collapsed="true">
|
||||
<Position X="19" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAA=</HashCode>
|
||||
<FileName>Crawler.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Trapper" Collapsed="true">
|
||||
<Position X="1" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAkAwQEAQAAIoQBQAAAEIAQECAAEMgAABAAEAAkgAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Warrior" Collapsed="true">
|
||||
<Position X="12.25" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ACkAgQEAQAAIoQBQAAAEAAQACAAEIgAAAAAEAAkAAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Witch" Collapsed="true">
|
||||
<Position X="10" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAkAwQEAQAAIoQBQAAAEKAQACAAEMgAABAAEAAkgAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Wizard" Collapsed="true">
|
||||
<Position X="5.5" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAkAwQEAQAAIoQBQAAAEIAQACAAEMgAABAIEAAkgAgA=</HashCode>
|
||||
<FileName>Player.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="XMLTag" Collapsed="true">
|
||||
<Position X="20.75" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AACAACAgACAAAIAAAAAAAAAAAAAAACAAAAAQAAAAQAA=</HashCode>
|
||||
<FileName>TMXParser.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Enum Name="Attribute" Collapsed="true">
|
||||
<Position X="17.25" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AQQBgAAAAAoAAIAAAAAAAAIAJAAAAACAAAAAAAAAAAI=</HashCode>
|
||||
<FileName>MonsterAttribute.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="BuffType" Collapsed="true">
|
||||
<Position X="19" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAgAIAAAAAAAAAAAAAAAAAAAAEAgAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Buff.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="Class" Collapsed="true">
|
||||
<Position X="20.75" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AACAAAAAAAAAAAAAAAgAAAAEAAggAAAAAAAAAAAACAA=</HashCode>
|
||||
<FileName>Class.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="MapName" Collapsed="true">
|
||||
<Position X="17.25" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAABAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Map.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="MonsterAnimation" Collapsed="true">
|
||||
<Position X="19" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAEAAAAAAAAgAAACAAAAAAAQAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Monster.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="olc::DecalMode" Collapsed="true">
|
||||
<Position X="22.5" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAgAAAAAACCAAAAAABAAAIAAAAAAAAAAAAAgAAAABAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="olc::DecalStructure" Collapsed="true">
|
||||
<Position X="24.25" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAACAAAAAAAAAAAAAIAAAAEQAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="olc::Key" Collapsed="true">
|
||||
<Position X="26" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>IgBKPCYRIAQCigCAAQAAwU8kkgMKYJhzAAAAvv//YQE=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="olc::rcode" Collapsed="true">
|
||||
<Position X="20.75" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAgCA=</HashCode>
|
||||
<FileName>olcPixelGameEngine.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="olc::utils::Animate2D::Style" Collapsed="true">
|
||||
<Position X="24.25" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAQAAAAAAAAACAAAAAAAAICAAAAAAA=</HashCode>
|
||||
<FileName>olcUTIL_Animate2D.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="State::State" Collapsed="true">
|
||||
<Position X="22.5" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAABAQCAAgCAACABABEBKAgACAAAABAgAAAAAAAA=</HashCode>
|
||||
<FileName>State.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
BIN
Crawler/ClassDiagram2.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
Crawler/Crawler
@ -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;
|
||||
@ -62,6 +63,8 @@ Crawler::Crawler()
|
||||
std::string MONSTERSTRATEGIES_CONFIG = CONFIG_PATH + "monsterstrategies_config"_S;
|
||||
utils::datafile::Read(DATA,MONSTERSTRATEGIES_CONFIG);
|
||||
|
||||
DEBUG_PATHFINDING="debug_pathfinding"_I;
|
||||
|
||||
for(std::string&cl:DATA.GetProperty("class_list").GetValues()){
|
||||
std::cout<<cl<<std::endl;
|
||||
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
|
||||
@ -70,7 +73,6 @@ Crawler::Crawler()
|
||||
}
|
||||
|
||||
bool Crawler::OnUserCreate(){
|
||||
|
||||
InitializeLevels();
|
||||
|
||||
player=std::make_unique<Warrior>();
|
||||
@ -82,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
|
||||
@ -130,18 +109,22 @@ bool Crawler::OnUserCreate(){
|
||||
InitializeClasses();
|
||||
ChangePlayerClass(WARRIOR);
|
||||
Warrior::ability4=Ranger::ability1; //Class ability swapping demonstration.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Crawler::OnUserUpdate(float fElapsedTime){
|
||||
fElapsedTime=std::clamp(fElapsedTime,0.f,1/60.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/60th of a second.
|
||||
fElapsedTime=std::clamp(fElapsedTime,0.f,1/30.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/30th of a second.
|
||||
levelTime+=fElapsedTime;
|
||||
HandleUserInput(fElapsedTime);
|
||||
UpdateEffects(fElapsedTime);
|
||||
player->Update(fElapsedTime);
|
||||
for(Monster&m:MONSTER_LIST){
|
||||
m.Update(fElapsedTime);
|
||||
}
|
||||
for(Monster&m:monstersToBeSpawned){
|
||||
MONSTER_LIST.push_back(m);
|
||||
}
|
||||
monstersToBeSpawned.clear();
|
||||
UpdateBullets(fElapsedTime);
|
||||
UpdateCamera(fElapsedTime);
|
||||
RenderWorld(fElapsedTime);
|
||||
@ -212,8 +195,8 @@ void Crawler::HandleUserInput(float fElapsedTime){
|
||||
int truncatedPlayerY=int(player->GetY())/24;
|
||||
int tileID=layer.tiles[truncatedPlayerY][truncatedPlayerX];
|
||||
TilesheetData dat=GetTileSheet(GetCurrentLevel(),tileID);
|
||||
if (dat.tileset.staircaseTiles.find(tileID)!=dat.tileset.staircaseTiles.end()){
|
||||
return dat.tileset.staircaseTiles[tileID].data["value"];
|
||||
if (dat.tileset->staircaseTiles.find(tileID)!=dat.tileset->staircaseTiles.end()){
|
||||
return dat.tileset->staircaseTiles[tileID].data["value"];
|
||||
}
|
||||
}
|
||||
return std::string("NONE");
|
||||
@ -399,6 +382,7 @@ void Crawler::UpdateEffects(float fElapsedTime){
|
||||
std::erase_if(EMITTER_LIST,[](std::unique_ptr<Emitter>&e){return e->dead;});
|
||||
std::erase_if(backgroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||||
std::erase_if(foregroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||||
std::erase_if(DAMAGENUMBER_LIST,[](std::shared_ptr<DamageNumber>&n){return n->lifeTime>1;});
|
||||
|
||||
for(auto it=foregroundEffectsToBeInserted.begin();it!=foregroundEffectsToBeInserted.end();++it){
|
||||
foregroundEffects.push_back(std::move(*it));
|
||||
@ -417,13 +401,10 @@ void Crawler::UpdateBullets(float fElapsedTime){
|
||||
b->animation.UpdateState(b->internal_animState,fElapsedTime);
|
||||
if(!b->deactivated){
|
||||
float totalDistance=(b->vel*fElapsedTime).mag();
|
||||
vf2d moveStep=b->vel*fElapsedTime;
|
||||
if((b->vel*fElapsedTime).mag()>1){
|
||||
moveStep=(b->vel*fElapsedTime).norm();
|
||||
}
|
||||
while(totalDistance>0){
|
||||
totalDistance=std::max(0.f,totalDistance-1);
|
||||
b->pos+=moveStep;
|
||||
int iterations=std::max(1.f,(b->vel*fElapsedTime).mag());
|
||||
int totalIterations=iterations;
|
||||
vf2d finalBulletPos=b->pos+b->vel*fElapsedTime;
|
||||
const auto CollisionCheck=[&](){
|
||||
if(b->friendly){
|
||||
for(Monster&m:MONSTER_LIST){
|
||||
if(geom2d::overlaps(geom2d::circle(m.GetPos(),12*m.GetSizeMult()),geom2d::circle(b->pos,b->radius))){
|
||||
@ -431,7 +412,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
|
||||
if(!b->hitsMultiple){
|
||||
if(b->MonsterHit(m)){
|
||||
b->dead=true;
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
b->hitList[&m]=true;
|
||||
@ -443,13 +424,26 @@ void Crawler::UpdateBullets(float fElapsedTime){
|
||||
if(player->Hurt(b->damage,b->OnUpperLevel(),0)){
|
||||
if(b->PlayerHit(player.get())){
|
||||
b->dead=true;
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
while(iterations>0){
|
||||
iterations--;
|
||||
b->pos+=(b->vel*fElapsedTime)/float(totalIterations);
|
||||
if(!CollisionCheck()){
|
||||
goto nextBullet;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
b->pos=finalBulletPos;
|
||||
if(!CollisionCheck()){
|
||||
goto nextBullet;
|
||||
}
|
||||
}else{
|
||||
b->pos+=b->vel*fElapsedTime;
|
||||
}
|
||||
if(b->pos.x+b->radius<view.GetWorldTL().x-WINDOW_SIZE.x||b->pos.x-b->radius>view.GetWorldBR().x+WINDOW_SIZE.x||b->pos.y+b->radius<view.GetWorldTL().y-WINDOW_SIZE.y||b->pos.y-b->radius>view.GetWorldBR().y+WINDOW_SIZE.y){
|
||||
@ -461,6 +455,8 @@ void Crawler::UpdateBullets(float fElapsedTime){
|
||||
b->dead=true;
|
||||
continue;
|
||||
}
|
||||
nextBullet:
|
||||
int a;
|
||||
}
|
||||
outsideBulletLoop:
|
||||
std::erase_if(BULLET_LIST,[](std::unique_ptr<Bullet>&b){return b->dead;});
|
||||
@ -473,7 +469,18 @@ void Crawler::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float
|
||||
}
|
||||
}
|
||||
|
||||
void Crawler::PopulateRenderLists(std::vector<Monster*>&monstersBeforeLower,std::vector<Monster*>&monstersBeforeUpper,std::vector<Monster*>&monstersAfterLower,std::vector<Monster*>&monstersAfterUpper,std::vector<Bullet*>&bulletsLower,std::vector<Bullet*>&bulletsUpper,std::vector<Effect*>&backgroundEffectsLower,std::vector<Effect*>&backgroundEffectsUpper,std::vector<Effect*>&foregroundEffectsLower,std::vector<Effect*>&foregroundEffectsUpper){
|
||||
void Crawler::PopulateRenderLists(){
|
||||
monstersBeforeLower.clear();
|
||||
monstersAfterLower.clear();
|
||||
monstersBeforeUpper.clear();
|
||||
monstersAfterUpper.clear();
|
||||
bulletsLower.clear();
|
||||
bulletsUpper.clear();
|
||||
backgroundEffectsLower.clear();
|
||||
backgroundEffectsUpper.clear();
|
||||
foregroundEffectsLower.clear();
|
||||
foregroundEffectsUpper.clear();
|
||||
|
||||
Player*pl=GetPlayer();
|
||||
for(auto it=MONSTER_LIST.begin();it!=MONSTER_LIST.end();++it){
|
||||
Monster&m=*it;
|
||||
@ -521,49 +528,157 @@ void Crawler::PopulateRenderLists(std::vector<Monster*>&monstersBeforeLower,std:
|
||||
std::sort(monstersAfterLower.begin(),monstersAfterLower.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
|
||||
}
|
||||
|
||||
void Crawler::RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos){
|
||||
if(tileSheet.tileset->animationData.count(tileSheetIndex)){
|
||||
int animationDuration_ms=tileSheet.tileset->animationData[tileSheetIndex].size()*"animation_tile_precision"_I;
|
||||
int animatedIndex=tileSheet.tileset->animationData[tileSheetIndex][int(fmod(levelTime*1000,animationDuration_ms)/"animation_tile_precision"_I)];
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetX=animatedIndex%tileSheetWidth;
|
||||
int tileSheetY=animatedIndex/tileSheetWidth;
|
||||
view.DrawPartialDecal(pos*24,{24,24},tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY}*24,{24,24});
|
||||
}else{
|
||||
view.DrawPartialDecal(pos*24,{24,24},tileSheet.tileset->tileset->Decal(),tileSheetPos*24,{24,24});
|
||||
}
|
||||
}
|
||||
|
||||
void Crawler::RenderTile(TileRenderData&tileSheet,Pixel col){
|
||||
if(tileSheet.tileSheet.tileset->animationData.count(tileSheet.tileID%1000000)){
|
||||
int animationDuration_ms=tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000].size()*"animation_tile_precision"_I;
|
||||
int animatedIndex=tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000][int(fmod(levelTime*1000,animationDuration_ms)/"animation_tile_precision"_I)];
|
||||
int tileSheetWidth=tileSheet.tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetX=animatedIndex%tileSheetWidth;
|
||||
int tileSheetY=animatedIndex/tileSheetWidth;
|
||||
view.DrawPartialDecal(tileSheet.pos,{24,24},tileSheet.tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY},{24,24},col);
|
||||
}else{
|
||||
view.DrawPartialDecal(tileSheet.pos,{24,24},tileSheet.tileSheet.tileset->tileset->Decal(),tileSheet.tileSheetPos,{24,24},col);
|
||||
}
|
||||
}
|
||||
|
||||
void Crawler::RenderWorld(float fElapsedTime){
|
||||
Clear({100,180,100});
|
||||
Clear(BLANK);
|
||||
LayerTag*bridgeLayer=nullptr;
|
||||
bool bridgeLayerFade=false;
|
||||
Player*pl=GetPlayer();
|
||||
|
||||
PopulateRenderLists();
|
||||
|
||||
auto RenderPlayer=[&](vf2d pos,vf2d scale){
|
||||
vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult());
|
||||
int count=0;
|
||||
for(vf2d&pos:player->ghostPositions){
|
||||
view.DrawPartialRotatedDecal(pos,player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,{0,0,0,uint8_t(float(count)/player->RETREAT_GHOST_FRAMES*255)});
|
||||
count++;
|
||||
}
|
||||
if(player->teleportAnimationTimer>0){
|
||||
playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3));
|
||||
pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35);
|
||||
}
|
||||
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);
|
||||
};
|
||||
|
||||
enum class RenderMode{
|
||||
REFLECTIVE_TILES,
|
||||
NORMAL_TILES,
|
||||
EMPTY_TILES,
|
||||
};
|
||||
|
||||
reflectionUpdateTimer-=fElapsedTime;
|
||||
if(reflectionUpdateTimer<=0){
|
||||
reflectionStepTime+="water_reflection_time_step"_F;
|
||||
reflectionUpdateTimer="water_reflection_update_time"_F;
|
||||
}
|
||||
|
||||
#pragma region Basic Tile Layer Rendering
|
||||
for(RenderMode mode=RenderMode::REFLECTIVE_TILES;mode<=RenderMode::EMPTY_TILES;mode=RenderMode(int(mode)+1)){
|
||||
if(mode==RenderMode::NORMAL_TILES){
|
||||
SetDecalMode(DecalMode::ADDITIVE);
|
||||
float reflectionHeight=(float(player->GetFrame().GetSourceRect().size.y)-8)*player->GetSizeMult();
|
||||
float reflectionBottom=player->GetPos().y+reflectionHeight;
|
||||
float cutOff=reflectionBottom-WORLD_SIZE.y*24;
|
||||
float multiplierX=0.9;
|
||||
multiplierX*=(1-abs(sin(reflectionStepTime))*"water_reflection_scale_factor"_F);
|
||||
multiplierX*=(1-abs(cos(1.5*reflectionStepTime))*"water_reflection_scale_factor"_F);
|
||||
float reflectionRatioX=abs(sin(reflectionStepTime))*"water_reflection_scale_factor"_F;
|
||||
RenderPlayer(player->GetPos()+vf2d{reflectionRatioX*player->GetFrame().GetSourceRect().size.x,float(player->GetFrame().GetSourceRect().size.y)-8}*player->GetSizeMult(),{multiplierX,-1});
|
||||
for(Monster&m:MONSTER_LIST){
|
||||
m.DrawReflection(reflectionRatioX,multiplierX);
|
||||
}
|
||||
SetDecalMode(DecalMode::NORMAL);
|
||||
}
|
||||
for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){
|
||||
for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){
|
||||
if(x>=0&&x<WORLD_SIZE.x&&y>=0&&y<WORLD_SIZE.y){
|
||||
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||||
if(IsBridgeLayer(layer)){
|
||||
bridgeLayer=&layer;
|
||||
if(!bridgeLayerFade&&!player->upperLevel){
|
||||
switch(mode){
|
||||
case RenderMode::NORMAL_TILES:{
|
||||
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||||
if(IsBridgeLayer(layer)){
|
||||
bridgeLayer=&layer;
|
||||
if(!bridgeLayerFade&&!player->upperLevel){
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
int playerXTruncated=int(player->GetPos().x)/24;
|
||||
int playerYTruncated=int(player->GetPos().y)/24;
|
||||
if(playerXTruncated==x&&playerYTruncated==y){
|
||||
bridgeLayerFade=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
int playerXTruncated=int(player->GetPos().x)/24;
|
||||
int playerYTruncated=int(player->GetPos().y)/24;
|
||||
if(playerXTruncated==x&&playerYTruncated==y){
|
||||
bridgeLayerFade=true;
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheetIndex)&&!IsReflectiveTile(tileSheet,tileSheetIndex)){
|
||||
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
|
||||
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
|
||||
}
|
||||
if("debug_collision_boxes"_I){
|
||||
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
|
||||
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
|
||||
view.FillRectDecal(vi2d{x,y}*24+collision.pos,collision.size,{0,0,0,128});
|
||||
view.DrawRectDecal(vi2d{x,y}*24+collision.pos,collision.size,GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset.tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset.tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheet,tileSheetIndex)){
|
||||
view.DrawPartialDecal(vi2d{x,y}*24,{24,24},tileSheet.tileset.tileset->Decal(),vi2d{tileSheetX,tileSheetY}*24,{24,24});
|
||||
}
|
||||
if("debug_collision_boxes"_I){
|
||||
if(tileSheet.tileset.collision.find(tileSheetIndex)!=tileSheet.tileset.collision.end()){
|
||||
geom2d::rect<int>collision=tileSheet.tileset.collision[tileSheetIndex].collision;
|
||||
view.FillRectDecal(vi2d{x,y}*24+collision.pos,collision.size,{0,0,0,128});
|
||||
view.DrawRectDecal(vi2d{x,y}*24+collision.pos,collision.size,GREY);
|
||||
}break;
|
||||
case RenderMode::REFLECTIVE_TILES:{
|
||||
visibleTiles.insert({x,y});
|
||||
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
if(IsReflectiveTile(tileSheet,tileSheetIndex)){
|
||||
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
|
||||
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
|
||||
}
|
||||
if("debug_collision_boxes"_I){
|
||||
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
|
||||
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
|
||||
view.FillRectDecal(vi2d{x,y}*24+collision.pos,collision.size,{0,0,0,128});
|
||||
view.DrawRectDecal(vi2d{x,y}*24+collision.pos,collision.size,GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case RenderMode::EMPTY_TILES:{
|
||||
if(visibleTiles.count({x,y})){
|
||||
view.FillRectDecal(vi2d{x,y}*24,{24,24},{100,180,100});
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -572,18 +687,17 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
}else{
|
||||
bridgeFadeFactor=std::max(bridgeFadeFactor-fElapsedTime,0.f);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
//DrawDecal({0,0},MAP_TILESETS["assets/maps/"+MAP_DATA[LEVEL1].TilesetData[1].data["source"]]->Decal());
|
||||
std::vector<Monster*>monstersBeforeLower,monstersAfterLower,monstersBeforeUpper,monstersAfterUpper;
|
||||
std::vector<Bullet*>bulletsLower,bulletsUpper;
|
||||
std::vector<Effect*>backgroundEffectsLower,backgroundEffectsUpper,foregroundEffectsLower,foregroundEffectsUpper;
|
||||
Player*pl=GetPlayer();
|
||||
|
||||
PopulateRenderLists(monstersBeforeLower,monstersBeforeUpper,monstersAfterLower,monstersAfterUpper,bulletsLower,bulletsUpper,backgroundEffectsLower,backgroundEffectsUpper,foregroundEffectsLower,foregroundEffectsUpper);
|
||||
for(Monster&m:MONSTER_LIST){
|
||||
m.strategyDraw(this);
|
||||
}
|
||||
|
||||
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();
|
||||
@ -591,28 +705,11 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
for(Monster*m:monstersBeforeLower){
|
||||
m->Draw();
|
||||
}
|
||||
vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult());
|
||||
vf2d playerPosition=player->GetPos();
|
||||
auto RenderPlayer=[&](){
|
||||
int count=0;
|
||||
for(vf2d&pos:player->ghostPositions){
|
||||
view.DrawPartialRotatedDecal(pos,player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,{0,0,0,uint8_t(float(count)/player->RETREAT_GHOST_FRAMES*255)});
|
||||
count++;
|
||||
}
|
||||
if(player->teleportAnimationTimer>0){
|
||||
playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3));
|
||||
playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35);
|
||||
view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);
|
||||
} else {
|
||||
view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);
|
||||
}
|
||||
};
|
||||
//define end
|
||||
if(!player->upperLevel){
|
||||
RenderPlayer();
|
||||
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();
|
||||
@ -628,15 +725,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});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -654,7 +751,7 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
|
||||
}
|
||||
for(TileRenderData&tile:group.GetTiles()){
|
||||
view.DrawPartialDecal(tile.pos,{24,24},tile.tileset,tile.tileSheetPos,{24,24},{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
RenderTile(tile,{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -667,12 +764,12 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
int tileID=bridgeLayer->tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset.tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset.tileset->Sprite()->height/24;
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
view.DrawPartialDecal(vi2d{x,y}*24,{24,24},tileSheet.tileset.tileset->Decal(),vi2d{tileSheetX,tileSheetY}*24,{24,24},{255,255,255,uint8_t(255-bridgeFadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
view.DrawPartialDecal(vi2d{x,y}*24,{24,24},tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY}*24,{24,24},{255,255,255,uint8_t(255-bridgeFadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
#ifdef DEBUG_COLLISIONS
|
||||
if(tileSheet.tileset.collision.find(tileSheetIndex)!=tileSheet.tileset.collision.end()){
|
||||
geom2d::rect<int>collision=tileSheet.tileset.collision[tileSheetIndex].collision;
|
||||
@ -693,7 +790,7 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
m->Draw();
|
||||
}
|
||||
if(player->upperLevel){
|
||||
RenderPlayer();
|
||||
RenderPlayer(player->GetPos(),{1,1});
|
||||
}
|
||||
for(Monster*m:monstersAfterUpper){
|
||||
m->Draw();
|
||||
@ -717,7 +814,7 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
|
||||
}
|
||||
for(TileRenderData&tile:group.GetTiles()){
|
||||
view.DrawPartialDecal(tile.pos,{24,24},tile.tileset,tile.tileSheetPos,{24,24},{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
RenderTile(tile,{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
@ -727,21 +824,22 @@ void Crawler::RenderWorld(float fElapsedTime){
|
||||
dn->pauseTime-=fElapsedTime;
|
||||
} else{
|
||||
dn->lifeTime+=fElapsedTime;
|
||||
if(dn->lifeTime>1){
|
||||
it=DAMAGENUMBER_LIST.erase(it);
|
||||
if(it==DAMAGENUMBER_LIST.end()){
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(dn->lifeTime<=1){
|
||||
if(dn->lifeTime<DamageNumber::MOVE_UP_TIME){
|
||||
dn->pos.y-=20*fElapsedTime;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
std::string text=std::to_string(dn->damage);
|
||||
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,DARK_RED);
|
||||
}
|
||||
|
||||
if(DEBUG_PATHFINDING){
|
||||
std::vector<vf2d>pathing=game->pathfinder.Solve_AStar(player.get()->GetPos(),GetWorldMousePos(),8,player.get()->OnUpperLevel());
|
||||
for(vf2d&square:pathing){
|
||||
view.FillRectDecal(square*24,{24,24},DARK_GREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player*Crawler::GetPlayer(){
|
||||
@ -798,8 +896,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});
|
||||
@ -862,6 +960,9 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
|
||||
MAP_TILESETS["assets/maps/"+baseSourceDir].upperForegroundTiles=tileset.GetData().UpperForegroundTileData;
|
||||
MAP_TILESETS["assets/maps/"+baseSourceDir].collision=tileset.GetData().CollisionData;
|
||||
MAP_TILESETS["assets/maps/"+baseSourceDir].staircaseTiles=tileset.GetData().StaircaseData;
|
||||
MAP_TILESETS["assets/maps/"+baseSourceDir].animationData=tileset.GetData().AnimationData;
|
||||
MAP_TILESETS["assets/maps/"+baseSourceDir].reflectiveData=tileset.GetData().ReflectiveData;
|
||||
std::cout<<"assets/maps/"+baseSourceDir<<" Animation Data Size: "<<MAP_TILESETS["assets/maps/"+baseSourceDir].animationData.size()<<std::endl;
|
||||
r->Load("assets/maps/"+tileset.GetData().ImageData.data["source"]);
|
||||
}
|
||||
}
|
||||
@ -872,103 +973,148 @@ void Crawler::LoadLevel(MapName map){
|
||||
foregroundTileGroups.clear();
|
||||
currentLevel=map;
|
||||
WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height};
|
||||
levelTime=0;
|
||||
|
||||
for(auto key:MAP_DATA[map].SpawnerData){
|
||||
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key.first];
|
||||
std::vector<std::pair<int,vf2d>>monster_list;
|
||||
#pragma region Monster Spawn Data Setup
|
||||
for(auto key:MAP_DATA[map].SpawnerData){
|
||||
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key.first];
|
||||
std::vector<std::pair<int,vf2d>>monster_list;
|
||||
|
||||
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||||
for(XMLTag&monster:spawnData.monsters){
|
||||
int monsterTypeID=monster.GetInteger("value")-1;
|
||||
monster_list.push_back({monsterTypeID,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||||
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||||
for(XMLTag&monster:spawnData.monsters){
|
||||
int monsterTypeID=monster.GetInteger("value")-1;
|
||||
monster_list.push_back({monsterTypeID,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||||
}
|
||||
SPAWNER_LIST.push_back(MonsterSpawner{{spawnData.ObjectData.GetFloat("x"),spawnData.ObjectData.GetFloat("y")},spawnerRadius*2,monster_list,spawnData.upperLevel});
|
||||
}
|
||||
SPAWNER_LIST.push_back(MonsterSpawner{{spawnData.ObjectData.GetFloat("x"),spawnData.ObjectData.GetFloat("y")},spawnerRadius*2,monster_list,spawnData.upperLevel});
|
||||
}
|
||||
|
||||
std::set<vi2d>foregroundTilesAdded,upperForegroundTilesAdded;
|
||||
for(int x=0;x<WORLD_SIZE.x;x++){
|
||||
for(int y=0;y<WORLD_SIZE.y;y++){
|
||||
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset.tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset.tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
#pragma region TileGroupShenanigans
|
||||
auto SetupTileGroups=[&](std::function<bool(TilesheetData,int)>IsForeground,TileRenderData tile,std::set<vi2d>&foregroundTilesIncluded,std::vector<TileGroup>&groups){
|
||||
int layerID=layer.tag.GetInteger("id");
|
||||
if(IsForeground(tileSheet,tileSheetIndex)&&foregroundTilesIncluded.find({x,y})==foregroundTilesIncluded.end()){
|
||||
std::queue<vi2d>tileGroupChecks;
|
||||
TileGroup group;
|
||||
foregroundTilesIncluded.insert({x,y});
|
||||
group.originatingLayer=layerID;
|
||||
group.InsertTile(tile);
|
||||
if(x>0)tileGroupChecks.push({x-1,y});
|
||||
if(x<WORLD_SIZE.x-1)tileGroupChecks.push({x+1,y});
|
||||
if(y>0)tileGroupChecks.push({x,y-1});
|
||||
if(y<WORLD_SIZE.y-1)tileGroupChecks.push({x,y+1});
|
||||
auto IterateThroughOtherLayers=[&](vi2d pos){
|
||||
for(LayerTag&layer2:MAP_DATA[currentLevel].LayerData){
|
||||
if(&layer==&layer2)continue;
|
||||
int tileID=layer2.tiles[pos.y][pos.x]-1;
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset.tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset.tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
TileRenderData tile={tileSheet.tileset.tileset->Decal(),vi2d{pos.x,pos.y}*24,vi2d{tileSheetX,tileSheetY}*24};
|
||||
if(IsForeground(tileSheet,tileSheetIndex)){
|
||||
foregroundTilesIncluded.insert({pos.x,pos.y});
|
||||
group.InsertTile(tile);
|
||||
}
|
||||
}
|
||||
};
|
||||
IterateThroughOtherLayers({x,y});
|
||||
while(!tileGroupChecks.empty()){
|
||||
vi2d&pos=tileGroupChecks.front();
|
||||
tileGroupChecks.pop();
|
||||
int tileID=layer.tiles[pos.y][pos.x]-1;
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset.tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset.tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||||
TileRenderData tile={tileSheet.tileset.tileset->Decal(),pos*24,vi2d{tileSheetX,tileSheetY}*24};
|
||||
if(IsForeground(tileSheet,tileSheetIndex)&&foregroundTilesIncluded.find(pos)==foregroundTilesIncluded.end()){
|
||||
foregroundTilesIncluded.insert(pos);
|
||||
group.InsertTile(tile);
|
||||
if(pos.x>0)tileGroupChecks.push(pos+vi2d{-1,0});
|
||||
if(pos.x<WORLD_SIZE.x-1)tileGroupChecks.push(pos+vi2d{1,0});
|
||||
if(pos.y>0)tileGroupChecks.push(pos+vi2d{0,-1});
|
||||
if(pos.y<WORLD_SIZE.y-1)tileGroupChecks.push(pos+vi2d{0,1});
|
||||
IterateThroughOtherLayers(pos);
|
||||
}
|
||||
}
|
||||
groups.push_back(group);
|
||||
}
|
||||
};
|
||||
TileRenderData tile={tileSheet.tileset.tileset->Decal(),vi2d{x,y}*24,vi2d{tileSheetX,tileSheetY}*24};
|
||||
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsForegroundTile(sheet,tileID);},tile,foregroundTilesAdded,foregroundTileGroups);
|
||||
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsUpperForegroundTile(sheet,tileID);},tile,upperForegroundTilesAdded,upperForegroundTileGroups);
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Identify Upper Foreground Tiles
|
||||
auto GetUpperZones=[&](){
|
||||
for(auto&zoneSet:MAP_DATA[map].ZoneData){
|
||||
if(zoneSet.first=="UpperZone"){ //We are interested in all upper zones.
|
||||
return zoneSet.second;
|
||||
}
|
||||
}
|
||||
return std::vector<geom2d::rect<int>>{};
|
||||
};
|
||||
|
||||
for(geom2d::rect<int>&zone:GetUpperZones()){
|
||||
int zoneX=zone.pos.x/24; //snap to grid
|
||||
int zoneY=zone.pos.y/24;
|
||||
int zoneW=zone.right().start.x/24-zoneX;
|
||||
int zoneH=zone.bottom().start.y/24-zoneY;
|
||||
for(int x=zoneX;x<zoneX+zoneW;x++){
|
||||
for(int y=zoneY;y<zoneY+zoneH;y++){
|
||||
for(LayerTag&layer:MAP_DATA[map].LayerData){
|
||||
int tile=layer.tiles[y][x]-1;
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tile);
|
||||
int tileSheetIndex=tile-(tileSheet.firstgid-1);
|
||||
if(IsForegroundTile(tileSheet,tileSheetIndex)){
|
||||
layer.tiles[y][x]+=1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
int counter=0;
|
||||
bridgeLayerIndex=-1;
|
||||
for(LayerTag&layer:MAP_DATA[map].LayerData){
|
||||
if(IsBridgeLayer(layer)){
|
||||
bridgeLayerIndex=counter;
|
||||
#pragma region Foreground and Upper Foreground Tile Fade Group Setup
|
||||
std::set<vi2d>foregroundTilesAdded,upperForegroundTilesAdded;
|
||||
for(int x=0;x<WORLD_SIZE.x;x++){
|
||||
for(int y=0;y<WORLD_SIZE.y;y++){
|
||||
int layerID=0;
|
||||
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||||
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||||
#pragma region TileGroupShenanigans
|
||||
auto SetupTileGroups=[&](std::function<bool(TilesheetData,int)>IsForeground,TileRenderData tile,std::set<vi2d>&foregroundTilesIncluded,std::vector<TileGroup>&groups){
|
||||
if(foregroundTilesIncluded.find({x,y})==foregroundTilesIncluded.end()&&IsForeground(tileSheet,tileSheetIndex)){
|
||||
std::queue<vi2d>tileGroupChecks;
|
||||
TileGroup group;
|
||||
foregroundTilesIncluded.insert({x,y});
|
||||
group.InsertTile(tile);
|
||||
if(x>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{-1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x-1,y});
|
||||
if(x<WORLD_SIZE.x-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x+1,y});
|
||||
if(y>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,-1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y-1});
|
||||
if(y<WORLD_SIZE.y-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y+1});
|
||||
auto IterateThroughOtherLayers=[&](vi2d pos,bool loopAll=false){
|
||||
int layer2ID=0;
|
||||
bool hadForeground=false;
|
||||
for(LayerTag&layer2:MAP_DATA[currentLevel].LayerData){
|
||||
if(!loopAll&&&layer==&layer2){layer2ID++;continue;};
|
||||
int tileID=layer2.tiles[pos.y][pos.x]-1;
|
||||
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID%1000000);
|
||||
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/24;
|
||||
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/24;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||||
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||||
TileRenderData tile={tileSheet,vi2d{pos.x,pos.y}*24,vi2d{tileSheetX,tileSheetY}*24,realTileSheetIndex,layer2ID};
|
||||
if(IsForeground(tileSheet,tileSheetIndex)){
|
||||
foregroundTilesIncluded.insert({pos.x,pos.y});
|
||||
group.InsertTile(tile);
|
||||
hadForeground=true;
|
||||
}
|
||||
layer2ID++;
|
||||
}
|
||||
return hadForeground;
|
||||
};
|
||||
IterateThroughOtherLayers({x,y});
|
||||
while(!tileGroupChecks.empty()){
|
||||
vi2d&pos=tileGroupChecks.front();
|
||||
if(IterateThroughOtherLayers(pos,true)){
|
||||
foregroundTilesIncluded.insert({pos.x,pos.y}); //Regardless of if we found a foreground tile or not, we need to add this to not get stuck in an infinite loop.
|
||||
vi2d targetPos=pos+vi2d{-1,0};
|
||||
if(pos.x>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{1,0};
|
||||
if(pos.x<WORLD_SIZE.x-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{0,-1};
|
||||
if(pos.y>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{0,1};
|
||||
if(pos.y<WORLD_SIZE.y-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
}
|
||||
tileGroupChecks.pop();
|
||||
}
|
||||
groups.push_back(group);
|
||||
}
|
||||
};
|
||||
TileRenderData tile={tileSheet,vi2d{x,y}*24,vi2d{tileSheetX,tileSheetY}*24,tileID,layerID};
|
||||
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsForegroundTile(sheet,tileID);},tile,foregroundTilesAdded,foregroundTileGroups);
|
||||
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsUpperForegroundTile(tileID);},tile,upperForegroundTilesAdded,upperForegroundTileGroups);
|
||||
#pragma endregion
|
||||
}
|
||||
layerID++;
|
||||
}
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
for(TileGroup&group:foregroundTileGroups){
|
||||
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||||
}
|
||||
for(TileGroup&group:upperForegroundTileGroups){
|
||||
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Bridge Layer Setup
|
||||
int counter=0;
|
||||
bridgeLayerIndex=-1;
|
||||
for(LayerTag&layer:MAP_DATA[map].LayerData){
|
||||
if(IsBridgeLayer(layer)){
|
||||
bridgeLayerIndex=counter;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
player->upperLevel=false; //Assume player starts on lower level.
|
||||
player->SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
|
||||
@ -987,12 +1133,12 @@ vi2d Crawler::GetWorldSize(){
|
||||
return WORLD_SIZE;
|
||||
}
|
||||
|
||||
bool Crawler::IsUpperForegroundTile(TilesheetData sheet,int tileID){
|
||||
return sheet.tileset.upperForegroundTiles.find(tileID)!=sheet.tileset.upperForegroundTiles.end();
|
||||
bool Crawler::IsUpperForegroundTile(int tileID){
|
||||
return tileID>=1000000;
|
||||
}
|
||||
|
||||
bool Crawler::IsForegroundTile(TilesheetData sheet,int tileID){
|
||||
return sheet.tileset.foregroundTiles.find(tileID)!=sheet.tileset.foregroundTiles.end();
|
||||
return sheet.tileset->foregroundTiles.find(tileID)!=sheet.tileset->foregroundTiles.end();
|
||||
}
|
||||
|
||||
TilesheetData Crawler::GetTileSheet(MapName map,int tileID){
|
||||
@ -1000,18 +1146,18 @@ TilesheetData Crawler::GetTileSheet(MapName map,int tileID){
|
||||
if(tileData.size()==1){
|
||||
size_t slashMarkerSourceDir = tileData[0].data["source"].find_last_of('/');
|
||||
std::string baseSourceDir=tileData[0].data["source"].substr(slashMarkerSourceDir+1);
|
||||
return {MAP_TILESETS["assets/maps/"+baseSourceDir],1};
|
||||
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],1};
|
||||
} else {
|
||||
for (int i=1;i<tileData.size();i++){
|
||||
if(tileID<stoi(tileData[i].data["firstgid"])){
|
||||
if(tileID%1000000<stoi(tileData[i].data["firstgid"])-1){
|
||||
size_t slashMarkerSourceDir = tileData[i-1].data["source"].find_last_of('/');
|
||||
std::string baseSourceDir=tileData[i-1].data["source"].substr(slashMarkerSourceDir+1);
|
||||
return {MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[i-1].data["firstgid"])};
|
||||
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[i-1].data["firstgid"])};
|
||||
}
|
||||
}
|
||||
size_t slashMarkerSourceDir = tileData[tileData.size()-1].data["source"].find_last_of('/');
|
||||
std::string baseSourceDir=tileData[tileData.size()-1].data["source"].substr(slashMarkerSourceDir+1);
|
||||
return {MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[tileData.size()-1].data["firstgid"])};
|
||||
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[tileData.size()-1].data["firstgid"])};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1032,7 +1178,7 @@ geom2d::rect<int>Crawler::GetTileCollision(MapName map,vf2d pos,bool upperLevel)
|
||||
if(!upperLevel){ //We are looking for lower bridge collisions.
|
||||
for(geom2d::rect<int>&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){
|
||||
if(geom2d::contains(zone,pos)){
|
||||
return {{0,0},{32,32}};
|
||||
return {{0,0},{24,24}};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1041,24 +1187,34 @@ geom2d::rect<int>Crawler::GetTileCollision(MapName map,vf2d pos,bool upperLevel)
|
||||
if(upperLevel&&bridgeLayerIndex!=-1){
|
||||
int tileID=MAP_DATA[map].LayerData[bridgeLayerIndex].tiles[int(pos.y)/24][int(pos.x)/24]-1;
|
||||
if(tileID!=-1){
|
||||
if (GetTileSheet(map,tileID).tileset.collision.find(tileID-GetTileSheet(map,tileID).firstgid+1)!=GetTileSheet(map,tileID).tileset.collision.end()){
|
||||
return GetTileSheet(map,tileID).tileset.collision[tileID-GetTileSheet(map,tileID).firstgid+1].collision;
|
||||
if (GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
||||
return GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
||||
}
|
||||
return NO_COLLISION;
|
||||
}
|
||||
}
|
||||
int counter=0;
|
||||
geom2d::rect<int>foundRect=NO_COLLISION;
|
||||
for(LayerTag&layer:MAP_DATA[map].LayerData){
|
||||
auto HasNoClass=[&](){return layer.tag.data.find("class")==layer.tag.data.end();};
|
||||
if(HasNoClass()&&counter!=bridgeLayerIndex){
|
||||
//auto HasNoClass=[&](){return layer.tag.data.find("class")==layer.tag.data.end();};
|
||||
if(counter!=bridgeLayerIndex){
|
||||
int tileID=layer.tiles[int(pos.y)/24][int(pos.x)/24]-1;
|
||||
if(tileID!=-1&&GetTileSheet(map,tileID).tileset.collision.find(tileID-GetTileSheet(map,tileID).firstgid+1)!=GetTileSheet(map,tileID).tileset.collision.end()){
|
||||
return GetTileSheet(map,tileID).tileset.collision[tileID-GetTileSheet(map,tileID).firstgid+1].collision;
|
||||
if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
||||
geom2d::rect<int>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
||||
if(foundRect.pos==NO_COLLISION.pos&&foundRect.size==NO_COLLISION.size){
|
||||
foundRect=collisionRect;
|
||||
}else{
|
||||
//When we find another rectangle in the same square, we expand it to consume the area, whichever tile creates a larger surface or the combination of the two.
|
||||
foundRect.pos.x=std::min(foundRect.pos.x,collisionRect.pos.x);
|
||||
foundRect.pos.y=std::min(foundRect.pos.y,collisionRect.pos.y);
|
||||
foundRect.size.x=std::max(foundRect.size.x,collisionRect.size.x);
|
||||
foundRect.size.y=std::max(foundRect.size.y,collisionRect.size.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return NO_COLLISION;
|
||||
return foundRect;
|
||||
}
|
||||
|
||||
MapName Crawler::GetCurrentLevel(){
|
||||
@ -1143,9 +1299,8 @@ datafiledoubledata Crawler::GetDoubleList(std::string key){
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"I change this"<<std::endl;
|
||||
Crawler demo;
|
||||
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4))
|
||||
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4, false))
|
||||
demo.Start();
|
||||
|
||||
return 0;
|
||||
@ -1215,6 +1370,15 @@ void Crawler::OutputDebugInfo(const char*key,std::size_t len){
|
||||
}
|
||||
}
|
||||
|
||||
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); \
|
||||
@ -1226,4 +1390,8 @@ void Crawler::InitializeLevels(){
|
||||
INITLEVEL(CAMPAIGN_1_2);
|
||||
|
||||
LEVEL_NAMES.SetInitialized();
|
||||
}
|
||||
|
||||
void Crawler::SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel){
|
||||
monstersToBeSpawned.push_back(Monster(pos,*data,upperLevel));
|
||||
}
|
@ -12,32 +12,19 @@
|
||||
#include "TMXParser.h"
|
||||
#include "olcUTIL_DataFile.h"
|
||||
|
||||
struct TilesheetData{
|
||||
TilesetData&tileset;
|
||||
int firstgid;
|
||||
};
|
||||
|
||||
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;
|
||||
static Key KEY_ABILITY3;
|
||||
static Key KEY_ABILITY4;
|
||||
static float SIZE_CHANGE_SPEED;
|
||||
float levelTime;
|
||||
private:
|
||||
std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted;
|
||||
std::map<MapName,Map>MAP_DATA;
|
||||
@ -53,10 +40,19 @@ private:
|
||||
int bridgeLayerIndex=-1;
|
||||
float bridgeFadeFactor=0.f;
|
||||
void InitializeClasses();
|
||||
int DEBUG_PATHFINDING=0;
|
||||
std::vector<Monster*>monstersBeforeLower,monstersAfterLower,monstersBeforeUpper,monstersAfterUpper;
|
||||
std::vector<Bullet*>bulletsLower,bulletsUpper;
|
||||
std::vector<Effect*>backgroundEffectsLower,backgroundEffectsUpper,foregroundEffectsLower,foregroundEffectsUpper;
|
||||
float reflectionUpdateTimer=0;
|
||||
float reflectionStepTime=0;
|
||||
std::set<vi2d>visibleTiles;
|
||||
std::vector<Monster>monstersToBeSpawned;
|
||||
public:
|
||||
Crawler();
|
||||
bool OnUserCreate() override;
|
||||
bool OnUserUpdate(float fElapsedTime) override;
|
||||
bool OnUserDestroy() override;
|
||||
public:
|
||||
geom2d::rect<int>NO_COLLISION={};
|
||||
vi2d WORLD_SIZE={120,8};
|
||||
@ -88,7 +84,7 @@ public:
|
||||
//tileID is the tile number from the tilesets.
|
||||
bool IsForegroundTile(TilesheetData sheet,int tileID);
|
||||
//tileID is the tile number from the tilesets.
|
||||
bool IsUpperForegroundTile(TilesheetData sheet,int tileID);
|
||||
bool IsUpperForegroundTile(int tileID);
|
||||
//tileID is the tile number from the tilesets.
|
||||
TilesheetData GetTileSheet(MapName map,int tileID);
|
||||
//Gets the rectangle of the tile collision at this tile. If upperLevel is set to true, the collision tile must be in a Bridge class layer for the tile to hit. Also, zones containing LowerBridgeCollision will apply when upperLevel is set to false.
|
||||
@ -98,7 +94,7 @@ public:
|
||||
MapName GetCurrentLevel();
|
||||
bool IsBridgeLayer(LayerTag&layer);
|
||||
std::map<std::string,std::vector<geom2d::rect<int>>>&GetZoneData(MapName map);
|
||||
void PopulateRenderLists(std::vector<Monster*>&monstersBeforeLower,std::vector<Monster*>&monstersBeforeUpper,std::vector<Monster*>&monstersAfterLower,std::vector<Monster*>&monstersAfterUpper,std::vector<Bullet*>&bulletsLower,std::vector<Bullet*>&bulletsUpper,std::vector<Effect*>&backgroundEffectsLower,std::vector<Effect*>&backgroundEffectsUpper,std::vector<Effect*>&foregroundEffectsLower,std::vector<Effect*>&foregroundEffectsUpper);
|
||||
void PopulateRenderLists();
|
||||
void ChangePlayerClass(Class cl);
|
||||
std::string GetString(std::string key);
|
||||
datafilestringdata GetStringList(std::string key);
|
||||
@ -110,6 +106,10 @@ public:
|
||||
datafiledoubledata GetDoubleList(std::string key);
|
||||
static void OutputDebugInfo(const char*key,std::size_t len);
|
||||
void InitializeLevels();
|
||||
void RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos);
|
||||
void RenderTile(TileRenderData&tileSheet,Pixel col);
|
||||
bool IsReflectiveTile(TilesheetData tileSheet,int tileID);
|
||||
void SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel=false); //Queues a monster for spawning on the next frame.
|
||||
|
||||
struct TileGroupData{
|
||||
vi2d tilePos;
|
||||
|
@ -21,6 +21,18 @@
|
||||
"layer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ffa44949",
|
||||
"drawFill": true,
|
||||
"id": 18,
|
||||
"members": [
|
||||
],
|
||||
"name": "CollisionOnly",
|
||||
"type": "class",
|
||||
"useAs": [
|
||||
"layer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ffbdc34c",
|
||||
"drawFill": true,
|
||||
@ -141,6 +153,19 @@
|
||||
"object"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ff0574a4",
|
||||
"drawFill": true,
|
||||
"id": 16,
|
||||
"members": [
|
||||
],
|
||||
"name": "Reflective",
|
||||
"type": "class",
|
||||
"useAs": [
|
||||
"property",
|
||||
"tile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ffe67300",
|
||||
"drawFill": true,
|
||||
@ -170,13 +195,7 @@
|
||||
"type": "class",
|
||||
"useAs": [
|
||||
"property",
|
||||
"map",
|
||||
"layer",
|
||||
"object",
|
||||
"tile",
|
||||
"tileset",
|
||||
"wangcolor",
|
||||
"wangset"
|
||||
"tile"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -208,32 +227,6 @@
|
||||
"object"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ff35e500",
|
||||
"drawFill": true,
|
||||
"id": 13,
|
||||
"members": [
|
||||
],
|
||||
"name": "UpperForegroundTile",
|
||||
"type": "class",
|
||||
"useAs": [
|
||||
"property",
|
||||
"tile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ffff74fd",
|
||||
"drawFill": true,
|
||||
"id": 16,
|
||||
"members": [
|
||||
],
|
||||
"name": "UpperSpawnGroup",
|
||||
"type": "class",
|
||||
"useAs": [
|
||||
"property",
|
||||
"object"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "#ffa40aa4",
|
||||
"drawFill": true,
|
||||
|
@ -302,6 +302,7 @@
|
||||
<ClCompile Include="Effect.cpp" />
|
||||
<ClCompile Include="Emitter.cpp" />
|
||||
<ClCompile Include="EnergyBolt.cpp" />
|
||||
<ClCompile Include="FallingDebris.h" />
|
||||
<ClCompile Include="FireBolt.cpp" />
|
||||
<ClCompile Include="LightningBolt.cpp" />
|
||||
<ClCompile Include="LightningBoltEmitter.cpp" />
|
||||
@ -327,6 +328,7 @@
|
||||
<ClCompile Include="Wizard.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram2.cd" />
|
||||
<None Include="cpp.hint" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -239,9 +239,13 @@
|
||||
<ClCompile Include="SlimeKing.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FallingDebris.h">
|
||||
<Filter>Source Files\Effects</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
<None Include="ClassDiagram2.cd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="InitialConcept.txt">
|
||||
|
@ -5,12 +5,14 @@
|
||||
#define INCLUDE_DAMAGENUMBER_LIST extern std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
|
||||
#define INCLUDE_game extern Crawler*game;
|
||||
#define INCLUDE_MONSTER_DATA extern std::map<int,MonsterData>MONSTER_DATA;
|
||||
#define INCLUDE_MONSTER_NAME_DATA extern safemap<std::string,MonsterData*>MONSTER_NAME_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;
|
||||
}
|
||||
|
19
Crawler/FallingDebris.h
Normal file
@ -0,0 +1,19 @@
|
||||
#include "Effect.h"
|
||||
#include "DEFINES.h"
|
||||
#include "safemap.h"
|
||||
|
||||
INCLUDE_GFX
|
||||
|
||||
class FallingDebris:public Effect{
|
||||
const float GRAVITY=20;
|
||||
public:
|
||||
inline FallingDebris(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)
|
||||
:Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){
|
||||
|
||||
}
|
||||
|
||||
inline bool Update(float fElapsedTime)override{
|
||||
spd.y+=GRAVITY*fElapsedTime;
|
||||
return Effect::Update(fElapsedTime);
|
||||
}
|
||||
};
|
@ -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++;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ geom2d::rect<int>TileGroup::GetRange(){
|
||||
}
|
||||
|
||||
geom2d::rect<int>TileGroup::GetFadeRange(){
|
||||
return {range.pos+vi2d{-24,-24},range.size+vi2d{48,48}};
|
||||
return {range.pos+vi2d{-24,-24},range.size+vi2d{48,24}};
|
||||
}
|
||||
|
||||
std::vector<TileRenderData>&TileGroup::GetTiles(){
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include <set>
|
||||
|
||||
struct XMLTag;
|
||||
|
||||
@ -20,12 +21,21 @@ struct TilesetData{
|
||||
std::map<int,XMLTag>upperForegroundTiles;
|
||||
std::map<int,TileCollisionData>collision;
|
||||
std::map<int,XMLTag>staircaseTiles;
|
||||
std::map<int,std::vector<int>>animationData;
|
||||
std::set<int>reflectiveData;
|
||||
};
|
||||
|
||||
struct TilesheetData{
|
||||
TilesetData*tileset;
|
||||
int firstgid;
|
||||
};
|
||||
|
||||
struct TileRenderData{
|
||||
Decal*tileset;
|
||||
TilesheetData tileSheet;
|
||||
vi2d pos;
|
||||
vi2d tileSheetPos;
|
||||
int tileID;
|
||||
int layerID;
|
||||
};
|
||||
|
||||
struct TileGroup{
|
||||
@ -44,5 +54,4 @@ public:
|
||||
void InsertTile(TileRenderData tile);
|
||||
bool playerBehind=false;
|
||||
float fadeFactor=0.f;
|
||||
int originatingLayer=-1;
|
||||
};
|
@ -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){
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "BulletTypes.h"
|
||||
#include "DEFINES.h"
|
||||
#include "safemap.h"
|
||||
#include "MonsterStrategyHelpers.h"
|
||||
#include "utils.h"
|
||||
|
||||
INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_MONSTER_DATA
|
||||
@ -14,6 +16,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 +142,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));
|
||||
@ -183,16 +186,16 @@ Key Monster::GetFacingDirection(){
|
||||
return facingDirection;
|
||||
}
|
||||
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);
|
||||
}
|
||||
if(GetFacingDirection()==RIGHT){
|
||||
game->view.DrawPartialDecal((GetPos()+vf2d{float(GetFrame().GetSourceRect().size.x),0}*GetSizeMult())-vf2d{12,12}*GetSizeMult()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*-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);
|
||||
} else {
|
||||
game->view.DrawPartialDecal(GetPos()-vf2d{12,12}*GetSizeMult()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult(),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.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);
|
||||
}
|
||||
void Monster::DrawReflection(float drawRatioX,float multiplierX){
|
||||
game->SetDecalMode(DecalMode::ADDITIVE);
|
||||
game->view.DrawPartialRotatedDecal(GetPos()+vf2d{drawRatioX*GetFrame().GetSourceRect().size.x,GetZ()+(GetFrame().GetSourceRect().size.y-16)*GetSizeMult()},GetFrame().GetSourceImage()->Decal(),0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1)*multiplierX,GetSizeMult()*-1),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->SetDecalMode(DecalMode::NORMAL);
|
||||
}
|
||||
void Monster::Collision(Player*p){
|
||||
if(MONSTER_DATA[id].GetCollisionDmg()>0&&!hasHitPlayer){
|
||||
@ -206,7 +209,7 @@ void Monster::Collision(Monster&m){
|
||||
Collision();
|
||||
}
|
||||
void Monster::Collision(){
|
||||
if(strategy==0&&GetState()==State::MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision.
|
||||
if(strategy==0&&GetState()==State::MOVE_TOWARDS&&util::random(Monster::STRATEGY::_GetInt(*this,"BumpStopChance",strategy))<1){//The run towards strategy causes state to return to normal upon a collision.
|
||||
SetState(State::NORMAL);
|
||||
}
|
||||
}
|
||||
@ -285,7 +288,7 @@ void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
|
||||
triggered=trigger;
|
||||
if(spawnMonsters){
|
||||
for(std::pair<int,vf2d>&monsterInfo:monsters){
|
||||
MONSTER_LIST.push_back(Monster(pos+monsterInfo.second,MONSTER_DATA[monsterInfo.first],DoesUpperLevelSpawning()));
|
||||
game->SpawnMonster(pos+monsterInfo.second,&MONSTER_DATA[monsterInfo.first],DoesUpperLevelSpawning());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,6 @@ private:
|
||||
bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die.
|
||||
float targetSize=0;
|
||||
std::map<Attribute,std::variant<VARIANTS>>attributes;
|
||||
std::function<void(Crawler*)>strategyDraw=[](Crawler*pge){};
|
||||
protected:
|
||||
public:
|
||||
Monster()=delete;
|
||||
@ -112,6 +111,7 @@ public:
|
||||
vf2d&GetTargetPos();
|
||||
Key GetFacingDirection();
|
||||
void Draw();
|
||||
void DrawReflection(float drawRatioX,float multiplierX);
|
||||
void Collision(Player*p);
|
||||
void Collision(Monster&p);
|
||||
void Collision();
|
||||
@ -145,6 +145,7 @@ public:
|
||||
bool&GetBool(Attribute a);
|
||||
vf2d&GetVf2d(Attribute a);
|
||||
void SetStrategyDrawFunction(std::function<void(Crawler*)>func);
|
||||
std::function<void(Crawler*)>strategyDraw=[](Crawler*pge){};
|
||||
private:
|
||||
struct STRATEGY{
|
||||
static int _GetInt(Monster&m,std::string param,int strategyNumber,int index=0);
|
||||
|
@ -20,4 +20,6 @@ enum class Attribute{
|
||||
JUMP_TARGET_POS,
|
||||
JUMP_ORIGINAL_POS,
|
||||
RECOVERY_TIME,
|
||||
SHOOT_ANIMATION_TIME,
|
||||
SHOOT_TIMER,
|
||||
};
|
@ -10,6 +10,7 @@ INCLUDE_STRATEGY_DATA
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
std::map<int,MonsterData>MONSTER_DATA;
|
||||
safemap<std::string,MonsterData*>MONSTER_NAME_DATA;
|
||||
|
||||
MonsterData::MonsterData()
|
||||
:atk(0),collisionDmg(0),hp(0),id(0),moveSpd(0),size(0),strategy(0){}
|
||||
@ -98,6 +99,7 @@ void MonsterData::InitializeMonsterData(){
|
||||
);
|
||||
|
||||
MONSTER_DATA[id]=monster;
|
||||
MONSTER_NAME_DATA[MonsterName]=&MONSTER_DATA[id];
|
||||
|
||||
id++;
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ std::vector<vf2d> Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRa
|
||||
nodeStart->fGlobalGoal = heuristic(nodeStart, nodeEnd);
|
||||
|
||||
std::list<sNode*> listNotTestedNodes;
|
||||
//if((!upperLevel && nodeStart->bObstacle)||(upperLevel && nodeStart->bObstacleUpper))return {};
|
||||
listNotTestedNodes.push_back(nodeStart);
|
||||
|
||||
while (!listNotTestedNodes.empty() && nodeCurrent != nodeEnd)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "BulletTypes.h"
|
||||
#include "DEFINES.h"
|
||||
#include "safemap.h"
|
||||
#include "utils.h"
|
||||
|
||||
INCLUDE_MONSTER_DATA
|
||||
INCLUDE_MONSTER_LIST
|
||||
@ -230,7 +231,7 @@ void Player::Update(float fElapsedTime){
|
||||
spin_angle-=spin_spd*fElapsedTime;
|
||||
}
|
||||
if(spin_attack_timer>0){
|
||||
z="Warrior.Ability 2.SpinMaxHeight"_I*sin(3.3*(GROUND_SLAM_SPIN_TIME-spin_attack_timer)/GROUND_SLAM_SPIN_TIME);
|
||||
z=float("Warrior.Ability 2.SpinMaxHeight"_I)*sin(3.3*(GROUND_SLAM_SPIN_TIME-spin_attack_timer)/GROUND_SLAM_SPIN_TIME);
|
||||
spin_attack_timer=std::max(0.f,spin_attack_timer-fElapsedTime);
|
||||
} else {
|
||||
SetState(State::NORMAL);
|
||||
@ -238,7 +239,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);
|
||||
@ -310,7 +311,11 @@ void Player::Update(float fElapsedTime){
|
||||
}
|
||||
geom2d::line line(pos,m.GetPos());
|
||||
float dist = line.length();
|
||||
m.SetPos(line.rpoint(dist*1.1));
|
||||
if(dist<=0.001){
|
||||
m.SetPos(m.GetPos()+vf2d{util::random(2)-1,util::random(2)-1});
|
||||
}else{
|
||||
m.SetPos(line.rpoint(dist*1.1));
|
||||
}
|
||||
if(m.IsAlive()){
|
||||
vel=line.vector().norm()*-128;
|
||||
}
|
||||
@ -341,9 +346,13 @@ void Player::Update(float fElapsedTime){
|
||||
//If pressed is set to false, uses held instead.
|
||||
auto CheckAndPerformAbility=[&](Ability&ability,HWButton key){
|
||||
if(ability.name!="???"){
|
||||
if(CanAct()){
|
||||
if(CanAct(ability)){
|
||||
if(ability.cooldown==0&&GetMana()>=ability.manaCost){
|
||||
if(key.bHeld||key.bReleased&&&ability==castPrepAbility&&GetState()==State::PREP_CAST){
|
||||
if(GetState()==State::CASTING){
|
||||
SetState(State::NORMAL);
|
||||
castInfo.castTimer=castInfo.castTotalTime=0;
|
||||
}
|
||||
if(AllowedToCast(ability)&&ability.action(this,{})){
|
||||
ability.cooldown=ability.COOLDOWN_TIME;
|
||||
mana-=ability.manaCost;
|
||||
@ -483,7 +492,12 @@ bool Player::CanMove(){
|
||||
}
|
||||
|
||||
bool Player::CanAct(){
|
||||
return state!=State::CASTING&&state!=State::ANIMATION_LOCK;
|
||||
Ability dummyAbility{"Dummy Ability",0,0};
|
||||
return CanAct(dummyAbility);
|
||||
}
|
||||
|
||||
bool Player::CanAct(Ability&ability){
|
||||
return (ability.canCancelCast||state!=State::CASTING)&&state!=State::ANIMATION_LOCK;
|
||||
}
|
||||
|
||||
bool Player::HasIframes(){
|
||||
@ -669,4 +683,8 @@ void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){
|
||||
UpdateAnimation("RANGER_SHOOT_N");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SetIframes(float duration){
|
||||
iframe_time=duration;
|
||||
}
|
@ -53,6 +53,7 @@ private:
|
||||
float lastHitTimer=0; //When this is greater than zero, if we get hit again it adds to our displayed combo number.
|
||||
std::shared_ptr<DamageNumber>damageNumberPtr;
|
||||
void Initialize();
|
||||
float iframe_time=0;
|
||||
protected:
|
||||
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
|
||||
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
|
||||
@ -69,10 +70,8 @@ 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;
|
||||
float teleportAnimationTimer=0;
|
||||
vf2d teleportTarget={};
|
||||
vf2d teleportStartPosition={};
|
||||
@ -130,6 +129,9 @@ public:
|
||||
bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8);
|
||||
bool CanMove();
|
||||
bool CanAct();
|
||||
bool CanAct(Ability&ability);
|
||||
void Knockback(vf2d vel);
|
||||
void SetIframes(float duration);
|
||||
|
||||
void AddBuff(BuffType type,float duration,float intensity);
|
||||
std::vector<Buff>GetBuffs(BuffType buff);
|
||||
@ -352,7 +354,8 @@ struct Witch:Player{
|
||||
#class".Right Click Ability.Mana Cost"_I, \
|
||||
{uint8_t(#class".Right Click Ability.Cooldown Bar Color 1"_f[0]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 1"_f[1]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 1"_f[2]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 1"_f[3]==0?255:#class".Right Click Ability.Cooldown Bar Color 1"_f[3])}, \
|
||||
{uint8_t(#class".Right Click Ability.Cooldown Bar Color 2"_f[0]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 2"_f[1]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 2"_f[2]),uint8_t(#class".Right Click Ability.Cooldown Bar Color 2"_f[3]==0?255:#class".Right Click Ability.Cooldown Bar Color 2"_f[3])}, \
|
||||
{#class".Right Click Ability.Precast Time"_F,#class".Right Click Ability.Casting Range"_I/100.f*24,#class".Right Click Ability.Casting Size"_I/100.f*24} \
|
||||
{#class".Right Click Ability.Precast Time"_F,#class".Right Click Ability.Casting Range"_I/100.f*24,#class".Right Click Ability.Casting Size"_I/100.f*24}, \
|
||||
bool( #class".Right Click Ability.CancelCast"_I ) \
|
||||
}; \
|
||||
class::ability1={ \
|
||||
#class".Ability 1.Name"_S, \
|
||||
@ -360,7 +363,8 @@ struct Witch:Player{
|
||||
#class".Ability 1.Mana Cost"_I, \
|
||||
{uint8_t(#class".Ability 1.Cooldown Bar Color 1"_f[0]),uint8_t(#class".Ability 1.Cooldown Bar Color 1"_f[1]),uint8_t(#class".Ability 1.Cooldown Bar Color 1"_f[2]),uint8_t(#class".Ability 1.Cooldown Bar Color 1"_f[3]==0?255:#class".Ability 1.Cooldown Bar Color 1"_f[3])}, \
|
||||
{uint8_t(#class".Ability 1.Cooldown Bar Color 2"_f[0]),uint8_t(#class".Ability 1.Cooldown Bar Color 2"_f[1]),uint8_t(#class".Ability 1.Cooldown Bar Color 2"_f[2]),uint8_t(#class".Ability 1.Cooldown Bar Color 2"_f[3]==0?255:#class".Ability 1.Cooldown Bar Color 2"_f[3])}, \
|
||||
{#class".Ability 1.Precast Time"_F,#class".Ability 1.Casting Range"_I/100.f*24,#class".Ability 1.Casting Size"_I/100.f*24} \
|
||||
{#class".Ability 1.Precast Time"_F,#class".Ability 1.Casting Range"_I/100.f*24,#class".Ability 1.Casting Size"_I/100.f*24}, \
|
||||
bool(#class".Ability 1.CancelCast"_I) \
|
||||
}; \
|
||||
class::ability2={ \
|
||||
#class".Ability 2.Name"_S, \
|
||||
@ -368,7 +372,8 @@ struct Witch:Player{
|
||||
#class".Ability 2.Mana Cost"_I, \
|
||||
{uint8_t(#class".Ability 2.Cooldown Bar Color 1"_f[0]),uint8_t(#class".Ability 2.Cooldown Bar Color 1"_f[1]),uint8_t(#class".Ability 2.Cooldown Bar Color 1"_f[2]),uint8_t(#class".Ability 2.Cooldown Bar Color 1"_f[3]==0?255:#class".Ability 2.Cooldown Bar Color 1"_f[3])}, \
|
||||
{uint8_t(#class".Ability 2.Cooldown Bar Color 2"_f[0]),uint8_t(#class".Ability 2.Cooldown Bar Color 2"_f[1]),uint8_t(#class".Ability 2.Cooldown Bar Color 2"_f[2]),uint8_t(#class".Ability 2.Cooldown Bar Color 2"_f[3]==0?255:#class".Ability 2.Cooldown Bar Color 2"_f[3])}, \
|
||||
{#class".Ability 2.Precast Time"_F,#class".Ability 2.Casting Range"_I/100.f*24,#class".Ability 2.Casting Size"_I/100.f*24} \
|
||||
{#class".Ability 2.Precast Time"_F,#class".Ability 2.Casting Range"_I/100.f*24,#class".Ability 2.Casting Size"_I/100.f*24}, \
|
||||
bool(#class".Ability 2.CancelCast"_I) \
|
||||
}; \
|
||||
class::ability3={ \
|
||||
#class".Ability 3.Name"_S, \
|
||||
@ -376,6 +381,7 @@ struct Witch:Player{
|
||||
#class".Ability 3.Mana Cost"_I, \
|
||||
{uint8_t(#class".Ability 3.Cooldown Bar Color 1"_f[0]),uint8_t(#class".Ability 3.Cooldown Bar Color 1"_f[1]),uint8_t(#class".Ability 3.Cooldown Bar Color 1"_f[2]),uint8_t(#class".Ability 3.Cooldown Bar Color 1"_f[3]==0?255:#class".Ability 3.Cooldown Bar Color 1"_f[3])}, \
|
||||
{uint8_t(#class".Ability 3.Cooldown Bar Color 2"_f[0]),uint8_t(#class".Ability 3.Cooldown Bar Color 2"_f[1]),uint8_t(#class".Ability 3.Cooldown Bar Color 2"_f[2]),uint8_t(#class".Ability 3.Cooldown Bar Color 2"_f[3]==0?255:#class".Ability 3.Cooldown Bar Color 2"_f[3])}, \
|
||||
{#class".Ability 3.Precast Time"_F,#class".Ability 3.Casting Range"_I/100.f*24,#class".Ability 3.Casting Size"_I/100.f*24} \
|
||||
{#class".Ability 3.Precast Time"_F,#class".Ability 3.Casting Range"_I/100.f*24,#class".Ability 3.Casting Size"_I/100.f*24}, \
|
||||
bool(#class".Ability 3.CancelCast"_I) \
|
||||
}; \
|
||||
class::ability4={"???",0,0};
|
@ -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,29 +4,77 @@
|
||||
#include "Crawler.h"
|
||||
#include "utils.h"
|
||||
#include "safemap.h"
|
||||
#include "Effect.h"
|
||||
#include "FallingDebris.h"
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_BULLET_LIST
|
||||
INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_MONSTER_NAME_DATA
|
||||
|
||||
typedef Attribute A;
|
||||
|
||||
void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumber){
|
||||
|
||||
|
||||
float bulletSpd=ConfigFloat("BulletSpd")/100*24;
|
||||
|
||||
m.F(A::SHOOT_TIMER)=std::max(0.f,m.F(A::SHOOT_TIMER)-fElapsedTime);
|
||||
m.F(A::SHOOT_RING_TIMER)=std::max(0.f,m.F(A::SHOOT_RING_TIMER)-fElapsedTime);
|
||||
m.F(A::SHOOT_RING_DELAY)=std::max(0.f,m.F(A::SHOOT_RING_DELAY)-fElapsedTime);
|
||||
m.F(A::JUMP_LANDING_TIMER)=std::max(0.f,m.F(A::JUMP_LANDING_TIMER)-fElapsedTime);
|
||||
|
||||
auto ShootBulletRing=[&](float angleOffset){
|
||||
const auto ShootBulletRing=[&](float angleOffset){
|
||||
int bulletCount=ConfigInt("Phase1.RingBulletCount");
|
||||
for(int i=0;i<bulletCount;i++){
|
||||
float angle=((2*PI)/bulletCount)*i+angleOffset;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
}
|
||||
};
|
||||
auto StartJump=[&](float jumpDuration,vf2d targetPos,float recoveryTime){
|
||||
|
||||
const auto Landed=[&ShootBulletRing,&m](int currentPhase){
|
||||
if(currentPhase==1){
|
||||
ShootBulletRing(m.F(A::SHOOT_RING_OFFSET));
|
||||
}
|
||||
};
|
||||
|
||||
const auto TransitionPhase=[&](int newPhase){
|
||||
const int MAX_ATTEMPTS=100; //Maximum number of tries to find a valid location.
|
||||
Player*player=game->GetPlayer();
|
||||
const auto PositionInRangeOfPlayer=[&player](vf2d&pos,float radius){
|
||||
return geom2d::line<float>(player->GetPos(),pos).length()<=player->GetSizeMult()*12*2+radius;
|
||||
};
|
||||
const auto SpawnMonsterFromConfig=[&](int phase){
|
||||
std::string spawnMonster=ConfigStringArr("Phase"+std::to_string(phase)+".MonsterSpawnOnChange",0);
|
||||
int spawnCount=ConfigIntArr("Phase"+std::to_string(phase)+".MonsterSpawnOnChange",1);
|
||||
|
||||
for(int i=0;i<spawnCount;i++){
|
||||
float randomAngle=util::random(2*PI);
|
||||
vf2d spawnPos=m.pos+vf2d{cos(randomAngle),sin(randomAngle)}*m.GetSizeMult()*12;
|
||||
for(int attempts=0;attempts<MAX_ATTEMPTS&&PositionInRangeOfPlayer(spawnPos,MONSTER_NAME_DATA[spawnMonster]->GetSizeMult()*12);attempts++){
|
||||
randomAngle=util::random(2*PI);
|
||||
spawnPos=m.pos+vf2d{cos(randomAngle),sin(randomAngle)}*m.GetSizeMult()*12;
|
||||
}
|
||||
game->SpawnMonster(spawnPos,MONSTER_NAME_DATA[spawnMonster]);
|
||||
}
|
||||
};
|
||||
switch(newPhase){
|
||||
case 2:{
|
||||
SpawnMonsterFromConfig(2);
|
||||
}break;
|
||||
case 3:{
|
||||
SpawnMonsterFromConfig(3);
|
||||
}break;
|
||||
case 4:{
|
||||
SpawnMonsterFromConfig(4);
|
||||
}break;
|
||||
case 5:{
|
||||
|
||||
}break;
|
||||
}
|
||||
};
|
||||
|
||||
const auto StartJump=[&](float jumpDuration,vf2d targetPos,float recoveryTime){
|
||||
m.V(A::JUMP_ORIGINAL_POS)=m.GetPos();
|
||||
m.F(A::JUMP_ORIGINAL_LANDING_TIMER)=m.F(A::JUMP_LANDING_TIMER)=jumpDuration;
|
||||
m.V(A::JUMP_TARGET_POS)=targetPos;
|
||||
@ -44,7 +92,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,29 +112,52 @@ 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(std::make_unique<FallingDebris>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||
}
|
||||
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"));
|
||||
game->GetPlayer()->SetIframes(1);
|
||||
}
|
||||
Landed(m.phase);
|
||||
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;
|
||||
}
|
||||
|
||||
if(m.state==State::CASTING){
|
||||
m.UpdateAnimation("monsters/Slime King - Cast.png");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(m.phase){
|
||||
case 0:{
|
||||
m.size=ConfigInt("Phase1.Size")/100;
|
||||
m.diesNormally=false;
|
||||
m.F(A::IFRAME_TIME_UPON_HIT)=0;
|
||||
m.iframe_timer=ConfigFloat("Phase5.IframeTimePerHit");
|
||||
m.phase=1;
|
||||
m.phase=ConfigInt("StartPhase");
|
||||
}break;
|
||||
case 1:{
|
||||
if(m.hp<=m.maxhp*ConfigFloat("Phase2.Change")/100){
|
||||
m.phase=2;
|
||||
m.SetSize(ConfigFloat("Phase2.Size")/100,false);
|
||||
TransitionPhase(m.phase);
|
||||
return;
|
||||
}
|
||||
if(m.F(A::SHOOT_RING_TIMER)==0){
|
||||
if(m.I(A::PATTERN_REPEAT_COUNT)>=ConfigInt("Phase1.JumpAfter")){
|
||||
@ -119,18 +189,38 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
|
||||
if(m.hp<=m.maxhp*ConfigFloat("Phase3.Change")/100){
|
||||
m.phase=3;
|
||||
m.SetSize(ConfigFloat("Phase3.Size")/100,false);
|
||||
TransitionPhase(m.phase);
|
||||
return;
|
||||
}
|
||||
if(m.F(A::SHOOT_TIMER)==0){
|
||||
m.F(A::SHOOT_TIMER)=ConfigInt("Phase2.ShootRate");
|
||||
m.I(A::PATTERN_REPEAT_COUNT)++;
|
||||
int bulletCount=ConfigInt("Phase2.ShootProjectileCount");
|
||||
for(int i=0;i<bulletCount;i++){
|
||||
float initialAngle=util::angleTo(m.GetPos(),game->GetPlayer()->GetPos());
|
||||
float angle=(i-(bulletCount/2))*util::degToRad(ConfigFloat("Phase2.ShootAngleSpread"))+initialAngle;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
}
|
||||
}
|
||||
if(m.I(A::PATTERN_REPEAT_COUNT)>ConfigInt("Phase2.ShootCount")){
|
||||
m.I(A::PATTERN_REPEAT_COUNT)=0;
|
||||
m.SetState(State::CASTING);
|
||||
}
|
||||
}break;
|
||||
case 3:{
|
||||
if(m.hp<=m.maxhp*ConfigFloat("Phase4.Change")/100){
|
||||
m.phase=4;
|
||||
m.SetSize(ConfigFloat("Phase4.Size")/100,false);
|
||||
TransitionPhase(m.phase);
|
||||
return;
|
||||
}
|
||||
}break;
|
||||
case 4:{
|
||||
if(m.hp<=0){
|
||||
m.phase=5;
|
||||
m.F(A::IFRAME_TIME_UPON_HIT)=1;
|
||||
TransitionPhase(m.phase);
|
||||
return;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include <strstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace olc;
|
||||
|
||||
@ -223,10 +223,6 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
||||
LayerTag l = {newTag};
|
||||
parsedMapInfo.LayerData.push_back(l);
|
||||
}else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="UpperSpawnGroup") {
|
||||
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag};
|
||||
parsedMapInfo.SpawnerData[newTag.GetInteger("id")].upperLevel=true;
|
||||
} else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="SpawnGroup") {
|
||||
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag};
|
||||
} else
|
||||
@ -318,6 +314,26 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
||||
for(XMLTag&monster:accumulatedMonsterTags){
|
||||
parsedMapInfo.SpawnerData[monster.GetInteger("spawnerLink")].monsters.push_back(monster);
|
||||
}
|
||||
|
||||
for(auto&spawnerData:parsedMapInfo.SpawnerData){
|
||||
SpawnerTag&spawner=spawnerData.second;
|
||||
for(auto&zoneData:parsedMapInfo.ZoneData){
|
||||
if(zoneData.first=="UpperZone"){
|
||||
std::vector<geom2d::rect<int>>&zones=zoneData.second;
|
||||
for(geom2d::rect<int>&zone:zones){
|
||||
if(geom2d::overlaps(zone,geom2d::rect<int>{{spawner.ObjectData.GetInteger("x"),spawner.ObjectData.GetInteger("y")},{spawner.ObjectData.GetInteger("width"),spawner.ObjectData.GetInteger("height")}})){
|
||||
spawner.upperLevel=true;
|
||||
goto continueSpawnerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continueSpawnerLoop:
|
||||
continue;
|
||||
}
|
||||
|
||||
std::sort(parsedMapInfo.TilesetData.begin(),parsedMapInfo.TilesetData.end(),[](XMLTag&t1,XMLTag&t2){return t1.GetInteger("firstgid")<t2.GetInteger("firstgid");});
|
||||
|
||||
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n";
|
||||
}
|
||||
#endif
|
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include <strstream>
|
||||
#include <sstream>
|
||||
#include "TMXParser.h"
|
||||
#include "Map.h"
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include "olcUTIL_DataFile.h"
|
||||
|
||||
using namespace olc;
|
||||
|
||||
@ -13,6 +14,8 @@ struct Tileset{
|
||||
std::map<int,XMLTag> UpperForegroundTileData;
|
||||
std::map<int,TileCollisionData> CollisionData;
|
||||
std::map<int,XMLTag> StaircaseData;
|
||||
std::map<int,std::vector<int>> AnimationData;
|
||||
std::set<int> ReflectiveData;
|
||||
friend std::ostream& operator << (std::ostream& os, Tileset& rhs);
|
||||
};
|
||||
|
||||
@ -89,19 +92,35 @@ class TSXParser{
|
||||
parsedTilesetInfo.ImageData=newTag;
|
||||
} else
|
||||
if (newTag.tag=="tile"&&newTag.data["type"]=="ForegroundTile"){
|
||||
previousTag=newTag.tag;
|
||||
previousTagID=newTag.GetInteger("id");
|
||||
parsedTilesetInfo.ForegroundTileData[newTag.GetInteger("id")]=newTag;
|
||||
} else
|
||||
if (newTag.tag=="tile"&&newTag.data["type"]=="UpperForegroundTile"){
|
||||
previousTag=newTag.tag;
|
||||
previousTagID=newTag.GetInteger("id");
|
||||
parsedTilesetInfo.UpperForegroundTileData[newTag.GetInteger("id")]=newTag;
|
||||
} else
|
||||
if (newTag.tag=="tile"&&newTag.data["type"]=="Staircase"){
|
||||
previousTag=newTag.tag;
|
||||
staircaseTag=newTag.tag;
|
||||
previousTagID=newTag.GetInteger("id");
|
||||
} else
|
||||
if (newTag.tag=="tile"&&newTag.data["type"]=="Reflective"){
|
||||
previousTag=newTag.tag;
|
||||
previousTagID=newTag.GetInteger("id");
|
||||
parsedTilesetInfo.ReflectiveData.insert(newTag.GetInteger("id"));
|
||||
} else
|
||||
if (newTag.tag=="tile"){
|
||||
previousTag=newTag.tag;
|
||||
previousTagID=newTag.GetInteger("id");
|
||||
} else
|
||||
if (newTag.tag=="frame"){
|
||||
//The way animation data is stored is every "animation_tile_precision" ms indicating which frame we should be on.
|
||||
for(int i=0;i<newTag.GetInteger("duration")/"animation_tile_precision"_I;i++){
|
||||
parsedTilesetInfo.AnimationData[previousTagID].push_back(newTag.GetInteger("tileid"));
|
||||
}
|
||||
} else
|
||||
if (newTag.tag=="property"&&staircaseTag=="tile"){
|
||||
parsedTilesetInfo.StaircaseData[previousTagID]=newTag;
|
||||
staircaseTag="";
|
||||
@ -109,6 +128,10 @@ class TSXParser{
|
||||
if (newTag.tag=="object"&&previousTag=="tile"){
|
||||
TileCollisionData data;
|
||||
data.collision=geom2d::rect<int>{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}};
|
||||
if(parsedTilesetInfo.CollisionData.count(previousTagID)){
|
||||
std::cout<<"WARNING! There was already collision data defined for tile "<<previousTagID<<"!"<<std::endl;
|
||||
throw;
|
||||
}
|
||||
parsedTilesetInfo.CollisionData[previousTagID]=data;
|
||||
}
|
||||
std::cout<<"\n"<<"=============\n";
|
||||
|
@ -4,11 +4,19 @@
|
||||
#include "Crawler.h"
|
||||
#include "utils.h"
|
||||
|
||||
typedef Attribute A;
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_BULLET_LIST
|
||||
|
||||
void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime,int strategyNumber){
|
||||
m.attackCooldownTimer=std::max(0.f,m.attackCooldownTimer-fElapsedTime);
|
||||
if(m.F(A::SHOOT_ANIMATION_TIME)>0){
|
||||
m.F(A::SHOOT_ANIMATION_TIME)=std::max(0.f,m.F(A::SHOOT_ANIMATION_TIME)-fElapsedTime);
|
||||
if(m.F(A::SHOOT_ANIMATION_TIME)==0){
|
||||
m.PerformIdleAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
if(m.queueShotTimer>0){
|
||||
m.queueShotTimer-=fElapsedTime;
|
||||
@ -23,6 +31,7 @@ void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime,int strategyNumber){
|
||||
if(m.attackCooldownTimer==0){
|
||||
m.attackCooldownTimer=ConfigFloat("ShootingSpeed");
|
||||
m.queueShotTimer=std::min(m.attackCooldownTimer-0.001,0.3);
|
||||
m.F(A::SHOOT_ANIMATION_TIME)=ConfigIntArr("ShootAnimation",0)*ConfigFloatArr("ShootAnimation",1);
|
||||
m.PerformShootAnimation();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 1147
|
||||
#define VERSION_BUILD 1372
|
||||
|
||||
#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;
|
||||
};
|
||||
|
@ -74,14 +74,13 @@ void Wizard::InitializeClassAbilities(){
|
||||
#pragma region Wizard Right-click Ability (Teleport)
|
||||
Wizard::rightClickAbility.action=
|
||||
[](Player*p,vf2d pos={}){
|
||||
if(p->GetState()==State::CASTING)return false;
|
||||
float pointMouseDirection=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
|
||||
vf2d pointTowardsMouse={cos(pointMouseDirection),sin(pointMouseDirection)};
|
||||
float dist=std::clamp(geom2d::line<float>{p->GetPos(),game->GetWorldMousePos()}.length(),0.f,"Wizard.Right Click Ability.TeleportRange"_F/100*24);
|
||||
if(dist<"Wizard.Right Click Ability.TilesMin"_I*12)return false;
|
||||
vf2d teleportPoint=p->GetPos()+pointTowardsMouse*dist;
|
||||
while(dist>0&&game->HasTileCollision(game->GetCurrentLevel(),teleportPoint)&&p->CanPathfindTo(p->GetPos(),teleportPoint,"Wizard.Right Click Ability.TilesMax"_I)){
|
||||
dist-=24;
|
||||
dist-=4;
|
||||
teleportPoint=p->GetPos()+pointTowardsMouse*dist;
|
||||
}
|
||||
if(dist>0&&p->CanPathfindTo(p->GetPos(),teleportPoint,"Wizard.Right Click Ability.TilesMax"_I)){
|
||||
@ -91,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 {
|
||||
@ -120,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
|
||||
|
BIN
Crawler/assets/Campaigns/1_1_v2.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
@ -43,6 +43,8 @@ MonsterStrategy
|
||||
WaitTime = 3
|
||||
# How far the monster will travel before reassessing for a new path.
|
||||
MaxDistance = 999999
|
||||
# 1 of X chance to stop after bumping into something.
|
||||
BumpStopChance = 5
|
||||
}
|
||||
1
|
||||
{
|
||||
@ -63,7 +65,7 @@ MonsterStrategy
|
||||
# How far away the monster starts shooting from
|
||||
Range = 800
|
||||
# How often the enemy shoots.
|
||||
ShootingSpeed = 0.6
|
||||
ShootingSpeed = 2
|
||||
BulletSpeed = 450
|
||||
BulletSize = 30
|
||||
BulletColor = 0, 255, 0, 255
|
||||
@ -72,13 +74,17 @@ MonsterStrategy
|
||||
{
|
||||
# The Slime King Boss script.
|
||||
Name = Slime King
|
||||
# Which phase to start on. Should be 1 most of the time.
|
||||
StartPhase = 1
|
||||
# How much time a jump will be pre-telegraphed.
|
||||
JumpWarningIndicatorTime = 1.0
|
||||
# Distance to jump up into the sky. A higher value causes it to launch up and down seemingly faster.
|
||||
JumpHeight = 2400
|
||||
ProjectileDamage = 10
|
||||
JumpAttackDamage = 20
|
||||
JumpMoveSpd = 95
|
||||
JumpMoveSpd = 75
|
||||
# How far the player gets knocked back if hit.
|
||||
JumpKnockbackFactor = 250
|
||||
|
||||
BulletSpd = 250
|
||||
|
||||
|
@ -12,6 +12,7 @@ Monsters
|
||||
Size = 80
|
||||
|
||||
Strategy = Run Towards
|
||||
BumpStopChance = 2
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
@ -138,6 +139,7 @@ Monsters
|
||||
Size = 800
|
||||
|
||||
Strategy = Slime King
|
||||
StartPhase = 2
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
@ -149,6 +151,6 @@ Monsters
|
||||
DeathAnimation = 10, 0.1, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
ANIMATION[0] = monsters/Slime King - Cast.png
|
||||
}
|
||||
}
|
@ -7,14 +7,19 @@ Ranger
|
||||
DamageMult = 1
|
||||
Radius = 100
|
||||
Cooldown = 0.6
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
ArrowSpd = 250
|
||||
|
||||
}
|
||||
Right Click Ability
|
||||
{
|
||||
Name = Retreat
|
||||
Cooldown = 7
|
||||
Mana Cost = 0
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -34,6 +39,8 @@ Ranger
|
||||
Name = Rapid Fire
|
||||
Cooldown = 12
|
||||
Mana Cost = 35
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -62,6 +69,8 @@ Ranger
|
||||
Name = Charged Shot
|
||||
Cooldown = 15
|
||||
Mana Cost = 40
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -88,6 +97,8 @@ Ranger
|
||||
Name = Multishot
|
||||
Cooldown = 25
|
||||
Mana Cost = 50
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -7,6 +7,8 @@ Thief
|
||||
Name = ???
|
||||
Cooldown = 8
|
||||
Mana Cost = 5
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -21,6 +23,8 @@ Thief
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 30
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -35,6 +39,8 @@ Thief
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 25
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -49,6 +55,8 @@ Thief
|
||||
Name = ???
|
||||
Cooldown = 40
|
||||
Mana Cost = 75
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -7,6 +7,8 @@ Trapper
|
||||
Name = ???
|
||||
Cooldown = 8
|
||||
Mana Cost = 5
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -21,6 +23,8 @@ Trapper
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 30
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -35,6 +39,8 @@ Trapper
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 25
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -49,6 +55,8 @@ Trapper
|
||||
Name = ???
|
||||
Cooldown = 40
|
||||
Mana Cost = 75
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -7,6 +7,8 @@ Warrior
|
||||
DamageMult = 1
|
||||
Range = 150
|
||||
Cooldown = 0.35
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
SwordSwingTime = 0.2
|
||||
}
|
||||
@ -15,6 +17,8 @@ Warrior
|
||||
Name = Block
|
||||
Cooldown = 15
|
||||
Mana Cost = 0
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -37,6 +41,8 @@ Warrior
|
||||
Name = Battlecry
|
||||
Cooldown = 12
|
||||
Mana Cost = 40
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -79,6 +85,8 @@ Warrior
|
||||
Name = Ground Slam
|
||||
Cooldown = 15
|
||||
Mana Cost = 50
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -107,6 +115,8 @@ Warrior
|
||||
Name = Sonic Slash
|
||||
Cooldown = 40
|
||||
Mana Cost = 60
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -7,6 +7,8 @@ Witch
|
||||
Name = ???
|
||||
Cooldown = 8
|
||||
Mana Cost = 5
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -21,6 +23,8 @@ Witch
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 30
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -35,6 +39,8 @@ Witch
|
||||
Name = ???
|
||||
Cooldown = 6
|
||||
Mana Cost = 25
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -49,6 +55,8 @@ Witch
|
||||
Name = ???
|
||||
Cooldown = 40
|
||||
Mana Cost = 75
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -8,6 +8,8 @@ Wizard
|
||||
Radius = 100
|
||||
Speed = 200
|
||||
Cooldown = 0.85
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
# When bullet makes contact, how fast the bullet will fade out.
|
||||
BulletHitFadeoutTime = 0.2
|
||||
@ -28,6 +30,8 @@ Wizard
|
||||
Name = Teleport
|
||||
Cooldown = 8
|
||||
Mana Cost = 5
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 1
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 0, 0, 64, 255
|
||||
@ -64,6 +68,8 @@ Wizard
|
||||
Name = Firebolt
|
||||
Cooldown = 6
|
||||
Mana Cost = 30
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -126,6 +132,8 @@ Wizard
|
||||
Name = Lightning Bolt
|
||||
Cooldown = 6
|
||||
Mana Cost = 25
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
@ -178,6 +186,8 @@ Wizard
|
||||
Name = Meteor
|
||||
Cooldown = 40
|
||||
Mana Cost = 75
|
||||
# Whether or not this ability cancels casts.
|
||||
CancelCast = 0
|
||||
|
||||
#RGB Values. Color 1 is the left side of the bar, Color 2 is the right side.
|
||||
Cooldown Bar Color 1 = 64, 0, 0, 255
|
||||
|
@ -34,4 +34,19 @@ debug_access_options = 0
|
||||
debug_player_info = 0
|
||||
|
||||
# Shows collision boxes of tiles.
|
||||
debug_collision_boxes = 0
|
||||
debug_collision_boxes = 0
|
||||
|
||||
# Shows pathfinding debugging
|
||||
debug_pathfinding = 0
|
||||
|
||||
# ms precision of animation tile caching.
|
||||
animation_tile_precision = 50
|
||||
|
||||
# frequency of water reflection moving update.
|
||||
water_reflection_update_time = 0.5
|
||||
|
||||
# amount of time step of water reflection moving update.
|
||||
water_reflection_time_step = 0.6
|
||||
|
||||
# the amount of scaling done to the water reflection.
|
||||
water_reflection_scale_factor = 0.05
|
@ -2,32 +2,38 @@ GFX_Prefix = assets/
|
||||
|
||||
Images
|
||||
{
|
||||
GFX_Warrior_Sheet = nico-warrior.png
|
||||
GFX_Arrow = arrow.png
|
||||
GFX_Battlecry_Effect = battlecry_effect.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_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_Mana = mana.png
|
||||
GFX_SonicSlash = sonicslash.png
|
||||
GFX_BulletCircle = circle.png
|
||||
GFX_BulletCircleOutline = circle_outline.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
|
||||
GFX_SlimeKing_Cast = monsters/Slime King - Cast.png
|
||||
}
|
BIN
Crawler/assets/fire_ring0.png
Normal file
After Width: | Height: | Size: 627 B |
BIN
Crawler/assets/fire_ring1.png
Normal file
After Width: | Height: | Size: 706 B |
BIN
Crawler/assets/fire_ring2.png
Normal file
After Width: | Height: | Size: 683 B |
BIN
Crawler/assets/fire_ring3.png
Normal file
After Width: | Height: | Size: 681 B |
BIN
Crawler/assets/fire_ring4.png
Normal file
After Width: | Height: | Size: 672 B |
124
Crawler/assets/maps/24x24_Waterfall.tsx
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.10.1" name="24x24_Waterfall" tilewidth="24" tileheight="24" tilecount="80" columns="8">
|
||||
<image source="24x24_Waterfall.png" width="192" height="240"/>
|
||||
<tile id="0">
|
||||
<animation>
|
||||
<frame tileid="0" duration="100"/>
|
||||
<frame tileid="1" duration="100"/>
|
||||
<frame tileid="2" duration="100"/>
|
||||
<frame tileid="3" duration="100"/>
|
||||
<frame tileid="4" duration="100"/>
|
||||
<frame tileid="5" duration="100"/>
|
||||
<frame tileid="6" duration="100"/>
|
||||
<frame tileid="7" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="8">
|
||||
<animation>
|
||||
<frame tileid="8" duration="100"/>
|
||||
<frame tileid="9" duration="100"/>
|
||||
<frame tileid="10" duration="100"/>
|
||||
<frame tileid="11" duration="100"/>
|
||||
<frame tileid="12" duration="100"/>
|
||||
<frame tileid="13" duration="100"/>
|
||||
<frame tileid="14" duration="100"/>
|
||||
<frame tileid="15" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="16">
|
||||
<animation>
|
||||
<frame tileid="16" duration="100"/>
|
||||
<frame tileid="17" duration="100"/>
|
||||
<frame tileid="18" duration="100"/>
|
||||
<frame tileid="19" duration="100"/>
|
||||
<frame tileid="20" duration="100"/>
|
||||
<frame tileid="21" duration="100"/>
|
||||
<frame tileid="22" duration="100"/>
|
||||
<frame tileid="23" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="24">
|
||||
<animation>
|
||||
<frame tileid="24" duration="100"/>
|
||||
<frame tileid="25" duration="100"/>
|
||||
<frame tileid="26" duration="100"/>
|
||||
<frame tileid="27" duration="100"/>
|
||||
<frame tileid="28" duration="100"/>
|
||||
<frame tileid="29" duration="100"/>
|
||||
<frame tileid="30" duration="100"/>
|
||||
<frame tileid="31" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="32">
|
||||
<animation>
|
||||
<frame tileid="32" duration="100"/>
|
||||
<frame tileid="33" duration="100"/>
|
||||
<frame tileid="34" duration="100"/>
|
||||
<frame tileid="35" duration="100"/>
|
||||
<frame tileid="36" duration="100"/>
|
||||
<frame tileid="37" duration="100"/>
|
||||
<frame tileid="38" duration="100"/>
|
||||
<frame tileid="39" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="40">
|
||||
<animation>
|
||||
<frame tileid="40" duration="100"/>
|
||||
<frame tileid="41" duration="100"/>
|
||||
<frame tileid="42" duration="100"/>
|
||||
<frame tileid="43" duration="100"/>
|
||||
<frame tileid="44" duration="100"/>
|
||||
<frame tileid="45" duration="100"/>
|
||||
<frame tileid="46" duration="100"/>
|
||||
<frame tileid="47" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="48">
|
||||
<animation>
|
||||
<frame tileid="48" duration="100"/>
|
||||
<frame tileid="49" duration="100"/>
|
||||
<frame tileid="50" duration="100"/>
|
||||
<frame tileid="51" duration="100"/>
|
||||
<frame tileid="52" duration="100"/>
|
||||
<frame tileid="53" duration="100"/>
|
||||
<frame tileid="54" duration="100"/>
|
||||
<frame tileid="55" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="56">
|
||||
<animation>
|
||||
<frame tileid="56" duration="100"/>
|
||||
<frame tileid="57" duration="100"/>
|
||||
<frame tileid="58" duration="100"/>
|
||||
<frame tileid="59" duration="100"/>
|
||||
<frame tileid="60" duration="100"/>
|
||||
<frame tileid="61" duration="100"/>
|
||||
<frame tileid="62" duration="100"/>
|
||||
<frame tileid="63" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="64">
|
||||
<animation>
|
||||
<frame tileid="64" duration="100"/>
|
||||
<frame tileid="65" duration="100"/>
|
||||
<frame tileid="66" duration="100"/>
|
||||
<frame tileid="67" duration="100"/>
|
||||
<frame tileid="68" duration="100"/>
|
||||
<frame tileid="69" duration="100"/>
|
||||
<frame tileid="70" duration="100"/>
|
||||
<frame tileid="71" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="72">
|
||||
<animation>
|
||||
<frame tileid="72" duration="100"/>
|
||||
<frame tileid="73" duration="100"/>
|
||||
<frame tileid="74" duration="100"/>
|
||||
<frame tileid="75" duration="100"/>
|
||||
<frame tileid="76" duration="100"/>
|
||||
<frame tileid="77" duration="100"/>
|
||||
<frame tileid="78" duration="100"/>
|
||||
<frame tileid="79" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
</tileset>
|
BIN
Crawler/assets/monsters/Slime King - Cast.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@ -35,7 +35,7 @@ var Module = {
|
||||
})(),
|
||||
};
|
||||
</script>
|
||||
<script async type="text/javascript" src="pge.js"></script>
|
||||
<script async type="text/javascript" src="_REPLACEME_"></script>
|
||||
<script type="text/javascript">
|
||||
Module.canvas.addEventListener("resize", (e) => {
|
||||
|
||||
|
@ -324,7 +324,7 @@ namespace olc
|
||||
|
||||
olc::vf2d TransformedView::WorldToScreen(const olc::vf2d& vWorldPos) const
|
||||
{
|
||||
olc::vf2d vFloat = ((vd2d(vWorldPos) - vd2d(m_vWorldOffset)) * vd2d(m_vWorldScale));
|
||||
olc::vf2d vFloat = ((vf2d(vWorldPos) - vf2d(m_vWorldOffset)) * vf2d(m_vWorldScale));
|
||||
//vFloat = { std::floor(vFloat.x + 0.5f), std::floor(vFloat.y + 0.5f) };
|
||||
return vFloat;
|
||||
}
|
||||
|
@ -2891,8 +2891,8 @@ namespace olc
|
||||
di.decal = decal;
|
||||
di.tint = { tint, tint, tint, tint };
|
||||
di.pos = { { vScreenSpacePos.x, vScreenSpacePos.y }, { vScreenSpacePos.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpacePos.y } };
|
||||
olc::vf2d uvtl = (source_pos) * decal->vUVScale;
|
||||
olc::vf2d uvbr = uvtl + ((source_size) * decal->vUVScale);
|
||||
olc::vf2d uvtl = (source_pos + olc::vf2d(0.0001f, 0.0001f)) * decal->vUVScale;
|
||||
olc::vf2d uvbr = uvtl + ((source_size - olc::vf2d(0.0001f, 0.0001f)) * decal->vUVScale);
|
||||
di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
|
||||
di.w = { 1,1,1,1 };
|
||||
di.mode = nDecalMode;
|
||||
|
@ -130,11 +130,26 @@ 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
|
||||
inline bool HasProperty(const std::string& sName)
|
||||
{
|
||||
return m_mapObjects.count(sName) > 0;
|
||||
size_t x = sName.find_first_of('.');
|
||||
if (x != std::string::npos)
|
||||
{
|
||||
std::string sProperty = sName.substr(0, x);
|
||||
if(HasProperty(sProperty)){
|
||||
return GetProperty(sName.substr(0, x)).HasProperty(sName.substr(x + 1, sName.size()));
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return m_mapObjects.count(sName) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Access a datafile via a convenient name - "root.node.something.property"
|
||||
|
16280
Crawler/pge.data
BIN
Crawler/pge.wasm
@ -1,3 +1,4 @@
|
||||
//#define OLC_PGE_HEADLESS
|
||||
#define OLC_PGE_APPLICATION
|
||||
#include "olcPixelGameEngine.h"
|
||||
#define OLC_PGEX_TRANSFORMEDVIEW
|
||||
|
75
Crawler/play.html
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Emscripten-Generated Code</title>
|
||||
<style>
|
||||
html,body { width: 100%; height: 100%; }
|
||||
body { font-family: arial; margin: 0; padding: 0; background: #000; }
|
||||
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
div.emscripten_border { border: none; }
|
||||
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten { border: 0px none; background-color: black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
|
||||
return canvas;
|
||||
})(),
|
||||
};
|
||||
</script>
|
||||
<script async type="text/javascript" src="pge.js"></script>
|
||||
<script type="text/javascript">
|
||||
Module.canvas.addEventListener("resize", (e) => {
|
||||
|
||||
var viewWidth = e.detail.width;
|
||||
var viewHeight = e.detail.width / Module._olc_WindowAspectRatio;
|
||||
|
||||
if(viewHeight > e.detail.height)
|
||||
{
|
||||
viewHeight = e.detail.height;
|
||||
viewWidth = e.detail.height * Module._olc_WindowAspectRatio;
|
||||
}
|
||||
|
||||
// update dom attributes
|
||||
Module.canvas.setAttribute("width", viewWidth);
|
||||
Module.canvas.setAttribute("height", viewHeight);
|
||||
|
||||
var top = (e.detail.height - viewHeight) / 2;
|
||||
var left = (e.detail.width - viewWidth) / 2;
|
||||
|
||||
// update styles
|
||||
Module.canvas.style.position = "fixed";
|
||||
Module.canvas.style.top = top.toString() + "px";
|
||||
Module.canvas.style.left = left.toString() + "px";
|
||||
Module.canvas.style.width = "";
|
||||
Module.canvas.style.height = "";
|
||||
|
||||
// trigger PGE update
|
||||
Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight);
|
||||
|
||||
// ensure canvas has focus
|
||||
Module.canvas.focus();
|
||||
e.preventDefault();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -14,7 +14,24 @@ public:
|
||||
}
|
||||
return map[key];
|
||||
}
|
||||
size_t count(T key){
|
||||
return map.count(key);
|
||||
}
|
||||
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();
|
||||
}
|
||||
auto begin()const{
|
||||
return map.begin();
|
||||
}
|
||||
auto end()const{
|
||||
return map.end();
|
||||
}
|
||||
};
|
@ -1,9 +1,10 @@
|
||||
export AUTO_UPDATE=false
|
||||
export AUTO_UPDATE=true
|
||||
|
||||
source utils/define.sh
|
||||
|
||||
define PROJECT_NAME "Crawler"
|
||||
define CUSTOM_PARAMS "-std=c++20 -lX11 -lGL -lpthread -lpng -lstdc++fs -I/usr/include/lua5.3"
|
||||
define CUSTOM_PARAMS "-std=c++20 -lX11 -lpthread -lpng -lstdc++fs -I/usr/include/lua5.3"
|
||||
define EMSCRIPTEN_CUSTOM_PARAMS "-s MAXIMUM_MEMORY=4GB"
|
||||
define LANGUAGE "C++"
|
||||
|
||||
source utils/main.sh
|
||||
|
@ -8,6 +8,10 @@ vf2d util::pointTo(vf2d posFrom,vf2d posTo){
|
||||
return geom2d::line(posFrom,posTo).vector().norm();
|
||||
}
|
||||
|
||||
float util::angleTo(vf2d posFrom,vf2d posTo){
|
||||
return geom2d::line<float>(posFrom,posTo).vector().polar().y;
|
||||
}
|
||||
|
||||
float util::degToRad(float deg){
|
||||
return deg*(PI/180);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ namespace util{
|
||||
float random(float range);
|
||||
//Returns a normalized vector pointing from posFrom towards posTo.
|
||||
vf2d pointTo(vf2d posFrom,vf2d posTo);
|
||||
//Returns the angle (in radians) pointing from posFrom towards posTo.
|
||||
float angleTo(vf2d posFrom,vf2d posTo);
|
||||
float degToRad(float deg);
|
||||
float radToDeg(float rad);
|
||||
float lerp(float n1,float n2,double t);
|
||||
|