diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 329a8ee48..bbb5d5998 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1090,6 +1090,29 @@ void RegisterRandomizerSheikSpawn() { }); } +void UpdateHurtContainerModeState(bool newState) { + static bool hurtEnabled = false; + if (hurtEnabled == newState) { + return; + } + + hurtEnabled = newState; + uint16_t getHeartPieces = gSaveContext.sohStats.heartPieces / 4; + uint16_t getHeartContainers = gSaveContext.sohStats.heartContainers; + + if (hurtEnabled) { + gSaveContext.healthCapacity = 320 - ((getHeartPieces + getHeartContainers) * 16); + } else { + gSaveContext.healthCapacity = 48 + ((getHeartPieces + getHeartContainers) * 16); + } +} + +void RegisterHurtContainerModeHandler() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + UpdateHurtContainerModeState(CVarGetInteger("gHurtContainer", 0)); + }); +} + void RegisterRandomizedEnemySizes() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { // Randomized Enemy Sizes @@ -1256,4 +1279,5 @@ void InitMods() { RegisterRandomizedEnemySizes(); RegisterToTMedallions(); NameTag_RegisterHooks(); + RegisterHurtContainerModeHandler(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index 46123f968..43a41449c 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -9,6 +9,7 @@ extern "C" { void UpdateDirtPathFixState(int32_t sceneNum); void UpdateMirrorModeState(int32_t sceneNum); +void UpdateHurtContainerModeState(bool newState); void PatchToTMedallions(); void UpdatePermanentHeartLossState(); void InitMods(); diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 4df2fb960..9f3604219 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1294,6 +1294,14 @@ void DrawEnhancementsMenu() { } } + UIWidgets::Spacer(0); + if (UIWidgets::PaddedEnhancementCheckbox("Hurt Container Mode", "gHurtContainer", true, false)) { + UpdateHurtContainerModeState(CVarGetInteger("gHurtContainer", 0)); + } + UIWidgets::Tooltip("Changes Heart Piece and Heart Container functionality.\n\n" + "- Each Heart Container or full Heart Piece reduces Links hearts by 1.\n" + "- Can be enabled retroactively after a File has already started."); + ImGui::EndMenu(); } diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 7bb3803fc..4c661aad7 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3361,8 +3361,13 @@ void Message_Update(PlayState* play) { } if ((s32)(gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000) { gSaveContext.inventory.questItems ^= 0x40000000; - gSaveContext.healthCapacity += 0x10; - gSaveContext.health += 0x10; + if (!CVarGetInteger("gHurtContainer", 0)) { + gSaveContext.healthCapacity += 0x10; + gSaveContext.health += 0x10; + } else { + gSaveContext.healthCapacity -= 0x10; + gSaveContext.health -= 0x10; + } } if (msgCtx->ocarinaAction != OCARINA_ACTION_CHECK_NOWARP_DONE) { if (sLastPlayedSong == OCARINA_SONG_SARIAS) { diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index f9a54eb2c..6efa962b6 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2278,8 +2278,13 @@ u8 Item_Give(PlayState* play, u8 item) { gSaveContext.sohStats.heartPieces++; return Return_Item(item, MOD_NONE, ITEM_NONE); } else if (item == ITEM_HEART_CONTAINER) { - gSaveContext.healthCapacity += 0x10; - gSaveContext.health += 0x10; + if (!CVarGetInteger("gHurtContainer", 0)) { + gSaveContext.healthCapacity += 0x10; + gSaveContext.health += 0x10; + } else { + gSaveContext.healthCapacity -= 0x10; + gSaveContext.health -= 0x10; + } gSaveContext.sohStats.heartContainers++; return Return_Item(item, MOD_NONE, ITEM_NONE); } else if (item == ITEM_HEART) {