Fix bug involving lingering tornado attack. Reduce size of boss arena so item drops and the end zone ring spawn within player reachable locations. Made item drop locations respect boss arenas. Added mid phase for 2nd chapter bonus boss. Fix boss indicator appearing when no boss is present. Release Build 9534.

mac-build
sigonasr2 6 months ago
parent 78d2234ccc
commit 6be3e5e83d
  1. 2
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 8
      Adventures in Lestoria/ItemDrop.cpp
  3. 2
      Adventures in Lestoria/ItemDrop.h
  4. 2
      Adventures in Lestoria/Monster.cpp
  5. 2
      Adventures in Lestoria/Version.h
  6. 63
      Adventures in Lestoria/Zephy.cpp
  7. 4
      Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx
  8. 5
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  9. 2
      Adventures in Lestoria/assets/config/Monsters.txt
  10. BIN
      x64/Release/Adventures in Lestoria.exe

@ -4183,8 +4183,6 @@ rcode AiL::LoadResource(Renderable&renderable,std::string_view imgPath,bool filt
void AiL::UpdateMonsters(){ void AiL::UpdateMonsters(){
for(std::unique_ptr<Monster>&m:MONSTER_LIST){ for(std::unique_ptr<Monster>&m:MONSTER_LIST){
if(m->HasArrowIndicator())bossIndicatorPos=m->GetPos();
if(m->markedForDeletion){ if(m->markedForDeletion){
AMonsterIsMarkedForDeletion(); AMonsterIsMarkedForDeletion();
continue; continue;

@ -50,8 +50,14 @@ void ItemDrop::Initialize(){
gravity="ItemDrop.Item Drop Gravity"_F; 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){ :item(item),pos(pos),upperLevel(isUpper){
const bool HasBossArenaBounds=game->GetCurrentMap().GetMapType()=="Boss";
if(HasBossArenaBounds){
const geom2d::rect<int>arenaBounds=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.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]; 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; zSpeed="ItemDrop.Item Drop Initial Rise Speed"_F;

@ -51,7 +51,7 @@ class ItemDrop{
static float gravity; static float gravity;
static std::vector<ItemDrop>drops; static std::vector<ItemDrop>drops;
bool collected=false; bool collected=false;
ItemDrop(const ItemInfo*item,vf2d pos,bool isUpper); ItemDrop(const ItemInfo*item,const vf2d pos,const bool isUpper);
public: public:
static void Initialize(); static void Initialize();
vf2d GetPos()const; vf2d GetPos()const;

@ -266,7 +266,7 @@ bool Monster::Update(float fElapsedTime){
lastFacingDirectionChange+=fElapsedTime; lastFacingDirectionChange+=fElapsedTime;
timeSpentAlive+=fElapsedTime; timeSpentAlive+=fElapsedTime;
if(HasArrowIndicator())game->SetBossIndicatorPos(GetPos()); if(HasArrowIndicator()&&IsAlive())game->SetBossIndicatorPos(GetPos());
#pragma region Handle Monster Lifetime and fade timer. #pragma region Handle Monster Lifetime and fade timer.
if(fadeTimer>0.f){ if(fadeTimer>0.f){

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

@ -54,6 +54,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
enum Phase{ enum Phase{
INITIALIZE, INITIALIZE,
IDLE, IDLE,
ATTACK_RESET,
FLY_ACROSS_PREPARE, FLY_ACROSS_PREPARE,
FLY_ACROSS, FLY_ACROSS,
TORNADO_ATTACK_PREPARE, TORNADO_ATTACK_PREPARE,
@ -61,6 +62,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
WIND_ATTACK_FLY, WIND_ATTACK_FLY,
WIND_ATTACK_LAND, WIND_ATTACK_LAND,
WIND_ATTACK, WIND_ATTACK,
HALFHEALTH_PREPARE_PHASE,
HALFHEALTH_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.phase!=HALFHEALTH_PHASE)m.F(A::SPAWNER_TIMER)-=fElapsedTime;
if(m.F(A::SPAWNER_TIMER)<=0.f){ if(m.F(A::SPAWNER_TIMER)<=0.f){
const float randomDir=util::random(2*PI); 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"); 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->SetOverlay(ConfigString("Wind Attack.Wind Overlay Sprite"),ConfigPixel("Wind Attack.Wind Overlay Color"));
game->GetOverlay().Disable(); 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->SetWindSpeed({});
game->GetOverlay().Disable(); game->GetOverlay().Disable();
std::for_each(BULLET_LIST.begin(),BULLET_LIST.end(),[](const std::unique_ptr<Bullet>&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; 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)){ if(m.GetHealthRatio()<=ConfigFloat("Mid Phase Health Transition %")/100.f&&!m.B(A::PHASE)){
m.B(A::PHASE)=true; 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;i<ConfigInt("Mid Phase.Basic Hawk Spawn Count");i++){
const vf2d xRange=ConfigVec("Mid Phase.Adds Spawn X Range");
const vf2d yRange=ConfigVec("Mid Phase.Adds Spawn Y Range");
const vf2d spawnPos={util::random_range(xRange.x,xRange.y),util:: random_range(yRange.x,yRange.y)};
game->SpawnMonster(spawnPos,MONSTER_DATA.at("Hawk_NOXP"),m.OnUpperLevel(),true);
}
for(int i=0;i<ConfigInt("Mid Phase.Major Hawk Spawn Count");i++){
const vf2d xRange=ConfigVec("Mid Phase.Adds Spawn X Range");
const vf2d yRange=ConfigVec("Mid Phase.Adds Spawn Y Range");
const vf2d spawnPos={util::random_range(xRange.x,xRange.y),util:: random_range(yRange.x,yRange.y)};
game->SpawnMonster(spawnPos,MONSTER_DATA.at("Major Hawk"),m.OnUpperLevel(),true);
}
break; //An early break to not perform an attack.
} }
}break; #pragma endregion
case IDLE:{
const int randomAttackChoice=2;
int randomAttackChoice;
do randomAttackChoice=util::random()%3;
while(randomAttackChoice==m.I(A::PREVIOUS_PHASE));
m.I(A::PREVIOUS_PHASE)=randomAttackChoice;
switch(randomAttackChoice){ switch(randomAttackChoice){
case 0:{ 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; const bool LeftLandingSite=m.I(A::ATTACK_CHOICE)=util::random()%2;
if(LeftLandingSite)m.target=ConfigVec("Wind Attack.Left Landing Site"); if(LeftLandingSite)m.target=ConfigVec("Wind Attack.Left Landing Site");
else m.target=ConfigVec("Wind Attack.Right Landing Site"); else m.target=ConfigVec("Wind Attack.Right Landing Site");
}break; }break;
} }
}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"); m.F(A::SHOOT_TIMER)=ConfigFloat("Wind Attack.Wind Projectile Spawn Rate");
} }
}break; }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:{ case HALFHEALTH_PHASE:{
m.ApplyIframes(1.f);
m.UpdateFacingDirection(Direction::SOUTH);
m.PerformAnimation("ATTACK");
if(game->BossEncounterMobCount()==1)m.phase=IDLE;
}break; }break;
} }
} }

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="160" height="144" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="26"> <map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="160" height="144" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="26">
<properties> <properties>
<property name="Backdrop" propertytype="Backdrop" value="mountain_night"/> <property name="Backdrop" propertytype="Backdrop" value="mountain_night"/>
<property name="Background Music" propertytype="BGM" value="foresty_boss"/> <property name="Background Music" propertytype="BGM" value="foresty_boss"/>
@ -608,7 +608,7 @@
<property name="Spawn2" type="object" value="19"/> <property name="Spawn2" type="object" value="19"/>
</properties> </properties>
</object> </object>
<object id="25" name="Boss Arena" type="BossArena" x="1302" y="1122" width="1448" height="1206"/> <object id="25" name="Boss Arena" type="BossArena" x="1560" y="1584" width="960" height="336"/>
</objectgroup> </objectgroup>
<objectgroup id="7" name="Spawn Zone 3" visible="0"> <objectgroup id="7" name="Spawn Zone 3" visible="0">
<object id="19" name="Boss Spawn Zone" type="SpawnGroup" x="1560" y="1314" width="964" height="882"> <object id="19" name="Boss Spawn Zone" type="SpawnGroup" x="1560" y="1314" width="964" height="882">

@ -866,7 +866,10 @@ MonsterStrategy
# The boss will go land at this position first. # The boss will go land at this position first.
Pillar Position = 2040, 1488 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
} }
} }
} }

@ -937,7 +937,7 @@ Monsters
# DROP[0] = Ring of the Bear,100%,1,1 # DROP[0] = Ring of the Bear,100%,1,1
} }
Hawk_NOXP 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. # Which monster base image this monster should be based off of.
Base Image Name = "Hawk" Base Image Name = "Hawk"
Display Name = "Hawk" Display Name = "Hawk"

Loading…
Cancel
Save