Finish stone throw phase/animation for 2nd chapter boss. Adjust animation frames slightly. Correct stone positioning of rock before throw. Rock throw no longer continues rerolling every game frame while Bear AI is running. Release Build 9648.

This commit is contained in:
sigonasr2 2024-06-18 09:47:18 -05:00
parent eb3562eca3
commit 0fd1d5ee8a
6 changed files with 33 additions and 18 deletions

View File

@ -340,7 +340,6 @@ bool Monster::Update(float fElapsedTime){
if(&*m==this)continue;
if(!m->HasIframes()&&OnUpperLevel()==m->OnUpperLevel()&&abs(m->GetZ()-GetZ())<=1&&geom2d::overlaps(geom2d::circle(pos,monsterRadius),geom2d::circle(m->GetPos(),otherMonsterRadius))){
m->Collision(*this);
if(IsSolid())continue; //Solid objects don't need any movement/knockback processing and can be ignored from here on out.
geom2d::line line(pos,m->GetPos());
float dist = line.length();
while(dist<=0.001){
@ -349,6 +348,7 @@ bool Monster::Update(float fElapsedTime){
}
const float displacementDist=(otherMonsterRadius+monsterRadius)-dist;
if(m->IsAlive()){
const bool BothAreSolid=IsSolid()&&m->IsSolid();
if(!m->IsSolid()){
float knockbackStrength=1.f;
std::vector<Buff> knockbackBuffs=m->GetBuffs(COLLISION_KNOCKBACK_STRENGTH);
@ -357,7 +357,7 @@ bool Monster::Update(float fElapsedTime){
}
Knockback(line.vector().norm()*-128*knockbackStrength);
}else
if(!IgnoresTerrainCollision()){
if(!IgnoresTerrainCollision()||BothAreSolid){
SetPos(line.rpoint(-displacementDist));
}
}

View File

@ -54,6 +54,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
SPAWN_PILLAR_CAST,
STANDARD,
STONE_THROW_CAST,
STONE_THROW_FINISH_ANIMATION,
};
switch(m.phase){
@ -91,24 +92,38 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
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);
const bool StoneThrowRollSucceeds=util::random(100.f)<=ConfigFloat("Standard Attack.Stone Throw Chance");
if(SlamHasFinished&&StoneThrowRollSucceeds){
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(SlamHasFinished){
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);
//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)};
CreateBullet(LargeStone)(m.GetPos()+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;
}
}
}break;
case STONE_THROW_CAST:{
m.F(A::CASTING_TIMER)-=fElapsedTime;
if(m.F(A::CASTING_TIMER)<=0.f){
m.PerformAnimation("TOSS ROCK");
m.F(A::RECOVERY_TIME)=m.GetCurrentAnimation().GetTotalAnimationDuration();
m.phase=STONE_THROW_FINISH_ANIMATION;
}
}break;
case STONE_THROW_FINISH_ANIMATION:{
m.F(A::RECOVERY_TIME)-=fElapsedTime;
if(m.F(A::RECOVERY_TIME)<=0.f){
m.phase=STANDARD;
}
}break;
}
}

View File

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

View File

@ -922,7 +922,7 @@ MonsterStrategy
# How high in the air the rock starts at from the GROUND.
Stone Throw Height Offset = 160pixels
Stone Throw Time = 0.75s
Stone Throw Knockback Factor = 80
Stone Throw Knockback Factor = 250
Stone Throw Spell Circle Color = 40, 40, 40, 80
Stone Throw Spell Insignia Color = 144, 137, 160, 255

View File

@ -1040,7 +1040,7 @@ Monsters
RISE FROM UNDERGROUND = 5, 0.15, OneShot
TOSS ROCK CAST = 2, 0.2, Repeat
SLAM = 3, 0.15, OneShot
TOSS ROCK = 4, 0.2, OneShot
TOSS ROCK = 3, 0.2, OneShot
}
Ignore Collisions = True