Quapsel 1 year ago
commit 74d86d476e
  1. 10
      Crawler/Crawler.cpp
  2. 2
      Crawler/Crawler.h
  3. 2
      Crawler/FireBolt.cpp
  4. 2
      Crawler/LightningBolt.cpp
  5. 2
      Crawler/Meteor.cpp
  6. 9
      Crawler/Monster.cpp
  7. 2
      Crawler/Monster.h
  8. 6
      Crawler/Player.cpp
  9. 2
      Crawler/Player.h
  10. 2
      Crawler/PulsatingFire.cpp
  11. 17
      Crawler/SlimeKing.cpp
  12. 2
      Crawler/Version.h
  13. 3
      Crawler/Warrior.cpp
  14. 3
      Crawler/assets/config/MonsterStrategies.txt

@ -427,7 +427,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
if(b->friendly){
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(geom2d::circle(m.GetPos(),12*m.GetSizeMult()),geom2d::circle(b->pos,b->radius))){
if(b->hitList.find(&m)==b->hitList.end()&&m.Hurt(b->damage,b->OnUpperLevel())){
if(b->hitList.find(&m)==b->hitList.end()&&m.Hurt(b->damage,b->OnUpperLevel(),0)){
if(!b->hitsMultiple){
if(b->MonsterHit(m)){
b->dead=true;
@ -440,7 +440,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
}
} else {
if(geom2d::overlaps(geom2d::circle(player->GetPos(),12*player->GetSizeMult()/2),geom2d::circle(b->pos,b->radius))){
if(player->Hurt(b->damage,b->OnUpperLevel())){
if(player->Hurt(b->damage,b->OnUpperLevel(),0)){
if(b->PlayerHit(player.get())){
b->dead=true;
continue;
@ -465,10 +465,10 @@ void Crawler::UpdateBullets(float fElapsedTime){
outsideBulletLoop:
std::erase_if(BULLET_LIST,[](std::unique_ptr<Bullet>&b){return b->dead;});
}
void Crawler::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel){
void Crawler::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z){
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(geom2d::circle(pos,radius),geom2d::circle(m.GetPos(),12*m.GetSizeMult()))){
m.Hurt(damage,upperLevel);
m.Hurt(damage,upperLevel,z);
}
}
}
@ -840,7 +840,7 @@ vf2d Crawler::GetWorldMousePos(){
void Crawler::SetupWorldShake(float duration){
worldShakeVel={750,-750};
worldShakeTime=duration;
worldShake=player->GetPos();
worldShake=vf2d{player->GetPos()};
camera.SetTarget(worldShake);
}

@ -72,7 +72,7 @@ public:
void AddEffect(std::unique_ptr<Effect>foreground,std::unique_ptr<Effect>background);
//If back is true, places the effect in the background
void AddEffect(std::unique_ptr<Effect>foreground,bool back=false);
void HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel);
void HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z);
vf2d GetWorldMousePos();
bool LeftHeld();
bool RightHeld();

@ -35,7 +35,7 @@ bool FireBolt::MonsterHit(Monster& monster)
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->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());
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));
return false;
}

@ -55,7 +55,7 @@ bool LightningBolt::MonsterHit(Monster& monster)
geom2d::line<float>lineToTarget=geom2d::line<float>(monster.GetPos(),m.GetPos());
float dist=lineToTarget.length();
if(dist<="Wizard.Ability 2.LightningChainRadius"_F/100*24){
if(m.Hurt(game->GetPlayer()->GetAttack()*"Wizard.Ability 2.LightningChainDamageMult"_F,OnUpperLevel())){
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));
targetsHit++;

@ -24,7 +24,7 @@ bool Meteor::Update(float fElapsedTime){
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->HurtEnemies(pos,"Wizard.Ability 3.MeteorRadius"_F/100*24,game->GetPlayer()->GetAttack()*"Wizard.Ability 3.MeteorDamageMult"_F,OnUpperLevel());
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);
}
return Effect::Update(fElapsedTime);

@ -196,8 +196,9 @@ void Monster::Draw(){
}
void Monster::Collision(Player*p){
if(MONSTER_DATA[id].GetCollisionDmg()>0&&!hasHitPlayer){
hasHitPlayer=true;
p->Hurt(MONSTER_DATA[id].GetCollisionDmg(),OnUpperLevel());
if(p->Hurt(MONSTER_DATA[id].GetCollisionDmg(),OnUpperLevel(),GetZ())){
hasHitPlayer=true;
}
}
Collision();
}
@ -236,8 +237,8 @@ void Monster::Moved(){
std::string Monster::GetDeathAnimationName(){
return MONSTER_DATA[id].GetDeathAnimation();
}
bool Monster::Hurt(int damage,bool onUpperLevel){
if(!IsAlive()||onUpperLevel!=OnUpperLevel()||HasIframes()) return false;
bool Monster::Hurt(int damage,bool onUpperLevel,float z){
if(!IsAlive()||onUpperLevel!=OnUpperLevel()||HasIframes()||abs(GetZ()-z)>1) return false;
float mod_dmg=damage;
for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
mod_dmg-=damage*b.intensity;

@ -107,7 +107,7 @@ public:
bool Update(float fElapsedTime);
//Returns true when damage is actually dealt. Provide whether or not the attack is on the upper level or not. Monsters must be on the same level to get hit by it. (there is a death check and level check here.)
//If you need to hurt multiple enemies try Crawler::HurtEnemies()
bool Hurt(int damage,bool onUpperLevel);
bool Hurt(int damage,bool onUpperLevel,float z);
bool IsAlive();
vf2d&GetTargetPos();
Key GetFacingDirection();

@ -237,7 +237,7 @@ void Player::Update(float fElapsedTime){
spin_angle=0;
z=0;
float numb=4;
game->HurtEnemies(pos,"Warrior.Ability 2.Range"_F/100*12,GetAttack()*"Warrior.Ability 2.DamageMult"_F,OnUpperLevel());
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));
}
if(lastAnimationFlip>0){
@ -490,8 +490,8 @@ bool Player::HasIframes(){
return iframe_time>0;
}
bool Player::Hurt(int damage,bool onUpperLevel){
if(hp<=0||HasIframes()||OnUpperLevel()!=onUpperLevel) return false;
bool Player::Hurt(int damage,bool onUpperLevel,float z){
if(hp<=0||HasIframes()||OnUpperLevel()!=onUpperLevel||abs(GetZ()-z)>1) return false;
if(GetState()==State::BLOCK)damage*=1-"Warrior.Right Click Ability.DamageReduction"_F;
float mod_dmg=damage;
for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){

@ -137,7 +137,7 @@ public:
void RemoveAllBuffs(BuffType type); //Removes all buffs of a certain type.
void RemoveAllBuffs(); //Remove every buff.
bool Hurt(int damage,bool onUpperLevel);
bool Hurt(int damage,bool onUpperLevel,float z);
//specificClass is a bitwise-combination of classes from the Class enum. It makes sure certain animations only play if you are a certain class.
void UpdateAnimation(std::string animState,int specificClass=ANY);
Animate2D::Frame GetFrame();

@ -31,7 +31,7 @@ bool PulsatingFire::Update(float fElapsedTime){
}
if(lastDamageTimer<=0){
lastDamageTimer="Wizard.Ability 3.FireRingDamageFreq"_F-0.01;
game->HurtEnemies(pos,"Wizard.Ability 3.MeteorRadius"_F/100*24,game->GetPlayer()->GetAttack()*"Wizard.Ability 3.FireRingDamageMult"_F,OnUpperLevel());
game->HurtEnemies(pos,"Wizard.Ability 3.MeteorRadius"_F/100*24,game->GetPlayer()->GetAttack()*"Wizard.Ability 3.FireRingDamageMult"_F,OnUpperLevel(),0);
}
return Effect::Update(fElapsedTime);
}

@ -44,14 +44,27 @@ 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);
m.SetPos(m.V(A::JUMP_ORIGINAL_POS).lerp(m.V(A::JUMP_TARGET_POS),1-jumpLandingTimerRatio));
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
if(m.GetPos().x<game->GetPlayer()->GetPos().x){
m.SetX(std::min(game->GetPlayer()->GetPos().x,m.GetPos().x+ConfigInt("JumpMoveSpd")*game->GetElapsedTime()));
}
if(m.GetPos().y>game->GetPlayer()->GetPos().y){
m.SetY(std::max(game->GetPlayer()->GetPos().y,m.GetPos().y-ConfigInt("JumpMoveSpd")*game->GetElapsedTime()));
} else
if(m.GetPos().y<game->GetPlayer()->GetPos().y){
m.SetY(std::min(game->GetPlayer()->GetPos().y,m.GetPos().y+ConfigInt("JumpMoveSpd")*game->GetElapsedTime()));
}
if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){
m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),1-jumpLandingTimerRatio*2));
m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),1-jumpLandingTimerRatio));
}else{
m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),jumpLandingTimerRatio*2));
}
if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY;
game->SetupWorldShake(0.6);
m.SetStrategyDrawFunction([](Crawler*game){});
} else
if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){

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

@ -35,14 +35,13 @@ bool Warrior::AutoAttack(){
float closest_dist=999999;
for(Monster&m:MONSTER_LIST){
if(m.IsAlive()
&&m.OnUpperLevel()==OnUpperLevel()
&&geom2d::overlaps(geom2d::circle<float>(GetPos(),attack_range*GetSizeMult()*12),geom2d::circle<float>(m.GetPos(),m.GetSizeMult()*12))
&&geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length()<closest_dist){
closest_dist=geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length();
closest=&m;
}
}
if(closest!=nullptr&&closest->Hurt(GetAttack()*"Warrior.Auto Attack.DamageMult"_F,OnUpperLevel())){
if(closest!=nullptr&&closest->Hurt(GetAttack()*"Warrior.Auto Attack.DamageMult"_F,OnUpperLevel(),GetZ())){
attack_cooldown_timer=ATTACK_COOLDOWN;
swordSwingTimer="Warrior.Auto Attack.SwordSwingTime"_F;
SetState(State::SWING_SWORD);

@ -75,9 +75,10 @@ MonsterStrategy
# 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 = 300
JumpHeight = 2400
ProjectileDamage = 10
JumpAttackDamage = 20
JumpMoveSpd = 95
BulletSpd = 250

Loading…
Cancel
Save