From f7d6a4713993b2b462b59697c53bd0f6c939f0dc Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Thu, 13 Feb 2025 04:09:58 -0500 Subject: [PATCH 1/5] Fix issues leftover from PR #5023 (#5054) --- soh/soh/Enhancements/randomizer/context.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index d2eb4f2e1ab..9ae705295ff 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -174,8 +174,17 @@ void Context::GenerateLocationPool() { location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO )) || + (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || - (location.GetRCType() == RCTYPE_FISH && mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OFF)) || + (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) || + (location.GetRCType() == RCTYPE_FISH && ( + mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OFF) || + (mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OVERWORLD) && location.GetScene() == SCENE_FISHING_POND) || + (mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_POND) && (location.GetScene() != SCENE_FISHING_POND || + (mOptions[RSK_FISHSANITY_AGE_SPLIT].Is(RO_GENERIC_OFF) && ( + location.GetRandomizerCheck() >= RC_LH_ADULT_FISH_1 && location.GetRandomizerCheck() <= RC_LH_ADULT_LOACH)) + )) + )) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OFF)) || (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || (location.GetRCType() == RCTYPE_FREESTANDING && From dbf7fcf7756b04b3782f65b5ce5d490ab946bbe2 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Thu, 13 Feb 2025 04:10:27 -0500 Subject: [PATCH 2/5] explicitly exclude ganon + triforce completed (#5050) --- .../Enhancements/randomizer/randomizer_check_tracker.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 0b5178621a8..a84922ba707 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -80,7 +80,6 @@ bool initialized; bool doAreaScroll; bool previousShowHidden = false; bool hideShopUnshuffledChecks = true; -bool hideTriforceCompleted = true; bool alwaysShowGS = false; std::map startingShopItem = { { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 }, @@ -1192,8 +1191,6 @@ void LoadSettings() { showLinksPocket = IS_RANDO ? // don't show Link's Pocket if not randomizer, or if rando and pocket is disabled OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING :false; - hideTriforceCompleted = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != RO_GENERIC_ON : false; if (IS_RANDO) { switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) { @@ -1300,7 +1297,8 @@ bool IsCheckShuffled(RandomizerCheck rc) { OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && (loc->GetRCType() != RCTYPE_SHOP || (showShops && OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1).enGirlAShopItem == 50)) && - (rc != RC_TRIFORCE_COMPLETED || !hideTriforceCompleted) && + (rc != RC_TRIFORCE_COMPLETED) && + (rc != RC_GANON) && (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized From 668040562fae802d7e416d15e6201585d9d075aa Mon Sep 17 00:00:00 2001 From: aMannus Date: Fri, 14 Feb 2025 21:29:22 +0100 Subject: [PATCH 3/5] Autosave Overhaul (#5022) * Autosave interval based * Move to save on soft reset, remove adjustable interval * Use new BeforeExitGame hook to prevent non-existent data problems * Fix check tracker crash, remove BeforeExitGame hook * update comment --- soh/include/functions.h | 1 - soh/soh/Enhancements/Autosave.cpp | 78 ++++++++++++++++++ soh/soh/Enhancements/Autosave.h | 4 + soh/soh/Enhancements/debugconsole.cpp | 1 - soh/soh/Enhancements/enhancementTypes.h | 9 -- soh/soh/Enhancements/mods.cpp | 82 ------------------- soh/soh/Enhancements/presets.h | 5 +- .../Enhancements/randomizer/randomizer.cpp | 4 + .../randomizer/randomizer_check_tracker.cpp | 4 +- soh/soh/SohGui/SohGui.cpp | 1 - soh/soh/SohGui/SohMenuBar.cpp | 12 ++- soh/soh/config/ConfigMigrators.h | 1 - soh/src/code/z_play.c | 8 -- 13 files changed, 96 insertions(+), 114 deletions(-) create mode 100644 soh/soh/Enhancements/Autosave.cpp create mode 100644 soh/soh/Enhancements/Autosave.h diff --git a/soh/include/functions.h b/soh/include/functions.h index 8f902c5a8df..147500c6609 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -1073,7 +1073,6 @@ uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, in u8 Item_Give(PlayState* play, u8 item); u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry); u8 Item_CheckObtainability(u8 item); -void PerformAutosave(PlayState* play, u8 item); void Inventory_DeleteItem(u16 item, u16 invSlot); s32 Inventory_ReplaceItem(PlayState* play, u16 oldItem, u16 newItem); s32 Inventory_HasEmptyBottle(void); diff --git a/soh/soh/Enhancements/Autosave.cpp b/soh/soh/Enhancements/Autosave.cpp new file mode 100644 index 00000000000..74b548dab09 --- /dev/null +++ b/soh/soh/Enhancements/Autosave.cpp @@ -0,0 +1,78 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Notification/Notification.h" +#include "soh/ShipInit.hpp" +#include "soh/SaveManager.h" + +extern "C" { +extern PlayState* gPlayState; +#include "functions.h" +#include "variables.h" +} + +static uint64_t lastSaveTimestamp = GetUnixTimestamp(); + +#define CVAR_AUTOSAVE_NAME CVAR_ENHANCEMENT("Autosave") +#define CVAR_AUTOSAVE_DEFAULT AUTOSAVE_OFF +#define CVAR_AUTOSAVE_VALUE CVarGetInteger(CVAR_AUTOSAVE_NAME, CVAR_AUTOSAVE_DEFAULT) +#define THREE_MINUTES_IN_UNIX 3 * 60000 + +typedef enum { + AUTOSAVE_OFF, + AUTOSAVE_ON, +} AutosaveOptions; + +bool Autosave_CanSave() { + + // Don't save when in title screen + // Don't save the first 60 frames to not save the magic meter when it's still in the animation of filling it. + // Don't save in Ganon's fight and chamber of sages because of master sword and remember save location issues. + if (!GameInteractor::IsSaveLoaded(true) || gPlayState->gameplayFrames < 60 || + gPlayState->sceneNum == SCENE_GANON_BOSS || gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { + return false; + } + + return true; +} + +void Autosave_PerformSave() { + Play_PerformSave(gPlayState); + + // Send notification + Notification::Emit({ + .message = "Game autosaved", + }); +} + +void Autosave_IntervalSave() { + // Check if the interval has passed in minutes. + uint64_t currentTimestamp = GetUnixTimestamp(); + if ((currentTimestamp - lastSaveTimestamp) < THREE_MINUTES_IN_UNIX) { + return; + } + + // If save available to create, do it and reset the interval. + // Interval gets extra check for being paused to avoid rare issues like bypassing shop + // rupees draining after buying an item. Since the interval can just retry until it + // passes, it can use more conditions without hampering the player experience. + if (Autosave_CanSave() && !GameInteractor::IsGameplayPaused()) { + + // Reset timestamp, set icon timer to show autosave icon for 5 seconds (100 frames) + lastSaveTimestamp = currentTimestamp; + + Autosave_PerformSave(); + } +} + +void Autosave_SoftResetSave() { + if (Autosave_CanSave()) { + Autosave_PerformSave(); + } +} + +void RegisterAutosave() { + COND_HOOK(GameInteractor::OnGameFrameUpdate, CVAR_AUTOSAVE_VALUE, Autosave_IntervalSave); + COND_HOOK(GameInteractor::OnExitGame, CVAR_AUTOSAVE_VALUE, [](int32_t fileNum) { Autosave_SoftResetSave(); }); +} + +static RegisterShipInitFunc initFunc(RegisterAutosave, { CVAR_AUTOSAVE_NAME }); diff --git a/soh/soh/Enhancements/Autosave.h b/soh/soh/Enhancements/Autosave.h new file mode 100644 index 00000000000..202fcde4fab --- /dev/null +++ b/soh/soh/Enhancements/Autosave.h @@ -0,0 +1,4 @@ +typedef enum { + AUTOSAVE_OFF, + AUTOSAVE_ON, +} AutosaveOptions; diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 7037f9b0aaa..5df00dfaba6 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -208,7 +208,6 @@ static bool ResetHandler(std::shared_ptr Console, std::vectorrunning = false; GameInteractor::Instance->ExecuteHooks(gSaveContext.fileNum); diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index 4b2f825f52b..db96a770001 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -52,15 +52,6 @@ typedef enum { ENEMY_RANDOMIZER_RANDOM_SEEDED, } EnemyRandomizerMode; -typedef enum { - AUTOSAVE_OFF, - AUTOSAVE_LOCATION_AND_MAJOR_ITEMS, - AUTOSAVE_LOCATION_AND_ALL_ITEMS, - AUTOSAVE_LOCATION, - AUTOSAVE_MAJOR_ITEMS, - AUTOSAVE_ALL_ITEMS -} AutosaveType; - typedef enum { BOOTSEQUENCE_DEFAULT, BOOTSEQUENCE_AUTHENTIC, diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index bbfcf105221..e6777644e43 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -135,87 +135,6 @@ void RegisterOcarinaTimeTravel() { }); } -void AutoSave(GetItemEntry itemEntry) { - u8 item = itemEntry.itemId; - bool performSave = false; - // Don't autosave immediately after buying items from shops to prevent getting them for free! - // Don't autosave in the Chamber of Sages since resuming from that map breaks the game - // Don't autosave during the Ganon fight when picking up the Master Sword - if ((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.ship.pendingSale == ITEM_NONE) && - (gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_BOSS) && (gPlayState->sceneNum != SCENE_CHAMBER_OF_THE_SAGES)) { - if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) { - // Autosave for all items - performSave = true; - - } else if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_MAJOR_ITEMS)) && (item != ITEM_NONE)) { - // Autosave for major items - if (itemEntry.modIndex == 0) { - switch (item) { - case ITEM_STICK: - case ITEM_NUT: - case ITEM_BOMB: - case ITEM_BOW: - case ITEM_SEEDS: - case ITEM_FISHING_POLE: - case ITEM_MAGIC_SMALL: - case ITEM_MAGIC_LARGE: - case ITEM_INVALID_4: - case ITEM_INVALID_5: - case ITEM_INVALID_6: - case ITEM_INVALID_7: - case ITEM_HEART: - case ITEM_RUPEE_GREEN: - case ITEM_RUPEE_BLUE: - case ITEM_RUPEE_RED: - case ITEM_RUPEE_PURPLE: - case ITEM_RUPEE_GOLD: - case ITEM_INVALID_8: - case ITEM_STICKS_5: - case ITEM_STICKS_10: - case ITEM_NUTS_5: - case ITEM_NUTS_10: - case ITEM_BOMBS_5: - case ITEM_BOMBS_10: - case ITEM_BOMBS_20: - case ITEM_BOMBS_30: - case ITEM_ARROWS_SMALL: - case ITEM_ARROWS_MEDIUM: - case ITEM_ARROWS_LARGE: - case ITEM_SEEDS_30: - case ITEM_NONE: - break; - case ITEM_BOMBCHU: - case ITEM_BOMBCHUS_5: - case ITEM_BOMBCHUS_20: - if (!CVarGetInteger(CVAR_ENHANCEMENT("EnableBombchuDrops"), 0)) { - performSave = true; - } - break; - default: - performSave = true; - break; - } - } else if (itemEntry.modIndex == 1 && item != RG_ICE_TRAP) { - performSave = true; - } - } else if (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS || - CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS || - CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION) { - performSave = true; - } - if (performSave) { - Play_PerformSave(gPlayState); - performSave = false; - } - } -} - -void RegisterAutoSave() { - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { AutoSave(itemEntry); }); - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { AutoSave(itemEntry); }); - GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { AutoSave(GET_ITEM_NONE); }); -} - void RegisterRupeeDash() { GameInteractor::Instance->RegisterGameHook([]() { if (!CVarGetInteger(CVAR_ENHANCEMENT("RupeeDash"), 0)) { @@ -1168,7 +1087,6 @@ void InitMods() { TimeSavers_Register(); RegisterTTS(); RegisterOcarinaTimeTravel(); - RegisterAutoSave(); RegisterDaytimeGoldSkultullas(); RegisterRupeeDash(); RegisterShadowTag(); diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index d61ff6ade6b..83b0e94d5e6 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -157,7 +157,6 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("GSCutscene"), CVAR_ENHANCEMENT("RestoreRBAValues"), CVAR_ENHANCEMENT("SkipSaveConfirmation"), - CVAR_ENHANCEMENT("Autosave"), CVAR_ENHANCEMENT("DisableCritWiggle"), CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), CVAR_ENHANCEMENT("SkipArrowAnimation"), @@ -754,7 +753,7 @@ const std::vector enhancedPresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubisFix"), 1), // Autosave - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 1), // Bombchu shop doesn't sell out, and 10 bombchus cost 99 instead of 100 PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterBombchuShopping"), 1), @@ -887,7 +886,7 @@ const std::vector randomizerPresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubisFix"), 1), // Autosave - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 1), // Customize Fishing Behaviour PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index d1ca49162ef..44831c7c045 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -39,6 +39,7 @@ #include "soh/util.h" #include "fishsanity.h" #include "randomizerTypes.h" +#include "soh/Notification/Notification.h" extern std::map rcAreaNames; @@ -4105,6 +4106,9 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { gSaveContext.ship.stats.gameComplete = 1; Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); Play_PerformSave(play); + Notification::Emit({ + .message = "Game autosaved", + }); GameInteractor_SetTriforceHuntCreditsWarpActive(true); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a84922ba707..e3b07b672b3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1382,7 +1382,9 @@ void UpdateAllAreas() { } void UpdateAreas(RandomizerCheckArea area) { - areasFullyChecked[area] = areaChecksGotten[area] == checksByArea.find(area)->second.size(); + if (checksByArea.contains(area)) { + areasFullyChecked[area] = areaChecksGotten[area] == checksByArea.find(area)->second.size(); + } } void UpdateAllOrdering() { diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index 84a44b0525a..8d7a4ba45c5 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -64,7 +64,6 @@ namespace SohGui { static const char* subPowers[8] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6], allPowers[7] }; static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] }; static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" }; - static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" }; static const char* bonkDamageValues[8] = { "No Damage", "0.25 Heart", diff --git a/soh/soh/SohGui/SohMenuBar.cpp b/soh/soh/SohGui/SohMenuBar.cpp index e6337dae663..bad852f7a36 100644 --- a/soh/soh/SohGui/SohMenuBar.cpp +++ b/soh/soh/SohGui/SohMenuBar.cpp @@ -45,6 +45,7 @@ #include "soh/Enhancements/randomizer/Plandomizer.h" #include "soh/Enhancements/TimeDisplay/TimeDisplay.h" #include "soh/AboutWindow.h" +#include "soh/Enhancements/Autosave.h" // FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but // they don't work how I expect them to so I added that because it looked good when I eyeballed it @@ -104,7 +105,6 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large static const char* subPowers[8] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6], allPowers[7] }; static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] }; static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" }; - static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" }; static const char* bootSequenceLabels[3] = { "Default", "Authentic", "File Select" }; static const char* DebugSaveFileModes[3] = { "Off", "Vanilla", "Maxed" }; static const char* DekuStickCheat[3] = { "Normal", "Unbreakable", "Unbreakable + Always on Fire" }; @@ -1569,13 +1569,11 @@ void DrawEnhancementsMenu() { ImGui::EndMenu(); } - UIWidgets::PaddedSeparator(false, true); + UIWidgets::PaddedSeparator(); - // Autosave enum value of 1 is the default in presets and the old checkbox "on" state for backwards compatibility - UIWidgets::PaddedText("Autosave", false, true); - UIWidgets::EnhancementCombobox(CVAR_ENHANCEMENT("Autosave"), autosaveLabels, AUTOSAVE_OFF); - UIWidgets::Tooltip("Automatically save the game when changing locations and/or obtaining items\n" - "Major items exclude rupees and health/magic/ammo refills (but include bombchus unless bombchu drops are enabled)"); + UIWidgets::EnhancementCheckbox("Autosave", CVAR_ENHANCEMENT("Autosave")); + UIWidgets::Tooltip("Save the game automatically on a 3 minute interval and when soft-resetting the game.\n\n" + "The interval autosave will wait if the game is paused in any way (dialogue, pause screen up, cutscenes)."); UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f); diff --git a/soh/soh/config/ConfigMigrators.h b/soh/soh/config/ConfigMigrators.h index 3a566f4934e..29cbb07747e 100644 --- a/soh/soh/config/ConfigMigrators.h +++ b/soh/soh/config/ConfigMigrators.h @@ -145,7 +145,6 @@ namespace SOH { { MigrationAction::Rename, "gAskToEquip", "gEnhancements.AskToEquip" }, { MigrationAction::Rename, "gAssignableTunicsAndBoots", "gEnhancements.AssignableTunicsAndBoots" }, { MigrationAction::Rename, "gAuthenticLogo", "gEnhancements.AuthenticLogo" }, - { MigrationAction::Rename, "gAutosave", "gEnhancements.Autosave" }, { MigrationAction::Rename, "gBetterFW", "gEnhancements.BetterFarore" }, { MigrationAction::Rename, "gBetterOwl", "gEnhancements.BetterOwl" }, { MigrationAction::Rename, "gBlueFireArrows", "gEnhancements.BlueFireArrows" }, diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 0b6db75b1c0..11536917113 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -2206,13 +2206,5 @@ void Play_PerformSave(PlayState* play) { // Restore temp B values back gSaveContext.equips.buttonItems[0] = prevB; gSaveContext.buttonStatus[0] = prevStatus; - - uint8_t triforceHuntCompleted = - IS_RANDO && - gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == (Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1) && - Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT); - if (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF || triforceHuntCompleted) { - Overlay_DisplayText(3.0f, "Game Saved"); - } } } From 6df5abc30b177bc3cdf2d1f86aa0b7ddc5610edc Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Fri, 14 Feb 2025 15:30:11 -0500 Subject: [PATCH 4/5] Fix ER + Fishsanity settings combos (#5061) --- soh/soh/Enhancements/randomizer/3drando/fill.cpp | 2 +- soh/soh/Enhancements/randomizer/context.cpp | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 9c2bff0441d..ff3413e98aa 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -602,7 +602,7 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce auto message = "Location " + Rando::StaticData::GetLocation(ctx->GetItemLocation(loc)->GetRandomizerCheck())->GetName() + " not reachable\n"; - SPDLOG_DEBUG(message); + LUSLOG_DEBUG("%s", message.c_str()); #ifndef ENABLE_DEBUG break; #endif diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 9ae705295ff..ba9ab6d2cfd 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -178,12 +178,14 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) || (location.GetRCType() == RCTYPE_FISH && ( - mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OFF) || + mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OFF) || mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_HYRULE_LOACH) || (mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_OVERWORLD) && location.GetScene() == SCENE_FISHING_POND) || - (mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_POND) && (location.GetScene() != SCENE_FISHING_POND || - (mOptions[RSK_FISHSANITY_AGE_SPLIT].Is(RO_GENERIC_OFF) && ( - location.GetRandomizerCheck() >= RC_LH_ADULT_FISH_1 && location.GetRandomizerCheck() <= RC_LH_ADULT_LOACH)) - )) + (mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_POND) && location.GetScene() != SCENE_FISHING_POND) || + ((mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_POND) || mOptions[RSK_FISHSANITY].Is(RO_FISHSANITY_BOTH)) && + (mOptions[RSK_FISHSANITY_AGE_SPLIT].Is(RO_GENERIC_OFF) && ( + location.GetRandomizerCheck() >= RC_LH_ADULT_FISH_1 && location.GetRandomizerCheck() <= RC_LH_ADULT_LOACH) + ) + ) )) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OFF)) || (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || From 20a9f4190659c2108437a798d87605e86e8c49ef Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 14 Feb 2025 12:32:25 -0800 Subject: [PATCH 5/5] remove unused `VB_SHOULD`s (#5056) * remove an unused should * another unused * remove more unused * one more * remove case * more cases for unused shoulds --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 7 ------- .../vanilla-behavior/GIVanillaBehavior.h | 18 ------------------ .../Enhancements/randomizer/hook_handlers.cpp | 3 --- 3 files changed, 28 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 96220f0574a..aabe5d67ab2 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -522,13 +522,6 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } - // Replace the blue warp transitions with ones that lead back to the chamber of sages - case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { - DoorWarp1* blueWarp = va_arg(args, DoorWarp1*); - BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); - *should = false; - break; - } // Spawn clean blue warps (no ruto, adult animation, etc) case VB_SPAWN_BLUE_WARP: { switch (gPlayState->sceneNum) { diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 96453dff86b..a9118c77617 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -212,9 +212,6 @@ typedef enum { // - None VB_BIGGORON_CONSIDER_TRADE_COMPLETE, - // # UNUSED - VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, - // #### `result` // Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT // ```c @@ -335,9 +332,6 @@ typedef enum { // - None VB_DEKU_STICK_BURN_OUT, - // # UNUSED - VB_DEKU_UPDATE_BURNING_DEKU_STICK, - // #### `result` // ```c // Flags_GetItemGetInf(ITEMGETINF_30) @@ -730,12 +724,6 @@ typedef enum { // - None VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, - // # UNUSED - VB_GIVE_ITEM_GORON_RUBY, - - // # UNUSED - VB_GIVE_ITEM_KOKIRI_EMERALD, - // #### `result` // ```c // true @@ -904,9 +892,6 @@ typedef enum { // - None VB_GIVE_ITEM_ZELDAS_LULLABY, - // # UNUSED - VB_GIVE_ITEM_ZORA_SAPPHIRE, - // #### `result` // ```c // false @@ -1390,9 +1375,6 @@ typedef enum { // - None VB_PLAY_NABOORU_CAPTURED_CS, - // # UNUSED - VB_PLAY_ODD_POTION_ANIM, - // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index da22818944b..5eee3541a4e 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1667,9 +1667,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_GIVE_ITEM_STRENGTH_1: case VB_GIVE_ITEM_ZELDAS_LETTER: case VB_GIVE_ITEM_OCARINA_OF_TIME: - case VB_GIVE_ITEM_KOKIRI_EMERALD: - case VB_GIVE_ITEM_GORON_RUBY: - case VB_GIVE_ITEM_ZORA_SAPPHIRE: case VB_GIVE_ITEM_LIGHT_MEDALLION: case VB_GIVE_ITEM_FOREST_MEDALLION: case VB_GIVE_ITEM_FIRE_MEDALLION: