diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index b6773ae1..e4f8ef7d 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -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&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); } diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index fea99f09..80c73c8e 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -72,7 +72,7 @@ public: void AddEffect(std::unique_ptrforeground,std::unique_ptrbackground); //If back is true, places the effect in the background void AddEffect(std::unique_ptrforeground,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(); diff --git a/Crawler/FireBolt.cpp b/Crawler/FireBolt.cpp index fe74dbc2..9f51f891 100644 --- a/Crawler/FireBolt.cpp +++ b/Crawler/FireBolt.cpp @@ -35,7 +35,7 @@ bool FireBolt::MonsterHit(Monster& monster) game->AddEffect(std::make_unique(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(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; } diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp index 88d3ab7f..ff79b36e 100644 --- a/Crawler/LightningBolt.cpp +++ b/Crawler/LightningBolt.cpp @@ -55,7 +55,7 @@ bool LightningBolt::MonsterHit(Monster& monster) geom2d::linelineToTarget=geom2d::line(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(monster.GetPos(),m.GetPos(),"Wizard.Ability 2.LightningChainFrequency"_F,"Wizard.Ability 2.LightningChainLifetime"_F,upperLevel))); game->AddEffect(std::make_unique(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++; diff --git a/Crawler/Meteor.cpp b/Crawler/Meteor.cpp index e02012a6..4fb17569 100644 --- a/Crawler/Meteor.cpp +++ b/Crawler/Meteor.cpp @@ -24,7 +24,7 @@ bool Meteor::Update(float fElapsedTime){ vf2d effectPos=vf2d{cos(randomAngle),sin(randomAngle)}*randomRange+meteorOffset; game->AddEffect(std::make_unique(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.yHurtEnemies(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(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); diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index a79baed0..8de075e9 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -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; diff --git a/Crawler/Monster.h b/Crawler/Monster.h index d80124d9..0aa20159 100644 --- a/Crawler/Monster.h +++ b/Crawler/Monster.h @@ -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(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 4a2320c8..6ead4e72 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -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(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(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)){ diff --git a/Crawler/Player.h b/Crawler/Player.h index 3101f482..ade674df 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -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(); diff --git a/Crawler/PulsatingFire.cpp b/Crawler/PulsatingFire.cpp index 74b80062..05a6aca0 100644 --- a/Crawler/PulsatingFire.cpp +++ b/Crawler/PulsatingFire.cpp @@ -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); } diff --git a/Crawler/SlimeKing.cpp b/Crawler/SlimeKing.cpp index 1a92e2f6..0749c450 100644 --- a/Crawler/SlimeKing.cpp +++ b/Crawler/SlimeKing.cpp @@ -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().xGetPlayer()->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().yGetPlayer()->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")){ diff --git a/Crawler/Version.h b/Crawler/Version.h index 23cfb35a..eb48fbce 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 1138 +#define VERSION_BUILD 1147 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/Warrior.cpp b/Crawler/Warrior.cpp index 8b1ad5ed..d6988418 100644 --- a/Crawler/Warrior.cpp +++ b/Crawler/Warrior.cpp @@ -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(GetPos(),attack_range*GetSizeMult()*12),geom2d::circle(m.GetPos(),m.GetSizeMult()*12)) &&geom2d::line(game->GetWorldMousePos(),m.GetPos()).length()(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); diff --git a/Crawler/assets/config/MonsterStrategies.txt b/Crawler/assets/config/MonsterStrategies.txt index 994a4729..2c357071 100644 --- a/Crawler/assets/config/MonsterStrategies.txt +++ b/Crawler/assets/config/MonsterStrategies.txt @@ -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