diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 0edd3d04..c69926ff 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -349,6 +349,10 @@ + + + + @@ -575,6 +579,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index 73f186aa..0e82ccea 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -435,6 +435,9 @@ Header Files + + Header Files + @@ -740,6 +743,9 @@ Source Files\Interface + + Source Files + diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index bd7ef6f3..ad3f2759 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -199,6 +199,9 @@ bool AiL::OnUserCreate(){ InitializeLevels(); + healthCounter.Initialize(&player->hp,"Interface.HUD Health Tick Rate"_F,"Interface.HUD Health Display Color"_Pixel,"Interface.HUD Heal Damage Color"_Pixel,"Interface.HUD Take Damage Color"_Pixel,"Interface.HUD Health Change Time"_F); + manaCounter.Initialize(&player->mana,"Interface.HUD Mana Tick Rate"_F,"Interface.HUD Mana Display Color"_Pixel,"Interface.HUD Restore Mana Color"_Pixel,"Interface.HUD Reduce Mana Color"_Pixel,"Interface.HUD Mana Change Time"_F); + //Initialize Camera. camera=Camera2D{WINDOW_SIZE}; camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); @@ -1402,6 +1405,9 @@ Player*AiL::GetPlayer(){ } void AiL::RenderHud(){ + healthCounter.Update(); + manaCounter.Update(); + auto RenderAimingCursor=[&](){ if(Input::UsingGamepad()&&Input::AxesActive()){ vf2d aimingLocation=player->GetAimingLocation(); @@ -1453,10 +1459,10 @@ void AiL::RenderHud(){ DrawDecal({2,2},GFX["heart.png"].Decal()); DrawDecal({2,20},GFX["mana.png"].Decal()); - std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X"; - std::string text_mana=std::to_string(player->GetMana()); - DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2},INFINITE); - DrawShadowStringPropDecal({24,23},text_mana,{192,192,255},BLACK,{1.5f,1.5f},INFINITE); + std::string text=player->GetHealth()>0?std::to_string(healthCounter.GetDisplayValue()):"X"; + std::string text_mana=std::to_string(manaCounter.GetDisplayValue()); + DrawShadowStringPropDecal({20,3},text,healthCounter.GetDisplayColor(),BLACK,{2,2},INFINITE); + DrawShadowStringPropDecal({24,23},text_mana,manaCounter.GetDisplayColor(),BLACK,{1.5f,1.5f},INFINITE); if(player->notEnoughManaDisplay.second>0){ std::string displayText="Not enough mana for "+player->notEnoughManaDisplay.first+"!"; DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)}-GetTextSizeProp(displayText)/2,displayText,DARK_RED,VERY_DARK_RED); @@ -2106,10 +2112,8 @@ void AiL::ChangePlayerClass(Class cl){ player.reset(NEW Witch(player.get())); }break; } - player->level=level; + player->level=1; player->levelCap=levelCap; - player->totalXPEarned=totalXPEarned; - player->currentLevelXP=currentLevelXP; player->stats=previousStats; player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt()); player->hp=player->GetBaseStat("Health"); @@ -2120,6 +2124,10 @@ void AiL::ChangePlayerClass(Class cl){ player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal()); player->money=oldMoney; player->cooldownSoundInstance=cooldownSoundInstance; + player->AddXP(totalXPEarned); + player->AddAccumulatedXP(totalXPEarned); + game->healthCounter.UpdateNumberPointer(&player->hp); + game->manaCounter.UpdateNumberPointer(&player->mana); sig::Animation::SetupPlayerAnimations(); GetPlayer()->UpdateIdleAnimation(DOWN); GetPlayer()->SetItem1UseFunc(itemAbility1); diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 3daef371..696631ad 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -55,6 +55,7 @@ All rights reserved. #include "Audio.h" #include "olcPGEX_SplashScreen.h" #include "olcPixelGameEngine.h" +#include "DynamicCounter.h" #define CreateBullet(type) BULLET_LIST.push_back(std::make_unique(type #define EndBullet )); @@ -137,6 +138,8 @@ private: float fadeInDuration=0; float fadeOutTotalTime=0; bool disableFadeIn=false; + DynamicCounter healthCounter; + DynamicCounter manaCounter; void ValidateGameStatus(); #ifndef __EMSCRIPTEN__ diff --git a/Adventures in Lestoria/DynamicCounter.cpp b/Adventures in Lestoria/DynamicCounter.cpp new file mode 100644 index 00000000..82f35bcf --- /dev/null +++ b/Adventures in Lestoria/DynamicCounter.cpp @@ -0,0 +1,99 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2023 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion + +#include "DynamicCounter.h" +#include "AdventuresInLestoria.h" +#include "DEFINES.h" + +INCLUDE_game + +DynamicCounter::DynamicCounter(){} + +void DynamicCounter::Initialize(const int*number,float tickRate,Pixel originalCol,Pixel increaseCol,Pixel decreaseCol,float colorChangeTime){ + this->targetNumber=number; + this->tickRate=tickRate; + this->originalCol=originalCol; + this->increaseCol=increaseCol; + this->decreaseCol=decreaseCol; + this->colorChangeTime=colorChangeTime; +} + +void DynamicCounter::Update(){ + if(targetNumber==nullptr)ERR("WARNING! This dynamic counter has not been properly initialized! Call Initialize() first!"); + targetChangedTimer=std::max(0.f,targetChangedTimer-game->GetElapsedTime()); + + bool targetNumberChanged=*targetNumber!=lastTargetNumber; + + tickTimer+=game->GetElapsedTime(); + while(tickTimer>tickRate){ + tickTimer-=tickRate; + if(displayNumber!=int(*targetNumber)){ + if(displayNumber>int(*targetNumber)){ + displayNumber--; + + if(targetNumberChanged){ + adjustedCol=decreaseCol; + targetChangedTimer=colorChangeTime; + } + }else{ + displayNumber++; + + if(targetNumberChanged){ + adjustedCol=increaseCol; + targetChangedTimer=colorChangeTime; + } + } + } + } + + lastTargetNumber=int(*targetNumber); + + displayCol=PixelLerp(adjustedCol,originalCol,1-(targetChangedTimer/colorChangeTime)); +} + +const int&DynamicCounter::GetDisplayValue()const{ + return displayNumber; +} + +const Pixel&DynamicCounter::GetDisplayColor()const{ + return displayCol; +} + +void DynamicCounter::UpdateNumberPointer(const int*newPtr){ + targetNumber=newPtr; +} \ No newline at end of file diff --git a/Adventures in Lestoria/DynamicCounter.h b/Adventures in Lestoria/DynamicCounter.h new file mode 100644 index 00000000..f74223d7 --- /dev/null +++ b/Adventures in Lestoria/DynamicCounter.h @@ -0,0 +1,63 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2023 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once + +#include "olcPixelGameEngine.h" + +class DynamicCounter{ +public: + DynamicCounter(); + void Initialize(const int*number,float tickRate=0.01f,Pixel originalCol=WHITE,Pixel increaseCol=WHITE,Pixel decreaseCol=WHITE,float colorChangeTime=0.4f); + void Update(); + const int&GetDisplayValue()const; + const Pixel&GetDisplayColor()const; + void UpdateNumberPointer(const int*newPtr); +private: + int displayNumber; + const int*targetNumber=nullptr; + int lastTargetNumber; + float targetChangedTimer; + float colorChangeTime; + float tickRate; + float tickTimer; + Pixel originalCol; + Pixel displayCol; + Pixel adjustedCol; + Pixel increaseCol; + Pixel decreaseCol; +}; \ No newline at end of file diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index 4debdffd..6dfa5d68 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -1203,9 +1203,9 @@ const float Player::GetDamageReductionPct()const{ void Player::AddXP(const uint32_t xpGain){ currentLevelXP+=xpGain; totalXPEarned+=xpGain; - uint32_t nextLevelXP=NextLevelXPRequired(); if(Level()nextLevelXP){ + uint32_t nextLevelXP=NextLevelXPRequired(); + while(currentLevelXP>nextLevelXP){ currentLevelXP-=nextLevelXP; level++; OnLevelUp(); diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt index f49a84dd..157290a2 100644 --- a/Adventures in Lestoria/TODO.txt +++ b/Adventures in Lestoria/TODO.txt @@ -16,7 +16,6 @@ Settings Menu January 31st ============ -Make new unlocked nodes more obvious, made neighboring nodes more obvious Implement Ursule, Mother of Bears Boss Story proofreading/correcting/storyboarding @@ -27,7 +26,6 @@ Story proofreading/correcting/storyboarding - Export/Import Save Files Online/Offline - Lock up unimplemented classes. -- Don't enable all stage plates normally. - Add Death screen (Zoom in on fatal blow, slow time down... Display some game over text... Allow retry or return to world map.) diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 56634d79..ad79f529 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 6264 +#define VERSION_BUILD 6271 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/config/Interface.txt b/Adventures in Lestoria/assets/config/Interface.txt index 5ee84070..2cc4c511 100644 --- a/Adventures in Lestoria/assets/config/Interface.txt +++ b/Adventures in Lestoria/assets/config/Interface.txt @@ -14,4 +14,34 @@ Interface # The text color of input keys. InputButtonTextCol = 175,199,191,255 + + # The original health display color. + HUD Health Display Color = 255,255,255,255 + + # The color the HUD changes when we take damage. + HUD Take Damage Color = 128,0,0,255 + + # The color the HUD changes when we take damage. + HUD Heal Damage Color = 0,192,0,255 + + # The amount of time it takes for the health to go from a damaging color back to its original color. + HUD Health Change Time = 0.4s + + # How long between each reduction/addition of health. + HUD Health Tick Rate = 0.01s + + # The original mana display color. + HUD Mana Display Color = 192,192,255,255 + + # The color the HUD changes when we take damage. + HUD Reduce Mana Color = 192,192,255,255 + + # The color the HUD changes when we take damage. + HUD Restore Mana Color = 192,192,255,255 + + # The amount of time it takes for the health to go from a damaging color back to its original color. + HUD Mana Change Time = 0.4s + + # How long between each reduction/addition of health. + HUD Mana Tick Rate = 0.01s } \ No newline at end of file diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index bf15321b..4430a127 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ