From 40425c8c28b921b478e459365a08709aed6c80c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:31:41 +0000 Subject: [PATCH] Fix seeded warp traps to be deterministic (#6469) --- soh/soh/Enhancements/ExtraTraps.cpp | 35 +++++-------------- .../game-interactor/GameInteractor.h | 10 ------ soh/soh/Network/CrowdControl/CrowdControl.cpp | 17 +++++---- 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index 0be9f2bd3..b506582df 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -32,6 +32,7 @@ typedef enum { static AltTrapType roll = ADD_TRAP_MAX; static int statusTimer = -1; static int eventTimer = -1; +static EntranceIndex teleportRoll = ENTR_MAX; const char* altTrapTypeCvars[] = { CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), @@ -41,6 +42,12 @@ const char* altTrapTypeCvars[] = { CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), }; +const std::array teleportDestinations = { + ENTR_LINKS_HOUSE_CHILD_SPAWN, ENTR_SACRED_FOREST_MEADOW_WARP_PAD, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, + ENTR_LAKE_HYLIA_WARP_PAD, ENTR_DESERT_COLOSSUS_WARP_PAD, ENTR_GRAVEYARD_WARP_PAD, + ENTR_TEMPLE_OF_TIME_WARP_PAD, +}; + std::vector getEnabledAddTraps() { std::vector enabledAddTraps; for (int i = 0; i < ADD_TRAP_MAX; i++) { @@ -102,6 +109,7 @@ static void RollRandomTrap(uint64_t seed) { break; case ADD_TELEPORT_TRAP: eventTimer = 3; + teleportRoll = ShipUtils::RandomElement(teleportDestinations, &state); break; default: break; @@ -135,32 +143,7 @@ static void OnPlayerUpdate() { &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; case ADD_TELEPORT_TRAP: { - int entrance; - int index = Random(0, 7); - switch (index) { - case 0: - entrance = GI_TP_DEST_SERENADE; - break; - case 1: - entrance = GI_TP_DEST_REQUIEM; - break; - case 2: - entrance = GI_TP_DEST_BOLERO; - break; - case 3: - entrance = GI_TP_DEST_MINUET; - break; - case 4: - entrance = GI_TP_DEST_NOCTURNE; - break; - case 5: - entrance = GI_TP_DEST_PRELUDE; - break; - default: - entrance = GI_TP_DEST_LINKSHOUSE; - break; - } - GameInteractor::RawAction::TeleportPlayer(entrance); + GameInteractor::RawAction::TeleportPlayer(teleportRoll); break; } default: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 20267760b..8d2055fbe 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -52,16 +52,6 @@ typedef enum { /* 0x08 */ GI_COLOR_BLACK, } GIColors; -typedef enum { - /* */ GI_TP_DEST_LINKSHOUSE = ENTR_LINKS_HOUSE_CHILD_SPAWN, - /* */ GI_TP_DEST_MINUET = ENTR_SACRED_FOREST_MEADOW_WARP_PAD, - /* */ GI_TP_DEST_BOLERO = ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, - /* */ GI_TP_DEST_SERENADE = ENTR_LAKE_HYLIA_WARP_PAD, - /* */ GI_TP_DEST_REQUIEM = ENTR_DESERT_COLOSSUS_WARP_PAD, - /* */ GI_TP_DEST_NOCTURNE = ENTR_GRAVEYARD_WARP_PAD, - /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_WARP_PAD, -} GITeleportDestinations; - #ifdef __cplusplus extern "C" { #endif diff --git a/soh/soh/Network/CrowdControl/CrowdControl.cpp b/soh/soh/Network/CrowdControl/CrowdControl.cpp index a308685a1..19ac74f27 100644 --- a/soh/soh/Network/CrowdControl/CrowdControl.cpp +++ b/soh/soh/Network/CrowdControl/CrowdControl.cpp @@ -5,8 +5,7 @@ #include #include #include -#include -#include "soh/OTRGlobals.h" +#include "soh/ShipInit.hpp" extern "C" { #include @@ -625,37 +624,37 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) { case kEffectTpLinksHouse: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_LINKSHOUSE; + ENTR_LINKS_HOUSE_CHILD_SPAWN; break; case kEffectTpMinuet: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_MINUET; + ENTR_SACRED_FOREST_MEADOW_WARP_PAD; break; case kEffectTpBolero: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_BOLERO; + ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD; break; case kEffectTpSerenade: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_SERENADE; + ENTR_LAKE_HYLIA_WARP_PAD; break; case kEffectTpRequiem: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_REQUIEM; + ENTR_DESERT_COLOSSUS_WARP_PAD; break; case kEffectTpNocturne: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_NOCTURNE; + ENTR_GRAVEYARD_WARP_PAD; break; case kEffectTpPrelude: effect->giEffect = std::make_unique(); dynamic_cast(effect->giEffect.get())->parameters[0] = - GI_TP_DEST_PRELUDE; + ENTR_TEMPLE_OF_TIME_WARP_PAD; break; default: