Fix Broken Giant's Knife flag not resetting (#4608)

* Fix Broken Giant's Knife flag not resetting

* Force setting on in rando

* Fix flag when checkbox is toggled
This commit is contained in:
Jordan Longstaff 2025-01-03 02:16:03 -05:00 committed by GitHub
parent 1a040b3198
commit 1b6508556d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 7 deletions

View File

@ -775,6 +775,42 @@ 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
@ -1429,6 +1465,7 @@ void InitMods() {
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterResetNaviTimer();
RegisterBrokenGiantsKnifeFix();
RegisterEnemyDefeatCounts();
RegisterBossDefeatTimestamps();
RegisterAltTrapTypes();

View File

@ -14,6 +14,8 @@
#include "z64.h"
#include "cvar_prefixes.h"
#include "macros.h"
#include "functions.h"
#include "variables.h"
#include "Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/presets.h"
#include "soh/Enhancements/mods.h"
@ -1523,10 +1525,23 @@ void DrawEnhancementsMenu() {
"This will lower them, making activating them easier");
UIWidgets::PaddedEnhancementCheckbox("Fix Zora hint dialogue", CVAR_ENHANCEMENT("FixZoraHintDialogue"), true, false);
UIWidgets::Tooltip("Fixes one Zora's dialogue giving a hint about bringing Ruto's Letter to King Zora to properly occur before moving King Zora rather than after");
if (UIWidgets::PaddedEnhancementCheckbox("Fix hand holding Hammer", "gEnhancements.FixHammerHand", true, false)) {
if (UIWidgets::PaddedEnhancementCheckbox("Fix hand holding Hammer", CVAR_ENHANCEMENT("FixHammerHand"), true, false)) {
UpdatePatchHand();
}
UIWidgets::Tooltip("Fixes Adult Link have a backwards left hand when holding the Megaton Hammer.");
UIWidgets::Tooltip("Fixes Adult Link having a backwards left hand when holding the Megaton Hammer.");
if (UIWidgets::PaddedEnhancementCheckbox(
"Fix Broken Giant's Knife bug", CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), true, false, IS_RANDO,
"This setting is forcefully enabled when you are playing a randomizer.",
UIWidgets::CheckboxGraphics::Checkmark)) {
bool hasGiantsKnife = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON);
bool hasBrokenKnife = CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);
bool knifeIsBroken = gSaveContext.swordHealth == 0.0f;
if (hasGiantsKnife && (hasBrokenKnife != knifeIsBroken)) {
func_800849EC(gPlayState);
}
}
UIWidgets::Tooltip("Fixes the Broken Giant's Knife flag not being reset when Medigoron fixes it");
ImGui::EndMenu();
}

View File

@ -1987,13 +1987,9 @@ u8 Item_Give(PlayState* play, u8 item) {
if (item == ITEM_SWORD_BGS) {
gSaveContext.swordHealth = 8;
// In rando, when buying Giant's Knife, also check
// without the Koriri Sword in case we don't have it
if (ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) ==
((1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) |
(1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)) ||
(IS_RANDO && ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) ==
((1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)))) {
(1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE))) {
gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);