From 20e5ad08a3f59cc2c43143b7f1ce461f313431b6 Mon Sep 17 00:00:00 2001 From: Etienne Mitchell-Bouchard Date: Fri, 12 Jun 2026 01:31:58 -0400 Subject: [PATCH] Implemented both Infinite Bottle Contents and Infinite Fishing Bait cheats --- include/dusk/settings.h | 2 ++ src/d/actor/d_a_alink_bottle.inc | 19 +++++++++++++++++-- src/d/actor/d_a_alink_canoe.inc | 23 ++++++++++++++++++----- src/d/actor/d_a_alink_demo.inc | 5 +++++ src/d/actor/d_a_alink_kandelaar.inc | 5 +++++ src/dusk/settings.cpp | 4 ++++ src/dusk/ui/settings.cpp | 6 ++++++ 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index 7bdb97370e..3366ea3497 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -240,6 +240,8 @@ struct UserSettings { ConfigVar infiniteOil; ConfigVar infiniteOxygen; ConfigVar infiniteRupees; + ConfigVar infiniteBottle; + ConfigVar infiniteBait; ConfigVar enableIndefiniteItemDrops; ConfigVar moonJump; ConfigVar superClawshot; diff --git a/src/d/actor/d_a_alink_bottle.inc b/src/d/actor/d_a_alink_bottle.inc index 8af270df7a..83b17959f4 100644 --- a/src/d/actor/d_a_alink_bottle.inc +++ b/src/d/actor/d_a_alink_bottle.inc @@ -213,7 +213,11 @@ int daAlink_c::commonBottleDrink(BOOL param_0) { } field_0x072c->setFrame(1.0f); - if (mDemo.getDemoType() == daPy_demo_c::DEMO_TYPE_SPECIAL_e) { + bool consumeContents = true; + #if TARGET_PC + consumeContents = !dusk::getSettings().game.infiniteBottle; + #endif + if (mDemo.getDemoType() == daPy_demo_c::DEMO_TYPE_SPECIAL_e && consumeContents) { dComIfGs_setEquipBottleItemIn(mSelectItemId, dItemNo_HALF_MILK_BOTTLE_e); } } else if (mProcVar2.field_0x300c == 0) { @@ -267,7 +271,12 @@ int daAlink_c::commonBottleDrink(BOOL param_0) { } field_0x072c->setFrame(2.0f); - if (mDemo.getDemoType() == daPy_demo_c::DEMO_TYPE_SPECIAL_e) { + + bool consumeContents = true; + #if TARGET_PC + consumeContents = !dusk::getSettings().game.infiniteBottle; + #endif + if (mDemo.getDemoType() == daPy_demo_c::DEMO_TYPE_SPECIAL_e && consumeContents) { dComIfGs_setEquipBottleItemEmpty(mSelectItemId); } @@ -497,7 +506,13 @@ int daAlink_c::procBottleOpen() { } else if (frameCtrl_p->checkPass(11.0f)) { mHeldItemModel->getModelData()->entryTexMtxAnimator(field_0x0720); mProcVar2.field_0x300c = 2; + + #if TARGET_PC + if (!dusk::getSettings().game.infiniteBottle) + dComIfGs_setEquipBottleItemEmpty(mSelectItemId); + #else dComIfGs_setEquipBottleItemEmpty(mSelectItemId); + #endif if (mEquipItem == dItemNo_WATER_BOTTLE_e && mProcVar3.field_0x300e != 0) { seStartOnlyReverb(Z2SE_LK_SPRINKLE_WATER); diff --git a/src/d/actor/d_a_alink_canoe.inc b/src/d/actor/d_a_alink_canoe.inc index fdf1ca0f6a..c184dc43f5 100644 --- a/src/d/actor/d_a_alink_canoe.inc +++ b/src/d/actor/d_a_alink_canoe.inc @@ -1663,7 +1663,12 @@ int daAlink_c::procFishingCast() { field_0x2fc8 = 0; } - if (checkEndResetFlg0(ERFLG0_FISHING_HIT) && mItemMode != 0xFF) { + bool consumesBait = true; + #if TARGET_PC + consumesBait = !dusk::getSettings().game.infiniteBait; + #endif + + if (checkEndResetFlg0(ERFLG0_FISHING_HIT) && mItemMode != 0xFF && consumesBait) { mItemMode = 0xFF; dComIfGs_setBaitItem(0xFF); @@ -1741,10 +1746,18 @@ int daAlink_c::procFishingFood() { mProcVar2.field_0x300c = 1; u16 item = dComIfGp_getSelectItem(mProcVar3.field_0x300e); - if (item == dItemNo_WORM_e || dComIfGp_getSelectItemNum(mProcVar3.field_0x300e) == 1) { - dComIfGs_setEquipBottleItemEmpty(mProcVar3.field_0x300e); - } else { - dComIfGp_addSelectItemNum(mProcVar3.field_0x300e, -1); + + bool consumesContents = true; + #if TARGET_PC + if (dusk::getSettings().game.infiniteBottle) + consumesContents = false; + #endif + if (consumesContents) { + if (item == dItemNo_WORM_e || dComIfGp_getSelectItemNum(mProcVar3.field_0x300e) == 1) { // If Worm or Bee Larva == 1 + dComIfGs_setEquipBottleItemEmpty(mProcVar3.field_0x300e); // Set bottle to empty + } else { // If there are more than 1 Bee Larva left in the bottle + dComIfGp_addSelectItemNum(mProcVar3.field_0x300e, -1); // Substract 1 Bee Larva + } } if (mItemMode != dItemNo_NONE_e) { diff --git a/src/d/actor/d_a_alink_demo.inc b/src/d/actor/d_a_alink_demo.inc index b1eb71a85d..a84d927a08 100644 --- a/src/d/actor/d_a_alink_demo.inc +++ b/src/d/actor/d_a_alink_demo.inc @@ -1300,7 +1300,12 @@ BOOL daAlink_c::checkDeadAction(int param_0) { } } else if (dComIfGs_getLife() == 0 && !checkResetFlg0(RFLG0_UNK_400) && dComIfGs_checkBottle(dItemNo_FAIRY_e)) { makeFairy(¤t.pos, 0); + #if TARGET_PC + if (!dusk::getSettings().game.infiniteBottle) + dComIfGs_setBottleItemIn(dItemNo_FAIRY_e, dItemNo_EMPTY_BOTTLE_e); + #else dComIfGs_setBottleItemIn(dItemNo_FAIRY_e, dItemNo_EMPTY_BOTTLE_e); + #endif } } diff --git a/src/d/actor/d_a_alink_kandelaar.inc b/src/d/actor/d_a_alink_kandelaar.inc index 339ff90ce6..9417e252fe 100644 --- a/src/d/actor/d_a_alink_kandelaar.inc +++ b/src/d/actor/d_a_alink_kandelaar.inc @@ -303,7 +303,12 @@ int daAlink_c::commonKandelaarPour(int param_0) { } field_0x072c->setFrame(2.0f); + #if TARGET_PC + if (!dusk::getSettings().game.infiniteBottle) + dComIfGs_setEquipBottleItemEmpty(mSelectItemId); + #else dComIfGs_setEquipBottleItemEmpty(mSelectItemId); + #endif } } } else if (checkAnmEnd(frameCtrl_p)) { diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 0a58dfd1ec..0e40c108df 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -119,6 +119,8 @@ UserSettings g_userSettings = { .infiniteOil {"game.infiniteOil", false}, .infiniteOxygen {"game.infiniteOxygen", false}, .infiniteRupees {"game.infiniteRupees", false}, + .infiniteBottle {"game.infiniteBottle", false}, + .infiniteBait {"game.infiniteBait", false}, .enableIndefiniteItemDrops {"game.enableIndefiniteItemDrops", false}, .moonJump {"game.moonJump", false}, .superClawshot {"game.superClawshot", false}, @@ -283,6 +285,8 @@ void registerSettings() { Register(g_userSettings.game.infiniteOil); Register(g_userSettings.game.infiniteOxygen); Register(g_userSettings.game.infiniteRupees); + Register(g_userSettings.game.infiniteBottle); + Register(g_userSettings.game.infiniteBait); Register(g_userSettings.game.enableIndefiniteItemDrops); Register(g_userSettings.game.moonJump); Register(g_userSettings.game.superClawshot); diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index c0f1dc235a..1b39cb845a 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -211,6 +211,8 @@ void reset_for_speedrun_mode() { getSettings().game.infiniteOil.setSpeedrunValue(false); getSettings().game.infiniteOxygen.setSpeedrunValue(false); getSettings().game.infiniteRupees.setSpeedrunValue(false); + getSettings().game.infiniteBottle.setSpeedrunValue(false); + getSettings().game.infiniteBait.setSpeedrunValue(false); getSettings().game.enableIndefiniteItemDrops.setSpeedrunValue(false); getSettings().game.moonJump.setSpeedrunValue(false); getSettings().game.superClawshot.setSpeedrunValue(false); @@ -1262,6 +1264,10 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { "Keeps your underwater oxygen meter full."); addCheat( "Infinite Rupees", getSettings().game.infiniteRupees, "Keeps your rupee count full."); + addCheat("Infinite Bottle Contents", getSettings().game.infiniteBottle, + "Using the contents of a bottle does not consume them."); + addCheat("Infinite Fishing Bait", getSettings().game.infiniteBait, + "Catching a fish while bobber fishing with bait does not consume the bait."); addCheat("No Item Timer", getSettings().game.enableIndefiniteItemDrops, "Item drops such as rupees and hearts will never disappear after they drop.");