Remove completed mask quest option, add all masks to starting items menu (#7104)

Fix masks not rendering properly with completed mask quest

Remove completed mask quest option, add all masks to starting items menu

logic: handle starting with masks being able to skip ahead a bit in trade sequence
This commit is contained in:
Philip Dubé
2026-08-31 17:13:25 +00:00
committed by GitHub
parent a7cd6c8113
commit 3175ea9c20
24 changed files with 174 additions and 171 deletions
@@ -9,7 +9,6 @@
"BombchuBag": 1,
"BossKeysanity": 5,
"ClosedForest": 2,
"CompleteMaskQuest": 1,
"CuccosToReturn": 1,
"DampeHint": 1,
"DoorOfTime": 2,
@@ -46,6 +45,7 @@
"ShuffleKeyRings": 2,
"ShuffleKeyRingsRandomCount": 4,
"ShuffleKokiriSword": 1,
"ShuffleMasks": 1,
"ShuffleMasterSword": 1,
"ShuffleMerchants": 3,
"ShuffleOcarinas": 1,
@@ -12,7 +12,6 @@
"BlueFireArrows": 1,
"BossKeysanity": 2,
"ClosedForest": 2,
"CompleteMaskQuest": 1,
"CuccosToReturn": 1,
"DampeHint": 1,
"DoorOfTime": 2,
@@ -33,11 +32,13 @@
"SariaHint": 1,
"SheikLAHint": 0,
"ShuffleGanonBossKey": 8,
"ShuffleMasks": 1,
"ShuffleOcarinas": 1,
"ShuffleWeirdEgg": 2,
"SkipEponaRace": 1,
"SkipScarecrowsSong": 1,
"StartingKokiriSword": 1,
"StartingBunnyHood": 1,
"StartingMapsCompasses": 0,
"StartingOcarina": 1,
"StartingZeldasLetter": 1,
@@ -13,7 +13,6 @@
"BombchuBag": 1,
"BossKeysanity": 2,
"ClosedForest": 2,
"CompleteMaskQuest": 1,
"CuccosToReturn": 1,
"DampeHint": 1,
"DoorOfTime": 2,
@@ -42,6 +41,7 @@
"ShuffleKeyRings": 2,
"ShuffleKeyRingsRandomCount": 8,
"ShuffleKokiriSword": 1,
"ShuffleMasks": 1,
"ShuffleMerchants": 1,
"ShuffleOcarinas": 1,
"ShuffleScrubs": 2,
+2 -2
View File
@@ -8,7 +8,7 @@ extern "C" {
static void RegisterMaskSelectFixes() {
// Fix mask quest so replacing SOLD OUT with mask select doesn't break quest
COND_VB_SHOULD(VB_HAPPY_MASK_SHOP_CHECK_SOLD_OUT, CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0), {
COND_VB_SHOULD(VB_HAPPY_MASK_SHOP_CHECK_SOLD_OUT, CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) || IS_RANDO, {
Actor* actor = va_arg(args, Actor*);
if (actor->params == OSSAN_TYPE_MASK &&
(Flags_GetItemGetInf(ITEMGETINF_3B) && !Flags_GetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE)) ||
@@ -20,4 +20,4 @@ static void RegisterMaskSelectFixes() {
});
}
static RegisterShipInitFunc initFunc(RegisterMaskSelectFixes, { CVAR_ENHANCEMENT("MaskSelect") });
static RegisterShipInitFunc initFunc(RegisterMaskSelectFixes, { CVAR_ENHANCEMENT("MaskSelect"), "IS_RANDO" });
@@ -302,7 +302,7 @@ struct ConditionalAlwaysHint {
std::vector<ConditionalAlwaysHint> conditionalAlwaysHints = {
// clang-format off
{ RC_MARKET_10_BIG_POES, RSK_BIG_POES_HINT, []() { return Rando::Context::GetInstance()->GetOption(RSK_BIG_POE_COUNT).Get() > 3; } },
{ RC_DEKU_THEATER_MASK_OF_TRUTH, RSK_MASK_SHOP_HINT, []() { return !Rando::Context::GetInstance()->GetOption(RSK_MASK_QUEST); } },
{ RC_DEKU_THEATER_MASK_OF_TRUTH, RSK_MASK_SHOP_HINT, []() { return !Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_MASKS); } },
{ RC_SONG_FROM_OCARINA_OF_TIME, RSK_OOT_HINT, []() { return StonesRequiredBySettings() < 2; } },
{ RC_HF_OCARINA_OF_TIME_ITEM, RSK_OOT_HINT, []() { return StonesRequiredBySettings() < 2; } },
{ RC_SHEIK_IN_KAKARIKO, RSK_NONE, []() { return MedallionsRequiredBySettings() < 5; } },
@@ -415,15 +415,15 @@ void GenerateItemPool() {
AddFixedItemToPool(RG_SKELETON_KEY, 1);
}
if (ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_SHUFFLE)) {
AddItemToPool(RG_KEATON_MASK, 2, 1, 1, 1);
AddItemToPool(RG_SKULL_MASK, 2, 1, 1, 1);
AddItemToPool(RG_SPOOKY_MASK, 2, 1, 1, 1);
if (ctx->GetOption(RSK_SHUFFLE_MASKS)) {
if (!ctx->GetOption(RSK_STARTING_KEATON_MASK)) AddItemToPool(RG_KEATON_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_SKULL_MASK)) AddItemToPool(RG_SKULL_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_SPOOKY_MASK)) AddItemToPool(RG_SPOOKY_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_BUNNY_HOOD)) AddItemToPool(RG_BUNNY_HOOD, 2, 1, 1, 1);
AddItemToPool(RG_GORON_MASK, 2, 1, 1, 1);
AddItemToPool(RG_ZORA_MASK, 2, 1, 1, 1);
AddItemToPool(RG_GERUDO_MASK, 2, 1, 1, 1);
AddItemToPool(RG_MASK_OF_TRUTH, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_GORON_MASK)) AddItemToPool(RG_GORON_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_ZORA_MASK)) AddItemToPool(RG_ZORA_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_GERUDO_MASK)) AddItemToPool(RG_GERUDO_MASK, 2, 1, 1, 1);
if (!ctx->GetOption(RSK_STARTING_MASK_OF_TRUTH)) AddItemToPool(RG_MASK_OF_TRUTH, 2, 1, 1, 1);
}
if (ctx->GetOption(RSK_ROCS_FEATHER)) {
@@ -120,7 +120,14 @@ void GenerateStartingInventory() {
if (ctx->GetOption(RSK_SHUFFLE_ZELDAS_LETTER)) {
AddItemToInventory(RG_ZELDAS_LETTER, ctx->GetOption(RSK_STARTING_ZELDAS_LETTER) ? 1 : 0);
}
AddItemToInventory(RG_KEATON_MASK, ctx->GetOption(RSK_STARTING_KEATON_MASK) ? 1 : 0);
AddItemToInventory(RG_SKULL_MASK, ctx->GetOption(RSK_STARTING_SKULL_MASK) ? 1 : 0);
AddItemToInventory(RG_SPOOKY_MASK, ctx->GetOption(RSK_STARTING_SPOOKY_MASK) ? 1 : 0);
AddItemToInventory(RG_BUNNY_HOOD, ctx->GetOption(RSK_STARTING_BUNNY_HOOD) ? 1 : 0);
AddItemToInventory(RG_GORON_MASK, ctx->GetOption(RSK_STARTING_GORON_MASK) ? 1 : 0);
AddItemToInventory(RG_ZORA_MASK, ctx->GetOption(RSK_STARTING_ZORA_MASK) ? 1 : 0);
AddItemToInventory(RG_GERUDO_MASK, ctx->GetOption(RSK_STARTING_GERUDO_MASK) ? 1 : 0);
AddItemToInventory(RG_MASK_OF_TRUTH, ctx->GetOption(RSK_STARTING_MASK_OF_TRUTH) ? 1 : 0);
AddItemToInventory(RG_CLAIM_CHECK, ctx->GetOption(RSK_STARTING_CLAIM_CHECK) ? 1 : 0);
AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Get());
AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0);
@@ -2426,8 +2426,7 @@ void RandomizerOnActorInitHandler(void* actorRef) {
}
}
if (actor->id == ACTOR_EN_OSSAN && actor->params == OSSAN_TYPE_MASK &&
RAND_GET_OPTION(RSK_MASK_QUEST).Is(RO_MASK_QUEST_SHUFFLE)) {
if (actor->id == ACTOR_EN_OSSAN && actor->params == OSSAN_TYPE_MASK && RAND_GET_OPTION(RSK_SHUFFLE_MASKS)) {
Actor_Kill(actor);
}
@@ -10,7 +10,7 @@ void RegionTable_Init_Graveyard() {
EVENT_ACCESS(LOGIC_PLANT_GRAVEYARD_BEAN, CanPlantBean(RG_GRAVEYARD_BEAN_SOUL)),
EVENT_ACCESS(LOGIC_FAIRY_ACCESS, (logic->AtDay && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))),
EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)),
EVENT_ACCESS(LOGIC_BORROW_BUNNY_HOOD, logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
EVENT_ACCESS(LOGIC_SOLD_SPOOKY_MASK, logic->IsChild && logic->AtDay && logic->HasItem(RG_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
}, {
//Locations
LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))),
@@ -8,7 +8,7 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", SCENE_HYRULE_FIELD, {
//Events
EVENT_ACCESS(LOGIC_BIG_POE_KILL, logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->SummonEpona() || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA))),
EVENT_ACCESS(LOGIC_BORROW_RIGHT_MASKS, logic->IsChild && logic->Get(LOGIC_BORROW_BUNNY_HOOD) && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
EVENT_ACCESS(LOGIC_SOLD_BUNNY_HOOD, logic->IsChild && logic->HasItem(RG_BUNNY_HOOD) && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
}, {
//Locations
LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)),
@@ -11,7 +11,7 @@ void RegionTable_Init_Kakariko() {
//Open Gate setting is applied in RR_ROOT
EVENT_ACCESS(LOGIC_KAKARIKO_GATE_OPEN, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)),
//Needs wallet to be able to get another mask after selling Keaton
EVENT_ACCESS(LOGIC_BORROW_SKULL_MASK, logic->IsChild && logic->Get(LOGIC_CAN_BORROW_MASKS) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
EVENT_ACCESS(LOGIC_SOLD_KEATON_MASK, logic->IsChild && logic->Get(LOGIC_KAKARIKO_GATE_OPEN) && logic->HasItem(RG_KEATON_MASK) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)),
}, {
//Locations
LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)),
@@ -15,7 +15,7 @@ void RegionTable_Init_LostWoods() {
EVENT_ACCESS(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN, CanPlantBean(RG_LOST_WOODS_BRIDGE_BEAN_SOUL)),
EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->CanCutShrubs()),
EVENT_ACCESS(LOGIC_BORROW_SPOOKY_MASK, logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_KOKIRI) && logic->HasItem(RG_SPEAK_HYLIAN)),
EVENT_ACCESS(LOGIC_SOLD_SKULL_MASK, logic->IsChild && logic->HasItem(RG_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_KOKIRI) && logic->HasItem(RG_SPEAK_HYLIAN)),
}, {
//Locations
LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)),
@@ -149,14 +149,7 @@ void RegionTable_Init_Market() {
areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", SCENE_HAPPY_MASK_SHOP, {
//Events
//Currently, mask swap in menu doesn't need access to the mask shop
//If it is forced on/a setting, a copy of these events should be added to root
//it also doesn't need you to open kak gate, but that might be best treated as a bug
EVENT_ACCESS(LOGIC_CAN_BORROW_MASKS, logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_KAKARIKO_GATE_OPEN)),
EVENT_ACCESS(LOGIC_BORROW_SKULL_MASK, ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_COMPLETED) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_CAN_BORROW_MASKS)),
EVENT_ACCESS(LOGIC_BORROW_SPOOKY_MASK, ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_COMPLETED) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_CAN_BORROW_MASKS)),
EVENT_ACCESS(LOGIC_BORROW_BUNNY_HOOD, ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_COMPLETED) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_CAN_BORROW_MASKS)),
EVENT_ACCESS(LOGIC_BORROW_RIGHT_MASKS, ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_COMPLETED) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_CAN_BORROW_MASKS)),
EVENT_ACCESS(LOGIC_CAN_BORROW_MASKS, logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_KAKARIKO_GATE_OPEN)),
}, {
//Locations
LOCATION(RC_MASK_SHOP_HINT, true),
+14 -22
View File
@@ -124,30 +124,22 @@ bool Logic::HasItem(RandomizerGet itemName) {
case RG_DOUBLE_DEFENSE:
return GetSaveContext()->isDoubleDefenseAcquired;
// Masks
case RG_KEATON_MASK:
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON) ||
(!ctx->GetOption(RSK_SHUFFLE_MASKS) && Get(LOGIC_CAN_BORROW_MASKS));
case RG_SKULL_MASK:
switch (ctx->GetOption(RSK_MASK_QUEST).Get()) {
case RO_MASK_QUEST_VANILLA:
return Get(LOGIC_BORROW_SKULL_MASK);
case RO_MASK_QUEST_COMPLETED:
return Get(LOGIC_KAKARIKO_GATE_OPEN);
case RO_MASK_QUEST_SHUFFLE:
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL);
default:
assert(false);
return false;
}
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL) ||
(!ctx->GetOption(RSK_SHUFFLE_MASKS) && Get(LOGIC_CAN_BORROW_MASKS) && Get(LOGIC_SOLD_KEATON_MASK));
case RG_SPOOKY_MASK:
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY) ||
(!ctx->GetOption(RSK_SHUFFLE_MASKS) && Get(LOGIC_CAN_BORROW_MASKS) && Get(LOGIC_SOLD_SKULL_MASK));
case RG_BUNNY_HOOD:
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY) ||
(!ctx->GetOption(RSK_SHUFFLE_MASKS) && Get(LOGIC_CAN_BORROW_MASKS) && Get(LOGIC_SOLD_SPOOKY_MASK));
case RG_MASK_OF_TRUTH:
switch (ctx->GetOption(RSK_MASK_QUEST).Get()) {
case RO_MASK_QUEST_VANILLA:
return Get(LOGIC_BORROW_RIGHT_MASKS);
case RO_MASK_QUEST_COMPLETED:
return Get(LOGIC_KAKARIKO_GATE_OPEN);
case RO_MASK_QUEST_SHUFFLE:
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH);
default:
assert(false);
return false;
}
return CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH) ||
(!ctx->GetOption(RSK_SHUFFLE_MASKS) && Get(LOGIC_CAN_BORROW_MASKS) && Get(LOGIC_SOLD_KEATON_MASK) &&
Get(LOGIC_SOLD_SKULL_MASK) && Get(LOGIC_SOLD_SPOOKY_MASK) && Get(LOGIC_SOLD_BUNNY_HOOD));
case RG_POWER_BRACELET:
case RG_CHILD_WALLET:
case RG_FISHING_POLE:
@@ -709,13 +709,8 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] =
"The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.";
mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo.";
mOptionDescriptions[RSK_MASK_QUEST] =
"How masks are acquired.\n"
"Vanilla - Mask trade quest.\n"
"\n"
"Completed - Once the Happy Mask Shop is opened, all masks will be available to be borrowed.\n"
"\n"
"Shuffle - Happy Mask Shop never opens, masks are shuffled with the rest of the items.";
mOptionDescriptions[RSK_SHUFFLE_MASKS] =
"The Happy Mask Shop never opens, masks are shuffled with the rest of the items.";
mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] =
"Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will "
"automatically summon him.\n"
@@ -201,10 +201,10 @@ RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_MQ_SILVER_WATER)
RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_MQ_SILVER_SHADOW)
RANDO_ENUM_ITEM(LOGIC_ROCS_FEATHER)
RANDO_ENUM_ITEM(LOGIC_CAN_BORROW_MASKS)
RANDO_ENUM_ITEM(LOGIC_BORROW_SKULL_MASK)
RANDO_ENUM_ITEM(LOGIC_BORROW_SPOOKY_MASK)
RANDO_ENUM_ITEM(LOGIC_BORROW_BUNNY_HOOD)
RANDO_ENUM_ITEM(LOGIC_BORROW_RIGHT_MASKS)
RANDO_ENUM_ITEM(LOGIC_SOLD_KEATON_MASK)
RANDO_ENUM_ITEM(LOGIC_SOLD_SKULL_MASK)
RANDO_ENUM_ITEM(LOGIC_SOLD_SPOOKY_MASK)
RANDO_ENUM_ITEM(LOGIC_SOLD_BUNNY_HOOD)
RANDO_ENUM_ITEM(LOGIC_FREED_EPONA)
RANDO_ENUM_ITEM(LOGIC_DEKU_TREE_CLEAR)
RANDO_ENUM_ITEM(LOGIC_DODONGOS_CAVERN_CLEAR)
@@ -343,13 +343,6 @@ RANDO_ENUM_ITEM(RO_STARTING_BGS_GIANTS_KNIFE)
RANDO_ENUM_ITEM(RO_STARTING_BGS_BIGGORON_SWORD)
RANDO_ENUM_END(RandoOptionStartingBiggoronSword)
// Mask Quest Settings (vanilla, completed, shuffle)
RANDO_ENUM_BEGIN(RandoOptionMaskQuest)
RANDO_ENUM_ITEM(RO_MASK_QUEST_VANILLA)
RANDO_ENUM_ITEM(RO_MASK_QUEST_COMPLETED)
RANDO_ENUM_ITEM(RO_MASK_QUEST_SHUFFLE)
RANDO_ENUM_END(RandoOptionMaskQuest)
// Item Pool Settings
RANDO_ENUM_BEGIN(RandoOptionItemPool)
RANDO_ENUM_ITEM(RO_ITEM_POOL_PLENTIFUL)
@@ -183,7 +183,7 @@ RANDO_ENUM_ITEM(RSK_FULL_WALLETS)
RANDO_ENUM_ITEM(RSK_SHUFFLE_CHEST_MINIGAME)
RANDO_ENUM_ITEM(RSK_BIG_POE_COUNT)
RANDO_ENUM_ITEM(RSK_SKIP_EPONA_RACE)
RANDO_ENUM_ITEM(RSK_MASK_QUEST)
RANDO_ENUM_ITEM(RSK_SHUFFLE_MASKS)
RANDO_ENUM_ITEM(RSK_SKIP_SCARECROWS_SONG)
RANDO_ENUM_ITEM(RSK_SKIP_PLANTING_BEANS)
RANDO_ENUM_ITEM(RSK_SKULLS_SUNS_SONG)
@@ -307,7 +307,14 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_SIGNS)
RANDO_ENUM_ITEM(RSK_ROCS_FEATHER)
RANDO_ENUM_ITEM(RSK_SHUFFLE_ICICLES)
RANDO_ENUM_ITEM(RSK_SHUFFLE_RED_ICE)
RANDO_ENUM_ITEM(RSK_STARTING_KEATON_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_SKULL_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_SPOOKY_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_BUNNY_HOOD)
RANDO_ENUM_ITEM(RSK_STARTING_GORON_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_ZORA_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_GERUDO_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_MASK_OF_TRUTH)
RANDO_ENUM_ITEM(RSK_PROGRESSIVE_GORON_SWORD)
RANDO_ENUM_ITEM(RSK_MAX)
RANDO_ENUM_END(RandomizerSettingKey)
+23 -30
View File
@@ -350,10 +350,27 @@ void SetStartingItems() {
Item_Give(NULL, ITEM_GERUDO_CARD);
}
if (Randomizer_GetSettingValue(RSK_STARTING_BUNNY_HOOD)) {
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY);
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_NONE) {
INV_CONTENT(ITEM_TRADE_CHILD) = ITEM_MASK_BUNNY;
struct StartingMask {
RandomizerSettingKey setting;
RandomizerInf randInf;
uint8_t item;
};
static const StartingMask startingMasks[] = {
{ RSK_STARTING_KEATON_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, ITEM_MASK_KEATON },
{ RSK_STARTING_SKULL_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, ITEM_MASK_SKULL },
{ RSK_STARTING_SPOOKY_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, ITEM_MASK_SPOOKY },
{ RSK_STARTING_BUNNY_HOOD, RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, ITEM_MASK_BUNNY },
{ RSK_STARTING_GORON_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_GORON, ITEM_MASK_GORON },
{ RSK_STARTING_ZORA_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, ITEM_MASK_ZORA },
{ RSK_STARTING_GERUDO_MASK, RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, ITEM_MASK_GERUDO },
{ RSK_STARTING_MASK_OF_TRUTH, RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, ITEM_MASK_TRUTH },
};
for (const auto& mask : startingMasks) {
if (Randomizer_GetSettingValue(mask.setting)) {
Flags_SetRandomizerInf(mask.randInf);
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_NONE) {
INV_CONTENT(ITEM_TRADE_CHILD) = mask.item;
}
}
}
@@ -617,11 +634,8 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15);
}
int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME);
switch (doorOfTime) {
case RO_DOOROFTIME_OPEN:
Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME);
break;
if (Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) == RO_DOOROFTIME_OPEN) {
Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME);
}
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST ||
@@ -655,25 +669,4 @@ extern "C" void Randomizer_InitSaveFile() {
Item_Give(NULL, ITEM_GERUDO_CARD);
}
}
// complete mask quest
if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) {
Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK);
Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH);
gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask
gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask
gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask
gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related
gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth
}
}
+58 -58
View File
@@ -1352,7 +1352,7 @@ void Settings::CreateOptions() {
mOptions[RSK_BIG_POES_HINT].Enable();
}
});
OPT_U8(RSK_MASK_QUEST, "Mask Quest", {"Vanilla", "Completed", "Shuffle"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_MASK_QUEST], WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_SHUFFLE_MASKS, "Shuffle Masks", CVAR_RANDOMIZER_SETTING("ShuffleMasks"), mOptionDescriptions[RSK_SHUFFLE_MASKS]);
OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WIDGET_CVAR_COMBOBOX, RO_GOSSIP_STONES_NEED_NOTHING, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_GOSSIP_STONE_HINTS, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GossipStoneHints"), RO_GOSSIP_STONES_NEED_NOTHING) ==
@@ -1445,7 +1445,14 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_STARTING_ZELDAS_LETTER, "Start with Zelda's Letter", CVAR_RANDOMIZER_SETTING("StartingZeldasLetter"));
OPT_BOOL(RSK_STARTING_CLAIM_CHECK, "Start with Claim Check", CVAR_RANDOMIZER_SETTING("StartingClaimCheck"));
OPT_BOOL(RSK_STARTING_GERUDO_CARD, "Start with Gerudo Card", CVAR_RANDOMIZER_SETTING("StartingGerudoCard"));
OPT_BOOL(RSK_STARTING_KEATON_MASK, "Start with Keaton Mask", CVAR_RANDOMIZER_SETTING("StartingKeatonMask"));
OPT_BOOL(RSK_STARTING_SKULL_MASK, "Start with Skull Mask", CVAR_RANDOMIZER_SETTING("StartingSkullMask"));
OPT_BOOL(RSK_STARTING_SPOOKY_MASK, "Start with Spooky Mask", CVAR_RANDOMIZER_SETTING("StartingSpookyMask"));
OPT_BOOL(RSK_STARTING_BUNNY_HOOD, "Start with Bunny Hood", CVAR_RANDOMIZER_SETTING("StartingBunnyHood"));
OPT_BOOL(RSK_STARTING_GORON_MASK, "Start with Goron Mask", CVAR_RANDOMIZER_SETTING("StartingGoronMask"));
OPT_BOOL(RSK_STARTING_ZORA_MASK, "Start with Zora Mask", CVAR_RANDOMIZER_SETTING("StartingZoraMask"));
OPT_BOOL(RSK_STARTING_GERUDO_MASK, "Start with Gerudo Mask", CVAR_RANDOMIZER_SETTING("StartingGerudoMask"));
OPT_BOOL(RSK_STARTING_MASK_OF_TRUTH, "Start with Mask of Truth", CVAR_RANDOMIZER_SETTING("StartingMaskOfTruth"));
OPT_U8(RSK_STARTING_BIGGORON_SWORD, "Start with Biggoron's Sword", {"Off", "Giant's Knife", "Biggoron's Sword"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBiggoronSword"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_FULL_WALLETS, "Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, "Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE);
@@ -1870,7 +1877,6 @@ void Settings::CreateOptions() {
&mOptions[RSK_FULL_WALLETS],
&mOptions[RSK_SLINGBOW_BREAK_BEEHIVES],
&mOptions[RSK_SWORDLESS_EPONA_ITEMS],
&mOptions[RSK_MASK_QUEST],
&mOptions[RSK_SKIP_CHILD_STEALTH],
&mOptions[RSK_EARLY_GRANNYS_SHOP],
&mOptions[RSK_SKIP_PLANTING_BEANS],
@@ -2011,41 +2017,24 @@ void Settings::CreateOptions() {
mOptionGroups[RSG_MENU_SECTION_BASIC_SHUFFLES] =
OptionGroup::SubGroup("Shuffle Items",
{
&mOptions[RSK_SHUFFLE_SONGS],
&mOptions[RSK_SHUFFLE_TOKENS],
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
&mOptions[RSK_SHUFFLE_MASTER_SWORD],
&mOptions[RSK_SHUFFLE_OCARINA],
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER],
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
&mOptions[RSK_FISHSANITY],
&mOptions[RSK_FISHSANITY_POND_COUNT],
&mOptions[RSK_FISHSANITY_AGE_SPLIT],
&mOptions[RSK_SHUFFLE_FREESTANDING],
&mOptions[RSK_SHUFFLE_WONDER_ITEMS],
&mOptions[RSK_SHUFFLE_SILVER],
&mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_POTS],
&mOptions[RSK_SHUFFLE_GRASS],
&mOptions[RSK_SHUFFLE_CRATES],
&mOptions[RSK_SHUFFLE_BOULDERS],
&mOptions[RSK_SHUFFLE_ROCKS],
&mOptions[RSK_SHUFFLE_TREES],
&mOptions[RSK_SHUFFLE_BUSHES],
&mOptions[RSK_SHUFFLE_ICICLES],
&mOptions[RSK_SHUFFLE_RED_ICE],
&mOptions[RSK_SHUFFLE_SIGNS],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
&mOptions[RSK_SHUFFLE_STONE_FAIRIES],
&mOptions[RSK_SHUFFLE_BEAN_FAIRIES],
&mOptions[RSK_SHUFFLE_SONG_FAIRIES],
&mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES],
&mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_TOKENS],
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_MASTER_SWORD],
&mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_WEIRD_EGG],
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
&mOptions[RSK_SHUFFLE_MASKS], &mOptions[RSK_FISHSANITY],
&mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT],
&mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_WONDER_ITEMS],
&mOptions[RSK_SHUFFLE_SILVER], &mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS],
&mOptions[RSK_SHUFFLE_GRASS], &mOptions[RSK_SHUFFLE_CRATES],
&mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_ROCKS],
&mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES],
&mOptions[RSK_SHUFFLE_ICICLES], &mOptions[RSK_SHUFFLE_RED_ICE],
&mOptions[RSK_SHUFFLE_SIGNS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
&mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
&mOptions[RSK_SHUFFLE_STONE_FAIRIES], &mOptions[RSK_SHUFFLE_BEAN_FAIRIES],
&mOptions[RSK_SHUFFLE_SONG_FAIRIES], &mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES],
},
WidgetContainerType::SECTION);
mOptionGroups[RSG_MENU_COLUMN_BASIC_SHUFFLES] =
@@ -2283,6 +2272,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER],
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
&mOptions[RSK_SHUFFLE_MASKS],
&mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_MERCHANT_PRICES],
&mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE],
@@ -2357,27 +2347,30 @@ void Settings::CreateOptions() {
&mOptions[RSK_KEYRINGS_GANONS_CASTLE],
&mOptions[RSK_KEYRINGS_CHEST_GAME],
});
mOptionGroups[RSG_STARTING_ITEMS] =
OptionGroup::SubGroup("Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD],
&mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD],
&mOptions[RSK_STARTING_HYLIAN_SHIELD], &mOptions[RSK_STARTING_MIRROR_SHIELD],
&mOptions[RSK_STARTING_GORON_TUNIC], &mOptions[RSK_STARTING_ZORA_TUNIC],
&mOptions[RSK_STARTING_IRON_BOOTS], &mOptions[RSK_STARTING_HOVER_BOOTS],
&mOptions[RSK_STARTING_MEGATON_HAMMER], &mOptions[RSK_STARTING_BOOMERANG],
&mOptions[RSK_STARTING_LENS_OF_TRUTH], &mOptions[RSK_STARTING_DINS_FIRE],
&mOptions[RSK_STARTING_FARORES_WIND], &mOptions[RSK_STARTING_NAYRUS_LOVE],
&mOptions[RSK_STARTING_FIRE_ARROWS], &mOptions[RSK_STARTING_ICE_ARROWS],
&mOptions[RSK_STARTING_LIGHT_ARROWS], &mOptions[RSK_STARTING_STONE_OF_AGONY],
&mOptions[RSK_STARTING_HOOKSHOT], &mOptions[RSK_STARTING_BOW],
&mOptions[RSK_STARTING_SLINGSHOT], &mOptions[RSK_STARTING_BOMB_BAG],
&mOptions[RSK_STARTING_STRENGTH], &mOptions[RSK_STARTING_SCALE],
&mOptions[RSK_STARTING_WALLET], &mOptions[RSK_STARTING_MAGIC_METER],
&mOptions[RSK_STARTING_BOMBCHU_BAG], &mOptions[RSK_STARTING_BOTTLE_1],
&mOptions[RSK_STARTING_BOTTLE_2], &mOptions[RSK_STARTING_BOTTLE_3],
&mOptions[RSK_STARTING_BOTTLE_4], &mOptions[RSK_STARTING_WEIRD_EGG],
&mOptions[RSK_STARTING_ZELDAS_LETTER], &mOptions[RSK_STARTING_CLAIM_CHECK],
&mOptions[RSK_STARTING_GERUDO_CARD], &mOptions[RSK_STARTING_BIGGORON_SWORD],
&mOptions[RSK_STARTING_BUNNY_HOOD] });
mOptionGroups[RSG_STARTING_ITEMS] = OptionGroup::SubGroup(
"Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD],
&mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD],
&mOptions[RSK_STARTING_HYLIAN_SHIELD], &mOptions[RSK_STARTING_MIRROR_SHIELD],
&mOptions[RSK_STARTING_GORON_TUNIC], &mOptions[RSK_STARTING_ZORA_TUNIC],
&mOptions[RSK_STARTING_IRON_BOOTS], &mOptions[RSK_STARTING_HOVER_BOOTS],
&mOptions[RSK_STARTING_MEGATON_HAMMER], &mOptions[RSK_STARTING_BOOMERANG],
&mOptions[RSK_STARTING_LENS_OF_TRUTH], &mOptions[RSK_STARTING_DINS_FIRE],
&mOptions[RSK_STARTING_FARORES_WIND], &mOptions[RSK_STARTING_NAYRUS_LOVE],
&mOptions[RSK_STARTING_FIRE_ARROWS], &mOptions[RSK_STARTING_ICE_ARROWS],
&mOptions[RSK_STARTING_LIGHT_ARROWS], &mOptions[RSK_STARTING_STONE_OF_AGONY],
&mOptions[RSK_STARTING_HOOKSHOT], &mOptions[RSK_STARTING_BOW],
&mOptions[RSK_STARTING_SLINGSHOT], &mOptions[RSK_STARTING_BOMB_BAG],
&mOptions[RSK_STARTING_STRENGTH], &mOptions[RSK_STARTING_SCALE],
&mOptions[RSK_STARTING_WALLET], &mOptions[RSK_STARTING_MAGIC_METER],
&mOptions[RSK_STARTING_BOMBCHU_BAG], &mOptions[RSK_STARTING_BOTTLE_1],
&mOptions[RSK_STARTING_BOTTLE_2], &mOptions[RSK_STARTING_BOTTLE_3],
&mOptions[RSK_STARTING_BOTTLE_4], &mOptions[RSK_STARTING_WEIRD_EGG],
&mOptions[RSK_STARTING_ZELDAS_LETTER], &mOptions[RSK_STARTING_CLAIM_CHECK],
&mOptions[RSK_STARTING_GERUDO_CARD], &mOptions[RSK_STARTING_BIGGORON_SWORD],
&mOptions[RSK_STARTING_BUNNY_HOOD], &mOptions[RSK_STARTING_KEATON_MASK],
&mOptions[RSK_STARTING_SKULL_MASK], &mOptions[RSK_STARTING_SPOOKY_MASK],
&mOptions[RSK_STARTING_GORON_MASK], &mOptions[RSK_STARTING_ZORA_MASK],
&mOptions[RSK_STARTING_GERUDO_MASK], &mOptions[RSK_STARTING_MASK_OF_TRUTH] });
mOptionGroups[RSG_STARTING_SONGS] =
OptionGroup::SubGroup("Ocarina Songs", {
&mOptions[RSK_STARTING_ZELDAS_LULLABY],
@@ -3159,6 +3152,13 @@ void Settings::RandomizeAllSettings() {
case RSK_STARTING_GERUDO_CARD:
case RSK_STARTING_BIGGORON_SWORD:
case RSK_STARTING_BUNNY_HOOD:
case RSK_STARTING_KEATON_MASK:
case RSK_STARTING_SKULL_MASK:
case RSK_STARTING_SPOOKY_MASK:
case RSK_STARTING_GORON_MASK:
case RSK_STARTING_ZORA_MASK:
case RSK_STARTING_GERUDO_MASK:
case RSK_STARTING_MASK_OF_TRUTH:
continue;
default:
break;
+2 -4
View File
@@ -1014,10 +1014,8 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Mask Select in Inventory", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("MaskSelect"))
.PreFunc([](WidgetInfo& info) {
info.options->disabled =
OTRGlobals::Instance->gRandoContext->GetOption(RSK_MASK_QUEST).IsNot(RO_MASK_QUEST_VANILLA);
info.options->disabledTooltip =
"This setting is forcefully enabled when Mask Quest is Completed from the start or Shuffled.";
info.options->disabled = IS_RANDO;
info.options->disabledTooltip = "This setting is forcefully enabled in randomizer.";
})
.Options(CheckboxOptions().Tooltip(
"After completing the mask trading sub-quest, press A and any direction on the mask "
+13
View File
@@ -311,8 +311,21 @@ void DrawStartingItemsMenu(WidgetInfo& info) {
"you get the item Impa would give and skip everything up to meeting Zelda.");
}
}
StartingItemToggle(RSK_STARTING_KEATON_MASK, ITEM_MASK_KEATON);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_SKULL_MASK, ITEM_MASK_SKULL);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_SPOOKY_MASK, ITEM_MASK_SPOOKY);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_BUNNY_HOOD, ITEM_MASK_BUNNY);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_GORON_MASK, ITEM_MASK_GORON);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_ZORA_MASK, ITEM_MASK_ZORA);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_GERUDO_MASK, ITEM_MASK_GERUDO);
ImGui::SameLine();
StartingItemToggle(RSK_STARTING_MASK_OF_TRUTH, ITEM_MASK_TRUTH);
ImGui::SeparatorText("Songs");
StartingSongToggle(RSK_STARTING_ZELDAS_LULLABY, QUEST_SONG_LULLABY);
+18
View File
@@ -1671,5 +1671,23 @@ void ConfigVersion7Updater::Update(Ship::Config* conf) {
// Kakariko Gate setting removed; the gate opens when starting with an unshuffled letter
CVarClear("gRandoSettings.KakarikoGate");
// Mask Quest: Completed was dropped, it's now starting with every mask, and the setting is Shuffle Masks
switch (CVarGetInteger("gRandoSettings.CompleteMaskQuest", 0)) {
case 1: // Completed
CVarSetInteger("gRandoSettings.StartingKeatonMask", 1);
CVarSetInteger("gRandoSettings.StartingSkullMask", 1);
CVarSetInteger("gRandoSettings.StartingSpookyMask", 1);
CVarSetInteger("gRandoSettings.StartingBunnyHood", 1);
CVarSetInteger("gRandoSettings.StartingGoronMask", 1);
CVarSetInteger("gRandoSettings.StartingZoraMask", 1);
CVarSetInteger("gRandoSettings.StartingGerudoMask", 1);
CVarSetInteger("gRandoSettings.StartingMaskOfTruth", 1);
[[fallthrough]];
case 2: // Shuffle
CVarSetInteger("gRandoSettings.ShuffleMasks", 1);
break;
}
CVarClear("gRandoSettings.CompleteMaskQuest");
}
} // namespace SOH
@@ -322,20 +322,14 @@ void KaleidoScope_HandleItemCycleExtras(PlayState* play, u8 slot, bool canCycle,
bool CanMaskSelect() {
if (IS_RANDO) {
return ((CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) ||
Randomizer_GetSettingValue(RSK_MASK_QUEST) != RO_MASK_QUEST_VANILLA) &&
Flags_GetRandomizerInf(RAND_INF_ZELDAS_LETTER) &&
Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD)) ||
Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_SHUFFLE;
return true;
}
// only allow mask select when:
// the shop is open:
// * zelda's letter check: Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)
// * kak gate check: Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD)
// and the mask quest is complete: Flags_GetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE)
return (CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) ||
Randomizer_GetSettingValue(RSK_MASK_QUEST) != RO_MASK_QUEST_VANILLA) &&
return CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) &&
Flags_GetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE) &&
Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) &&
Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD);
@@ -344,7 +338,7 @@ bool CanMaskSelect() {
void KaleidoScope_HandleItemCycles(PlayState* play) {
// handle the mask select
KaleidoScope_HandleItemCycleExtras(
play, SLOT_TRADE_CHILD, IS_RANDO || CanMaskSelect(),
play, SLOT_TRADE_CHILD, CanMaskSelect(),
IS_RANDO ? Randomizer_GetPrevChildTradeItem()
: (INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH
? ITEM_MASK_TRUTH
@@ -368,7 +362,7 @@ void KaleidoScope_HandleItemCycles(PlayState* play) {
void KaleidoScope_DrawItemCycles(PlayState* play) {
// draw the mask select
KaleidoScope_DrawItemCycleExtras(
play, SLOT_TRADE_CHILD, IS_RANDO || CanMaskSelect(),
play, SLOT_TRADE_CHILD, CanMaskSelect(),
IS_RANDO ? Randomizer_GetPrevChildTradeItem()
: (INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH
? ITEM_MASK_TRUTH