summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraMannus <mannusmenting@gmail.com>2025-10-30 10:46:04 +0100
committeraMannus <mannusmenting@gmail.com>2025-10-30 10:46:04 +0100
commitf99f03aac9b687cd1c71c9fae952f4223c798a5f (patch)
tree3f35be43e55e003d6e25e7feec4b91cd39aaf2ef
parenta5892590c10c7e498085f3b944434e034250c978 (diff)
parent4e913cc094add604e74fecf006fff28f3d4857bb (diff)
Merge branch 'develop' into aManchipelago
-rw-r--r--CMakeLists.txt4
m---------libultraship0
-rw-r--r--soh/include/functions.h4
-rw-r--r--soh/soh/Enhancements/Fixes/DirtPathFix.cpp26
-rw-r--r--soh/soh/Enhancements/Fixes/FloorSwitches.cpp26
-rw-r--r--soh/soh/Enhancements/Graphics/ToTMedallions.cpp129
-rw-r--r--soh/soh/Enhancements/QoL/PauseWarp.cpp (renamed from soh/soh/Enhancements/pausewarp.c)45
-rw-r--r--soh/soh/Enhancements/QoL/ResetNaviTimer.cpp17
-rw-r--r--soh/soh/Enhancements/mod_menu.cpp6
-rw-r--r--soh/soh/Enhancements/mods.cpp176
-rw-r--r--soh/soh/Enhancements/mods.h4
-rw-r--r--soh/soh/Enhancements/randomizer/ShuffleFairies.cpp5
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/logic.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/savefile.cpp4
-rw-r--r--soh/soh/SohGui/SohMenuEnhancements.cpp7
17 files changed, 253 insertions, 206 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9ab7b6aa4..775170f46 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 23 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.5 LANGUAGES C CXX)
+project(Ship VERSION 9.1.0 LANGUAGES C CXX)
include(CMake/soh-cvars.cmake)
include(CMake/lus-cvars.cmake)
@@ -35,7 +35,7 @@ math(EXPR PATCH_INDEX "${PROJECT_VERSION_PATCH}")
# Use the patch number to select the correct word
list(GET NATO_PHONETIC_ALPHABET ${PATCH_INDEX} PROJECT_PATCH_WORD)
-set(PROJECT_BUILD_NAME "Blair ${PROJECT_PATCH_WORD}" CACHE STRING "" FORCE)
+set(PROJECT_BUILD_NAME "Copper ${PROJECT_PATCH_WORD}" CACHE STRING "" FORCE)
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "" FORCE)
execute_process(
diff --git a/libultraship b/libultraship
-Subproject 9abb6790d30ed98ee8de34e51ff37dc2aeadbc3
+Subproject 5f4be9b6f5f74917c303ab8b66a0b2f4ef91613
diff --git a/soh/include/functions.h b/soh/include/functions.h
index c3d7b4c30..043326bca 100644
--- a/soh/include/functions.h
+++ b/soh/include/functions.h
@@ -2458,10 +2458,6 @@ void Interface_RandoRestoreSwordless(void);
s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw,
bool* shouldUpdate);
-//Pause Warp
-void PauseWarp_HandleSelection();
-void PauseWarp_Execute();
-
// #endregion
#ifdef __cplusplus
diff --git a/soh/soh/Enhancements/Fixes/DirtPathFix.cpp b/soh/soh/Enhancements/Fixes/DirtPathFix.cpp
new file mode 100644
index 000000000..0ceafc9c1
--- /dev/null
+++ b/soh/soh/Enhancements/Fixes/DirtPathFix.cpp
@@ -0,0 +1,26 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/Enhancements/enhancementTypes.h"
+#include "soh/Enhancements/mods.h"
+#include "soh/ShipInit.hpp"
+
+static constexpr ZFightingFixType CVAR_DIRT_PATH_DEFAULT = ZFIGHT_FIX_DISABLED;
+#define CVAR_DIRT_PATH_NAME CVAR_ENHANCEMENT("SceneSpecificDirtPathFix")
+#define CVAR_DIRT_PATH_VALUE CVarGetInteger(CVAR_DIRT_PATH_NAME, CVAR_DIRT_PATH_DEFAULT)
+
+void DirtPathFix_UpdateZFightingMode(int32_t sceneNum) {
+ switch (sceneNum) {
+ case SCENE_HYRULE_FIELD:
+ case SCENE_KOKIRI_FOREST:
+ case SCENE_HYRULE_CASTLE:
+ CVarSetInteger(CVAR_Z_FIGHTING_MODE, CVAR_DIRT_PATH_VALUE);
+ return;
+ default:
+ CVarClear(CVAR_Z_FIGHTING_MODE);
+ }
+}
+
+static void RegisterDirtPathFix() {
+ COND_HOOK(OnTransitionEnd, CVAR_DIRT_PATH_VALUE, DirtPathFix_UpdateZFightingMode);
+}
+
+static RegisterShipInitFunc initFunc(RegisterDirtPathFix, { CVAR_DIRT_PATH_NAME });
diff --git a/soh/soh/Enhancements/Fixes/FloorSwitches.cpp b/soh/soh/Enhancements/Fixes/FloorSwitches.cpp
new file mode 100644
index 000000000..8c05c5c67
--- /dev/null
+++ b/soh/soh/Enhancements/Fixes/FloorSwitches.cpp
@@ -0,0 +1,26 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "macros.h"
+#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h"
+}
+
+static constexpr int32_t CVAR_FLOOR_SWITCHES_DEFAULT = 0;
+#define CVAR_FLOOR_SWITCHES_NAME CVAR_ENHANCEMENT("FixFloorSwitches")
+#define CVAR_FLOOR_SWITCHES_VALUE CVarGetInteger(CVAR_FLOOR_SWITCHES_NAME, CVAR_FLOOR_SWITCHES_DEFAULT)
+
+static void OnInitFloorSwitches(void* refActor) {
+ ObjSwitch* switchActor = reinterpret_cast<ObjSwitch*>(refActor);
+ s32 type = (switchActor->dyna.actor.params & 7);
+
+ if (switchActor->dyna.actor.params == 0x1200 || switchActor->dyna.actor.params == 0x3A00) {
+ switchActor->dyna.actor.world.pos.y -= 1;
+ }
+}
+
+static void RegisterFloorSwitchesFix() {
+ COND_ID_HOOK(OnActorInit, ACTOR_OBJ_SWITCH, CVAR_FLOOR_SWITCHES_VALUE, OnInitFloorSwitches);
+}
+
+static RegisterShipInitFunc initFunc(RegisterFloorSwitchesFix, { CVAR_FLOOR_SWITCHES_NAME });
diff --git a/soh/soh/Enhancements/Graphics/ToTMedallions.cpp b/soh/soh/Enhancements/Graphics/ToTMedallions.cpp
new file mode 100644
index 000000000..13c752a62
--- /dev/null
+++ b/soh/soh/Enhancements/Graphics/ToTMedallions.cpp
@@ -0,0 +1,129 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/Enhancements/mods.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "align_asset_macro.h"
+#include "macros.h"
+#include "variables.h"
+#include "soh/ResourceManagerHelpers.h"
+extern PlayState* gPlayState;
+}
+
+static constexpr int32_t CVAR_TOT_MEDALLION_COLORS_DEFAULT = 0;
+#define CVAR_TOT_MEDALLION_COLORS_NAME CVAR_ENHANCEMENT("ToTMedallionsColors")
+#define CVAR_TOT_MEDALLION_COLORS_VALUE \
+ CVarGetInteger(CVAR_TOT_MEDALLION_COLORS_NAME, CVAR_TOT_MEDALLION_COLORS_DEFAULT)
+
+// GreyScaleEndDlist
+#define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL"
+static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL;
+
+// This is used for the Temple of Time Medalions' color
+#define dtokinoma_room_0DL_007A70 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007A70"
+static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL_007A70;
+#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0"
+static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0;
+
+static Gfx grayscaleWhite = gsDPSetGrayscaleColor(255, 255, 255, 255);
+
+class ToTPatchSetup {
+ public:
+ ToTPatchSetup(Gfx ifColored, const char* patchName, int index, const char* patchName2 = "", int index2 = 0)
+ : patchName(patchName), index(index), ifColored(ifColored), patchName2(patchName2), index2(index2) {
+ }
+
+ void ApplyPatch(bool colored = true) {
+ Gfx colorGfx = colored ? ifColored : grayscaleWhite;
+ ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, patchName, index, colorGfx);
+ if (patchName2 && *patchName2) {
+ ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, patchName2, index2, colorGfx);
+ }
+ }
+
+ void RevertPatch() {
+ ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, patchName);
+ if (patchName2 && *patchName2) {
+ ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, patchName2);
+ }
+ }
+
+ private:
+ const char* patchName;
+ const char* patchName2;
+ int index;
+ int index2;
+ Gfx ifColored;
+};
+
+typedef struct MedallionColorPatch {
+ QuestItem questItemId;
+ ToTPatchSetup patch;
+} MedallionColorPatch;
+
+static ToTPatchSetup startGrayscale =
+ ToTPatchSetup(gsSPGrayscale(true), "ToTMedallions_StartGrayscale", 7, "ToTMedallions_2_StartGrayscale", 7);
+
+static MedallionColorPatch medallionColorPatches[] = {
+ { QUEST_MEDALLION_WATER, ToTPatchSetup(gsDPSetGrayscaleColor(0, 161, 255, 255), "ToTMedallions_MakeBlue", 16) },
+ { QUEST_MEDALLION_SPIRIT, ToTPatchSetup(gsDPSetGrayscaleColor(255, 135, 0, 255), "ToTMedallions_MakeOrange", 45) },
+ { QUEST_MEDALLION_LIGHT, ToTPatchSetup(gsDPSetGrayscaleColor(255, 255, 0, 255), "ToTMedallions_MakeYellow", 69,
+ "ToTMedallions_2_MakeYellow", 16) },
+ { QUEST_MEDALLION_FOREST, ToTPatchSetup(gsDPSetGrayscaleColor(0, 255, 0, 255), "ToTMedallions_MakeGreen", 94) },
+ { QUEST_MEDALLION_FIRE, ToTPatchSetup(gsDPSetGrayscaleColor(255, 0, 0, 255), "ToTMedallions_MakeRed", 118) },
+ { QUEST_MEDALLION_SHADOW, ToTPatchSetup(gsDPSetGrayscaleColor(212, 0, 255, 255), "ToTMedallions_MakePurple", 142,
+ "ToTMedallions_2_MakePurple", 27) },
+};
+
+static ToTPatchSetup endGrayscale =
+ ToTPatchSetup(gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL), "ToTMedallions_EndGrayscaleAndEndDlist", 160,
+ "ToTMedallions_2_EndGrayscaleAndEndDlist", 51);
+
+static void PatchToTMedallions() {
+ // TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect
+ // effects to take effect in there
+ startGrayscale.ApplyPatch();
+
+ for (auto& medallionPatch : medallionColorPatches) {
+ medallionPatch.patch.ApplyPatch(CHECK_QUEST_ITEM(medallionPatch.questItemId));
+ }
+
+ endGrayscale.ApplyPatch();
+}
+
+static void ResetToTMedallions() {
+ // Unpatch everything
+ startGrayscale.RevertPatch();
+
+ for (auto& medallionPatch : medallionColorPatches) {
+ medallionPatch.patch.RevertPatch();
+ }
+
+ endGrayscale.RevertPatch();
+}
+
+void UpdateToTMedallions() {
+ if (CVAR_TOT_MEDALLION_COLORS_VALUE) {
+ PatchToTMedallions();
+ } else {
+ ResetToTMedallions();
+ }
+}
+
+static void CheckTempleOfTime(int16_t sceneNum) {
+ if (sceneNum != SCENE_TEMPLE_OF_TIME) {
+ return;
+ }
+ PatchToTMedallions();
+}
+
+static void RegisterToTMedallions() {
+ COND_HOOK(OnItemReceive, CVAR_TOT_MEDALLION_COLORS_VALUE, [](GetItemEntry) {
+ if (gPlayState) {
+ CheckTempleOfTime(gPlayState->sceneNum);
+ }
+ });
+ COND_HOOK(OnSceneInit, CVAR_TOT_MEDALLION_COLORS_VALUE, CheckTempleOfTime);
+}
+
+static RegisterShipInitFunc initFunc(RegisterToTMedallions, { CVAR_TOT_MEDALLION_COLORS_NAME });
diff --git a/soh/soh/Enhancements/pausewarp.c b/soh/soh/Enhancements/QoL/PauseWarp.cpp
index 10f7e4e39..391f42c61 100644
--- a/soh/soh/Enhancements/pausewarp.c
+++ b/soh/soh/Enhancements/QoL/PauseWarp.cpp
@@ -1,8 +1,21 @@
-#include "custom-message/CustomMessageTypes.h"
-#include "global.h"
-#include "z64.h"
-#include "game-interactor/GameInteractor.h"
-#include "soh/OTRGlobals.h"
+#include <string>
+#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "functions.h"
+#include "macros.h"
+#include "variables.h"
+
+extern PlayState* gPlayState;
+
+u8 Randomizer_GetSettingValue(RandomizerSettingKey);
+}
+
+static constexpr int32_t CVAR_PAUSE_WARP_DEFAULT = 0;
+#define CVAR_PAUSE_WARP_NAME CVAR_ENHANCEMENT("PauseWarp")
+#define CVAR_PAUSE_WARP_VALUE CVarGetInteger(CVAR_PAUSE_WARP_NAME, CVAR_PAUSE_WARP_DEFAULT)
static const int songMessageMap[] = {
TEXT_WARP_MINUET_OF_FOREST, TEXT_WARP_BOLERO_OF_FIRE, TEXT_WARP_SERENADE_OF_WATER,
@@ -30,7 +43,7 @@ static const int songAudioMap[] = {
static bool isWarpActive = false;
-void PauseWarp_Execute() {
+static void PauseWarp_Execute() {
if (!isWarpActive || gPlayState->msgCtx.msgMode != MSGMODE_NONE) {
return;
}
@@ -48,13 +61,14 @@ void PauseWarp_Execute() {
for (int i = 0; i < ARRAY_COUNT(ocarinaSongMap); i++) {
if (gPlayState->msgCtx.lastPlayedSong == ocarinaSongMap[i]) {
gPlayState->nextEntranceIndex = entranceIndexMap[i];
+ func_80088AF0(gPlayState);
return;
}
}
gPlayState->transitionTrigger = TRANS_TRIGGER_OFF;
}
-void ActivateWarp(PauseContext* pauseCtx, int song) {
+static void ActivateWarp(PauseContext* pauseCtx, int song) {
Audio_OcaSetInstrument(0);
Interface_SetDoAction(gPlayState, DO_ACTION_NONE);
pauseCtx->state = 0x12;
@@ -70,7 +84,7 @@ void ActivateWarp(PauseContext* pauseCtx, int song) {
isWarpActive = true;
}
-void PauseWarp_HandleSelection() {
+static void PauseWarp_HandleSelection() {
if (gSaveContext.inventory.items[SLOT_OCARINA] != ITEM_NONE) {
int aButtonPressed = CHECK_BTN_ALL(gPlayState->state.input->press.button, BTN_A);
int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST];
@@ -122,3 +136,18 @@ void PauseWarp_HandleSelection() {
}
}
}
+
+static void RegisterPauseMenuHooks() {
+ COND_HOOK(OnKaleidoUpdate, CVAR_PAUSE_WARP_VALUE, [] {
+ if (GameInteractor::IsSaveLoaded()) {
+ PauseWarp_HandleSelection();
+ }
+ });
+ COND_HOOK(OnGameFrameUpdate, CVAR_PAUSE_WARP_VALUE, [] {
+ if (GameInteractor::IsSaveLoaded()) {
+ PauseWarp_Execute();
+ }
+ });
+}
+
+static RegisterShipInitFunc initFunc(RegisterPauseMenuHooks, { CVAR_PAUSE_WARP_NAME });
diff --git a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp
new file mode 100644
index 000000000..b3048be53
--- /dev/null
+++ b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp
@@ -0,0 +1,17 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "variables.h"
+extern SaveContext gSaveContext;
+}
+
+static constexpr int32_t CVAR_RESET_NAVI_DEFAULT = 0;
+#define CVAR_RESET_NAVI_NAME CVAR_ENHANCEMENT("ResetNaviTimer")
+#define CVAR_RESET_NAVI_VALUE CVarGetInteger(CVAR_RESET_NAVI_NAME, CVAR_RESET_NAVI_DEFAULT)
+
+static void RegisterResetNaviTimer() {
+ COND_HOOK(OnSceneInit, CVAR_RESET_NAVI_VALUE, [](int32_t) { gSaveContext.naviTimer = 0; });
+}
+
+static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME });
diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp
index 3051efe74..9e3fda114 100644
--- a/soh/soh/Enhancements/mod_menu.cpp
+++ b/soh/soh/Enhancements/mod_menu.cpp
@@ -205,7 +205,7 @@ void DrawMods(bool enabled) {
int switchToIndex = -1;
uint32_t index = 0;
- for (int i = selectedModFiles.size() - 1; i >= 0; i--) {
+ for (int i = static_cast<int>(selectedModFiles.size()) - 1; i >= 0; i--) {
std::string file = selectedModFiles[i];
if (enabled) {
ImGui::BeginGroup();
@@ -365,7 +365,7 @@ void RegisterModMenuWidgets() {
auto options = std::static_pointer_cast<UIWidgets::CheckboxOptions>(info.options);
options->disabled = editing;
});
- SohGui::mSohMenu->AddSearchWidget({ enableModsWidget, "Settings", "Mod Menu", "Top", "alternat assets" });
+ SohGui::mSohMenu->AddSearchWidget({ enableModsWidget, "Settings", "Mod Menu", "Top", "alternate assets" });
tabHotkeyWidget = { .name = "Mods Tab Hotkey", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
tabHotkeyWidget.CVar(CVAR_SETTING("Mods.AlternateAssetsHotkey"))
@@ -375,7 +375,7 @@ void RegisterModMenuWidgets() {
.Tooltip("Allows pressing the Tab key to toggle mods")
.DefaultValue(true));
SohGui::mSohMenu->AddSearchWidget(
- { enableModsWidget, "Settings", "Mod Menu", "Top", "alternat assets tab hotkey" });
+ { tabHotkeyWidget, "Settings", "Mod Menu", "Top", "alternate assets tab hotkey" });
}
static RegisterMenuInitFunc menuInitFunc(RegisterModMenuWidgets);
diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp
index 74a4a876e..dc1961530 100644
--- a/soh/soh/Enhancements/mods.cpp
+++ b/soh/soh/Enhancements/mods.cpp
@@ -28,7 +28,6 @@
#include "src/overlays/actors/ovl_En_Firefly/z_en_firefly.h"
#include "src/overlays/actors/ovl_En_Xc/z_en_xc.h"
#include "src/overlays/actors/ovl_Fishing/z_fishing.h"
-#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h"
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
@@ -50,16 +49,6 @@ extern SaveContext gSaveContext;
extern PlayState* gPlayState;
}
-// GreyScaleEndDlist
-#define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL"
-static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL;
-
-// This is used for the Temple of Time Medalions' color
-#define dtokinoma_room_0DL_007A70 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007A70"
-static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL_007A70;
-#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0"
-static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0;
-
/// Switches Link's age and respawns him at the last entrance he entered.
void SwitchAge() {
if (gPlayState == NULL)
@@ -298,24 +287,6 @@ void UpdateHyperEnemiesState() {
}
}
-void UpdateDirtPathFixState(int32_t sceneNum) {
- switch (sceneNum) {
- case SCENE_HYRULE_FIELD:
- case SCENE_KOKIRI_FOREST:
- case SCENE_HYRULE_CASTLE:
- CVarSetInteger(CVAR_Z_FIGHTING_MODE,
- CVarGetInteger(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_DISABLED));
- return;
- default:
- CVarClear(CVAR_Z_FIGHTING_MODE);
- }
-}
-
-void RegisterMenuPathFix() {
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnTransitionEnd>(
- [](int32_t sceneNum) { UpdateDirtPathFixState(sceneNum); });
-}
-
void UpdateMirrorModeState(int32_t sceneNum) {
static bool prevMirroredWorld = false;
bool nextMirroredWorld = false;
@@ -429,14 +400,6 @@ void RegisterPatchHandHandler() {
[](int32_t sceneNum) { UpdatePatchHand(); });
}
-void RegisterResetNaviTimer() {
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int32_t sceneNum) {
- if (CVarGetInteger(CVAR_ENHANCEMENT("ResetNaviTimer"), 0)) {
- gSaveContext.naviTimer = 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
@@ -743,140 +706,6 @@ void RegisterRandomizedEnemySizes() {
});
}
-void PatchToTMedallions() {
- // TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect
- // effects to take effect in there
- if (CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale", 7, gsSPGrayscale(true));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale", 7, gsSPGrayscale(true));
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16,
- gsDPSetGrayscaleColor(0, 161, 255, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45,
- gsDPSetGrayscaleColor(255, 135, 0, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69,
- gsDPSetGrayscaleColor(255, 255, 0, 255));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16,
- gsDPSetGrayscaleColor(255, 255, 0, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94,
- gsDPSetGrayscaleColor(0, 255, 0, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118,
- gsDPSetGrayscaleColor(255, 0, 0, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142,
- gsDPSetGrayscaleColor(212, 0, 255, 255));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27,
- gsDPSetGrayscaleColor(212, 0, 255, 255));
- } else {
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27,
- gsDPSetGrayscaleColor(255, 255, 255, 255));
- }
-
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist", 160,
- gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL));
- ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist", 51,
- gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL));
- } else {
- // Unpatch everything
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale");
-
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple");
-
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist");
- ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist");
- }
-}
-
-void RegisterToTMedallions() {
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry _unused) {
- if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState ||
- gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) {
- return;
- }
- PatchToTMedallions();
- });
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
- if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || sceneNum != SCENE_TEMPLE_OF_TIME) {
- return;
- }
- PatchToTMedallions();
- });
-}
-
-void RegisterFloorSwitchesHook() {
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
- Actor* actor = static_cast<Actor*>(refActor);
- if (actor->id != ACTOR_OBJ_SWITCH || !CVarGetInteger(CVAR_ENHANCEMENT("FixFloorSwitches"), 0)) {
- return;
- }
-
- ObjSwitch* switchActor = reinterpret_cast<ObjSwitch*>(actor);
- s32 type = (switchActor->dyna.actor.params & 7);
-
- if (switchActor->dyna.actor.params == 0x1200 || switchActor->dyna.actor.params == 0x3A00) {
- switchActor->dyna.actor.world.pos.y -= 1;
- }
- });
-}
-
-void RegisterPauseMenuHooks() {
- static bool pauseWarpHooksRegistered = false;
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([&]() {
- if (!GameInteractor::IsSaveLoaded() || !CVarGetInteger(CVAR_ENHANCEMENT("PauseWarp"), 0)) {
- pauseWarpHooksRegistered = false;
- return;
- }
- if (!pauseWarpHooksRegistered) {
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoUpdate>(
- []() { PauseWarp_HandleSelection(); });
- GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>(
- []() { PauseWarp_Execute(); });
- pauseWarpHooksRegistered = true;
- }
- });
-}
-
void RegisterCustomSkeletons() {
static int8_t previousTunic = -1;
@@ -909,17 +738,12 @@ void InitMods() {
RegisterDeleteFileOnDeath();
RegisterHyperBosses();
UpdateHyperEnemiesState();
- RegisterMenuPathFix();
RegisterMirrorModeHandler();
- RegisterResetNaviTimer();
RegisterEnemyDefeatCounts();
RegisterBossDefeatTimestamps();
RegisterRandomizedEnemySizes();
- RegisterToTMedallions();
- RegisterFloorSwitchesHook();
RegisterPatchHandHandler();
RegisterHurtContainerModeHandler();
- RegisterPauseMenuHooks();
RandoKaleido_RegisterHooks();
RegisterCustomSkeletons();
}
diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h
index 8ada99f1e..24710d5b2 100644
--- a/soh/soh/Enhancements/mods.h
+++ b/soh/soh/Enhancements/mods.h
@@ -7,10 +7,10 @@
extern "C" {
#endif
-void UpdateDirtPathFixState(int32_t sceneNum);
+void DirtPathFix_UpdateZFightingMode(int32_t sceneNum);
void UpdateMirrorModeState(int32_t sceneNum);
void UpdateHurtContainerModeState(bool newState);
-void PatchToTMedallions();
+void UpdateToTMedallions();
void UpdatePermanentHeartLossState();
void UpdateHyperEnemiesState();
void UpdateHyperBossesState();
diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp
index 75717f8e9..d4a58ee55 100644
--- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp
+++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp
@@ -180,8 +180,9 @@ void RegisterShuffleFairies() {
// collected, the vanilla code will handle that part automatically.
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
if (!ShuffleFairies_FairyExists(fairyIdentity)) {
- if (SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y,
- gossipStone->actor.world.pos.z, params, fairyType)) {
+ Player* player = GET_PLAYER(gPlayState);
+ if (SpawnFairy(player->actor.world.pos.x, (player->actor.world.pos.y + 20), player->actor.world.pos.z,
+ params, fairyType)) {
Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY);
// Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well.
gossipStone->unk_19D = 0;
diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp
index caa46d9c7..6dde5698d 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp
@@ -133,7 +133,7 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_2, logic->CanCutShrubs()),
}, {
//Exits
- Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, []{return true;}),
+ Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, []{return Here(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return Here(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
});
diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp
index 17a665624..fd578d7de 100644
--- a/soh/soh/Enhancements/randomizer/logic.cpp
+++ b/soh/soh/Enhancements/randomizer/logic.cpp
@@ -2172,7 +2172,7 @@ const std::vector<uint8_t>& GetDungeonSmallKeyDoors(SceneID sceneId) {
dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F);
}
} else if (transitionActor.id == ACTOR_DOOR_SHUTTER) {
- uint8_t doorType = (transitionActor.params >> 7) & 15;
+ uint8_t doorType = (transitionActor.params >> 6) & 15;
if (doorType == SHUTTER_KEY_LOCKED) {
dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F);
}
diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
index 0935ce46c..cd32cc4b1 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
@@ -2113,7 +2113,7 @@ void RegisterItemTrackerWidgets() {
SohGui::mSohMenu->AddSearchWidget({ personalNotesWiget, "Randomizer", "Item Tracker", "General Settings" });
hookshotIdentWidget = { .name = "Show Hookshot Identifiers", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
- hookshotIdentWidget.CVar(CVAR_SETTING("FreeLook.Enabled"))
+ hookshotIdentWidget.CVar(CVAR_TRACKER_ITEM("HookshotIdentifier"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Shows an 'H' or an 'L' to more easily distinguish between Hookshot and Longshot."));
diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp
index ade5dd163..106cecb11 100644
--- a/soh/soh/Enhancements/randomizer/savefile.cpp
+++ b/soh/soh/Enhancements/randomizer/savefile.cpp
@@ -282,15 +282,15 @@ extern "C" void Randomizer_InitSaveFile() {
}
int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get();
+ gSaveContext.savedSceneNum = -1;
switch (startingAge) {
case RO_AGE_ADULT: // Adult
gSaveContext.linkAge = LINK_AGE_ADULT;
gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD;
- gSaveContext.savedSceneNum = SCENE_LON_LON_RANCH; // Set scene num manually to ToT.
+ gSaveContext.cutsceneIndex = 0;
break;
case RO_AGE_CHILD: // Child
gSaveContext.linkAge = LINK_AGE_CHILD;
- gSaveContext.savedSceneNum = -1;
break;
default:
break;
diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp
index 639d7469b..e020d2ab8 100644
--- a/soh/soh/SohGui/SohMenuEnhancements.cpp
+++ b/soh/soh/SohGui/SohMenuEnhancements.cpp
@@ -334,8 +334,7 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Skip Feeding Jabu-Jabu", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"))
.PreFunc([](WidgetInfo& info) {
- info.options->disabled =
- IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN);
+ info.options->disabled = IS_RANDO;
info.options->disabledTooltip =
"This setting is disabled because a randomizer savefile with \"Jabu-Jabu: Open\" is loaded.";
})
@@ -603,7 +602,7 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Color Temple of Time's Medallions", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("ToTMedallionsColors"))
.RaceDisable(false)
- .Callback([](WidgetInfo& info) { PatchToTMedallions(); })
+ .Callback([](WidgetInfo& info) { UpdateToTMedallions(); })
.Options(CheckboxOptions().Tooltip(
"When Medallions are collected, the Medallion imprints around the Master Sword Pedestal in the Temple "
"of Time will become colored-in."));
@@ -1083,7 +1082,7 @@ void SohMenu::AddMenuEnhancements() {
.RaceDisable(false)
.Callback([](WidgetInfo& info) {
if (gPlayState != NULL) {
- UpdateDirtPathFixState(gPlayState->sceneNum);
+ DirtPathFix_UpdateZFightingMode(gPlayState->sceneNum);
}
})
.Options(