Medallions Locked Trials (#6046)

Adds rando option to bar doors to trials until corresponding medallion acquired
This commit is contained in:
Philip Dubé
2026-01-02 15:17:57 +00:00
committed by GitHub
parent dd9d63eecb
commit 33758e49db
5 changed files with 54 additions and 2 deletions

View File

@@ -60,7 +60,6 @@ std::map<SceneDoorParamsPair, RandomizerInf> lookupTable = {
{{ SCENE_LON_LON_RANCH, 447 }, RAND_INF_BACK_TOWER_UNLOCKED }, {{ SCENE_LON_LON_RANCH, 447 }, RAND_INF_BACK_TOWER_UNLOCKED },
{{ SCENE_LAKE_HYLIA, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED }, {{ SCENE_LAKE_HYLIA, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED },
{{ SCENE_LAKE_HYLIA, 1471 }, RAND_INF_FISHING_HOLE_UNLOCKED }, {{ SCENE_LAKE_HYLIA, 1471 }, RAND_INF_FISHING_HOLE_UNLOCKED },
// clang-format on // clang-format on
}; };

View File

@@ -0,0 +1,48 @@
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
extern PlayState* gPlayState;
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
void DoorShutter_SetupAction(DoorShutter*, DoorShutterActionFunc);
void DoorShutter_SetupType(DoorShutter*, PlayState*);
}
static void OnDoorInit(void* actorRef) {
if (gPlayState->sceneNum == SCENE_INSIDE_GANONS_CASTLE) {
DoorShutter* door = static_cast<DoorShutter*>(actorRef);
bool barred = false;
switch (door->dyna.actor.params) {
case 8255:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST);
break;
case 9279:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER);
break;
case 10303:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT);
break;
case 11327:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE);
break;
case 12351:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW);
break;
case 16447:
barred = !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT);
break;
}
if (barred) {
door->doorType = SHUTTER_FRONT_SWITCH_BACK_CLEAR;
DoorShutter_SetupAction(door, DoorShutter_SetupType);
}
}
}
void RegisterMedallionLockedTrials() {
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_MEDALLION_LOCKED_TRIALS);
COND_ID_HOOK(OnActorInit, ACTOR_DOOR_SHUTTER, shouldRegister, OnDoorInit);
}
static RegisterShipInitFunc initFunc(RegisterMedallionLockedTrials, { "IS_RANDO" });

View File

@@ -103,6 +103,8 @@ void Settings::CreateOptionDescriptions() {
"\n" "\n"
"Random Number - A random number and set of trials will be required."; "Random Number - A random number and set of trials will be required.";
mOptionDescriptions[RSK_TRIAL_COUNT] = "Set the number of trials required to enter Ganon's Tower."; mOptionDescriptions[RSK_TRIAL_COUNT] = "Set the number of trials required to enter Ganon's Tower.";
mOptionDescriptions[RSK_MEDALLION_LOCKED_TRIALS] =
"Doors to trials will be barred until their corresponding medallion is acquired.";
mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM] = mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM] =
"Sets the number of Master Quest Dungeons that are shuffled into the pool.\n" "Sets the number of Master Quest Dungeons that are shuffled into the pool.\n"
"\n" "\n"

View File

@@ -6217,6 +6217,7 @@ typedef enum {
RSK_BRIDGE_OPTIONS, RSK_BRIDGE_OPTIONS,
RSK_GANONS_TRIALS, RSK_GANONS_TRIALS,
RSK_TRIAL_COUNT, RSK_TRIAL_COUNT,
RSK_MEDALLION_LOCKED_TRIALS,
RSK_STARTING_OCARINA, RSK_STARTING_OCARINA,
RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA,
RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_OCARINA_BUTTONS,

View File

@@ -279,6 +279,7 @@ void Settings::CreateOptions() {
} }
}); });
OPT_U8(RSK_TRIAL_COUNT, "Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WIDGET_CVAR_SLIDER_INT, 6, true); OPT_U8(RSK_TRIAL_COUNT, "Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_BOOL(RSK_MEDALLION_LOCKED_TRIALS, "Medallion Locked Trials", CVAR_RANDOMIZER_SETTING("MedallionLockedTrials"), mOptionDescriptions[RSK_MEDALLION_LOCKED_TRIALS]);
OPT_U8(RSK_STARTING_AGE, "Starting Age", {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD); OPT_U8(RSK_STARTING_AGE, "Starting Age", {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_U8(RSK_SELECTED_STARTING_AGE, "Selected Starting Age", {"Child", "Adult"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SelectedStartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD); OPT_U8(RSK_SELECTED_STARTING_AGE, "Selected Starting Age", {"Child", "Adult"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SelectedStartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_BOOL(RSK_SHUFFLE_ENTRANCES, "Shuffle Entrances"); OPT_BOOL(RSK_SHUFFLE_ENTRANCES, "Shuffle Entrances");
@@ -2167,7 +2168,6 @@ void Settings::CreateOptions() {
} }
} }
mOptionGroups[RSG_TRICKS] = OptionGroup::SubGroup("Logical Tricks", tricksOption); mOptionGroups[RSG_TRICKS] = OptionGroup::SubGroup("Logical Tricks", tricksOption);
// TODO: Glitches
mOptionGroups[RSG_MENU_SECTION_LOGIC] = OptionGroup::SubGroup("Logic", mOptionGroups[RSG_MENU_SECTION_LOGIC] = OptionGroup::SubGroup("Logic",
{ {
&mOptions[RSK_LOGIC_RULES], &mOptions[RSK_LOGIC_RULES],
@@ -2219,6 +2219,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT], &mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT],
&mOptions[RSK_GANONS_TRIALS], &mOptions[RSK_GANONS_TRIALS],
&mOptions[RSK_TRIAL_COUNT], &mOptions[RSK_TRIAL_COUNT],
&mOptions[RSK_MEDALLION_LOCKED_TRIALS],
}, },
WidgetContainerType::SECTION); WidgetContainerType::SECTION);
mOptionGroups[RSG_MENU_COLUMN_AREA_ACCESS] = mOptionGroups[RSG_MENU_COLUMN_AREA_ACCESS] =
@@ -2519,6 +2520,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_BRIDGE_OPTIONS], &mOptions[RSK_BRIDGE_OPTIONS],
&mOptions[RSK_GANONS_TRIALS], &mOptions[RSK_GANONS_TRIALS],
&mOptions[RSK_TRIAL_COUNT], &mOptions[RSK_TRIAL_COUNT],
&mOptions[RSK_MEDALLION_LOCKED_TRIALS],
}); });
mOptionGroups[RSG_WORLD] = OptionGroup("World Settings", { mOptionGroups[RSG_WORLD] = OptionGroup("World Settings", {
&mOptions[RSK_STARTING_AGE], &mOptions[RSK_STARTING_AGE],