diff --git a/Adventures in Lestoria/GiantOctopus.cpp b/Adventures in Lestoria/GiantOctopus.cpp index fd3e1632..23990d19 100644 --- a/Adventures in Lestoria/GiantOctopus.cpp +++ b/Adventures in Lestoria/GiantOctopus.cpp @@ -53,6 +53,18 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s IDENTIFY_ARMS, NORMAL, }; + + if(!m.B(A::ARM_SPEEDS_INCREASED)&&m.GetHealth()<=ConfigInt("Arm Speedup Health Threshold")){ + m.B(A::ARM_SPEEDS_INCREASED)=true; + for(std::shared_ptr&arm:MONSTER_LIST){ + const std::string OCTOPUS_ARM_NAME{"Octopus Arm"}; + if(arm->GetName()==OCTOPUS_ARM_NAME){ + std::weak_ptrarmPtr{arm}; + if(!armPtr.expired())armPtr.lock()->GetFloat(A::ATTACK_ANIMATION_SPEED)=1.f+ConfigFloat("Arm Animation Speed Increase")/100.f; + } + } + } + switch(PHASE()){ case INIT:{ m.F(A::BREAK_TIME)=0.5f; @@ -101,7 +113,6 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s randomArm.lock()->GetFloat(A::RECOVERY_TIME)=randomArm.lock()->GetCurrentAnimation().GetTotalAnimationDuration(); randomArm.lock()->SetCollisionRadius(0.f); randomArm.lock()->V(A::JUMP_TARGET_POS)=randomLoc; - LOG(std::format("Random chosen location set to {}",randomLoc.str())); } m.F(A::CASTING_TIMER)=util::random_range(ConfigFloatArr("Arm Move Timer",0),ConfigFloatArr("Arm Move Timer",1)); } diff --git a/Adventures in Lestoria/MonsterAttribute.h b/Adventures in Lestoria/MonsterAttribute.h index 3f847cfb..71ee9e57 100644 --- a/Adventures in Lestoria/MonsterAttribute.h +++ b/Adventures in Lestoria/MonsterAttribute.h @@ -158,4 +158,6 @@ enum class Attribute{ ARM_LIST, SUBMERGE_LOCATION, SUBMERGE_STRAT_ID, + ATTACK_ANIMATION_SPEED, + ARM_SPEEDS_INCREASED, }; \ No newline at end of file diff --git a/Adventures in Lestoria/OctopusArm.cpp b/Adventures in Lestoria/OctopusArm.cpp index c5bcd6b6..1d02e6c7 100644 --- a/Adventures in Lestoria/OctopusArm.cpp +++ b/Adventures in Lestoria/OctopusArm.cpp @@ -72,14 +72,17 @@ void Monster::STRATEGY::OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string str if(m.F(A::ENVIRONMENT_TIMER)<=0.f)m.ANY(A::STORED_ARC).reset(); } + fElapsedTime*=m.F(A::ATTACK_ANIMATION_SPEED); + switch(PHASE()){ case INIT:{ m.I(A::SUBMERGE_STRAT_ID)=SUBMERGE; + m.F(A::ATTACK_ANIMATION_SPEED)=1.f; if(ConfigFloat("Attack Swing Damage Wait Time")>m.GetAnimation("ATTACKING").GetTotalAnimationDuration())ERR(std::format("The Attack Swing Damage Wait Time ({}s) should not be greater than the total attack time animation duration! ({}s)",ConfigFloat("Attack Swing Damage Wait Time"),m.GetAnimation("ATTACKING").GetTotalAnimationDuration())); m.PerformAnimation("RISE",game->GetPlayer()->GetPos()); m.F(A::CASTING_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); SETPHASE(RISE_ANIMATION); - m.SetStrategyDeathFunction([deathFadeTime=ConfigFloat("Death Fade Time"),bossDamageOnDeath=ConfigInt("Boss Damage On Death")](GameEvent&event,Monster&m,const StrategyName&strategyName){ + m.SetStrategyDeathFunction([deathFadeTime=ConfigFloat("Death Fade Time"),bossDamageOnDeath=ConfigInt("Boss Damage On Death"),armHealAmtOnDeath=ConfigInt("Arm Heal Amount On Death"),reemergeWaitTime=ConfigFloat("Re-Emerge Wait Time"),delayTimeIncreasePerArm=ConfigFloat("Delay Time Increase Per Arm"),armAttackBuffOnDeath=ConfigFloat("Arm Attack Buff On Death"),bossAttackBuffOnDeath=ConfigFloat("Boss Attack Buff On Death")](GameEvent&event,Monster&m,const StrategyName&strategyName){ m.SetStrategyDrawFunction([](AiL*game,Monster&monster,const std::string&strategy){}); const std::string GIANT_OCTOPUS_NAME{"Giant Octopus"}; const std::string OCTOPUS_ARM_NAME{"Octopus Arm"}; @@ -93,12 +96,41 @@ void Monster::STRATEGY::OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string str Monster&bossMonster{**boss}; bossMonster._DealTrueDamage(bossDamageOnDeath); } - std::for_each(MONSTER_LIST.begin(),MONSTER_LIST.end(),[&OCTOPUS_ARM_NAME,&strategyName](const std::shared_ptr&m){ + float delayTimePerArm{0.f}; + std::for_each(MONSTER_LIST.begin(),MONSTER_LIST.end(),[&OCTOPUS_ARM_NAME,&GIANT_OCTOPUS_NAME,&strategyName,&armHealAmtOnDeath,&reemergeWaitTime,&delayTimeIncreasePerArm,&delayTimePerArm,&armAttackBuffOnDeath,&bossAttackBuffOnDeath](const std::shared_ptr&m){ if(m->GetName()==OCTOPUS_ARM_NAME){ m->PerformAnimation("SUBMERGE"); m->SetPhase(strategyName,SUBMERGE); m->V(A::JUMP_TARGET_POS)=m->GetPos(); - m->GetFloat(A::RECOVERY_TIME)=m->GetCurrentAnimation().GetTotalAnimationDuration(); + m->SetCollisionRadius(0.f); + if(!m->IsDead())m->Heal(armHealAmtOnDeath,true); + m->GetFloat(A::RECOVERY_TIME)=reemergeWaitTime+delayTimePerArm; + if(m->HasBuff(BuffType::STAT_UP)){ + bool found{false}; + for(Buff&b:m->EditBuffs(BuffType::STAT_UP)){ + for(const ItemAttribute&attr:b.attr){ + if(attr.ActualName()=="Attack %"){ + found=true; + b.intensity+=armAttackBuffOnDeath/100.f; + } + } + } + if(!found)m->AddBuff(BuffType::STAT_UP,INFINITE,armAttackBuffOnDeath/100.f,{"Attack %"}); + }else m->AddBuff(BuffType::STAT_UP,INFINITE,armAttackBuffOnDeath/100.f,{"Attack %"}); + delayTimePerArm+=delayTimeIncreasePerArm; + }else if(m->GetName()==GIANT_OCTOPUS_NAME){ + if(m->HasBuff(BuffType::STAT_UP)){ + bool found{false}; + for(Buff&b:m->EditBuffs(BuffType::STAT_UP)){ + for(const ItemAttribute&attr:b.attr){ + if(attr.ActualName()=="Attack %"){ + found=true; + b.intensity+=bossAttackBuffOnDeath/100.f; + } + } + } + if(!found)m->AddBuff(BuffType::STAT_UP,INFINITE,bossAttackBuffOnDeath/100.f,{"Attack %"}); + }else m->AddBuff(BuffType::STAT_UP,INFINITE,bossAttackBuffOnDeath/100.f,{"Attack %"}); } }); @@ -176,9 +208,7 @@ void Monster::STRATEGY::OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string str m.F(A::RECOVERY_TIME)-=fElapsedTime; if(m.F(A::RECOVERY_TIME)<=0.f){ m.PerformAnimation("RISE"); - LOG(std::format("Moved from {}",m.GetPos().str())); m.SetPos(m.V(A::JUMP_TARGET_POS)); - LOG(std::format("to {}. Expected to go to {}",m.GetPos().str(),m.V(A::JUMP_TARGET_POS).str())); m.F(A::CASTING_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); SETPHASE(RISE_ANIMATION); } diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 5b963f3d..b2b64b52 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 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 11848 +#define VERSION_BUILD 11852 #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 4f078b0d..2eb4bb23 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -1219,6 +1219,19 @@ MonsterStrategy Attack Effect Time = 0.4s Death Fade Time = 1s + + # Amount of health to recover each time another arm dies. + Arm Heal Amount On Death = 1000hp + + # Amount of time to wait after kills before re-emerging. + Re-Emerge Wait Time = 3s + + # Amount of wait time between each arm rising back up. + Delay Time Increase Per Arm = 0.25s + + # Boost to attack stats on each arm death. + Arm Attack Buff On Death = 10% + Boss Attack Buff On Death = 10% } Giant Octopus { @@ -1230,5 +1243,11 @@ MonsterStrategy # How resistant the boss is to attacks. Permanent Resistance Buff = 80% + + # Amount of health the boss needs to have for the arms to have a sped up animation. + Arm Speedup Health Threshold = 12000hp + + # Speed at which attacks come out when boss is below the health threshold. + Arm Animation Speed Increase = 10% } } \ No newline at end of file diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 8e343f8a..c4cc2b33 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ