diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 25c1c4b9..96ebe053 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -4183,8 +4183,6 @@ rcode AiL::LoadResource(Renderable&renderable,std::string_view imgPath,bool filt void AiL::UpdateMonsters(){ for(std::unique_ptr&m:MONSTER_LIST){ - if(m->HasArrowIndicator())bossIndicatorPos=m->GetPos(); - if(m->markedForDeletion){ AMonsterIsMarkedForDeletion(); continue; diff --git a/Adventures in Lestoria/ItemDrop.cpp b/Adventures in Lestoria/ItemDrop.cpp index dd724582..c3346f5f 100644 --- a/Adventures in Lestoria/ItemDrop.cpp +++ b/Adventures in Lestoria/ItemDrop.cpp @@ -50,8 +50,14 @@ void ItemDrop::Initialize(){ gravity="ItemDrop.Item Drop Gravity"_F; } -ItemDrop::ItemDrop(const ItemInfo*item,vf2d pos,bool isUpper) +ItemDrop::ItemDrop(const ItemInfo*item,const vf2d pos,const bool isUpper) :item(item),pos(pos),upperLevel(isUpper){ + const bool HasBossArenaBounds=game->GetCurrentMap().GetMapType()=="Boss"; + if(HasBossArenaBounds){ + const geom2d::rectarenaBounds=game->GetZones().at("BossArena")[0].zone; + this->pos.x=std::clamp(this->pos.x,float(arenaBounds.pos.x),float(arenaBounds.pos.x+arenaBounds.size.x)); + this->pos.y=std::clamp(this->pos.y,float(arenaBounds.pos.y),float(arenaBounds.pos.y+arenaBounds.size.y)); + } speed.x=util::random("ItemDrop.Item Drop Horizontal Speed"_f[1]-"ItemDrop.Item Drop Horizontal Speed"_f[0])+"ItemDrop.Item Drop Horizontal Speed"_f[0]; speed.y=util::random("ItemDrop.Item Drop Vertical Speed"_f[1]-"ItemDrop.Item Drop Vertical Speed"_f[0])+"ItemDrop.Item Drop Vertical Speed"_f[0]; zSpeed="ItemDrop.Item Drop Initial Rise Speed"_F; diff --git a/Adventures in Lestoria/ItemDrop.h b/Adventures in Lestoria/ItemDrop.h index b1cdeece..732e29f8 100644 --- a/Adventures in Lestoria/ItemDrop.h +++ b/Adventures in Lestoria/ItemDrop.h @@ -51,7 +51,7 @@ class ItemDrop{ static float gravity; static std::vectordrops; bool collected=false; - ItemDrop(const ItemInfo*item,vf2d pos,bool isUpper); + ItemDrop(const ItemInfo*item,const vf2d pos,const bool isUpper); public: static void Initialize(); vf2d GetPos()const; diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index e4fcff6e..45ec6fe8 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -266,7 +266,7 @@ bool Monster::Update(float fElapsedTime){ lastFacingDirectionChange+=fElapsedTime; timeSpentAlive+=fElapsedTime; - if(HasArrowIndicator())game->SetBossIndicatorPos(GetPos()); + if(HasArrowIndicator()&&IsAlive())game->SetBossIndicatorPos(GetPos()); #pragma region Handle Monster Lifetime and fade timer. if(fadeTimer>0.f){ diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 1c566fc3..7bf341d8 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 9524 +#define VERSION_BUILD 9534 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Zephy.cpp b/Adventures in Lestoria/Zephy.cpp index f7c55320..c4cde189 100644 --- a/Adventures in Lestoria/Zephy.cpp +++ b/Adventures in Lestoria/Zephy.cpp @@ -54,6 +54,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) enum Phase{ INITIALIZE, IDLE, + ATTACK_RESET, FLY_ACROSS_PREPARE, FLY_ACROSS, TORNADO_ATTACK_PREPARE, @@ -61,6 +62,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) WIND_ATTACK_FLY, WIND_ATTACK_LAND, WIND_ATTACK, + HALFHEALTH_PREPARE_PHASE, HALFHEALTH_PHASE, }; @@ -72,7 +74,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) if(m.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()); + game->SpawnMonster(m.GetPos()+vf2d{ConfigFloat("Basic Hawk Spawn Radius"),randomDir}.cart(),MONSTER_DATA.at("Hawk_NOXP"),m.OnUpperLevel(),true); m.F(A::SPAWNER_TIMER)=ConfigFloat("Basic Hawk Spawn Time"); } @@ -90,19 +92,54 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) game->SetOverlay(ConfigString("Wind Attack.Wind Overlay Sprite"),ConfigPixel("Wind Attack.Wind Overlay Color")); game->GetOverlay().Disable(); - m.SetStrategyDeathFunction([](GameEvent&ev,Monster&m,const std::string&strategy){ + m.SetStrategyDeathFunction([&](GameEvent&ev,Monster&m,const std::string&strategy){ game->SetWindSpeed({}); game->GetOverlay().Disable(); + + std::for_each(BULLET_LIST.begin(),BULLET_LIST.end(),[](const std::unique_ptr&bullet){ + if(!bullet->friendly){ //Forces all bullets at the end of a fight for the boss to be completely nullified. + bullet->fadeOutTime=0.5f; + bullet->deactivated=true; + } + }); return true; }); + m.I(A::PREVIOUS_PHASE)=-1; + }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_PHASE; + m.phase=HALFHEALTH_PREPARE_PHASE; + m.F(A::TARGET_FLYING_HEIGHT)=50.f; + m.target=ConfigVec("Mid Phase.Pillar Position"); + for(int i=0;iSpawnMonster(spawnPos,MONSTER_DATA.at("Hawk_NOXP"),m.OnUpperLevel(),true); + } + for(int i=0;iSpawnMonster(spawnPos,MONSTER_DATA.at("Major Hawk"),m.OnUpperLevel(),true); + } + break; //An early break to not perform an attack. } - }break; - case IDLE:{ - const int randomAttackChoice=2; + #pragma endregion + + + int randomAttackChoice; + do randomAttackChoice=util::random()%3; + while(randomAttackChoice==m.I(A::PREVIOUS_PHASE)); + + m.I(A::PREVIOUS_PHASE)=randomAttackChoice; switch(randomAttackChoice){ case 0:{ @@ -124,7 +161,6 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) const bool LeftLandingSite=m.I(A::ATTACK_CHOICE)=util::random()%2; if(LeftLandingSite)m.target=ConfigVec("Wind Attack.Left Landing Site"); else m.target=ConfigVec("Wind Attack.Right Landing Site"); - }break; } }break; @@ -291,8 +327,19 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) m.F(A::SHOOT_TIMER)=ConfigFloat("Wind Attack.Wind Projectile Spawn Rate"); } }break; + case HALFHEALTH_PREPARE_PHASE:{ + m.targetAcquireTimer=20.f; + RUN_TOWARDS(m,fElapsedTime,"Run Towards"); + if(m.ReachedTargetPos()){ + m.F(A::TARGET_FLYING_HEIGHT)=0.f; + if(m.GetZ()==0.f)m.phase=HALFHEALTH_PHASE; + } + }break; case HALFHEALTH_PHASE:{ - + m.ApplyIframes(1.f); + m.UpdateFacingDirection(Direction::SOUTH); + m.PerformAnimation("ATTACK"); + if(game->BossEncounterMobCount()==1)m.phase=IDLE; }break; } } \ No newline at end of file diff --git a/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx b/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx index 441f4a3f..302aafe8 100644 --- a/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx +++ b/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx @@ -1,5 +1,5 @@ - + @@ -608,7 +608,7 @@ - + diff --git a/Adventures in Lestoria/assets/config/MonsterStrategies.txt b/Adventures in Lestoria/assets/config/MonsterStrategies.txt index b66191e2..62a294fe 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -866,7 +866,10 @@ MonsterStrategy # The boss will go land at this position first. Pillar Position = 2040, 1488 - + Adds Spawn X Range = 1752, 2352 + Adds Spawn Y Range = 1344, 1344 + Basic Hawk Spawn Count = 4 + Major Hawk Spawn Count = 2 } } } \ No newline at end of file diff --git a/Adventures in Lestoria/assets/config/Monsters.txt b/Adventures in Lestoria/assets/config/Monsters.txt index d00b3ef5..a36bd937 100644 --- a/Adventures in Lestoria/assets/config/Monsters.txt +++ b/Adventures in Lestoria/assets/config/Monsters.txt @@ -937,7 +937,7 @@ Monsters # DROP[0] = Ring of the Bear,100%,1,1 } Hawk_NOXP - { # A versions of the Hawk that does not provide any XP. All other features remain identical. + { # A version of the Hawk that does not provide any XP. All other features remain identical. # Which monster base image this monster should be based off of. Base Image Name = "Hawk" Display Name = "Hawk" diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 1c2cb2c4..dec2fba6 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ