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) {
auto ctx = Rando::Context::GetInstance();
// Condition for validating Temple of Time Access
if (!gals.foundTempleOfTime && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) ||
(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) {
if (!gals.foundTempleOfTime && ((ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) ||
(ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) {
gals.foundTempleOfTime = true;
}
// Condition for validating a valid starting region
if (!gals.validatedStartingRegion) {
bool childAccess = ctx->GetSettings()->ResolvedStartingAge() == 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 childAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child();
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* 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
ApplyAllAdvancmentItems();
// 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) {
RegionTable(regionKey)->adultDay = 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.
static void WriteRequiredTrials() {
auto ctx = Rando::Context::GetInstance();
for (const auto& trial : ctx->GetTrials()->GetTrialList()) {
if (trial->IsRequired()) {
std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN);
jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName));
}
static void WriteChosenOptions() {
auto ctx = Rando::Context::GetInstance();
for (const auto& trial : ctx->GetTrials()->GetTrialList()) {
if (trial->IsRequired()) {
std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN);
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.
@ -331,7 +336,7 @@ const char* SpoilerLog_Write() {
WriteStartingInventory();
WriteEnabledTricks();
WriteMasterQuestDungeons();
WriteRequiredTrials();
WriteChosenOptions();
WritePlaythrough();
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
// 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");
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()) {
SPDLOG_DEBUG("Path to Temple of Time as child is not guaranteed\n");
return false;

View File

@ -438,13 +438,13 @@ namespace Regions {
}
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;
} else {
RegionTable(RR_ROOT)->adultNight = true;
}
} else {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) {
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childDay = true;
} else {
RegionTable(RR_ROOT)->adultDay = true;
@ -465,13 +465,13 @@ namespace Regions {
}
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;
} else {
RegionTable(RR_ROOT)->adultNight = true;
}
} else {
if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) {
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
RegionTable(RR_ROOT)->childDay = true;
} else {
RegionTable(RR_ROOT)->adultDay = true;

View File

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

View File

@ -5098,6 +5098,7 @@ typedef enum {
RSK_ZORAS_FOUNTAIN,
RSK_SLEEPING_WATERFALL,
RSK_STARTING_AGE,
RSK_SELECTED_STARTING_AGE,
RSK_GERUDO_FORTRESS,
RSK_RAINBOW_BRIDGE,
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) {
s8 startingAge = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_AGE);
uint8_t startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
RandomizerCheckArea startingArea;
switch (startingAge) {
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);
}
int startingAge = OTRGlobals::Instance->gRandoContext->GetSettings()->ResolvedStartingAge();
int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
switch (startingAge) {
case RO_AGE_ADULT: // 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_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_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_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);
@ -1327,11 +1328,6 @@ std::vector<Option *>& Settings::GetExcludeOptionsForArea(const RandomizerCheckA
const std::vector<std::vector<Option *>>& Settings::GetExcludeLocationsOptions() const {
return mExcludeLocationsOptionsAreas;
}
RandoOptionStartingAge Settings::ResolvedStartingAge() const {
return mResolvedStartingAge;
}
RandoOptionLACSCondition Settings::LACSCondition() const {
return mLACSCondition;
}
@ -2368,12 +2364,12 @@ void Settings::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocatio
if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) {
if (const uint32_t choice = Random(0, 2); choice == 0) {
mResolvedStartingAge = RO_AGE_CHILD;
mOptions[RSK_SELECTED_STARTING_AGE].SetContextIndex(RO_AGE_CHILD);
} else {
mResolvedStartingAge = RO_AGE_ADULT;
mOptions[RSK_SELECTED_STARTING_AGE].SetContextIndex(RO_AGE_ADULT);
}
} 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

View File

@ -77,14 +77,6 @@ class Settings {
*/
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.
* 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<TrickOption, RT_MAX> mTrickOptions = {};
std::vector<std::vector<Option*>> mExcludeLocationsOptionsAreas = {};
RandoOptionStartingAge mResolvedStartingAge = RO_AGE_CHILD;
RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA;
std::string mHash;
std::string mSeedString;