From dfa10383e400d06f1100082c1ca786a743f6ac79 Mon Sep 17 00:00:00 2001 From: OtherBlue <93625085+OtherBlue@users.noreply.github.com> Date: Thu, 3 Jul 2025 01:35:49 -0300 Subject: [PATCH 01/15] Split Skip Pickup Messages (#5648) * Split Skip Pickup Messages following ZFG's comment https://youtube.com/clip/UgkxF-LDaR-zyTkqSkqtP3dkLrCca_KGScIw?si=RJY9SIG8QKSiWgVl splits the Skip Pickup Messages time saver for consumables and bottle pickups * CVar updates I missed * another cvar I missed --- soh/soh/SohGui/SohMenuEnhancements.cpp | 7 +++++-- soh/src/overlays/actors/ovl_player_actor/z_player.c | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 8e1e94c08..c08e9c7ba 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -353,9 +353,12 @@ void SohMenu::AddMenuEnhancements() { "Door Switch CS, Water Temple Dragon Switch CS, and the Box Skip One Point in Jabu.")); AddWidget(path, "Text", WIDGET_SEPARATOR_TEXT); - AddWidget(path, "Skip Pickup Messages", WIDGET_CVAR_CHECKBOX) + AddWidget(path, "Skip Bottle Pickup Messages", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("FastBottles")) + .Options(CheckboxOptions().Tooltip("Skip Pickup Messages for Bottle Swipes.")); + AddWidget(path, "Skip Consumable Item Pickup Messages", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("FastDrops")) - .Options(CheckboxOptions().Tooltip("Skip Pickup Messages for new Consumable Items and Bottle Swipes.")); + .Options(CheckboxOptions().Tooltip("Skip Pickup Messages for new Consumable Items.")); AddWidget(path, "Skip Forced Dialog", WIDGET_CVAR_COMBOBOX) .CVar(CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog")) .Options(ComboboxOptions() diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index b2ebcbb88..777de3e59 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -14697,7 +14697,7 @@ void Player_Action_SwingBottle(Player* this, PlayState* play) { if (LinkAnimation_Update(play, &this->skelAnime)) { if (this->av1.bottleCatchType != BOTTLE_CATCH_NONE) { if (!this->av2.startedTextbox) { - if (CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) { this->av1.bottleCatchType = BOTTLE_CATCH_NONE; } else { // 1 is subtracted because `sBottleCatchInfo` does not have an entry for `BOTTLE_CATCH_NONE` @@ -14740,13 +14740,13 @@ void Player_Action_SwingBottle(Player* this, PlayState* play) { this->av1.bottleCatchType = i + 1; this->av2.startedTextbox = false; - if (!CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) { this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE; } this->interactRangeActor->parent = &this->actor; Player_UpdateBottleHeld(play, this, catchInfo->itemId, ABS(catchInfo->itemAction)); - if (!CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) { Player_AnimPlayOnceAdjusted(play, this, swingEntry->catchAnimation); func_80835EA4(play, 4); } From a93b484cf38d02f49932776cefda5292960c6019 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 21 Jul 2025 10:44:53 -0700 Subject: [PATCH 02/15] Add Clear Devices button that will erase the controllers block. (#5683) --- soh/soh/SohGui/SohGui.cpp | 6 ++---- soh/soh/SohGui/SohMenuSettings.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index 7eb3fc6c7..67fb99f0a 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -71,7 +71,6 @@ std::shared_ptr mSohMenuBar; std::shared_ptr mConsoleWindow; std::shared_ptr mStatsWindow; std::shared_ptr mGfxDebuggerWindow; -std::shared_ptr mInputEditorWindow; std::shared_ptr mSohMenu; std::shared_ptr mAudioEditorWindow; @@ -131,10 +130,10 @@ void SetupGuiElements() { mStatsWindow = std::make_shared(CVAR_WINDOW("SohStats"), "Stats##Soh", ImVec2(400, 100)); gui->AddGuiWindow(mStatsWindow); - mInputEditorWindow = gui->GetGuiWindow("Controller Configuration"); + /*mInputEditorWindow = gui->GetGuiWindow("Controller Configuration"); if (mInputEditorWindow == nullptr) { SPDLOG_ERROR("Could not find input editor window"); - } + }*/ mAudioEditorWindow = std::make_shared(CVAR_WINDOW("AudioEditor"), "Audio Editor", ImVec2(820, 630)); gui->AddGuiWindow(mAudioEditorWindow); @@ -228,7 +227,6 @@ void Destroy() { mActorViewerWindow = nullptr; mCosmeticsEditorWindow = nullptr; mAudioEditorWindow = nullptr; - mInputEditorWindow = nullptr; mStatsWindow = nullptr; mConsoleWindow = nullptr; mGfxDebuggerWindow = nullptr; diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index 909c647bd..6fb9e466c 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -1,5 +1,7 @@ #include "SohMenu.h" #include "soh/Notification/Notification.h" +#include "soh/Enhancements/controls/SohInputEditorWindow.h" +#include "SohModals.h" #include #include "soh/ResourceManagerHelpers.h" #include "UIWidgets.hpp" @@ -13,6 +15,7 @@ extern "C" { namespace SohGui { extern std::shared_ptr mSohMenu; +extern std::shared_ptr mModalWindow; using namespace UIWidgets; static std::unordered_map imguiScaleOptions = { @@ -373,6 +376,20 @@ void SohMenu::AddMenuSettings() { path.sidebarName = "Controls"; path.column = SECTION_COLUMN_1; AddSidebarEntry("Settings", "Controls", 2); + AddWidget(path, "Clear Devices", WIDGET_BUTTON) + .Callback([](WidgetInfo& info) { + SohGui::mModalWindow->RegisterPopup( + "Clear Config", + "This will completely erase the controls config, including registered devices.\nContinue?", "Clear", + "Cancel", + []() { + Ship::Context::GetInstance()->GetConsoleVariables()->ClearBlock(CVAR_PREFIX_SETTING ".Controllers"); + uint8_t bits = 0; + Ship::Context::GetInstance()->GetControlDeck()->Init(&bits); + }, + nullptr); + }) + .Options(ButtonOptions().Size(Sizes::Inline)); AddWidget(path, "Controller Bindings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Popout Bindings Window", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("ControllerConfiguration")) From 681e8dda2636f47b6bf6b55d03b3cd723948d7e7 Mon Sep 17 00:00:00 2001 From: Shishu the Dragon <183069616+ShishuTheDragon@users.noreply.github.com> Date: Tue, 22 Jul 2025 05:47:03 +1200 Subject: [PATCH 03/15] Ivan: collect deku seeds (#5654) --- soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c index ab8ca1a6f..ab379267e 100644 --- a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c +++ b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c @@ -654,7 +654,7 @@ void EnPartner_Update(Actor* thisx, PlayState* play) { itemActor->params == ITEM00_ARROWS_MEDIUM || itemActor->params == ITEM00_ARROWS_LARGE || itemActor->params == ITEM00_BOMBCHU || itemActor->params == ITEM00_MAGIC_SMALL || itemActor->params == ITEM00_MAGIC_LARGE || itemActor->params == ITEM00_NUTS || - itemActor->params == ITEM00_STICK) { + itemActor->params == ITEM00_STICK || itemActor->params == ITEM00_SEEDS) { f32 distanceToObject = Actor_WorldDistXYZToActor(&this->actor, itemActor); if (distanceToObject <= 20.0f) { itemActor->world.pos = GET_PLAYER(play)->actor.world.pos; From 37fb25d2b337cc65e0cc0174f1daf40065efdf7a Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Mon, 21 Jul 2025 19:00:39 +0100 Subject: [PATCH 04/15] Fix logic for items given at run start due to settings (#5665) * initial changes * submodules * fix master sword, skip zelda and skip epona logic * I for one welcome our new clang overlords... --- soh/soh/Enhancements/randomizer/3drando/hints.cpp | 3 +++ soh/soh/Enhancements/randomizer/location_access.cpp | 3 +++ .../randomizer/location_access/overworld/lon_lon_ranch.cpp | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index c38d57d8b..bf71ef023 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -648,6 +648,9 @@ void CreateStoneHints() { if (ctx->GetOption(RSK_SKIP_CHILD_ZELDA)) { ctx->GetItemLocation(RC_SONG_FROM_IMPA)->SetHintAccesible(); } + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)) { + ctx->GetItemLocation(RC_TOT_MASTER_SWORD)->SetHintAccesible(); + } // Add 'always' location hints std::vector alwaysHintLocations = {}; diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index cdd684f04..26ec51f27 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -382,11 +382,14 @@ void RegionTable_Init() { //The big poes bottle softlock safety check does not account for the guard house lock if the guard house is not shuffled, so the key is needed before we can safely allow bottle use in logic //RANDOTODO a setting that lets you drink/dump big poes so we don't need this logic EventAccess(&logic->CouldEmptyBigPoes, []{return !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) || logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}), + EventAccess(&logic->FreedEpona, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}), }, { //Locations LOCATION(RC_LINKS_POCKET, true), LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1;), LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_SONG_FROM_IMPA, (bool)ctx->GetOption(RSK_SKIP_CHILD_ZELDA)), + LOCATION(RC_TOT_MASTER_SWORD, (bool)ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)), }, { //Exits Entrance(RR_ROOT_EXITS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index fae41664e..6fe85afc7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -7,8 +7,8 @@ void RegionTable_Init_LonLonRanch() { // clang-format off areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", "Lon Lon Ranch", {RA_LON_LON_RANCH}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->FreedEpona, []{return logic->FreedEpona || ((logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}), - EventAccess(&logic->LinksCow, []{return logic->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}), + EventAccess(&logic->FreedEpona, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONA) && logic->IsAdult && logic->AtDay;}), }, { //Locations LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), From 47c5a7f30841045c833bbf4712d8c85ffd6f0000 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 21 Jul 2025 14:31:48 -0700 Subject: [PATCH 05/15] Bump version to Blair Delta 9.0.3, and fix a typo. (#5687) --- CMakeLists.txt | 2 +- soh/soh/SohGui/SohMenuEnhancements.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9a5afe4c..39cad6d8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 9.0.2 LANGUAGES C CXX) +project(Ship VERSION 9.0.3 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake) diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index c08e9c7ba..41cbbd904 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -272,7 +272,7 @@ void SohMenu::AddMenuEnhancements() { info.options->disabled = IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN); info.options->disabledTooltip = - "This setting is disabled because a randomizer savefile with \"Jabu-Jaby: Open\" is loaded."; + "This setting is disabled because a randomizer savefile with \"Jabu-Jabu: Open\" is loaded."; }) .Options(CheckboxOptions().Tooltip("Allow Link to enter Jabu-Jabu without feeding him a fish.")); From 5066fbf82c541ce3bf861a52e9892f5a3719f59e Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 21 Jul 2025 17:57:40 -0700 Subject: [PATCH 06/15] Fix old file deletion. (#5688) --- soh/soh/SaveManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 43bd25b23..b62dbfee6 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1163,7 +1163,6 @@ void SaveManager::LoadFile(int fileNum) { " " + newFileName + "\n" + "If this was not in error, the file should be deleted."); saveMtx.unlock(); - SaveFile(fileNum); return; } } From 35ad68578e6df5c51acd77546691c7ee98d14ac5 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 21 Jul 2025 22:19:04 -0700 Subject: [PATCH 07/15] Prevent empty randomizer blocks from triggering the rando version flow. (#5689) Clear SpoilerLog CVar when unsupported spoiler log is discovered on load. --- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 ++ soh/soh/SaveManager.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 581861158..ac1716fc3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -406,6 +406,8 @@ bool Randomizer::SpoilerFileExists(const char* spoilerFileName) { "The spoiler file located at\n" + std::string(spoilerFileName) + "\nwas made by a version that doesn't match the currently running version.\n" + "Loading for this file has been cancelled."); + CVarClear(CVAR_GENERAL("SpoilerLog")); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } // Update cache diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index b62dbfee6..2e2f05f72 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1111,6 +1111,7 @@ void SaveManager::LoadFile(int fileNum) { std::ifstream input(fileName); try { + bool deleteRando = false; saveBlock = nlohmann::json::object(); input >> saveBlock; if (!saveBlock.contains("version")) { @@ -1122,6 +1123,10 @@ void SaveManager::LoadFile(int fileNum) { for (auto& block : saveBlock["sections"].items()) { std::string sectionName = block.key(); if (sectionName == "randomizer") { + if (block.value()["data"].empty()) { + deleteRando = true; + continue; + } bool hasStats = saveBlock["sections"].contains("sohStats"); if (block.value()["data"].contains("aat0") || !hasStats) { // Rachael rando data SohGui::RegisterPopup( @@ -1201,6 +1206,11 @@ void SaveManager::LoadFile(int fileNum) { assert(false); break; } + if (deleteRando) { + saveBlock["sections"].erase(saveBlock["sections"].find("randomizer")); + SaveFile(fileNum); + deleteRando = false; + } InitMeta(fileNum); GameInteractor::Instance->ExecuteHooks(fileNum); } catch (const std::exception& e) { From c588d48672b56b329f07aa181af3554ab38914cb Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 21 Jul 2025 22:21:59 -0700 Subject: [PATCH 08/15] Bump version to Blair Echo. (#5690) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39cad6d8f..d7db400c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 9.0.3 LANGUAGES C CXX) +project(Ship VERSION 9.0.4 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake) From d51e88b9722f99096033a90080039d7d44e68e91 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 23 Jul 2025 20:45:22 -0700 Subject: [PATCH 09/15] Rando Versioning (Again) (#5691) * Adds Sulu/Spock rando block check (data not empty, but all sub-entries null), and put that and data being empty to the old file flow. Also moves the `SaveFile` call to after everything else is loaded to preserve sohStats block. * Add check for blank buildVersion in sohStats block for determining old saves. * clang --- soh/soh/SaveManager.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 2e2f05f72..bdb2800e3 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1121,25 +1121,24 @@ void SaveManager::LoadFile(int fileNum) { switch (saveBlock["version"].get()) { case 1: for (auto& block : saveBlock["sections"].items()) { + bool oldVanilla = + block.value()["data"].empty() || block.value()["data"].contains("aat0") || + block.value()["data"]["entrances"].empty() || + SohUtils::IsStringEmpty(saveBlock["sections"]["sohStats"]["data"]["buildVersion"]); std::string sectionName = block.key(); if (sectionName == "randomizer") { - if (block.value()["data"].empty()) { - deleteRando = true; - continue; - } bool hasStats = saveBlock["sections"].contains("sohStats"); - if (block.value()["data"].contains("aat0") || !hasStats) { // Rachael rando data + if (oldVanilla || !hasStats) { // Vanilla "rando" data SohGui::RegisterPopup( "Loading old file", "The file in slot " + std::to_string(fileNum + 1) + - " appears to contain randomizer data, but is a very old format.\n" + + " appears to contain randomizer data, but is a very old format or is empty.\n" + "The randomizer data has been removed, and this file will be treated as a vanilla " - "file.\n" + + "file.\nIf this was a vanilla file, it still is, and you shouldn't see this " + "message again.\n" + "If this was a randomizer file, the file will not work, and should be deleted."); - input.close(); - saveMtx.unlock(); - SaveFile(fileNum); - return; + deleteRando = true; + continue; } s16 major = saveBlock["sections"]["sohStats"]["data"]["buildVersionMajor"]; s16 minor = saveBlock["sections"]["sohStats"]["data"]["buildVersionMinor"]; @@ -1206,6 +1205,7 @@ void SaveManager::LoadFile(int fileNum) { assert(false); break; } + input.close(); if (deleteRando) { saveBlock["sections"].erase(saveBlock["sections"].find("randomizer")); SaveFile(fileNum); From d06cf6bf1032037d67b46bad37b8320bec9643d6 Mon Sep 17 00:00:00 2001 From: AltoXorg <56553686+Alto1772@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:45:46 +0800 Subject: [PATCH 10/15] `timesplitdata.json` obey app directory (#5693) --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index f08235970..d590bbd07 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -4,6 +4,7 @@ #include "soh/util.h" #include #include "include/z64item.h" +#include "Context.h" #include #include @@ -363,7 +364,7 @@ void TimeSplitsSkipSplit(uint32_t index) { } void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vector listData) { - std::string filename = "timesplitdata.json"; + std::string filename = Ship::Context::GetPathRelativeToAppDirectory("timesplitdata.json"); json saveFile; json listArray = nlohmann::json::array(); @@ -948,9 +949,10 @@ void TimeSplitsDrawManageList() { } void InitializeSplitDataFile() { - if (!std::filesystem::exists("timesplitdata.json")) { + std::string filename = Ship::Context::GetPathRelativeToAppDirectory("timesplitdata.json"); + if (!std::filesystem::exists(filename)) { json j; - std::ofstream file("timesplitdata.json"); + std::ofstream file(filename); file << j.dump(4); file.close(); } From ccf3d4b6a0e6a4e2276da6336fea86b30c32428a Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Wed, 23 Jul 2025 23:48:01 -0400 Subject: [PATCH 11/15] Add playing icon to improve Audio Editor indicator (#5686) --- soh/soh/Enhancements/audio/AudioEditor.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 4cf1f389d..6660bee7d 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -298,9 +298,12 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::TextColored( - UIWidgets::ColorValues.at(isCurrentlyPlaying ? UIWidgets::Colors::Yellow : UIWidgets::Colors::White), "%s", - seqData.label.c_str()); + if (isCurrentlyPlaying) { + ImGui::TextColored(UIWidgets::ColorValues.at(UIWidgets::Colors::Yellow), "%s %s", ICON_FA_PLAY, + seqData.label.c_str()); + } else { + ImGui::Text("%s", seqData.label.c_str()); + } ImGui::TableNextColumn(); ImGui::PushItemWidth(-FLT_MIN); const int initialValue = map.contains(currentValue) ? currentValue : defaultValue; From 7d7072f717c853678c4aed7cce39aa1eba592994 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 23 Jul 2025 21:31:13 -0700 Subject: [PATCH 12/15] Bump version to 9.0.5 (#5694) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d7db400c5..89f32f74e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 9.0.4 LANGUAGES C CXX) +project(Ship VERSION 9.0.5 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake) From 1d20000411c120d81144c736f81e5552498a3e77 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 28 Jul 2025 08:54:31 -0700 Subject: [PATCH 13/15] MPQ Support LUS Bump (#5570) * Adapt to changes to LUS regarding including MPQ support. * CMake compile definitions are stupid. * Don't manually close O2RArchive. * Finish LUS bump, including SoH-side fix for font free crash. --- CMakeLists.txt | 4 ++++ libultraship | 2 +- soh/soh/OTRGlobals.cpp | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3324b7c00..ef00ae8f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,9 @@ set(GFX_DEBUG_DISASSEMBLER ON) set(GBI_UCODE F3DEX_GBI_2) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") +# Enable MPQ and OTR support +set(INCLUDE_MPQ_SUPPORT ON) + ################################################################################ # Set CONTROLLERBUTTONS_T ################################################################################ @@ -165,6 +168,7 @@ add_compile_definitions(CONTROLLERBUTTONS_T=uint32_t) ################################################################################ add_subdirectory(libultraship ${CMAKE_BINARY_DIR}/libultraship) target_compile_options(libultraship PRIVATE "${WARNING_OVERRIDE}") +target_compile_definitions(libultraship PUBLIC INCLUDE_MPQ_SUPPORT) add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) add_subdirectory(OTRExporter) add_subdirectory(soh) diff --git a/libultraship b/libultraship index 6a3f6cd32..7f737f8be 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 6a3f6cd327b99f617b623e5b9a3afeae460aac2b +Subproject commit 7f737f8be9580980f5a1fe7784d6e1045f0309da diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index bc9b3106e..d59871d54 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -984,7 +984,6 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { version.minor = reader->ReadUInt16(); version.patch = reader->ReadUInt16(); } - archive->Close(); } return version; @@ -1679,7 +1678,9 @@ ImFont* OTRGlobals::CreateFontWithSize(float size, std::string fontPath) { initData->Path = fontPath; std::shared_ptr fontData = std::static_pointer_cast( Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); - font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size); + ImFontConfig fontConf; + fontConf.FontDataOwnedByAtlas = false; + font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size, &fontConf); } // FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly float iconFontSize = size * 2.0f / 3.0f; From 429021d43471ce89b69c24028a8a3ea19eb73828 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 5 Aug 2025 18:28:19 -0700 Subject: [PATCH 14/15] Add `THRescuedAllCarpenters` to reset list to prevent seed bleed of bridge. (#5725) --- soh/soh/Enhancements/randomizer/logic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..3c0c8345e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2471,6 +2471,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { THCouldFreeDoubleCellCarpenter = false; TH_CouldFreeDeadEndCarpenter = false; THCouldRescueSlopeCarpenter = false; + THRescuedAllCarpenters = false; GF_GateOpen = false; GtG_GateOpen = false; DampesWindmillAccess = false; From 6d4c6f8ea649d1e4857a275994e854c8a983dab8 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 6 Aug 2025 05:43:41 +0200 Subject: [PATCH 15/15] Rando: Remove ice trap effect from vanilla ice trap chests (#5711) --- .../game-interactor/vanilla-behavior/GIVanillaBehavior.h | 9 +++++++++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 1 + soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 6 ++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..0ba910cf6 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2222,6 +2222,15 @@ typedef enum { // - `s32` limbCount // - `*Vec3s` frameTable VB_LOAD_PLAYER_ANIMATION_FRAME, + + // #### `result` + // ```c + // (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + // this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100 + // ``` + // #### `args` + // - `*EnBox` + VB_CHEST_USE_ICE_EFFECT, } GIVanillaBehavior; #endif diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d73cebca7..447125ae1 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1713,6 +1713,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_GIVE_ITEM_WATER_MEDALLION: case VB_GIVE_ITEM_SPIRIT_MEDALLION: case VB_GIVE_ITEM_SHADOW_MEDALLION: + case VB_CHEST_USE_ICE_EFFECT: *should = false; break; case VB_GIVE_ITEM_SKULL_TOKEN: diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 9a3a8fb77..f52b4a458 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -567,8 +567,10 @@ void EnBox_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->dyna.actor, 40.0f); } - if ((this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && - this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { + if (GameInteractor_Should(VB_CHEST_USE_ICE_EFFECT, + (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100, + this)) { EnBox_SpawnIceSmoke(this, play); } }