diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index e4b4ad76e..f8e692ee4 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -496,5 +496,7 @@ const std::vector flagTables = { { RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD, "ADULT_TRADES_DMT_TRADE_BROKEN_SWORD" }, { RAND_INF_ADULT_TRADES_LH_TRADE_FROG, "ADULT_TRADES_LH_TRADE_FROG" }, { RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS, "ADULT_TRADES_DMT_TRADE_EYEDROPS" }, + + { RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, "KAK_100_GOLD_SKULLTULA_REWARD" }, } }, }; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 0e8ab67e1..84fce11a2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -148,7 +148,10 @@ static int GetMaxGSCount() { //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 - if (Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + if (Location(KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 100; + } + else if (Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { maxUseful = 50; } else if (Location(KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index f52d1091c..ba47ad92d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -74,6 +74,25 @@ void HintTable_Init() { Text{ "#Malon's obstacle course# leads to", /*french*/ "la #course à obstacle de Malon# amène à", /*spanish*/ "la #carrera de obstáculos de Malon# brinda" }); + hintTable[KAK_100_GOLD_SKULLTULA_REWARD] = HintText::Always( + { + // obscure text + Text{ "#100 bug badges# rewards", + /*french*/ "#100 écussons# donnent", + /*spanish*/ "#100 medallas de insectos# otorgan" }, + Text{ "#100 spider souls# yields", + /*french*/ "#100 âmes d'arachnide# donnent", + /*spanish*/ "#100 almas de araña# otorgan" }, + Text{ "#100 auriferous arachnids# lead to", + /*french*/ "#100 arachnides aurifères# donnent", + /*spanish*/ "#100 arácnidos auríferos# otorgan" }, + }, + {}, + // clear text + Text{ "slaying #100 Gold Skulltulas# reveals", + /*french*/ "détruire #100 Skulltulas d'or# donne", + /*spanish*/ "exterminar #100 skulltulas doradas# revela" }); + /*-------------------------- | SOMETIMES HINT TEXT | ---------------------------*/ @@ -2699,6 +2718,13 @@ void HintTable_Init() { /*spanish*/ "Y el héroe recibirá la llave del #señor del mal# cuando haya completado la #Trifuerza#." }, }); + hintTable[GANON_BK_SKULLTULA_HINT] = HintText::GanonsBossKey({ + // obscure text + Text { "And the %revil one%w's key will be&provided by the cursed rich man&once %r100 Gold Skulltula Tokens%w&are retrieved.", + /*french*/ "Aussi, la %rclé du Malin%w sera&donnée par l'homme maudit une&fois que %r100 Symboles de&Skulltula d'or%w auront été trouvés.", + /*spanish*/ "Y el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#."}, + }); + /*-------------------------- | LACS HINT TEXT | ---------------------------*/ diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 6b613246b..09c6a6528 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -653,6 +653,9 @@ static Text BuildGanonBossKeyText() { } else if (GanonsBossKey.Is(GANONSBOSSKEY_ANYWHERE)) { ganonBossKeyText = Hint(GANON_BK_ANYWHERE_HINT).GetText(); + } else if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) { + ganonBossKeyText = Hint(GANON_BK_SKULLTULA_HINT).GetText(); + } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_VANILLA)) { ganonBossKeyText = Hint(LACS_VANILLA_HINT).GetText(); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index d88117cec..d91511f98 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -116,6 +116,7 @@ void LocationTable_Init() { locationTable[KAK_30_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_30_GOLD_SKULLTULA_REWARD, 0x50, 0x46, "Kak 30 Gold Skulltula Reward", KAK_30_GOLD_SKULLTULA_REWARD, PROGRESSIVE_WALLET, {Category::cKakarikoVillage, Category::cKakariko, Category::cSkulltulaHouse}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_40_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_40_GOLD_SKULLTULA_REWARD, 0x50, 0x03, "Kak 40 Gold Skulltula Reward", KAK_40_GOLD_SKULLTULA_REWARD, BOMBCHU_10, {Category::cKakarikoVillage, Category::cKakariko, Category::cSkulltulaHouse}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_50_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_50_GOLD_SKULLTULA_REWARD, 0x50, 0x3E, "Kak 50 Gold Skulltula Reward", KAK_50_GOLD_SKULLTULA_REWARD, PIECE_OF_HEART, {Category::cKakarikoVillage, Category::cKakariko, Category::cSkulltulaHouse}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, 0x3E, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {Category::cKakarikoVillage, Category::cKakariko, Category::cSkulltulaHouse}, SpoilerCollectionCheck::EventChkInf(0xDF), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, 0x3E, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {Category::cKakarikoVillage, Category::cKakariko,}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, 0x30, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {Category::cKakarikoVillage, Category::cKakariko, Category::cMinigame}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, 0x20, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(56), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); @@ -1276,6 +1277,7 @@ std::vector overworldLocations = { KAK_30_GOLD_SKULLTULA_REWARD, KAK_40_GOLD_SKULLTULA_REWARD, KAK_50_GOLD_SKULLTULA_REWARD, + KAK_100_GOLD_SKULLTULA_REWARD, KAK_MAN_ON_ROOF, KAK_SHOOTING_GALLERY_REWARD, KAK_TRADE_ODD_MUSHROOM, diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 6cca76be9..b4f4a7c52 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -798,6 +798,15 @@ void GenerateItemPool() { AddItemToMainPool(GOLD_SKULLTULA_TOKEN, 100); } + if (Shuffle100GSReward) { + if (Tokensanity.IsNot(TOKENSANITY_OFF) && ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, GOLD_SKULLTULA_TOKEN, 10); + } + AddItemToMainPool(HUGE_RUPEE); + } else { + PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, false, true); + } + if (BombchusInLogic) { AddItemToMainPool(PROGRESSIVE_BOMBCHUS, 5); } else { @@ -1119,7 +1128,9 @@ void GenerateItemPool() { AddItemToMainPool(SHADOW_TEMPLE_BOSS_KEY); } - if (GanonsBossKey.Value() >= GANONSBOSSKEY_LACS_VANILLA) { + if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) { + PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, GANONS_CASTLE_BOSS_KEY); + } else if (GanonsBossKey.Value() >= GANONSBOSSKEY_LACS_VANILLA) { PlaceItemInLocation(TOT_LIGHT_ARROWS_CUTSCENE, GANONS_CASTLE_BOSS_KEY); } else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) { PlaceItemInLocation(GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY); diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp index 0016ff205..3163d37dd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/keys.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/keys.hpp @@ -392,6 +392,7 @@ typedef enum { KAK_30_GOLD_SKULLTULA_REWARD, KAK_40_GOLD_SKULLTULA_REWARD, KAK_50_GOLD_SKULLTULA_REWARD, + KAK_100_GOLD_SKULLTULA_REWARD, KAK_IMPAS_HOUSE_COW, KAK_GS_TREE, KAK_GS_GUARDS_HOUSE, @@ -1762,6 +1763,7 @@ typedef enum { GANON_BK_ANY_DUNGEON_HINT, GANON_BK_ANYWHERE_HINT, GANON_BK_TRIFORCE_HINT, + GANON_BK_SKULLTULA_HINT, LACS_VANILLA_HINT, LACS_MEDALLIONS_HINT, diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp index fbd4adff9..d75b06f84 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -97,6 +97,7 @@ void AreaTable_Init_Kakariko() { LocationAccess(KAK_30_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 30;}}), LocationAccess(KAK_40_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 40;}}), LocationAccess(KAK_50_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 50;}}), + LocationAccess(KAK_100_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 100;}}) }, { //Exits Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp index 8c404f354..1a0544ee1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp @@ -368,7 +368,7 @@ string_view tokensOverworld = "This only shuffles the GS locations tha "outside of dungeons."; // string_view tokensAllTokens = "Effectively adds 100 new locations for items to\n"// "appear."; // - // + /*------------------------------ // | SCRUB SHUFFLE | // ------------------------------*/ // @@ -471,6 +471,15 @@ string_view chestMinigameDesc = "The 5 key chests in the Treasure Chest "\n" // "If you choose the \"pack\" option, you will get\n"// "all the keys at once, in a single item."; // + // +/*------------------------------ // +| SHUFFLE 100 GS REWARD | // +------------------------------*/ // +string_view shuffle100GsDesc = "The cursed rich man in the House of Skulltula\n" // + "will give you a random item for collecting all\n" // + "100 Gold Skulltula Tokens, then he will give you\n" + "Huge Rupees."; // + // /*------------------------------ // | MAPS AND COMPASSES | // ------------------------------*/ // @@ -571,6 +580,9 @@ string_view ganonKeyAnywhere = "Ganon's Castle Boss Key can appear anyw string_view ganonKeyLACS = "These settings put the boss key on the Light Arrow" "Cutscene location, from Zelda in Temple of Time as" "adult, with differing requirements."; // +string_view ganonKey100GS = "Ganon's Castle Boss Key is given to you by the\n" // + "cursed rich man in the House of Skulltula after\n"// + "you collect all 100 Gold Skulltula Tokens."; // /*------------------------------ // | LACS CONDITIONS | // ------------------------------*/ // diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp index 096ebf658..b99087944 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp @@ -148,6 +148,8 @@ extern string_view adultTradeDesc; extern string_view chestMinigameDesc; +extern string_view shuffle100GsDesc; + extern string_view mapCompassStartWith; extern string_view mapCompassVanilla; extern string_view mapCompassOwnDungeon; @@ -183,6 +185,7 @@ extern string_view ganonKeyAnyDungeon; extern string_view ganonKeyOverworld; extern string_view ganonKeyAnywhere; extern string_view ganonKeyLACS; +extern string_view ganonKey100GS; extern string_view lacsMedallionCountDesc; extern string_view lacsStoneCountDesc; diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 1a4e10a65..b8a05c345 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -190,6 +190,7 @@ namespace Settings { Option ShuffleFrogSongRupees = Option::Bool("Shuffle Frog Song Rupees",{"Off", "On"}, {frogSongRupeesDesc}); Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"}, {adultTradeDesc}); Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}, {chestMinigameDesc}); + Option Shuffle100GSReward = Option::Bool("Shuffle 100 GS Reward", {"No", "Yes"}, {shuffle100GsDesc}, OptionCategory::Toggle); std::vector