diff --git a/Adventures in Lestoria/Effect.cpp b/Adventures in Lestoria/Effect.cpp index daeca148..81118474 100644 --- a/Adventures in Lestoria/Effect.cpp +++ b/Adventures in Lestoria/Effect.cpp @@ -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); } diff --git a/Adventures in Lestoria/StoneGolem.cpp b/Adventures in Lestoria/StoneGolem.cpp index 31021290..23e05536 100644 --- a/Adventures in Lestoria/StoneGolem.cpp +++ b/Adventures in Lestoria/StoneGolem.cpp @@ -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(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(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; } } \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 9be9a123..40faf38a 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -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 diff --git a/Adventures in Lestoria/assets/config/MonsterStrategies.txt b/Adventures in Lestoria/assets/config/MonsterStrategies.txt index 56d35777..f4ed582d 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -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 diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index ca0edb25..eaceab04 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ