summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmber Burton <parchmentwolf@gmail.com>2026-06-29 00:48:27 -0400
committerGitHub <noreply@github.com>2026-06-29 04:48:27 +0000
commitaedddc21e9f0eb3659c05050442d69d35f7284e2 (patch)
tree062b2281858372c420389901549c66210082bc51
parenta629af2e9f1942e4914d0be27f207e572b40eae4 (diff)
Sync's Ganons Trials and Fixes Softlock (#6828)
Previous co op softlock fix introduced a possible trial softlock making barrier never dissappear. This not only ensures that softlock cant happen, it syncs the trial flags in real time and allows all cutscenes to finish playing to properly remove the barrier even if the beams are physically visible in your game.
-rw-r--r--soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp5
-rw-r--r--soh/src/code/z_demo.c12
2 files changed, 17 insertions, 0 deletions
diff --git a/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp b/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp
index 436ac92fd..b05ab6f02 100644
--- a/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp
+++ b/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp
@@ -199,6 +199,11 @@ void Anchor::HandlePacket_UpdateTeamState(nlohmann::json payload) {
gSaveContext.ship.stats.firstInput = loadedData.ship.stats.firstInput;
gSaveContext.ship.stats.fileCreatedAt = loadedData.ship.stats.fileCreatedAt;
+ // Ensure ganon barrier state matches trials
+ if (gSaveContext.eventChkInf[10] & 0x2000 && gSaveContext.eventChkInf[11] & 0xFC00) {
+ gSaveContext.eventChkInf[12] |= 0x8;
+ }
+
// Restore master sword state
// Disabling this for now, not really sure I understand why I did this in the past
// u8 hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, 1);
diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c
index fda3cd061..ecf26bead 100644
--- a/soh/src/code/z_demo.c
+++ b/soh/src/code/z_demo.c
@@ -1229,31 +1229,43 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_2;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL);
+ gSaveContext.eventChkInf[11] &= ~0x800;
break;
case 108:
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_3;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_WATER_TRIAL);
+ gSaveContext.eventChkInf[11] &= ~0x1000;
break;
case 109:
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_4;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_SHADOW_TRIAL);
+ gSaveContext.eventChkInf[11] &= ~0x2000;
break;
case 110:
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_5;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_FIRE_TRIAL);
+ gSaveContext.eventChkInf[11] &= ~0x4000;
break;
case 111:
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_6;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_LIGHT_TRIAL);
+ gSaveContext.eventChkInf[11] &= ~0x8000;
break;
case 112:
play->nextEntranceIndex = ENTR_INSIDE_GANONS_CASTLE_7;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK;
+ Flags_SetEventChkInf(EVENTCHKINF_COMPLETED_SPIRIT_TRIAL);
+ gSaveContext.eventChkInf[10] &= ~0x2000;
break;
case 113:
if (Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL) &&