diff --git a/Adventures in Lestoria/Bear.cpp b/Adventures in Lestoria/Bear.cpp index a2b5ddf6..3566e72f 100644 --- a/Adventures in Lestoria/Bear.cpp +++ b/Adventures in Lestoria/Bear.cpp @@ -52,11 +52,11 @@ INCLUDE_MONSTER_DATA using A=Attribute; void Monster::STRATEGY::BEAR(Monster&m,float fElapsedTime,std::string strategy){ - switch(m.I(A::PHASE)){ + switch(PHASE()){ case 0:{ float distToPlayer=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).length(); if(distToPlayer(m.GetPos(),game->GetPlayer()->GetPos()).length(); SoundEffect::PlaySFX("Bear Slam Attack",m.GetPos()+m.V(A::LOCKON_POS).cart()); - m.I(A::PHASE)=0; + SETPHASE(0); m.I(A::BEAR_STOMP_COUNT)++; geom2d::circleattackCircle={m.GetPos()+m.V(A::LOCKON_POS).cart(),float(operator""_Pixels(ConfigFloat("Smash Attack Diameter"))/2.f)}; if(geom2d::overlaps(attackCircle,game->GetPlayer()->Hitbox())){ diff --git a/Adventures in Lestoria/Boar.cpp b/Adventures in Lestoria/Boar.cpp index 09ee1a4d..16bd5a85 100644 --- a/Adventures in Lestoria/Boar.cpp +++ b/Adventures in Lestoria/Boar.cpp @@ -57,7 +57,7 @@ void Monster::STRATEGY::BOAR(Monster&m,float fElapsedTime,std::string strategy){ RECOVERY, }; - switch(m.phase){ + switch(PHASE()){ case PhaseName::MOVE:{ float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos()); if(m.canMove&&distToPlayer>=ConfigInt("Closein Range")/100.f*24){ @@ -75,7 +75,7 @@ void Monster::STRATEGY::BOAR(Monster&m,float fElapsedTime,std::string strategy){ ScratchPhaseTransition: m.PerformAnimation("SCRATCH"); m.F(A::CASTING_TIMER)=ConfigInt("Ground Scratch Count")*m.GetCurrentAnimation().GetTotalAnimationDuration(); - m.phase=PhaseName::SCRATCH; + SETPHASE(PhaseName::SCRATCH); vf2d chargeTargetPoint=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).rpoint(ConfigFloat("Charge Distance")/100.f*24); float distanceToChargePoint=geom2d::line(m.GetPos(),chargeTargetPoint).length(); @@ -89,7 +89,7 @@ void Monster::STRATEGY::BOAR(Monster&m,float fElapsedTime,std::string strategy){ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0.f){ m.PerformShootAnimation(); - m.phase=PhaseName::CHARGE; + SETPHASE(PhaseName::CHARGE); m.AddBuff(BuffType::SPEEDBOOST,INFINITE,ConfigFloat("Charge Movespeed")/100.f-1); @@ -102,7 +102,7 @@ void Monster::STRATEGY::BOAR(Monster&m,float fElapsedTime,std::string strategy){ float distToTarget=geom2d::line(m.GetPos(),m.target).length(); auto TransitionToRecoveryPhase=[&](){ - m.phase=PhaseName::RECOVERY; + SETPHASE(PhaseName::RECOVERY); m.F(A::CHARGE_COOLDOWN)=ConfigFloat("Charge Recovery Time"); m.PerformIdleAnimation(); }; @@ -120,7 +120,7 @@ void Monster::STRATEGY::BOAR(Monster&m,float fElapsedTime,std::string strategy){ m.F(A::CHARGE_COOLDOWN)-=fElapsedTime; m.targetAcquireTimer=0.f; m.RemoveBuff(BuffType::SPEEDBOOST); - if(m.F(A::CHARGE_COOLDOWN)<=0)m.phase=PhaseName::MOVE; + if(m.F(A::CHARGE_COOLDOWN)<=0)SETPHASE(PhaseName::MOVE); }break; } } \ No newline at end of file diff --git a/Adventures in Lestoria/BreakingPillar.cpp b/Adventures in Lestoria/BreakingPillar.cpp index f61e3e81..5f54f8a7 100644 --- a/Adventures in Lestoria/BreakingPillar.cpp +++ b/Adventures in Lestoria/BreakingPillar.cpp @@ -56,11 +56,11 @@ void Monster::STRATEGY::BREAKING_PILLAR(Monster&m,float fElapsedTime,std::string m.animation.ModifyDisplaySprite(m.internal_animState,ConfigString("Break Phase 1 Animation Name")); }else m.animation.ModifyDisplaySprite(m.internal_animState,ConfigString("Break Phase 2 Animation Name")); - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::BREAK_TIME)=ConfigFloat("Break Time"); m.F(A::SHAKE_TIMER)=0.2f; - m.phase=RUN; + SETPHASE(RUN); m.SetStrategyDeathFunction([&](GameEvent&deathEvent,Monster&m,const std::string&strategy){ m.lifetime=0.01f; diff --git a/Adventures in Lestoria/DamageNumber.cpp b/Adventures in Lestoria/DamageNumber.cpp index 763996fc..8840c26e 100644 --- a/Adventures in Lestoria/DamageNumber.cpp +++ b/Adventures in Lestoria/DamageNumber.cpp @@ -143,7 +143,7 @@ void DamageNumber::Draw(){ float DamageNumber::GetOriginalRiseSpd(){ float riseSpd{20.f}; - if(type==INTERRUPT||type==MANA_GAIN)riseSpd=40.f; + if(type==INTERRUPT||type==MANA_GAIN||type==HEALTH_GAIN)riseSpd=40.f; if(type==DOT)riseSpd=-10.f; return riseSpd; } diff --git a/Adventures in Lestoria/Frog.cpp b/Adventures in Lestoria/Frog.cpp index c733a77a..7292b714 100644 --- a/Adventures in Lestoria/Frog.cpp +++ b/Adventures in Lestoria/Frog.cpp @@ -51,11 +51,11 @@ using A=Attribute; void Monster::STRATEGY::FROG(Monster&m,float fElapsedTime,std::string strategy){ m.F(A::LOCKON_WAITTIME)=std::max(0.0f,m.F(A::LOCKON_WAITTIME)-fElapsedTime); phase: - switch(m.I(A::PHASE)){ + switch(PHASE()){ case 0:{ //Move towards phase. float distToPlayer=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).length(); if(distToPlayer<24*ConfigInt("Range")/100.f){ - m.I(A::PHASE)++; + SETPHASE(PHASE()+1); m.F(A::LOCKON_WAITTIME)=ConfigFloat("Lockon Wait Time"); m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos(); m.RotateTowardsPos(m.V(A::LOCKON_POS)); @@ -72,23 +72,23 @@ void Monster::STRATEGY::FROG(Monster&m,float fElapsedTime,std::string strategy){ SoundEffect::PlaySFX("Slime Shoot",m.pos); CreateBullet(FrogTongue)(m,tongueMaxRangePos,ConfigFloat("Attack Duration"),m.GetAttack(),m.OnUpperLevel(),ConfigFloat("Tongue Knockback Strength"),false,ConfigPixel("Tongue Color"))EndBullet; m.PerformShootAnimation(); - m.I(A::PHASE)=2; + SETPHASE(2); } m.PerformIdleAnimation(); }break; case 2:{ if(m.F(A::LOCKON_WAITTIME)==0.0f){ m.F(A::LOCKON_WAITTIME)=ConfigFloat("Attack Recovery Time"); - m.I(A::PHASE)=3; + SETPHASE(3); } }break; case 3:{ if(m.F(A::LOCKON_WAITTIME)==0.0f){ - m.I(A::PHASE)=0; + SETPHASE(0); } }break; default:{ - ERR(std::format("Unhandled phase {} for {} strategy!",m.I(A::PHASE),strategy)); + ERR(std::format("Unhandled phase {} for {} strategy!",PHASE(),strategy)); } } } \ No newline at end of file diff --git a/Adventures in Lestoria/Goblin_Bomb.cpp b/Adventures in Lestoria/Goblin_Bomb.cpp index a25a156a..525b4eaa 100644 --- a/Adventures in Lestoria/Goblin_Bomb.cpp +++ b/Adventures in Lestoria/Goblin_Bomb.cpp @@ -60,10 +60,10 @@ void Monster::STRATEGY::GOBLIN_BOMB(Monster&m,float fElapsedTime,std::string str RUN, }; - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::SHOOT_TIMER)=m.randomFrameOffset; - m.phase=RUN; + SETPHASE(RUN); }break; case RUN:{ m.F(A::SHOOT_TIMER)+=fElapsedTime; diff --git a/Adventures in Lestoria/Goblin_Bow.cpp b/Adventures in Lestoria/Goblin_Bow.cpp index f0216077..cdafd4be 100644 --- a/Adventures in Lestoria/Goblin_Bow.cpp +++ b/Adventures in Lestoria/Goblin_Bow.cpp @@ -66,10 +66,10 @@ void Monster::STRATEGY::GOBLIN_BOW(Monster&m,float fElapsedTime,std::string stra }; #pragma endregion - switch(m.phase){ + switch(PHASE()){ case INITIALIZE_PERCEPTION:{ m.F(A::PERCEPTION_LEVEL)=ConfigFloat("Starting Perception Level"); - m.phase=MOVE; + SETPHASE(MOVE); }break; case MOVE:{ m.F(A::ATTACK_COOLDOWN)+=fElapsedTime; @@ -79,7 +79,7 @@ void Monster::STRATEGY::GOBLIN_BOW(Monster&m,float fElapsedTime,std::string stra const bool outsideMaxShootingRange=distToPlayer>=ConfigPixelsArr("Stand Still and Shoot Range",1); auto PrepareToShoot=[&](){ - m.phase=LOCKON; + SETPHASE(LOCKON); m.F(A::SHOOT_TIMER)=ConfigFloat("Attack Windup Time"); m.PerformAnimation("SHOOT",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); @@ -118,7 +118,7 @@ void Monster::STRATEGY::GOBLIN_BOW(Monster&m,float fElapsedTime,std::string stra m.V(A::EXTENDED_LINE)=extendedLine; Arrow tempArrow{m.GetPos(),extendedLine,pointTowardsPlayer.vector().norm()*ConfigFloat("Arrow Spd"),"goblin_arrow.png",ConfigFloat("Arrow Hitbox Radius"),m.GetAttack(),m.OnUpperLevel()}; m.V(A::FIRE_VELOCITY)=tempArrow.PointToBestTargetPath(m.F(A::PERCEPTION_LEVEL)); - m.phase=WINDUP; + SETPHASE(WINDUP); } }break; case WINDUP:{ @@ -128,7 +128,7 @@ void Monster::STRATEGY::GOBLIN_BOW(Monster&m,float fElapsedTime,std::string stra CreateBullet(Arrow)(m.GetPos(),m.V(A::EXTENDED_LINE),m.V(A::FIRE_VELOCITY),"goblin_arrow.png",ConfigFloat("Arrow Hitbox Radius"),m.GetAttack(),m.OnUpperLevel())EndBullet; m.F(A::PERCEPTION_LEVEL)=std::min(ConfigFloat("Maximum Perception Level"),m.F(A::PERCEPTION_LEVEL)+ConfigFloat("Perception Level Increase")); m.PerformAnimation("IDLE",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); - m.phase=MOVE; + SETPHASE(MOVE); } m.B(A::RANDOM_DIRECTION)=util::random()%2; m.F(A::RANDOM_RANGE)=util::random_range(ConfigPixelsArr("Random Direction Range",0),ConfigPixelsArr("Random Direction Range",1)); diff --git a/Adventures in Lestoria/Goblin_Dagger.cpp b/Adventures in Lestoria/Goblin_Dagger.cpp index 9640dbd9..434903b7 100644 --- a/Adventures in Lestoria/Goblin_Dagger.cpp +++ b/Adventures in Lestoria/Goblin_Dagger.cpp @@ -66,13 +66,13 @@ void Monster::STRATEGY::GOBLIN_DAGGER(Monster&m,float fElapsedTime,std::string s SLASH }; - switch(m.phase){ + switch(PHASE()){ case MOVE:{ float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos()); if(distToPlayer>ConfigFloat("Attack Spacing")/100.f*24){ RUN_TOWARDS(m,fElapsedTime,"Run Towards"); }else{ - m.phase=WINDUP; + SETPHASE(WINDUP); m.I(A::ATTACK_TYPE)=util::random()%2; //Choose randomly between stab or slash. switch(m.I(A::ATTACK_TYPE)){ case STAB:{ @@ -90,7 +90,7 @@ void Monster::STRATEGY::GOBLIN_DAGGER(Monster&m,float fElapsedTime,std::string s case WINDUP:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){ - m.phase=RECOVERY; + SETPHASE(RECOVERY); switch(m.I(A::ATTACK_TYPE)){ case STAB:{ vf2d stabTarget=game->GetPlayer()->GetPos(); @@ -113,7 +113,7 @@ void Monster::STRATEGY::GOBLIN_DAGGER(Monster&m,float fElapsedTime,std::string s m.F(A::CASTING_TIMER)-=fElapsedTime; m.F(A::RECOVERY_TIME)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));} - if(m.F(A::RECOVERY_TIME)<=0)m.phase=MOVE; + if(m.F(A::RECOVERY_TIME)<=0)SETPHASE(MOVE); }break; } } \ No newline at end of file diff --git a/Adventures in Lestoria/Hawk.cpp b/Adventures in Lestoria/Hawk.cpp index 75b48dc9..682d224a 100644 --- a/Adventures in Lestoria/Hawk.cpp +++ b/Adventures in Lestoria/Hawk.cpp @@ -63,11 +63,11 @@ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){ m.SetZ(std::max(float(m.F(A::FLYING_HEIGHT)+ConfigFloat("Flight Oscillation Amount")*sin((PI*m.TimeSpentAlive())/1.5f)),0.f)); #pragma endregion - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::TARGET_FLYING_HEIGHT)=m.F(A::FLYING_HEIGHT)=ConfigFloat("Flight Height")-ConfigFloat("Flight Height Variance")+util::random_range(0,ConfigFloat("Flight Height Variance")*2); m.B(A::RANDOM_DIRECTION)=int(util::random_range(0,2)); - m.phase=FLYING; + SETPHASE(FLYING); m.AddBuff(BuffType::SELF_INFLICTED_SLOWDOWN,INFINITE,util::random_range(0,ConfigFloat("Flight Speed Variance")/100)); m.F(A::ATTACK_COOLDOWN)=util::random_range(1.f,ConfigFloat("Flight Charge Cooldown")); }break; @@ -76,7 +76,7 @@ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){ if(m.F(A::FLYING_HEIGHT)GetPlayer()->GetPos(),m.GetPos()).polar().y}; dirToPlayer+=m.B(A::RANDOM_DIRECTION)?0.25*PI:-0.25*PI; @@ -89,7 +89,7 @@ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){ m.UpdateFacingDirection(game->GetPlayer()->GetPos()); m.PerformAnimation("ATTACK"); if(m.F(A::CASTING_TIMER)<=0){ - m.phase=CHARGE; + SETPHASE(CHARGE); m.PerformAnimation("ATTACKING"); m.target=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).rpoint(ConfigFloat("Flight Distance")*2.f); m.UpdateFacingDirection(m.target); @@ -103,7 +103,7 @@ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){ float distToTarget=geom2d::line(m.GetPos(),m.target).length(); if(distToTarget<12.f){ m.F(A::TARGET_FLYING_HEIGHT)=ConfigFloat("Flight Height")-ConfigFloat("Flight Height Variance")+util::random_range(0,ConfigFloat("Flight Height Variance")*2); - m.phase=FLYING; + SETPHASE(FLYING); m.F(A::ATTACK_COOLDOWN)=ConfigFloat("Flight Charge Cooldown"); m.PerformJumpAnimation(); } diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index 42469382..36cbc5b6 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -81,6 +81,7 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob): randomFrameOffset=(util::random()%1000)/1000.f; monsterWalkSoundTimer=util::random(1.f); UpdateFacingDirection(game->GetPlayer()->GetPos()); + animation.UpdateState(internal_animState,randomFrameOffset); } const vf2d&Monster::GetPos()const{ return pos; @@ -284,8 +285,8 @@ void Monster::Update(const float fElapsedTime){ unconsciousTimer=std::max(0.f,unconsciousTimer-fElapsedTime); if(unconsciousTimer==0.f){ Heal(GetMaxHealth()); + PerformIdleAnimation(); } - } if(IsSolid()&&FadeoutWhenStandingBehind()){ @@ -402,7 +403,7 @@ void Monster::Update(const float fElapsedTime){ } if(!game->TestingModeEnabled()&&CanMove())Monster::STRATEGY::RUN_STRATEGY(*this,fElapsedTime); } - animation.UpdateState(internal_animState,randomFrameOffset+fElapsedTime); + animation.UpdateState(internal_animState,fElapsedTime); if(HasMountedMonster())mounted_animation.value().UpdateState(internal_mounted_animState,fElapsedTime); attackedByPlayer=false; } @@ -1653,4 +1654,11 @@ const bool Monster::IsUnconscious()const{ } const float Monster::UnconsciousTime()const{ return MONSTER_DATA.at(name).UnconsciousTime(); +} +void Monster::SetPhase(const std::string&strategyName,int phase){ + this->phase[strategyName]=phase; +} +const int Monster::GetPhase(const std::string&strategyName){ + if(!phase.contains(strategyName))phase[strategyName]=0; + return this->phase[strategyName]; } \ No newline at end of file diff --git a/Adventures in Lestoria/Monster.h b/Adventures in Lestoria/Monster.h index 4f85c82d..01cefcb3 100644 --- a/Adventures in Lestoria/Monster.h +++ b/Adventures in Lestoria/Monster.h @@ -60,6 +60,8 @@ enum class Attribute; class GameEvent; +using StrategyName=std::string; + namespace MonsterTests{ class MonsterTest; }; @@ -229,6 +231,8 @@ public: const bool FaceTarget()const; void ResetCurseOfDeathDamage(); void MoveForward(const vf2d&moveForwardVec,const float fElapsedTime); //Moves the monster forward in given vector direction (will be auto-normalized) applying speeed boosts and other proper movement requirements as if you wanted to move on a frame-by-frame basis. + void SetPhase(const std::string&strategyName,int phase); + const int GetPhase(const std::string&strategyName); private: //NOTE: Marking a monster for deletion does not trigger any death events. It just simply removes the monster from the field!! // The way this works is that monsters marked for deletion will cause the monster update loop to detect there's at least one or more monsters that must be deleted and will call erase_if on the list at the end of the iteration loop. @@ -273,7 +277,7 @@ private: float spriteRot=0; std::shared_ptrdamageNumberPtr; std::shared_ptrdotNumberPtr; - int phase=0; + std::unordered_mapphase{}; //NOTE: THIS SHOULD NOT BE MODIFIED DIRECTLY!!! Use SetPhase(), GetPhase() / PHASE() SETPHASE() macros! bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die. float targetSize=0; bool isBoss=false; diff --git a/Adventures in Lestoria/MonsterAttribute.h b/Adventures in Lestoria/MonsterAttribute.h index 1f6b58bd..b5ef6e1b 100644 --- a/Adventures in Lestoria/MonsterAttribute.h +++ b/Adventures in Lestoria/MonsterAttribute.h @@ -79,7 +79,6 @@ enum class Attribute{ ITEM_QUANTITY, LAST_INVENTORY_TYPE_OPENED, NEXT_MENU, //Set to 0 for New Game, Set to 1 for Load Game Menu. This is used for the username checks - PHASE, LOCKON_WAITTIME, LOCKON_POS, TARGET_TIMER, @@ -148,4 +147,6 @@ enum class Attribute{ EXTENDED_LINE, ENCHANT, PARROT_FLY_TIMER, + MID_PHASE, + RUM_DRINK_COUNT, }; \ No newline at end of file diff --git a/Adventures in Lestoria/MonsterStrategyHelpers.h b/Adventures in Lestoria/MonsterStrategyHelpers.h index 9f9bf876..9d879637 100644 --- a/Adventures in Lestoria/MonsterStrategyHelpers.h +++ b/Adventures in Lestoria/MonsterStrategyHelpers.h @@ -49,4 +49,7 @@ All rights reserved. #define ConfigIntArr(param,ind) _GetInt(m,param,strategy,ind) #define ConfigFloatArr(param,ind) _GetFloat(m,param,strategy,ind) #define ConfigStringArr(param,ind) _GetString(m,param,strategy,ind) -#define ConfigVecArr(param,ind) _GetVec(m,param,strategy,ind) \ No newline at end of file +#define ConfigVecArr(param,ind) _GetVec(m,param,strategy,ind) + +#define PHASE() m.GetPhase(strategy) +#define SETPHASE(phase) m.SetPhase(strategy,phase) \ No newline at end of file diff --git a/Adventures in Lestoria/NPC.cpp b/Adventures in Lestoria/NPC.cpp index 67aef1ed..c13b99de 100644 --- a/Adventures in Lestoria/NPC.cpp +++ b/Adventures in Lestoria/NPC.cpp @@ -53,7 +53,7 @@ INCLUDE_game INCLUDE_DATA void Monster::STRATEGY::NPC(Monster&m,float fElapsedTime,std::string strategy){ - if(m.phase==0){ //Initialization. + if(PHASE()==0){ //Initialization. if(m.npcData.function.length()>0){ m.SetStrategyDrawOverlayFunction([](AiL*game,Monster&m,const std::string&strategy){ vf2d nameTextSize=game->GetTextSizeProp(m.GetName()); @@ -62,7 +62,7 @@ void Monster::STRATEGY::NPC(Monster&m,float fElapsedTime,std::string strategy){ game->KEY_CONFIRM.DrawPrimaryInput(&game->view,m.GetPos()+vf2d{ConfigFloatArr("Interaction Display Offset",0),ConfigFloatArr("Interaction Display Offset",1)},"Interact",alpha); }); } - m.phase=1; + SETPHASE(1); } float distFromPlayer=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).length(); if(distFromPlayerIsAlive()){ + m.PerformAnimation("FLYING"); + HAWK(m,fElapsedTime,"Hawk"); + }else{ m.lifetime=10.f; - m.phase=FLY_AWAY; + SETPHASE(FLY_AWAY); m.F(A::PATH_DIR)=1.f; if(util::random(1.f)<0.5f)m.F(A::PATH_DIR)=-1.f; m.manualIgnoreTerrain=true; } }break; case FLY_AWAY:{ + if(m.F(A::PATH_DIR)>0.f)m.PerformAnimation("FLYING",Direction::EAST); + else m.PerformAnimation("FLYING",Direction::WEST); m.z+=fElapsedTime*ConfigFloat("Fly Away Z Speed"); m.SetVelocity({m.F(A::PATH_DIR)*ConfigFloat("Fly Away Speed"),0.f}); }break; diff --git a/Adventures in Lestoria/Pirate_Buccaneer.cpp b/Adventures in Lestoria/Pirate_Buccaneer.cpp index 99e3fecb..b149864d 100644 --- a/Adventures in Lestoria/Pirate_Buccaneer.cpp +++ b/Adventures in Lestoria/Pirate_Buccaneer.cpp @@ -49,7 +49,6 @@ INCLUDE_game void Monster::STRATEGY::PIRATE_BUCCANEER(Monster&m,float fElapsedTime,std::string strategy){ #pragma region Phase, Animation, and Helper function setup enum PhaseName{ - INIT, MOVE, LOCKON, WINDUP, @@ -57,10 +56,7 @@ void Monster::STRATEGY::PIRATE_BUCCANEER(Monster&m,float fElapsedTime,std::strin }; #pragma endregion - switch(m.phase){ - case INIT:{ - m.phase=MOVE; - }break; + switch(PHASE()){ case MOVE:{ m.F(A::ATTACK_COOLDOWN)+=fElapsedTime; @@ -69,7 +65,7 @@ void Monster::STRATEGY::PIRATE_BUCCANEER(Monster&m,float fElapsedTime,std::strin const bool outsideMaxShootingRange=distToPlayer>=ConfigPixelsArr("Stand Still and Shoot Range",1); auto PrepareToShoot=[&](){ - m.phase=WINDUP; + SETPHASE(WINDUP); m.F(A::SHOOT_TIMER)=ConfigFloat("Attack Windup Time"); m.PerformAnimation("SHOOT",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); }; @@ -96,7 +92,7 @@ void Monster::STRATEGY::PIRATE_BUCCANEER(Monster&m,float fElapsedTime,std::strin CreateBullet(ChargedArrow)("musket_bullet.png","musket_trail.png",m.GetPos(),util::pointTo(m.GetPos(),m.V(A::LOCKON_POS))*ConfigFloat("Arrow Spd"),ConfigFloat("Arrow Hitbox Radius"),m.GetAttack(),m.OnUpperLevel())EndBullet; m.PerformAnimation("SHOOTING",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); m.SetStrategyDrawFunction([](AiL*game,Monster&monster,const std::string&strategy){}); - m.phase=FIRE_ANIMATION; + SETPHASE(FIRE_ANIMATION); m.F(A::SHOOT_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); }else if(m.F(A::SHOOT_TIMER)>=ConfigFloat("Attack Lockon Time")){ @@ -115,7 +111,7 @@ void Monster::STRATEGY::PIRATE_BUCCANEER(Monster&m,float fElapsedTime,std::strin m.F(A::SHOOT_TIMER)-=fElapsedTime; if(m.F(A::SHOOT_TIMER)<=0.f){ m.PerformAnimation("IDLE",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); - m.phase=MOVE; + SETPHASE(MOVE); } }break; } diff --git a/Adventures in Lestoria/Pirate_Captain.cpp b/Adventures in Lestoria/Pirate_Captain.cpp index 8ba8719d..e5b58989 100644 --- a/Adventures in Lestoria/Pirate_Captain.cpp +++ b/Adventures in Lestoria/Pirate_Captain.cpp @@ -63,12 +63,7 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string SLASH }; - if(!m.B(A::INITIALIZED)){ - m.B(A::INITIALIZED)=true; - m.phase=INIT; - } - - switch(m.phase){ + switch(PHASE()){ case INIT:{ m.F(A::TARGET_TIMER)=ConfigFloat("Shooting Frequency"); m.F(A::PARROT_FLY_TIMER)=ConfigFloat("Parrot Fly Wait Time"); @@ -81,7 +76,7 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string } m.mountedSprOffset=ConfigVec("Imposed Monster Offset"); m.deathData.emplace_back(ConfigString("Spawned Monster"),1U); - m.phase=MOVE; + SETPHASE(MOVE); }break; case MOVE:{ if(m.F(A::PARROT_FLY_TIMER)>0.f){ @@ -99,24 +94,25 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string const float distToPlayer{util::distance(game->GetPlayer()->GetPos(),m.GetPos())}; if(distToPlayer<=ConfigFloat("Shoot Max Range")/100.f*24){ m.F(A::SHOOT_TIMER)=ConfigFloat("Shooting Delay"); - m.phase=PREPARE_SHOOT; + SETPHASE(PREPARE_SHOOT); m.PerformAnimation("SHOOT",game->GetPlayer()->GetPos()); m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos(); } } m.F(A::TARGET_TIMER)=ConfigFloat("Shooting Frequency"); }else - if(m.GetHealth()GetPlayer()->GetPos()); if(distToPlayer>ConfigFloat("Attack Spacing")/100.f*24){ RUN_TOWARDS(m,fElapsedTime,"Run Towards"); }else{ - m.phase=WINDUP; + SETPHASE(WINDUP); m.I(A::ATTACK_TYPE)=util::random()%2; //Choose randomly between stab or slash. switch(m.I(A::ATTACK_TYPE)){ case STAB:{ @@ -138,38 +134,38 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),m.V(A::LOCKON_POS))*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),m.GetAttack(),m.OnUpperLevel(),false,ConfigPixel("Bullet Color"),vf2d{1.f,1.f}*ConfigFloat("Bullet Radius")/3.f)EndBullet; m.PerformAnimation("SHOOTING"); m.F(A::SHOOT_ANIMATION_TIME)=m.GetCurrentAnimation().GetTotalAnimationDuration(); - m.phase=SHOOT_RELOAD; + SETPHASE(SHOOT_RELOAD); } }break; case SHOOT_RELOAD:{ m.F(A::SHOOT_ANIMATION_TIME)-=fElapsedTime; if(m.F(A::SHOOT_ANIMATION_TIME)<=0.f){ m.PerformAnimation("IDLE"); - m.phase=MOVE; + SETPHASE(MOVE); } }break; case DRINK_RUM:{ m.F(A::BREAK_TIME)-=fElapsedTime; if(m.F(A::BREAK_TIME)<=0.f){ m.Heal(ConfigInt("Rum Health Recovery"),true); - m.phase=MOVE; + SETPHASE(MOVE); } }break; case WINDUP:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){ - m.phase=RECOVERY; + SETPHASE(RECOVERY); switch(m.I(A::ATTACK_TYPE)){ case STAB:{ vf2d stabTarget=game->GetPlayer()->GetPos(); - m.PerformAnimation("STABBING",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); - CreateBullet(DaggerStab)(m,ConfigString("Dagger Stab Image"),ConfigFloat("Dagger Hit Radius"),m.GetAttack(),ConfigFloat("Dagger Stab Knockback"),m.OnUpperLevel(),m.GetFacingDirectionToTarget(stabTarget),ConfigFloat("Dagger Frame Duration"),ConfigFloat("Dagger Stab Distance"), + m.PerformAnimation("STABBING"); + CreateBullet(DaggerStab)(m,ConfigString("Dagger Stab Image"),ConfigFloat("Dagger Hit Radius"),m.GetAttack(),ConfigFloat("Dagger Stab Knockback"),m.OnUpperLevel(),m.GetFacingDirection(),ConfigFloat("Dagger Frame Duration"),ConfigFloat("Dagger Stab Distance"), DaggerStab::DirectionOffsets{ConfigVec("Dagger Up Offset"),ConfigVec("Dagger Down Offset"),ConfigVec("Dagger Right Offset"),ConfigVec("Dagger Left Offset")})EndBullet; }break; case SLASH:{ vf2d slashTarget=game->GetPlayer()->GetPos(); - m.PerformAnimation("SLASHING",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); - CreateBullet(DaggerSlash)(m,ConfigString("Dagger Slash Image"),ConfigFloat("Dagger Hit Radius"),m.GetAttack(),ConfigFloat("Dagger Slash Knockback"),m.OnUpperLevel(),m.GetFacingDirectionToTarget(slashTarget),ConfigFloat("Dagger Frame Duration"),ConfigFloat("Dagger Slash Distance"))EndBullet; + m.PerformAnimation("SLASHING"); + CreateBullet(DaggerSlash)(m,ConfigString("Dagger Slash Image"),ConfigFloat("Dagger Hit Radius"),m.GetAttack(),ConfigFloat("Dagger Slash Knockback"),m.OnUpperLevel(),m.GetFacingDirection(),ConfigFloat("Dagger Frame Duration"),ConfigFloat("Dagger Slash Distance"))EndBullet; }break; default:ERR(std::format("WARNING! Invalid Attack type {} provided. THIS SHOULD NOT BE HAPPENING!",m.I(A::ATTACK_TYPE))); } @@ -181,7 +177,7 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string m.F(A::CASTING_TIMER)-=fElapsedTime; m.F(A::RECOVERY_TIME)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));} - if(m.F(A::RECOVERY_TIME)<=0)m.phase=MOVE; + if(m.F(A::RECOVERY_TIME)<=0)SETPHASE(MOVE); }break; } } \ No newline at end of file diff --git a/Adventures in Lestoria/Pirate_Marauder.cpp b/Adventures in Lestoria/Pirate_Marauder.cpp index 99b74974..fcfe1f0f 100644 --- a/Adventures in Lestoria/Pirate_Marauder.cpp +++ b/Adventures in Lestoria/Pirate_Marauder.cpp @@ -57,10 +57,10 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string WHIRLWIND, }; - switch(m.phase){ + switch(PHASE()){ case INIT:{ m.F(A::CHASE_TIMER)=ConfigFloat("Ability Choose Timer"); - m.phase=MOVE; + SETPHASE(MOVE); }break; case MOVE:{ float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos()); @@ -78,7 +78,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string std::pairwhirlwindAttackRollRange{jumpAttackRollRange.second,jumpAttackRollRange.second+ConfigFloat("Whirlwind Attack Chance")}; if(roll=ConfigFloatArr("Jump Attack Ranges",0)/100.f*24.f&&distanceToPlayer<=ConfigFloatArr("Jump Attack Ranges",1)/100.f*24.f){ - m.phase=LEAP; + SETPHASE(LEAP); m.V(A::JUMP_TARGET_POS)=game->GetPlayer()->GetPos(); m.I(A::ABILITY_COUNT)--; const float impactArea{ConfigFloat("Jump Attack Impact Area")}; @@ -92,7 +92,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string }else if(roll>=whirlwindAttackRollRange.first&&roll=ConfigFloatArr("Whirlwind Attack Ranges",0)/100.f*24.f&&distanceToPlayer<=ConfigFloatArr("Whirlwind Attack Ranges",1)/100.f*24.f){ - m.phase=PREPARE_WHIRLWIND; + SETPHASE(PREPARE_WHIRLWIND); m.I(A::ABILITY_COUNT)--; vf2d aimingTarget{game->GetPlayer()->GetPos()}; if(aimingTarget==m.GetPos()){ //Handle edge case. @@ -109,7 +109,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string if(distToPlayer>ConfigFloat("Attack Spacing")/100.f*24){ RUN_TOWARDS(m,fElapsedTime,"Run Towards"); }else{ - m.phase=WINDUP; + SETPHASE(WINDUP); m.F(A::CASTING_TIMER)=ConfigFloat("Slash Windup Time"); m.PerformAnimation("SLASH",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); } @@ -117,7 +117,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string case WINDUP:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){ - m.phase=RECOVERY; + SETPHASE(RECOVERY); vf2d slashTarget=game->GetPlayer()->GetPos(); m.PerformAnimation("SLASHING",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); CreateBullet(DaggerSlash)(m,ConfigString("Dagger Slash Image"),ConfigFloat("Dagger Hit Radius"),m.GetAttack(),ConfigFloat("Dagger Slash Knockback"),m.OnUpperLevel(),m.GetFacingDirectionToTarget(slashTarget),ConfigFloat("Dagger Frame Duration"),ConfigFloat("Dagger Slash Distance"))EndBullet; @@ -129,7 +129,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string m.F(A::CASTING_TIMER)-=fElapsedTime; m.F(A::RECOVERY_TIME)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0){m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));} - if(m.F(A::RECOVERY_TIME)<=0)m.phase=MOVE; + if(m.F(A::RECOVERY_TIME)<=0)SETPHASE(MOVE); }break; case LEAP:{ m.F(A::JUMP_MOVE_TO_TARGET_TIMER)+=fElapsedTime; @@ -143,7 +143,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string game->ProximityKnockback(m.GetPos(),ConfigFloat("Jump Attack Impact Area")/100.f*24.f,ConfigFloat("Jump Attack Knockback Amount"),HurtType::MONSTER|HurtType::PLAYER); m.SetZ(0.f); m.SetPos(m.V(A::JUMP_TARGET_POS)); - m.phase=MOVE; + SETPHASE(MOVE); m.PerformIdleAnimation(); m.SetStrategyDrawFunction([](AiL*game,Monster&monster,const std::string&strategy){}); } @@ -151,7 +151,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string case PREPARE_WHIRLWIND:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0.f){ - m.phase=WHIRLWIND; + SETPHASE(WHIRLWIND); m.F(A::CHASE_TIMER)=0.f; m.PerformAnimation("SPINNING"); } @@ -159,7 +159,7 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string case WHIRLWIND:{ m.F(A::CHASE_TIMER)+=fElapsedTime; if(m.F(A::CHASE_TIMER)>=ConfigFloat("Whirlwind Spin Time")){ - m.phase=MOVE; + SETPHASE(MOVE); m.PerformIdleAnimation(); } m.MoveForward(m.V(A::PATH_DIR),fElapsedTime); diff --git a/Adventures in Lestoria/SlimeKing.cpp b/Adventures in Lestoria/SlimeKing.cpp index a79a6158..c7f3001b 100644 --- a/Adventures in Lestoria/SlimeKing.cpp +++ b/Adventures in Lestoria/SlimeKing.cpp @@ -136,7 +136,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat }; const auto Recovered=[&](){ - switch(m.phase){ + switch(PHASE()){ case 2:{ switch(m.I(A::JUMP_COUNT)){ case 1: @@ -211,7 +211,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat lineToPlayer={m.GetPos(),m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*1}; } game->GetPlayer()->Knockback(lineToPlayer.vector().norm()*float(ConfigInt("JumpKnockbackFactor"))); - if(m.phase!=2){ + if(PHASE()!=2){ game->GetPlayer()->ApplyIframes(1.f); }else{ //In phase 2 you can get hit by multiple knockbacks, so the iframe time is a lot shorter. game->GetPlayer()->ApplyIframes(0.2f); @@ -219,7 +219,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat } } m.SetZ(0); - Landed(m.phase); + Landed(PHASE()); m.SetStrategyDrawFunction([](AiL*game,Monster&m,const std::string&strategy){}); } else if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){ @@ -244,19 +244,19 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat return; } - switch(m.phase){ + switch(PHASE()){ case 0:{ m.size=ConfigInt("Phase1.Size")/100.f; m.diesNormally=false; m.F(A::IFRAME_TIME_UPON_HIT)=0; m.ApplyIframes(ConfigFloat("Phase5.IframeTimePerHit")); - m.phase=ConfigInt("StartPhase"); + SETPHASE(ConfigInt("StartPhase")); }break; case 1:{ if(m.GetHealthRatio()<=ConfigFloat("Phase2.Change")/100.f){ - m.phase=2; + SETPHASE(2); m.SetSize(ConfigFloat("Phase2.Size")/100,false); - TransitionPhase(m.phase); + TransitionPhase(PHASE()); return; } if(m.F(A::SHOOT_RING_TIMER)==0){ @@ -287,12 +287,12 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat }break; case 2:{ if(m.GetHealthRatio()<=ConfigFloat("Phase3.Change")/100.f){ - m.phase=3; + SETPHASE(3); m.SetSize(ConfigFloat("Phase3.Size")/100,false); if(m.I(A::PATTERN_REPEAT_COUNT)==0){ m.I(A::PATTERN_REPEAT_COUNT)=1; } - TransitionPhase(m.phase); + TransitionPhase(PHASE()); return; } if(m.F(A::SHOOT_TIMER)==0){ @@ -315,10 +315,10 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat }break; case 3:{ if(m.GetHealthRatio()<=ConfigFloat("Phase4.Change")/100.f){ - m.phase=4; + SETPHASE(4); m.SetSize(ConfigFloat("Phase4.Size")/100,false); m.AddBuff(BuffType::SLOWDOWN,99999,ConfigFloat("Phase4.MoveSpdModifier")/100); - TransitionPhase(m.phase); + TransitionPhase(PHASE()); return; } if(m.I(A::PATTERN_REPEAT_COUNT)==0){ @@ -344,10 +344,10 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat }break; case 4:{ if(m.hp<=1){ //HP can't reach 0 when the dies normally flag is on. - m.phase=5; + SETPHASE(5); m.F(A::IFRAME_TIME_UPON_HIT)=1; m.I(A::HITS_UNTIL_DEATH)=int(m.GetSizeMult()*100/ConfigFloat("Phase5.SizeLossPerHit"))-1; - TransitionPhase(m.phase); + TransitionPhase(PHASE()); return; } if(m.I(A::PHASE_REPEAT_COUNT)>=5){ diff --git a/Adventures in Lestoria/StoneGolem.cpp b/Adventures in Lestoria/StoneGolem.cpp index f5b55b20..2f1cb3c8 100644 --- a/Adventures in Lestoria/StoneGolem.cpp +++ b/Adventures in Lestoria/StoneGolem.cpp @@ -157,14 +157,14 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str } #pragma endregion - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::RECOVERY_TIME)=ConfigFloat("Beginning Phase.Pillar Cast Delay Time"); m.I(A::PATTERN_REPEAT_COUNT)=ConfigInt("Beginning Phase.Repeat Count"); m.F(A::HEALTH_PCT_PHASE)=1.f; m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)=ConfigFloat("Pillar Respawns.Start HP Threshold")/100.f; m.I(A::SHOCKWAVE_COLOR)=ConfigPixel("Shockwave.Danger Area Color").n; - m.phase=SPAWN_PILLAR_PREPARE; + SETPHASE(SPAWN_PILLAR_PREPARE); if(ConfigIntArr("Pillar Respawns.Respawn Count",0)AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Beginning Phase.Pillar Cast Time"),"range_indicator.png","spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Golem Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Golem Pillar").GetSizeMult()/12.f)*1.25f,0.3f,vf2d{},ConfigPixel("Beginning Phase.Pillar Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Beginning Phase.Pillar Spell Circle Rotation Spd")),false,vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Golem Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Golem Pillar").GetSizeMult()/12.f)*0.9f,0.3f,vf2d{},ConfigPixel("Beginning Phase.Pillar Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Beginning Phase.Pillar Spell Insignia Rotation Spd"))),true); m.F(A::CASTING_TIMER)=ConfigFloat("Beginning Phase.Pillar Cast Time"); - m.phase=SPAWN_PILLAR_CAST; + SETPHASE(SPAWN_PILLAR_CAST); } }break; case SPAWN_PILLAR_CAST:{ @@ -188,11 +188,11 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str game->SpawnMonster(m.V(A::LOCKON_POS),MONSTER_DATA.at("Stone Golem Pillar"),m.OnUpperLevel()); game->Hurt(m.V(A::LOCKON_POS),MONSTER_DATA.at("Stone Golem Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Golem Pillar").GetSizeMult(),MONSTER_DATA.at("Stone Golem Pillar").GetAttack(),m.OnUpperLevel(),0.f,HurtType::PLAYER); if(m.I(A::PATTERN_REPEAT_COUNT)<=0){ - m.phase=STANDARD; + SETPHASE(STANDARD); }else{ m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); m.F(A::RECOVERY_TIME)=ConfigFloat("Beginning Phase.Pillar Cast Delay Time"); - m.phase=SPAWN_PILLAR_PREPARE; + SETPHASE(SPAWN_PILLAR_PREPARE); } } }break; @@ -205,7 +205,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str m.SIZET(A::PREVIOUS_MONSTER_COUNT)=MONSTER_LIST.size(); m.PerformAnimation("CAST",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); PrepareSafeAreas(); - m.phase=SHOCKWAVE; + SETPHASE(SHOCKWAVE); break; } if(m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)>=m.GetHealthRatio()){ @@ -218,7 +218,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str } 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; + SETPHASE(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"); @@ -233,7 +233,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str 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; + SETPHASE(BEAR_ATTACK); m.F(A::CHASE_TIMER)=0.f; } }break; @@ -243,13 +243,13 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str SoundEffect::StopLoopingSFX(m.SIZET(A::LOOPING_SOUND_ID)); m.PerformAnimation("TOSS ROCK"); m.F(A::RECOVERY_TIME)=m.GetCurrentAnimation().GetTotalAnimationDuration(); - m.phase=STONE_THROW_FINISH_ANIMATION; + SETPHASE(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; + SETPHASE(STANDARD); } }break; case SHOCKWAVE:{ @@ -259,7 +259,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str game->SetWorldColor(newCol); if(m.SIZET(A::PREVIOUS_MONSTER_COUNT)!=MONSTER_LIST.size()){ //The monster list has changed...Whether it's a pillar getting added or removed, it's important we recalculate safe areas proper. - m.phase=FIX_SAFE_AREAS; //HACK ALERT! Since spawning/removing monsters doesn't immediately occur in the MONSTER_LIST structure, we must defer the safe areas until the next tick and then recalculate them. To do this, we put the monster into another state and pause the shockwave attack for a frame to fix the new spawn areas on the next tick. + SETPHASE(FIX_SAFE_AREAS); //HACK ALERT! Since spawning/removing monsters doesn't immediately occur in the MONSTER_LIST structure, we must defer the safe areas until the next tick and then recalculate them. To do this, we put the monster into another state and pause the shockwave attack for a frame to fix the new spawn areas on the next tick. m.F(A::SAFE_AREA_WAIT_TIMER)=0.01f; m.SIZET(A::PREVIOUS_MONSTER_COUNT)=MONSTER_LIST.size(); } @@ -288,14 +288,14 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str }); SoundEffect::PlaySFX("Shockwave",m.GetPos()); game->AddEffect(std::make_unique(m.GetPos(),ConfigFloat("Shockwave.Shockwave Ring Lifetime"),"finishring.png",m.OnUpperLevel(),vf2d{ConfigFloat("Shockwave.Ring Expand Speed"),ConfigFloat("Shockwave.Ring Expand Speed")},vf2d{1.f,1.f},ConfigFloat("Shockwave.Shockwave Fadeout Time"),vf2d{},ConfigPixel("Shockwave.Shockwave Color")),true); - m.phase=STANDARD; + SETPHASE(STANDARD); game->SetWorldColor(WHITE); } }break; case FIX_SAFE_AREAS:{ if(m.F(A::SAFE_AREA_WAIT_TIMER)<=0.f){ PrepareSafeAreas(); //Recalculate safe areas if the shockwave attack is going off. - m.phase=SHOCKWAVE; + SETPHASE(SHOCKWAVE); }else m.F(A::SAFE_AREA_WAIT_TIMER)-=fElapsedTime; }break; case BEAR_ATTACK:{ @@ -304,11 +304,11 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str //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; + SETPHASE(STANDARD); m.I(A::ATTACK_COUNT)=m.I(A::BEAR_STOMP_COUNT); }else - if(m.I(A::PHASE)==0&&m.F(A::CHASE_TIMER)>=ConfigFloat("Max Chase Time")){ - m.phase=DOUBLE_ROCK_TOSS; + if(m.GetPhase("Bear")==0&&m.F(A::CHASE_TIMER)>=ConfigFloat("Max Chase Time")){ + SETPHASE(DOUBLE_ROCK_TOSS); m.PerformAnimation("RAISE ROCK"); m.I(A::STONE_TOSS_COUNT)=ConfigInt("Stone Rain.Initial Stone Toss Count"); m.F(A::STONE_TOSS_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); @@ -325,7 +325,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str game->AddEffect(std::make_unique(m.GetPos()+vf2d{util::random_range(throwPos.GetReal(0),throwPos.GetReal(2)),util::random_range(throwPos.GetReal(1),throwPos.GetReal(3))},10.f,"rock.png",ConfigFloat("Stone Rain.Stone Toss Delay"),ConfigFloat("Stone Rain.Stone Toss Rock Size Mult"),0.1f,vf2d{0.f,-ConfigFloat("Stone Rain.Stone Toss Throw Speed")},WHITE,util::random(2*PI),0.f)); if(m.I(A::STONE_TOSS_COUNT)<=0){ - m.phase=STONE_RAIN; + SETPHASE(STONE_RAIN); m.F(A::BREAK_TIME)=ConfigFloat("Stone Rain.Stone Golem Wait Time"); m.PerformAnimation("CAST"); @@ -338,7 +338,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str case STONE_RAIN:{ m.F(A::BREAK_TIME)-=fElapsedTime; if(m.F(A::BREAK_TIME)<=0.f){ - m.phase=STANDARD; + SETPHASE(STANDARD); } }break; } diff --git a/Adventures in Lestoria/Stone_Elemental.cpp b/Adventures in Lestoria/Stone_Elemental.cpp index 47bbed61..8659b96f 100644 --- a/Adventures in Lestoria/Stone_Elemental.cpp +++ b/Adventures in Lestoria/Stone_Elemental.cpp @@ -72,15 +72,15 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string }; auto ReturnToWaitingPhase=[&](){ - m.phase=WAITING; + SETPHASE(WAITING); m.PerformIdleAnimation(); m.F(A::ATTACK_COOLDOWN)=0.f; }; - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::ATTACK_COOLDOWN)=util::random(ConfigFloat("Attack Wait Time")/1.5f); - m.phase=WAITING; + SETPHASE(WAITING); }break; case WAITING:{ m.F(A::ATTACK_COOLDOWN)+=fElapsedTime; @@ -95,7 +95,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string case 0:{ m.PerformAnimation("STONE PILLAR CAST"); m.SIZET(A::LOOPING_SOUND_ID)=SoundEffect::PlayLoopingSFX("Rock Toss Cast",m.GetPos()); - m.phase=STONE_PILLAR_CAST; + SETPHASE(STONE_PILLAR_CAST); m.F(A::CASTING_TIMER)=ConfigFloat("Stone Pillar Cast Time"); m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos(); game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"range_indicator.png","spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Pillar").GetSizeMult()/12.f)*1.25f,0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Circle Rotation Spd")),false,vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Pillar").GetSizeMult()/12.f)*0.9f,0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Insignia Rotation Spd"))),false); @@ -103,7 +103,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string case 1:{ m.PerformAnimation("ROCK TOSS CAST"); m.SIZET(A::LOOPING_SOUND_ID)=SoundEffect::PlayLoopingSFX("Rock Toss Cast",m.GetPos()); - m.phase=SHOOT_STONE_CAST; + SETPHASE(SHOOT_STONE_CAST); m.B(A::PLAYED_FLAG)=false; m.F(A::CASTING_TIMER)=ConfigFloat("Rock Toss Track Time")+ConfigFloat("Rock Toss Wait Time"); CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,0.f,ConfigPixels("Rock Toss Max Spawn Distance"),ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius"),std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{1,1})EndBullet; @@ -121,7 +121,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string case 2:{ SoundEffect::PlaySFX("Dig",m.GetPos()); m.PerformAnimation("BURROW UNDERGROUND"); - m.phase=DIVE_UNDERGROUND_DIG; + SETPHASE(DIVE_UNDERGROUND_DIG); m.F(A::CASTING_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); }break; } @@ -167,7 +167,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string case DIVE_UNDERGROUND_DIG:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0.f){ - m.phase=DIVE_UNDERGROUND_MOVE; + SETPHASE(DIVE_UNDERGROUND_MOVE); float randomAngle=util::random(2*PI); const float minDist=ConfigPixelsArr("Burrow Teleport Distance",0); @@ -198,7 +198,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string m.B(A::IGNORE_DEFAULT_ANIMATIONS)=false; SoundEffect::PlaySFX("Rise",m.GetPos()); m.PerformAnimation("RISE FROM UNDERGROUND"); - m.phase=DIVE_UNDERGROUND_SURFACE; + SETPHASE(DIVE_UNDERGROUND_SURFACE); m.targetAcquireTimer=0; m.F(A::CASTING_TIMER)=m.GetCurrentAnimation().GetTotalAnimationDuration(); diff --git a/Adventures in Lestoria/Ursule.cpp b/Adventures in Lestoria/Ursule.cpp index 14b64d00..bf2085ea 100644 --- a/Adventures in Lestoria/Ursule.cpp +++ b/Adventures in Lestoria/Ursule.cpp @@ -53,9 +53,9 @@ INCLUDE_DATA using A=Attribute; void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy){ - switch(m.phase){ + switch(PHASE()){ case 0:{ - m.phase=ConfigInt("StartPhase"); + SETPHASE(ConfigInt("StartPhase")); m.overlaySprite=ConfigString("Overlay Sprite"); m.overlaySpriteTransparency=0U; @@ -94,7 +94,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy }break; case 1:{ //Run bear strategy in phase 1. auto TransitionToPhase2=[&](){ - m.phase=2; + SETPHASE(2); m.PerformAnimation("SIT"); m.AddBuff(BARRIER_DAMAGE_REDUCTION,INFINITE,ConfigFloat("Phase 2.Barrier Damage Reduction")/100.f); m.I(A::PHASE_REPEAT_COUNT)=ConfigInt("Phase 2.Wisp Pattern Spawn Count"); @@ -106,7 +106,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy if(m.GetHealthRatio()<=ConfigFloat("Phase 2.Change")/100.f){ //before moving to Phase 2, we need to make sure we're in Phase 0 of the bear AI. if(m.overlaySpriteTransparency<210U){ - if(m.I(A::PHASE)!=0)goto bear; + if(m.GetPhase("Bear")!=0)goto bear; else{ if(m.F(A::RUN_AWAY_TIMER)==0.f)m.F(A::RUN_AWAY_TIMER)=ConfigFloat("Phase 1.Fur Change Color Time"); else{ @@ -142,9 +142,9 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy if(m.I(A::BEAR_STOMP_COUNT)%(ConfigInt("Phase 1.Stomp Count")+1)==ConfigInt("Phase 1.Stomp Count")){ m.F(A::RUN_AWAY_TIMER)=ConfigFloat("Phase 1.Run Time"); - m.I(A::PREVIOUS_PHASE)=m.phase; + m.I(A::PREVIOUS_PHASE)=PHASE(); m.AddBuff(SPEEDBOOST,10.f,ConfigFloat("Phase 1.Run Speed Boost")/100.f); - m.phase=6; + SETPHASE(6); break; } @@ -219,7 +219,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy }else{ auto TransitionToPhase3=[&](){ - m.phase=3; + SETPHASE(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; @@ -266,11 +266,11 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy float distToPlayer=geom2d::line(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(m.GetPhase("Bear")!=0)goto bear2; //Prevent doing anything else if a part of bear AI is still running. if(m.GetHealthRatio()<=ConfigFloat("Phase 4.Change")/100.f){ auto TransitionToPhase5=[&](){ - m.phase=5; + SETPHASE(5); m.PerformAnimation("SIT"); SoundEffect::PlaySFX("Ursule Phase Transition",SoundEffect::CENTERED); m.F(A::ENVIRONMENT_TIMER)=ConfigFloat("Phase 4.Environment Fade-out Time"); @@ -311,7 +311,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy 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; + SETPHASE(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")); @@ -332,8 +332,8 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy if(m.I(A::BEAR_STOMP_COUNT)%(ConfigInt("Phase 3.Stomp Count")+1)==ConfigInt("Phase 3.Stomp Count")){ m.F(A::RUN_AWAY_TIMER)=ConfigFloat("Phase 3.Run Time"); m.AddBuff(SPEEDBOOST,10.f,ConfigFloat("Phase 3.Run Speed Boost")/100.f); - m.I(A::PREVIOUS_PHASE)=m.phase; - m.phase=6; + m.I(A::PREVIOUS_PHASE)=PHASE(); + SETPHASE(6); break; } } @@ -352,7 +352,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy float distToTarget=geom2d::line(m.target,m.GetPos()).length(); if(distToTarget<=4.f||m.F(A::TARGET_TIMER)==0.f||m.B(A::COLLIDED_WITH_PLAYER)){ - m.phase=3; + SETPHASE(3); m.RemoveBuff(SPEEDBOOST); m.RemoveBuff(FIXED_COLLISION_DMG); m.RemoveBuff(COLLISION_KNOCKBACK_STRENGTH); @@ -429,13 +429,13 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy m.target=game->GetPlayer()->GetPos(); RUN_TOWARDS(m,fElapsedTime,"Run Towards"); if(m.F(A::RUN_AWAY_TIMER)==0.f){ - m.phase=m.I(A::PREVIOUS_PHASE); + SETPHASE(m.I(A::PREVIOUS_PHASE)); m.RemoveBuff(SPEEDBOOST); m.I(A::BEAR_STOMP_COUNT)=0; } }break; default:{ - ERR(std::format("WARNING! Unknown phase {} for {} reached!",m.phase,m.GetName())); + ERR(std::format("WARNING! Unknown phase {} for {} reached!",PHASE(),m.GetName())); } } } \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index b916b0a0..67b38b8e 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 11657 +#define VERSION_BUILD 11666 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Wolf.cpp b/Adventures in Lestoria/Wolf.cpp index 95f9aa02..6bd295d3 100644 --- a/Adventures in Lestoria/Wolf.cpp +++ b/Adventures in Lestoria/Wolf.cpp @@ -49,11 +49,11 @@ INCLUDE_BULLET_LIST using A=Attribute; void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){ - switch(m.I(A::PHASE)){ + switch(PHASE()){ case 0:{ //Run towards the player. float distToPlayer=geom2d::line(game->GetPlayer()->GetPos(),m.GetPos()).length(); if(distToPlayer<=ConfigFloat("Lockon Range")/100*24.f){ - m.I(A::PHASE)=1; + SETPHASE(1); m.V(A::LOCKON_POS)=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).upoint(1.2f); m.AddBuff(BuffType::LOCKON_SPEEDBOOST,INFINITE,ConfigFloat("Lockon Speed Boost")/100); m.F(A::TARGET_TIMER)=5.0f; @@ -65,7 +65,7 @@ void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){ m.F(A::TARGET_TIMER)=std::max(0.f,m.F(A::TARGET_TIMER)-fElapsedTime); float distToTarget=geom2d::line(m.GetPos(),m.V(A::LOCKON_POS)).length(); if(distToTarget<=12.f||m.F(A::TARGET_TIMER)==0.f){ - m.I(A::PHASE)=2; + SETPHASE(2); m.F(A::RECOVERY_TIME)=ConfigFloat("Charge Recovery Time"); m.PerformIdleAnimation(); }else{ @@ -97,7 +97,7 @@ void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){ m.I(A::PATH_DIR)=util::random()%2; if(m.I(A::PATH_DIR)==0)m.I(A::PATH_DIR)=-1; m.pathIndex=util::random()%disengagePoints.size(); - m.I(A::PHASE)=3; + SETPHASE(3); m.F(A::RUN_AWAY_TIMER)=ConfigFloat("Disengage Duration"); m.PerformJumpAnimation(); } @@ -110,7 +110,7 @@ void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){ m.pathIndex=m.pathIndex+m.path.points.size(); } if(m.F(A::RUN_AWAY_TIMER)==0.f){ - m.I(A::PHASE)=0; + SETPHASE(0); } m.target=m.path.GetSplinePoint(m.pathIndex).pos; geom2d::linemoveTowardsLine=geom2d::line(m.pos,m.path.GetSplinePoint(m.pathIndex).pos); diff --git a/Adventures in Lestoria/Zephy.cpp b/Adventures in Lestoria/Zephy.cpp index 4b260b36..a07d02bf 100644 --- a/Adventures in Lestoria/Zephy.cpp +++ b/Adventures in Lestoria/Zephy.cpp @@ -71,7 +71,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) LEFT }; - if(m.phase!=HALFHEALTH_PHASE)m.F(A::SPAWNER_TIMER)-=fElapsedTime; + if(PHASE()!=HALFHEALTH_PHASE)m.F(A::SPAWNER_TIMER)-=fElapsedTime; if(m.F(A::SPAWNER_TIMER)<=0.f){ const float randomDir=util::random(2*PI); game->SpawnMonster(m.GetPos()+vf2d{ConfigFloat("Basic Hawk Spawn Radius"),randomDir}.cart(),MONSTER_DATA.at("Hawk_NOXP"),m.OnUpperLevel(),true); @@ -85,10 +85,10 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) if(m.F(A::FLYING_HEIGHT)-ConfigFloat("Flight Oscillation Amount"))m.F(A::FLYING_HEIGHT)=std::max(-ConfigFloat("Flight Oscillation Amount"),m.F(A::FLYING_HEIGHT)-ConfigPixels("Fly Rise/Fall Speed")*fElapsedTime); - switch(m.phase){ + switch(PHASE()){ case INITIALIZE:{ m.F(A::SPAWNER_TIMER)=ConfigFloat("Basic Hawk Spawn Time"); - m.phase=IDLE; + SETPHASE(IDLE); game->SetOverlay(ConfigString("Wind Attack.Wind Overlay Sprite"),ConfigPixel("Wind Attack.Wind Overlay Color")); game->GetOverlay().Disable(); @@ -110,9 +110,9 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) }break; case IDLE:{ #pragma region Mid Phase Check - if(m.GetHealthRatio()<=ConfigFloat("Mid Phase Health Transition %")/100.f&&!m.B(A::PHASE)){ - m.B(A::PHASE)=true; - m.phase=HALFHEALTH_PREPARE_PHASE; + if(m.GetHealthRatio()<=ConfigFloat("Mid Phase Health Transition %")/100.f&&!m.B(A::MID_PHASE)){ + m.B(A::MID_PHASE)=true; + SETPHASE(HALFHEALTH_PREPARE_PHASE); m.F(A::TARGET_FLYING_HEIGHT)=50.f; m.target=ConfigVec("Mid Phase.Pillar Position"); for(int i=0;iGetOverlay().Enable(); m.F(A::CASTING_TIMER)=ConfigFloat("Wind Attack.Wind Duration"); m.F(A::WIND_STRENGTH)=ConfigFloat("Wind Attack.Wind Starting Strength")/100.f; @@ -310,7 +310,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) #pragma endregion if(m.F(A::CASTING_TIMER)<=0.f){ - m.phase=IDLE; + SETPHASE(IDLE); game->GetOverlay().Disable(); game->SetWindSpeed({}); } @@ -337,7 +337,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) const bool HasLandedOnGround=m.GetZ()==0.f; if(HasLandedOnGround){ - m.phase=HALFHEALTH_PHASE; + SETPHASE(HALFHEALTH_PHASE); CreateBullet(LargeTornado)(ConfigVec("Mid Phase.Large Tornado Position"),ConfigPixels("Mid Phase.Large Tornado Suction"),ConfigFloat("Mid Phase.Large Tornado Knockup Duration"),ConfigFloat("Mid Phase.Large Tornado Knockback Amount"),ConfigInt("Mid Phase.Large Tornado Damage"),ConfigFloat("Mid Phase.Large Tornado Radius"),INFINITY,m.OnUpperLevel())EndBullet; BULLET_LIST.back()->SetFadeinTime(1.0f); m.F(A::SHOOT_TIMER)=2.f; @@ -350,7 +350,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) m.UpdateFacingDirection(Direction::SOUTH); m.PerformAnimation("ATTACK"); if(game->BossEncounterMobCount()==1){ - m.phase=IDLE; + SETPHASE(IDLE); std::for_each(BULLET_LIST.begin(),BULLET_LIST.end(),[](std::unique_ptr&bullet){ if(bullet->GetBulletType()==BulletType::LARGE_TORNADO){ bullet->fadeOutTime=1.f; diff --git a/Adventures in Lestoria/assets/Campaigns/3_1.tmx b/Adventures in Lestoria/assets/Campaigns/3_1.tmx index 56d496b2..71332dba 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_1.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_1.tmx @@ -1,5 +1,5 @@ - + @@ -870,5 +870,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/3_2.tmx b/Adventures in Lestoria/assets/Campaigns/3_2.tmx index 51a6e715..db30a4f7 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_2.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_2.tmx @@ -1,5 +1,5 @@ - + @@ -1471,5 +1471,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/3_3.tmx b/Adventures in Lestoria/assets/Campaigns/3_3.tmx index eea71e70..28062bbc 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_3.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_3.tmx @@ -1,5 +1,5 @@ - + @@ -861,5 +861,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/3_5.tmx b/Adventures in Lestoria/assets/Campaigns/3_5.tmx index 36010348..41c3f2a8 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_5.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_5.tmx @@ -1,5 +1,5 @@ - + @@ -1076,5 +1076,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/3_6.tmx b/Adventures in Lestoria/assets/Campaigns/3_6.tmx index 6f882f71..78984978 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_6.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_6.tmx @@ -1,5 +1,5 @@ - + @@ -1821,5 +1821,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/3_8.tmx b/Adventures in Lestoria/assets/Campaigns/3_8.tmx index 814e9994..97173f63 100644 --- a/Adventures in Lestoria/assets/Campaigns/3_8.tmx +++ b/Adventures in Lestoria/assets/Campaigns/3_8.tmx @@ -1,5 +1,5 @@ - + @@ -1886,5 +1886,11 @@ + + + + + + diff --git a/Adventures in Lestoria/assets/config/MonsterStrategies.txt b/Adventures in Lestoria/assets/config/MonsterStrategies.txt index 64315b3e..4db31e88 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -1148,8 +1148,8 @@ MonsterStrategy # Amount of time parrot remains stunned on death. Stun Time = 5s - Fly Away Speed = 100 - Fly Away Z Speed = 10 + Fly Away Speed = 140 + Fly Away Z Speed = 30 } Crab { diff --git a/Adventures in Lestoria/assets/config/Monsters.txt b/Adventures in Lestoria/assets/config/Monsters.txt index e49a824f..14ba11bd 100644 --- a/Adventures in Lestoria/assets/config/Monsters.txt +++ b/Adventures in Lestoria/assets/config/Monsters.txt @@ -1263,10 +1263,10 @@ Monsters Dagger Slash Distance = 12 # Slash Attack windup time - Slash Windup Time = 0.2s + Slash Windup Time = 0.4s # Stab Attack windup time - Stab Windup Time = 0.2s + Stab Windup Time = 0.4s # Amount of time where nothing happens after an attack. Attack Recovery Time = 0.6s @@ -1343,7 +1343,7 @@ Monsters Attack Spacing = 100 # Slash Attack windup time - Slash Windup Time = 0.2s + Slash Windup Time = 0.4s Dagger Slash Image = "pirate_slash.png" @@ -1415,10 +1415,10 @@ Monsters Dagger Slash Distance = 12 # Slash Attack windup time - Slash Windup Time = 0.2s + Slash Windup Time = 0.4s # Stab Attack windup time - Stab Windup Time = 0.2s + Stab Windup Time = 0.4s # Amount of time where nothing happens after an attack. Attack Recovery Time = 0.6s @@ -1434,9 +1434,9 @@ Monsters # Offset for the dagger stab effect per direction from the monster's center. Dagger Up Offset = -6,-5.5 - Dagger Down Offset = -5,-1 - Dagger Right Offset = 9,0 - Dagger Left Offset = -8,-2 + Dagger Down Offset = -7,-1 + Dagger Right Offset = 10,1 + Dagger Left Offset = -8,0 ######## @@ -1455,7 +1455,7 @@ Monsters SHOOTING = 3, 0.2, OneShot SHOOT = 1, 0.1, OneShot # Drink is approximately 2 seconds long. - DRINK = 3, 0.65, PingPong + DRINK = 2, 0.65, PingPong } # Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity @@ -1602,6 +1602,8 @@ Monsters Strategy = Seagull + Ignore Collisions = True + #Size of each animation frame SheetFrameSize = 48,48 @@ -1666,7 +1668,7 @@ Monsters Hurt Sound = Monster Hurt Death Sound = Slime Dead - Walk Sound = Slime Walk + Walk Sound = Wing Flap } Parrot { @@ -1676,12 +1678,14 @@ Monsters CollisionDmg = 22 MoveSpd = 180% - Size = 50% + Size = 100% XP = 0 Collision Radius = 7 + Ignore Collisions = True + Strategy = Parrot # Instead of the monster dying, it gets knocked unconscious @@ -1698,10 +1702,10 @@ Monsters # Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot) # Animations must be defined in the same order as they are in their sprite sheets # The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator. - IDLE = 4, 0.2, Repeat + IDLE = 1, 0.2, Repeat FLYING = 4, 0.15, Repeat ATTACKING = 2, 0.3, Repeat - DEATH = 4, 0.15, OneShot + DEATH = 1, 0.15, OneShot ATTACK = 2, 0.3, Repeat } @@ -1710,6 +1714,6 @@ Monsters Hurt Sound = Monster Hurt Death Sound = Slime Dead - Walk Sound = Slime Walk + Walk Sound = Wing Flap } } \ No newline at end of file diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 4c3a347c..32c32272 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 34890171..25cacee4 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ