Skip to content

Commit

Permalink
Fix Broken Giant's Knife flag not resetting (HarbourMasters#4608)
Browse files Browse the repository at this point in the history
* Fix Broken Giant's Knife flag not resetting

* Force setting on in rando

* Fix flag when checkbox is toggled
  • Loading branch information
JordanLongstaff authored Jan 3, 2025
1 parent 1a040b3 commit 1b65085
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
37 changes: 37 additions & 0 deletions soh/soh/Enhancements/mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1429,6 +1465,7 @@ void InitMods() {
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterResetNaviTimer();
RegisterBrokenGiantsKnifeFix();
RegisterEnemyDefeatCounts();
RegisterBossDefeatTimestamps();
RegisterAltTrapTypes();
Expand Down
19 changes: 17 additions & 2 deletions soh/soh/SohMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
}
Expand Down
6 changes: 1 addition & 5 deletions soh/src/code/z_parameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 1b65085

Please sign in to comment.