Move Broken Giant's Knife fix hook to its own file (#5049)

* Move Broken Giant's Knife fix hook to its own file

* Separate IS_RANDO out of value macro

* Remove redundant extern

* One-line comment
This commit is contained in:
Jordan Longstaff 2025-02-27 22:33:48 -05:00 committed by GitHub
parent 06387060d6
commit 2d78cb561a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 39 deletions

View file

@ -0,0 +1,46 @@
#include <libultraship/bridge.h>
#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" });

View file

@ -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<GameInteractor::OnItemReceive>([](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();