diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index e89da81fc..463205c60 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -940,6 +940,8 @@ namespace SohImGui { Tooltip("Show dungeon entrances icon only when it should be"); EnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle"); Tooltip("Makes two handed idle animation play, a seemingly finished animation that was disabled on accident in the original game"); + EnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix"); + Tooltip("Fixes a bug where you can permanently miss the Gravedigging Tour Heart Piece"); EnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix"); Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw"); EnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix"); diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index 77dd075c5..d21f140e9 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -35,6 +35,7 @@ void BootCommands_Init() CVar_RegisterS32("gNewDrops", 0); CVar_RegisterS32("gVisualAgony", 0); CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French + CVar_RegisterS32("gGravediggingTourFix", 1); CVar_RegisterS32("gHudColors", 1); //0 = N64 / 1 = NGC / 2 = Custom CVar_RegisterS32("gUseNaviCol", 0); CVar_RegisterS32("gUseTunicsCol", 0); diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 1559b188c..8319c2bc9 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -9,6 +9,10 @@ #include "objects/object_tk/object_tk.h" #define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3) +#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19 +#define ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE 0x1000 + +bool heartPieceSpawned; void EnTk_Init(Actor* thisx, GlobalContext* globalCtx); void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx); @@ -505,6 +509,7 @@ void EnTk_Init(Actor* thisx, GlobalContext* globalCtx) { this->currentReward = -1; this->currentSpot = NULL; this->actionFunc = EnTk_Rest; + heartPieceSpawned = false; } void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -611,13 +616,23 @@ void EnTk_Dig(EnTk* this, GlobalContext* globalCtx) { * Upgrade the purple rupee reward to the heart piece if this * is the first grand prize dig. */ - if (!(gSaveContext.itemGetInf[1] & 0x1000)) { - gSaveContext.itemGetInf[1] |= 0x1000; + // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true. + // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true. + // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag. + if (!heartPieceSpawned && + (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) || + CVar_GetS32("gGravediggingTourFix", 0) && + !Flags_GetCollectible(globalCtx, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) { this->currentReward = 4; + gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE; + heartPieceSpawned = true; } } - Item_DropCollectible(globalCtx, &rewardPos, rewardParams[this->currentReward]); + EnItem00* reward = Item_DropCollectible(globalCtx, &rewardPos, rewardParams[this->currentReward]); + if (this->currentReward == 4) { + reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE; + } } }