diff --git a/soh/include/functions.h b/soh/include/functions.h index 7854b9835..894987f8c 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -1532,6 +1532,8 @@ void Play_Main(GameState* thisx); 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); diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index bf1b621b8..1a17368a9 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -272,6 +272,7 @@ const std::vector<const char*> randomizerCvars = { "gRandomizeBlueFireArrows", "gRandomizeBombchusInLogic", "gRandomizeBossKeysanity", + "gRandomizeBridgeRewardOptions", "gRandomizeCompleteMaskQuest", "gRandomizeCuccosToReturn", "gRandomizeDampeHint", @@ -298,6 +299,7 @@ const std::vector<const char*> randomizerCvars = { "gRandomizeLacsDungeonCount", "gRandomizeLacsMedallionCount", "gRandomizeLacsRewardCount", + "gRandomizeLacsRewardOptions", "gRandomizeLacsStoneCount", "gRandomizeLacsTokenCount", "gRandomizeLAHint", diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp index 29f5f32fa..38011b8b8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/keys.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/keys.hpp @@ -1783,8 +1783,8 @@ typedef enum { GANON_BK_SKULLTULA_HINT, LACS_VANILLA_HINT, - LACS_MEDALLIONS_HINT, LACS_STONES_HINT, + LACS_MEDALLIONS_HINT, LACS_REWARDS_HINT, LACS_DUNGEONS_HINT, LACS_TOKENS_HINT, diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.cpp b/soh/soh/Enhancements/randomizer/3drando/logic.cpp index 9eb219cf1..533060eb7 100644 --- a/soh/soh/Enhancements/randomizer/3drando/logic.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/logic.cpp @@ -122,6 +122,7 @@ namespace Logic { //Greg bool Greg = false; + bool GregInLogic = false; //Progressive Items uint8_t ProgressiveBulletBag = 0; @@ -292,8 +293,8 @@ namespace Logic { bool CanUseMagicArrow = false; //Bridge and LACS Requirements - uint8_t MedallionCount = 0; uint8_t StoneCount = 0; + uint8_t MedallionCount = 0; uint8_t DungeonCount = 0; bool HasAllStones = false; bool HasAllMedallions = false; @@ -778,21 +779,22 @@ namespace Logic { DungeonCount = (DekuTreeClear ? 1:0) + (DodongosCavernClear ? 1:0) + (JabuJabusBellyClear ? 1:0) + (ForestTempleClear ? 1:0) + (FireTempleClear ? 1:0) + (WaterTempleClear ? 1:0) + (SpiritTempleClear ? 1:0) + (ShadowTempleClear ? 1:0); HasAllStones = StoneCount == 3; HasAllMedallions = MedallionCount == 6; + GregInLogic = BridgeRewardOptions.Is(BRIDGE_OPTION_GREG) || LACSRewardOptions.Is(LACS_OPTION_GREG); CanBuildRainbowBridge = Bridge.Is(RAINBOWBRIDGE_OPEN) || (Bridge.Is(RAINBOWBRIDGE_VANILLA) && ShadowMedallion && SpiritMedallion && LightArrows) || - (Bridge.Is(RAINBOWBRIDGE_STONES) && StoneCount >= BridgeStoneCount.Value<uint8_t>()) || - (Bridge.Is(RAINBOWBRIDGE_MEDALLIONS) && MedallionCount >= BridgeMedallionCount.Value<uint8_t>()) || - (Bridge.Is(RAINBOWBRIDGE_REWARDS) && StoneCount + MedallionCount >= BridgeRewardCount.Value<uint8_t>()) || - (Bridge.Is(RAINBOWBRIDGE_DUNGEONS) && DungeonCount >= BridgeDungeonCount.Value<uint8_t>()) || + (Bridge.Is(RAINBOWBRIDGE_STONES) && StoneCount + (Greg && GregInLogic ? 1 : 0) >= BridgeStoneCount.Value<uint8_t>()) || + (Bridge.Is(RAINBOWBRIDGE_MEDALLIONS) && MedallionCount + (Greg && GregInLogic ? 1 : 0) >= BridgeMedallionCount.Value<uint8_t>()) || + (Bridge.Is(RAINBOWBRIDGE_REWARDS) && StoneCount + MedallionCount + (Greg && GregInLogic ? 1 : 0) >= BridgeRewardCount.Value<uint8_t>()) || + (Bridge.Is(RAINBOWBRIDGE_DUNGEONS) && DungeonCount + (Greg && GregInLogic ? 1 : 0) >= BridgeDungeonCount.Value<uint8_t>()) || (Bridge.Is(RAINBOWBRIDGE_TOKENS) && GoldSkulltulaTokens >= BridgeTokenCount.Value<uint8_t>()) || (Bridge.Is(RAINBOWBRIDGE_GREG) && Greg); CanTriggerLACS = (LACSCondition == LACSCONDITION_VANILLA && ShadowMedallion && SpiritMedallion) || - (LACSCondition == LACSCONDITION_STONES && StoneCount >= LACSStoneCount.Value<uint8_t>()) || - (LACSCondition == LACSCONDITION_MEDALLIONS && MedallionCount >= LACSMedallionCount.Value<uint8_t>()) || - (LACSCondition == LACSCONDITION_REWARDS && StoneCount + MedallionCount >= LACSRewardCount.Value<uint8_t>()) || - (LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount >= LACSDungeonCount.Value<uint8_t>()) || + (LACSCondition == LACSCONDITION_STONES && StoneCount + (Greg && GregInLogic ? 1 : 0) >= LACSStoneCount.Value<uint8_t>()) || + (LACSCondition == LACSCONDITION_MEDALLIONS && MedallionCount + (Greg && GregInLogic ? 1 : 0) >= LACSMedallionCount.Value<uint8_t>()) || + (LACSCondition == LACSCONDITION_REWARDS && StoneCount + MedallionCount + (Greg && GregInLogic ? 1 : 0) >= LACSRewardCount.Value<uint8_t>()) || + (LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount + (Greg && GregInLogic ? 1 : 0) >= LACSDungeonCount.Value<uint8_t>()) || (LACSCondition == LACSCONDITION_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value<uint8_t>()); } diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp index 0a9a3b411..f1fc714d2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp @@ -125,6 +125,10 @@ string_view bridgeDungeonCountDesc = "Set the number of completed dungeons re "spawn the Rainbow Bridge."; // string_view bridgeTokenCountDesc = "Set the number of Gold Skulltula Tokens required\n" "to spawn the Rainbow Bridge."; // +string_view bridgeRewardOptionsDesc = "Set whether the rewards are standard, if Greg\n" + "counts as a reward and considered for logic\n" + "or if Greg becomes a wildcard, counting as a reward but\n" + "not considered in logic."; // /*------------------------------ // | RANDOM GANONS TRIALS | // ------------------------------*/ // @@ -601,10 +605,10 @@ string_view ganonKey100GS = "Ganon's Castle Boss Key is given to you /*------------------------------ // | LACS CONDITIONS | // ------------------------------*/ // -string_view lacsMedallionCountDesc = "Set the number of Medallions required to trigger\n" - "the Light Arrow Cutscene."; // string_view lacsStoneCountDesc = "Set the number of Spiritual Stones required to\n" // "trigger the Light Arrow Cutscene."; // +string_view lacsMedallionCountDesc = "Set the number of Medallions required to trigger\n" + "the Light Arrow Cutscene."; // string_view lacsRewardCountDesc = "Set the number of Dungeon Rewards (Spiritual\n" // "Stones and Medallions) required to trigger the\n" // "Light Arrow Cutscene."; // @@ -615,6 +619,10 @@ string_view lacsDungeonCountDesc = "Set the number of completed dungeons re "into the blue warp at the end of them."; // string_view lacsTokenCountDesc = "Set the number of Gold Skulltula Tokens required\n" "to trigger the Light Arrow Cutscene."; // +string_view lacsRewardOptionsDesc = "Set whether the rewards are standard, if Greg\n" + "counts as a reward and considered for logic\n" + "or if Greg becomes a wildcard, counting as a reward but\n" + "not considered in logic."; // /*------------------------------ // | SKIP CHILD STEALTH | // ------------------------------*/ // diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp index e50584578..c0c34c773 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp @@ -48,6 +48,8 @@ extern string_view bridgeRewardCountDesc; extern string_view bridgeDungeonCountDesc; extern string_view bridgeTokenCountDesc; +extern string_view bridgeRewardOptionsDesc; + extern string_view randomGanonsTrialsDesc; extern string_view ganonsTrialCountDesc; @@ -195,12 +197,14 @@ extern string_view ganonKeyAnywhere; extern string_view ganonKeyLACS; extern string_view ganonKey100GS; -extern string_view lacsMedallionCountDesc; extern string_view lacsStoneCountDesc; +extern string_view lacsMedallionCountDesc; extern string_view lacsRewardCountDesc; extern string_view lacsDungeonCountDesc; extern string_view lacsTokenCountDesc; +extern string_view lacsRewardOptionsDesc; + extern string_view childStealthDesc; extern string_view skipTowerEscapeDesc; diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index b2a1217b2..cbbc7ba6d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -60,11 +60,12 @@ namespace Settings { Option ZorasFountain = Option::U8 ("Zora's Fountain", {"Closed", "Closed as child", "Open"}, {fountainNormal, fountainAdult, fountainOpen}); Option GerudoFortress = Option::U8 ("Gerudo Fortress", {"Normal", "Fast", "Open"}, {gerudoNormal, gerudoFast, gerudoOpen}); Option Bridge = Option::U8 ("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, {bridgeVanilla, bridgeOpen, bridgeStones, bridgeMedallions, bridgeRewards, bridgeDungeons, bridgeTokens, bridgeGreg}, OptionCategory::Setting, RAINBOWBRIDGE_VANILLA); - Option BridgeStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 3)}, {bridgeStoneCountDesc}, OptionCategory::Setting, 1, true); - Option BridgeMedallionCount= Option::U8 ("Medallion Count", {NumOpts(0, 6)}, {bridgeMedallionCountDesc}, OptionCategory::Setting, 1, true); - Option BridgeRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 9)}, {bridgeRewardCountDesc}, OptionCategory::Setting, 1, true); - Option BridgeDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 8)}, {bridgeDungeonCountDesc}, OptionCategory::Setting, 1, true); + Option BridgeStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 4)}, {bridgeStoneCountDesc}, OptionCategory::Setting, 1, true); + Option BridgeMedallionCount= Option::U8 ("Medallion Count", {NumOpts(0, 7)}, {bridgeMedallionCountDesc}, OptionCategory::Setting, 1, true); + Option BridgeRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 10)}, {bridgeRewardCountDesc}, OptionCategory::Setting, 1, true); + Option BridgeDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 9)}, {bridgeDungeonCountDesc}, OptionCategory::Setting, 1, true); Option BridgeTokenCount = Option::U8 ("Token Count", {NumOpts(0, 100)}, {bridgeTokenCountDesc}, OptionCategory::Setting, 1, true); + Option BridgeRewardOptions = Option::U8 ("Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, {bridgeRewardOptionsDesc}); Option RandomGanonsTrials = Option::Bool("Random Ganon's Trials", {"Off", "On"}, {randomGanonsTrialsDesc}, OptionCategory::Setting, ON); Option GanonsTrialsCount = Option::U8 ("Trial Count", {NumOpts(0, 6)}, {ganonsTrialCountDesc}, OptionCategory::Setting, 1, true); std::vector<Option *> openOptions = { @@ -80,6 +81,7 @@ namespace Settings { &BridgeRewardCount, &BridgeDungeonCount, &BridgeTokenCount, + &BridgeRewardOptions, &RandomGanonsTrials, &GanonsTrialsCount, }; @@ -227,14 +229,15 @@ namespace Settings { {gerudoKeysVanilla, gerudoKeysAnyDungeon, gerudoKeysOverworld, gerudoKeysAnywhere}); Option BossKeysanity = Option::U8 ("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, {bossKeyStartWith, bossKeyVanilla, bossKeyOwnDungeon, bossKeyAnyDungeon, bossKeyOverworld, bossKeyAnywhere}, OptionCategory::Setting, BOSSKEYSANITY_OWN_DUNGEON); - Option GanonsBossKey = Option::U8 ("Ganon's Boss Key", {"Vanilla", "Own dungeon", "Start with", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Medallions", "LACS-Stones", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward"}, + Option GanonsBossKey = Option::U8 ("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"}, {ganonKeyVanilla, ganonKeyOwnDungeon, ganonKeyStartWith, ganonKeyAnyDungeon, ganonKeyOverworld, ganonKeyAnywhere, ganonKeyLACS, ganonKey100GS}, OptionCategory::Setting, GANONSBOSSKEY_VANILLA); uint8_t LACSCondition = 0; - Option LACSMedallionCount = Option::U8 ("Medallion Count", {NumOpts(0, 6)}, {lacsMedallionCountDesc}, OptionCategory::Setting, 1, true); - Option LACSStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 3)}, {lacsStoneCountDesc}, OptionCategory::Setting, 1, true); - Option LACSRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 9)}, {lacsRewardCountDesc}, OptionCategory::Setting, 1, true); - Option LACSDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 8)}, {lacsDungeonCountDesc}, OptionCategory::Setting, 1, true); + Option LACSStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 4)}, {lacsStoneCountDesc}, OptionCategory::Setting, 1, true); + Option LACSMedallionCount = Option::U8 ("Medallion Count", {NumOpts(0, 7)}, {lacsMedallionCountDesc}, OptionCategory::Setting, 1, true); + Option LACSRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 10)}, {lacsRewardCountDesc}, OptionCategory::Setting, 1, true); + Option LACSDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 9)}, {lacsDungeonCountDesc}, OptionCategory::Setting, 1, true); Option LACSTokenCount = Option::U8 ("Token Count", {NumOpts(0, 100)}, {lacsTokenCountDesc}, OptionCategory::Setting, 1, true); + Option LACSRewardOptions = Option::U8 ("LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, {lacsRewardOptionsDesc}); Option KeyRings = Option::U8 ("Key Rings", {"Off", "Random", "Count", "Selection"}, {keyRingDesc}); Option KeyRingsRandomCount = Option::U8 ("Keyring Dungeon Count", {NumOpts(0, 9)}, {keyRingDesc}, OptionCategory::Setting, 1); Option RingFortress = Option::Bool("Gerudo Fortress", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting); @@ -254,11 +257,12 @@ namespace Settings { &GerudoKeys, &BossKeysanity, &GanonsBossKey, - &LACSMedallionCount, &LACSStoneCount, + &LACSMedallionCount, &LACSRewardCount, &LACSDungeonCount, &LACSTokenCount, + &LACSRewardOptions, &KeyRings, &KeyRingsRandomCount, &RingFortress, @@ -1297,6 +1301,7 @@ namespace Settings { ctx.bridgeRewardCount = BridgeRewardCount.Value<uint8_t>(); ctx.bridgeDungeonCount = BridgeDungeonCount.Value<uint8_t>(); ctx.bridgeTokenCount = BridgeTokenCount.Value<uint8_t>(); + ctx.bridgeRewardOptions = BridgeRewardOptions.Value<uint8_t>(); ctx.randomGanonsTrials = (RandomGanonsTrials) ? 1 : 0; ctx.ganonsTrialsCount = GanonsTrialsCount.Value<uint8_t>(); @@ -1345,11 +1350,12 @@ namespace Settings { ctx.bossKeysanity = BossKeysanity.Value<uint8_t>(); ctx.ganonsBossKey = GanonsBossKey.Value<uint8_t>(); ctx.lacsCondition = LACSCondition; - ctx.lacsMedallionCount = LACSMedallionCount.Value<uint8_t>(); ctx.lacsStoneCount = LACSStoneCount.Value<uint8_t>(); + ctx.lacsMedallionCount = LACSMedallionCount.Value<uint8_t>(); ctx.lacsRewardCount = LACSRewardCount.Value<uint8_t>(); ctx.lacsDungeonCount = LACSDungeonCount.Value<uint8_t>(); ctx.lacsTokenCount = LACSTokenCount.Value<uint8_t>(); + ctx.lacsRewardOptions = LACSRewardOptions.Value<uint8_t>(); ctx.ringFortress = (RingFortress) ? 1 : 0; ctx.ringForest = (RingForest) ? 1 : 0; @@ -2114,14 +2120,6 @@ namespace Settings { } if (!RandomizeDungeon) { - //Only show Medallion Count if setting Ganons Boss Key to LACS Medallions - if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { - LACSMedallionCount.Unhide(); - } else { - LACSMedallionCount.SetSelectedIndex(6); - LACSMedallionCount.Hide(); - } - //Only show Stone Count if setting Ganons Boss Key to LACS Stones if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_STONES)) { LACSStoneCount.Unhide(); @@ -2129,6 +2127,14 @@ namespace Settings { LACSStoneCount.SetSelectedIndex(3); LACSStoneCount.Hide(); } + + //Only show Medallion Count if setting Ganons Boss Key to LACS Medallions + if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { + LACSMedallionCount.Unhide(); + } else { + LACSMedallionCount.SetSelectedIndex(6); + LACSMedallionCount.Hide(); + } //Only show Reward Count if setting Ganons Boss Key to LACS Rewards if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_REWARDS)) { @@ -2695,6 +2701,7 @@ namespace Settings { BridgeRewardCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_REWARD_COUNT]); BridgeDungeonCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT]); BridgeTokenCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_TOKEN_COUNT]); + BridgeRewardOptions.SetSelectedIndex(cvarSettings[RSK_BRIDGE_OPTIONS]); if (cvarSettings[RSK_GANONS_TRIALS] == RO_GANONS_TRIALS_RANDOM_NUMBER) { RandomGanonsTrials.SetSelectedIndex(1); } else { @@ -2826,6 +2833,7 @@ namespace Settings { LACSRewardCount.SetSelectedIndex(cvarSettings[RSK_LACS_REWARD_COUNT]); LACSDungeonCount.SetSelectedIndex(cvarSettings[RSK_LACS_DUNGEON_COUNT]); LACSTokenCount.SetSelectedIndex(cvarSettings[RSK_LACS_TOKEN_COUNT]); + LACSRewardOptions.SetSelectedIndex(cvarSettings[RSK_LACS_OPTIONS]); KeyRings.SetSelectedIndex(cvarSettings[RSK_KEYRINGS]); KeyRingsRandomCount.SetSelectedIndex(cvarSettings[RSK_KEYRINGS_RANDOM_COUNT]); @@ -3008,10 +3016,10 @@ namespace Settings { HasNightStart = StartingTime.Is(STARTINGTIME_NIGHT); - if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { - LACSCondition = LACSCONDITION_MEDALLIONS; - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_STONES)) { + if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_STONES)) { LACSCondition = LACSCONDITION_STONES; + } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { + LACSCondition = LACSCONDITION_MEDALLIONS; } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_REWARDS)) { LACSCondition = LACSCONDITION_REWARDS; } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_DUNGEONS)) { diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.hpp b/soh/soh/Enhancements/randomizer/3drando/settings.hpp index 9905ab313..60c3e5ea1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.hpp @@ -72,6 +72,12 @@ typedef enum { RAINBOWBRIDGE_GREG, } RainbowBridgeSetting; +typedef enum { + BRIDGE_OPTION_STANDARD, + BRIDGE_OPTION_GREG, + BRIDGE_OPTION_WILDCARD, +} BridgeRewardOptionsSetting; + typedef enum { LACSCONDITION_VANILLA, LACSCONDITION_STONES, @@ -81,6 +87,12 @@ typedef enum { LACSCONDITION_TOKENS, } LACSConditionSetting; +typedef enum { + LACS_OPTION_STANDARD, + LACS_OPTION_GREG, + LACS_OPTION_WILDCARD, +} LACSRewardOptionsSetting; + typedef enum { AGE_CHILD, AGE_ADULT, @@ -233,8 +245,8 @@ typedef enum { GANONSBOSSKEY_OVERWORLD, GANONSBOSSKEY_ANYWHERE, GANONSBOSSKEY_LACS_VANILLA, - GANONSBOSSKEY_LACS_MEDALLIONS, GANONSBOSSKEY_LACS_STONES, + GANONSBOSSKEY_LACS_MEDALLIONS, GANONSBOSSKEY_LACS_REWARDS, GANONSBOSSKEY_LACS_DUNGEONS, GANONSBOSSKEY_LACS_TOKENS, @@ -389,6 +401,7 @@ typedef struct { uint8_t bridgeRewardCount; uint8_t bridgeDungeonCount; uint8_t bridgeTokenCount; + uint8_t bridgeRewardOptions; uint8_t randomGanonsTrials; uint8_t ganonsTrialsCount; @@ -440,11 +453,12 @@ typedef struct { uint8_t bossKeysanity; uint8_t ganonsBossKey; uint8_t lacsCondition; - uint8_t lacsMedallionCount; uint8_t lacsStoneCount; + uint8_t lacsMedallionCount; uint8_t lacsRewardCount; uint8_t lacsDungeonCount; uint8_t lacsTokenCount; + uint8_t lacsRewardOptions; uint8_t ringFortress; uint8_t ringForest; @@ -908,6 +922,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin extern Option BridgeRewardCount; extern Option BridgeDungeonCount; extern Option BridgeTokenCount; + extern Option BridgeRewardOptions; extern Option RandomGanonsTrials; extern Option GanonsTrialsCount; @@ -960,11 +975,12 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin extern Option BossKeysanity; extern Option GanonsBossKey; extern uint8_t LACSCondition; - extern Option LACSMedallionCount; extern Option LACSStoneCount; + extern Option LACSMedallionCount; extern Option LACSRewardCount; extern Option LACSDungeonCount; extern Option LACSTokenCount; + extern Option LACSRewardOptions; extern Option KeyRings; extern Option KeyRingsRandomCount; extern Option RingFortress; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 4c5b08f73..5ceddeb4f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -225,6 +225,7 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn { "Open Settings:Reward Count", RSK_RAINBOW_BRIDGE_REWARD_COUNT }, { "Open Settings:Dungeon Count", RSK_RAINBOW_BRIDGE_DUNGEON_COUNT }, { "Open Settings:Token Count", RSK_RAINBOW_BRIDGE_TOKEN_COUNT }, + { "Open Settings:Bridge Reward Options", RSK_BRIDGE_OPTIONS }, { "Shuffle Settings:Shuffle Dungeon Rewards", RSK_SHUFFLE_DUNGEON_REWARDS }, { "Shuffle Settings:Link's Pocket", RSK_LINKS_POCKET}, { "Shuffle Settings:Shuffle Songs", RSK_SHUFFLE_SONGS }, @@ -263,11 +264,12 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn { "Shuffle Dungeon Items:Gerudo Fortress Keys", RSK_GERUDO_KEYS }, { "Shuffle Dungeon Items:Boss Keys", RSK_BOSS_KEYSANITY }, { "Shuffle Dungeon Items:Ganon's Boss Key", RSK_GANONS_BOSS_KEY }, - { "Shuffle Dungeon Items:Medallion Count", RSK_LACS_MEDALLION_COUNT }, { "Shuffle Dungeon Items:Stone Count", RSK_LACS_STONE_COUNT }, + { "Shuffle Dungeon Items:Medallion Count", RSK_LACS_MEDALLION_COUNT }, { "Shuffle Dungeon Items:Reward Count", RSK_LACS_REWARD_COUNT }, { "Shuffle Dungeon Items:Dungeon Count", RSK_LACS_DUNGEON_COUNT }, { "Shuffle Dungeon Items:Token Count", RSK_LACS_TOKEN_COUNT }, + { "Shuffle Dungeon Items:LACS Reward Options", RSK_LACS_OPTIONS }, { "Shuffle Dungeon Items:Key Rings", RSK_KEYRINGS }, { "Shuffle Dungeon Items:Keyring Dungeon Count", RSK_KEYRINGS_RANDOM_COUNT }, { "Shuffle Dungeon Items:Gerudo Fortress", RSK_KEYRINGS_GERUDO_FORTRESS }, @@ -705,6 +707,24 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { gSaveContext.randoSettings[index].value = RO_BRIDGE_GREG; } break; + case RSK_BRIDGE_OPTIONS: + if (it.value() == "Standard Rewards") { + gSaveContext.randoSettings[index].value = RO_BRIDGE_STANDARD_REWARD; + } else if (it.value() == "Greg as Reward") { + gSaveContext.randoSettings[index].value = RO_BRIDGE_GREG_REWARD; + } else if (it.value() == "Greg as Wildcard") { + gSaveContext.randoSettings[index].value = RO_BRIDGE_WILDCARD_REWARD; + } + break; + case RSK_LACS_OPTIONS: + if (it.value() == "Standard Reward") { + gSaveContext.randoSettings[index].value = RO_LACS_STANDARD_REWARD; + } else if (it.value() == "Greg as Reward") { + gSaveContext.randoSettings[index].value = RO_LACS_GREG_REWARD; + } else if (it.value() == "Greg as Wildcard") { + gSaveContext.randoSettings[index].value = RO_LACS_WILDCARD_REWARD; + } + break; case RSK_RAINBOW_BRIDGE_STONE_COUNT: case RSK_RAINBOW_BRIDGE_MEDALLION_COUNT: case RSK_RAINBOW_BRIDGE_REWARD_COUNT: @@ -966,10 +986,10 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_ANYWHERE; } else if(it.value() == "LACS-Vanilla") { gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_VANILLA; - } else if(it.value() == "LACS-Medallions") { - gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_MEDALLIONS; } else if(it.value() == "LACS-Stones") { gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_STONES; + } else if(it.value() == "LACS-Medallions") { + gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_MEDALLIONS; } else if(it.value() == "LACS-Rewards") { gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_REWARDS; } else if(it.value() == "LACS-Dungeons") { @@ -2854,11 +2874,12 @@ void GenerateRandomizerImgui(std::string seed = "") { cvarSettings[RSK_STARTING_AGE] = CVarGetInteger("gRandomizeStartingAge", RO_AGE_CHILD); cvarSettings[RSK_GERUDO_FORTRESS] = CVarGetInteger("gRandomizeGerudoFortress", RO_GF_NORMAL); cvarSettings[RSK_RAINBOW_BRIDGE] = CVarGetInteger("gRandomizeRainbowBridge", RO_BRIDGE_VANILLA); - cvarSettings[RSK_RAINBOW_BRIDGE_STONE_COUNT] = CVarGetInteger("gRandomizeStoneCount", 3); - cvarSettings[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = CVarGetInteger("gRandomizeMedallionCount", 6); - cvarSettings[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = CVarGetInteger("gRandomizeRewardCount", 9); - cvarSettings[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = CVarGetInteger("gRandomizeDungeonCount", 8); + cvarSettings[RSK_RAINBOW_BRIDGE_STONE_COUNT] = CVarGetInteger("gRandomizeStoneCount", 4); + cvarSettings[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = CVarGetInteger("gRandomizeMedallionCount", 7); + cvarSettings[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = CVarGetInteger("gRandomizeRewardCount", 10); + cvarSettings[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = CVarGetInteger("gRandomizeDungeonCount", 9); cvarSettings[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = CVarGetInteger("gRandomizeTokenCount", 100); + cvarSettings[RSK_BRIDGE_OPTIONS] = CVarGetInteger("gRandomizeBridgeRewardOptions", 0); cvarSettings[RSK_GANONS_TRIALS] = CVarGetInteger("gRandomizeGanonTrial", RO_GANONS_TRIALS_SET_NUMBER); cvarSettings[RSK_TRIAL_COUNT] = CVarGetInteger("gRandomizeGanonTrialCount", 6); cvarSettings[RSK_STARTING_OCARINA] = CVarGetInteger("gRandomizeStartingOcarina", 0); @@ -2946,11 +2967,12 @@ void GenerateRandomizerImgui(std::string seed = "") { cvarSettings[RSK_KEYRINGS_GANONS_CASTLE] = CVarGetInteger("gRandomizeShuffleKeyRingsGanonsCastle", 0); cvarSettings[RSK_BOSS_KEYSANITY] = CVarGetInteger("gRandomizeBossKeysanity", RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); cvarSettings[RSK_GANONS_BOSS_KEY] = CVarGetInteger("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_VANILLA); - cvarSettings[RSK_LACS_STONE_COUNT] = CVarGetInteger("gRandomizeLacsStoneCount", 3); - cvarSettings[RSK_LACS_MEDALLION_COUNT] = CVarGetInteger("gRandomizeLacsMedallionCount", 6); - cvarSettings[RSK_LACS_REWARD_COUNT] = CVarGetInteger("gRandomizeLacsRewardCount", 9); - cvarSettings[RSK_LACS_DUNGEON_COUNT] = CVarGetInteger("gRandomizeLacsDungeonCount", 8); + cvarSettings[RSK_LACS_STONE_COUNT] = CVarGetInteger("gRandomizeLacsStoneCount", 4); + cvarSettings[RSK_LACS_MEDALLION_COUNT] = CVarGetInteger("gRandomizeLacsMedallionCount", 7); + cvarSettings[RSK_LACS_REWARD_COUNT] = CVarGetInteger("gRandomizeLacsRewardCount", 10); + cvarSettings[RSK_LACS_DUNGEON_COUNT] = CVarGetInteger("gRandomizeLacsDungeonCount", 9); cvarSettings[RSK_LACS_TOKEN_COUNT] = CVarGetInteger("gRandomizeLacsTokenCount", 100); + cvarSettings[RSK_LACS_OPTIONS] = CVarGetInteger("gRandomizeLacsRewardOptions", 0); cvarSettings[RSK_STARTING_CONSUMABLES] = CVarGetInteger("gRandomizeStartingConsumables", 0); cvarSettings[RSK_FULL_WALLETS] = CVarGetInteger("gRandomizeFullWallets", 0); @@ -3079,6 +3101,7 @@ void DrawRandoEditor(bool& open) { static const char* randoGerudoFortress[3] = { "Normal", "Fast", "Open" }; static const char* randoRainbowBridge[8] = { "Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg" }; + static const char* randoBridgeRewardOptions[3] = { "Standard Rewards", "Greg as Reward", "Greg as Wildcard" }; static const char* randoGanonsTrial[3] = { "Skip", "Set Number", "Random Number" }; static const char* randoMqDungeons[3] = { "None", "Set Number", "Random Number" }; @@ -3111,9 +3134,10 @@ void DrawRandoEditor(bool& open) { "Any Dungeon", "Overworld", "Anywhere" }; static const char* randoShuffleGanonsBossKey[13] = {"Vanilla", "Own dungeon", "Start with", "Any Dungeon", "Overworld", "Anywhere", - "LACS-Vanilla", "LACS-Medallions", "LACS-Stones", + "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward"}; + static const char* randoLACSRewardOptions[3] = { "Standard Reward", "Greg as Reward", "Greg as Wildcard" }; static const char* randoShuffleKeyRings[4] = { "Off", "Random", "Count", "Selection" }; // Misc Settings @@ -3338,20 +3362,121 @@ void DrawRandoEditor(bool& open) { case RO_BRIDGE_VANILLA: break; case RO_BRIDGE_STONES: - UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", - "gRandomizeStoneCount", 1, 3, "", 3, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help open the bridge, 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 opening " + "bridge), Greg helps open bridge, 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 open the bridge, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeBridgeRewardOptions", randoBridgeRewardOptions, RO_BRIDGE_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeBridgeRewardOptions", RO_BRIDGE_STANDARD_REWARD)) { + case RO_BRIDGE_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + "gRandomizeStoneCount", 1, 3, "", 3, true, true, false); + break; + case RO_BRIDGE_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + "gRandomizeStoneCount", 1, 4, "", 4, true, true, false); + break; + case RO_BRIDGE_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + "gRandomizeStoneCount", 1, 3, "", 3, true, true, false); + break; + } break; case RO_BRIDGE_MEDALLIONS: - UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", - "gRandomizeMedallionCount", 1, 6, "", 6, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help open the bridge, 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 opening " + "bridge), Greg helps open bridge, 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 open the bridge, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeBridgeRewardOptions", randoBridgeRewardOptions, RO_BRIDGE_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeBridgeRewardOptions", RO_BRIDGE_STANDARD_REWARD)) { + case RO_BRIDGE_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + "gRandomizeMedallionCount", 1, 6, "", 6, true, true, false); + break; + case RO_BRIDGE_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + "gRandomizeMedallionCount", 1, 7, "", 7, true, true, false); + break; + case RO_BRIDGE_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + "gRandomizeMedallionCount", 1, 6, "", 6, true, true, false); + break; + } break; case RO_BRIDGE_DUNGEON_REWARDS: - UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", - "gRandomizeRewardCount", 1, 9, "", 9, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help open the bridge, 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 opening " + "bridge), Greg helps open bridge, 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 open the bridge, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeBridgeRewardOptions", randoBridgeRewardOptions, RO_BRIDGE_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeBridgeRewardOptions", RO_BRIDGE_STANDARD_REWARD)) { + case RO_BRIDGE_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + "gRandomizeRewardCount", 1, 9, "", 9, true, true, false); + break; + case RO_BRIDGE_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + "gRandomizeRewardCount", 1, 10, "", 10, true, true, false); + break; + case RO_BRIDGE_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + "gRandomizeRewardCount", 1, 9, "", 9, true, true, false); + + break; + } break; case RO_BRIDGE_DUNGEONS: - UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", - "gRandomizeDungeonCount", 1, 8, "", 8, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help open the bridge, 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 opening " + "bridge), Greg helps open bridge, 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 open the bridge, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeBridgeRewardOptions", randoBridgeRewardOptions, RO_BRIDGE_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeBridgeRewardOptions", RO_BRIDGE_STANDARD_REWARD)) { + case RO_BRIDGE_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + "gRandomizeDungeonCount", 1, 8, "", 8, true, true, false); + break; + case RO_BRIDGE_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + "gRandomizeDungeonCount", 1, 9, "", 9, true, true, false); + break; + case RO_BRIDGE_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + "gRandomizeDungeonCount", 1, 8, "", 8, true, true, false); + break; + } break; case RO_BRIDGE_TOKENS: UIWidgets::PaddedEnhancementSliderInt("Token Count: %d", "##RandoTokenCount", @@ -3995,8 +4120,8 @@ void DrawRandoEditor(bool& open) { "\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" - "- Medallions: Obtain the specified amount of medallions.\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" @@ -4006,21 +4131,121 @@ void DrawRandoEditor(bool& open) { UIWidgets::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, RO_GANON_BOSS_KEY_VANILLA); ImGui::PopItemWidth(); switch (CVarGetInteger("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_VANILLA)) { - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount", - "gRandomizeLacsMedallionCount", 1, 6, "", 6, true, true, false); - break; case RO_GANON_BOSS_KEY_LACS_STONES: - UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount", - "gRandomizeLacsStoneCount", 1, 3, "", 3, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, 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 " + "GBK), Greg helps obtain GBK, 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 GBK, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeLacsRewardOptions", randoLACSRewardOptions, RO_LACS_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeLacsRewardOptions", RO_LACS_STANDARD_REWARD)) { + case RO_LACS_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount", + "gRandomizeLacsStoneCount", 1, 3, "", 3, true, true, false); + break; + case RO_LACS_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount", + "gRandomizeLacsStoneCount", 1, 4, "", 4, true, true, false); + break; + case RO_LACS_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount", + "gRandomizeLacsStoneCount", 1, 3, "", 3, true, true, false); + break; + } + break; + case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, 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 " + "GBK), Greg helps obtain GBK, 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 GBK, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeLacsRewardOptions", randoLACSRewardOptions, RO_LACS_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeLacsRewardOptions", RO_LACS_STANDARD_REWARD)) { + case RO_LACS_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount", + "gRandomizeLacsMedallionCount", 1, 6, "", 6, true, true, false); + break; + case RO_LACS_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount", + "gRandomizeLacsMedallionCount", 1, 7, "", 7, true, true, false); + break; + case RO_LACS_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount", + "gRandomizeLacsMedallionCount", 1, 6, "", 6, true, true, false); + break; + } break; case RO_GANON_BOSS_KEY_LACS_REWARDS: - UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount", - "gRandomizeLacsRewardCount", 1, 9, "", 9, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, 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 " + "GBK), Greg helps obtain GBK, 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 GBK, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeLacsRewardOptions", randoLACSRewardOptions, RO_LACS_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeLacsRewardOptions", RO_LACS_STANDARD_REWARD)) { + case RO_LACS_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount", + "gRandomizeLacsRewardCount", 1, 9, "", 9, true, true, false); + break; + case RO_LACS_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount", + "gRandomizeLacsRewardCount", 1, 10, "", 10, true, true, false); + break; + case RO_LACS_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount", + "gRandomizeLacsRewardCount", 1, 9, "", 9, true, true, false); + break; + } break; case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount", - "gRandomizeLacsDungeonCount", 1, 8, "", 8, true, true, false); + ImGui::Text("Reward Options"); + UIWidgets::InsertHelpHoverText( + "Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, 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 " + "GBK), Greg helps obtain GBK, 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 GBK, max number of " + "rewards on slider does not change."); + + UIWidgets::EnhancementCombobox("gRandomizeLacsRewardOptions", randoLACSRewardOptions, RO_LACS_STANDARD_REWARD); + switch (CVarGetInteger("gRandomizeLacsRewardOptions", RO_LACS_STANDARD_REWARD)) { + case RO_LACS_STANDARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount", + "gRandomizeLacsDungeonCount", 1, 8, "", 8, true, true, false); + break; + case RO_LACS_GREG_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount", + "gRandomizeLacsDungeonCount", 1, 9, "", 9, true, true, false); + break; + case RO_LACS_WILDCARD_REWARD: + UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount", + "gRandomizeLacsDungeonCount", 1, 8, "", 8, true, true, false); + break; + } break; case RO_GANON_BOSS_KEY_LACS_TOKENS: UIWidgets::PaddedEnhancementSliderInt("Token Count: %d", "##RandoLacsTokenCount", diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 299788f14..f15978392 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -990,6 +990,7 @@ typedef enum { RSK_RAINBOW_BRIDGE_REWARD_COUNT, RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, RSK_RAINBOW_BRIDGE_TOKEN_COUNT, + RSK_BRIDGE_OPTIONS, RSK_GANONS_TRIALS, RSK_TRIAL_COUNT, RSK_STARTING_OCARINA, @@ -1065,11 +1066,12 @@ typedef enum { RSK_LINKS_POCKET, RSK_RANDOM_MQ_DUNGEONS, RSK_MQ_DUNGEON_COUNT, - RSK_LACS_MEDALLION_COUNT, RSK_LACS_STONE_COUNT, + RSK_LACS_MEDALLION_COUNT, RSK_LACS_REWARD_COUNT, RSK_LACS_DUNGEON_COUNT, RSK_LACS_TOKEN_COUNT, + RSK_LACS_OPTIONS, RSK_KEYRINGS, RSK_KEYRINGS_RANDOM_COUNT, RSK_KEYRINGS_GERUDO_FORTRESS, @@ -1174,6 +1176,13 @@ typedef enum { RO_BRIDGE_GREG, } RandoOptionRainbowBridge; +// Bridge Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard) +typedef enum { + RO_BRIDGE_STANDARD_REWARD, + RO_BRIDGE_GREG_REWARD, + RO_BRIDGE_WILDCARD_REWARD, +} RandoOptionBridgeRewards; + //Shopsanity settings (off, 0-4 items, random) typedef enum { RO_SHOPSANITY_OFF, @@ -1246,14 +1255,21 @@ typedef enum { RO_GANON_BOSS_KEY_OVERWORLD, RO_GANON_BOSS_KEY_ANYWHERE, RO_GANON_BOSS_KEY_LACS_VANILLA, - RO_GANON_BOSS_KEY_LACS_MEDALLIONS, RO_GANON_BOSS_KEY_LACS_STONES, + RO_GANON_BOSS_KEY_LACS_MEDALLIONS, RO_GANON_BOSS_KEY_LACS_REWARDS, RO_GANON_BOSS_KEY_LACS_DUNGEONS, RO_GANON_BOSS_KEY_LACS_TOKENS, RO_GANON_BOSS_KEY_KAK_TOKENS, } RandoOptionGanonsBossKey; +// LACS Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard) +typedef enum { + RO_LACS_STANDARD_REWARD, + RO_LACS_GREG_REWARD, + RO_LACS_WILDCARD_REWARD, +} RandoOptionLACSRewards; + //Ganon's Trials typedef enum { RO_GANONS_TRIALS_SKIP, diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index ead1574f7..a3d275390 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -338,29 +338,65 @@ u8 CheckDungeonCount() { return dungeonCount; } +u8 CheckBridgeRewardCount() { + u8 bridgeRewardCount = 0; + + switch (Randomizer_GetSettingValue(RSK_BRIDGE_OPTIONS)) { + case RO_BRIDGE_WILDCARD_REWARD: + if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) { + bridgeRewardCount += 1; + } + break; + case RO_BRIDGE_GREG_REWARD: + if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) { + bridgeRewardCount += 1; + } + break; + } + 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 GivePlayerRandoRewardZeldaLightArrowsGift(PlayState* play, RandomizerCheck check) { Player* player = GET_PLAYER(play); u8 meetsRequirements = 0; switch (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY)) { - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - if (CheckMedallionCount() >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) { + case RO_GANON_BOSS_KEY_LACS_STONES: + if ((CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) { meetsRequirements = true; } break; - case RO_GANON_BOSS_KEY_LACS_STONES: - if (CheckStoneCount() >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) { + case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: + if ((CheckMedallionCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) { meetsRequirements = true; } break; case RO_GANON_BOSS_KEY_LACS_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) { + if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) { meetsRequirements = true; } break; case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - if (CheckDungeonCount() >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) { + if ((CheckDungeonCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) { meetsRequirements = true; } break; diff --git a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c index 3d9649d79..1865b6a30 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c +++ b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c @@ -106,25 +106,25 @@ void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) { } break; case RO_BRIDGE_STONES: - if (CheckStoneCount() >= bridgeStoneCount) { + if ((CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeStoneCount) { this->actionFunc = BgGjyoBridge_SpawnBridge; func_800F595C(NA_BGM_BRIDGE_TO_GANONS); } break; case RO_BRIDGE_MEDALLIONS: - if (CheckMedallionCount() >= bridgeMedallionCount) { + if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= bridgeMedallionCount) { this->actionFunc = BgGjyoBridge_SpawnBridge; func_800F595C(NA_BGM_BRIDGE_TO_GANONS); } break; case RO_BRIDGE_DUNGEON_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount()) >= bridgeRewardCount) { + if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeRewardCount) { this->actionFunc = BgGjyoBridge_SpawnBridge; func_800F595C(NA_BGM_BRIDGE_TO_GANONS); } break; case RO_BRIDGE_DUNGEONS: - if (CheckDungeonCount() >= bridgeDungeonCount) { + if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= bridgeDungeonCount) { this->actionFunc = BgGjyoBridge_SpawnBridge; func_800F595C(NA_BGM_BRIDGE_TO_GANONS); }