diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index e3b0dc4f..9595a5f8 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -1434,6 +1434,7 @@ void AiL::RenderWorld(float fElapsedTime){ while(dropsAfterLowerIt!=dropsAfterLower.end()){ const int dropInd=*dropsAfterLowerIt; ItemDrop::drops[dropInd].Draw(); + ++dropsAfterLowerIt; } for(const Bullet*const b:bulletsLower){ b->_Draw(); @@ -3164,6 +3165,11 @@ datafile operator ""_A(const char*key,std::size_t len){ return DATA.GetProperty(std::string(key,len)); } +vf2d operator ""_V(const char*key,std::size_t len){ + AiL::OutputDebugInfo(key,len); + return DATA.GetProperty(std::string(key,len)).GetVf2d(); +} + void AiL::OutputDebugInfo(const char*key,std::size_t len){ #ifdef _DEBUG if(utils::datafile::DEBUG_ACCESS_OPTIONS){ diff --git a/Adventures in Lestoria/Bear.cpp b/Adventures in Lestoria/Bear.cpp index 954707b5..b5e24d8a 100644 --- a/Adventures in Lestoria/Bear.cpp +++ b/Adventures in Lestoria/Bear.cpp @@ -59,13 +59,14 @@ void Monster::STRATEGY::BEAR(Monster&m,float fElapsedTime,std::string strategy){ m.I(A::PHASE)=1; m.PerformShootAnimation(); m.F(A::CASTING_TIMER)=ConfigFloat("Chargeup Time"); - m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos(); + //The bear slam attack indicator will move with the bear, and the LOCKON_POS variable will hold a polar coordinate indicating distance and angle for where it should be attacking relative to its position. + m.V(A::LOCKON_POS)=vf2d{distToPlayer,util::angleTo(m.GetPos(),game->GetPlayer()->GetPos())}; m.SetStrategyDrawFunction([](AiL*game,Monster&m,const std::string&strategy){ if(m.IsAlive()){ - game->view.DrawRotatedDecal(m.V(A::LOCKON_POS),GFX["range_indicator.png"].Decal(),0.f,{12.f,12.f},vf2d{ConfigFloat("Smash Attack Diameter"),ConfigFloat("Smash Attack Diameter")}/100.f,{255,255,0,160}); + game->view.DrawRotatedDecal(m.GetPos()+m.V(A::LOCKON_POS).cart(),GFX["range_indicator.png"].Decal(),0.f,{12.f,12.f},vf2d{ConfigFloat("Smash Attack Diameter"),ConfigFloat("Smash Attack Diameter")}/100.f,{255,255,0,160}); } }); - m.RotateTowardsPos(m.V(A::LOCKON_POS)); + m.RotateTowardsPos(m.GetPos()+m.V(A::LOCKON_POS).cart()); }else{ m.target=game->GetPlayer()->GetPos(); RUN_TOWARDS(m,fElapsedTime,"Run Towards"); @@ -82,10 +83,11 @@ void Monster::STRATEGY::BEAR(Monster&m,float fElapsedTime,std::string strategy){ case 2:{ m.F(A::CASTING_TIMER)=std::max(0.f,m.F(A::CASTING_TIMER)-fElapsedTime); if(m.F(A::CASTING_TIMER)==0.f){ - SoundEffect::PlaySFX("Bear Slam Attack",m.V(A::LOCKON_POS)); + float distToPlayer=geom2d::line(m.GetPos(),game->GetPlayer()->GetPos()).length(); + SoundEffect::PlaySFX("Bear Slam Attack",m.GetPos()+m.V(A::LOCKON_POS).cart()); m.I(A::PHASE)=0; m.I(A::BEAR_STOMP_COUNT)++; - geom2d::circleattackCircle={m.V(A::LOCKON_POS),float(operator""_Pixels(ConfigFloat("Smash Attack Diameter"))/2.f)}; + 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())){ if(game->GetPlayer()->Hurt(m.GetAttack(),m.OnUpperLevel(),0.f)){ game->GetPlayer()->Knockup(ConfigFloat("Attack Knockup Duration")); diff --git a/Adventures in Lestoria/BreakingPillar.cpp b/Adventures in Lestoria/BreakingPillar.cpp index 95989472..97b55b08 100644 --- a/Adventures in Lestoria/BreakingPillar.cpp +++ b/Adventures in Lestoria/BreakingPillar.cpp @@ -43,11 +43,6 @@ All rights reserved. using A=Attribute; void Monster::STRATEGY::BREAKING_PILLAR(Monster&m,float fElapsedTime,std::string strategy){ - enum PhaseName{ - INITIALIZE, - IDLE, - }; - if(m.GetHealthRatio()>=ConfigFloat("Break Phase 1 HP % Threshold")/100.f){ m.animation.ModifyDisplaySprite(m.internal_animState,ConfigString("Unbroken Animation Name")); }else diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index c450541a..86150b13 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -795,4 +795,9 @@ void Menu::ReInitializeInputGroup(){ const bool Menu::GameInitialized()const{ return game->GameInitialized(); +} + +const bool Menu::IsMouseOverMenu(){ + if(Menu::stack.size()==0)return false; + return geom2d::overlaps(game->GetMousePos(),geom2d::rect{Menu::stack.back()->pos-"Interface.9PatchSize"_V.x,Menu::stack.back()->size+"Interface.9PatchSize"_V.y*2}); } \ No newline at end of file diff --git a/Adventures in Lestoria/Menu.h b/Adventures in Lestoria/Menu.h index 3bcc3f6a..3890b12f 100644 --- a/Adventures in Lestoria/Menu.h +++ b/Adventures in Lestoria/Menu.h @@ -202,6 +202,7 @@ public: static void IgnoreNextMouseNavigationAttempt(); //Returns whether or not this menu type is currently in the foreground of the game, and thus being interacted with by the user. static bool IsCurrentlyActive(MenuType type); + static const bool IsMouseOverMenu(); //Returns whether the mouse is hovering over any portion of the menu, thus can be used if a menu is not supposed to cover up everything to determine mouse interactions. private: Menu(vf2d pos,vf2d size); static MenuType lastMenuTypeCreated; diff --git a/Adventures in Lestoria/State_OverworldMap.cpp b/Adventures in Lestoria/State_OverworldMap.cpp index 8ab12144..cb6e32a7 100644 --- a/Adventures in Lestoria/State_OverworldMap.cpp +++ b/Adventures in Lestoria/State_OverworldMap.cpp @@ -110,7 +110,7 @@ void State_OverworldMap::OnUserUpdate(AiL*game){ if(game->GetMouse(Mouse::LEFT).bPressed&&geom2d::overlaps(game->GetWorldMousePos(),cp.rect) ||game->KEY_LEFT.Pressed()||game->KEY_RIGHT.Pressed()||game->KEY_UP.Pressed()||game->KEY_DOWN.Pressed() ||(!analogMove&&(abs(game->KEY_SCROLLHORZ_L.Analog())>=0.2f||abs(game->KEY_SCROLLVERT_L.Analog())>=0.2f))){ - bool mouseUsed=game->GetMouse(Mouse::LEFT).bPressed&&geom2d::overlaps(game->GetWorldMousePos(),cp.rect); + bool mouseUsed=game->GetMouse(Mouse::LEFT).bPressed&&geom2d::overlaps(game->GetWorldMousePos(),cp.rect)&&!Menu::IsMouseOverMenu()&&game->IsMouseInsideWindow(); if(Unlock::IsUnlocked(cp)){ if(mouseUsed){ @@ -193,7 +193,7 @@ void State_OverworldMap::Draw(AiL*game){ } bool highlightedAStage=false; for(ConnectionPoint&cp:connections){ - if(Unlock::IsUnlocked(cp)&&geom2d::overlaps(game->GetWorldMousePos(),cp.rect)){ + if(Unlock::IsUnlocked(cp)&&geom2d::overlaps(game->GetWorldMousePos(),cp.rect)&&!Menu::IsMouseOverMenu()&&game->IsMouseInsideWindow()){ drawutil::DrawCrosshairDecalTransformedView(game->view,cp.rect,currentTime); highlightedAStage=true; break; diff --git a/Adventures in Lestoria/StoneGolem.cpp b/Adventures in Lestoria/StoneGolem.cpp index d2797ebe..0674544a 100644 --- a/Adventures in Lestoria/StoneGolem.cpp +++ b/Adventures in Lestoria/StoneGolem.cpp @@ -40,6 +40,7 @@ All rights reserved. #include "MonsterStrategyHelpers.h" #include "AdventuresInLestoria.h" #include "DEFINES.h" +#include "util.h" INCLUDE_game @@ -48,13 +49,43 @@ using A=Attribute; void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string strategy){ enum PhaseName{ INITIALIZE, + SPAWN_PILLAR_PREPARE, + SPAWN_PILLAR_CAST, + STANDARD, }; switch(m.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.phase=SPAWN_PILLAR_PREPARE; + }break; + case SPAWN_PILLAR_PREPARE:{ + m.F(A::RECOVERY_TIME)-=fElapsedTime; + if(m.F(A::RECOVERY_TIME)<=0.f){ + m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos(); + m.PerformAnimation("STONE PILLAR CAST",m.GetFacingDirectionToTarget(m.V(A::LOCKON_POS))); + game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Beginning Phase.Pillar Cast Time"),"range_indicator.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"))),true); + game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Beginning Phase.Pillar Cast Time"),"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)*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; + } + }break; + case SPAWN_PILLAR_CAST:{ + m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)<=0.f){ - m.PerformAnimation("STONE PILLAR CAST",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); + m.I(A::PATTERN_REPEAT_COUNT)--; + if(m.I(A::PATTERN_REPEAT_COUNT)<=0){ + m.phase=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; + } } }break; + case STANDARD:{ + + }break; } } \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 6f76e4fa..812fe17b 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 9578 +#define VERSION_BUILD 9585 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/Campaigns/Boss_2.tmx b/Adventures in Lestoria/assets/Campaigns/Boss_2.tmx index 9cc4c781..c765fdda 100644 --- a/Adventures in Lestoria/assets/Campaigns/Boss_2.tmx +++ b/Adventures in Lestoria/assets/Campaigns/Boss_2.tmx @@ -1,5 +1,5 @@ - + @@ -385,5 +385,16 @@ + + + + + + + + + + + diff --git a/Adventures in Lestoria/assets/config/MonsterStrategies.txt b/Adventures in Lestoria/assets/config/MonsterStrategies.txt index b122ddb4..eff9c2bd 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -886,7 +886,7 @@ MonsterStrategy 6 monsters = 2/s 5 monsters = 2.5/s 4 monsters = 3/s - 3 monsters = 3.5/s + 3 monsters = 3.5/s( 2 monsters = 4/s 1 monster = 4.5/s } @@ -898,7 +898,19 @@ MonsterStrategy } Stone Golem { - + Beginning Phase + { + # Number of pillars to spawn. + Repeat Count = 3 + Pillar Cast Time = 2s + Pillar Cast Delay Time = 0.5s + Pillar Spell Circle Color = 40, 40, 40, 80 + Pillar Spell Insignia Color = 144, 137, 160, 255 + # Degrees/sec. Positive is CW, Negative is CCW. + Pillar Spell Circle Rotation Spd = -30 + # Degrees/sec. Positive is CW, Negative is CCW. + Pillar Spell Insignia Rotation Spd = 50 + } } Breaking Pillar { diff --git a/Adventures in Lestoria/assets/config/Monsters.txt b/Adventures in Lestoria/assets/config/Monsters.txt index fcb01a30..92b3e258 100644 --- a/Adventures in Lestoria/assets/config/Monsters.txt +++ b/Adventures in Lestoria/assets/config/Monsters.txt @@ -1061,7 +1061,7 @@ Monsters NORMAL = 4, 0.4, OneShot BREAK1 = 4, 0.4, OneShot BREAK2 = 4, 0.4, OneShot - DEATH = 1, 0.15, OneShot + CRUMBLE = 6, 0.3, OneShot } Hurt Sound = Warrior Ground Slam diff --git a/Adventures in Lestoria/assets/maps/Monster_Presets.tmx b/Adventures in Lestoria/assets/maps/Monster_Presets.tmx index d2f737e5..1d2df413 100644 --- a/Adventures in Lestoria/assets/maps/Monster_Presets.tmx +++ b/Adventures in Lestoria/assets/maps/Monster_Presets.tmx @@ -1,5 +1,5 @@ - + @@ -26,5 +26,6 @@ + diff --git a/Adventures in Lestoria/assets/maps/Monsters/Stone Golem.tx b/Adventures in Lestoria/assets/maps/Monsters/Stone Golem.tx new file mode 100644 index 00000000..97ae30ea --- /dev/null +++ b/Adventures in Lestoria/assets/maps/Monsters/Stone Golem.tx @@ -0,0 +1,5 @@ + + diff --git a/Adventures in Lestoria/assets/maps/monsters-tileset.png b/Adventures in Lestoria/assets/maps/monsters-tileset.png index 29e816cc..16e60c79 100644 Binary files a/Adventures in Lestoria/assets/maps/monsters-tileset.png and b/Adventures in Lestoria/assets/maps/monsters-tileset.png differ diff --git a/Adventures in Lestoria/config.h b/Adventures in Lestoria/config.h index 75245235..d00db0d0 100644 --- a/Adventures in Lestoria/config.h +++ b/Adventures in Lestoria/config.h @@ -62,6 +62,8 @@ int operator ""_I(const char*key,std::size_t len); float operator ""_F(const char*key,std::size_t len); //Read a double key from the config. double operator ""_D(const char*key,std::size_t len); +//Read a vf2d key from the config. +vf2d operator ""_V(const char*key,std::size_t len); //Read a datafile indexed property from the config. utils::datafile operator ""_A(const char*key,std::size_t len); diff --git a/Adventures in Lestoria/olcUTIL_DataFile.h b/Adventures in Lestoria/olcUTIL_DataFile.h index f0fbd72a..f88a02e4 100644 --- a/Adventures in Lestoria/olcUTIL_DataFile.h +++ b/Adventures in Lestoria/olcUTIL_DataFile.h @@ -129,6 +129,12 @@ namespace olc::utils return std::atoi(GetString(nItem).c_str()); } + // Retrieves the Integer Value of a Property (for a given index) or 0 + inline const vf2d GetVf2d(const size_t nItem = 0) const + { + return {GetReal(0),GetReal(1)}; + } + // Retrieves the Boolean Value of a Property (for a given index) or false inline const bool GetBool(const size_t nItem = 0) const { diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 234fda2a..e274a459 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ