Implemented Death Defiance enchant. Correct shadow render strings being square (not using proper Y sizes to create cached text). Move game configuration initialization out to global scope to allow config variables to be used when initializing the AiL class. Release Build 10670.

mac-build
sigonasr2 4 months ago
parent 62086cbd92
commit cfd73ab036
  1. 31
      Adventures in Lestoria Tests/EnchantTests.cpp
  2. 2
      Adventures in Lestoria Tests/EngineTests.cpp
  3. 2
      Adventures in Lestoria Tests/ItemTests.cpp
  4. 2
      Adventures in Lestoria Tests/MonsterTests.cpp
  5. 2
      Adventures in Lestoria Tests/PlayerTests.cpp
  6. 40
      Adventures in Lestoria/AdventuresInLestoria.cpp
  7. 4
      Adventures in Lestoria/AdventuresInLestoria.h
  8. 2
      Adventures in Lestoria/DEFINES.h
  9. 16
      Adventures in Lestoria/MenuLabel.h
  10. 13
      Adventures in Lestoria/Player.cpp
  11. 2
      Adventures in Lestoria/Version.h
  12. 3
      Adventures in Lestoria/assets/config/Interface.txt
  13. 2
      Adventures in Lestoria/assets/config/items/ItemEnchants.txt
  14. 12
      Adventures in Lestoria/olcPGEX_ViewPort.h
  15. 12
      Adventures in Lestoria/olcPixelGameEngine.h
  16. 8
      Adventures in Lestoria/olcUTIL_DataFile.h
  17. BIN
      x64/Release/Adventures in Lestoria.exe

@ -50,6 +50,7 @@ using namespace olc::utils;
INCLUDE_GFX INCLUDE_GFX
INCLUDE_ITEM_DATA INCLUDE_ITEM_DATA
INCLUDE_DAMAGENUMBER_LIST INCLUDE_DAMAGENUMBER_LIST
INCLUDE_INITIALIZEGAMECONFIGURATIONS
extern std::mt19937 rng; extern std::mt19937 rng;
@ -71,6 +72,7 @@ namespace EnchantTests
Player*player; Player*player;
const HWButton*testKey; const HWButton*testKey;
TEST_METHOD_INITIALIZE(PlayerInitialize){ TEST_METHOD_INITIALIZE(PlayerInitialize){
InitializeGameConfigurations();
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run. rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
testGame.reset(new AiL(true)); testGame.reset(new AiL(true));
ItemAttribute::Initialize(); ItemAttribute::Initialize();
@ -260,5 +262,34 @@ namespace EnchantTests
Assert::AreEqual(4.5_Pct+0.5_Pct*i,player->GetHP4RecoveryPct(),0.1_Pct,L"HP Recovery/4 Pct is increasing by 0.5% per 10% missing health."); Assert::AreEqual(4.5_Pct+0.5_Pct*i,player->GetHP4RecoveryPct(),0.1_Pct,L"HP Recovery/4 Pct is increasing by 0.5% per 10% missing health.");
} }
} }
TEST_METHOD(DeathDefianceCheck){
for(int i:std::ranges::iota_view(0,10)){
player->Heal(100);
player->Hurt(1000,player->OnUpperLevel(),player->GetZ());
if(player->IsAlive()){Assert::Fail(L"Player survived while not having the Death Defiance Enchant! THIS SHOULD NOT BE HAPPENING!");}
player->_SetIframes(0.f);
}
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
Inventory::EquipItem(nullRing,EquipSlot::RING1);
nullRing.lock()->EnchantItem("Death Defiance");
player->Heal(100);
for(int i:std::ranges::iota_view(0,10)){
const int prevPlayerHP{player->GetHealth()};
player->Hurt(1,player->OnUpperLevel(),player->GetZ());
Assert::AreNotEqual(prevPlayerHP,player->GetHealth(),L"Death Defiance triggered even though the player did not take lethal damage!");
player->_SetIframes(0.f);
}
bool survivedAtLeastOnce{false};
for(int i:std::ranges::iota_view(0,10)){
player->Heal(100);
player->Hurt(1000,player->OnUpperLevel(),player->GetZ());
if(player->IsAlive()){
survivedAtLeastOnce=true;
break;
}
player->_SetIframes(0.f);
}
Assert::AreEqual(true,survivedAtLeastOnce,L"Player should have survived at least one time with Death Defiance.");
}
}; };
} }

@ -41,6 +41,7 @@ All rights reserved.
using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Microsoft::VisualStudio::CppUnitTestFramework;
INCLUDE_INITIALIZEGAMECONFIGURATIONS
namespace EngineTests namespace EngineTests
{ {
@ -49,6 +50,7 @@ namespace EngineTests
public: public:
std::unique_ptr<AiL>testGame; std::unique_ptr<AiL>testGame;
TEST_METHOD_INITIALIZE(PlayerInitialize){ TEST_METHOD_INITIALIZE(PlayerInitialize){
InitializeGameConfigurations();
testGame.reset(new AiL(true)); testGame.reset(new AiL(true));
} }
TEST_METHOD(StripColorTest){ TEST_METHOD(StripColorTest){

@ -48,6 +48,7 @@ using namespace olc::utils;
INCLUDE_GFX INCLUDE_GFX
INCLUDE_ITEM_DATA INCLUDE_ITEM_DATA
INCLUDE_INITIALIZEGAMECONFIGURATIONS
extern std::mt19937 rng; extern std::mt19937 rng;
@ -61,6 +62,7 @@ namespace ItemTests
Player*player; Player*player;
HWButton*testKey; HWButton*testKey;
TEST_METHOD_INITIALIZE(ItemInitialize){ TEST_METHOD_INITIALIZE(ItemInitialize){
InitializeGameConfigurations();
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run. rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
testGame.reset(new AiL(true)); testGame.reset(new AiL(true));
ItemAttribute::Initialize(); ItemAttribute::Initialize();

@ -50,6 +50,7 @@ INCLUDE_game
INCLUDE_GFX INCLUDE_GFX
INCLUDE_DAMAGENUMBER_LIST INCLUDE_DAMAGENUMBER_LIST
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
INCLUDE_INITIALIZEGAMECONFIGURATIONS
TEST_MODULE_INITIALIZE(AiLTestSuite) TEST_MODULE_INITIALIZE(AiLTestSuite)
{ {
@ -65,6 +66,7 @@ namespace MonsterTests
#pragma region Setup Functions #pragma region Setup Functions
//Makes MONSTER_DATA["TestName"] available. //Makes MONSTER_DATA["TestName"] available.
void SetupTestMonster(){ void SetupTestMonster(){
InitializeGameConfigurations();
testGame.reset(new AiL(true)); testGame.reset(new AiL(true));
ItemAttribute::Initialize(); ItemAttribute::Initialize();
ItemInfo::InitializeItems(); ItemInfo::InitializeItems();

@ -49,6 +49,7 @@ using namespace olc::utils;
INCLUDE_GFX INCLUDE_GFX
INCLUDE_ITEM_DATA INCLUDE_ITEM_DATA
INCLUDE_DAMAGENUMBER_LIST INCLUDE_DAMAGENUMBER_LIST
INCLUDE_INITIALIZEGAMECONFIGURATIONS
extern std::mt19937 rng; extern std::mt19937 rng;
@ -62,6 +63,7 @@ namespace PlayerTests
Player*player; Player*player;
HWButton*testKey; HWButton*testKey;
TEST_METHOD_INITIALIZE(PlayerInitialize){ TEST_METHOD_INITIALIZE(PlayerInitialize){
InitializeGameConfigurations();
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run. rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
testGame.reset(new AiL(true)); testGame.reset(new AiL(true));
ItemAttribute::Initialize(); ItemAttribute::Initialize();

@ -161,15 +161,33 @@ float AiL::SIZE_CHANGE_SPEED=1;
AiL::AiL(bool testingMode){ AiL::AiL(bool testingMode){
olc_SetTestingMode(testingMode); olc_SetTestingMode(testingMode);
GFX.Reset(); GFX.Reset();
DATA.Reset();
MONSTER_LIST.clear(); MONSTER_LIST.clear();
InitializeGameConfigurations();
#pragma region Extra Config Initializations
if(TestingModeEnabled()){ //Unit Test-specific custom configurations.
std::string CONFIG_PATH = "config_path"_S;
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
ITEM_CONFIG = CONFIG_PATH + "item-test_config"_S;
ITEM_SET_CONFIG = CONFIG_PATH + "item_set-test_config"_S;
utils::datafile::Read(DATA,ITEM_CONFIG,',',datafile::OverwriteMode::OVERWRITE);
utils::datafile::Read(DATA,ITEM_SET_CONFIG,',',datafile::OverwriteMode::OVERWRITE);
auto keys=DATA.GetProperty("ItemConfiguration");
for(auto&[key,value]:keys){
std::string config=DATA["ItemConfiguration"][key].GetString();
utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config,',',datafile::OverwriteMode::OVERWRITE);
}
}
DEBUG_PATHFINDING="debug_pathfinding"_I;
#pragma endregion
sAppName="GAME_NAME"_S; sAppName="GAME_NAME"_S;
game=this; game=this;
gameStarted=time(NULL); gameStarted=time(NULL);
} }
void AiL::InitializeGameConfigurations(){ void InitializeGameConfigurations(){
DATA.Reset();
utils::datafile::Read(DATA,"assets/config/configuration.txt"); utils::datafile::Read(DATA,"assets/config/configuration.txt");
std::filesystem::create_directories("save_file_path"_S); std::filesystem::create_directories("save_file_path"_S);
@ -205,11 +223,6 @@ void AiL::InitializeGameConfigurations(){
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S; std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S; std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
if(TestingModeEnabled()){ //Unit Test-specific custom configurations.
ITEM_CONFIG = CONFIG_PATH + "item-test_config"_S;
ITEM_SET_CONFIG = CONFIG_PATH + "item_set-test_config"_S;
}
utils::datafile::Read(DATA,ITEM_CONFIG); utils::datafile::Read(DATA,ITEM_CONFIG);
utils::datafile::Read(DATA,ITEM_SET_CONFIG); utils::datafile::Read(DATA,ITEM_SET_CONFIG);
} }
@ -229,8 +242,6 @@ void AiL::InitializeGameConfigurations(){
utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config); utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config);
} }
DEBUG_PATHFINDING="debug_pathfinding"_I;
std::vector<std::string>values=DATA.GetProperty("class_list").GetValues(); std::vector<std::string>values=DATA.GetProperty("class_list").GetValues();
for(const std::string&cl:values){ for(const std::string&cl:values){
LOG(cl); LOG(cl);
@ -2060,10 +2071,9 @@ void AiL::RenderHud(){
hudOverlay.Draw(); hudOverlay.Draw();
Pixel vignetteOverlayColor="Interface.Vignette Color"_Pixel;
const float vignetteTotalDisplayTime="Interface.Vignette Appearance Time"_F+"Interface.Vignette Fadeout Time"_F; const float vignetteTotalDisplayTime="Interface.Vignette Appearance Time"_F+"Interface.Vignette Fadeout Time"_F;
if(vignetteDisplayTime<"Interface.Vignette Fadeout Time"_F)vignetteOverlayColor.a=util::lerp(0,255,vignetteDisplayTime/"Interface.Vignette Fadeout Time"_F); if(vignetteDisplayTime<"Interface.Vignette Fadeout Time"_F)vignetteOverlayCol.a=util::lerp(0,255,vignetteDisplayTime/"Interface.Vignette Fadeout Time"_F);
DrawDecal({0,0},GFX["vignette.png"].Decal(),{1.f,1.f},vignetteOverlayColor); DrawDecal({0,0},GFX["vignette.png"].Decal(),{1.f,1.f},vignetteOverlayCol);
} }
void AiL::RenderCooldowns(){ void AiL::RenderCooldowns(){
@ -3080,6 +3090,7 @@ int main(const int argn,char**args)
} }
} }
{ {
InitializeGameConfigurations();
AiL demo; AiL demo;
demo.UsingSteamAPI(usingSteam); demo.UsingSteamAPI(usingSteam);
@ -4334,8 +4345,9 @@ const float AiL::GetEncounterDuration()const{
return encounterDuration; return encounterDuration;
} }
void AiL::ShowDamageVignetteOverlay(){ void AiL::ShowDamageVignetteOverlay(const Pixel col){
vignetteDisplayTime="Interface.Vignette Appearance Time"_F+"Interface.Vignette Fadeout Time"_F; vignetteDisplayTime="Interface.Vignette Appearance Time"_F+"Interface.Vignette Fadeout Time"_F;
vignetteOverlayCol=col;
} }
void AiL::GlobalGameUpdates(){ void AiL::GlobalGameUpdates(){

@ -229,6 +229,7 @@ private:
float lastLockOnTargetTime{}; float lastLockOnTargetTime{};
void AdminConsole(); void AdminConsole();
virtual bool OnConsoleCommand(const std::string& sCommand)override final; virtual bool OnConsoleCommand(const std::string& sCommand)override final;
Pixel vignetteOverlayCol{"Interface.Vignette Color"_Pixel};
public: public:
AiL(bool testingMode=false); AiL(bool testingMode=false);
bool OnUserCreate() override; bool OnUserCreate() override;
@ -362,7 +363,7 @@ public:
void UpdateMonsters(); void UpdateMonsters();
void ActivateActionSetForAllControllers(InputActionSetHandle_t actionSetHandle); void ActivateActionSetForAllControllers(InputActionSetHandle_t actionSetHandle);
const float GetEncounterDuration()const; const float GetEncounterDuration()const;
void ShowDamageVignetteOverlay(); void ShowDamageVignetteOverlay(const Pixel="Interface.Vignette Color"_Pixel);
void GlobalGameUpdates(); void GlobalGameUpdates();
const bool QuitRequested()const; const bool QuitRequested()const;
void SetQuitAllowed(bool quittingAllowed); //Locks the game from quitting during sensitive operations such as file saving/loading. void SetQuitAllowed(bool quittingAllowed); //Locks the game from quitting during sensitive operations such as file saving/loading.
@ -377,7 +378,6 @@ public:
Overlay&GetOverlay(); Overlay&GetOverlay();
void SetWindSpeed(vf2d newWindSpd); void SetWindSpeed(vf2d newWindSpd);
const vf2d&GetWindSpeed()const; const vf2d&GetWindSpeed()const;
void InitializeGameConfigurations();
void InitializePlayer(); void InitializePlayer();
void SetWorldZoom(float newZoomScale); void SetWorldZoom(float newZoomScale);
//Plays the correct footstep sound based on player's current tile. //Plays the correct footstep sound based on player's current tile.

@ -73,6 +73,8 @@ using MonsterSpawnerID=int;
#define ACCESS_PLAYER Player*p=game->GetPlayer(); #define ACCESS_PLAYER Player*p=game->GetPlayer();
#define INCLUDE_INITIALIZEGAMECONFIGURATIONS extern void InitializeGameConfigurations();
#define VARIANTS float,int,std::string,bool,vf2d,std::vector<std::any>,size_t #define VARIANTS float,int,std::string,bool,vf2d,std::vector<std::any>,size_t
#undef INFINITE #undef INFINITE
#define INFINITE 999999 #define INFINITE 999999

@ -92,15 +92,15 @@ protected:
vf2d adjustedScale={scale,scale}; vf2d adjustedScale={scale,scale};
vf2d labelTextSize= vf2d labelTextSize=
proportional? proportional?
vf2d(game->GetWrappedTextSizeProp(finalLabel,rect.size.x-2,adjustedScale)): vf2d(game->GetWrappedTextSizeProp(finalLabel,rect.size.x-4,adjustedScale)):
vf2d(game->GetWrappedTextSize(finalLabel,rect.size.x-2,adjustedScale)); vf2d(game->GetWrappedTextSize(finalLabel,rect.size.x-4,adjustedScale));
if(fitToLabel){ if(fitToLabel){
labelTextSize= labelTextSize=
proportional? proportional?
vf2d(game->GetTextSizeProp(finalLabel)*adjustedScale): vf2d(game->GetTextSizeProp(finalLabel)*adjustedScale):
vf2d(game->GetTextSize(finalLabel)*adjustedScale); vf2d(game->GetTextSize(finalLabel)*adjustedScale);
float sizeRatio=(labelTextSize.x)/(rect.size.x-2); float sizeRatio=(labelTextSize.x)/(rect.size.x-4);
if(sizeRatio>1){ if(sizeRatio>1){
adjustedScale.x/=sizeRatio; adjustedScale.x/=sizeRatio;
labelTextSize.x/=sizeRatio; labelTextSize.x/=sizeRatio;
@ -110,7 +110,7 @@ protected:
vf2d drawPos=vf2d{-1,0}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered. vf2d drawPos=vf2d{-1,0}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
if(!centered){ if(!centered){
if(rightAlign){ if(rightAlign){
drawPos=vf2d{rect.pos.x+rect.size.x-labelTextSize.x-2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. drawPos=vf2d{rect.pos.x+rect.size.x-labelTextSize.x-4,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
}else{ //Left Align }else{ //Left Align
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
} }
@ -138,15 +138,15 @@ protected:
}else{ }else{
if(shadow){ if(shadow){
if(proportional){ if(proportional){
window.DrawShadowStringPropDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-2,1.0f); window.DrawShadowStringPropDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
}else{ }else{
window.DrawShadowStringDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-2,1.0f); window.DrawShadowStringDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
} }
}else{ }else{
if(proportional){ if(proportional){
window.DrawStringPropDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-2,1.0f); window.DrawStringPropDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
}else{ }else{
window.DrawStringDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-2,1.0f); window.DrawStringDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
} }
} }
} }

@ -903,10 +903,19 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag dama
if(Menu::IsMenuOpen()&&mod_dmg>0)Menu::CloseAllMenus(); if(Menu::IsMenuOpen()&&mod_dmg>0)Menu::CloseAllMenus();
const bool tookLethalDamage{int(mod_dmg)>=hp};
bool survivedHitDueToDefiance{false};
if(tookLethalDamage&&game->GetPlayer()->HasEnchant("Death Defiance"))survivedHitDueToDefiance=util::random(1.f)<="Death Defiance"_ENC["LETHAL DAMAGE AVOID CHANCE"]/100.f;
if(!IsDOT&&mod_dmg>0)game->ShowDamageVignetteOverlay(); if(!IsDOT&&mod_dmg>0){
Pixel vignetteOverlayCol{"Interface.Vignette Color"_Pixel};
if(tookLethalDamage&&survivedHitDueToDefiance)vignetteOverlayCol="Interface.Vignette Death Defiance Color"_Pixel;
game->ShowDamageVignetteOverlay(vignetteOverlayCol);
}
hp=std::max(0,hp-int(mod_dmg)); if(tookLethalDamage&&survivedHitDueToDefiance)ApplyIframes("Death Defiance"_ENC["LETHAL DAMAGE SURVIVE IFRAME TIME"]);
else hp=std::max(0,hp-int(mod_dmg));
if(!IsAlive()&&GameState::STATE!=GameState::states[States::DEATH])GameState::ChangeState(States::DEATH); if(!IsAlive()&&GameState::STATE!=GameState::states[States::DEATH])GameState::ChangeState(States::DEATH);

@ -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 10653 #define VERSION_BUILD 10670
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -30,6 +30,9 @@ Interface
# Damage Vignette Overlay Color # Damage Vignette Overlay Color
Vignette Color = 218, 44, 143, 255 Vignette Color = 218, 44, 143, 255
# Damage Vignette Death Defiance Overlay Color
Vignette Death Defiance Color = 79, 255, 255, 255
# The original health display color. # The original health display color.
HUD Health Display Color = 255,255,255,255 HUD Health Display Color = 255,255,255,255

@ -608,6 +608,8 @@ Item Enchants
Description = "{LETHAL DAMAGE AVOID CHANCE}% chance to avoid taking lethal damage." Description = "{LETHAL DAMAGE AVOID CHANCE}% chance to avoid taking lethal damage."
LETHAL DAMAGE AVOID CHANCE = 30% LETHAL DAMAGE AVOID CHANCE = 30%
# If the player took lethal damage, they are given iframes to survive longer.
LETHAL DAMAGE SURVIVE IFRAME TIME = 2.0s
# Stat, Lowest, Highest Value # Stat, Lowest, Highest Value
# Stat Modifier[0] = ..., 0, 0 # Stat Modifier[0] = ..., 0, 0

@ -650,7 +650,7 @@ void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
pge->garbageCollector[key].decal=newDecal; pge->garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=pge->garbageCollector[key].decal; newDecal=pge->garbageCollector[key].decal;
@ -698,7 +698,7 @@ void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view s
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
pge->garbageCollector[key].decal=newDecal; pge->garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=pge->garbageCollector[key].decal; newDecal=pge->garbageCollector[key].decal;
@ -730,7 +730,7 @@ void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.x/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
pge->garbageCollector[key].decal=newDecal; pge->garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=pge->garbageCollector[key].decal; newDecal=pge->garbageCollector[key].decal;
@ -743,7 +743,7 @@ void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale; vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
Decal*newShadowDecal=nullptr; Decal*newShadowDecal=nullptr;
if(!ShadowRerenderRequired){ if(!ShadowRerenderRequired){
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.x/scale.x*4)+adjustedShadowSizeFactor.y*2)); newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal; pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
}else{ }else{
newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal; newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal;
@ -782,7 +782,7 @@ void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.x/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
pge->garbageCollector[key].decal=newDecal; pge->garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=pge->garbageCollector[key].decal; newDecal=pge->garbageCollector[key].decal;
@ -795,7 +795,7 @@ void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale; vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
Decal*newShadowDecal=nullptr; Decal*newShadowDecal=nullptr;
if(!ShadowRerenderRequired){ if(!ShadowRerenderRequired){
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.x/scale.x*4)+adjustedShadowSizeFactor.y*2)); newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal; pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
}else{ }else{
newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal; newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal;

@ -3499,7 +3499,7 @@ namespace olc
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
garbageCollector[key].decal=newDecal; garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=garbageCollector[key].decal; newDecal=garbageCollector[key].decal;
@ -3531,7 +3531,7 @@ namespace olc
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
garbageCollector[key].decal=newDecal; garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=garbageCollector[key].decal; newDecal=garbageCollector[key].decal;
@ -3563,7 +3563,7 @@ namespace olc
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.x/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
garbageCollector[key].decal=newDecal; garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=garbageCollector[key].decal; newDecal=garbageCollector[key].decal;
@ -3576,7 +3576,7 @@ namespace olc
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale; vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
Decal*newShadowDecal=nullptr; Decal*newShadowDecal=nullptr;
if(!ShadowRerenderRequired){ if(!ShadowRerenderRequired){
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.x/scale.x*4)+adjustedShadowSizeFactor.y*2)); newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
}else{ }else{
newShadowDecal=garbageCollector[key+"_SHADOW"].decal; newShadowDecal=garbageCollector[key+"_SHADOW"].decal;
@ -3673,7 +3673,7 @@ namespace olc
if(imageSize.x<1||imageSize.y<1)return; if(imageSize.x<1||imageSize.y<1)return;
Decal*newDecal=nullptr; Decal*newDecal=nullptr;
if(!RerenderRequired){ if(!RerenderRequired){
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.x/scale.x)); newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
garbageCollector[key].decal=newDecal; garbageCollector[key].decal=newDecal;
}else{ }else{
newDecal=garbageCollector[key].decal; newDecal=garbageCollector[key].decal;
@ -3686,7 +3686,7 @@ namespace olc
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale; vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
Decal*newShadowDecal=nullptr; Decal*newShadowDecal=nullptr;
if(!ShadowRerenderRequired){ if(!ShadowRerenderRequired){
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.x/scale.x*4)+adjustedShadowSizeFactor.y*2)); newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
}else{ }else{
newShadowDecal=garbageCollector[key+"_SHADOW"].decal; newShadowDecal=garbageCollector[key+"_SHADOW"].decal;

@ -73,6 +73,10 @@ namespace olc::utils
class datafile class datafile
{ {
public: public:
enum class OverwriteMode{
NO_OVERWRITE,
OVERWRITE,
};
inline datafile() = default; inline datafile() = default;
inline static bool DEBUG_ACCESS_OPTIONS=false; inline static bool DEBUG_ACCESS_OPTIONS=false;
inline static bool INITIAL_SETUP_COMPLETE=false; inline static bool INITIAL_SETUP_COMPLETE=false;
@ -325,7 +329,7 @@ namespace olc::utils
return false; return false;
} }
inline static bool Read(datafile& n, const std::string& sFileName, const char sListSep = ',') inline static bool Read(datafile& n, const std::string& sFileName, const char sListSep = ',', const OverwriteMode mode=OverwriteMode::NO_OVERWRITE)
{ {
bool previousSetupState=INITIAL_SETUP_COMPLETE; bool previousSetupState=INITIAL_SETUP_COMPLETE;
INITIAL_SETUP_COMPLETE=false; INITIAL_SETUP_COMPLETE=false;
@ -393,7 +397,7 @@ namespace olc::utils
sPropName = line.substr(0, x); sPropName = line.substr(0, x);
trim(sPropName); trim(sPropName);
auto&top=stkPath.top().get(); auto&top=stkPath.top().get();
if(stkPath.top().get().HasProperty(sPropName))ERR(std::format("WARNING! Duplicate key found! Key {} already exists! Duplicate line: {}",sPropName,line)); if(mode==OverwriteMode::NO_OVERWRITE&&stkPath.top().get().HasProperty(sPropName))ERR(std::format("WARNING! Duplicate key found! Key {} already exists! Duplicate line: {}",sPropName,line));
// Extract the property value, which is all characters after // Extract the property value, which is all characters after
// the first assignment operator, trim any whitespace from ends // the first assignment operator, trim any whitespace from ends

Loading…
Cancel
Save