diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index b7622f0c..4383c915 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -1911,58 +1911,6 @@ void AiL::RenderWorld(float fElapsedTime){ } #pragma endregion - for(std::vector>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){ - DamageNumber*dn=(*it).get(); - - #define NumberScalesWithDamage true - #define NormalNumber false - - auto DrawDamageNumber=[&](const bool ScaleWithNumber,std::string_view text,std::paircolorsEnemy,std::paircolorsFriendly,vf2d scaling={1.f,1.f}){ - vf2d textSize=GetTextSizeProp(text)*scaling; - if(!dn->friendly){ - vf2d additionalScaling={1.f,1.f}; - if(ScaleWithNumber)additionalScaling=dn->size; - - textSize*=additionalScaling; - vf2d drawPos=dn->pos-textSize/2.f; - - drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x); - drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y); - - view.DrawShadowStringPropDecal(drawPos,text,colorsEnemy.first,colorsEnemy.second,scaling*additionalScaling); - }else{ - vf2d drawPos=dn->pos-textSize/2.f; - drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x); - drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y); - - view.DrawShadowStringPropDecal(drawPos,text,colorsFriendly.first,colorsFriendly.second,scaling); - } - }; - - switch(dn->type){ - case HEALTH_LOSS:{ - std::string text=std::to_string(dn->damage); - DrawDamageNumber(NumberScalesWithDamage,text,{DARK_RED,{0,0,0,0}},{RED,VERY_DARK_GREY}); - }break; - case HEALTH_GAIN:{ - std::string text="+"+std::to_string(dn->damage); - DrawDamageNumber(NormalNumber,text,{DARK_GREEN,{0,0,0,0}},{GREEN,VERY_DARK_GREY}); - }break; - case MANA_GAIN:{ - std::string text="+"+std::to_string(dn->damage); - DrawDamageNumber(NormalNumber,text,{BLUE,VERY_DARK_GREY},{BLUE,VERY_DARK_GREY}); - }break; - case INTERRUPT:{ - std::string text="Interrupted!"; - DrawDamageNumber(NormalNumber,text,{BLACK,VERY_DARK_GREY},{BLACK,VERY_DARK_GREY},{0.5f,1}); - }break; - case CRIT:{ - std::string text=std::to_string(dn->damage); - DrawDamageNumber(NumberScalesWithDamage,text,{YELLOW,DARK_YELLOW},{BLACK,{0,0,0,0}}); - }break; - } - } - for(std::unique_ptr&m:MONSTER_LIST){ m->strategyDrawOverlay(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy()); } @@ -2008,6 +1956,38 @@ void AiL::RenderHud(){ } } }; + + #pragma region Boss Indicators + if(bossIndicatorPos.has_value()){ + const vf2d&bossIndicator=bossIndicatorPos.value(); + const bool BossIsOutsideView=!geom2d::overlaps(geom2d::rect{view.GetWorldTL(),view.GetWorldVisibleArea()},bossIndicator); + if(BossIsOutsideView){ + + const bool flicker=sinf(GetRunTime())>0.5f&&sinf(GetRunTime())<0.55f; + + #pragma region Side Indicators + const float yPos{std::clamp(view.WorldToScreen(bossIndicator).y,0.f,view.GetWorldVisibleArea().y)}; + + if(bossIndicator.xview.GetWorldBR().x){ + DrawRotatedDecal({float(ScreenWidth()-8),yPos},GFX["bossIndicator.png"].Decal(),0.f,{0,16},{8,1},flicker?RED:DARK_RED); + } + #pragma endregion + #pragma region Top+Bottom Indicators + const float xPos{std::clamp(view.WorldToScreen(bossIndicator).x,0.f,view.GetWorldVisibleArea().x)}; + + if(bossIndicator.yview.GetWorldBR().y){ + DrawRotatedDecal({xPos,float(ScreenHeight()-4)},GFX["bossIndicator.png"].Decal(),PI/2,{0.5f,16.f},{8,1},flicker?RED:DARK_RED); + } + #pragma endregion + } + } + #pragma endregion minimap.Update(); minimap.Draw(); @@ -2040,7 +2020,7 @@ void AiL::RenderHud(){ Pixel healthOutlineCol=BLACK; if(player->GetHealth()/player->GetMaxHealth()<="Player.Health Warning Pct"_F/100.f){ - float runTimeAmt=fmod(GetRuntime(),"Player.Health Warning Flicker Time"_F*2); + float runTimeAmt=fmod(GetRunTime(),"Player.Health Warning Flicker Time"_F*2); if(runTimeAmt<"Player.Health Warning Flicker Time"_F){ healthOutlineCol="Player.Health Warning Outline Color"_Pixel; } @@ -2084,6 +2064,59 @@ void AiL::RenderHud(){ } DisplayBossEncounterInfo(); + + for(std::vector>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){ + DamageNumber*dn=(*it).get(); + + #define NumberScalesWithDamage true + #define NormalNumber false + + auto DrawDamageNumber=[&](const bool ScaleWithNumber,std::string_view text,std::paircolorsEnemy,std::paircolorsFriendly,vf2d scaling={1.f,1.f}){ + vf2d textSize=GetTextSizeProp(text)*scaling; + if(!dn->friendly){ + vf2d additionalScaling={1.f,1.f}; + if(ScaleWithNumber)additionalScaling=dn->size; + + textSize*=additionalScaling; + vf2d drawPos=dn->pos-textSize/2.f; + + drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x); + drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y); + + view.DrawShadowStringPropDecal(drawPos,text,colorsEnemy.first,colorsEnemy.second,scaling*additionalScaling); + }else{ + vf2d drawPos=dn->pos-textSize/2.f; + drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x); + drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y); + + view.DrawShadowStringPropDecal(drawPos,text,colorsFriendly.first,colorsFriendly.second,scaling); + } + }; + + switch(dn->type){ + case HEALTH_LOSS:{ + std::string text=std::to_string(dn->damage); + DrawDamageNumber(NumberScalesWithDamage,text,{DARK_RED,{0,0,0,0}},{RED,VERY_DARK_GREY}); + }break; + case HEALTH_GAIN:{ + std::string text="+"+std::to_string(dn->damage); + DrawDamageNumber(NormalNumber,text,{DARK_GREEN,{0,0,0,0}},{GREEN,VERY_DARK_GREY}); + }break; + case MANA_GAIN:{ + std::string text="+"+std::to_string(dn->damage); + DrawDamageNumber(NormalNumber,text,{BLUE,VERY_DARK_GREY},{BLUE,VERY_DARK_GREY}); + }break; + case INTERRUPT:{ + std::string text="Interrupted!"; + DrawDamageNumber(NormalNumber,text,{BLACK,VERY_DARK_GREY},{BLACK,VERY_DARK_GREY},{0.5f,1}); + }break; + case CRIT:{ + std::string text=std::to_string(dn->damage); + DrawDamageNumber(NumberScalesWithDamage,text,{YELLOW,DARK_YELLOW},{BLACK,{0,0,0,0}}); + }break; + } + } + #ifdef _DEBUG if("debug_player_info"_I){ DrawShadowStringDecal({0,128},player->GetPos().str()); @@ -2390,6 +2423,7 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){ } #pragma endregion + bossIndicatorPos.reset(); SPAWNER_LIST.clear(); SPAWNER_CONTROLLER={}; foregroundTileGroups.clear(); @@ -3775,7 +3809,7 @@ void AiL::ValidateGameStatus(){ void AiL::RenderVersionInfo(){ saveGameDisplayTime=std::max(0.f,saveGameDisplayTime-game->GetElapsedTime()); if(saveGameDisplayTime>3.f){ - DrawShadowStringDecal({4.f,4.f},"Saving Game...",{255,255,255,uint8_t((sin(game->GetRuntime())+1)*127)},{0,0,0,uint8_t((sin(game->GetRuntime())+1)*127)}); + DrawShadowStringDecal({4.f,4.f},"Saving Game...",{255,255,255,uint8_t((sin(game->GetRunTime())+1)*127)},{0,0,0,uint8_t((sin(game->GetRunTime())+1)*127)}); }else if(saveGameDisplayTime>0.f){ uint8_t alpha=uint8_t(util::lerp(0,255,saveGameDisplayTime/3.f)); @@ -4252,6 +4286,8 @@ 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; @@ -4289,6 +4325,8 @@ void AiL::ShowDamageVignetteOverlay(){ } void AiL::GlobalGameUpdates(){ + bossIndicatorPos={}; + levelTime+=GetElapsedTime(); SteamAPI_RunCallbacks(); STEAMINPUT( @@ -4388,4 +4426,8 @@ void AiL::UpdateEntities(){ void AiL::AMonsterIsMarkedForDeletion(){ aMonsterIsMarkedForDeletion=true; +} + +void AiL::SetBossIndicatorPos(const vf2d pos){ + bossIndicatorPos=pos; } \ No newline at end of file diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 9eff1554..c8302068 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -206,6 +206,7 @@ private: Audio audioEngine; SteamKeyboardCallbackHandler*steamKeyboardCallbackListener=nullptr; SteamStatsReceivedHandler*steamStatsReceivedHandlerListener=nullptr; + std::optionalbossIndicatorPos{}; public: AiL(); bool OnUserCreate() override; @@ -345,6 +346,7 @@ public: void UpdateEntities(); Minimap minimap; void AMonsterIsMarkedForDeletion(); //The way this is implemented 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. + void SetBossIndicatorPos(const vf2d pos); struct TileGroupData{ vi2d tilePos; diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp index ccf32d53..065afae0 100644 --- a/Adventures in Lestoria/Item.cpp +++ b/Adventures in Lestoria/Item.cpp @@ -1015,7 +1015,7 @@ const std::string Stats::GetStatsString(const Stats&maxStats,CompactText compact std::string col=""; if(maxStats.attributes.count(attr)&&int(val)>=int(maxStats.attributes.at(attr))){ - Pixel shimmeringCol=PixelLerp({255,196,60},{254,217,133},sin((70*game->GetRuntime())/2.f+0.5f)); + Pixel shimmeringCol=PixelLerp({255,196,60},{254,217,133},sin((70*game->GetRunTime())/2.f+0.5f)); col=util::PixelToHTMLColorCode(shimmeringCol); } diff --git a/Adventures in Lestoria/LevitatingRock.cpp b/Adventures in Lestoria/LevitatingRock.cpp index 89111daf..84a83b32 100644 --- a/Adventures in Lestoria/LevitatingRock.cpp +++ b/Adventures in Lestoria/LevitatingRock.cpp @@ -79,7 +79,7 @@ void LevitatingRock::Update(float fElapsedTime){ if(!RocksHaveLaunched){ deactivated=true; - drawOffsetY=cos(PI*game->GetRuntime())*3.f; + drawOffsetY=cos(PI*game->GetRunTime())*3.f; } else if(targetVel.has_value()){ vel=targetVel.value(); diff --git a/Adventures in Lestoria/LoadingScreen.cpp b/Adventures in Lestoria/LoadingScreen.cpp index ecb3c4d2..5b76ca19 100644 --- a/Adventures in Lestoria/LoadingScreen.cpp +++ b/Adventures in Lestoria/LoadingScreen.cpp @@ -90,7 +90,7 @@ void LoadingScreen::Draw(){ } game->GetPlayer()->GetWalkEAnimation(); Animate2D::FrameSequence&playerWalkE=ANIMATION_DATA[game->GetPlayer()->GetWalkEAnimation()]; - game->DrawPartialRotatedDecal({(float(currentProgress)/totalProgress)*(WINDOW_SIZE.x-48.f),WINDOW_SIZE.y-36.f},playerWalkE.GetFrame(game->GetRuntime()).GetSourceImage()->Decal(),game->GetPlayer()->GetSpinAngle(),{12,12},playerWalkE.GetFrame(game->GetRuntime()).GetSourceRect().pos,playerWalkE.GetFrame(game->GetRuntime()).GetSourceRect().size,playerScale*scale,blendCol); + game->DrawPartialRotatedDecal({(float(currentProgress)/totalProgress)*(WINDOW_SIZE.x-48.f),WINDOW_SIZE.y-36.f},playerWalkE.GetFrame(game->GetRunTime()).GetSourceImage()->Decal(),game->GetPlayer()->GetSpinAngle(),{12,12},playerWalkE.GetFrame(game->GetRunTime()).GetSourceRect().pos,playerWalkE.GetFrame(game->GetRunTime()).GetSourceRect().size,playerScale*scale,blendCol); } } diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index 2d53899f..3847415b 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -271,6 +271,8 @@ bool Monster::Update(float fElapsedTime){ lastFacingDirectionChange+=fElapsedTime; timeSpentAlive+=fElapsedTime; + if(HasArrowIndicator())game->SetBossIndicatorPos(GetPos()); + #pragma region Handle Monster Lifetime and fade timer. if(fadeTimer>0.f){ fadeTimer=std::max(0.f,fadeTimer-fElapsedTime); @@ -338,9 +340,18 @@ bool Monster::Update(float fElapsedTime){ m->Collision(*this); geom2d::line line(pos,m->GetPos()); float dist = line.length(); + while(dist<=0.001){ + line={pos+vf2d{util::random(0.2f)-0.1f,util::random(0.2f)-0.1f},m->GetPos()}; + dist=line.length(); + } m->SetPos(line.rpoint(dist*1.1f)); if(!Immovable()&&m->IsAlive()){ - vel=line.vector().norm()*-128; + float knockbackStrength=1.f; + std::vector knockbackBuffs=m->GetBuffs(COLLISION_KNOCKBACK_STRENGTH); + for(Buff&b:knockbackBuffs){ + knockbackStrength+=b.intensity; + } + Knockback(line.vector().norm()*-128*knockbackStrength); } } } @@ -502,33 +513,11 @@ void Monster::Collision(Player*p){ } } - #pragma region Knockback due to buffs - vf2d knockbackVecNorm=geom2d::line(GetPos(),p->GetPos()).vector().norm(); - float knockbackStrength=0.f; - std::vector knockbackBuffs=GetBuffs(COLLISION_KNOCKBACK_STRENGTH); - for(Buff&b:knockbackBuffs){ - knockbackStrength+=b.intensity; - } - p->Knockback(knockbackVecNorm*knockbackStrength); - #pragma endregion - - B(Attribute::COLLIDED_WITH_PLAYER)=true; Collision(); } void Monster::Collision(Monster&m){ - - #pragma region Knockback due to buffs - vf2d knockbackVecNorm=geom2d::line(GetPos(),m.GetPos()).vector().norm(); - float knockbackStrength=0.f; - std::vector knockbackBuffs=GetBuffs(COLLISION_KNOCKBACK_STRENGTH); - for(Buff&b:knockbackBuffs){ - knockbackStrength+=b.intensity; - } - m.Knockback(knockbackVecNorm*knockbackStrength); - #pragma endregion - Collision(); } void Monster::Collision(){ @@ -892,7 +881,10 @@ geom2d::circleMonster::BulletCollisionHitbox(){ void Monster::Knockback(const vf2d&vel){ //A new angle will be applied, but will be constrained by whichever applied velocity is strongest (either the current velocity, or the new one). This prevents continuous uncapped velocities to knockbacks applied. - float maxVelThreshold=std::max(vel.mag(),this->vel.mag()); + if(vel==vf2d{})return; + float maxVelThreshold; + if(this->vel==vf2d{})maxVelThreshold=vel.mag(); + else maxVelThreshold=std::max(vel.mag(),this->vel.mag()); this->vel+=vel; float newVelAngle=this->vel.polar().y; this->vel=vf2d{maxVelThreshold,newVelAngle}.cart(); diff --git a/Adventures in Lestoria/MonsterData.cpp b/Adventures in Lestoria/MonsterData.cpp index 3efd65a4..22885df6 100644 --- a/Adventures in Lestoria/MonsterData.cpp +++ b/Adventures in Lestoria/MonsterData.cpp @@ -437,7 +437,7 @@ const std::optionalMonsterData::GetLifetime()const{ return lifetime; } const float MonsterData::GetCollisionRadius()const{ - return collisionRadius; + return collisionRadius*0.6f; } const bool MonsterData::HasArrowIndicator()const{ return hasArrowIndicator; diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index c84514ec..429bd49d 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -306,7 +306,10 @@ State::State Player::GetState(){ void Player::Knockback(vf2d vel){ //A new angle will be applied, but will be constrained by whichever applied velocity is strongest (either the current velocity, or the new one). This prevents continuous uncapped velocities to knockbacks applied. - float maxVelThreshold=std::max(vel.mag(),this->vel.mag()); + if(vel==vf2d{})return; + float maxVelThreshold; + if(this->vel==vf2d{})maxVelThreshold=vel.mag(); + else maxVelThreshold=std::max(vel.mag(),this->vel.mag()); this->vel+=vel; float newVelAngle=this->vel.polar().y; this->vel=vf2d{maxVelThreshold,newVelAngle}.cart(); @@ -522,18 +525,27 @@ void Player::Update(float fElapsedTime){ } geom2d::line line(pos,m->GetPos()); float dist = line.length(); + while(dist<=0.001){ + line={pos+vf2d{util::random(0.2f)-0.1f,util::random(0.2f)-0.1f},m->GetPos()}; + dist=line.length(); + } if(!m->Immovable()){ - if(dist<=0.001){ - m->SetPos(m->GetPos()+vf2d{util::random(2)-1,util::random(2)-1}); - }else{ - m->SetPos(line.rpoint(dist*1.1f)); - } + m->SetPos(line.rpoint(dist*1.1f)); } if(m->IsAlive()&&!m->IsNPC()){ //Don't set the knockback if this monster is actually an NPC. Let's just push them around. - Knockback(line.vector().norm()*-128.f); + float knockbackStrength=1.f; + std::vectorknockbackBuffs=m->GetBuffs(COLLISION_KNOCKBACK_STRENGTH); + for(Buff&b:knockbackBuffs){ + knockbackStrength+=b.intensity; + } + Knockback(line.vector().norm()*-128.f*knockbackStrength); } } } + if(!std::isfinite(vel.x)||!std::isfinite(vel.y)){ + ERR(std::format("WARNING! The velocity vector for the player is NOT normal! Current vel:{} . Attempting manual resetting of velocity.",vel.str())); + vel={}; + } if(vel.x>0){ vel.x=std::max(0.f,vel.x-friction*fElapsedTime); } else { diff --git a/Adventures in Lestoria/SaveFile.cpp b/Adventures in Lestoria/SaveFile.cpp index f1f74e57..95e858ad 100644 --- a/Adventures in Lestoria/SaveFile.cpp +++ b/Adventures in Lestoria/SaveFile.cpp @@ -134,7 +134,7 @@ const void SaveFile::SaveGame(){ saveFile["Overworld Map Location"].SetString(State_OverworldMap::GetCurrentConnectionPoint().name); saveFile["Chapter"].SetInt(game->GetCurrentChapter()); saveFile["Save Name"].SetString(std::string(GetSaveFileName())); - saveFile["Game Time"].SetReal(game->GetRuntime()); + saveFile["Game Time"].SetReal(game->GetRunTime()); saveFile["TravelingMerchant"].SetString(std::string(Merchant::GetCurrentTravelingMerchant().GetKeyName())); saveFile["Minimap Display Mode"].SetInt(int(game->minimap.GetMinimapMode())); @@ -216,7 +216,7 @@ const void SaveFile::SaveGame(){ utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat"); } } - metadata.GetProperty(std::format("save{}",saveFileID)).SetReal(game->GetRuntime(),0U); + metadata.GetProperty(std::format("save{}",saveFileID)).SetReal(game->GetRunTime(),0U); metadata.GetProperty(std::format("save{}",saveFileID)).SetInt(game->GetCurrentChapter(),1U); metadata.GetProperty(std::format("save{}",saveFileID)).SetInt(game->GetPlayer()->Level(),2U); metadata.GetProperty(std::format("save{}",saveFileID)).SetString(game->GetPlayer()->GetClassName(),3U); diff --git a/Adventures in Lestoria/State_Death.cpp b/Adventures in Lestoria/State_Death.cpp index 5765085a..cbd6c390 100644 --- a/Adventures in Lestoria/State_Death.cpp +++ b/Adventures in Lestoria/State_Death.cpp @@ -84,7 +84,7 @@ void State_Death::OnUserUpdate(AiL*game){ } Input::StopVibration(); game->SetMosaicEffect(uint8_t(util::lerp(9.f,1.f,(gameSlowdownPct-7)/3.f))); - Input::SetLightbar(PixelLerp(BLACK,DARK_RED,sin(1.5f*game->GetRuntime())/2.f+0.5f)); + Input::SetLightbar(PixelLerp(BLACK,DARK_RED,sin(1.5f*game->GetRunTime())/2.f+0.5f)); } if(gameSlowdownPct<10.f){ diff --git a/Adventures in Lestoria/State_LevelComplete.cpp b/Adventures in Lestoria/State_LevelComplete.cpp index 6b59520b..b6c8252d 100644 --- a/Adventures in Lestoria/State_LevelComplete.cpp +++ b/Adventures in Lestoria/State_LevelComplete.cpp @@ -139,8 +139,8 @@ void State_LevelComplete::DrawOverlay(AiL*game){ game->DrawRotatedDecal(levelUpTextPos+vf2d{2.f,1.f},GFX["overworld_arrow.png"].Decal(),-PI/2,GFX["overworld_arrow.png"].Sprite()->Size(),{1.f,1.f},BLACK); game->DrawRotatedDecal(levelUpTextPos+vf2d{2.f,0.f},GFX["overworld_arrow.png"].Decal(),-PI/2,GFX["overworld_arrow.png"].Sprite()->Size(),{1.f,1.f},YELLOW); - game->DrawShadowStringPropDecal(levelUpTextPos+vf2d{-69.f,4.f},std::format("HP +{}",int(game->GetPlayer()->GetHealthGrowthRate())),PixelLerp({226,234,244},WHITE,sin((40*game->GetRuntime())/2.f+0.5f))); - game->DrawShadowStringPropDecal(levelUpTextPos+vf2d{-69.f,12.f},std::format("ATK+{}",int(game->GetPlayer()->GetAtkGrowthRate())),PixelLerp({226,234,244},WHITE,sin((40*game->GetRuntime())/2.f+0.5f))); + game->DrawShadowStringPropDecal(levelUpTextPos+vf2d{-69.f,4.f},std::format("HP +{}",int(game->GetPlayer()->GetHealthGrowthRate())),PixelLerp({226,234,244},WHITE,sin((40*game->GetRunTime())/2.f+0.5f))); + game->DrawShadowStringPropDecal(levelUpTextPos+vf2d{-69.f,12.f},std::format("ATK+{}",int(game->GetPlayer()->GetAtkGrowthRate())),PixelLerp({226,234,244},WHITE,sin((40*game->GetRunTime())/2.f+0.5f))); } void State_LevelComplete::TurnOffXPSound(){ diff --git a/Adventures in Lestoria/State_OverworldMap.cpp b/Adventures in Lestoria/State_OverworldMap.cpp index dcfff821..46cc7cdc 100644 --- a/Adventures in Lestoria/State_OverworldMap.cpp +++ b/Adventures in Lestoria/State_OverworldMap.cpp @@ -163,7 +163,7 @@ void State_OverworldMap::Draw(AiL*game){ if(!Unlock::IsUnlocked(cp)){ game->view.FillRectDecal(cp.rect.pos,cp.rect.size,{0,0,0,128}); }else{ - float exclamationScale=fmod(game->GetRuntime(),1.0f)<0.2f?1.f:1.2f; + float exclamationScale=fmod(game->GetRunTime(),1.0f)<0.2f?1.f:1.2f; if(!cp.Visited()){ game->view.DrawDecal(cp.rect.pos+vf2d{-1.f,0.f},GFX["exclamation.png"].Decal(),{exclamationScale,exclamationScale},BLACK); game->view.DrawDecal(cp.rect.pos+vf2d{-1.f,-1.f},GFX["exclamation.png"].Decal(),{exclamationScale,exclamationScale}); @@ -209,7 +209,7 @@ void State_OverworldMap::Draw(AiL*game){ direction++; } - float arrowDist=fmod(game->GetRuntime(),1.0f)<0.5f?14:18; + float arrowDist=fmod(game->GetRunTime(),1.0f)<0.5f?14:18; for(auto&[index,medianAngle]:neighbors){ game->view.DrawRotatedDecal(game->GetPlayer()->GetPos()+vf2d{arrowDist,GetAngle(medianAngle)}.cart()+vf2d{0.f,1.f},GFX["overworld_arrow.png"].Decal(),GetAngle(medianAngle),GFX["overworld_arrow.png"].Sprite()->Size()/2,{1.f,1.f},{0,0,0}); diff --git a/Adventures in Lestoria/Stone_Elemental.cpp b/Adventures in Lestoria/Stone_Elemental.cpp index 235f2833..009a2c77 100644 --- a/Adventures in Lestoria/Stone_Elemental.cpp +++ b/Adventures in Lestoria/Stone_Elemental.cpp @@ -96,8 +96,8 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string m.phase=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",m.OnUpperLevel(),vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Pillar").GetSizeMult()/12.f)*1.1f,0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Circle Rotation Spd"))),true); - game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*(MONSTER_DATA.at("Stone Pillar").GetCollisionRadius()*MONSTER_DATA.at("Stone Pillar").GetSizeMult()/12.f)*0.75f,0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Insignia Rotation Spd"))),true); + game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"range_indicator.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"))),true); + game->AddEffect(std::make_unique(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"spell_insignia.png",m.OnUpperLevel(),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"))),true); }break; case 1:{ m.PerformAnimation("ROCK TOSS CAST"); @@ -142,7 +142,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string case SHOOT_STONE_CAST:{ m.F(A::CASTING_TIMER)-=fElapsedTime; if(m.F(A::CASTING_TIMER)>=ConfigFloat("Rock Toss Wait Time")-ConfigFloat("Rock Toss Track Time")){ - m.PerformIdleAnimation(); + m.PerformAnimation("STONE PILLAR CAST"); m.UpdateFacingDirection(game->GetPlayer()->GetPos()); } if(m.F(A::CASTING_TIMER)<=0.f){ diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 8d326255..39acb80d 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 0 -#define VERSION_BUILD 9382 +#define VERSION_BUILD 9413 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/Campaigns/2_1.tmx b/Adventures in Lestoria/assets/Campaigns/2_1.tmx index 148d08e4..97102c46 100644 --- a/Adventures in Lestoria/assets/Campaigns/2_1.tmx +++ b/Adventures in Lestoria/assets/Campaigns/2_1.tmx @@ -1,5 +1,5 @@ - + @@ -1897,5 +1897,13 @@ + + + + + + + + diff --git a/Adventures in Lestoria/assets/bossIndicator.png b/Adventures in Lestoria/assets/bossIndicator.png new file mode 100644 index 00000000..e01260c5 Binary files /dev/null and b/Adventures in Lestoria/assets/bossIndicator.png differ diff --git a/Adventures in Lestoria/assets/bossIndicatorStripe.png b/Adventures in Lestoria/assets/bossIndicatorStripe.png new file mode 100644 index 00000000..2375e51f Binary files /dev/null and b/Adventures in Lestoria/assets/bossIndicatorStripe.png differ diff --git a/Adventures in Lestoria/assets/config/MonsterStrategies.txt b/Adventures in Lestoria/assets/config/MonsterStrategies.txt index 55ef0488..7783aa06 100644 --- a/Adventures in Lestoria/assets/config/MonsterStrategies.txt +++ b/Adventures in Lestoria/assets/config/MonsterStrategies.txt @@ -550,7 +550,7 @@ MonsterStrategy Backpedal Movespeed = 50% - Charge Knockback Amount = 140 + Charge Knockback Amount = 1.4 } Goblin Dagger { diff --git a/Adventures in Lestoria/assets/config/Monsters.txt b/Adventures in Lestoria/assets/config/Monsters.txt index 729039df..e786dd27 100644 --- a/Adventures in Lestoria/assets/config/Monsters.txt +++ b/Adventures in Lestoria/assets/config/Monsters.txt @@ -792,8 +792,8 @@ Monsters MoveSpd = 0% # The Pillar is supposed to be 350 radius. - Size = 350% - Collision Radius = 8 + Size = 300% + Collision Radius = 7 Lifetime = 5s XP = 0 diff --git a/Adventures in Lestoria/assets/config/gfx/gfx.txt b/Adventures in Lestoria/assets/config/gfx/gfx.txt index e7c2b533..f885cc75 100644 --- a/Adventures in Lestoria/assets/config/gfx/gfx.txt +++ b/Adventures in Lestoria/assets/config/gfx/gfx.txt @@ -96,6 +96,7 @@ Images GFX_SpellInsignia = spell_insignia.png GFX_Rock = rock.png GFX_RockOutline = rock_outline.png + GFX_BossIndicator = bossIndicator.png # Ability Icons GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 99adf8e0..d25158cd 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/olcPGEX_ViewPort.h b/Adventures in Lestoria/olcPGEX_ViewPort.h index c5781917..e85ce7f4 100644 --- a/Adventures in Lestoria/olcPGEX_ViewPort.h +++ b/Adventures in Lestoria/olcPGEX_ViewPort.h @@ -658,7 +658,7 @@ void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText pge->SetDrawTarget(nullptr); newDecal->Update(); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos,pge->garbageCollector[key].decal,scale,col); } @@ -673,7 +673,7 @@ void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std:: pge->garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); pge->garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos,pge->garbageCollector[key].decal,scale/4,col); } @@ -701,7 +701,7 @@ void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view s pge->SetDrawTarget(nullptr); newDecal->Update(); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos,pge->garbageCollector[key].decal,scale,col); } @@ -747,8 +747,8 @@ void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view pge->SetDrawTarget(nullptr); newShadowDecal->Update(); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; - pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; + pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},pge->garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos,pge->garbageCollector[key].decal,scale,col); } @@ -795,8 +795,8 @@ void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_ pge->SetDrawTarget(nullptr); newShadowDecal->Update(); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; - pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; + pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},pge->garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos,pge->garbageCollector[key].decal,scale,col); } @@ -812,9 +812,9 @@ void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const pge->garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); pge->garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; std::erase_if(pge->garbageCollector,[&](auto&key){ - if(key.second.expireTimeGetRuntime()){ + if(key.second.expireTimeGetRunTime()){ delete key.second.decal; return true; } @@ -841,7 +841,7 @@ void olc::ViewPort::DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, c pge->garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); pge->garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - pge->garbageCollector[key].expireTime=pge->GetRuntime()+120.0f; + pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f; DrawDecal(pos+vf2d{0,0.5f},pge->garbageCollector[key].decal,scale/4,shadowCol); DrawDecal(pos+vf2d{0.5f,0},pge->garbageCollector[key].decal,scale/4,shadowCol); DrawDecal(pos+vf2d{0.5f,0.5f},pge->garbageCollector[key].decal,scale/4,shadowCol); diff --git a/Adventures in Lestoria/olcPixelGameEngine.h b/Adventures in Lestoria/olcPixelGameEngine.h index aa126699..c0db5e0d 100644 --- a/Adventures in Lestoria/olcPixelGameEngine.h +++ b/Adventures in Lestoria/olcPixelGameEngine.h @@ -1066,7 +1066,7 @@ namespace olc // Specify which Sprite should be the target of drawing functions, use nullptr // to specify the primary screen void SetDrawTarget(Sprite* target); - double GetRuntime() const; + double GetRunTime() const; void SetRuntime(const double runTime); // Gets the current Frames Per Second uint32_t GetFPS() const; @@ -2257,7 +2257,7 @@ namespace olc return 0; } - double PixelGameEngine::GetRuntime() const + double PixelGameEngine::GetRunTime() const { return dRunTime; } void PixelGameEngine::SetRuntime(const double runTime){ @@ -2271,7 +2271,7 @@ namespace olc } void PixelGameEngine::ClearTimedOutGarbage(){ std::erase_if(garbageCollector,[&](auto&key){ - if(key.second.expireTimeUpdate(); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; DrawDecal(pos,garbageCollector[key].decal,scale,col); } @@ -3629,7 +3629,7 @@ namespace olc SetDrawTarget(nullptr); newDecal->Update(); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; DrawDecal(pos,garbageCollector[key].decal,scale,col); } @@ -3675,8 +3675,8 @@ namespace olc SetDrawTarget(nullptr); newShadowDecal->Update(); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; - garbageCollector[key+"_SHADOW"].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; + garbageCollector[key+"_SHADOW"].expireTime=GetRunTime()+120.0f; DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos,garbageCollector[key].decal,scale,col); } @@ -3692,7 +3692,7 @@ namespace olc garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; DrawDecal(pos,garbageCollector[key].decal,scale/4,col); } @@ -3707,7 +3707,7 @@ namespace olc garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ @@ -3729,7 +3729,7 @@ namespace olc garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE); garbageCollector[key].originalStr=std::string(sText.begin(),sText.end()); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; DrawDecal(pos+vf2d{0,0.5f},garbageCollector[key].decal,scale/4,shadowCol); DrawDecal(pos+vf2d{0.5f,0},garbageCollector[key].decal,scale/4,shadowCol); DrawDecal(pos+vf2d{0.5f,0.5f},garbageCollector[key].decal,scale/4,shadowCol); @@ -3778,8 +3778,8 @@ namespace olc SetDrawTarget(nullptr); newShadowDecal->Update(); } - garbageCollector[key].expireTime=GetRuntime()+120.0f; - garbageCollector[key+"_SHADOW"].expireTime=GetRuntime()+120.0f; + garbageCollector[key].expireTime=GetRunTime()+120.0f; + garbageCollector[key+"_SHADOW"].expireTime=GetRunTime()+120.0f; DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos,garbageCollector[key].decal,scale,col); } diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index c8319ef3..43f7e4b5 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ