diff --git a/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp b/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp new file mode 100644 index 000000000..6d21d812b --- /dev/null +++ b/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp @@ -0,0 +1,46 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "z64save.h" + +extern "C" PlayState* gPlayState; + +static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0; +#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife") +#define CVAR_BGS_FIX_VALUE CVarGetInteger(CVAR_BGS_FIX_NAME, CVAR_BGS_FIX_DEFAULT) + +void OnReceiveBrokenGiantsKnife(GetItemEntry itemEntry) { + if (itemEntry.itemId != ITEM_SWORD_BGS) { + return; + } + + // Flag wasn't reset because Kokiri or Master Sword was missing, so we need to bypass those checks + int32_t bypassEquipmentChecks = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER); + + int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD); + int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | + (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (allSwordsInEquipment != allSwordFlags) { + return; + } + + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; + if (gPlayState != NULL) { + Interface_LoadItemIcon1(gPlayState, 0); + } + } +} + +void RegisterBrokenGiantsKnifeFix() { + // If enhancement is off, flag should be handled exclusively by vanilla behaviour + COND_HOOK(OnItemReceive, CVAR_BGS_FIX_VALUE || IS_RANDO, OnReceiveBrokenGiantsKnife); +} + +static RegisterShipInitFunc initFunc(RegisterBrokenGiantsKnifeFix, { CVAR_BGS_FIX_NAME, "IS_RANDO" }); diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index e6777644e..cd60f7d8c 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -35,7 +35,6 @@ #include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" -#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" @@ -47,7 +46,6 @@ extern "C" { #include "align_asset_macro.h" #include "macros.h" #include "soh/cvar_prefixes.h" -#include "functions.h" #include "variables.h" #include "functions.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h" @@ -552,42 +550,6 @@ void RegisterResetNaviTimer() { }); } -void RegisterBrokenGiantsKnifeFix() { - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - if (itemEntry.itemId != ITEM_SWORD_BGS) { - return; - } - - int32_t bypassEquipmentChecks = 0; - - if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 0)) { - // Flag wasn't reset because Kokiri or Master Sword was missing, so we need to - // bypass those checks - bypassEquipmentChecks |= (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER); - } else { - // If enhancement is off, flag should be handled exclusively by vanilla behaviour - return; - } - - int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD); - int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | - (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE); - - if (allSwordsInEquipment != allSwordFlags) { - return; - } - - gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); - - if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; - if (gPlayState != NULL) { - Interface_LoadItemIcon1(gPlayState, 0); - } - } - }); -} - //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -1098,7 +1060,6 @@ void InitMods() { RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); - RegisterBrokenGiantsKnifeFix(); RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterRandomizedEnemySizes();