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.
This commit is contained in:
parent
62086cbd92
commit
cfd73ab036
@ -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
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user