Properly store starting age in spoiler log (#4873)

* properly store starting age in spoiler log

* convert ResolvedStatingAge to a setting to store it in the save
This commit is contained in:
Pepper0ni 2025-01-15 12:05:52 +00:00 committed by GitHub
parent 7f31fd2e4e
commit ce289c0be9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 32 additions and 39 deletions

View File

@ -130,14 +130,14 @@ static bool UpdateToDAccess(Entrance* entrance, Region* connection) {
static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) { static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
// Condition for validating Temple of Time Access // Condition for validating Temple of Time Access
if (!gals.foundTempleOfTime && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) || if (!gals.foundTempleOfTime && ((ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) ||
(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) { (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) {
gals.foundTempleOfTime = true; gals.foundTempleOfTime = true;
} }
// Condition for validating a valid starting region // Condition for validating a valid starting region
if (!gals.validatedStartingRegion) { if (!gals.validatedStartingRegion) {
bool childAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); bool childAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child();
bool adultAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); bool adultAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult();
Region* kokiri = RegionTable(RR_KOKIRI_FOREST); Region* kokiri = RegionTable(RR_KOKIRI_FOREST);
Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE); Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE);
@ -168,7 +168,7 @@ static void ValidateSphereZero(GetAccessibleLocationsStruct& gals){
// Apply all items that are necessary for checking all location access // Apply all items that are necessary for checking all location access
ApplyAllAdvancmentItems(); ApplyAllAdvancmentItems();
// Reset access as the non-starting age // Reset access as the non-starting age
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
for (RandomizerRegion regionKey : gals.regionPool) { for (RandomizerRegion regionKey : gals.regionPool) {
RegionTable(regionKey)->adultDay = false; RegionTable(regionKey)->adultDay = false;
RegionTable(regionKey)->adultNight = false; RegionTable(regionKey)->adultNight = false;

View File

@ -206,14 +206,19 @@ static void WriteMasterQuestDungeons() {
} }
// Writes the required trials to the spoiler log, if there are any. // Writes the required trials to the spoiler log, if there are any.
static void WriteRequiredTrials() { static void WriteChosenOptions() {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
for (const auto& trial : ctx->GetTrials()->GetTrialList()) { for (const auto& trial : ctx->GetTrials()->GetTrialList()) {
if (trial->IsRequired()) { if (trial->IsRequired()) {
std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN); std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN);
jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName)); jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName));
}
} }
}
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)){
jsonData["SelectedStartingAge"] = "Adult";
} else {
jsonData["SelectedStartingAge"] = "Child";
}
} }
// Writes the intended playthrough to the spoiler log, separated into spheres. // Writes the intended playthrough to the spoiler log, separated into spheres.
@ -331,7 +336,7 @@ const char* SpoilerLog_Write() {
WriteStartingInventory(); WriteStartingInventory();
WriteEnabledTricks(); WriteEnabledTricks();
WriteMasterQuestDungeons(); WriteMasterQuestDungeons();
WriteRequiredTrials(); WriteChosenOptions();
WritePlaythrough(); WritePlaythrough();
ctx->playthroughLocations.clear(); ctx->playthroughLocations.clear();

View File

@ -536,10 +536,10 @@ static bool ValidateWorld(Entrance* entrancePlaced) {
// The player should be able to get back to ToT after going through time, without having collected any items // The player should be able to get back to ToT after going through time, without having collected any items
// This is important to ensure that the player never loses access to the pedestal after going through time // This is important to ensure that the player never loses access to the pedestal after going through time
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && !RegionTable(RR_TEMPLE_OF_TIME)->Adult()) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && !RegionTable(RR_TEMPLE_OF_TIME)->Adult()) {
SPDLOG_DEBUG("Path to Temple of Time as adult is not guaranteed\n"); SPDLOG_DEBUG("Path to Temple of Time as adult is not guaranteed\n");
return false; return false;
} else if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && } else if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) &&
!RegionTable(RR_TEMPLE_OF_TIME)->Child()) { !RegionTable(RR_TEMPLE_OF_TIME)->Child()) {
SPDLOG_DEBUG("Path to Temple of Time as child is not guaranteed\n"); SPDLOG_DEBUG("Path to Temple of Time as child is not guaranteed\n");
return false; return false;

View File

@ -438,13 +438,13 @@ namespace Regions {
} }
if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childNight = true; RegionTable(RR_ROOT)->childNight = true;
} else { } else {
RegionTable(RR_ROOT)->adultNight = true; RegionTable(RR_ROOT)->adultNight = true;
} }
} else { } else {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childDay = true; RegionTable(RR_ROOT)->childDay = true;
} else { } else {
RegionTable(RR_ROOT)->adultDay = true; RegionTable(RR_ROOT)->adultDay = true;
@ -465,13 +465,13 @@ namespace Regions {
} }
if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childNight = true; RegionTable(RR_ROOT)->childNight = true;
} else { } else {
RegionTable(RR_ROOT)->adultNight = true; RegionTable(RR_ROOT)->adultNight = true;
} }
} else { } else {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childDay = true; RegionTable(RR_ROOT)->childDay = true;
} else { } else {
RegionTable(RR_ROOT)->adultDay = true; RegionTable(RR_ROOT)->adultDay = true;

View File

@ -2149,7 +2149,7 @@ namespace Rando {
//Other //Other
AtDay = false; AtDay = false;
AtNight = false; AtNight = false;
GetSaveContext()->linkAge = !ctx->GetSettings()->ResolvedStartingAge(); GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
//Events //Events
ShowedMidoSwordAndShield = false; ShowedMidoSwordAndShield = false;

View File

@ -5098,6 +5098,7 @@ typedef enum {
RSK_ZORAS_FOUNTAIN, RSK_ZORAS_FOUNTAIN,
RSK_SLEEPING_WATERFALL, RSK_SLEEPING_WATERFALL,
RSK_STARTING_AGE, RSK_STARTING_AGE,
RSK_SELECTED_STARTING_AGE,
RSK_GERUDO_FORTRESS, RSK_GERUDO_FORTRESS,
RSK_RAINBOW_BRIDGE, RSK_RAINBOW_BRIDGE,
RSK_RAINBOW_BRIDGE_STONE_COUNT, RSK_RAINBOW_BRIDGE_STONE_COUNT,

View File

@ -490,7 +490,7 @@ void CheckTrackerLoadGame(int32_t fileNum) {
} }
} }
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && IS_RANDO) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && IS_RANDO) {
s8 startingAge = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_AGE); uint8_t startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
RandomizerCheckArea startingArea; RandomizerCheckArea startingArea;
switch (startingAge) { switch (startingAge) {
case RO_AGE_CHILD: case RO_AGE_CHILD:

View File

@ -272,7 +272,7 @@ extern "C" void Randomizer_InitSaveFile() {
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO); Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO);
} }
int startingAge = OTRGlobals::Instance->gRandoContext->GetSettings()->ResolvedStartingAge(); int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
switch (startingAge) { switch (startingAge) {
case RO_AGE_ADULT: // Adult case RO_AGE_ADULT: // Adult
gSaveContext.linkAge = LINK_AGE_ADULT; gSaveContext.linkAge = LINK_AGE_ADULT;

View File

@ -126,6 +126,7 @@ void Settings::CreateOptions() {
mOptions[RSK_GANONS_TRIALS] = Option::U8("Ganon's Trials", {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), mOptionDescriptions[RSK_GANONS_TRIALS], WidgetType::Combobox, RO_GANONS_TRIALS_SET_NUMBER); mOptions[RSK_GANONS_TRIALS] = Option::U8("Ganon's Trials", {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), mOptionDescriptions[RSK_GANONS_TRIALS], WidgetType::Combobox, RO_GANONS_TRIALS_SET_NUMBER);
mOptions[RSK_TRIAL_COUNT] = Option::U8("Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WidgetType::Slider, 6, true); mOptions[RSK_TRIAL_COUNT] = Option::U8("Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WidgetType::Slider, 6, true);
mOptions[RSK_STARTING_AGE] = Option::U8("Starting Age", {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WidgetType::Combobox, RO_AGE_CHILD); mOptions[RSK_STARTING_AGE] = Option::U8("Starting Age", {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WidgetType::Combobox, RO_AGE_CHILD);
mOptions[RSK_SELECTED_STARTING_AGE] = Option::U8("Selected Starting Age", {"Child", "Adult"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SelectedStartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WidgetType::Combobox, RO_AGE_CHILD);
mOptions[RSK_SHUFFLE_ENTRANCES] = Option::Bool("Shuffle Entrances"); mOptions[RSK_SHUFFLE_ENTRANCES] = Option::Bool("Shuffle Entrances");
mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] = Option::U8("Dungeon Entrances", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], WidgetType::Combobox, RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] = Option::U8("Dungeon Entrances", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], WidgetType::Combobox, RO_DUNGEON_ENTRANCE_SHUFFLE_OFF);
mOptions[RSK_SHUFFLE_BOSS_ENTRANCES] = Option::U8("Boss Entrances", {"Off", "Age Restricted", "Full"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES], WidgetType::Combobox, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); mOptions[RSK_SHUFFLE_BOSS_ENTRANCES] = Option::U8("Boss Entrances", {"Off", "Age Restricted", "Full"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES], WidgetType::Combobox, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
@ -1327,11 +1328,6 @@ std::vector<Option *>& Settings::GetExcludeOptionsForArea(const RandomizerCheckA
const std::vector<std::vector<Option *>>& Settings::GetExcludeLocationsOptions() const { const std::vector<std::vector<Option *>>& Settings::GetExcludeLocationsOptions() const {
return mExcludeLocationsOptionsAreas; return mExcludeLocationsOptionsAreas;
} }
RandoOptionStartingAge Settings::ResolvedStartingAge() const {
return mResolvedStartingAge;
}
RandoOptionLACSCondition Settings::LACSCondition() const { RandoOptionLACSCondition Settings::LACSCondition() const {
return mLACSCondition; return mLACSCondition;
} }
@ -2368,12 +2364,12 @@ void Settings::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocatio
if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) { if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) {
if (const uint32_t choice = Random(0, 2); choice == 0) { if (const uint32_t choice = Random(0, 2); choice == 0) {
mResolvedStartingAge = RO_AGE_CHILD; mOptions[RSK_SELECTED_STARTING_AGE].SetContextIndex(RO_AGE_CHILD);
} else { } else {
mResolvedStartingAge = RO_AGE_ADULT; mOptions[RSK_SELECTED_STARTING_AGE].SetContextIndex(RO_AGE_ADULT);
} }
} else { } else {
mResolvedStartingAge = static_cast<RandoOptionStartingAge>(mOptions[RSK_STARTING_AGE].GetContextOptionIndex()); mOptions[RSK_SELECTED_STARTING_AGE].SetContextIndex(mOptions[RSK_STARTING_AGE].GetContextOptionIndex());
} }
// TODO: Random Starting Time // TODO: Random Starting Time

View File

@ -77,14 +77,6 @@ class Settings {
*/ */
const std::vector<std::vector<Option*>>& GetExcludeLocationsOptions() const; const std::vector<std::vector<Option*>>& GetExcludeLocationsOptions() const;
/**
* @brief Gets the resolved Starting Age. Represents the actual starting age when the
* RSK_STARTING_AGE option is set to Random.
*
* @return RandoOptionStartingAge
*/
RandoOptionStartingAge ResolvedStartingAge() const;
/** /**
* @brief Gets the resolved Light Arrow CutScene check condition. * @brief Gets the resolved Light Arrow CutScene check condition.
* There is no direct option for this, it is inferred based on the value of a few other options. * There is no direct option for this, it is inferred based on the value of a few other options.
@ -200,7 +192,6 @@ class Settings {
std::array<OptionGroup, RSG_MAX> mOptionGroups = {}; std::array<OptionGroup, RSG_MAX> mOptionGroups = {};
std::array<TrickOption, RT_MAX> mTrickOptions = {}; std::array<TrickOption, RT_MAX> mTrickOptions = {};
std::vector<std::vector<Option*>> mExcludeLocationsOptionsAreas = {}; std::vector<std::vector<Option*>> mExcludeLocationsOptionsAreas = {};
RandoOptionStartingAge mResolvedStartingAge = RO_AGE_CHILD;
RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA; RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA;
std::string mHash; std::string mHash;
std::string mSeedString; std::string mSeedString;