mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-04-23 08:14:31 +00:00
Decouple GBK from LACS, blend better with Triforce Hunt
This commit is contained in:
parent
92ba43d675
commit
bd542eae7d
|
|
@ -24,7 +24,7 @@
|
|||
"IncludeTycoonWallet": 1,
|
||||
"KakarikoGate": 1,
|
||||
"Keysanity": 5,
|
||||
"LacsRewardCount": 8,
|
||||
"GbkRewardCount": 8,
|
||||
"MalonHint": 1,
|
||||
"MerchantText": 1,
|
||||
"RainbowBridge": 7,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
"IncludeTycoonWallet": 1,
|
||||
"KakarikoGate": 1,
|
||||
"Keysanity": 2,
|
||||
"LacsRewardCount": 6,
|
||||
"GbkRewardCount": 6,
|
||||
"MalonHint": 1,
|
||||
"MerchantText": 1,
|
||||
"RainbowBridge": 7,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
"IncludeTycoonWallet": 1,
|
||||
"KakarikoGate": 1,
|
||||
"Keysanity": 5,
|
||||
"LacsRewardCount": 10,
|
||||
"LacsRewardOptions": 1,
|
||||
"GbkRewardCount": 10,
|
||||
"GbkRewardOptions": 1,
|
||||
"LockOverworldDoors": 1,
|
||||
"MixBosses": 1,
|
||||
"MixDungeons": 1,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
"IncludeTycoonWallet": 1,
|
||||
"KakarikoGate": 1,
|
||||
"Keysanity": 5,
|
||||
"LacsRewardCount": 7,
|
||||
"GbkRewardCount": 7,
|
||||
"MalonHint": 1,
|
||||
"MerchantText": 1,
|
||||
"RainbowBridge": 7,
|
||||
|
|
|
|||
|
|
@ -1540,7 +1540,6 @@ u8 CheckStoneCount();
|
|||
u8 CheckMedallionCount();
|
||||
u8 CheckDungeonCount();
|
||||
u8 CheckBridgeRewardCount();
|
||||
u8 CheckLACSRewardCount();
|
||||
s32 Play_InCsMode(PlayState* play);
|
||||
f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec);
|
||||
void* Play_LoadFile(PlayState* play, RomFile* file);
|
||||
|
|
|
|||
|
|
@ -2205,6 +2205,14 @@ typedef enum {
|
|||
// - None
|
||||
VB_SKIP_TALKING,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_SLAY_GANON,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// (collectible >= 0) && (collectible <= 0x19
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ Kaleido::Kaleido() {
|
|||
mEntries.push_back(std::make_shared<KaleidoEntryIconCountRequired>(
|
||||
gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 },
|
||||
reinterpret_cast<int*>(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected),
|
||||
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1,
|
||||
ctx->GetOption(RSK_WINCON_TRIFORCE_COUNT).Get(),
|
||||
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1));
|
||||
}
|
||||
if (ctx->GetOption(RSK_SKELETON_KEY)) {
|
||||
|
|
@ -170,7 +170,7 @@ Kaleido::Kaleido() {
|
|||
FlagType::FLAG_RANDOMIZER_INF, i, bossSoulNames[i - RAND_INF_GOHMA_SOUL]));
|
||||
}
|
||||
}
|
||||
if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) {
|
||||
if (ctx->GetOption(RSK_GANONS_SOUL).IsNot(RO_GANONS_SOUL_STARTWITH)) {
|
||||
mEntries.push_back(std::make_shared<KaleidoEntryIconFlag>(
|
||||
gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 },
|
||||
FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, "Ganon's Soul"));
|
||||
|
|
|
|||
|
|
@ -230,16 +230,6 @@ void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, Randomizer
|
|||
// Get the max number of tokens that can possibly be useful
|
||||
static int GetMaxGSCount() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
// If bridge or LACS is set to tokens, get how many are required
|
||||
int maxBridge = 0;
|
||||
int maxLACS = 0;
|
||||
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
|
||||
maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get();
|
||||
}
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
|
||||
maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get();
|
||||
}
|
||||
maxBridge = std::max(maxBridge, maxLACS);
|
||||
// Get the max amount of GS which could be useful from token reward locations
|
||||
int maxUseful = 0;
|
||||
// If the highest advancement item is a token, we know it is useless since it won't lead to an otherwise useful item
|
||||
|
|
@ -262,8 +252,18 @@ static int GetMaxGSCount() {
|
|||
ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) {
|
||||
maxUseful = 10;
|
||||
}
|
||||
// If bridge or GBK or Ganon's Soul is set to tokens, get how many are required
|
||||
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
|
||||
maxUseful = std::max(maxUseful, (int)ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get());
|
||||
}
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TOKENS)) {
|
||||
maxUseful = std::max(maxUseful, (int)ctx->GetOption(RSK_GBK_TOKEN_COUNT).Get());
|
||||
}
|
||||
if (ctx->GetOption(RSK_GANONS_SOUL).Is(RO_GANONS_SOUL_TOKENS)) {
|
||||
maxUseful = std::max(maxUseful, (int)ctx->GetOption(RSK_GANONS_SOUL_TOKEN_COUNT).Get());
|
||||
}
|
||||
// Return max of the two possible reasons tokens could be important, minus the tokens in the starting inventory
|
||||
return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get();
|
||||
return maxUseful - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get();
|
||||
}
|
||||
|
||||
std::string GetShopItemBaseName(std::string itemName) {
|
||||
|
|
|
|||
|
|
@ -2072,39 +2072,33 @@ void StaticData::HintTable_Init() {
|
|||
{QM_PINK, QM_YELLOW}));
|
||||
// /*spanish*/$bY el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#.^
|
||||
|
||||
hintTextTable[RHT_LACS_VANILLA_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once the #Shadow and Spirit Medallions# are retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #die Amulette des Schattens und der Geister# geborgen wurden.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois que les #Médaillons de l'Ombre et de l'Esprit# seront récupérés.^",
|
||||
{QM_PINK, QM_YELLOW, QM_RED}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #el medallón de las sombras y del espíritu#.^
|
||||
|
||||
hintTextTable[RHT_LACS_MEDALLIONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Medallion|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Amulett|# geborgen wurde|e# geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] Médaillon# aura été récupéré|que #[[d]] Médaillons# auront été récupérés|.^",
|
||||
hintTextTable[RHT_GBK_MEDALLIONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided once #[[d]] Medallion|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald #[[d]] Amulett|# geborgen wurde|e# geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie une fois |qu' #[[d]] Médaillon# aura été récupéré|que #[[d]] Médaillons# auront été récupérés|.^",
|
||||
{QM_PINK, QM_YELLOW, QM_RED}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave&del #señor del mal# tras obtener #[[d]] |medallón|medallones|#.^
|
||||
|
||||
hintTextTable[RHT_LACS_STONES_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Spiritual Stone|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Heilige|r Stein# geborgen wurde| Steine# geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] Pierre Ancestrale# aura été&récupérée|que #[[d]] Pierres Ancestrales# auront été récupérées|.^",
|
||||
hintTextTable[RHT_GBK_STONES_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided once #[[d]] Spiritual Stone|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald #[[d]] Heilige|r Stein# geborgen wurde| Steine# geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie une fois |qu' #[[d]] Pierre Ancestrale# aura été&récupérée|que #[[d]] Pierres Ancestrales# auront été récupérées|.^",
|
||||
{QM_PINK, QM_YELLOW, QM_BLUE}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]] piedra| espiritual|s espirituales|#.^
|
||||
|
||||
hintTextTable[RHT_LACS_REWARDS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]]# #Spiritual Stone|# or #Medallion# is|s# and #Medallions# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]]# #Heilige|r Stein# oder #Amulett#&geborgen wurde| Steine# oder #Amulette#&geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois qu|' #[[d]]# #Pierre Ancestrale# ou #[[d]] Médaillon# sera récupéré|e&#[[d]]# #Pierres Ancestrales# et&#Médaillons# seront récupérés|.^",
|
||||
hintTextTable[RHT_GBK_REWARDS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided once #[[d]]# #Spiritual Stone|# or #Medallion# is|s# and #Medallions# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald #[[d]]# #Heilige|r Stein# oder #Amulett#&geborgen wurde| Steine# oder #Amulette#&geborgen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie une fois qu|' #[[d]]# #Pierre Ancestrale# ou #[[d]] Médaillon# sera récupéré|e&#[[d]]# #Pierres Ancestrales# et&#Médaillons# seront récupérés|.^",
|
||||
{QM_PINK, QM_YELLOW, QM_YELLOW, QM_BLUE, QM_RED}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]]# piedra| espiritual o medallón|s espirituales o medallones|#.^
|
||||
|
||||
hintTextTable[RHT_LACS_DUNGEONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Dungeon|# is|s# are| conquered.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Labyrinth|# abgeschloßen wurde|e# abgeschloßen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois qu|' #[[d]] donjon #sera conquis|e #[[d]] donjons# seront conquis|.^",
|
||||
hintTextTable[RHT_GBK_DUNGEONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided once #[[d]] Dungeon|# is|s# are| conquered.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald #[[d]] Labyrinth|# abgeschloßen wurde|e# abgeschloßen wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie une fois qu|' #[[d]] donjon #sera conquis|e #[[d]] donjons# seront conquis|.^",
|
||||
{QM_PINK, QM_YELLOW, QM_PINK}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras completar #[[d]] mazmorra||s|#.^
|
||||
|
||||
hintTextTable[RHT_LACS_TOKENS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Gold Skulltula Token|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Skulltula-Symbol|# gesammelt wurde|e# gesammelt wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] symbole de Skulltula d'or #sera récupuéré"
|
||||
hintTextTable[RHT_GBK_TOKENS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided once #[[d]] Gold Skulltula Token|# is|s# are| retrieved.^",
|
||||
/*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald #[[d]] Skulltula-Symbol|# gesammelt wurde|e# gesammelt wurden|.^",
|
||||
/*french*/ "$bAussi, la #clé du Malin# sera fournie une fois |qu' #[[d]] symbole de Skulltula d'or #sera récupuéré"
|
||||
"|que &#[[d]] symboles de Skulltula d'or&#seront recupérés|.^",
|
||||
{QM_PINK, QM_YELLOW, QM_YELLOW}));
|
||||
// /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]] símbolo
|
||||
|
|
|
|||
|
|
@ -212,39 +212,63 @@ const std::array<HintSetting, 4> hintSettingTable{{
|
|||
}};
|
||||
|
||||
struct BridgeReqConfig {
|
||||
RandomizerSettingKey bridgeDirectKey;
|
||||
RandomizerSettingKey lacsDirectKey;
|
||||
RandomizerSettingKey bridgeKey;
|
||||
RandomizerSettingKey gbkKey;
|
||||
RandomizerSettingKey soulKey;
|
||||
RandomizerSettingKey winKey;
|
||||
RandoOptionRainbowBridge bridgeEnum;
|
||||
RandoOptionGanonsBossKey lacsEnum;
|
||||
RandoOptionGanonsBossKey gbkEnum;
|
||||
RandoOptionGanonsSoul soulEnum;
|
||||
RandoOptionWincon winEnum;
|
||||
uint8_t offset;
|
||||
};
|
||||
|
||||
static constexpr BridgeReqConfig StonesConfig{ RSK_RAINBOW_BRIDGE_STONE_COUNT, RSK_LACS_STONE_COUNT, RO_BRIDGE_STONES,
|
||||
RO_GANON_BOSS_KEY_LACS_STONES, 6 };
|
||||
static constexpr BridgeReqConfig MedallionsConfig{ RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, RSK_LACS_MEDALLION_COUNT,
|
||||
RO_BRIDGE_MEDALLIONS, RO_GANON_BOSS_KEY_LACS_MEDALLIONS, 3 };
|
||||
static constexpr BridgeReqConfig TokensConfig{ RSK_RAINBOW_BRIDGE_TOKEN_COUNT, RSK_LACS_TOKEN_COUNT, RO_BRIDGE_TOKENS,
|
||||
RO_GANON_BOSS_KEY_LACS_TOKENS, 0 };
|
||||
static constexpr BridgeReqConfig StonesConfig{ RSK_RAINBOW_BRIDGE_STONE_COUNT, RSK_GBK_STONE_COUNT, RSK_GANONS_SOUL_STONE_COUNT, RSK_WINCON_STONE_COUNT,
|
||||
RO_BRIDGE_STONES, RO_GANON_BOSS_KEY_STONES, RO_GANONS_SOUL_STONES, RO_WINCON_STONES, 6 };
|
||||
static constexpr BridgeReqConfig MedallionsConfig{ RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, RSK_GBK_MEDALLION_COUNT, RSK_GANONS_SOUL_STONE_COUNT, RSK_WINCON_MEDALLION_COUNT,
|
||||
RO_BRIDGE_MEDALLIONS, RO_GANON_BOSS_KEY_MEDALLIONS, RO_GANONS_SOUL_MEDALLIONS, RO_WINCON_MEDALLIONS, 3 };
|
||||
static constexpr BridgeReqConfig TokensConfig{ RSK_RAINBOW_BRIDGE_TOKEN_COUNT, RSK_GBK_TOKEN_COUNT, RSK_GANONS_SOUL_STONE_COUNT, RSK_WINCON_STONE_COUNT,
|
||||
RO_BRIDGE_TOKENS, RO_GANON_BOSS_KEY_TOKENS, RO_GANONS_SOUL_TOKENS, RO_WINCON_TOKENS, 0 };
|
||||
|
||||
static uint8_t RequiredBySettings(const BridgeReqConfig& cfg) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
uint8_t count = 0;
|
||||
|
||||
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(cfg.bridgeEnum)) {
|
||||
count = ctx->GetOption(cfg.bridgeDirectKey).Get();
|
||||
count = ctx->GetOption(cfg.bridgeKey).Get();
|
||||
} else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) {
|
||||
count = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - cfg.offset;
|
||||
} else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) &&
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
|
||||
count = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - cfg.offset;
|
||||
}
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(cfg.lacsEnum)) {
|
||||
count = std::max<uint8_t>(count, ctx->GetOption(cfg.lacsDirectKey).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - cfg.offset));
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) &&
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(cfg.gbkEnum)) {
|
||||
count = std::max<uint8_t>(count, ctx->GetOption(cfg.gbkKey).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_REWARDS)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_GBK_REWARD_COUNT).Get() - cfg.offset));
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_DUNGEONS) &&
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - cfg.offset));
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_GBK_DUNGEON_COUNT).Get() - cfg.offset));
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_GANONS_SOUL).Is(cfg.soulEnum)) {
|
||||
count = std::max<uint8_t>(count, ctx->GetOption(RSK_GANONS_SOUL_STONE_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_SOUL).Is(RO_GANONS_SOUL_REWARDS)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_GANONS_SOUL_REWARD_COUNT).Get() - cfg.offset));
|
||||
} else if (ctx->GetOption(RSK_GANONS_SOUL).Is(RO_GANONS_SOUL_DUNGEONS) &&
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_GANONS_SOUL_DUNGEON_COUNT).Get() - cfg.offset));
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_WINCON).Is(cfg.soulEnum)) {
|
||||
count = std::max<uint8_t>(count, ctx->GetOption(RSK_WINCON_STONE_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_REWARDS)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_WINCON_REWARD_COUNT).Get() - cfg.offset));
|
||||
} else if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_DUNGEONS) &&
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
|
||||
count = std::max<uint8_t>(count, (uint8_t)(ctx->GetOption(RSK_WINCON_DUNGEON_COUNT).Get() - cfg.offset));
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,25 +316,21 @@ void GenerateItemPool() {
|
|||
|
||||
if (ctx->GetOption(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) {
|
||||
AddFixedItemToPool(RG_TRIFORCE_PIECE, ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1, false);
|
||||
|
||||
switch (ctx->GetOption(RSK_TRIFORCE_HUNT).Get()) {
|
||||
case RO_TRIFORCE_HUNT_OFF:
|
||||
break;
|
||||
case RO_TRIFORCE_HUNT_WIN:
|
||||
ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition
|
||||
ctx->PlaceItemInLocation(RC_GANON, RG_BLUE_RUPEE, false, true);
|
||||
break;
|
||||
case RO_TRIFORCE_HUNT_GBK:
|
||||
ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition
|
||||
}
|
||||
|
||||
// Fixed item locations
|
||||
ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER);
|
||||
ctx->PlaceItemInLocation(RC_GANONS_BOSS_KEY, RG_BLUE_RUPEE); // placeholder, filled by setting
|
||||
ctx->PlaceItemInLocation(RC_GANON_SOUL, RG_BLUE_RUPEE); // placeholder, filled by setting
|
||||
ctx->PlaceItemInLocation(RC_WINCON, RG_BLUE_RUPEE); // placeholder, filled by setting
|
||||
|
||||
if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_DEFEAT_GANON)) {
|
||||
ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE);
|
||||
} else if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_ANYWHERE)) {
|
||||
AddFixedItemToPool(RG_TRIFORCE, 1);
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_WINCON, RG_TRIFORCE);
|
||||
}
|
||||
|
||||
if (!ctx->GetOption(RSK_STARTING_KOKIRI_SWORD)) {
|
||||
if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) {
|
||||
|
|
@ -593,9 +589,6 @@ void GenerateItemPool() {
|
|||
AddItemToPool(RG_MORPHA_SOUL, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_BONGO_BONGO_SOUL, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_TWINROVA_SOUL, 2, 1, 1, 1);
|
||||
if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) {
|
||||
AddItemToPool(RG_GANON_SOUL, 2, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Gerudo Fortress
|
||||
|
|
@ -697,12 +690,9 @@ void GenerateItemPool() {
|
|||
AddItemToPool(RG_SHADOW_TEMPLE_BOSS_KEY, 2, 1, 1, 1);
|
||||
}
|
||||
|
||||
// Don't add GBK to the pool at all for Triforce Hunt or if we start with it.
|
||||
if (!(ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || ctx->GetOption(RSK_TRIFORCE_HUNT))) {
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
|
||||
ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_LACS_VANILLA) {
|
||||
ctx->PlaceItemInLocation(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
if (!(ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH))) {
|
||||
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_STONES) {
|
||||
ctx->PlaceItemInLocation(RC_GANONS_BOSS_KEY, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) {
|
||||
ctx->PlaceItemInLocation(RC_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
} else {
|
||||
|
|
@ -710,6 +700,14 @@ void GenerateItemPool() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!(ctx->GetOption(RSK_GANONS_SOUL).Is(RO_GANONS_SOUL_STARTWITH))) {
|
||||
if (ctx->GetOption(RSK_GANONS_SOUL).Get() >= RO_GANONS_SOUL_STONES) {
|
||||
ctx->PlaceItemInLocation(RC_GANON_SOUL, RG_GANONS_CASTLE_BOSS_KEY);
|
||||
} else {
|
||||
AddItemToPool(RG_GANONS_CASTLE_BOSS_KEY, 2, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Shopsanity
|
||||
if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) ||
|
||||
(ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) &&
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ extern PlayState* gPlayState;
|
|||
|
||||
void BuildTriforcePieceMessage(CustomMessage& msg) {
|
||||
uint8_t current = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected + 1;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL) + 1;
|
||||
uint8_t remaining = required - current;
|
||||
float percentageCollected = (float)current / (float)required;
|
||||
|
||||
|
|
@ -67,6 +67,13 @@ void BuildTriforcePieceMessage(CustomMessage& msg) {
|
|||
msg.Format(ITEM_CUSTOM);
|
||||
}
|
||||
|
||||
void BuildTriforceMessage(CustomMessage& msg) {
|
||||
msg = { "You completed the %yTriforce of&Courage%w! %gGG%w!",
|
||||
"Das %yTriforce des Mutes%w! Du hast&alle Splitter gefunden. %gGut gemacht%w!",
|
||||
"Vous avez complété la %yTriforce&du Courage%w! %gFélicitations%w!" };
|
||||
msg.Format(ITEM_CUSTOM);
|
||||
}
|
||||
|
||||
void BuildCustomItemMessage(Player* player, CustomMessage& msg) {
|
||||
int16_t rgid;
|
||||
msg = CustomMessage("You found [[article]][[color]][[name]]%w!",
|
||||
|
|
@ -149,6 +156,8 @@ void BuildItemMessage(u16* textId, bool* loadFromMessageTable) {
|
|||
Rando::Traps::BuildIceTrapMessage(msg, player->getItemEntry);
|
||||
} else if (player->getItemEntry.getItemId == RG_TRIFORCE_PIECE) {
|
||||
BuildTriforcePieceMessage(msg);
|
||||
} else if (player->getItemEntry.getItemId == RG_TRIFORCE) {
|
||||
BuildTriforceMessage(msg);
|
||||
} else {
|
||||
BuildCustomItemMessage(player, msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ std::unordered_map<RandomizerGet, std::string> itemImageMap = {
|
|||
{ RG_FISHING_POLE, "ITEM_FISHING_POLE" },
|
||||
{ RG_SOLD_OUT, "ITEM_SOLD_OUT" },
|
||||
{ RG_TRIFORCE_PIECE, "TRIFORCE_PIECE" },
|
||||
{ RG_TRIFORCE, "TRIFORCE" },
|
||||
{ RG_SKELETON_KEY, "ITEM_KEY_SMALL" }
|
||||
};
|
||||
|
||||
|
|
@ -1192,4 +1193,6 @@ void PlandomizerWindow::InitElement() {
|
|||
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("BOSS_SOUL", gBossSoulTex, ImVec4(1, 1, 1, 1));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex,
|
||||
ImVec4(1, 1, 1, 1));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE", gTriforcePieceTex,
|
||||
ImVec4(1, 1, 1, 1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ void Context::GenerateLocationPool() {
|
|||
// skip RCs that shouldn't be in the pool for any reason (i.e. settings, unsupported check type, etc.)
|
||||
// TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.)
|
||||
if (location.GetRandomizerCheck() == RC_UNKNOWN_CHECK ||
|
||||
location.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || // already in pool
|
||||
location.GetRandomizerCheck() == RC_WINCON || // already in pool
|
||||
(location.GetRandomizerCheck() == RC_TOT_MASTER_SWORD &&
|
||||
mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD &&
|
||||
|
|
@ -281,7 +281,7 @@ void Context::GenerateLocationPool() {
|
|||
void Context::AddExcludedOptions() {
|
||||
for (auto& loc : StaticData::GetLocationTable()) {
|
||||
// Checks of these types don't have items, skip them.
|
||||
if (loc.GetRandomizerCheck() == RC_UNKNOWN_CHECK || loc.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED ||
|
||||
if (loc.GetRandomizerCheck() == RC_UNKNOWN_CHECK || loc.GetRandomizerCheck() == RC_WINCON ||
|
||||
loc.GetRCType() == RCTYPE_CHEST_GAME || loc.GetRCType() == RCTYPE_STATIC_HINT ||
|
||||
loc.GetRCType() == RCTYPE_GOSSIP_STONE) {
|
||||
continue;
|
||||
|
|
@ -550,12 +550,28 @@ OptionValue& Context::GetLocationOption(const RandomizerCheck key) {
|
|||
return itemLocationTable[key].GetExcludedOption();
|
||||
}
|
||||
|
||||
RandoOptionLACSCondition Context::LACSCondition() const {
|
||||
return mLACSCondition;
|
||||
RandoOptionCheckTrigger Context::GBKCondition() const {
|
||||
return mGBKCondition;
|
||||
}
|
||||
|
||||
void Context::LACSCondition(RandoOptionLACSCondition lacsCondition) {
|
||||
mLACSCondition = lacsCondition;
|
||||
void Context::GBKCondition(RandoOptionCheckTrigger condition) {
|
||||
mGBKCondition = condition;
|
||||
}
|
||||
|
||||
RandoOptionCheckTrigger Context::GanonsSoulCondition() const {
|
||||
return mGBKCondition;
|
||||
}
|
||||
|
||||
void Context::GanonsSoulCondition(RandoOptionCheckTrigger condition) {
|
||||
mGBKCondition = condition;
|
||||
}
|
||||
|
||||
RandoOptionWincon Context::WinCondition() const {
|
||||
return mWinCondition;
|
||||
}
|
||||
|
||||
void Context::WinCondition(RandoOptionWincon condition) {
|
||||
mWinCondition = condition;
|
||||
}
|
||||
|
||||
std::shared_ptr<Kaleido> Context::GetKaleido() {
|
||||
|
|
|
|||
|
|
@ -101,20 +101,24 @@ class Context {
|
|||
OptionValue& GetLocationOption(RandomizerCheck key);
|
||||
|
||||
/**
|
||||
* @brief Gets the resolved Light Arrow CutScene check condition.
|
||||
* @brief Gets the resolved GBK check condition.
|
||||
* There is no direct option for this, it is inferred based on the value of a few other options.
|
||||
*
|
||||
* @return RandoOptionLACSCondition
|
||||
* @return RandoOptionCheckTriggerCondition
|
||||
*/
|
||||
RandoOptionLACSCondition LACSCondition() const;
|
||||
RandoOptionCheckTrigger GBKCondition() const;
|
||||
RandoOptionCheckTrigger GanonsSoulCondition() const;
|
||||
RandoOptionWincon WinCondition() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the resolved Light Arrow CutScene check condition.
|
||||
* @brief Sets the resolved GBK check condition.
|
||||
* There is no direct option for this, it is inferred based on the value of a few other options.
|
||||
*
|
||||
* @param lacsCondition
|
||||
* @param condition
|
||||
*/
|
||||
void LACSCondition(RandoOptionLACSCondition lacsCondition);
|
||||
void GBKCondition(RandoOptionCheckTrigger condition);
|
||||
void GanonsSoulCondition(RandoOptionCheckTrigger condition);
|
||||
void WinCondition(RandoOptionWincon condition);
|
||||
|
||||
GetItemEntry GetFinalGIEntry(RandomizerCheck rc, bool checkObtainability = true, GetItemID ogItemId = GI_NONE);
|
||||
void ParseSpoiler(const char* spoilerFileName);
|
||||
|
|
@ -185,7 +189,9 @@ class Context {
|
|||
std::array<ItemLocation, RC_MAX> itemLocationTable = {};
|
||||
std::array<OptionValue, RSK_MAX> mOptions;
|
||||
std::array<OptionValue, RT_MAX> mTrickOptions;
|
||||
RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA;
|
||||
RandoOptionCheckTrigger mGBKCondition = RO_CHECK_TRIGGER_NONE;
|
||||
RandoOptionCheckTrigger mGanonsSoulCondition = RO_CHECK_TRIGGER_NONE;
|
||||
RandoOptionWincon mWinCondition = RO_WINCON_DEFEAT_GANON;
|
||||
std::shared_ptr<EntranceShuffler> mEntranceShuffler;
|
||||
std::shared_ptr<Dungeons> mDungeons;
|
||||
std::shared_ptr<Logic> mLogic;
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
|
|||
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
||||
|
||||
uint8_t current = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_WINCON_TRIFORCE_COUNT);
|
||||
|
||||
Matrix_Scale(triforcePieceScale, triforcePieceScale, triforcePieceScale, MTXMODE_APPLY);
|
||||
|
||||
|
|
|
|||
|
|
@ -597,25 +597,21 @@ CustomMessage Hint::GetGanonBossKeyText() {
|
|||
return StaticData::hintTextTable[RHT_GANON_BK_OVERWORLD_HINT].GetHintMessage();
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE)) {
|
||||
return StaticData::hintTextTable[RHT_GANON_BK_ANYWHERE_HINT].GetHintMessage();
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
|
||||
return StaticData::hintTextTable[RHT_GANON_BK_SKULLTULA_HINT].GetHintMessage();
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_VANILLA)) {
|
||||
return StaticData::hintTextTable[RHT_LACS_VANILLA_HINT].GetHintMessage();
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STONES)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_GBK_STONES_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_GBK_STONE_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_MEDALLIONS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_GBK_MEDALLIONS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_GBK_MEDALLION_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_REWARDS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_GBK_REWARDS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_GBK_REWARD_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_DUNGEONS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_GBK_DUNGEONS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_GBK_DUNGEON_COUNT).Get());
|
||||
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TOKENS)) {
|
||||
ganonBossKeyMessage = StaticData::hintTextTable[RHT_GBK_TOKENS_HINT].GetHintMessage();
|
||||
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_GBK_TOKEN_COUNT).Get());
|
||||
}
|
||||
return ganonBossKeyMessage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,42 +120,97 @@ RandomizerCheck GetRandomizerCheckFromSceneFlag(int16_t sceneNum, int16_t flagTy
|
|||
return RC_UNKNOWN_CHECK;
|
||||
}
|
||||
|
||||
bool MeetsLACSRequirements() {
|
||||
switch (RAND_GET_OPTION(RSK_GANONS_BOSS_KEY).Get()) {
|
||||
case RO_GANON_BOSS_KEY_LACS_STONES:
|
||||
if ((CheckStoneCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_STONE_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_MEDALLIONS:
|
||||
if ((CheckMedallionCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_MEDALLION_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_REWARDS:
|
||||
if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_LACS_REWARD_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_DUNGEONS:
|
||||
if ((CheckDungeonCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_DUNGEON_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_TOKENS:
|
||||
if (gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_LACS_TOKEN_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) {
|
||||
return true;
|
||||
bool MeetsGBKRequirements() {
|
||||
u8 bonusRewardCount = 0;
|
||||
switch (RAND_GET_OPTION(RSK_GBK_OPTIONS).Get()) {
|
||||
case RO_CHECK_TRIGGER_WILDCARD_REWARD:
|
||||
case RO_CHECK_TRIGGER_GREG_REWARD:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
bonusRewardCount = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
switch (RAND_GET_OPTION(RSK_GANONS_BOSS_KEY).Get()) {
|
||||
case RO_GANON_BOSS_KEY_STONES:
|
||||
return (CheckStoneCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GBK_STONE_COUNT).Get();
|
||||
case RO_GANON_BOSS_KEY_MEDALLIONS:
|
||||
return (CheckMedallionCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GBK_MEDALLION_COUNT).Get();
|
||||
case RO_GANON_BOSS_KEY_REWARDS:
|
||||
return (CheckMedallionCount() + CheckStoneCount() + bonusRewardCount) >=
|
||||
RAND_GET_OPTION(RSK_GBK_REWARD_COUNT).Get();
|
||||
case RO_GANON_BOSS_KEY_DUNGEONS:
|
||||
return (CheckDungeonCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GBK_DUNGEON_COUNT).Get();
|
||||
case RO_GANON_BOSS_KEY_TOKENS:
|
||||
return gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_GBK_TOKEN_COUNT).Get();
|
||||
case RO_GANON_BOSS_KEY_TRIFORCE_PIECES:
|
||||
return gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >=
|
||||
RAND_GET_OPTION(RSK_GBK_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MeetsGanonsSoulRequirements() {
|
||||
u8 bonusRewardCount = 0;
|
||||
switch (RAND_GET_OPTION(RSK_GANONS_SOUL_OPTIONS).Get()) {
|
||||
case RO_CHECK_TRIGGER_WILDCARD_REWARD:
|
||||
case RO_CHECK_TRIGGER_GREG_REWARD:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
bonusRewardCount = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (RAND_GET_OPTION(RSK_GANONS_SOUL).Get()) {
|
||||
case RO_GANONS_SOUL_STONES:
|
||||
return (CheckStoneCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GANONS_SOUL_STONE_COUNT).Get();
|
||||
case RO_GANONS_SOUL_MEDALLIONS:
|
||||
return (CheckMedallionCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GANONS_SOUL_MEDALLION_COUNT).Get();
|
||||
case RO_GANONS_SOUL_REWARDS:
|
||||
return (CheckMedallionCount() + CheckStoneCount() + bonusRewardCount) >=
|
||||
RAND_GET_OPTION(RSK_GANONS_SOUL_REWARD_COUNT).Get();
|
||||
case RO_GANONS_SOUL_DUNGEONS:
|
||||
return (CheckDungeonCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_GANONS_SOUL_DUNGEON_COUNT).Get();
|
||||
case RO_GANONS_SOUL_TOKENS:
|
||||
return gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_GANONS_SOUL_TOKEN_COUNT).Get();
|
||||
case RO_GANONS_SOUL_TRIFORCE_PIECES:
|
||||
return gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >=
|
||||
RAND_GET_OPTION(RSK_GANONS_SOUL_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MeetsWinconRequirements() {
|
||||
u8 bonusRewardCount = 0;
|
||||
switch (RAND_GET_OPTION(RSK_WINCON_OPTIONS).Get()) {
|
||||
case RO_CHECK_TRIGGER_WILDCARD_REWARD:
|
||||
case RO_CHECK_TRIGGER_GREG_REWARD:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
bonusRewardCount = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (RAND_GET_OPTION(RSK_WINCON).Get()) {
|
||||
case RO_WINCON_STONES:
|
||||
return (CheckStoneCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_WINCON_STONE_COUNT).Get();
|
||||
case RO_WINCON_MEDALLIONS:
|
||||
return (CheckMedallionCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_WINCON_MEDALLION_COUNT).Get();
|
||||
case RO_WINCON_REWARDS:
|
||||
return (CheckMedallionCount() + CheckStoneCount() + bonusRewardCount) >=
|
||||
RAND_GET_OPTION(RSK_WINCON_REWARD_COUNT).Get();
|
||||
case RO_WINCON_DUNGEONS:
|
||||
return (CheckDungeonCount() + bonusRewardCount) >= RAND_GET_OPTION(RSK_WINCON_DUNGEON_COUNT).Get();
|
||||
case RO_WINCON_TOKENS:
|
||||
return gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_WINCON_TOKEN_COUNT).Get();
|
||||
case RO_WINCON_TRIFORCE_PIECES:
|
||||
return gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >=
|
||||
RAND_GET_OPTION(RSK_WINCON_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CompletedAllTrials() {
|
||||
|
|
@ -169,59 +224,32 @@ bool CompletedAllTrials() {
|
|||
|
||||
bool MeetsRainbowBridgeRequirements() {
|
||||
switch (RAND_GET_OPTION(RSK_RAINBOW_BRIDGE).Get()) {
|
||||
case RO_BRIDGE_VANILLA: {
|
||||
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_STONES: {
|
||||
if ((CheckStoneCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_MEDALLIONS: {
|
||||
if ((CheckMedallionCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_DUNGEON_REWARDS: {
|
||||
if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_DUNGEONS: {
|
||||
if ((CheckDungeonCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_TOKENS: {
|
||||
if (gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_GREG: {
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RO_BRIDGE_ALWAYS_OPEN: {
|
||||
case RO_BRIDGE_VANILLA:
|
||||
return CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT;
|
||||
case RO_BRIDGE_STONES:
|
||||
return (CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get();
|
||||
case RO_BRIDGE_MEDALLIONS:
|
||||
return (CheckMedallionCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get();
|
||||
case RO_BRIDGE_DUNGEON_REWARDS:
|
||||
return (CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get();
|
||||
case RO_BRIDGE_DUNGEONS:
|
||||
return (CheckDungeonCount() + CheckBridgeRewardCount()) >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get();
|
||||
case RO_BRIDGE_TOKENS:
|
||||
return gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get();
|
||||
case RO_BRIDGE_TRIFORCE_PIECES:
|
||||
return gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >=
|
||||
RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT).Get();
|
||||
case RO_BRIDGE_GREG:
|
||||
return Flags_GetRandomizerInf(RAND_INF_GREG_FOUND);
|
||||
case RO_BRIDGE_ALWAYS_OPEN:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Todo Move this to randomizer context, clear it out on save load etc
|
||||
|
|
@ -229,9 +257,26 @@ static std::queue<RandomizerCheck> randomizerQueuedChecks;
|
|||
static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK;
|
||||
static GetItemEntry randomizerQueuedItemEntry = GET_ITEM_NONE;
|
||||
|
||||
void CheckTriggers() {
|
||||
if (!(gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER] & 1) && MeetsGBKRequirements()) {
|
||||
SPDLOG_INFO("Queuing RC: RC_GANONS_BOSS_KEY");
|
||||
randomizerQueuedChecks.push(RC_GANONS_BOSS_KEY);
|
||||
}
|
||||
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_GANON_SOUL) && MeetsGanonsSoulRequirements()) {
|
||||
SPDLOG_INFO("Queuing RC: RC_GANON_SOUL");
|
||||
randomizerQueuedChecks.push(RC_GANON_SOUL);
|
||||
}
|
||||
|
||||
if (MeetsWinconRequirements()) {
|
||||
SPDLOG_INFO("Queuing RC: RC_WINCON");
|
||||
randomizerQueuedChecks.push(RC_WINCON);
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) {
|
||||
// Consume adult trade items
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && flagType == FLAG_RANDOMIZER_INF) {
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE).Get() && flagType == FLAG_RANDOMIZER_INF) {
|
||||
switch (flag) {
|
||||
case RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD:
|
||||
Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN);
|
||||
|
|
@ -522,6 +567,8 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) {
|
|||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnPlayerUpdate>(updateHook);
|
||||
});
|
||||
}
|
||||
|
||||
CheckTriggers();
|
||||
}
|
||||
|
||||
void EnExItem_DrawRandomizedItem(EnExItem* enExItem, PlayState* play) {
|
||||
|
|
@ -1002,14 +1049,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
case VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD:
|
||||
*should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY);
|
||||
break;
|
||||
case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS:
|
||||
*should = LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
|
||||
MeetsLACSRequirements();
|
||||
break;
|
||||
case VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW:
|
||||
*should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT &&
|
||||
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE &&
|
||||
gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_KAKARIKO_VILLAGE &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && gSaveContext.cutsceneIndex < 0xFFF0;
|
||||
break;
|
||||
|
|
@ -1705,6 +1747,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
}
|
||||
break;
|
||||
}
|
||||
case VB_SLAY_GANON:
|
||||
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_WINCON_OPTIONS) != RO_WINCON_DEFEAT_GANON) {
|
||||
// TODO blue warp
|
||||
*should = false;
|
||||
}
|
||||
case VB_DRAW_AMMO_COUNT: {
|
||||
s16 item = *va_arg(args, s16*);
|
||||
// don't draw ammo count if you have the infinite upgrade
|
||||
|
|
@ -1755,8 +1802,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
}
|
||||
case VB_SKIP_SCARECROWS_SONG: {
|
||||
int ocarinaButtonCount = 0;
|
||||
for (int i = VB_HAVE_OCARINA_NOTE_A4; i <= VB_HAVE_OCARINA_NOTE_F4; i++) {
|
||||
if (GameInteractor_Should((GIVanillaBehavior)i, true)) {
|
||||
for (int i = RAND_INF_HAS_OCARINA_A; i <= RAND_INF_HAS_OCARINA_C_RIGHT; i++) {
|
||||
if (Flags_GetRandomizerInf((RandomizerInf)i)) {
|
||||
ocarinaButtonCount++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1906,6 +1953,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
break;
|
||||
}
|
||||
case VB_FREEZE_ON_SKULL_TOKEN:
|
||||
CheckTriggers();
|
||||
[[fallthrough]];
|
||||
case VB_TRADE_TIMER_ODD_MUSHROOM:
|
||||
case VB_TRADE_TIMER_FROG:
|
||||
case VB_GIVE_ITEM_FROM_TARGET_IN_WOODS:
|
||||
|
|
@ -2008,6 +2057,9 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) {
|
|||
Entrance_OverrideSpawnScene(sceneNum, gPlayState->curSpawn);
|
||||
}
|
||||
|
||||
// Check here in case queued item got lost by poorly timed save & quit
|
||||
CheckTriggers();
|
||||
|
||||
// LACS & Prelude checks
|
||||
static uint32_t updateHook = 0;
|
||||
|
||||
|
|
@ -2030,7 +2082,9 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) {
|
|||
}
|
||||
|
||||
// We're always in rando here, and rando always overrides this should so we can just pass false
|
||||
if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, false)) {
|
||||
if (LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
|
||||
}
|
||||
|
||||
|
|
@ -2309,9 +2363,9 @@ void RandomizerOnActorInitHandler(void* actorRef) {
|
|||
Actor_Kill(actor);
|
||||
}
|
||||
|
||||
RandomizerInf currentBossSoulRandInf = RAND_INF_MAX;
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BOSS_SOULS)) {
|
||||
// Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair
|
||||
RandomizerInf currentBossSoulRandInf = RAND_INF_MAX;
|
||||
switch (gPlayState->sceneNum) {
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
currentBossSoulRandInf = RAND_INF_GOHMA_SOUL;
|
||||
|
|
@ -2337,30 +2391,33 @@ void RandomizerOnActorInitHandler(void* actorRef) {
|
|||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
currentBossSoulRandInf = RAND_INF_TWINROVA_SOUL;
|
||||
break;
|
||||
case SCENE_GANONDORF_BOSS:
|
||||
case SCENE_GANON_BOSS:
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) {
|
||||
currentBossSoulRandInf = RAND_INF_GANON_SOUL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes all actors in the boss category if the soul isn't found.
|
||||
// Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual
|
||||
// bosses, so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX. Iron Knuckle
|
||||
// (Nabooru) in Twinrova's room is a special exception, so exclude knuckles too.
|
||||
if (currentBossSoulRandInf != RAND_INF_MAX) {
|
||||
if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS &&
|
||||
actor->id != ACTOR_EN_IK) {
|
||||
Actor_Delete(&gPlayState->actorCtx, actor, gPlayState);
|
||||
}
|
||||
// Special case for Phantom Ganon's horse (and fake), as they're considered "background actors",
|
||||
// but still control the boss fight flow.
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_PHANTOM_GANON_SOUL) && actor->id == ACTOR_EN_FHG) {
|
||||
Actor_Delete(&gPlayState->actorCtx, actor, gPlayState);
|
||||
}
|
||||
if (RAND_GET_OPTION(RSK_GANONS_SOUL).IsNot(RO_GANONS_SOUL_STARTWITH)) {
|
||||
switch (gPlayState->sceneNum) {
|
||||
case SCENE_GANONDORF_BOSS:
|
||||
case SCENE_GANON_BOSS:
|
||||
currentBossSoulRandInf = RAND_INF_GANON_SOUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes all actors in the boss category if the soul isn't found.
|
||||
// Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual
|
||||
// bosses, so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX. Iron Knuckle
|
||||
// (Nabooru) in Twinrova's room is a special exception, so exclude knuckles too.
|
||||
if (currentBossSoulRandInf != RAND_INF_MAX) {
|
||||
if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS &&
|
||||
actor->id != ACTOR_EN_IK) {
|
||||
Actor_Delete(&gPlayState->actorCtx, actor, gPlayState);
|
||||
}
|
||||
// Special case for Phantom Ganon's horse (and fake), as they're considered "background actors",
|
||||
// but still control the boss fight flow.
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_PHANTOM_GANON_SOUL) && actor->id == ACTOR_EN_FHG) {
|
||||
Actor_Delete(&gPlayState->actorCtx, actor, gPlayState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -427,7 +427,8 @@ bool Item::IsBottleItem() const {
|
|||
bool Item::IsMajorItem() const {
|
||||
const auto ctx = Context::GetInstance();
|
||||
if (type == ITEMTYPE_TOKEN) {
|
||||
return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) || ctx->LACSCondition() == RO_LACS_TOKENS;
|
||||
return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) ||
|
||||
ctx->GBKCondition() == RO_CHECK_TRIGGER_TOKENS;
|
||||
}
|
||||
|
||||
if (type == ITEMTYPE_DROP || type == ITEMTYPE_EVENT || type == ITEMTYPE_SHOP || type == ITEMTYPE_MAP ||
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ void Rando::StaticData::InitItemTable() {
|
|||
|
||||
itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "Sac de Noix Mojo", "Deku-Nuß-Tasche" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "eine "}).CustomIcon(gItemIconDekuNutTex);
|
||||
|
||||
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_MAJOR, {"the ", "la ", "die "});
|
||||
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_ITEM, RG_TRIFORCE, true, LOGIC_NONE, RHT_NONE, RG_TRIFORCE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "die "});
|
||||
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_LESSER);
|
||||
// Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen)
|
||||
itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "});
|
||||
|
|
@ -453,7 +453,7 @@ void Rando::StaticData::InitItemTable() {
|
|||
itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku-Stab-Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE).CustomIcon(gItemIconDekuStickTex);
|
||||
itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "das "}).CustomIcon(gQuestIconMagicJarSmallTex, ICON_SIZE_24);
|
||||
itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbessertes Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "das "}).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24);
|
||||
itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Morceau de Triforce", "Triforce-Fragment" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "ein "}).CustomIcon(gTriforcePieceTex);
|
||||
itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Morceau de Triforce", "Triforce-Fragment" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_NONE, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "ein "}).CustomIcon(gTriforcePieceTex);
|
||||
itemTable[RG_ROCS_FEATHER] = Item(RG_ROCS_FEATHER, Text{ "Roc's Feather", "Plume de Roc", "Grefenfeider" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_ROCS_FEATHER, RHT_ROCS_FEATHER, RG_ROCS_FEATHER, OBJECT_GI_BOMB_2, GID_ROCS_FEATHER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "la ", "ein "}).CustomIcon(gRocsFeatherTex);
|
||||
itemTable[RG_ROCS_FEATHER].SetCustomDrawFunc(Randomizer_DrawRocsFeather);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ void RegionTable_Init_TempleOfTime() {
|
|||
|
||||
areaTable[RR_TEMPLE_OF_TIME] = Region("Temple of Time", SCENE_TEMPLE_OF_TIME, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS()),
|
||||
LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->HasItem(RG_SHADOW_MEDALLION) && logic->HasItem(RG_SPIRIT_MEDALLION)),
|
||||
LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild),
|
||||
LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult),
|
||||
LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult && logic->HasItem(RG_SPEAK_HYLIAN)),
|
||||
|
|
@ -45,7 +45,7 @@ void RegionTable_Init_TempleOfTime() {
|
|||
//Locations
|
||||
LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult),
|
||||
LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult),
|
||||
LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult),
|
||||
LOCATION(RC_SHEIK_AT_TEMPLE, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION)),
|
||||
}, {
|
||||
//Exits
|
||||
ENTRANCE(RR_TEMPLE_OF_TIME, true),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ void RegionTable_Init_Root() {
|
|||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LINKS_POCKET, true),
|
||||
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1;),
|
||||
LOCATION(RC_GANONS_BOSS_KEY, logic->CanTriggerGBK()),
|
||||
LOCATION(RC_GANON_SOUL, logic->CanTriggerGanonsSoul()),
|
||||
LOCATION(RC_WINCON, logic->CanTriggerWincon()),
|
||||
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
||||
LOCATION(RC_SONG_FROM_IMPA, (bool)ctx->GetOption(RSK_SKIP_CHILD_ZELDA)),
|
||||
LOCATION(RC_HC_MALON_EGG, (bool)ctx->GetOption(RSK_SKIP_CHILD_ZELDA)),
|
||||
|
|
|
|||
|
|
@ -994,7 +994,10 @@ void Rando::StaticData::InitLocationTable() {
|
|||
locationTable[RC_BIGGORON_HINT] = Location::OtherHint(RC_BIGGORON_HINT, RCQUEST_BOTH, ACTOR_EN_GO2, SCENE_DEATH_MOUNTAIN_TRAIL, "Biggoron Hint");
|
||||
locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint");
|
||||
|
||||
locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE);
|
||||
// Conditional
|
||||
locationTable[RC_WINCON] = Location::Base(RC_WINCON, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Win Condition", "Win Condition", RHT_NONE, RG_NONE);
|
||||
locationTable[RC_GANONS_BOSS_KEY] = Location::Base(RC_GANONS_BOSS_KEY, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Ganon's Boss Key", "Ganon's Boss Key", RHT_NONE, RG_NONE);
|
||||
locationTable[RC_GANON_SOUL] = Location::Base(RC_GANON_SOUL, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Ganon's Soul", "Ganon's Soul", RHT_NONE, RG_NONE);
|
||||
// clang-format on
|
||||
|
||||
// Init locationNameToEnum
|
||||
|
|
|
|||
|
|
@ -450,7 +450,9 @@ bool Logic::HasProjectile(HasProjectileAge age) {
|
|||
}
|
||||
|
||||
bool Logic::HasBossSoul(RandomizerGet itemName) {
|
||||
if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) {
|
||||
if (itemName == RG_GANON_SOUL && ctx->GetOption(RSK_GANONS_SOUL).IsNot(RO_GANONS_SOUL_STARTWITH)) {
|
||||
return HasItem(itemName);
|
||||
} else if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) {
|
||||
return true;
|
||||
}
|
||||
switch (itemName) {
|
||||
|
|
@ -463,9 +465,6 @@ bool Logic::HasBossSoul(RandomizerGet itemName) {
|
|||
case RG_BONGO_BONGO_SOUL:
|
||||
case RG_TWINROVA_SOUL:
|
||||
return HasItem(itemName);
|
||||
case RG_GANON_SOUL:
|
||||
return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL)
|
||||
: true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1552,22 +1551,87 @@ bool Logic::CanBuildRainbowBridge() {
|
|||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE));
|
||||
}
|
||||
|
||||
bool Logic::CanTriggerLACS() {
|
||||
return (ctx->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) ||
|
||||
(ctx->LACSCondition() == RO_LACS_STONES &&
|
||||
StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_LACS_STONE_COUNT).Get()) ||
|
||||
(ctx->LACSCondition() == RO_LACS_MEDALLIONS &&
|
||||
MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()) ||
|
||||
(ctx->LACSCondition() == RO_LACS_REWARDS &&
|
||||
StoneCount() + MedallionCount() +
|
||||
(HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()) ||
|
||||
(ctx->LACSCondition() == RO_LACS_DUNGEONS &&
|
||||
DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()) ||
|
||||
(ctx->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get());
|
||||
bool Logic::CanTriggerGBK() {
|
||||
switch (ctx->GBKCondition()) {
|
||||
case RO_CHECK_TRIGGER_STONES:
|
||||
return StoneCount() +
|
||||
(HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_GBK_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GBK_STONE_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_MEDALLIONS:
|
||||
return MedallionCount() +
|
||||
(HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_GBK_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GBK_MEDALLION_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_REWARDS:
|
||||
return StoneCount() + MedallionCount() +
|
||||
(HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_GBK_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GBK_REWARD_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_DUNGEONS:
|
||||
return DungeonCount() +
|
||||
(HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_GBK_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GBK_DUNGEON_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_TOKENS:
|
||||
return GetGSCount() >= ctx->GetOption(RSK_GBK_TOKEN_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_TRIFORCE_PIECES:
|
||||
return GetTriforcePieceCount() >= ctx->GetOption(RSK_GBK_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Logic::CanTriggerGanonsSoul() {
|
||||
switch (ctx->GanonsSoulCondition()) {
|
||||
case RO_CHECK_TRIGGER_STONES:
|
||||
return StoneCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_GANONS_SOUL_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GANONS_SOUL_STONE_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_MEDALLIONS:
|
||||
return MedallionCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_GANONS_SOUL_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GANONS_SOUL_MEDALLION_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_REWARDS:
|
||||
return StoneCount() + MedallionCount() +
|
||||
(HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_GANONS_SOUL_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GANONS_SOUL_REWARD_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_DUNGEONS:
|
||||
return DungeonCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_GANONS_SOUL_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_GANONS_SOUL_DUNGEON_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_TOKENS:
|
||||
return GetGSCount() >= ctx->GetOption(RSK_GANONS_SOUL_TOKEN_COUNT).Get();
|
||||
case RO_CHECK_TRIGGER_TRIFORCE_PIECES:
|
||||
return GetTriforcePieceCount() >= ctx->GetOption(RSK_GANONS_SOUL_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Logic::CanTriggerWincon() {
|
||||
switch (ctx->WinCondition()) {
|
||||
case RO_WINCON_STONES:
|
||||
return StoneCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_WINCON_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_WINCON_STONE_COUNT).Get();
|
||||
case RO_WINCON_MEDALLIONS:
|
||||
return MedallionCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_WINCON_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_WINCON_MEDALLION_COUNT).Get();
|
||||
case RO_WINCON_REWARDS:
|
||||
return StoneCount() + MedallionCount() +
|
||||
(HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_WINCON_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_WINCON_REWARD_COUNT).Get();
|
||||
case RO_WINCON_DUNGEONS:
|
||||
return DungeonCount() + (HasItem(RG_GREG_RUPEE) &&
|
||||
ctx->GetOption(RSK_WINCON_OPTIONS).Is(RO_CHECK_TRIGGER_GREG_REWARD)) >=
|
||||
ctx->GetOption(RSK_WINCON_DUNGEON_COUNT).Get();
|
||||
case RO_WINCON_TOKENS:
|
||||
return GetGSCount() >= ctx->GetOption(RSK_WINCON_TOKEN_COUNT).Get();
|
||||
case RO_WINCON_TRIFORCE_PIECES:
|
||||
return GetTriforcePieceCount() >= ctx->GetOption(RSK_WINCON_TRIFORCE_COUNT).Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Logic::SmallKeys(s16 scene, uint8_t requiredAmount) {
|
||||
|
|
@ -2527,6 +2591,10 @@ uint8_t Logic::GetGSCount() {
|
|||
return static_cast<uint8_t>(mSaveContext->inventory.gsTokens);
|
||||
}
|
||||
|
||||
uint8_t Logic::GetTriforcePieceCount() {
|
||||
return mSaveContext->ship.quest.data.randomizer.triforcePiecesCollected;
|
||||
}
|
||||
|
||||
uint8_t Logic::GetAmmo(uint32_t item) {
|
||||
return mSaveContext->inventory.ammo[gItemSlots[item]];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,9 @@ class Logic {
|
|||
bool CanShield();
|
||||
bool CanUseProjectile();
|
||||
bool CanBuildRainbowBridge();
|
||||
bool CanTriggerLACS();
|
||||
bool CanTriggerGBK();
|
||||
bool CanTriggerGanonsSoul();
|
||||
bool CanTriggerWincon();
|
||||
bool IsFireLoopLocked();
|
||||
bool ReachScarecrow();
|
||||
bool ReachDistantScarecrow();
|
||||
|
|
@ -144,6 +146,7 @@ class Logic {
|
|||
void SetRandoInf(uint32_t flag, bool state);
|
||||
bool CheckEventChkInf(int32_t flag);
|
||||
uint8_t GetGSCount();
|
||||
uint8_t GetTriforcePieceCount();
|
||||
void SetEventChkInf(int32_t flag, bool state);
|
||||
uint8_t GetAmmo(uint32_t item);
|
||||
void SetAmmo(uint32_t item, uint8_t count);
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ void Settings::CreateOptionDescriptions() {
|
|||
mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL] =
|
||||
"The amount of Triforce pieces that will be placed in the world. "
|
||||
"Keep in mind seed generation can fail if more pieces are placed than there are junk items in the item pool.";
|
||||
mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] = "The amount of Triforce pieces required to win the game.";
|
||||
mOptionDescriptions[RSK_WINCON_TRIFORCE_COUNT] = "The amount of Triforce pieces required to win the game.";
|
||||
mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] =
|
||||
"Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Ground.\n"
|
||||
"\n"
|
||||
|
|
@ -637,19 +637,15 @@ void Settings::CreateOptionDescriptions() {
|
|||
"\n"
|
||||
"Anywhere - Ganon's Boss Key Key can appear anywhere in the world.\n"
|
||||
"\n"
|
||||
"LACS - These settings put the boss key on the Light Arrow Cutscene location, from Zelda in Temple of Time as "
|
||||
"adult, with differing requirements:\n"
|
||||
"- Vanilla: Obtain the Shadow Medallion and Spirit Medallion\n"
|
||||
"Trigger - These settings put the boss key on a trigger, "
|
||||
"granting key once requirements met:\n"
|
||||
"- Stones: Obtain the specified amount of Spiritual Stones.\n"
|
||||
"- Medallions: Obtain the specified amount of medallions.\n"
|
||||
"- Dungeon rewards: Obtain the specified total sum of Spiritual Stones or medallions.\n"
|
||||
"- Dungeons: Complete the specified amount of dungeons. Dungeons are considered complete after stepping in to "
|
||||
"the blue warp after the boss.\n"
|
||||
"- Tokens: Obtain the specified amount of Skulltula tokens.\n"
|
||||
"\n"
|
||||
"100 GS Reward - Ganon's Boss Key will be awarded by the cursed rich man after you collect 100 Gold Skulltula "
|
||||
"Tokens.";
|
||||
mOptionDescriptions[RSK_LACS_OPTIONS] =
|
||||
"- Tokens: Obtain the specified amount of Skulltula tokens.";
|
||||
mOptionDescriptions[RSK_GBK_OPTIONS] =
|
||||
"Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, max "
|
||||
"number of rewards on slider does not change.\n"
|
||||
"\n"
|
||||
|
|
@ -659,6 +655,16 @@ void Settings::CreateOptionDescriptions() {
|
|||
"\n"
|
||||
"Greg as Wildcard - Greg does not change logic, Greg helps obtain GBK, max number of "
|
||||
"rewards on slider does not change.";
|
||||
mOptionDescriptions[RSK_GANONS_SOUL_OPTIONS] =
|
||||
"Standard Rewards - Greg does not change logic, Greg does not help obtain Ganon's Soul, max "
|
||||
"number of rewards on slider does not change.\n"
|
||||
"\n"
|
||||
"Greg as Reward - Greg does change logic (can be part of expected path for obtaining "
|
||||
"Ganon's Soul), Greg helps obtain Ganon's Soul, max number of rewards on slider increases by 1 to "
|
||||
"account for Greg. \n"
|
||||
"\n"
|
||||
"Greg as Wildcard - Greg does not change logic, Greg helps obtain Ganon's Soul, max number of "
|
||||
"rewards on slider does not change.";
|
||||
mOptionDescriptions[RSK_BIG_POE_COUNT] = "The Poe collector will give a reward for turning in this many Big Poes.";
|
||||
mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] =
|
||||
"The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.";
|
||||
|
|
|
|||
|
|
@ -312,7 +312,6 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
|
|||
u8 numWallets = 2 + (u8)tycoonWallet + (infiniteUpgrades != RO_INF_UPGRADES_OFF ? 1 : 0);
|
||||
switch (randoGet) {
|
||||
case RG_NONE:
|
||||
case RG_TRIFORCE:
|
||||
case RG_HINT:
|
||||
case RG_MAX:
|
||||
case RG_SOLD_OUT:
|
||||
|
|
@ -718,6 +717,7 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
|
|||
case RG_TREASURE_GAME_GREEN_RUPEE:
|
||||
case RG_BUY_HEART:
|
||||
case RG_TRIFORCE_PIECE:
|
||||
case RG_TRIFORCE:
|
||||
default:
|
||||
return CAN_OBTAIN;
|
||||
}
|
||||
|
|
@ -4576,13 +4576,16 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
|||
Flags_SetRandomizerInf(RAND_INF_GREG_FOUND);
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_FOUND_GREG] = static_cast<u32>(GAMEPLAYSTAT_TOTAL_TIME);
|
||||
break;
|
||||
case RG_TRIFORCE:
|
||||
GameInteractor_SetTriforceHuntCreditsWarpActive(true);
|
||||
break;
|
||||
case RG_TRIFORCE_PIECE:
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected++;
|
||||
GameInteractor_SetTriforceHuntPieceGiven(true);
|
||||
|
||||
// Give Ganon's Boss Key and teleport to credits if set to Win when goal is reached.
|
||||
if (gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected ==
|
||||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) {
|
||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_WINCON_TRIFORCE_COUNT)) {
|
||||
Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY);
|
||||
|
||||
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) ==
|
||||
|
|
|
|||
|
|
@ -177,7 +177,6 @@ RANDO_ENUM_ITEM(LOGIC_OCARINA_C_UP_BUTTON)
|
|||
RANDO_ENUM_ITEM(LOGIC_OCARINA_C_DOWN_BUTTON)
|
||||
RANDO_ENUM_ITEM(LOGIC_OCARINA_C_LEFT_BUTTON)
|
||||
RANDO_ENUM_ITEM(LOGIC_OCARINA_C_RIGHT_BUTTON)
|
||||
RANDO_ENUM_ITEM(LOGIC_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_ITEM(LOGIC_ROCS_FEATHER)
|
||||
RANDO_ENUM_ITEM(LOGIC_CAN_BORROW_MASKS)
|
||||
RANDO_ENUM_ITEM(LOGIC_BORROW_SKULL_MASK)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
RANDO_ENUM_BEGIN(RandomizerCheck)
|
||||
RANDO_ENUM_ITEM(RC_UNKNOWN_CHECK)
|
||||
RANDO_ENUM_ITEM(RC_LINKS_POCKET)
|
||||
RANDO_ENUM_ITEM(RC_GANONS_BOSS_KEY)
|
||||
RANDO_ENUM_ITEM(RC_GANON_SOUL)
|
||||
RANDO_ENUM_ITEM(RC_QUEEN_GOHMA)
|
||||
RANDO_ENUM_ITEM(RC_KING_DODONGO)
|
||||
RANDO_ENUM_ITEM(RC_BARINADE)
|
||||
|
|
@ -1773,7 +1775,7 @@ RANDO_ENUM_ITEM(RC_COLOSSUS_GROTTO_BEEHIVE)
|
|||
RANDO_ENUM_ITEM(RC_GANONDORF_HINT)
|
||||
RANDO_ENUM_ITEM(RC_SHEIK_HINT_GC)
|
||||
RANDO_ENUM_ITEM(RC_SHEIK_HINT_MQ_GC)
|
||||
RANDO_ENUM_ITEM(RC_TRIFORCE_COMPLETED)
|
||||
RANDO_ENUM_ITEM(RC_WINCON)
|
||||
RANDO_ENUM_ITEM(RC_DAMPE_HINT)
|
||||
RANDO_ENUM_ITEM(RC_GREG_HINT)
|
||||
RANDO_ENUM_ITEM(RC_SARIA_SONG_HINT)
|
||||
|
|
|
|||
|
|
@ -1223,6 +1223,7 @@ RANDO_ENUM_ITEM(RHT_BRIDGE_MEDALLIONS_HINT)
|
|||
RANDO_ENUM_ITEM(RHT_BRIDGE_REWARDS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_BRIDGE_DUNGEONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_BRIDGE_TOKENS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_BRIDGE_TRIFORCE_PIECES_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_BRIDGE_GREG_HINT)
|
||||
// Ganon Boss Key
|
||||
RANDO_ENUM_ITEM(RHT_GANON_BK_START_WITH_HINT)
|
||||
|
|
@ -1233,13 +1234,20 @@ RANDO_ENUM_ITEM(RHT_GANON_BK_ANY_DUNGEON_HINT)
|
|||
RANDO_ENUM_ITEM(RHT_GANON_BK_ANYWHERE_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANON_BK_TRIFORCE_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANON_BK_SKULLTULA_HINT)
|
||||
// LACS
|
||||
RANDO_ENUM_ITEM(RHT_LACS_VANILLA_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_LACS_MEDALLIONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_LACS_STONES_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_LACS_REWARDS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_LACS_DUNGEONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_LACS_TOKENS_HINT)
|
||||
// GBK
|
||||
RANDO_ENUM_ITEM(RHT_GBK_MEDALLIONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GBK_STONES_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GBK_REWARDS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GBK_DUNGEONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GBK_TOKENS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GBK_TRIFORCE_PIECES_HINT)
|
||||
// Ganon's Soul
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_MEDALLIONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_STONES_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_REWARDS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_DUNGEONS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_TOKENS_HINT)
|
||||
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_TRIFORCE_PIECES_HINT)
|
||||
// Trials
|
||||
RANDO_ENUM_ITEM(RHT_SIX_TRIALS)
|
||||
RANDO_ENUM_ITEM(RHT_ZERO_TRIALS)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ RANDO_ENUM_BEGIN(RandomizerInf)
|
|||
|
||||
RANDO_ENUM_ITEM(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)
|
||||
RANDO_ENUM_ITEM(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)
|
||||
RANDO_ENUM_ITEM(RAND_INF_DUNGEONS_DONE_GANONS_TOWER)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)
|
||||
RANDO_ENUM_ITEM(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ RANDO_ENUM_ITEM(RO_BRIDGE_MEDALLIONS)
|
|||
RANDO_ENUM_ITEM(RO_BRIDGE_DUNGEON_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_BRIDGE_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_BRIDGE_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_BRIDGE_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_ITEM(RO_BRIDGE_GREG)
|
||||
RANDO_ENUM_END(RandoOptionRainbowBridge)
|
||||
|
||||
|
|
@ -155,7 +156,6 @@ RANDO_ENUM_END(RandoOptionBombchuBag)
|
|||
RANDO_ENUM_BEGIN(RandoOptionBossSouls)
|
||||
RANDO_ENUM_ITEM(RO_BOSS_SOULS_OFF)
|
||||
RANDO_ENUM_ITEM(RO_BOSS_SOULS_ON)
|
||||
RANDO_ENUM_ITEM(RO_BOSS_SOULS_ON_PLUS_GANON)
|
||||
RANDO_ENUM_END(RandoOptionBossSouls)
|
||||
|
||||
// Fishsanity settings (off, loach only, pond only, grottos only, both)
|
||||
|
|
@ -209,8 +209,7 @@ RANDO_ENUM_ITEM(RO_KEYRING_FOR_DUNGEON_RANDOM)
|
|||
RANDO_ENUM_ITEM(RO_KEYRING_FOR_DUNGEON_ON)
|
||||
RANDO_ENUM_END(RandoOptionKeyringForDungeon)
|
||||
|
||||
// Ganon's Boss Key Settings (vanilla, own dungeon, start with,
|
||||
// overworld, anywhere, 100 GS reward)
|
||||
// Ganon's Boss Key Settings
|
||||
RANDO_ENUM_BEGIN(RandoOptionGanonsBossKey)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_VANILLA)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_OWN_DUNGEON)
|
||||
|
|
@ -218,30 +217,57 @@ RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_STARTWITH)
|
|||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_ANY_DUNGEON)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_OVERWORLD)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_ANYWHERE)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_VANILLA)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_STONES)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_LACS_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_KAK_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_STONES)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_GANON_BOSS_KEY_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_END(RandoOptionGanonsBossKey)
|
||||
|
||||
RANDO_ENUM_BEGIN(RandoOptionLACSCondition)
|
||||
RANDO_ENUM_ITEM(RO_LACS_VANILLA)
|
||||
RANDO_ENUM_ITEM(RO_LACS_STONES)
|
||||
RANDO_ENUM_ITEM(RO_LACS_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_LACS_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_LACS_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_LACS_TOKENS)
|
||||
RANDO_ENUM_END(RandoOptionLACSCondition)
|
||||
// Ganon's Soul Settings
|
||||
RANDO_ENUM_BEGIN(RandoOptionGanonsSoul)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_STARTWITH)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_ANY_DUNGEON)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_OVERWORLD)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_ANYWHERE)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_STONES)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_GANONS_SOUL_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_END(RandoOptionGanonsSoul)
|
||||
|
||||
// LACS Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard)
|
||||
RANDO_ENUM_BEGIN(RandoOptionLACSRewards)
|
||||
RANDO_ENUM_ITEM(RO_LACS_STANDARD_REWARD)
|
||||
RANDO_ENUM_ITEM(RO_LACS_GREG_REWARD)
|
||||
RANDO_ENUM_ITEM(RO_LACS_WILDCARD_REWARD)
|
||||
RANDO_ENUM_END(RandoOptionLACSRewards)
|
||||
// Wincon Triggers
|
||||
RANDO_ENUM_BEGIN(RandoOptionWincon)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_DEFEAT_GANON)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_ANYWHERE)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_STONES)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_WINCON_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_END(RandoOptionWincon)
|
||||
|
||||
// Reward Triggers
|
||||
RANDO_ENUM_BEGIN(RandoOptionCheckTrigger)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_NONE)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_STONES)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_MEDALLIONS)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_REWARDS)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_DUNGEONS)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_TOKENS)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_TRIFORCE_PIECES)
|
||||
RANDO_ENUM_END(RandoOptionCheckTrigger)
|
||||
|
||||
// Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard)
|
||||
RANDO_ENUM_BEGIN(RandoOptionCheckTriggerRewards)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_STANDARD_REWARD)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_GREG_REWARD)
|
||||
RANDO_ENUM_ITEM(RO_CHECK_TRIGGER_WILDCARD_REWARD)
|
||||
RANDO_ENUM_END(RandoOptionCheckTriggerRewards)
|
||||
|
||||
// Ganon's Trials
|
||||
RANDO_ENUM_BEGIN(RandoOptionGanonsTrials)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ RANDO_ENUM_ITEM(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT)
|
|||
RANDO_ENUM_ITEM(RSK_RAINBOW_BRIDGE_REWARD_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_RAINBOW_BRIDGE_TOKEN_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_BRIDGE_OPTIONS)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_TRIALS)
|
||||
RANDO_ENUM_ITEM(RSK_TRIAL_COUNT)
|
||||
|
|
@ -135,6 +136,7 @@ RANDO_ENUM_ITEM(RSK_KEYSANITY)
|
|||
RANDO_ENUM_ITEM(RSK_GERUDO_KEYS)
|
||||
RANDO_ENUM_ITEM(RSK_BOSS_KEYSANITY)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_BOSS_KEY)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL)
|
||||
RANDO_ENUM_ITEM(RSK_SKIP_CHILD_STEALTH)
|
||||
RANDO_ENUM_ITEM(RSK_SKIP_CHILD_ZELDA)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_STICKS)
|
||||
|
|
@ -183,12 +185,20 @@ RANDO_ENUM_ITEM(RSK_MQ_BOTTOM_OF_THE_WELL)
|
|||
RANDO_ENUM_ITEM(RSK_MQ_ICE_CAVERN)
|
||||
RANDO_ENUM_ITEM(RSK_MQ_GTG)
|
||||
RANDO_ENUM_ITEM(RSK_MQ_GANONS_CASTLE)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_STONE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_MEDALLION_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_REWARD_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_TOKEN_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_LACS_OPTIONS)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_STONE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_MEDALLION_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_REWARD_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_TOKEN_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_TRIFORCE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GBK_OPTIONS)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_STONE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_MEDALLION_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_REWARD_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_TOKEN_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_TRIFORCE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_GANONS_SOUL_OPTIONS)
|
||||
RANDO_ENUM_ITEM(RSK_KEYRINGS)
|
||||
RANDO_ENUM_ITEM(RSK_KEYRINGS_RANDOM_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_KEYRINGS_GERUDO_FORTRESS)
|
||||
|
|
@ -226,7 +236,14 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_GANONS_TOWER_ENTRANCE)
|
|||
RANDO_ENUM_ITEM(RSK_SHUFFLE_100_GS_REWARD)
|
||||
RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT)
|
||||
RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT_PIECES_TOTAL)
|
||||
RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT_PIECES_REQUIRED)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_STONE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_MEDALLION_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_REWARD_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_TOKEN_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_TRIFORCE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_WINCON_OPTIONS)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_BEAN_SOULS)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_BOSS_SOULS)
|
||||
RANDO_ENUM_ITEM(RSK_FISHSANITY)
|
||||
|
|
|
|||
|
|
@ -242,24 +242,33 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
|
|||
RO_DUNGEON_ITEM_LOC_VANILLA) &&
|
||||
(location.GetRCType() != RCTYPE_GANON_BOSS_KEY ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_VANILLA ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), 0)) &&
|
||||
(location.GetRandomizerCheck() != RC_TOT_LIGHT_ARROWS_CUTSCENE ||
|
||||
RO_GANON_BOSS_KEY_VANILLA) && // vanilla ganon boss key
|
||||
(location.GetRandomizerCheck() != RC_GANONS_BOSS_KEY ||
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_DUNGEONS &&
|
||||
RO_GANON_BOSS_KEY_DUNGEONS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_MEDALLIONS &&
|
||||
RO_GANON_BOSS_KEY_MEDALLIONS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_REWARDS &&
|
||||
RO_GANON_BOSS_KEY_REWARDS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_STONES &&
|
||||
RO_GANON_BOSS_KEY_STONES &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_TOKENS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_LACS_VANILLA)) && // LACS ganon boss key
|
||||
(location.GetRandomizerCheck() != RC_KAK_100_GOLD_SKULLTULA_REWARD ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_KAK_TOKENS) && // 100 skull reward ganon boss key
|
||||
RO_GANON_BOSS_KEY_TOKENS) &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_TRIFORCE_PIECES) && // ganon boss key condition
|
||||
(location.GetRandomizerCheck() != RC_GANON_SOUL ||
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_DUNGEONS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_MEDALLIONS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_REWARDS &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_STONES &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_TOKENS) &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH) !=
|
||||
RO_GANONS_SOUL_TRIFORCE_PIECES) && // ganon's soul condition
|
||||
(location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_TH_FREED_CARPENTERS ||
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) ==
|
||||
RO_GF_CARPENTERS_FREE &&
|
||||
|
|
|
|||
|
|
@ -1577,23 +1577,23 @@ void LoadSettings() {
|
|||
}
|
||||
|
||||
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY)) {
|
||||
case RO_GANON_BOSS_KEY_LACS_STONES:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_STONES);
|
||||
case RO_GANON_BOSS_KEY_STONES:
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_STONES);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_MEDALLIONS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_MEDALLIONS);
|
||||
case RO_GANON_BOSS_KEY_MEDALLIONS:
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_MEDALLIONS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_REWARDS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_REWARDS);
|
||||
case RO_GANON_BOSS_KEY_REWARDS:
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_REWARDS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_DUNGEONS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_DUNGEONS);
|
||||
case RO_GANON_BOSS_KEY_DUNGEONS:
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_DUNGEONS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_TOKENS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_TOKENS);
|
||||
case RO_GANON_BOSS_KEY_TOKENS:
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_TOKENS);
|
||||
break;
|
||||
default:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_VANILLA);
|
||||
Rando::Context::GetInstance()->GBKCondition(RO_CHECK_TRIGGER_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1616,7 +1616,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
|
|||
(showShops &&
|
||||
OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1)
|
||||
.enGirlAShopItem == 50)) &&
|
||||
(rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) &&
|
||||
(rc != RC_WINCON) && (rc != RC_GANON) &&
|
||||
(loc->GetRCType() != RCTYPE_SCRUB || showScrubs ||
|
||||
(showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized
|
||||
rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) &&
|
||||
|
|
|
|||
|
|
@ -766,7 +766,7 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) {
|
|||
std::string requiredString = "";
|
||||
std::string maxString = "";
|
||||
uint8_t piecesRequired =
|
||||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1);
|
||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_WINCON_TRIFORCE_COUNT);
|
||||
uint8_t piecesTotal =
|
||||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL) + 1);
|
||||
ImU32 currentColor = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >= piecesRequired
|
||||
|
|
@ -830,11 +830,14 @@ void DrawQuest(ItemTrackerItem item) {
|
|||
};
|
||||
|
||||
bool HasBossSoul(RandomizerInf bossSoul) {
|
||||
uint8_t soulSetting = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS);
|
||||
bool isSoulRandomized = IS_RANDO && (soulSetting == RO_BOSS_SOULS_ON_PLUS_GANON ||
|
||||
(soulSetting == RO_BOSS_SOULS_ON && bossSoul != RAND_INF_GANON_SOUL));
|
||||
|
||||
return isSoulRandomized ? Flags_GetRandomizerInf(bossSoul) : true;
|
||||
if (!IS_RANDO) {
|
||||
return false;
|
||||
} else if (bossSoul == RAND_INF_GANON_SOUL) {
|
||||
return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_SOUL) == RO_GANONS_SOUL_STARTWITH ||
|
||||
Flags_GetRandomizerInf(RAND_INF_GANON_SOUL);
|
||||
} else {
|
||||
return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS) && Flags_GetRandomizerInf(bossSoul);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawItem(ItemTrackerItem item) {
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ void Settings::CreateOptions() {
|
|||
mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Enable();
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE, "Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_VANILLA, false, nullptr, IMFLAG_NONE);
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE, "Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Triforce Pieces", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_VANILLA, false, nullptr, IMFLAG_NONE);
|
||||
OPT_CALLBACK(RSK_RAINBOW_BRIDGE, {
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Hide();
|
||||
|
|
@ -204,37 +204,38 @@ void Settings::CreateOptions() {
|
|||
mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT].Hide();
|
||||
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_VANILLA)) {
|
||||
case RO_BRIDGE_STONES:
|
||||
// Show Bridge Options and Stone Count slider
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Unhide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Unhide();
|
||||
break;
|
||||
case RO_BRIDGE_MEDALLIONS:
|
||||
// Show Bridge Options and Medallion Count Slider
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Unhide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Unhide();
|
||||
break;
|
||||
case RO_BRIDGE_DUNGEON_REWARDS:
|
||||
// Show Bridge Options and Dungeon Reward Count Slider
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Unhide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Unhide();
|
||||
break;
|
||||
case RO_BRIDGE_DUNGEONS:
|
||||
// Show Bridge Options and Dungeon Count Slider
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Unhide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Unhide();
|
||||
break;
|
||||
case RO_BRIDGE_TOKENS:
|
||||
// Show token count slider (not bridge options)
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Unhide();
|
||||
break;
|
||||
case RO_BRIDGE_TRIFORCE_PIECES:
|
||||
mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_BRIDGE_OPTIONS].Hide();
|
||||
mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT].Unhide();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -244,6 +245,7 @@ void Settings::CreateOptions() {
|
|||
OPT_U8(RSK_RAINBOW_BRIDGE_REWARD_COUNT, "Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, "Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE_TOKEN_COUNT, "Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT, "Bridge Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforcePieceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_BRIDGE_OPTIONS, "Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), mOptionDescriptions[RSK_BRIDGE_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_STANDARD_REWARD, false, nullptr, IMFLAG_NONE);
|
||||
OPT_CALLBACK(RSK_BRIDGE_OPTIONS, {
|
||||
const uint8_t bridgeOpt = CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD);
|
||||
|
|
@ -433,28 +435,28 @@ void Settings::CreateOptions() {
|
|||
// TODO: AmmoDrops and/or HeartDropRefill, combine with/separate Ammo Drops from Bombchu Drops?
|
||||
OPT_U8(RSK_TRIFORCE_HUNT, "Triforce Hunt", {"Off", "Win", "Ganon's Boss Key"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHunt"), mOptionDescriptions[RSK_TRIFORCE_HUNT]);
|
||||
OPT_CALLBACK(RSK_TRIFORCE_HUNT, {
|
||||
// Remove the pieces required/total sliders and add a separator after Triforce Hunt if Triforce Hunt is off
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF) == RO_TRIFORCE_HUNT_OFF) {
|
||||
mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide();
|
||||
mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide();
|
||||
mOptions[RSK_GANONS_BOSS_KEY].Enable();
|
||||
} else {
|
||||
mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Unhide();
|
||||
mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Unhide();
|
||||
mOptions[RSK_GANONS_BOSS_KEY].Disable(
|
||||
"This option is disabled because Triforce Hunt is enabled."
|
||||
"Ganon's Boss key\nwill instead be given to you after Triforce Hunt completion.");
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_TOTAL, "Triforce Hunt Total Pieces", {NumOpts(1, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], WIDGET_CVAR_SLIDER_INT, 29, false, nullptr, IMFLAG_NONE);
|
||||
OPT_CALLBACK(RSK_TRIFORCE_HUNT_PIECES_TOTAL, {
|
||||
// Update triforce pieces required to be capped at the current value for pieces total.
|
||||
const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 30);
|
||||
if (mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].GetOptionCount() != triforceTotal + 1) {
|
||||
mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].ChangeOptions(NumOpts(1, triforceTotal + 1));
|
||||
const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 29) + 1;
|
||||
if (mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT].GetOptionCount() != triforceTotal) {
|
||||
mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT].ChangeOptions(NumOpts(0, triforceTotal));
|
||||
}
|
||||
if (mOptions[RSK_GBK_TRIFORCE_COUNT].GetOptionCount() != triforceTotal) {
|
||||
mOptions[RSK_GBK_TRIFORCE_COUNT].ChangeOptions(NumOpts(0, triforceTotal));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT].GetOptionCount() != triforceTotal) {
|
||||
mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT].ChangeOptions(NumOpts(0, triforceTotal));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_TRIFORCE_COUNT].GetOptionCount() != triforceTotal) {
|
||||
mOptions[RSK_WINCON_TRIFORCE_COUNT].ChangeOptions(NumOpts(0, triforceTotal));
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_REQUIRED, "Triforce Hunt Required Pieces", {NumOpts(1, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], WIDGET_CVAR_SLIDER_INT, 19);
|
||||
OPT_U8(RSK_MQ_DUNGEON_RANDOM, "MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WIDGET_CVAR_COMBOBOX, RO_MQ_DUNGEONS_NONE, false, nullptr, IMFLAG_NONE);
|
||||
OPT_CALLBACK(RSK_MQ_DUNGEON_RANDOM, {
|
||||
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE)) {
|
||||
|
|
@ -1103,77 +1105,216 @@ void Settings::CreateOptions() {
|
|||
}
|
||||
});
|
||||
OPT_U8(RSK_BOSS_KEYSANITY, "Boss Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
|
||||
OPT_U8(RSK_GANONS_BOSS_KEY, "Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WIDGET_CVAR_COMBOBOX, RO_GANON_BOSS_KEY_VANILLA);
|
||||
OPT_U8(RSK_GANONS_BOSS_KEY, "Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WIDGET_CVAR_COMBOBOX, RO_GANON_BOSS_KEY_VANILLA);
|
||||
OPT_CALLBACK(RSK_GANONS_BOSS_KEY, {
|
||||
// Shuffle 100 GS Reward - Force-Enabled if Ganon's Boss Key is on the 100 GS Reward
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) ==
|
||||
RO_GANON_BOSS_KEY_KAK_TOKENS) {
|
||||
mOptions[RSK_SHUFFLE_100_GS_REWARD].Disable(
|
||||
"This option is force-enabled because \"Ganon's Boss Key\" is set to \"100 GS Reward\".");
|
||||
} else {
|
||||
mOptions[RSK_SHUFFLE_100_GS_REWARD].Enable();
|
||||
}
|
||||
mOptions[RSK_LACS_OPTIONS].Hide();
|
||||
mOptions[RSK_LACS_STONE_COUNT].Hide();
|
||||
mOptions[RSK_LACS_MEDALLION_COUNT].Hide();
|
||||
mOptions[RSK_LACS_REWARD_COUNT].Hide();
|
||||
mOptions[RSK_LACS_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_LACS_TOKEN_COUNT].Hide();
|
||||
mOptions[RSK_GBK_OPTIONS].Hide();
|
||||
mOptions[RSK_GBK_STONE_COUNT].Hide();
|
||||
mOptions[RSK_GBK_MEDALLION_COUNT].Hide();
|
||||
mOptions[RSK_GBK_REWARD_COUNT].Hide();
|
||||
mOptions[RSK_GBK_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_GBK_TOKEN_COUNT].Hide();
|
||||
mOptions[RSK_GBK_TRIFORCE_COUNT].Hide();
|
||||
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA)) {
|
||||
case RO_GANON_BOSS_KEY_LACS_STONES:
|
||||
mOptions[RSK_LACS_OPTIONS].Unhide();
|
||||
mOptions[RSK_LACS_STONE_COUNT].Unhide();
|
||||
case RO_GANON_BOSS_KEY_STONES:
|
||||
mOptions[RSK_GBK_OPTIONS].Unhide();
|
||||
mOptions[RSK_GBK_STONE_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_MEDALLIONS:
|
||||
mOptions[RSK_LACS_OPTIONS].Unhide();
|
||||
mOptions[RSK_LACS_MEDALLION_COUNT].Unhide();
|
||||
case RO_GANON_BOSS_KEY_MEDALLIONS:
|
||||
mOptions[RSK_GBK_OPTIONS].Unhide();
|
||||
mOptions[RSK_GBK_MEDALLION_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_REWARDS:
|
||||
mOptions[RSK_LACS_OPTIONS].Unhide();
|
||||
mOptions[RSK_LACS_REWARD_COUNT].Unhide();
|
||||
case RO_GANON_BOSS_KEY_REWARDS:
|
||||
mOptions[RSK_GBK_OPTIONS].Unhide();
|
||||
mOptions[RSK_GBK_REWARD_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_DUNGEONS:
|
||||
mOptions[RSK_LACS_OPTIONS].Unhide();
|
||||
mOptions[RSK_LACS_DUNGEON_COUNT].Unhide();
|
||||
case RO_GANON_BOSS_KEY_DUNGEONS:
|
||||
mOptions[RSK_GBK_OPTIONS].Unhide();
|
||||
mOptions[RSK_GBK_DUNGEON_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_TOKENS:
|
||||
mOptions[RSK_LACS_TOKEN_COUNT].Unhide();
|
||||
case RO_GANON_BOSS_KEY_TOKENS:
|
||||
mOptions[RSK_GBK_TOKEN_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_TRIFORCE_PIECES:
|
||||
mOptions[RSK_GBK_TRIFORCE_COUNT].Unhide();
|
||||
break;
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_LACS_STONE_COUNT, "GCBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
|
||||
OPT_U8(RSK_LACS_MEDALLION_COUNT, "GCBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
|
||||
OPT_U8(RSK_LACS_REWARD_COUNT, "GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
|
||||
OPT_U8(RSK_LACS_DUNGEON_COUNT, "GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
|
||||
OPT_U8(RSK_LACS_TOKEN_COUNT, "GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), mOptionDescriptions[RSK_LACS_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_LACS_STANDARD_REWARD);
|
||||
OPT_CALLBACK(RSK_LACS_OPTIONS, {
|
||||
const uint8_t lacsOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), RO_LACS_STANDARD_REWARD);
|
||||
if (lacsOpts == RO_LACS_GREG_REWARD) {
|
||||
if (mOptions[RSK_LACS_STONE_COUNT].GetOptionCount() == 4) {
|
||||
mOptions[RSK_LACS_STONE_COUNT].ChangeOptions(NumOpts(0, 4));
|
||||
OPT_U8(RSK_GBK_STONE_COUNT, "GBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
|
||||
OPT_U8(RSK_GBK_MEDALLION_COUNT, "GBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
|
||||
OPT_U8(RSK_GBK_REWARD_COUNT, "GBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
|
||||
OPT_U8(RSK_GBK_DUNGEON_COUNT, "GBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
|
||||
OPT_U8(RSK_GBK_TOKEN_COUNT, "GBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_GBK_TRIFORCE_COUNT, "GBK Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_GBK_OPTIONS, "GBK Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardOptions"), mOptionDescriptions[RSK_GBK_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
OPT_CALLBACK(RSK_GBK_OPTIONS, {
|
||||
const uint8_t gbkOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("GbkRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
if (gbkOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
|
||||
if (mOptions[RSK_GBK_STONE_COUNT].GetOptionCount() == 4) {
|
||||
mOptions[RSK_GBK_STONE_COUNT].ChangeOptions(NumOpts(0, 4));
|
||||
}
|
||||
if (mOptions[RSK_LACS_MEDALLION_COUNT].GetOptionCount() == 7) {
|
||||
mOptions[RSK_LACS_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7));
|
||||
if (mOptions[RSK_GBK_MEDALLION_COUNT].GetOptionCount() == 7) {
|
||||
mOptions[RSK_GBK_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7));
|
||||
}
|
||||
if (mOptions[RSK_LACS_REWARD_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_LACS_REWARD_COUNT].ChangeOptions(NumOpts(0, 10));
|
||||
if (mOptions[RSK_GBK_REWARD_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_GBK_REWARD_COUNT].ChangeOptions(NumOpts(0, 10));
|
||||
}
|
||||
if (mOptions[RSK_LACS_DUNGEON_COUNT].GetOptionCount() == 9) {
|
||||
mOptions[RSK_LACS_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
if (mOptions[RSK_GBK_DUNGEON_COUNT].GetOptionCount() == 9) {
|
||||
mOptions[RSK_GBK_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
} else {
|
||||
if (mOptions[RSK_LACS_STONE_COUNT].GetOptionCount() == 5) {
|
||||
mOptions[RSK_LACS_STONE_COUNT].ChangeOptions(NumOpts(0, 3));
|
||||
if (mOptions[RSK_GBK_STONE_COUNT].GetOptionCount() == 5) {
|
||||
mOptions[RSK_GBK_STONE_COUNT].ChangeOptions(NumOpts(0, 3));
|
||||
}
|
||||
if (mOptions[RSK_LACS_MEDALLION_COUNT].GetOptionCount() == 8) {
|
||||
mOptions[RSK_LACS_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6));
|
||||
if (mOptions[RSK_GBK_MEDALLION_COUNT].GetOptionCount() == 8) {
|
||||
mOptions[RSK_GBK_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6));
|
||||
}
|
||||
if (mOptions[RSK_LACS_REWARD_COUNT].GetOptionCount() == 11) {
|
||||
mOptions[RSK_LACS_REWARD_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
if (mOptions[RSK_GBK_REWARD_COUNT].GetOptionCount() == 11) {
|
||||
mOptions[RSK_GBK_REWARD_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
if (mOptions[RSK_LACS_DUNGEON_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_LACS_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
|
||||
if (mOptions[RSK_GBK_DUNGEON_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_GBK_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
|
||||
}
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_GANONS_SOUL, "Ganon's Soul", {"Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), mOptionDescriptions[RSK_GANONS_SOUL], WIDGET_CVAR_COMBOBOX, RO_GANONS_SOUL_STARTWITH);
|
||||
OPT_CALLBACK(RSK_GANONS_SOUL, {
|
||||
mOptions[RSK_GANONS_SOUL_OPTIONS].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_STONE_COUNT].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_REWARD_COUNT].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_TOKEN_COUNT].Hide();
|
||||
mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT].Hide();
|
||||
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), RO_GANONS_SOUL_STARTWITH)) {
|
||||
case RO_GANONS_SOUL_STONES:
|
||||
mOptions[RSK_GANONS_SOUL_OPTIONS].Unhide();
|
||||
mOptions[RSK_GANONS_SOUL_STONE_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANONS_SOUL_MEDALLIONS:
|
||||
mOptions[RSK_GANONS_SOUL_OPTIONS].Unhide();
|
||||
mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANONS_SOUL_REWARDS:
|
||||
mOptions[RSK_GANONS_SOUL_OPTIONS].Unhide();
|
||||
mOptions[RSK_GANONS_SOUL_REWARD_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANONS_SOUL_DUNGEONS:
|
||||
mOptions[RSK_GANONS_SOUL_OPTIONS].Unhide();
|
||||
mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANONS_SOUL_TOKENS:
|
||||
mOptions[RSK_GANONS_SOUL_TOKEN_COUNT].Unhide();
|
||||
break;
|
||||
case RO_GANONS_SOUL_TRIFORCE_PIECES:
|
||||
mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT].Unhide();
|
||||
break;
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_GANONS_SOUL_STONE_COUNT, "Ganon's Soul Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_MEDALLION_COUNT, "Ganon's Soul Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_REWARD_COUNT, "Ganon's Soul Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_DUNGEON_COUNT, "Ganon's Soul Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_TOKEN_COUNT, "Ganon's Soul Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_TRIFORCE_COUNT, "Ganon's Soul Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_GANONS_SOUL_OPTIONS, "Ganon's Soul Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardOptions"), mOptionDescriptions[RSK_GANONS_SOUL_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
OPT_CALLBACK(RSK_GANONS_SOUL_OPTIONS, {
|
||||
const uint8_t soulOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonsSoulRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
if (soulOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
|
||||
if (mOptions[RSK_GANONS_SOUL_STONE_COUNT].GetOptionCount() == 4) {
|
||||
mOptions[RSK_GANONS_SOUL_STONE_COUNT].ChangeOptions(NumOpts(0, 4));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].GetOptionCount() == 7) {
|
||||
mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_REWARD_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_GANONS_SOUL_REWARD_COUNT].ChangeOptions(NumOpts(0, 10));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].GetOptionCount() == 9) {
|
||||
mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
} else {
|
||||
if (mOptions[RSK_GANONS_SOUL_STONE_COUNT].GetOptionCount() == 5) {
|
||||
mOptions[RSK_GANONS_SOUL_STONE_COUNT].ChangeOptions(NumOpts(0, 3));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].GetOptionCount() == 8) {
|
||||
mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_REWARD_COUNT].GetOptionCount() == 11) {
|
||||
mOptions[RSK_GANONS_SOUL_REWARD_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
if (mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
|
||||
}
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_WINCON, "Win Condition", {"Defeat Ganon", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWincon"), mOptionDescriptions[RSK_WINCON], WIDGET_CVAR_COMBOBOX, RO_WINCON_DEFEAT_GANON);
|
||||
OPT_CALLBACK(RSK_WINCON, {
|
||||
mOptions[RSK_WINCON_OPTIONS].Hide();
|
||||
mOptions[RSK_WINCON_STONE_COUNT].Hide();
|
||||
mOptions[RSK_WINCON_MEDALLION_COUNT].Hide();
|
||||
mOptions[RSK_WINCON_REWARD_COUNT].Hide();
|
||||
mOptions[RSK_WINCON_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_WINCON_TOKEN_COUNT].Hide();
|
||||
mOptions[RSK_WINCON_TRIFORCE_COUNT].Hide();
|
||||
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWincon"), RO_WINCON_DEFEAT_GANON)) {
|
||||
case RO_WINCON_STONES:
|
||||
mOptions[RSK_WINCON_OPTIONS].Unhide();
|
||||
mOptions[RSK_WINCON_STONE_COUNT].Unhide();
|
||||
break;
|
||||
case RO_WINCON_MEDALLIONS:
|
||||
mOptions[RSK_WINCON_OPTIONS].Unhide();
|
||||
mOptions[RSK_WINCON_MEDALLION_COUNT].Unhide();
|
||||
break;
|
||||
case RO_WINCON_REWARDS:
|
||||
mOptions[RSK_WINCON_OPTIONS].Unhide();
|
||||
mOptions[RSK_WINCON_REWARD_COUNT].Unhide();
|
||||
break;
|
||||
case RO_WINCON_DUNGEONS:
|
||||
mOptions[RSK_WINCON_OPTIONS].Unhide();
|
||||
mOptions[RSK_WINCON_DUNGEON_COUNT].Unhide();
|
||||
break;
|
||||
case RO_WINCON_TOKENS:
|
||||
mOptions[RSK_WINCON_TOKEN_COUNT].Unhide();
|
||||
break;
|
||||
case RO_WINCON_TRIFORCE_PIECES:
|
||||
mOptions[RSK_WINCON_TRIFORCE_COUNT].Unhide();
|
||||
break;
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_WINCON_STONE_COUNT, "Win Condition Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
|
||||
OPT_U8(RSK_WINCON_MEDALLION_COUNT, "Win Condition Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
|
||||
OPT_U8(RSK_WINCON_REWARD_COUNT, "Win Condition Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
|
||||
OPT_U8(RSK_WINCON_DUNGEON_COUNT, "Win Condition Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
|
||||
OPT_U8(RSK_WINCON_TOKEN_COUNT, "Win Condition Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_WINCON_TRIFORCE_COUNT, "Win Condition Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
|
||||
OPT_U8(RSK_WINCON_OPTIONS, "Win Condition Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardOptions"), mOptionDescriptions[RSK_WINCON_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
OPT_CALLBACK(RSK_WINCON_OPTIONS, {
|
||||
const uint8_t winconOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("WinconRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
|
||||
if (winconOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
|
||||
if (mOptions[RSK_WINCON_STONE_COUNT].GetOptionCount() == 4) {
|
||||
mOptions[RSK_WINCON_STONE_COUNT].ChangeOptions(NumOpts(0, 4));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_MEDALLION_COUNT].GetOptionCount() == 7) {
|
||||
mOptions[RSK_WINCON_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_REWARD_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_WINCON_REWARD_COUNT].ChangeOptions(NumOpts(0, 10));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_DUNGEON_COUNT].GetOptionCount() == 9) {
|
||||
mOptions[RSK_WINCON_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
} else {
|
||||
if (mOptions[RSK_WINCON_STONE_COUNT].GetOptionCount() == 5) {
|
||||
mOptions[RSK_WINCON_STONE_COUNT].ChangeOptions(NumOpts(0, 3));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_MEDALLION_COUNT].GetOptionCount() == 8) {
|
||||
mOptions[RSK_WINCON_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_REWARD_COUNT].GetOptionCount() == 11) {
|
||||
mOptions[RSK_WINCON_REWARD_COUNT].ChangeOptions(NumOpts(0, 9));
|
||||
}
|
||||
if (mOptions[RSK_WINCON_DUNGEON_COUNT].GetOptionCount() == 10) {
|
||||
mOptions[RSK_WINCON_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1744,9 +1885,17 @@ void Settings::CreateOptions() {
|
|||
mOptionGroups[RSG_MENU_SECTION_WINCON] = OptionGroup::SubGroup(
|
||||
"Win Condition",
|
||||
{ &mOptions[RSK_TRIFORCE_HUNT], &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL],
|
||||
&mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], &mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_LACS_OPTIONS],
|
||||
&mOptions[RSK_LACS_MEDALLION_COUNT], &mOptions[RSK_LACS_STONE_COUNT], &mOptions[RSK_LACS_DUNGEON_COUNT],
|
||||
&mOptions[RSK_LACS_REWARD_COUNT], &mOptions[RSK_LACS_TOKEN_COUNT] },
|
||||
&mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_GBK_OPTIONS],
|
||||
&mOptions[RSK_GBK_MEDALLION_COUNT], &mOptions[RSK_GBK_STONE_COUNT], &mOptions[RSK_GBK_DUNGEON_COUNT],
|
||||
&mOptions[RSK_GBK_REWARD_COUNT], &mOptions[RSK_GBK_TOKEN_COUNT], &mOptions[RSK_GBK_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL], &mOptions[RSK_GANONS_SOUL_OPTIONS],
|
||||
&mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT], &mOptions[RSK_GANONS_SOUL_STONE_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT], &mOptions[RSK_GANONS_SOUL_REWARD_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_TOKEN_COUNT], &mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_WINCON], &mOptions[RSK_WINCON_OPTIONS],
|
||||
&mOptions[RSK_WINCON_MEDALLION_COUNT], &mOptions[RSK_WINCON_STONE_COUNT],
|
||||
&mOptions[RSK_WINCON_DUNGEON_COUNT], &mOptions[RSK_WINCON_REWARD_COUNT],
|
||||
&mOptions[RSK_WINCON_TOKEN_COUNT], &mOptions[RSK_WINCON_TRIFORCE_COUNT] },
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_COLUMN_LOGIC_WINCON] = OptionGroup::SubGroup("",
|
||||
std::initializer_list<OptionGroup*>{
|
||||
|
|
@ -1773,6 +1922,7 @@ void Settings::CreateOptions() {
|
|||
&mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_GANONS_TRIALS],
|
||||
&mOptions[RSK_TRIAL_COUNT],
|
||||
&mOptions[RSK_MEDALLION_LOCKED_TRIALS],
|
||||
|
|
@ -2075,6 +2225,7 @@ void Settings::CreateOptions() {
|
|||
&mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_BRIDGE_OPTIONS],
|
||||
&mOptions[RSK_GANONS_TRIALS],
|
||||
&mOptions[RSK_TRIAL_COUNT],
|
||||
|
|
@ -2105,7 +2256,6 @@ void Settings::CreateOptions() {
|
|||
&mOptions[RSK_ENABLE_BOMBCHU_DROPS],
|
||||
&mOptions[RSK_TRIFORCE_HUNT],
|
||||
&mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL],
|
||||
&mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED],
|
||||
&mOptions[RSK_MQ_DUNGEON_RANDOM],
|
||||
&mOptions[RSK_MQ_DUNGEON_COUNT],
|
||||
&mOptions[RSK_MQ_DUNGEON_SET],
|
||||
|
|
@ -2206,12 +2356,29 @@ void Settings::CreateOptions() {
|
|||
&mOptions[RSK_GERUDO_KEYS],
|
||||
&mOptions[RSK_BOSS_KEYSANITY],
|
||||
&mOptions[RSK_GANONS_BOSS_KEY],
|
||||
&mOptions[RSK_LACS_STONE_COUNT],
|
||||
&mOptions[RSK_LACS_MEDALLION_COUNT],
|
||||
&mOptions[RSK_LACS_DUNGEON_COUNT],
|
||||
&mOptions[RSK_LACS_REWARD_COUNT],
|
||||
&mOptions[RSK_LACS_TOKEN_COUNT],
|
||||
&mOptions[RSK_LACS_OPTIONS],
|
||||
&mOptions[RSK_GBK_STONE_COUNT],
|
||||
&mOptions[RSK_GBK_MEDALLION_COUNT],
|
||||
&mOptions[RSK_GBK_DUNGEON_COUNT],
|
||||
&mOptions[RSK_GBK_REWARD_COUNT],
|
||||
&mOptions[RSK_GBK_TOKEN_COUNT],
|
||||
&mOptions[RSK_GBK_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_GBK_OPTIONS],
|
||||
&mOptions[RSK_GANONS_SOUL],
|
||||
&mOptions[RSK_GANONS_SOUL_STONE_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_MEDALLION_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_REWARD_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_TOKEN_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_GANONS_SOUL_OPTIONS],
|
||||
&mOptions[RSK_WINCON],
|
||||
&mOptions[RSK_WINCON_STONE_COUNT],
|
||||
&mOptions[RSK_WINCON_MEDALLION_COUNT],
|
||||
&mOptions[RSK_WINCON_DUNGEON_COUNT],
|
||||
&mOptions[RSK_WINCON_REWARD_COUNT],
|
||||
&mOptions[RSK_WINCON_TOKEN_COUNT],
|
||||
&mOptions[RSK_WINCON_TRIFORCE_COUNT],
|
||||
&mOptions[RSK_WINCON_OPTIONS],
|
||||
&mOptions[RSK_KEYRINGS],
|
||||
&mOptions[RSK_KEYRINGS_RANDOM_COUNT],
|
||||
&mOptions[RSK_KEYRINGS_GERUDO_FORTRESS],
|
||||
|
|
@ -2486,11 +2653,6 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
|
|||
mOptions[RSK_STARTING_AGE].Set(RO_AGE_CHILD);
|
||||
}
|
||||
|
||||
// Force 100 GS Shuffle if that's where Ganon's Boss Key is
|
||||
if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
|
||||
mOptions[RSK_SHUFFLE_100_GS_REWARD].Set(1);
|
||||
}
|
||||
|
||||
// If we only have MQ, set all dungeons to MQ
|
||||
if (OTRGlobals::Instance->HasMasterQuest() && !OTRGlobals::Instance->HasOriginal()) {
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].Set(RO_MQ_DUNGEONS_SET_NUMBER);
|
||||
|
|
@ -2828,18 +2990,36 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
|
|||
|
||||
// TODO: Random Starting Time
|
||||
|
||||
if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
|
||||
mLACSCondition = RO_LACS_STONES;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) {
|
||||
mLACSCondition = RO_LACS_MEDALLIONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
|
||||
mLACSCondition = RO_LACS_REWARDS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) {
|
||||
mLACSCondition = RO_LACS_DUNGEONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
|
||||
mLACSCondition = RO_LACS_TOKENS;
|
||||
if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_STONES)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_STONES;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_MEDALLIONS)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_MEDALLIONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_REWARDS)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_REWARDS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_DUNGEONS)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_DUNGEONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_TOKENS)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_TOKENS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_TRIFORCE_PIECES)) {
|
||||
mGBKCondition = RO_CHECK_TRIGGER_TRIFORCE_PIECES;
|
||||
} else {
|
||||
mLACSCondition = RO_LACS_VANILLA;
|
||||
mGBKCondition = RO_CHECK_TRIGGER_NONE;
|
||||
}
|
||||
|
||||
if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_STONES)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_STONES;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_MEDALLIONS)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_MEDALLIONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_REWARDS)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_REWARDS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_DUNGEONS)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_DUNGEONS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_TOKENS)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_TOKENS;
|
||||
} else if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_TRIFORCE_PIECES)) {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_TRIFORCE_PIECES;
|
||||
} else {
|
||||
mGanonsSoulCondition = RO_CHECK_TRIGGER_NONE;
|
||||
}
|
||||
|
||||
if (!mOptions[RSK_SHUFFLE_WARP_SONGS]) {
|
||||
|
|
|
|||
|
|
@ -175,12 +175,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
|||
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
// LACS
|
||||
u8 meetsLACSRequirements =
|
||||
LINK_IS_ADULT &&
|
||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
if (LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
|
||||
if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, meetsLACSRequirements)) {
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
|
||||
if (GameInteractor_Should(VB_GIVE_ITEM_LIGHT_ARROW, true)) {
|
||||
Item_Give(gPlayState, ITEM_ARROW_LIGHT);
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ void SaveManager::InitMeta(int fileNum) {
|
|||
auto randoContext = Rando::Context::GetInstance();
|
||||
|
||||
fileMetaInfo[fileNum].maxTriforcePieces = IS_RANDO && (bool)randoContext->GetOption(RSK_TRIFORCE_HUNT)
|
||||
? randoContext->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1
|
||||
? randoContext->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1
|
||||
: 0;
|
||||
fileMetaInfo[fileNum].fishingPoleShuffled =
|
||||
IS_RANDO ? (bool)randoContext->GetOption(RSK_SHUFFLE_FISHING_POLE) : false;
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ bool Scene_CommandSpawnList(PlayState* play, SOH::ISceneCommand* cmd) {
|
|||
ActorEntry* entries = (ActorEntry*)cmdStartPos->GetRawPointer();
|
||||
|
||||
play->linkActorEntry = &entries[play->setupEntranceList[play->curSpawn].spawn];
|
||||
play->linkAgeOnLoad = ((void)0, gSaveContext.linkAge);
|
||||
s16 linkObjectId = gLinkObjectIds[((void)0, gSaveContext.linkAge)];
|
||||
play->linkAgeOnLoad = gSaveContext.linkAge;
|
||||
s16 linkObjectId = gLinkObjectIds[gSaveContext.linkAge];
|
||||
|
||||
Object_Spawn(&play->objectCtx, linkObjectId);
|
||||
|
||||
|
|
@ -262,13 +262,13 @@ bool Scene_CommandTimeSettings(PlayState* play, SOH::ISceneCommand* cmd) {
|
|||
gTimeIncrement = play->envCtx.timeIncrement;
|
||||
}
|
||||
|
||||
play->envCtx.sunPos.x = -(Math_SinS(((void)0, gSaveContext.dayTime) - 0x8000) * 120.0f) * 25.0f;
|
||||
play->envCtx.sunPos.y = (Math_CosS(((void)0, gSaveContext.dayTime) - 0x8000) * 120.0f) * 25.0f;
|
||||
play->envCtx.sunPos.z = (Math_CosS(((void)0, gSaveContext.dayTime) - 0x8000) * 20.0f) * 25.0f;
|
||||
play->envCtx.sunPos.x = -(Math_SinS(gSaveContext.dayTime - 0x8000) * 120.0f) * 25.0f;
|
||||
play->envCtx.sunPos.y = (Math_CosS(gSaveContext.dayTime - 0x8000) * 120.0f) * 25.0f;
|
||||
play->envCtx.sunPos.z = (Math_CosS(gSaveContext.dayTime - 0x8000) * 20.0f) * 25.0f;
|
||||
|
||||
if (((play->envCtx.timeIncrement == 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) ||
|
||||
(gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD)) {
|
||||
gSaveContext.skyboxTime = ((void)0, gSaveContext.dayTime);
|
||||
gSaveContext.skyboxTime = gSaveContext.dayTime;
|
||||
if ((gSaveContext.skyboxTime >= 0x2AAC) && (gSaveContext.skyboxTime < 0x4555)) {
|
||||
gSaveContext.skyboxTime = 0x3556;
|
||||
} else if ((gSaveContext.skyboxTime >= 0x4555) && (gSaveContext.skyboxTime < 0x5556)) {
|
||||
|
|
@ -336,9 +336,9 @@ bool Scene_CommandAlternateHeaderList(PlayState* play, SOH::ISceneCommand* cmd)
|
|||
// s32 pad;
|
||||
// SceneCmd* altHeader;
|
||||
|
||||
// osSyncPrintf("\n[ZU]sceneset age =[%X]", ((void)0, gSaveContext.linkAge));
|
||||
// osSyncPrintf("\n[ZU]sceneset time =[%X]", ((void)0, gSaveContext.cutsceneIndex));
|
||||
// osSyncPrintf("\n[ZU]sceneset counter=[%X]", ((void)0, gSaveContext.sceneSetupIndex));
|
||||
// osSyncPrintf("\n[ZU]sceneset age =[%X]", gSaveContext.linkAge);
|
||||
// osSyncPrintf("\n[ZU]sceneset time =[%X]", gSaveContext.cutsceneIndex);
|
||||
// osSyncPrintf("\n[ZU]sceneset counter=[%X]", gSaveContext.sceneSetupIndex);
|
||||
|
||||
if (gSaveContext.sceneSetupIndex != 0) {
|
||||
SOH::Scene* desiredHeader =
|
||||
|
|
|
|||
|
|
@ -330,6 +330,10 @@ u8 CheckDungeonCount() {
|
|||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_GANONS_TOWER)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
return dungeonCount;
|
||||
}
|
||||
|
||||
|
|
@ -351,24 +355,6 @@ u8 CheckBridgeRewardCount() {
|
|||
return bridgeRewardCount;
|
||||
}
|
||||
|
||||
u8 CheckLACSRewardCount() {
|
||||
u8 lacsRewardCount = 0;
|
||||
|
||||
switch (Randomizer_GetSettingValue(RSK_LACS_OPTIONS)) {
|
||||
case RO_LACS_WILDCARD_REWARD:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
lacsRewardCount += 1;
|
||||
}
|
||||
break;
|
||||
case RO_LACS_GREG_REWARD:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
lacsRewardCount += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return lacsRewardCount;
|
||||
}
|
||||
|
||||
void Play_Init(GameState* thisx) {
|
||||
PlayState* play = (PlayState*)thisx;
|
||||
GraphicsContext* gfxCtx = play->state.gfxCtx;
|
||||
|
|
|
|||
|
|
@ -1638,7 +1638,8 @@ void Player_DrawGetItemImpl(PlayState* play, Player* this, Vec3f* refPos, s32 dr
|
|||
|
||||
if (this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId == RG_ICE_TRAP) {
|
||||
Player_DrawGetItemIceTrap(play, this, refPos, drawIdPlusOne, height);
|
||||
} else if (this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId == RG_TRIFORCE_PIECE) {
|
||||
} else if (this->getItemEntry.modIndex == MOD_RANDOMIZER &&
|
||||
(this->getItemEntry.getItemId == RG_TRIFORCE_PIECE || this->getItemEntry.getItemId == RG_TRIFORCE)) {
|
||||
Randomizer_DrawTriforcePieceGI(play, this->getItemEntry);
|
||||
} else if (this->getItemEntry.drawFunc != NULL) {
|
||||
this->getItemEntry.drawFunc(play, &this->getItemEntry);
|
||||
|
|
|
|||
|
|
@ -1692,14 +1692,16 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
|
|||
(player->meleeWeaponState != 0) && (player->heldItemAction == PLAYER_IA_SWORD_MASTER)) {
|
||||
func_80064520(play, &play->csCtx);
|
||||
GameInteractor_ExecuteOnBossDefeat(&this->actor);
|
||||
this->subCamId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
|
||||
this->csState = 7;
|
||||
this->csTimer = 0;
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &gGanonFinalBlowAnim, 0.0f);
|
||||
this->unk_194 = Animation_GetLastFrame(&gGanonFinalBlowAnim);
|
||||
play->startPlayerCutscene(play, &this->actor, 0x61);
|
||||
if (GameInteractor_Should(VB_SLAY_GANON, true)) {
|
||||
this->subCamId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
|
||||
this->csState = 7;
|
||||
this->csTimer = 0;
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &gGanonFinalBlowAnim, 0.0f);
|
||||
this->unk_194 = Animation_GetLastFrame(&gGanonFinalBlowAnim);
|
||||
play->startPlayerCutscene(play, &this->actor, 0x61);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue