Fix alpha colors not being applied to Effects. Move the Bear slam attack pattern to a separate phase within the second boss' cycle to avoid constantly rerolling and choose the stone toss attack. Make target indicator for the stone toss a different color from pillar casts. Release Build 9979.

mac-build
sigonasr2 5 months ago
parent 8e3cdf9d14
commit 08cdf26605
  1. 2
      Adventures in Lestoria/Effect.cpp
  2. 81
      Adventures in Lestoria/StoneGolem.cpp
  3. 2
      Adventures in Lestoria/Version.h
  4. 2
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  5. BIN
      x64/Release/Adventures in Lestoria.exe

@ -73,7 +73,7 @@ void Effect::Draw()const{
if(fadeout==0){
game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,col);
} else {
game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*255)});
game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*col.a)});
}
game->SetDecalMode(DecalMode::NORMAL);
}

@ -54,6 +54,7 @@ using A=Attribute;
void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string strategy){
enum PhaseName{
INITIALIZE,
BEAR_ATTACK,
SPAWN_PILLAR_PREPARE,
RESPAWN_PILLAR_PREPARE,
SPAWN_PILLAR_CAST,
@ -192,45 +193,43 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
}
}break;
case STANDARD:{
BEAR(m,fElapsedTime,"Bear");
//Extending the bear script's variables to read the state of it...
const bool SlamHasFinished=m.I(A::PHASE)==0; //The bear script uses the internal phase variable to determine the state of things.
if(SlamHasFinished){
if(m.F(A::HEALTH_PCT_PHASE)-m.GetHealthRatio()>=ConfigFloat("Shockwave.Repeating Threshold")/100.f){
m.F(A::HEALTH_PCT_PHASE)-=ConfigFloat("Shockwave.Repeating Threshold")/100.f;
m.F(A::CASTING_TIMER)=ConfigFloat("Shockwave.Cast Time");
m.SIZET(A::PREVIOUS_MONSTER_COUNT)=MONSTER_LIST.size();
PrepareSafeAreas();
m.phase=SHOCKWAVE;
break;
}
if(m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)>=m.GetHealthRatio()){
m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)-=ConfigFloat("Pillar Respawns.Repeating Threshold")/100.f;
SoundEffect::StopLoopingSFX(m.SIZET(A::LOOPING_SOUND_ID)); //If we get here, a sound effect should not be playing...
const bool StoneThrowRollSucceeds=util::random(100.f)<=ConfigFloat("Standard Attack.Stone Throw Chance");
if(m.F(A::HEALTH_PCT_PHASE)-m.GetHealthRatio()>=ConfigFloat("Shockwave.Repeating Threshold")/100.f){
m.F(A::HEALTH_PCT_PHASE)-=ConfigFloat("Shockwave.Repeating Threshold")/100.f;
m.F(A::CASTING_TIMER)=ConfigFloat("Shockwave.Cast Time");
m.SIZET(A::PREVIOUS_MONSTER_COUNT)=MONSTER_LIST.size();
m.PerformAnimation("CAST",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));
PrepareSafeAreas();
m.phase=SHOCKWAVE;
break;
}
if(m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)>=m.GetHealthRatio()){
m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)-=ConfigFloat("Pillar Respawns.Repeating Threshold")/100.f;
m.F(A::RESPAWN_RECOVERY_TIME)=ConfigFloat("Pillar Respawns.Cast Delay Time");
m.I(A::RESPAWN_PATTERN_REPEAT_COUNT)+=ConfigIntArr("Pillar Respawns.Respawn Count",0);
m.I(A::BAD_PILLAR_SPAWN_COUNT)+=ConfigIntArr("Pillar Respawns.Respawn Count",1);
m.I(A::RESPAWN_PHASE)=RESPAWN_PILLAR_PREPARE;
}
m.F(A::RESPAWN_RECOVERY_TIME)=ConfigFloat("Pillar Respawns.Cast Delay Time");
m.I(A::RESPAWN_PATTERN_REPEAT_COUNT)+=ConfigIntArr("Pillar Respawns.Respawn Count",0);
m.I(A::BAD_PILLAR_SPAWN_COUNT)+=ConfigIntArr("Pillar Respawns.Respawn Count",1);
m.I(A::RESPAWN_PHASE)=RESPAWN_PILLAR_PREPARE;
}
const bool StoneThrowRollSucceeds=util::random(100.f)<=ConfigFloat("Standard Attack.Stone Throw Chance");
m.I(A::ATTACK_COUNT)=m.I(A::BEAR_STOMP_COUNT); //Make sure the slams are now reset if necessary.
if(StoneThrowRollSucceeds){ //The intent is one or the other attack is supposed to happen. We can't do the slam and a throw, rerolling repeatedly each tick is unncessary.
m.phase=STONE_THROW_CAST;
m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos();
m.PerformAnimation("TOSS ROCK CAST");
m.F(A::CASTING_TIMER)=ConfigFloat("Standard Attack.Stone Throw Cast Time");
game->AddEffect(std::make_unique<SpellCircle>(m.V(A::LOCKON_POS),ConfigFloat("Standard Attack.Stone Throw Cast Time"),"range_indicator.png","spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*(ConfigPixels("Standard Attack.Stone Radius")/12.f)*1.25f,0.3f,vf2d{},ConfigPixel("Standard Attack.Stone Throw Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Standard Attack.Stone Throw Spell Circle Rotation Spd")),false,vf2d{1.f,1.f}*(ConfigPixels("Standard Attack.Stone Radius")/12.f)*0.9f,0.3f,vf2d{},ConfigPixel("Standard Attack.Stone Throw Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Standard Attack.Stone Throw Spell Insignia Rotation Spd"))),true);
if(StoneThrowRollSucceeds){ //The intent is one or the other attack is supposed to happen. We can't do the slam and a throw, rerolling repeatedly each tick is unncessary.
m.phase=STONE_THROW_CAST;
m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos();
m.PerformAnimation("TOSS ROCK CAST");
m.F(A::CASTING_TIMER)=ConfigFloat("Standard Attack.Stone Throw Cast Time");
game->AddEffect(std::make_unique<SpellCircle>(m.V(A::LOCKON_POS),ConfigFloat("Standard Attack.Stone Throw Cast Time"),"range_indicator.png","spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*(ConfigPixels("Standard Attack.Stone Radius")/12.f)*1.25f,0.3f,vf2d{},ConfigPixel("Standard Attack.Stone Throw Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Standard Attack.Stone Throw Spell Circle Rotation Spd")),false,vf2d{1.f,1.f}*(ConfigPixels("Standard Attack.Stone Radius")/12.f)*0.9f,0.3f,vf2d{},ConfigPixel("Standard Attack.Stone Throw Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Standard Attack.Stone Throw Spell Insignia Rotation Spd"))),true);
//Use acceleration equation to determine how much time it takes for the stone to land based on gravity.
const float stoneTossTime{ConfigFloat("Standard Attack.Stone Throw Time")};
//Physics!! Kinematic equation from https://openstax.org/books/physics/pages/3-2-representing-acceleration-with-equations-and-graphs a=(2d)/(t^2)
const float acc{(2*-ConfigFloat("Standard Attack.Stone Throw Height Offset"))/std::pow(stoneTossTime,2.f)};
//Use acceleration equation to determine how much time it takes for the stone to land based on gravity.
const float stoneTossTime{ConfigFloat("Standard Attack.Stone Throw Time")};
//Physics!! Kinematic equation from https://openstax.org/books/physics/pages/3-2-representing-acceleration-with-equations-and-graphs a=(2d)/(t^2)
const float acc{(2*-ConfigFloat("Standard Attack.Stone Throw Height Offset"))/std::pow(stoneTossTime,2.f)};
m.SIZET(A::LOOPING_SOUND_ID)=SoundEffect::PlayLoopingSFX("Rock Toss Cast",m.GetPos());
m.SIZET(A::LOOPING_SOUND_ID)=SoundEffect::PlayLoopingSFX("Rock Toss Cast",m.GetPos());
CreateBullet(LargeStone)(m.GetPos()+vf2d{0,ConfigFloat("Standard Attack.Stone Throw Height Offset")/2.f},ConfigFloat("Standard Attack.Stone Throw Time"),m.V(A::LOCKON_POS),m.F(A::CASTING_TIMER),ConfigPixels("Standard Attack.Stone Radius"),ConfigFloat("Standard Attack.Stone Throw Height Offset"),acc,ConfigInt("Standard Attack.Stone Damage"),ConfigFloat("Standard Attack.Stone Throw Knockback Factor"),m.OnUpperLevel(),false,INFINITY,false,WHITE,vf2d{1,1}*m.GetSizeMult(),util::random(2*PI))EndBullet;
}
CreateBullet(LargeStone)(m.GetPos()+vf2d{0,ConfigFloat("Standard Attack.Stone Throw Height Offset")/2.f},ConfigFloat("Standard Attack.Stone Throw Time"),m.V(A::LOCKON_POS),m.F(A::CASTING_TIMER),ConfigPixels("Standard Attack.Stone Radius"),ConfigFloat("Standard Attack.Stone Throw Height Offset"),acc,ConfigInt("Standard Attack.Stone Damage"),ConfigFloat("Standard Attack.Stone Throw Knockback Factor"),m.OnUpperLevel(),false,INFINITY,false,WHITE,vf2d{1,1}*m.GetSizeMult(),util::random(2*PI))EndBullet;
}else{
m.phase=BEAR_ATTACK;
}
}break;
case STONE_THROW_CAST:{
@ -293,6 +292,18 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
PrepareSafeAreas(); //Recalculate safe areas if the shockwave attack is going off.
m.phase=SHOCKWAVE;
}else m.F(A::SAFE_AREA_WAIT_TIMER)-=fElapsedTime;
};
}break;
case BEAR_ATTACK:{
BEAR(m,fElapsedTime,"Bear");
//Extending the bear script's variables to read the state of it...
const bool SlamHasFinished=m.I(A::ATTACK_COUNT)!=m.I(A::BEAR_STOMP_COUNT); //The bear script uses the internal phase variable to determine the state of things.
if(SlamHasFinished){
m.phase=STANDARD;
m.I(A::ATTACK_COUNT)=m.I(A::BEAR_STOMP_COUNT);
}else
if(m.I(A::PHASE)==0){
//Walking towards... If 7 seconds or more occurs here, fallback to a different plan.
}
}break;
}
}

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3
#define VERSION_BUILD 9974
#define VERSION_BUILD 9979
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -943,7 +943,7 @@ MonsterStrategy
Stone Throw Time = 0.75s
Stone Throw Knockback Factor = 250
Stone Throw Spell Circle Color = 40, 40, 40, 80
Stone Throw Spell Circle Color = 255, 40, 40, 60
Stone Throw Spell Insignia Color = 144, 137, 160, 255
# Degrees/sec. Positive is CW, Negative is CCW.
Stone Throw Spell Circle Rotation Spd = -30

Loading…
Cancel
Save