Boss Phase 3 completed.

pull/35/head
sigonasr2 10 months ago
parent 9f5bb212f8
commit 5ed991ec88
  1. 2
      Adventures in Lestoria/Buff.h
  2. 35
      Adventures in Lestoria/Monster.cpp
  3. 1
      Adventures in Lestoria/Monster.h
  4. 1
      Adventures in Lestoria/MonsterAttribute.h
  5. 81
      Adventures in Lestoria/Ursule.cpp
  6. 2
      Adventures in Lestoria/Version.h
  7. 17
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  8. 3
      Adventures in Lestoria/assets/config/Monsters.txt
  9. BIN
      Adventures in Lestoria/assets/monsters/Ursule Mother of Bears2.png
  10. BIN
      Adventures in Lestoria/assets/monsters/Ursule, Mother of Bears.png
  11. BIN
      x64/Release/Adventures in Lestoria.exe

@ -49,6 +49,8 @@ enum BuffType{
LOCKON_SPEEDBOOST, //Specifically used for wolves. LOCKON_SPEEDBOOST, //Specifically used for wolves.
SPEEDBOOST, SPEEDBOOST,
BARRIER_DAMAGE_REDUCTION, //Creates a visual barrier around the target BARRIER_DAMAGE_REDUCTION, //Creates a visual barrier around the target
FIXED_COLLISION_DMG, //Does a fixed amount of collision damage based on intensity of this buff.
COLLISION_KNOCKBACK_STRENGTH, //Causes an amount of knockback based on intensity when hit via collision with this buff
}; };
class AiL; class AiL;

@ -372,14 +372,36 @@ void Monster::DrawReflection(float drawRatioX,float multiplierX){
game->SetDecalMode(DecalMode::NORMAL); game->SetDecalMode(DecalMode::NORMAL);
} }
void Monster::Collision(Player*p){ void Monster::Collision(Player*p){
if(MONSTER_DATA[name].GetCollisionDmg()>0&&lastHitPlayer==0.0f){ if(GetCollisionDamage()>0&&lastHitPlayer==0.0f){
if(p->Hurt(MONSTER_DATA[name].GetCollisionDmg(),OnUpperLevel(),GetZ())){ if(p->Hurt(GetCollisionDamage(),OnUpperLevel(),GetZ())){
lastHitPlayer=1.0f; lastHitPlayer=1.0f;
} }
} }
#pragma region Knockback due to buffs
vf2d knockbackVecNorm=geom2d::line<float>(GetPos(),p->GetPos()).vector().norm();
float knockbackStrength=0.f;
std::vector<Buff> knockbackBuffs=GetBuffs(COLLISION_KNOCKBACK_STRENGTH);
for(Buff&b:knockbackBuffs){
knockbackStrength+=b.intensity;
}
p->Knockback(knockbackVecNorm*knockbackStrength);
#pragma endregion
Collision(); Collision();
} }
void Monster::Collision(Monster&m){ void Monster::Collision(Monster&m){
#pragma region Knockback due to buffs
vf2d knockbackVecNorm=geom2d::line<float>(GetPos(),m.GetPos()).vector().norm();
float knockbackStrength=0.f;
std::vector<Buff> knockbackBuffs=GetBuffs(COLLISION_KNOCKBACK_STRENGTH);
for(Buff&b:knockbackBuffs){
knockbackStrength+=b.intensity;
}
m.Knockback(knockbackVecNorm*knockbackStrength);
#pragma endregion
Collision(); Collision();
} }
void Monster::Collision(){ void Monster::Collision(){
@ -720,4 +742,13 @@ const float Monster::GetDamageReductionFromBuffs()const{
dmgReduction+=b.intensity; dmgReduction+=b.intensity;
} }
return std::min(1.0f,dmgReduction); return std::min(1.0f,dmgReduction);
}
const float Monster::GetCollisionDamage()const{
float collisionDmg=0.f;
for(Buff&b:GetBuffs(FIXED_COLLISION_DMG)){
collisionDmg+=b.intensity;
}
if(collisionDmg>0)return collisionDmg;
else return MONSTER_DATA[name].GetCollisionDmg();
} }

@ -185,6 +185,7 @@ public:
//Rotates this enemy's sprite towards a given location. Also flips it to face the correct direction. //Rotates this enemy's sprite towards a given location. Also flips it to face the correct direction.
void RotateTowardsPos(const vf2d&targetPos); void RotateTowardsPos(const vf2d&targetPos);
const float GetDamageReductionFromBuffs()const; const float GetDamageReductionFromBuffs()const;
const float GetCollisionDamage()const;
private: private:
std::string name; std::string name;
vf2d pos; vf2d pos;

@ -88,4 +88,5 @@ enum class Attribute{
WISP_PATTERN_LIST, WISP_PATTERN_LIST,
ENVIRONMENT_TIMER, ENVIRONMENT_TIMER,
ENVIRONMENT_PHASE, ENVIRONMENT_PHASE,
CHARGE_COOLDOWN,
}; };

@ -114,6 +114,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
m.PerformOtherAnimation(2); m.PerformOtherAnimation(2);
m.F(A::SHOOT_TIMER)=std::max(0.f,m.F(A::SHOOT_TIMER)-fElapsedTime); m.F(A::SHOOT_TIMER)=std::max(0.f,m.F(A::SHOOT_TIMER)-fElapsedTime);
#pragma region Environment Color Change Handling
m.F(A::ENVIRONMENT_TIMER)=std::max(0.f,m.F(A::ENVIRONMENT_TIMER)-fElapsedTime); m.F(A::ENVIRONMENT_TIMER)=std::max(0.f,m.F(A::ENVIRONMENT_TIMER)-fElapsedTime);
switch(m.I(A::ENVIRONMENT_PHASE)){ switch(m.I(A::ENVIRONMENT_PHASE)){
case 0:{ //Fade out. case 0:{ //Fade out.
@ -138,6 +139,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
} }
}break; }break;
} }
#pragma endregion
if(m.I(A::PHASE_REPEAT_COUNT)>0){ if(m.I(A::PHASE_REPEAT_COUNT)>0){
if(m.F(A::SHOOT_TIMER)==0.f){ if(m.F(A::SHOOT_TIMER)==0.f){
@ -174,19 +176,94 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
m.I(A::PHASE_REPEAT_COUNT)--; m.I(A::PHASE_REPEAT_COUNT)--;
} }
}else{ }else{
auto TransitionToPhase3=[&](){
m.phase=3;
game->SetWorldColor(ConfigPixel("Phase 3.Environment Fade-In Color"));
m.F(A::ENVIRONMENT_TIMER)=ConfigFloat("Phase 3.Environment Fade-in Time");
m.I(A::ENVIRONMENT_PHASE)=0;
m.RemoveBuff(BARRIER_DAMAGE_REDUCTION);
};
if(m.F(A::RECOVERY_TIME)==0.f){ if(m.F(A::RECOVERY_TIME)==0.f){
if(ConfigFloat("Phase 2.Wisp Count Phase Change Wait")==0.f)m.phase=3; if(ConfigFloat("Phase 2.Wisp Count Phase Change Wait")==0.f){
TransitionToPhase3();
}
m.F(A::RECOVERY_TIME)=ConfigFloat("Phase 2.Wisp Count Phase Change Wait"); m.F(A::RECOVERY_TIME)=ConfigFloat("Phase 2.Wisp Count Phase Change Wait");
}else{ }else{
m.F(A::RECOVERY_TIME)-=fElapsedTime; m.F(A::RECOVERY_TIME)-=fElapsedTime;
if(m.F(A::RECOVERY_TIME)<=0.f){ if(m.F(A::RECOVERY_TIME)<=0.f){
m.phase=3; TransitionToPhase3();
} }
} }
} }
}break; }break;
case 3:{ case 3:{
#pragma region Environment Color Change Handling
m.F(A::ENVIRONMENT_TIMER)=std::max(0.f,m.F(A::ENVIRONMENT_TIMER)-fElapsedTime);
switch(m.I(A::ENVIRONMENT_PHASE)){
case 0:{ //Fade out. Use the phase 2 environment fade-in color as the previous color to lerp out from.
game->SetWorldColor(ConfigPixel("Phase 2.Environment Fade-In Color")*util::lerp(0.f,1.0f,m.F(A::ENVIRONMENT_TIMER)/ConfigFloat("Phase 3.Environment Fade-out Time")));
if(m.F(A::ENVIRONMENT_TIMER)==0.f){
game->SetWorldColor({0,0,0,255});
m.F(A::ENVIRONMENT_TIMER)=ConfigFloat("Phase 3.Environment Fade-in Time");
m.I(A::ENVIRONMENT_PHASE)++;
game->SetWorldColorFunc([&](vi2d pos){return game->GetWorldColor();});
}
}break;
case 1:{ //Fade in.
Pixel fadeInCol=ConfigPixel("Phase 3.Environment Fade-In Color");
game->SetWorldColor(fadeInCol*util::lerp(1.f,0.f,m.F(A::ENVIRONMENT_TIMER)/ConfigFloat("Phase 3.Environment Fade-in Time")));
if(m.F(A::ENVIRONMENT_TIMER)==0.f){
game->SetWorldColor(fadeInCol);
}
}break;
}
#pragma endregion
float distToPlayer=geom2d::line<float>(game->GetPlayer()->GetPos(),m.GetPos()).length();
m.F(A::CHARGE_COOLDOWN)=std::max(0.f,m.F(A::CHARGE_COOLDOWN)-fElapsedTime);
if(m.I(A::PHASE)!=0)goto bear2; //Prevent doing anything else if a part of bear AI is still running.
if(distToPlayer>=ConfigFloat("Phase 3.Charge Range")/100.f*24.f&&m.F(A::CHARGE_COOLDOWN)==0.f){
if(ConfigFloat("Phase 3.Charge Cast Time")!=0.f){
if(m.F(A::CASTING_TIMER)==0.f)m.F(A::CASTING_TIMER)=ConfigFloat("Phase 3.Charge Cast Time");
}
if(m.F(A::CASTING_TIMER)>0.f){
m.F(A::CASTING_TIMER)=std::max(0.f,m.F(A::CASTING_TIMER)-fElapsedTime);
if(m.F(A::CASTING_TIMER)==0.f){
m.phase=4;
m.AddBuff(SPEEDBOOST,10.f,ConfigFloat("Phase 3.Charge Speed Boost")/100.f);
m.AddBuff(FIXED_COLLISION_DMG,10.f,ConfigFloat("Phase 3.Charge Attack Damage"));
m.AddBuff(COLLISION_KNOCKBACK_STRENGTH,10.f,ConfigFloat("Phase 3.Charge Attack Knockback Strength"));
m.target=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).upoint(2.0f);
m.F(A::CHARGE_COOLDOWN)=ConfigFloat("Phase 3.Charge Attack Cooldown");
m.PerformOtherAnimation(3);
break;
}
}
}
bear2:
BEAR(m,fElapsedTime,"Bear");
}break;
case 4:{ //A charging phase.
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
vf2d newPos=m.pos+geom2d::line(m.pos,m.target).vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
m.SetPos(newPos);
}
float distToTarget=geom2d::line<float>(m.target,m.GetPos()).length();
if(distToTarget<=4.f){
m.phase=3;
m.RemoveBuff(SPEEDBOOST);
m.RemoveBuff(FIXED_COLLISION_DMG);
m.RemoveBuff(COLLISION_KNOCKBACK_STRENGTH);
m.PerformIdleAnimation();
}
}break; }break;
default:{ default:{
ERR(std::format("WARNING! Unknown phase {} for {} reached!",m.phase,m.GetName())); ERR(std::format("WARNING! Unknown phase {} for {} reached!",m.phase,m.GetName()));

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 6322 #define VERSION_BUILD 6336
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -382,14 +382,23 @@ MonsterStrategy
} }
Phase 3 Phase 3
{ {
# Amount of time the environment fades out to pitch black.
Environment Fade-out Time = 0.4s
# Amount of time for the environment to fade in with the new color.
Environment Fade-in Time = 2.0s
# New fade-in environment color.
Environment Fade-In Color = 255, 255, 255, 255
# Minimum range the bear will decide to charge the player. # Minimum range the bear will decide to charge the player.
Charge Range = 700 Charge Range = 450
# Amount of time the bear spends preparing to charge. # Amount of time the bear spends preparing to charge.
Charge Cast Time = 0.6s Charge Cast Time = 0.1s
# Amount of speed to gain during the charge attack. # Amount of speed to gain during the charge attack.
Charge Speed Boost = 60% Charge Speed Boost = 200%
# Cooldown time of the charge attack. # Cooldown time of the charge attack.
Charge Attack Cooldown = 15.0s Charge Attack Cooldown = 15.0s
@ -398,7 +407,7 @@ MonsterStrategy
Charge Attack Damage = 30 Charge Attack Damage = 30
# Amount of knockback to cause to the player when hit by the charging attack. # Amount of knockback to cause to the player when hit by the charging attack.
Charge Attack Knockback Strength = 2.5 Charge Attack Knockback Strength = 3.5
} }
Phase 4 Phase 4
{ {

@ -364,7 +364,7 @@ Monsters
#Size of each animation frame #Size of each animation frame
SheetFrameSize = 24,24 SheetFrameSize = 26,26
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse) # Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
IdleAnimation = 4, 0.3, Repeat IdleAnimation = 4, 0.3, Repeat
@ -386,5 +386,6 @@ Monsters
ANIMATION[0] = 4, 0.1, OneShot ANIMATION[0] = 4, 0.1, OneShot
ANIMATION[1] = 6, 0.15, OneShot ANIMATION[1] = 6, 0.15, OneShot
ANIMATION[2] = 2, 0.2, Reverse ANIMATION[2] = 2, 0.2, Reverse
ANIMATION[3] = 5, 0.2, Repeat
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Loading…
Cancel
Save