Octopus Arm now has proper detection for empty pool spawns and responsive to player moving around (spawn in nearby empty water pools). Release Build 11848.

master
sigonasr2 2 months ago
parent 6ea6b9b88d
commit 58be1c8999
  1. 2
      Adventures in Lestoria/Adventures in Lestoria.vcxproj
  2. 41
      Adventures in Lestoria/GiantOctopus.cpp
  3. 1
      Adventures in Lestoria/OctopusArm.cpp
  4. 11
      Adventures in Lestoria/TODO.txt
  5. 2
      Adventures in Lestoria/Version.h
  6. 10
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  7. BIN
      x64/Release/Adventures in Lestoria.exe

@ -227,7 +227,7 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\LabUser\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\niconiconii\OneDrive\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\OneDrive\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;$(ProjectDir)steam;$(ProjectDir)discord-files;C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\LabUser\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\niconiconii\OneDrive\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\OneDrive\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatSpecificWarningsAsErrors>4099;5030;4715;4172;4834</TreatSpecificWarningsAsErrors>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>

@ -56,12 +56,13 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s
switch(PHASE()){
case INIT:{
m.F(A::BREAK_TIME)=0.5f;
m.AddBuff(BuffType::DAMAGE_REDUCTION,INFINITE,ConfigFloat("Permanent Resistance Buff")/100.f);
SETPHASE(IDENTIFY_ARMS);
}break;
case IDENTIFY_ARMS:{
m.F(A::BREAK_TIME)-=fElapsedTime;
if(m.F(A::BREAK_TIME)<=0.f){
m.F(A::CASTING_TIMER)=util::random_range(ConfigFloatArr("Tentacle Move Timer",0),ConfigFloatArr("Tentacle Move Timer",1));
m.F(A::CASTING_TIMER)=util::random_range(ConfigFloatArr("Arm Move Timer",0),ConfigFloatArr("Arm Move Timer",1));
for(std::shared_ptr<Monster>&arm:MONSTER_LIST){
const std::string OCTOPUS_ARM_NAME{"Octopus Arm"};
if(arm->GetName()==OCTOPUS_ARM_NAME){
@ -77,38 +78,32 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s
m.F(A::CASTING_TIMER)-=fElapsedTime;
if(m.F(A::CASTING_TIMER)<=0.f){
int deadMonsterCount{0};
std::vector<vf2d>tempArmLocs;
std::vector<vf2d>unoccupiedArmLocs;
AddAllUnoccupedArmLocations:
std::for_each(m.VEC(A::ARM_LOCATIONS).begin(),m.VEC(A::ARM_LOCATIONS).end(),[&unoccupiedArmLocs](const std::any&armLoc){unoccupiedArmLocs.emplace_back(std::any_cast<vf2d>(armLoc));});
std::vector<std::any>liveArms;
std::copy_if(m.VEC(A::ARM_LIST).begin(),m.VEC(A::ARM_LIST).end(),std::back_inserter(liveArms),[](const std::any&arm){
RemoveOccupiedArmLocationsAndDetectAliveArms:
std::copy_if(m.VEC(A::ARM_LIST).begin(),m.VEC(A::ARM_LIST).end(),std::back_inserter(liveArms),[&unoccupiedArmLocs,&deadMonsterCount](const std::any&arm){
const std::weak_ptr<Monster>&m{std::any_cast<std::weak_ptr<Monster>>(arm)};
return !m.expired()&&m.lock()->IsAlive();
});
for(int index{0};std::any&arm:m.VEC(A::ARM_LIST)){
const std::weak_ptr<Monster>&armM{std::any_cast<std::weak_ptr<Monster>>(arm)};
if(armM.expired()||armM.lock()->IsDead()){
deadMonsterCount++;
tempArmLocs.emplace_back(std::any_cast<vf2d>(m.VEC(A::ARM_LOCATIONS)[index]));
}else{
armM.lock()->V(A::JUMP_TARGET_POS)=std::any_cast<vf2d>(m.VEC(A::ARM_LOCATIONS)[index]);
}
index++;
}
int counter{};
std::for_each(tempArmLocs.begin(),tempArmLocs.end(),[counter](const std::any tempArm){
LOG(std::format("Arm Loc {}: {}",counter,std::any_cast<vf2d>(tempArm).str()));
const bool isLive{!m.expired()&&m.lock()->IsAlive()};
if(isLive)std::erase_if(unoccupiedArmLocs,[&m](const vf2d&armLoc){return m.lock()->GetPos()==armLoc;});
else deadMonsterCount++;
return isLive;
});
RemoveArmLocationsTooFarFromPlayer:
std::erase_if(unoccupiedArmLocs,[maxDist=ConfigPixels("Arm Max Move Distance From Player")](const vf2d&armLoc){return util::distance(game->GetPlayer()->GetPos(),armLoc)>maxDist;});
const bool AtLeastOneArmAlive{deadMonsterCount!=m.VEC(A::ARM_LIST).size()};
if(deadMonsterCount>0&&AtLeastOneArmAlive){
if(deadMonsterCount>0&&AtLeastOneArmAlive&&unoccupiedArmLocs.size()>0){
const std::weak_ptr<Monster>&randomArm{std::any_cast<std::weak_ptr<Monster>>(liveArms[util::random()%liveArms.size()])};
const vf2d&randomLoc{std::any_cast<vf2d>(tempArmLocs[util::random()%tempArmLocs.size()])};
const vf2d&randomLoc{std::any_cast<vf2d>(unoccupiedArmLocs[util::random()%unoccupiedArmLocs.size()])};
randomArm.lock()->PerformAnimation("SUBMERGE");
randomArm.lock()->GetCurrentAnimation().GetTotalAnimationDuration();
randomArm.lock()->SetPhase(strategy,randomArm.lock()->I(A::SUBMERGE_STRAT_ID));
randomArm.lock()->SetPhase("Octopus Arm",randomArm.lock()->I(A::SUBMERGE_STRAT_ID));
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("Tentacle Move Timer",0),ConfigFloatArr("Tentacle Move Timer",1));
m.F(A::CASTING_TIMER)=util::random_range(ConfigFloatArr("Arm Move Timer",0),ConfigFloatArr("Arm Move Timer",1));
}
}break;
}

@ -97,6 +97,7 @@ void Monster::STRATEGY::OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string str
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();
}
});

@ -3,6 +3,9 @@ Add unconscious monster state.
DEMO
====
Finish Octopus Boss
Arena
Add Sherman and Blacksmith story images
@ -11,6 +14,14 @@ Have all song ideas by Nov 1st
- Chapter 4 Stage + boss + outro
- Chapter 5 Stage + boss + outro
Start with a list of all positions, if something matches up remove from list. Remaining items are unoccupied.
Chapter 5 wont have a bonus boss instead there will be the endless arena. During the campaign there will be a 5 or 10 waves easy introduction after chapter 5 is cleared the endless mode unlocks.
You get placed in an arena that changes every 5 waves visually and spawns random monsters that stack up a buff every wave.
Instead of the area buffs i switched to giving highest exp and locking extra lore behind first time wave completions.
Adding new class animations
===========================
Player.txt contains animation names the player has to have loaded.

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 11828
#define VERSION_BUILD 11848
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -1204,7 +1204,7 @@ MonsterStrategy
{
Attack Radius = 600
Attack Wiggle Time Range = 2s,4s
Attack Wiggle Time Range = 1s,1.5s
Attack Arc = 60deg
Attack Wait Time = 1s
@ -1223,6 +1223,12 @@ MonsterStrategy
Giant Octopus
{
# Min, Max duration
Tentacle Move Timer = 15s,25s
Arm Move Timer = 15s,25s
# How far away max the player can be from a pool for the arm to decide to go there.
Arm Max Move Distance From Player = 900
# How resistant the boss is to attacks.
Permanent Resistance Buff = 80%
}
}
Loading…
Cancel
Save