diff options
| author | Ralphie Morell <rafael.morell@techfield.us> | 2023-10-21 21:51:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-21 20:51:37 -0500 |
| commit | 2eaed8d81ea2586a8a4112f17bd3a88d3c7882db (patch) | |
| tree | 6cb9848eeeda01c7ad15d8f86c49df72c053ea3a | |
| parent | e6445e0ce3b71c4db2e3a177054cffee1d3c5930 (diff) | |
Rando: Master Sword Shuffle (#2981)
* The mother of all commits
* Removed `GI_SWORD_MASTER`;
"Master Sword" Items now actually give MS
* Removed dupe MS entries in item pool;
updated GIMESSAGE (should stop crashing on non-Windows);
re-added MS in item list
* Give Adult Link a freebie with shuffle MS on;
cihld -> adult no longer gives MS;
ToT Master Sword now gives correct item
* add master sword GI draw func based on ToT MS object
* Force `MasterSword` logic var to only update upon getting MS
* Dorf funny line now activates with LA and MS in inv
* Apply suggestions
* Updated RAND_INF;
Check Tracker changes;
Gave RAND_INF and ice trap logic to ToT MS check;
Fixed swordless behavior for HBA/fishing
* ToT MS Check now works in check tracker;
Visual bug where box hovers over non-existent MS gone;
Fixed RAND_INF check with ToT MS pedestal;
Ganon no longer gives free MS
* adult equips no longer reset in MS shuffle
* Apply (most) locacc review suggestions
Co-authored-by: inspectredc <78732756+inspectredc@users.noreply.github.com>
* Reorganized swordless check for interface to fit edge cases;
getting master sword no longer highlights box
* Edge case for BGS but no bow
* Fix implicit declaration error for GI hooks (#9)
* Adjusted `CanAdultAttack/Damage`; applied logic suggestions
* Fixed build errors (hopefully)
* Cleanup merge
* get shit working again
* Tidied up remaining uses of DD flag as rando indicator
* make master sword invisible and fix ms flag (#10)
* Add text to sheik if go mode is obtained but barrier is still up
* overhaul swordless behavior in `func_80083108`
* reworked ToT MS Check to have an actual GI
* suggestions
* Apply suggestions
* Better swordless handling with temp B (#11)
* better swordless handling with temp B
* prevent auto save in fishing pond
* prevent auto save during bombchu bowling
* enum fix
---------
Co-authored-by: Adam Bird <archez39@me.com>
Co-authored-by: inspectredc <78732756+inspectredc@users.noreply.github.com>
Co-authored-by: RaelCappra <rael.cappra@gmail.com>
Co-authored-by: Adam Bird <Archez@users.noreply.github.com>
57 files changed, 558 insertions, 310 deletions
diff --git a/soh/include/functions.h b/soh/include/functions.h index e75777c87..3a1aa8ae2 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -2449,13 +2449,18 @@ void Heaps_Free(void); CollisionHeader* BgCheck_GetCollisionHeader(CollisionContext* colCtx, s32 bgId); -void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH); - // Exposing these methods to leverage them from the file select screen to render messages void Message_OpenText(PlayState* play, u16 textId); void Message_Decode(PlayState* play); void Message_DrawText(PlayState* play, Gfx** gfxP); +// #region SOH [General] + +void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH); +void Interface_RandoRestoreSwordless(void); + +// #endregion + #ifdef __cplusplus #undef this }; diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 4b87a179a..9458f28c7 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -289,7 +289,6 @@ typedef struct { /* */ u8 mqDungeonCount; /* */ u8 pendingIceTrapCount; /* */ SohStats sohStats; - /* */ u8 temporaryWeapon; /* */ FaroresWindData backupFW; /* */ RandomizerCheckTrackerData checkTrackerData[RC_MAX]; // #endregion @@ -302,11 +301,11 @@ typedef struct { /* */ char childAltarText[250]; /* */ char adultAltarText[750]; /* */ RandomizerCheck rewardCheck[9]; - /* */ char ganonHintText[150]; + /* */ char ganonHintText[300]; /* */ char gregHintText[250]; /* */ char ganonText[250]; /* */ char dampeText[150]; - /* */ char sheikText[150]; + /* */ char sheikText[200]; /* */ char sariaText[150]; /* */ char warpMinuetText[100]; /* */ char warpBoleroText[100]; @@ -314,6 +313,7 @@ typedef struct { /* */ char warpRequiemText[100]; /* */ char warpNocturneText[100]; /* */ char warpPreludeText[100]; + /* */ RandomizerCheck masterSwordHintCheck; /* */ RandomizerCheck lightArrowHintCheck; /* */ RandomizerCheck sariaCheck; /* */ RandomizerCheck gregCheck; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 3c3b66d73..42c9c91c0 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -500,6 +500,8 @@ const std::vector<FlagTable> flagTables = { { RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, "KAK_100_GOLD_SKULLTULA_REWARD" }, { RAND_INF_GREG_FOUND, "RAND_INF_GREG_FOUND" }, + + { RAND_INF_TOT_MASTER_SWORD, "RAND_INF_TOT_MASTER_SWORD"}, { RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" }, { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 73d6c4634..d23c5609e 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -248,6 +248,8 @@ void AutoSave(GetItemEntry itemEntry) { // Don't autosave immediately after buying items from shops to prevent getting them for free! // Don't autosave in the Chamber of Sages since resuming from that map breaks the game // Don't autosave during the Ganon fight when picking up the Master Sword + // Don't autosave in the fishing pond to prevent getting rod on B outside of the pond + // Don't autosave in the bombchu bowling alley to prevent having chus on B outside of the minigame // Don't autosave in grottos since resuming from grottos breaks the game. if ((CVarGetInteger("gAutosave", AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) && (gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_BOSS)) { @@ -311,8 +313,9 @@ void AutoSave(GetItemEntry itemEntry) { CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION) { performSave = true; } - if ((gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) || (gPlayState->sceneNum == SCENE_GROTTOS) || - (gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES)) { + if (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN || gPlayState->sceneNum == SCENE_GROTTOS || + gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES || gPlayState->sceneNum == SCENE_FISHING_POND || + gPlayState->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) { if (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS || CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS || CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION) { diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index b830efb60..d9d94da20 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2958,6 +2958,20 @@ void HintTable_Init() { "Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de " }, }); + + /*-------------------------- + |MASTER SWORD LOCATION TEXT| + ---------------------------*/ + + hintTable[MASTER_SWORD_LOCATION_HINT] = HintText::MasterSword({ + // obscure text + Text{"And even if you do, you'll never find the legendary blade hidden in ", + /*french*/ + "Et même si tu les trouves, tu ne touveras jamais l'épée de légende cachée dans ", + /*spanish*/ + "E incluso si lo haces, nunca encontrarás la espada legendaria escondida en " }, + }); + hintTable[YOUR_POCKET] = HintText::Exclude({ // obscure text Text{ "your pocket", /*french*/ "tes poches", /*spanish*/ "tu bolsillo" }, diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 8b9f37f9e..f2e110226 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -131,6 +131,10 @@ void HintTable_Init_Exclude_Overworld() { Text{"a #hole in a volcano# holds", /*french*/"la #grotte dans le volcan# contient", /*spanish*/"bajo el #hoyo de un volcán# yace"}, }); + hintTable[TOT_MASTER_SWORD] = HintText::Exclude({ + //obscure text + Text{"a #pedestal in a temple# holds", /*french*/"un #piédestal dans un temple# contient", /*spanish*/"un #pedestal en un templo# sostiene"}, + }); hintTable[TOT_LIGHT_ARROWS_CUTSCENE] = HintText::Exclude({ //obscure text diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index dea7833fc..3bdaeee5d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -6,6 +6,7 @@ #include "item_pool.hpp" #include "logic.hpp" #include "random.hpp" +#include "settings.hpp" #include "spoiler_log.hpp" #include "fill.hpp" #include "hint_list.hpp" @@ -143,7 +144,9 @@ Text warpRequiemText; Text warpNocturneText; Text warpPreludeText; + std::string lightArrowHintLoc; +std::string masterSwordHintLoc; std::string sariaHintLoc; std::string dampeHintLoc; @@ -203,6 +206,10 @@ Text& GetWarpPreludeText() { return warpPreludeText; } +std::string GetMasterSwordHintLoc() { + return masterSwordHintLoc; +} + std::string GetLightArrowHintLoc() { return lightArrowHintLoc; } @@ -607,6 +614,22 @@ void CreateGanonText() { } ganonHintText = ganonHintText + "!"; + if (ShuffleMasterSword) { + //Get the location of the master sword + auto masterSwordLocation = FilterFromPool(allLocations, [](const LocationKey loc){return Location(loc)->GetPlacedItemKey() == MASTER_SWORD;}); + + // Add second text box + ganonHintText = ganonHintText + "^"; + if (masterSwordLocation.empty()) { + ganonHintText = ganonHintText+Hint(MASTER_SWORD_LOCATION_HINT).GetText()+Hint(YOUR_POCKET).GetText(); + masterSwordHintLoc = "Link's Pocket"; + } else { + ganonHintText = ganonHintText+Hint(MASTER_SWORD_LOCATION_HINT).GetText()+GetHintRegion(Location(masterSwordLocation[0])->GetParentRegionKey())->GetHint().GetText(); + masterSwordHintLoc = Location(masterSwordLocation[0])->GetName(); + } + ganonHintText = ganonHintText + "!"; + } + CreateMessageFromTextObject(0x70CC, 0, 2, 3, AddColorsAndFormat(ganonHintText)); } @@ -865,6 +888,18 @@ void CreateSheikText() { }; Text temp2 = Text{"%w.", "%w.", "%w."}; sheikText = temp1 + area + temp2; + if (ShuffleMasterSword) { + sheikText = sheikText + "^"; + auto masterSwordLocation = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == MASTER_SWORD;}); + masterSwordHintLoc = Location(masterSwordLocation[0])->GetName(); + area = GetHintRegion(Location(masterSwordLocation[0])->GetParentRegionKey())->GetHint().GetText(); + Text temp3 = Text{ + "I also heard that he stole %rthe Master Sword%w and hid it somewhere within %g", + "Test", + "Test" + }; + sheikText = sheikText + temp3 + area + temp2; + } } void CreateSariaText() { diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.hpp b/soh/soh/Enhancements/randomizer/3drando/hints.hpp index 83985c0da..9bc6d61db 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.hpp @@ -43,6 +43,7 @@ enum class HintCategory { Altar, Validation, LightArrow, + MasterSword, GanonLine, MerchantsDialogs, }; @@ -116,6 +117,10 @@ public: return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LightArrow}; } + static auto MasterSword(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) { + return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MasterSword}; + } + static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine}; } @@ -228,5 +233,6 @@ Text& GetWarpNocturneText(); Text& GetWarpPreludeText(); std::string GetDampeHintLoc(); +std::string GetMasterSwordHintLoc(); std::string GetLightArrowHintLoc(); std::string GetSariaHintLoc(); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp b/soh/soh/Enhancements/randomizer/3drando/item_list.cpp index 417203a5b..c3722ffd0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_list.cpp @@ -12,7 +12,7 @@ static std::array<Item, KEY_ENUM_MAX> itemTable; void ItemTable_Init() { // RandomizerGet English name French Spanish Item Type getItemID advancement logic hint key itemTable[NONE] = Item(RG_NONE, Text{"No Item", "Rien", "Sin Objeto"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, &noVariable, NONE); itemTable[KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{"Kokiri Sword", "Épée Kokiri", "Espada Kokiri"}, ITEMTYPE_ITEM, GI_SWORD_KOKIRI, true, &KokiriSword, KOKIRI_SWORD); - //[MASTER_SWORD] + itemTable[MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{"Master Sword", "Épée de Legende", "Espada Master"}, ITEMTYPE_ITEM, 0x73, true, &MasterSword, MASTER_SWORD); itemTable[GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{"Giant's Knife", "Lame des Géants", "Espada de Biggoron"}, ITEMTYPE_ITEM, GI_SWORD_KNIFE, false, &noVariable, GIANTS_KNIFE); itemTable[BIGGORON_SWORD] = Item(RG_BIGGORON_SWORD, Text{"Biggoron's Sword", "Épée de Biggoron", "Espada de Biggoron"}, ITEMTYPE_ITEM, GI_SWORD_BGS, true, &BiggoronSword, BIGGORON_SWORD); itemTable[DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{"Deku Shield", "Bouclier Mojo", "Escudo deku"}, ITEMTYPE_ITEM, GI_SHIELD_DEKU, false, &noVariable, DEKU_SHIELD); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index 1c085021c..577de1c19 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -754,7 +754,7 @@ void LocationTable_Init() { /*------------------------------- --- CUTSCENES --- -------------------------------*/ - + locationTable[TOT_MASTER_SWORD] = ItemLocation::Delayed(RC_TOT_MASTER_SWORD, 0xFF, "ToT Master Sword", TOT_MASTER_SWORD, MASTER_SWORD, {}, SpoilerCollectionCheck::MasterSword(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[TOT_LIGHT_ARROWS_CUTSCENE] = ItemLocation::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, 0xFF, "ToT Light Arrow Cutscene", TOT_LIGHT_ARROWS_CUTSCENE, LIGHT_ARROWS, {}, SpoilerCollectionCheck::Chest(0x43, 0x1E), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[LW_GIFT_FROM_SARIA] = ItemLocation::Delayed(RC_LW_GIFT_FROM_SARIA, 0xFF, "LW Gift From Saria", LW_GIFT_FROM_SARIA, PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[ZF_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_ZF_GREAT_FAIRY_REWARD, 0xFF, "ZF Great Fairy Reward", ZF_GREAT_FAIRY_REWARD, FARORES_WIND, {}, SpoilerCollectionCheck::Chest(0x3D, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); @@ -1265,6 +1265,7 @@ std::vector<uint32_t> overworldLocations = { OGC_GREAT_FAIRY_REWARD, //Temple of Time + TOT_MASTER_SWORD, SHEIK_AT_TEMPLE, TOT_LIGHT_ARROWS_CUTSCENE, diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.hpp b/soh/soh/Enhancements/randomizer/3drando/item_location.hpp index e900ab941..5a61c2986 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.hpp @@ -149,9 +149,14 @@ class SpoilerCollectionCheck { static auto MagicBeans() { return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS, 0x00, 0x00); } + + static auto MasterSword() { + return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD, 0x00, 0x00); + } static auto Merchant() { return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT, 0x00, 0x00); + } static auto RandomizerInf() { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 485fc4154..1eb496eb2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -108,9 +108,10 @@ const std::array<uint32_t, 59> alwaysItems = { ARROWS_10, TREASURE_GAME_HEART, }; -const std::array<uint32_t, 43> easyItems = { +const std::array<uint32_t, 44> easyItems = { BIGGORON_SWORD, KOKIRI_SWORD, + MASTER_SWORD, BOOMERANG, LENS_OF_TRUTH, MEGATON_HAMMER, @@ -682,6 +683,13 @@ void GenerateItemPool() { PlaceItemInLocation(KF_KOKIRI_SWORD_CHEST, KOKIRI_SWORD, false, true); } + if (ShuffleMasterSword) { + AddItemToMainPool(MASTER_SWORD); + IceTrapModels.push_back(0xE0); //Master Sword without the GI enum + } else { + PlaceItemInLocation(TOT_MASTER_SWORD, MASTER_SWORD, false, true); + } + if (ShuffleWeirdEgg) { AddItemToMainPool(WEIRD_EGG); IceTrapModels.push_back(GI_WEIRD_EGG); @@ -1161,6 +1169,10 @@ void GenerateItemPool() { ReplaceMaxItem(KOKIRI_SWORD, 0); } + if (!ShuffleMasterSword) { + ReplaceMaxItem(MASTER_SWORD, 0); + } + if (ProgressiveGoronSword) { ReplaceMaxItem(BIGGORON_SWORD, 0); AddItemToMainPool(PROGRESSIVE_GORONSWORD, 2); diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp index 6e9e87f4e..e6e36e93d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/keys.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/keys.hpp @@ -357,6 +357,7 @@ typedef enum { MARKET_BOMBCHU_SHOP_ITEM_6, MARKET_BOMBCHU_SHOP_ITEM_7, MARKET_BOMBCHU_SHOP_ITEM_8, + TOT_MASTER_SWORD, TOT_LIGHT_ARROWS_CUTSCENE, //HYRULE_CASTLE HC_MALON_EGG, @@ -1804,6 +1805,7 @@ typedef enum { VALIDATION_LINE, LIGHT_ARROW_LOCATION_HINT, + MASTER_SWORD_LOCATION_HINT, DAMPE_DIARY, YOUR_POCKET, diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index 6691ac2f2..d98096314 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -52,6 +52,7 @@ void AreaTable_Init_CastleTown() { areaTable[TEMPLE_OF_TIME] = Area("Temple of Time", "Temple of Time", TEMPLE_OF_TIME, NO_DAY_NIGHT_CYCLE, {}, { //Locations + LocationAccess(TOT_MASTER_SWORD, {[]{return IsAdult;}}), LocationAccess(TOT_LIGHT_ARROWS_CUTSCENE, {[]{return IsAdult && CanTriggerLACS;}}), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index b52be650e..bf1d06148 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp @@ -95,7 +95,7 @@ void AreaTable_Init_DeathMountain() { LocationAccess(GC_ROLLING_GORON_AS_CHILD, {[]{return IsChild && (HasExplosives || (GoronBracelet && LogicChildRollingWithStrength));}}), LocationAccess(GC_ROLLING_GORON_AS_ADULT, {[]{return StopGCRollingGoronAsAdult;}}), LocationAccess(GC_GS_BOULDER_MAZE, {[]{return IsChild && CanBlastOrSmash;}}), - LocationAccess(GC_GS_CENTER_PLATFORM, {[]{return IsAdult;}}), + LocationAccess(GC_GS_CENTER_PLATFORM, {[]{return CanAdultAttack;}}), LocationAccess(GC_MEDIGORON, {[]{return IsAdult && AdultsWallet && (CanBlastOrSmash || GoronBracelet);}}), LocationAccess(GC_MAZE_GOSSIP_STONE, {[]{return CanBlastOrSmash || CanUse(SILVER_GAUNTLETS);}}), LocationAccess(GC_MEDIGORON_GOSSIP_STONE, {[]{return CanBlastOrSmash || GoronBracelet;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index c39676a82..2224df4ca 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp @@ -23,8 +23,8 @@ void AreaTable_Init_DekuTree() { if (Dungeon::DekuTree.IsVanilla()) { areaTable[DEKU_TREE_LOBBY] = Area("Deku Tree Lobby", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(DEKU_TREE_MAP_CHEST, {[]{return true;}}), @@ -33,7 +33,7 @@ void AreaTable_Init_DekuTree() { Entrance(DEKU_TREE_ENTRYWAY, {[]{return true;}}), Entrance(DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}), Entrance(DEKU_TREE_COMPASS_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_LOWER, {[]{return Here(DEKU_TREE_LOBBY, []{return IsAdult || CanChildAttack || Nuts;});}}), + Entrance(DEKU_TREE_BASEMENT_LOWER, {[]{return Here(DEKU_TREE_LOBBY, []{return CanAdultAttack || CanChildAttack || Nuts;});}}), Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), }); @@ -55,13 +55,13 @@ void AreaTable_Init_DekuTree() { areaTable[DEKU_TREE_COMPASS_ROOM] = Area("Deku Tree Compass Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(DEKU_TREE_COMPASS_CHEST, {[]{return true;}}), LocationAccess(DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_GS_COMPASS_ROOM, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(DEKU_TREE_GS_COMPASS_ROOM, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(DEKU_TREE_LOBBY, {[]{return HasFireSourceWithTorch || CanUse(BOW);}}), @@ -70,14 +70,14 @@ void AreaTable_Init_DekuTree() { areaTable[DEKU_TREE_BASEMENT_LOWER] = Area("Deku Tree Basement Lower", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}, + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || Boomerang);}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}, /*Glitched*/[]{return CanUse(MEGATON_HAMMER);}}), }, { //Locations LocationAccess(DEKU_TREE_BASEMENT_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_GS_BASEMENT_GATE, {[]{return IsAdult || CanChildAttack;}}), - LocationAccess(DEKU_TREE_GS_BASEMENT_VINES, {[]{return CanUseProjectile || CanUse(DINS_FIRE) || (LogicDekuBasementGS && (IsAdult || Sticks || KokiriSword));}}), + LocationAccess(DEKU_TREE_GS_BASEMENT_GATE, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE);}}), + LocationAccess(DEKU_TREE_GS_BASEMENT_VINES, {[]{return CanUseProjectile || CanUse(DINS_FIRE) || (LogicDekuBasementGS && CanJumpslash);}}), }, { //Exits Entrance(DEKU_TREE_LOBBY, {[]{return true;}}), @@ -100,8 +100,8 @@ void AreaTable_Init_DekuTree() { areaTable[DEKU_TREE_BASEMENT_TORCH_ROOM] = Area("Deku Tree Basement Torch Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, {}, { //Exits Entrance(DEKU_TREE_BASEMENT_WATER_ROOM, {[]{return true;}}), @@ -110,9 +110,9 @@ void AreaTable_Init_DekuTree() { areaTable[DEKU_TREE_BASEMENT_BACK_LOBBY] = Area("Deku Tree Basement Back Lobby", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (Here(DEKU_TREE_BASEMENT_BACK_LOBBY, []{return HasFireSourceWithTorch || CanUse(BOW);}) && - (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE)));}}), + (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE)));}}), }, {}, { //Exits Entrance(DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), @@ -131,8 +131,8 @@ void AreaTable_Init_DekuTree() { areaTable[DEKU_TREE_BASEMENT_UPPER] = Area("Deku Tree Basement Upper", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, {}, { //Exits Entrance(DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), @@ -153,15 +153,15 @@ void AreaTable_Init_DekuTree() { if (Dungeon::DekuTree.IsMQ()) { areaTable[DEKU_TREE_MQ_LOBBY] = Area("Deku Tree MQ Lobby", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(DEKU_TREE_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_MQ_SLINGSHOT_CHEST, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(DEKU_TREE_MQ_SLINGSHOT_CHEST, {[]{return CanAdultAttack || CanChildAttack;}}), LocationAccess(DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, {[]{return HasFireSourceWithTorch || (IsAdult && CanUse(BOW));}}), LocationAccess(DEKU_TREE_MQ_BASEMENT_CHEST, {[]{return HasFireSourceWithTorch || (IsAdult && CanUse(BOW));}}), - LocationAccess(DEKU_TREE_MQ_GS_LOBBY, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(DEKU_TREE_MQ_GS_LOBBY, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(DEKU_TREE_ENTRYWAY, {[]{return true;}}), @@ -201,7 +201,8 @@ void AreaTable_Init_DekuTree() { //Exits Entrance(DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE) || Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return IsAdult && CanUse(FIRE_ARROWS);});}) && - Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return IsAdult || KokiriSword || CanUseProjectile || (Nuts && Sticks);});}}), + Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || + CanUseProjectile || (Nuts && CanUse(STICKS));});}}), Entrance(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}), }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp index 133cdc340..9f8effbcc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp @@ -54,17 +54,17 @@ void AreaTable_Init_DodongosCavern() { areaTable[DODONGOS_CAVERN_SE_CORRIDOR] = Area("Dodongos Cavern SE Corridor", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DODONGOS_CAVERN_GS_SCARECROW, {[]{return CanUse(SCARECROW) || (IsAdult && CanUse(LONGSHOT)) || (LogicDCScarecrowGS && (IsAdult || CanChildAttack));}}), + LocationAccess(DODONGOS_CAVERN_GS_SCARECROW, {[]{return CanUse(SCARECROW) || (IsAdult && CanUse(LONGSHOT)) || (LogicDCScarecrowGS && (CanAdultAttack || CanChildAttack));}}), }, { //Exits Entrance(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_SE_ROOM, {[]{return Here(DODONGOS_CAVERN_SE_CORRIDOR, []{return CanBlastOrSmash || IsAdult || CanChildAttack || (CanTakeDamage && CanShield);});}}), + Entrance(DODONGOS_CAVERN_SE_ROOM, {[]{return Here(DODONGOS_CAVERN_SE_CORRIDOR, []{return CanBlastOrSmash || CanAdultAttack || CanChildAttack || (CanTakeDamage && CanShield);});}}), Entrance(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return true;}}), }); areaTable[DODONGOS_CAVERN_SE_ROOM] = Area("Dodongos Cavern SE Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), @@ -78,8 +78,10 @@ void AreaTable_Init_DodongosCavern() { areaTable[DODONGOS_CAVERN_LOWER_LIZALFOS] = Area("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return IsAdult || Slingshot || Sticks || KokiriSword || HasExplosives;});}}), - Entrance(DODONGOS_CAVERN_DODONGO_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return IsAdult || Slingshot || Sticks || KokiriSword || HasExplosives;});}}), + Entrance(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || + CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), + Entrance(DODONGOS_CAVERN_DODONGO_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || + CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), }); areaTable[DODONGOS_CAVERN_DODONGO_ROOM] = Area("Dodongos Cavern Dodongo Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -119,7 +121,7 @@ void AreaTable_Init_DodongosCavern() { LocationAccess(DODONGOS_CAVERN_COMPASS_CHEST, {[]{return true;}}), }, { //Exits - Entrance(DODONGOS_CAVERN_STAIRS_LOWER, {[]{return IsAdult || HasExplosives || GoronBracelet;}}), + Entrance(DODONGOS_CAVERN_STAIRS_LOWER, {[]{return CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives || GoronBracelet;}}), }); areaTable[DODONGOS_CAVERN_ARMOS_ROOM] = Area("Dodongos Cavern Armos Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -156,8 +158,10 @@ void AreaTable_Init_DodongosCavern() { areaTable[DODONGOS_CAVERN_UPPER_LIZALFOS] = Area("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return IsAdult || Slingshot || Sticks || KokiriSword || HasExplosives;});}}), - Entrance(DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return IsAdult || Slingshot || Sticks || KokiriSword || HasExplosives;});}}), + Entrance(DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || + CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), + Entrance(DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || + CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), }); areaTable[DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Area("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -197,7 +201,7 @@ void AreaTable_Init_DodongosCavern() { areaTable[DODONGOS_CAVERN_BACK_ROOM] = Area("Dodongos Cavern Back Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DODONGOS_CAVERN_GS_BACK_ROOM, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(DODONGOS_CAVERN_GS_BACK_ROOM, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}), @@ -221,10 +225,10 @@ void AreaTable_Init_DodongosCavern() { }, { //Locations LocationAccess(DODONGOS_CAVERN_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(DODONGOS_CAVERN_MQ_COMPASS_CHEST, {[]{return IsAdult || CanChildAttack || Nuts;}}), + LocationAccess(DODONGOS_CAVERN_MQ_COMPASS_CHEST, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), LocationAccess(DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, {[]{return (IsChild && CanUse(STICKS)) || HasFireSource;}}), LocationAccess(DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, {[]{return CanBlastOrSmash || (IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE) || (IsAdult && (LogicDCJump || HoverBoots || Hookshot));}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, {[]{return CanPlay(SongOfTime) && (CanChildAttack || IsAdult);}}), + LocationAccess(DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, {[]{return CanPlay(SongOfTime) && (CanChildAttack || CanAdultAttack);}}), LocationAccess(DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, {[]{return (IsChild && CanUse(STICKS)) || HasFireSource;}}), LocationAccess(DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, {[]{return CanBlastOrSmash;}}), LocationAccess(DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, {[]{return CanStunDeku;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp index 887766fe5..2275b0b6a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp @@ -46,12 +46,12 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_LOOP_ENEMIES] = Area("Fire Temple Loop Enemies", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(FIRE_TEMPLE_FIRST_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 8) || !IsKeysanity;}}), - Entrance(FIRE_TEMPLE_LOOP_TILES, {[]{return Here(FIRE_TEMPLE_LOOP_ENEMIES, []{return IsAdult || KokiriSword;});}}), + Entrance(FIRE_TEMPLE_LOOP_TILES, {[]{return Here(FIRE_TEMPLE_LOOP_ENEMIES, []{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);});}}), }); areaTable[FIRE_TEMPLE_LOOP_TILES] = Area("Fire Temple Loop Tiles", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_GS_BOSS_KEY_LOOP, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(FIRE_TEMPLE_GS_BOSS_KEY_LOOP, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(FIRE_TEMPLE_LOOP_ENEMIES, {[]{return true;}}), @@ -64,7 +64,8 @@ void AreaTable_Init_FireTemple() { }, { //Exits Entrance(FIRE_TEMPLE_LOOP_TILES, {[]{return true;}}), - Entrance(FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return (HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT)) && (IsAdult || KokiriSword || Slingshot || Boomerang);});}}), + Entrance(FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || + CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(BOOMERANG)));});}}), }); areaTable[FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Area("Fire Temple Loop Hammer Switch", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { @@ -110,7 +111,7 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES] = Area("Fire Temple Big Lava Room North Tiles", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, {[]{return IsAdult;}}), + LocationAccess(FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, {[]{return CanAdultAttack || HookshotOrBoomerang;}}), }, { //Exits Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), @@ -149,7 +150,7 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Area("Fire Temple Boulder Maze Lower", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, {[]{return true;}}), - LocationAccess(FIRE_TEMPLE_GS_BOULDER_MAZE, {[]{return HasExplosives && (IsAdult || Boomerang || CanUse(HOOKSHOT));}}), + LocationAccess(FIRE_TEMPLE_GS_BOULDER_MAZE, {[]{return HasExplosives && (IsAdult || HookshotOrBoomerang);}}), }, { //Exits Entrance(FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), @@ -203,7 +204,7 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_SCARECROW_ROOM] = Area("Fire Temple Scarecrow Room", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_GS_SCARECROW_CLIMB, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(FIRE_TEMPLE_GS_SCARECROW_CLIMB, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE);}}), }, { //Exits Entrance(FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), @@ -276,8 +277,10 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_UPPER_FLARE_DANCER] = Area("Fire Temple Upper Flare Dancer", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return (HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT)) && (IsAdult || KokiriSword || Slingshot || Boomerang);});}}), - Entrance(FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return (HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT)) && (IsAdult || KokiriSword || Slingshot || Boomerang);});}}), + Entrance(FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && ((CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || + CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(BOOMERANG)));});}}), + Entrance(FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && ((CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || + CanUse(SLINGSHOT) || CanUse(BOOMERANG)));});}}), }); areaTable[FIRE_TEMPLE_WEST_CLIMB] = Area("Fire Temple West Climb", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -314,14 +317,14 @@ void AreaTable_Init_FireTemple() { if (Dungeon::FireTemple.IsMQ()) { areaTable[FIRE_TEMPLE_MQ_LOWER] = Area("Fire Temple MQ Lower", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, {[]{return IsAdult || KokiriSword || Sticks || Slingshot || Bombs || CanUse(DINS_FIRE);}}), + LocationAccess(FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || Bombs || CanUse(DINS_FIRE);}}), LocationAccess(FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, {[]{return IsAdult && (LogicFewerTunicRequirements || CanUse(GORON_TUNIC)) && (((CanUse(HOVER_BOOTS) || (LogicFireMQNearBoss && CanUse(BOW))) && HasFireSource) || (CanUse(HOOKSHOT) && CanUse(FIRE_ARROWS) || (CanUse(DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || CanUse(GORON_TUNIC) || CanUse(BOW) || CanUse(LONGSHOT)))));}}), //Trick: IsAdult && (LogicFewerTunicRequirements || CanUse(GORON_TUNIC)) && (((CanUse(HOVER_BOOTS) || (LogicFireMQNearBoss && CanUse(BOW))) && HasFireSource) || (CanUse(HOOKSHOT) && CanUse(FIRE_ARROWS) || (CanUse(DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || CanUse(GORON_TUNIC) || CanUse(BOW) || CanUse(LONGSHOT))))) }, { //Exits Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return IsAdult && CanUse(GORON_TUNIC) && CanUse(MEGATON_HAMMER) && BossKeyFireTemple && ((HasFireSource && (LogicFireBossDoorJump || HoverBoots)) || HasAccessTo(FIRE_TEMPLE_MQ_UPPER));}}), - Entrance(FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return SmallKeys(FIRE_TEMPLE, 5) && (IsAdult || KokiriSword);}}), + Entrance(FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return SmallKeys(FIRE_TEMPLE, 5) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), Entrance(FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return IsAdult && FireTimer >= 24 && CanUse(MEGATON_HAMMER);}}), }); @@ -330,7 +333,7 @@ void AreaTable_Init_FireTemple() { EventAccess(&FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, {[]{return IsAdult && (HasExplosives || Hammer || Hookshot);}}), + LocationAccess(FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, {[]{return IsAdult && (CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(BOOMERANG))));}}), LocationAccess(FIRE_TEMPLE_MQ_MAP_CHEST, {[]{return IsAdult && CanUse(MEGATON_HAMMER);}}), }, {}); @@ -353,7 +356,7 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_MQ_LOWER_MAZE] = Area("Fire Temple MQ Lower Maze", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, {[]{return true;}}), + LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, {[]{return CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD);}}), LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, {[]{return HasExplosives && (LogicFireMQMazeSideRoom || HasAccessTo(FIRE_TEMPLE_MQ_UPPER_MAZE));}}), //Trick: HasExplosives && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult()) }, { @@ -378,7 +381,7 @@ void AreaTable_Init_FireTemple() { areaTable[FIRE_TEMPLE_MQ_UPPER] = Area("Fire Temple MQ Upper", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_FREESTANDING_KEY, {[]{return (IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze;}}), + LocationAccess(FIRE_TEMPLE_MQ_FREESTANDING_KEY, {[]{return ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(SLINGSHOT) || CanUse(BOOMERANG)) && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze;}}), //Trick: (IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze LocationAccess(FIRE_TEMPLE_MQ_CHEST_ON_FIRE, {[]{return ((IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze) && SmallKeys(FIRE_TEMPLE, 4);}}), //Trick: ((IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze) && SmallKeys(FIRE_TEMPLE, 4) diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp index d4e95e15c..fea9fda6f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp @@ -34,7 +34,7 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_SOUTH_CORRIDOR] = Area("Forest Temple South Corridor", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_LOBBY, {[]{return IsAdult || CanChildAttack || Nuts;}}), + Entrance(FOREST_TEMPLE_LOBBY, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), }); areaTable[FOREST_TEMPLE_LOBBY] = Area("Forest Temple Lobby", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { @@ -66,7 +66,7 @@ void AreaTable_Init_ForestTemple() { EventAccess(&FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_FIRST_STALFOS_CHEST, {[]{return IsAdult || KokiriSword;}}), + LocationAccess(FOREST_TEMPLE_FIRST_STALFOS_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), }, { //Exits Entrance(FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), @@ -74,8 +74,8 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_NW_OUTDOORS_LOWER] = Area("Forest Temple NW Outdoors Lower", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, {[]{return CanUse(LONGSHOT) || Here(FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return HookshotOrBoomerang;});}}), @@ -90,8 +90,8 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_NW_OUTDOORS_UPPER] = Area("Forest Temple NW Outdoors Upper", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, {}, { //Exits Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), @@ -102,8 +102,8 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_NE_OUTDOORS_LOWER] = Area("Forest Temple NE Outdoors Lower", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, {[]{return CanUse(HOOKSHOT) || HasAccessTo(FOREST_TEMPLE_FALLING_ROOM) || (HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER) && IsAdult && LogicForestOutdoorsLedge && HoverBoots);}}), @@ -118,22 +118,22 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_NE_OUTDOORS_UPPER] = Area("Forest Temple NE Outdoors Upper", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, {}, { //Exits Entrance(FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), Entrance(FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return LogicForestDoorFrame && CanUse(HOVER_BOOTS) && CanUse(SCARECROW);}}), + Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return LogicForestDoorFrame && CanJumpslash && CanUse(HOVER_BOOTS) && CanUse(SCARECROW);}}), }); areaTable[FOREST_TEMPLE_MAP_ROOM] = Area("Forest Temple Map Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_MAP_CHEST, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((IsAdult || Sticks || KokiriSword || Slingshot) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + LocationAccess(FOREST_TEMPLE_MAP_CHEST, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), }, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((IsAdult || Sticks || KokiriSword || Slingshot) && (Nuts || HookshotOrBoomerang || CanShield));});}}), - Entrance(FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((IsAdult || Sticks || KokiriSword || Slingshot) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + Entrance(FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), }); areaTable[FOREST_TEMPLE_SEWER] = Area("Forest Temple Sewer", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -147,12 +147,12 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Area("Forest Temple Below Boss Key Chest", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((IsAdult || Sticks || KokiriSword || Slingshot) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), }); areaTable[FOREST_TEMPLE_FLOORMASTER_ROOM] = Area("Forest Temple Floormaster Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_FLOORMASTER_CHEST, {[]{return IsAdult || CanChildDamage;}}), + LocationAccess(FOREST_TEMPLE_FLOORMASTER_CHEST, {[]{return CanAdultDamage || CanChildDamage;}}), }, { //Exits Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return true;}}), @@ -161,7 +161,7 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_WEST_CORRIDOR] = Area("Forest Temple West Corridor", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(FOREST_TEMPLE_LOBBY, {[]{return SmallKeys(FOREST_TEMPLE, 1, 5);}}), - Entrance(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return IsAdult || CanChildAttack || Nuts;}}), + Entrance(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), }); areaTable[FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Area("Forest Temple Block Push Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -172,7 +172,7 @@ void AreaTable_Init_ForestTemple() { Entrance(FOREST_TEMPLE_WEST_CORRIDOR, {[]{return true;}}), Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return CanUse(HOVER_BOOTS) || (LogicForestOutsideBackdoor && CanJumpslash && GoronBracelet);}}), Entrance(FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return IsAdult && GoronBracelet && SmallKeys(FOREST_TEMPLE, 2);}}), - Entrance(FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, {[]{return CanUse(BOW) && GoronBracelet && SmallKeys(FOREST_TEMPLE, 2);}}), + Entrance(FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, {[]{return (CanUse(BOW) || CanUse(SLINGSHOT)) && GoronBracelet && SmallKeys(FOREST_TEMPLE, 2);}}), }); areaTable[FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Area("Forest Temple NW Corridor Twisted", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -204,11 +204,11 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_UPPER_STALFOS] = Area("Forest Temple Upper Stalfos", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_BOW_CHEST, {[]{return IsAdult || KokiriSword;}}), + LocationAccess(FOREST_TEMPLE_BOW_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), }, { //Exits - Entrance(FOREST_TEMPLE_RED_POE_ROOM, {[]{return IsAdult || KokiriSword;}}), - Entrance(FOREST_TEMPLE_BLUE_POE_ROOM, {[]{return IsAdult || KokiriSword;}}), + Entrance(FOREST_TEMPLE_RED_POE_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), + Entrance(FOREST_TEMPLE_BLUE_POE_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), }); areaTable[FOREST_TEMPLE_BLUE_POE_ROOM] = Area("Forest Temple Blue Poe Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { @@ -261,8 +261,8 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_EAST_CORRIDOR] = Area("Forest Temple East Corridor", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(FOREST_TEMPLE_LOBBY, {[]{return IsAdult || CanChildAttack || Nuts;}}), - Entrance(FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return IsAdult || CanChildAttack || Nuts;}}), + Entrance(FOREST_TEMPLE_LOBBY, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), + Entrance(FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), }); areaTable[FOREST_TEMPLE_BOSS_REGION] = Area("Forest Temple Boss Region", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -282,12 +282,12 @@ void AreaTable_Init_ForestTemple() { if (Dungeon::ForestTemple.IsMQ()) { areaTable[FOREST_TEMPLE_MQ_LOBBY] = Area("Forest Temple MQ Lobby", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, {[]{return IsAdult || Bombs || CanUse(STICKS) || Nuts || CanUse(BOOMERANG) || CanUse(DINS_FIRE) || KokiriSword || CanUse(SLINGSHOT);}}), + LocationAccess(FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, {[]{return CanJumpslash || Bombs || Nuts || HookshotOrBoomerang || CanUse(DINS_FIRE) || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(HOVER_BOOTS);}}), LocationAccess(FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, {[]{return HookshotOrBoomerang;}}), }, { //Exits Entrance(FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return SmallKeys(FOREST_TEMPLE, 1) && (IsAdult || CanChildAttack || Nuts);}}), + Entrance(FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return SmallKeys(FOREST_TEMPLE, 1) && (CanAdultAttack || CanChildAttack || Nuts);}}), }); areaTable[FOREST_TEMPLE_MQ_CENTRAL_AREA] = Area("Forest Temple MQ Central Area", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { @@ -295,12 +295,12 @@ void AreaTable_Init_ForestTemple() { EventAccess(&FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_WOLFOS_CHEST, {[]{return (CanPlay(SongOfTime) || IsChild) && (IsAdult || CanUse(DINS_FIRE) || CanUse(STICKS) || CanUse(SLINGSHOT) || KokiriSword);}}), - LocationAccess(FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, {[]{return IsAdult || KokiriSword;}}), + LocationAccess(FOREST_TEMPLE_MQ_WOLFOS_CHEST, {[]{return (CanPlay(SongOfTime) || IsChild) && (CanJumpslash || CanUse(DINS_FIRE) || CanUse(SLINGSHOT));}}), + LocationAccess(FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));}}), - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));}}), //This is as far as child can get + Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), + Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), //This is as far as child can get Entrance(FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return IsAdult && (GoronBracelet || (LogicForestMQBlockPuzzle && HasBombchus && IsAdult && CanUse(HOOKSHOT)));}}), //Trick: IsAdult && (GoronBracelet || (LogicForestMQBlockPuzzle && HasBombchus && IsAdult && CanUse(HOOKSHOT))) Entrance(FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (LogicForestMQHallwaySwitchJS && IsAdult && CanUse(HOVER_BOOTS)) || (LogicForestMQHallwaySwitchBoomerang && CanUse(BOOMERANG)) || (LogicForestMQHallwaySwitchHookshot && IsAdult && CanUse(HOOKSHOT));}}), @@ -321,7 +321,7 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_MQ_OUTDOOR_LEDGE] = Area("Forest Temple MQ Outdoor Ledge", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_REDEAD_CHEST, {[]{return true;}}), + LocationAccess(FOREST_TEMPLE_MQ_REDEAD_CHEST, {[]{return CanJumpslash;}}), }, { //Exits Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), @@ -329,7 +329,7 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_MQ_NW_OUTDOORS] = Area("Forest Temple MQ NW Outdoors", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, {[]{return true;}}), + LocationAccess(FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (IsAdult && (CanUse(IRON_BOOTS) || CanUse(LONGSHOT) || (LogicForestMQWellSwim && CanUse(HOOKSHOT)))) || ProgressiveScale >= 2;}}), @@ -339,8 +339,8 @@ void AreaTable_Init_ForestTemple() { areaTable[FOREST_TEMPLE_MQ_NE_OUTDOORS] = Area("Forest Temple MQ NE Outdoors", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (IsAdult || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), }, { //Locations LocationAccess(FOREST_TEMPLE_MQ_WELL_CHEST, {[]{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));}}), @@ -376,7 +376,7 @@ void AreaTable_Init_ForestTemple() { EventAccess(&ForestTempleJoAndBeth, {[]{return ForestTempleJoAndBeth || (IsAdult && CanUse(BOW));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_BOW_CHEST, {[]{return true;}}), + LocationAccess(FOREST_TEMPLE_MQ_BOW_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), LocationAccess(FOREST_TEMPLE_MQ_MAP_CHEST, {[]{return IsAdult && CanUse(BOW);}}), LocationAccess(FOREST_TEMPLE_MQ_COMPASS_CHEST, {[]{return IsAdult && CanUse(BOW);}}), }, { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp index ebb8625ec..fa6ab967b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp @@ -56,7 +56,7 @@ void AreaTable_Init_GanonsCastle() { EventAccess(&ForestTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (FireArrows || DinsFire);}}), }, { //Locations - LocationAccess(GANONS_CASTLE_FOREST_TRIAL_CHEST, {[]{return IsAdult || CanChildDamage;}}), + LocationAccess(GANONS_CASTLE_FOREST_TRIAL_CHEST, {[]{return CanAdultDamage || CanChildDamage;}}), }, {}); areaTable[GANONS_CASTLE_FIRE_TRIAL] = Area("Ganon's Castle Fire Trial", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { @@ -68,7 +68,7 @@ void AreaTable_Init_GanonsCastle() { //Events EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), EventAccess(&FairyPot, {[]{return FairyPot || BlueFire;}}), - EventAccess(&WaterTrialClear, {[]{return BlueFire && Hammer && CanUse(LIGHT_ARROWS);}}), + EventAccess(&WaterTrialClear, {[]{return BlueFire && IsAdult && CanUse(MEGATON_HAMMER) && CanUse(LIGHT_ARROWS);}}), }, { //Locations LocationAccess(GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, {[]{return true;}}), @@ -77,7 +77,7 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_SHADOW_TRIAL] = Area("Ganon's Castle Shadow Trial", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&ShadowTrialClear, {[]{return CanUse(LIGHT_ARROWS) && Hammer && ((FireArrows && (LogicLensCastle || CanUse(LENS_OF_TRUTH))) || (CanUse(LONGSHOT) && (CanUse(HOVER_BOOTS) || (DinsFire && (LogicLensCastle || CanUse(LENS_OF_TRUTH))))));}}), + EventAccess(&ShadowTrialClear, {[]{return CanUse(LIGHT_ARROWS) && CanUse(MEGATON_HAMMER) && ((FireArrows && (LogicLensCastle || CanUse(LENS_OF_TRUTH))) || (CanUse(LONGSHOT) && (CanUse(HOVER_BOOTS) || (DinsFire && (LogicLensCastle || CanUse(LENS_OF_TRUTH))))));}}), }, { //Locations LocationAccess(GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, {[]{return CanUse(FIRE_ARROWS) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || CanPlay(SongOfTime) || IsChild;}}), @@ -86,11 +86,11 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&NutPot, {[]{return NutPot || ((LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && HasBombchus && Bow && (MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS))) && IsAdult);}}), - EventAccess(&SpiritTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (MirrorShield || SunlightArrows) && HasBombchus && (LogicSpiritTrialHookshot || CanUse(HOOKSHOT));}}), + EventAccess(&NutPot, {[]{return NutPot || (((LogicSpiritTrialHookshot && CanJumpslash) || CanUse(HOOKSHOT)) && HasBombchus && CanUse(BOW) && (CanUse(MIRROR_SHIELD) || (SunlightArrows && CanUse(LIGHT_ARROWS))));}}), + EventAccess(&SpiritTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (CanUse(MIRROR_SHIELD) || SunlightArrows) && HasBombchus && ((LogicSpiritTrialHookshot && CanJumpslash) || CanUse(HOOKSHOT));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, {[]{return LogicSpiritTrialHookshot || CanUse(HOOKSHOT);}}), + LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, {[]{return (LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && CanJumpslash;}}), LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, {[]{return (LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && HasBombchus && (LogicLensCastle || CanUse(LENS_OF_TRUTH));}}), }, {}); @@ -112,9 +112,9 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_TOWER] = Area("Ganon's Castle Tower", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GANONS_TOWER_BOSS_KEY_CHEST, {[]{return true;}}), - LocationAccess(GANONDORF_HINT, {[]{return BossKeyGanonsCastle;}}), - LocationAccess(GANON, {[]{return BossKeyGanonsCastle && CanUse(LIGHT_ARROWS);}}), + LocationAccess(GANONS_TOWER_BOSS_KEY_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(GANONDORF_HINT, {[]{return BossKeyGanonsCastle && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), + LocationAccess(GANON, {[]{return BossKeyGanonsCastle && CanUse(LIGHT_ARROWS) && CanUse(MASTER_SWORD);}}), }, {}); /*--------------------------- @@ -123,7 +123,7 @@ void AreaTable_Init_GanonsCastle() { if (Dungeon::GanonsCastle.IsMQ()) { areaTable[GANONS_CASTLE_MQ_LOBBY] = Area("Ganon's Castle MQ Lobby", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(GANONS_CASTLE_ENTRYWAY, {[]{return (IsAdult || (HasExplosives || ((Nuts || Boomerang) && (Sticks || KokiriSword))));}}), + Entrance(GANONS_CASTLE_ENTRYWAY, {[]{return (CanUse(MASTER_SWORD) || (HasExplosives || ((Nuts || Boomerang) && (Sticks || KokiriSword))));}}), Entrance(GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}), Entrance(GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}), Entrance(GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}), @@ -153,12 +153,12 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_MQ_FOREST_TRIAL] = Area("Ganon's Castle MQ Forest Trial", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&ForestTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && CanPlay(SongOfTime);}}), + EventAccess(&ForestTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && CanPlay(SongOfTime);}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, {[]{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));}}), - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, {[]{return HasFireSource;}}), - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, {[]{return HookshotOrBoomerang;}}), + LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (CanUse(BOW) || CanUse(SLINGSHOT));}}), + LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HasFireSource;}}), + LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HookshotOrBoomerang;}}), }, {}); areaTable[GANONS_CASTLE_MQ_FIRE_TRIAL] = Area("Ganon's Castle MQ Fire Trial", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { @@ -170,10 +170,10 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_MQ_WATER_TRIAL] = Area("Ganon's Castle MQ Water Trial", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&WaterTrialClear, {[]{return BlueFire && IsAdult && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3);}}), - EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), + EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || (HasBottle && CanJumpslash);}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, {[]{return BlueFire && (IsAdult || CanUse(STICKS) || KokiriSword || CanUseProjectile);}}), + LocationAccess(GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, {[]{return BlueFire;}}), }, {}); areaTable[GANONS_CASTLE_MQ_SHADOW_TRIAL] = Area("Ganon's Castle MQ Shadow Trial", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { @@ -203,11 +203,11 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_MQ_LIGHT_TRIAL] = Area("Ganon's Castle MQ Light Trial", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&LightTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (Hookshot || LogicLightTrialMQ);}}), + EventAccess(&LightTrialClear, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD)) && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (Hookshot || LogicLightTrialMQ);}}), //Trick: IsAdult && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (Hookshot || LogicLightTrialMQ) }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, {[]{return CanPlay(ZeldasLullaby);}}), + LocationAccess(GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, {[]{return (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD)) && CanPlay(ZeldasLullaby);}}), }, {}); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp index 77cf0a4e2..93ffca145 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp @@ -25,13 +25,13 @@ void AreaTable_Init_GerudoTrainingGrounds() { //Locations LocationAccess(GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), LocationAccess(GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, {[]{return IsAdult || KokiriSword;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, {[]{return HasExplosives && (IsAdult || KokiriSword);}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, {[]{return HasExplosives && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), }, { //Exits Entrance(GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (IsAdult || KokiriSword) && (CanUse(HOOKSHOT) || LogicGtgWithoutHookshot);}}), - Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(GERUDO_TRAINING_GROUNDS_LOBBY, []{return (IsAdult || KokiriSword) && HasExplosives;});}}), + Entrance(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (CanUse(HOOKSHOT) || LogicGtgWithoutHookshot);}}), + Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(GERUDO_TRAINING_GROUNDS_LOBBY, []{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HasExplosives;});}}), Entrance(GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, {[]{return true;}}), }); @@ -69,11 +69,11 @@ void AreaTable_Init_GerudoTrainingGrounds() { areaTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM] = Area("Gerudo Training Grounds Hammer Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, {[]{return true;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), LocationAccess(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST, {[]{return CanUse(MEGATON_HAMMER) || (CanTakeDamage && LogicFlamingChests);}}), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return CanUse(MEGATON_HAMMER) && Bow;}}), + Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return CanUse(MEGATON_HAMMER) && CanUse(BOW);}}), Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), }); @@ -95,7 +95,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { areaTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM] = Area("Gerudo Training Grounds Heavy Block Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, {[]{return true;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, {[]{return CanJumpslash;}}), }, { //Exits Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, {[]{return (LogicLensGtg || CanUse(LENS_OF_TRUTH)) && (CanUse(HOOKSHOT) || (LogicGtgFakeWall && CanUse(HOVER_BOOTS)));}}), @@ -104,10 +104,10 @@ void AreaTable_Init_GerudoTrainingGrounds() { areaTable[GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM] = Area("Gerudo Training Grounds Like Like Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, {[]{return true;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, {[]{return CanJumpslash;}}), }, {}); } @@ -135,10 +135,10 @@ void AreaTable_Init_GerudoTrainingGrounds() { //EventAccess(&WallFairy, {[]{return WallFairy || (IsAdult && CanUse(BOW));}}), }, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, {[]{return IsAdult;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (Bow || CanUse(LONGSHOT)) && CanUse(HOVER_BOOTS) && IsAdult;}}), + Entrance(GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (Bow || (CanUse(LONGSHOT) && HasFireSource)) && CanUse(HOVER_BOOTS) && IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), }); areaTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER] = Area("Gerudo Training Grounds MQ Underwater", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { @@ -148,7 +148,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { areaTable[GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE] = Area("Gerudo Training Grounds MQ Left Side", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, {[]{return IsAdult || KokiriSword || HasExplosives;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || HasExplosives;}}), }, { //Exits Entrance(GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (IsAdult && CanUse(LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && IsAdult && CanUse(HOOKSHOT));}}), @@ -160,8 +160,8 @@ void AreaTable_Init_GerudoTrainingGrounds() { EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), }, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, {[]{return IsAdult;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, {[]{return CanUse(SILVER_GAUNTLETS);}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, {[]{return CanUse(SILVER_GAUNTLETS) && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), }, { //Exits Entrance(GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return IsAdult && (LogicLensGtgMQ || CanUse(LENS_OF_TRUTH)) && BlueFire && (CanPlay(SongOfTime) || (LogicGtgFakeWall && IsAdult && CanUse(HOVER_BOOTS)));}}), @@ -170,12 +170,12 @@ void AreaTable_Init_GerudoTrainingGrounds() { areaTable[GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS] = Area("Gerudo Training Grounds MQ Back Areas", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, {[]{return Bow;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, {[]{return CanUse(HOOKSHOT) || Bow || HasExplosives;}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, {[]{return CanUse(BOW);}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, {[]{return (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), + LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, {[]{return CanUse(HOOKSHOT) || CanUse(BOW) || HasExplosives;}}), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return Hammer;}}), + Entrance(GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return CanUse(MEGATON_HAMMER);}}), Entrance(GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return CanUse(LONGSHOT);}}), }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index 70fd1f22b..f7b1c95af 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -104,13 +104,13 @@ void AreaTable_Init_GerudoValley() { LocationAccess(GF_CHEST, {[]{return CanUse(HOVER_BOOTS) || (IsAdult && CanUse(SCARECROW)) || CanUse(LONGSHOT);}}), LocationAccess(GF_HBA_1000_POINTS, {[]{return GerudoToken && CanRideEpona && Bow && AtDay;}}), LocationAccess(GF_HBA_1500_POINTS, {[]{return GerudoToken && CanRideEpona && Bow && AtDay;}}), - LocationAccess(GF_NORTH_F1_CARPENTER, {[]{return IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GF_NORTH_F2_CARPENTER, {[]{return (IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen);}}), - LocationAccess(GF_SOUTH_F1_CARPENTER, {[]{return IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GF_SOUTH_F2_CARPENTER, {[]{return IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(GF_NORTH_F1_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(GF_NORTH_F2_CARPENTER, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen);}}), + LocationAccess(GF_SOUTH_F1_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(GF_SOUTH_F2_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), LocationAccess(GF_GERUDO_MEMBERSHIP_CARD, {[]{return CanFinishGerudoFortress;}}), LocationAccess(GF_GS_ARCHERY_RANGE, {[]{return IsAdult && HookshotOrBoomerang && GerudoToken && AtNight && CanGetNightTimeGS;}}), - LocationAccess(GF_GS_TOP_FLOOR, {[]{return IsAdult && AtNight && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen || LogicGFJump) && CanGetNightTimeGS;}}), + LocationAccess(GF_GS_TOP_FLOOR, {[]{return IsAdult && AtNight && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen || LogicGFJump) && CanGetNightTimeGS;}}), }, { //Exits Entrance(GV_FORTRESS_SIDE, {[]{return true;}}), @@ -149,7 +149,7 @@ void AreaTable_Init_GerudoValley() { }, { //Locations LocationAccess(WASTELAND_CHEST, {[]{return HasFireSource;}}), - LocationAccess(WASTELAND_BOMBCHU_SALESMAN, {[]{return AdultsWallet && (IsAdult || Sticks || KokiriSword);}}), + LocationAccess(WASTELAND_BOMBCHU_SALESMAN, {[]{return AdultsWallet && (CanJumpslash || CanUse(HOVER_BOOTS)) ;}}), LocationAccess(WASTELAND_GS, {[]{return HookshotOrBoomerang;}}), }, { //Exits @@ -172,7 +172,7 @@ void AreaTable_Init_GerudoValley() { LocationAccess(COLOSSUS_FREESTANDING_POH, {[]{return IsAdult && CanPlantBean(DESERT_COLOSSUS);}}), LocationAccess(COLOSSUS_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), LocationAccess(COLOSSUS_GS_TREE, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(COLOSSUS_GS_HILL, {[]{return IsAdult && AtNight && (CanPlantBean(DESERT_COLOSSUS) || CanUse(LONGSHOT) || (LogicColossusGS && CanUse(HOOKSHOT))) && CanGetNightTimeGS;}}), + LocationAccess(COLOSSUS_GS_HILL, {[]{return IsAdult && AtNight && ((CanPlantBean(DESERT_COLOSSUS) && CanAdultAttack) || CanUse(LONGSHOT) || (LogicColossusGS && CanUse(HOOKSHOT))) && CanGetNightTimeGS;}}), LocationAccess(COLOSSUS_GOSSIP_STONE, {[]{return true;}}), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 7b247049d..50a0c340e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -115,7 +115,7 @@ void AreaTable_Init_HyruleField() { LocationAccess(LH_SUN, {[]{return IsAdult && WaterTempleClear && CanUse(BOW);}}), LocationAccess(LH_FREESTANDING_POH, {[]{return IsAdult && (CanUse(SCARECROW) || CanPlantBean(LAKE_HYLIA));}}), LocationAccess(LH_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(LH_GS_LAB_WALL, {[]{return IsChild && (HookshotOrBoomerang || (LogicLabWallGS && (Sticks || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)))) && AtNight && CanGetNightTimeGS;}}), + LocationAccess(LH_GS_LAB_WALL, {[]{return IsChild && (HookshotOrBoomerang || (LogicLabWallGS && CanJumpslash)) && AtNight && CanGetNightTimeGS;}}), LocationAccess(LH_GS_SMALL_ISLAND, {[]{return IsChild && CanChildAttack && AtNight && CanGetNightTimeGS;}}), LocationAccess(LH_GS_TREE, {[]{return IsAdult && CanUse(LONGSHOT) && AtNight && CanGetNightTimeGS;}}), LocationAccess(LH_LAB_GOSSIP_STONE, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp index f5efcc3c8..551cfc978 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp @@ -13,7 +13,7 @@ void AreaTable_Init_IceCavern() { areaTable[ICE_CAVERN_ENTRYWAY] = Area("Ice Cavern Entryway", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(ICE_CAVERN_BEGINNING, {[]{return Dungeon::IceCavern.IsVanilla();}}), - Entrance(ICE_CAVERN_MQ_BEGINNING, {[]{return Dungeon::IceCavern.IsMQ();}}), + Entrance(ICE_CAVERN_MQ_BEGINNING, {[]{return Dungeon::IceCavern.IsMQ() && CanUseProjectile;}}), Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), }); @@ -24,7 +24,7 @@ void AreaTable_Init_IceCavern() { areaTable[ICE_CAVERN_BEGINNING] = Area("Ice Cavern Beginning", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(ICE_CAVERN_MAIN, {[]{return Here(ICE_CAVERN_BEGINNING, []{return IsAdult || HasExplosives || CanUse(DINS_FIRE);});}}), + Entrance(ICE_CAVERN_MAIN, {[]{return Here(ICE_CAVERN_BEGINNING, []{return (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD)) || HasExplosives || CanUse(DINS_FIRE);});}}), }); areaTable[ICE_CAVERN_MAIN] = Area("Ice Cavern", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { @@ -34,8 +34,8 @@ void AreaTable_Init_IceCavern() { //Locations LocationAccess(ICE_CAVERN_MAP_CHEST, {[]{return BlueFire && IsAdult;}}), LocationAccess(ICE_CAVERN_COMPASS_CHEST, {[]{return BlueFire;}}), - LocationAccess(ICE_CAVERN_IRON_BOOTS_CHEST, {[]{return BlueFire && (IsAdult || Slingshot || Sticks || KokiriSword || CanUse(DINS_FIRE));}}), - LocationAccess(SHEIK_IN_ICE_CAVERN, {[]{return BlueFire && IsAdult;}}), + LocationAccess(ICE_CAVERN_IRON_BOOTS_CHEST, {[]{return BlueFire && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || CanUse(DINS_FIRE));}}), + LocationAccess(SHEIK_IN_ICE_CAVERN, {[]{return BlueFire && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || CanUse(DINS_FIRE)) && IsAdult;}}), LocationAccess(ICE_CAVERN_FREESTANDING_POH, {[]{return BlueFire;}}), LocationAccess(ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, {[]{return HookshotOrBoomerang;}}), LocationAccess(ICE_CAVERN_GS_HEART_PIECE_ROOM, {[]{return BlueFire && HookshotOrBoomerang;}}), @@ -53,24 +53,24 @@ void AreaTable_Init_IceCavern() { }, {}, { //Exits Entrance(ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(ICE_CAVERN_MQ_MAP_ROOM, {[]{return IsAdult || CanUse(DINS_FIRE) || (HasExplosives && (CanUse(STICKS) || CanUse(SLINGSHOT) || KokiriSword));}}), + Entrance(ICE_CAVERN_MQ_MAP_ROOM, {[]{return CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(DINS_FIRE) || (HasExplosives && (CanUse(STICKS) || CanUse(SLINGSHOT) || CanUse(BOW)));}}), Entrance(ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return IsAdult && BlueFire;}}), Entrance(ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return BlueFire;}}), }); areaTable[ICE_CAVERN_MQ_MAP_ROOM] = Area("Ice Cavern MQ Map Room", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), + EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || (HasBottle && CanJumpslash);}}), }, { //Locations - LocationAccess(ICE_CAVERN_MQ_MAP_CHEST, {[]{return BlueFire && (IsAdult || CanUse(STICKS) || KokiriSword || CanUseProjectile);}}), + LocationAccess(ICE_CAVERN_MQ_MAP_CHEST, {[]{return BlueFire && (CanJumpslash || CanUseProjectile);}}), }, {}); areaTable[ICE_CAVERN_MQ_IRON_BOOTS_REGION] = Area("Ice Cavern MQ Iron Boots Region", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(ICE_CAVERN_MQ_IRON_BOOTS_CHEST, {[]{return IsAdult;}}), + LocationAccess(ICE_CAVERN_MQ_IRON_BOOTS_CHEST, {[]{return IsAdult && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) ;}}), LocationAccess(SHEIK_IN_ICE_CAVERN, {[]{return IsAdult;}}), - LocationAccess(ICE_CAVERN_MQ_GS_ICE_BLOCK, {[]{return IsAdult || CanUseProjectile;}}), + LocationAccess(ICE_CAVERN_MQ_GS_ICE_BLOCK, {[]{return (IsAdult && CanJumpslash) || CanUseProjectile;}}), LocationAccess(ICE_CAVERN_MQ_GS_SCARECROW, {[]{return (CanUse(SCARECROW) || (HoverBoots && CanUse(LONGSHOT)) || LogicIceMQScarecrow) && IsAdult;}}), //Tricks: (CanUse(SCARECROW) || (HoverBoots && CanUse(LONGSHOT)) || LogicIceMQScarecrow) && IsAdult }, {}); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp index d7b48d7f1..108b69ccc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp @@ -111,7 +111,7 @@ void AreaTable_Init_JabuJabusBelly() { areaTable[JABU_JABUS_BELLY_COMPASS_ROOM] = Area("Jabu Jabus Belly Compass Room", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(JABU_JABUS_BELLY_COMPASS_CHEST, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(JABU_JABUS_BELLY_COMPASS_CHEST, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), @@ -150,7 +150,7 @@ void AreaTable_Init_JabuJabusBelly() { areaTable[JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Area("Jabu Jabus Belly Near Boss Room", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(JABU_JABUS_BELLY_GS_NEAR_BOSS, {[]{return IsAdult || CanChildAttack;}}), + LocationAccess(JABU_JABUS_BELLY_GS_NEAR_BOSS, {[]{return CanAdultAttack || CanChildAttack;}}), }, { //Exits Entrance(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), 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 db9bb69dc..55af16208 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -184,7 +184,7 @@ void AreaTable_Init_Kakariko() { areaTable[KAK_REDEAD_GROTTO] = Area("Kak Redead Grotto", "Kak Redead Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_REDEAD_GROTTO_CHEST, {[]{return IsAdult || (Sticks || KokiriSword || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), + LocationAccess(KAK_REDEAD_GROTTO_CHEST, {[]{return CanUse(STICKS) || CanUse(KOKIRI_SWORD) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), }, { //Exits Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), @@ -241,7 +241,7 @@ void AreaTable_Init_Kakariko() { areaTable[GRAVEYARD_COMPOSERS_GRAVE] = Area("Graveyard Composers Grave", "Graveyard Composers Grave", NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(GRAVEYARD_COMPOSERS_GRAVE_CHEST, {[]{return HasFireSource;}}), - LocationAccess(SONG_FROM_COMPOSERS_GRAVE, {[]{return IsAdult || (Slingshot || Boomerang || Sticks || HasExplosives || KokiriSword || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOW) || CanUse(HOOKSHOT));}}), + LocationAccess(SONG_FROM_COMPOSERS_GRAVE, {[]{return CanUseProjectile || CanJumpslash || CanUse(MEGATON_HAMMER);}}), }, { //Exits Entrance(THE_GRAVEYARD, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index 1ba2048a0..c16468d24 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp @@ -34,8 +34,8 @@ void AreaTable_Init_LostWoods() { areaTable[KF_OUTSIDE_DEKU_TREE] = Area("KF Outside Deku Tree", "Kokiri Forest", KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || ((IsAdult && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF)) || KokiriSword || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || ((IsAdult && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF)) || KokiriSword || Slingshot || Sticks || HasExplosives || CanUse(DINS_FIRE));}}), + EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || ((IsAdult && (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(KOKIRI_SWORD)) && !ShuffleEntrances) || (IsChild && (CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MASTER_SWORD) || CanUse(BOOMERANG))));}}), + EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || ((IsAdult && (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(KOKIRI_SWORD)) && !ShuffleEntrances) || (IsChild && (CanJumpslash || CanUse(SLINGSHOT) || HasExplosives || CanUse(DINS_FIRE))));}}), EventAccess(&ShowedMidoSwordAndShield, {[]{return ShowedMidoSwordAndShield || (IsChild && KokiriSword && DekuShield);}}), }, { //Locations @@ -144,7 +144,7 @@ void AreaTable_Init_LostWoods() { //Locations LocationAccess(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, {[]{return IsChild && CanStunDeku;}}), LocationAccess(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, {[]{return IsChild && CanStunDeku;}}), - LocationAccess(LW_GS_ABOVE_THEATER, {[]{return IsAdult && AtNight && (CanPlantBean(LW_BEYOND_MIDO) || (LogicLostWoodsGSBean && CanUse(HOOKSHOT) && (CanUse(LONGSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || HasBombchus || CanUse(DINS_FIRE)))) && CanGetNightTimeGS;}}), + LocationAccess(LW_GS_ABOVE_THEATER, {[]{return IsAdult && AtNight && ((CanPlantBean(LW_BEYOND_MIDO) && CanAdultAttack) || (LogicLostWoodsGSBean && CanUse(HOOKSHOT) && (CanUse(LONGSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || HasBombchus || CanUse(DINS_FIRE)))) && CanGetNightTimeGS;}}), LocationAccess(LW_GS_BEAN_PATCH_NEAR_THEATER, {[]{return CanPlantBugs && (CanChildAttack || (Scrubsanity.Is(SCRUBSANITY_OFF) && DekuShield));}}), }, { //Exits @@ -185,7 +185,7 @@ void AreaTable_Init_LostWoods() { areaTable[SFM_ENTRYWAY] = Area("SFM Entryway", "Sacred Forest Meadow", SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(LW_BEYOND_MIDO, {[]{return true;}}), - Entrance(SACRED_FOREST_MEADOW, {[]{return IsAdult || Slingshot || Sticks || KokiriSword || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + Entrance(SACRED_FOREST_MEADOW, {[]{return IsAdult || CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER);}}), Entrance(SFM_WOLFOS_GROTTO, {[]{return CanOpenBombGrotto;}}), }); @@ -218,7 +218,7 @@ void AreaTable_Init_LostWoods() { areaTable[SFM_WOLFOS_GROTTO] = Area("SFM Wolfos Grotto", "SFM Wolfos Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SFM_WOLFOS_GROTTO_CHEST, {[]{return IsAdult || Slingshot || Sticks || KokiriSword || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + LocationAccess(SFM_WOLFOS_GROTTO_CHEST, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER);}}), }, { //Exits Entrance(SFM_ENTRYWAY, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp index 5296a6398..a3dda7521 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp @@ -26,12 +26,12 @@ void AreaTable_Init_ShadowTemple() { EventAccess(&NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(SHADOW_TEMPLE_MAP_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_HOVER_BOOTS_CHEST, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_MAP_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(SHADOW_TEMPLE_HOVER_BOOTS_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), }, { //Exits Entrance(SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(SHADOW_TEMPLE_FIRST_BEAMOS, {[]{return HoverBoots;}}), + Entrance(SHADOW_TEMPLE_FIRST_BEAMOS, {[]{return CanUse(HOVER_BOOTS);}}), }); areaTable[SHADOW_TEMPLE_FIRST_BEAMOS] = Area("Shadow Temple First Beamos", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { @@ -39,7 +39,7 @@ void AreaTable_Init_ShadowTemple() { EventAccess(&FairyPot, {[]{return true;}}), //This fairy pot is only on 3DS }, { //Locations - LocationAccess(SHADOW_TEMPLE_COMPASS_CHEST, {[]{return IsAdult || KokiriSword || Sticks;}}), + LocationAccess(SHADOW_TEMPLE_COMPASS_CHEST, {[]{return CanJumpslash;}}), LocationAccess(SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, {[]{return CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT);}}), LocationAccess(SHADOW_TEMPLE_GS_NEAR_SHIP, {[]{return false;}}), }, { @@ -50,14 +50,14 @@ void AreaTable_Init_ShadowTemple() { areaTable[SHADOW_TEMPLE_HUGE_PIT] = Area("Shadow Temple Huge Pit", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, {[]{return CanJumpslash;}}), LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, {[]{return true;}}), LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), LocationAccess(SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH));}}), LocationAccess(SHADOW_TEMPLE_FREESTANDING_KEY, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH)) && Hookshot && (Bombs || GoronBracelet || (LogicShadowFreestandingKey && HasBombchus));}}), - LocationAccess(SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, {[]{return CanJumpslash;}}), LocationAccess(SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, {[]{return Hookshot || (LogicShadowUmbrellaGS && HoverBoots);}}), LocationAccess(SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH)) && Hookshot;}}), }, { @@ -68,20 +68,20 @@ void AreaTable_Init_ShadowTemple() { areaTable[SHADOW_TEMPLE_WIND_TUNNEL] = Area("Shadow Temple Wind Tunnel", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(SHADOW_TEMPLE_WIND_HINT_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, {[]{return CanJumpslash;}}), LocationAccess(SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, {[]{return true;}}), LocationAccess(SHADOW_TEMPLE_GS_NEAR_SHIP, {[]{return CanUse(LONGSHOT) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}), }, { //Exits - Entrance(SHADOW_TEMPLE_BEYOND_BOAT, {[]{return CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}), + Entrance(SHADOW_TEMPLE_BEYOND_BOAT, {[]{return CanJumpslash && CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}), }); areaTable[SHADOW_TEMPLE_BEYOND_BOAT] = Area("Shadow Temple Beyond Boat", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, {[]{return CanUse(DINS_FIRE);}}), LocationAccess(SHADOW_TEMPLE_BOSS_KEY_CHEST, {[]{return CanUse(DINS_FIRE);}}), - LocationAccess(SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, {[]{return CanAdultAttack;}}), }, { //Exits Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (CanUse(BOW) || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus)) && SmallKeys(SHADOW_TEMPLE, 5) && CanUse(HOVER_BOOTS) && BossKeyShadowTemple;}}) @@ -102,15 +102,15 @@ void AreaTable_Init_ShadowTemple() { areaTable[SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Area("Shadow Temple MQ Dead Hand Area", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SHADOW_TEMPLE_MQ_COMPASS_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, {[]{return CanPlay(SongOfTime) && IsAdult && CanUse(BOW);}}), + LocationAccess(SHADOW_TEMPLE_MQ_COMPASS_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, {[]{return CanJumpslash && CanPlay(SongOfTime) && IsAdult && CanUse(BOW);}}), }, {}); areaTable[SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Area("Shadow Temple MQ First Beamos", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SHADOW_TEMPLE_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_MQ_MAP_CHEST, {[]{return CanAdultAttack || Nuts;}}), + LocationAccess(SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, {[]{return CanJumpslash;}}), + LocationAccess(SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, {[]{return CanAdultAttack || Nuts;}}), }, { //Exits Entrance(SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return HasExplosives && SmallKeys(SHADOW_TEMPLE, 2);}}), @@ -134,8 +134,9 @@ void AreaTable_Init_ShadowTemple() { LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, {[]{return true;}}), LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), - LocationAccess(SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, {[]{return HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && ((LogicLensShadowMQ && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, {[]{return HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && Hookshot && ((LogicLensShadowMQ && LogicLensShadowMQInvisibleBlades && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), + LocationAccess(SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, {[]{return CanJumpslash && HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && ((LogicLensShadowMQ && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), + LocationAccess(SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && Hookshot && ((LogicLensShadowMQ && + LogicLensShadowMQInvisibleBlades && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), LocationAccess(SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, {[]{return Hookshot || (LogicShadowUmbrellaGS && HoverBoots);}}), }, { //Exits @@ -148,7 +149,7 @@ void AreaTable_Init_ShadowTemple() { }, { //Locations LocationAccess(SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, {[]{return true;}}), + LocationAccess(SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, {[]{return CanJumpslash;}}), LocationAccess(SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, {[]{return true;}}), LocationAccess(SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, {[]{return true;}}), LocationAccess(SHADOW_TEMPLE_MQ_GS_AFTER_WIND, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp index ec01cdbfd..2aa0c0516 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp @@ -46,9 +46,9 @@ void AreaTable_Init_SpiritTemple() { LocationAccess(SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, {[]{return HasProjectile(HasProjectileAge::Both) || ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && HasProjectile(HasProjectileAge::Adult)) || (SmallKeys(SPIRIT_TEMPLE, 5) && IsChild && HasProjectile(HasProjectileAge::Child));}}), LocationAccess(SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, {[]{return HasProjectile(HasProjectileAge::Both) || ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && HasProjectile(HasProjectileAge::Adult)) || (SmallKeys(SPIRIT_TEMPLE, 5) && IsChild && HasProjectile(HasProjectileAge::Child));}}), LocationAccess(SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, {[]{return HasProjectile(HasProjectileAge::Both) || CanUse(DINS_FIRE) || - (CanTakeDamage && (Sticks || KokiriSword || HasProjectile(HasProjectileAge::Child))) || + (CanTakeDamage && (CanJumpslash || HasProjectile(HasProjectileAge::Child))) || (IsChild && SmallKeys(SPIRIT_TEMPLE, 5) && HasProjectile(HasProjectileAge::Child)) || - ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && (HasProjectile(HasProjectileAge::Adult) || CanTakeDamage));}}), + ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && (HasProjectile(HasProjectileAge::Adult) || (CanTakeDamage && CanJumpslash)));}}), }, { //Exits Entrance(SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return HasExplosives || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), @@ -57,7 +57,7 @@ void AreaTable_Init_SpiritTemple() { areaTable[SPIRIT_TEMPLE_EARLY_ADULT] = Area("Early Adult Spirit Temple", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(SPIRIT_TEMPLE_COMPASS_CHEST, {[]{return CanUse(HOOKSHOT) && CanPlay(ZeldasLullaby);}}), - LocationAccess(SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, {[]{return Bow || Hookshot || HasBombchus || (Bombs && LogicSpiritLowerAdultSwitch);}}), + LocationAccess(SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, {[]{return (CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasBombchus || (Bombs && IsAdult && LogicSpiritLowerAdultSwitch)) && (CanUse(HOVER_BOOTS) || CanJumpslash);}}), LocationAccess(SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3);}}), LocationAccess(SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3);}}), LocationAccess(SPIRIT_TEMPLE_GS_BOULDER_ROOM, {[]{return CanPlay(SongOfTime) && (Bow || Hookshot || HasBombchus || (Bombs && LogicSpiritLowerAdultSwitch));}}), @@ -98,7 +98,7 @@ void AreaTable_Init_SpiritTemple() { (SmallKeys(SPIRIT_TEMPLE, 3) && CanUse(SILVER_GAUNTLETS) && (Hookshot || HoverBoots || LogicSpiritLobbyJump));}}), }, { //Exits - Entrance(SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return true;}}), + Entrance(SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return CanJumpslash || HasExplosives;}}), Entrance(SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, {[]{return SmallKeys(SPIRIT_TEMPLE, 4) && CanUse(SILVER_GAUNTLETS);}}), Entrance(SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return true;}}), }); @@ -125,7 +125,7 @@ void AreaTable_Init_SpiritTemple() { areaTable[SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(SPIRIT_TEMPLE_BOSS_KEY_CHEST, {[]{return CanPlay(ZeldasLullaby) && ((CanTakeDamage && LogicFlamingChests) || (Bow && Hookshot));}}), - LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), + LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return (MirrorShield && CanAdultAttack) || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), }, { //Exits Entrance(SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return MirrorShield && HasExplosives && Hookshot;}}), @@ -174,7 +174,7 @@ void AreaTable_Init_SpiritTemple() { areaTable[SPIRIT_TEMPLE_MQ_ADULT] = Area("Spirit Temple MQ Adult", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LocationAccess(SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 7);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, {[]{return CanPlay(ZeldasLullaby);}}), + LocationAccess(SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, {[]{return CanPlay(ZeldasLullaby) && (CanJumpslash || CanUse(HOVER_BOOTS));}}), LocationAccess(SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, {[]{return (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH));}}), LocationAccess(SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 5);}}), LocationAccess(SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime);}}), @@ -187,7 +187,7 @@ void AreaTable_Init_SpiritTemple() { //Trick: MirrorShield && IsAdult && (CanUse(FIRE_ARROWS) || (LogicSpiritMQLowerAdult && CanUse(DINS_FIRE) && Bow)) Entrance(SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}), Entrance(SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return SmallKeys(SPIRIT_TEMPLE, 6) && CanPlay(ZeldasLullaby) && Hammer;}}), - Entrance(SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH));}}), + Entrance(SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH));}}), }); areaTable[SPIRIT_TEMPLE_MQ_SHARED] = Area("Spirit Temple MQ Shared", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -200,9 +200,9 @@ void AreaTable_Init_SpiritTemple() { //Trick: (LogicSpiritMQSunBlockGS && Boomerang && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT)) || IsAdult }, { //Exits - Entrance(SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)));}}), + Entrance(SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)));}}), //Trick: (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH))) - Entrance(DESERT_COLOSSUS, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)) && IsAdult);}}), + Entrance(DESERT_COLOSSUS, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)) && IsAdult);}}), //Trick: (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)) && IsAdult) }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp index 79d9dff7c..559b6c20c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp @@ -122,7 +122,7 @@ void AreaTable_Init_WaterTemple() { areaTable[WATER_TEMPLE_SOUTH_LOWER] = Area("Water Temple South Lower", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(WATER_TEMPLE_GS_BEHIND_GATE, {[]{return CanUse(HOOKSHOT) || (IsAdult && CanUse(HOVER_BOOTS));}}), + LocationAccess(WATER_TEMPLE_GS_BEHIND_GATE, {[]{return (CanJumpslash || CanUse(MEGATON_HAMMER)) && (CanUse(HOOKSHOT) || (IsAdult && CanUse(HOVER_BOOTS)));}}), }, { //Exits Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(IRON_BOOTS);}}), @@ -131,7 +131,7 @@ void AreaTable_Init_WaterTemple() { areaTable[WATER_TEMPLE_WEST_LOWER] = Area("Water Temple West Lower", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(HOOKSHOT) && CanUse(IRON_BOOTS) && GoronBracelet;}}), - Entrance(WATER_TEMPLE_DRAGON_ROOM, {[]{return IsAdult || CanChildAttack;}}), + Entrance(WATER_TEMPLE_DRAGON_ROOM, {[]{return CanJumpslash || CanUseProjectile;}}), }); areaTable[WATER_TEMPLE_DRAGON_ROOM] = Area("Water Temple Dragon Room", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -257,8 +257,8 @@ void AreaTable_Init_WaterTemple() { //Exits Entrance(WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(WATER_TEMPLE_MQ_DIVE, {[]{return IsAdult && WaterTimer >= 24 && CanUse(IRON_BOOTS);}}), - Entrance(WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return SmallKeys(WATER_TEMPLE, 1) && IsAdult && CanUse(LONGSHOT);}}), - Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple && IsAdult && CanUse(LONGSHOT);}}), + Entrance(WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return SmallKeys(WATER_TEMPLE, 1) && IsAdult && CanUse(LONGSHOT) && CanJumpslash && Hearts > 0;}}), + Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple && IsAdult && CanJumpslash && CanUse(LONGSHOT);}}), }); areaTable[WATER_TEMPLE_MQ_DIVE] = Area("Water Temple MQ Dive", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { @@ -273,7 +273,8 @@ void AreaTable_Init_WaterTemple() { areaTable[WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Area("Water Temple MQ Lowered Water Levels", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(WATER_TEMPLE_MQ_COMPASS_CHEST, {[]{return (IsAdult && CanUse(BOW)) || CanUse(DINS_FIRE) || Here(WATER_TEMPLE_MQ_LOBBY, []{return IsChild && CanUse(STICKS) && HasExplosives;});}}), + LocationAccess(WATER_TEMPLE_MQ_COMPASS_CHEST, {[]{return ((IsAdult && CanUse(BOW)) || CanUse(DINS_FIRE) || Here(WATER_TEMPLE_MQ_LOBBY, []{return IsChild && CanUse(STICKS) && HasExplosives;})) && + (CanJumpslash || CanUseProjectile);}}), LocationAccess(WATER_TEMPLE_MQ_LONGSHOT_CHEST, {[]{return IsAdult && CanUse(HOOKSHOT);}}), LocationAccess(WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, {[]{return CanUse(DINS_FIRE);}}), LocationAccess(WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, {[]{return IsAdult && CanUse(LONGSHOT);}}), @@ -296,7 +297,7 @@ void AreaTable_Init_WaterTemple() { //Locations LocationAccess(WATER_TEMPLE_MQ_FREESTANDING_KEY, {[]{return HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump;}}), LocationAccess(WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, {[]{return CanUse(FIRE_ARROWS) && (HoverBoots || CanUse(SCARECROW));}}), - LocationAccess(WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, {[]{return LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump));}}), + LocationAccess(WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, {[]{return LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump) && CanJumpslash);}}), //Trick: LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump)) }, {}); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp index 6d46e783e..d9c91b876 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp @@ -95,7 +95,7 @@ void AreaTable_Init_ZorasDomain() { LocationAccess(ZD_CHEST, {[]{return IsChild && CanUse(STICKS);}}), LocationAccess(ZD_KING_ZORA_THAWED, {[]{return KingZoraThawed;}}), LocationAccess(ZD_TRADE_PRESCRIPTION, {[]{return KingZoraThawed && Prescription;}}), - LocationAccess(ZD_GS_FROZEN_WATERFALL, {[]{return IsAdult && AtNight && (HookshotOrBoomerang || CanUse(SLINGSHOT) || Bow || MagicMeter || LogicDomainGS) && CanGetNightTimeGS;}}), + LocationAccess(ZD_GS_FROZEN_WATERFALL, {[]{return IsAdult && AtNight && (HookshotOrBoomerang || CanUse(SLINGSHOT) || Bow || (MagicMeter && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD))) || (LogicDomainGS && CanJumpslash)) && CanGetNightTimeGS;}}), LocationAccess(ZD_GOSSIP_STONE, {[]{return true;}}), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.cpp b/soh/soh/Enhancements/randomizer/3drando/logic.cpp index 51cdebabb..580c687d0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/logic.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/logic.cpp @@ -256,6 +256,8 @@ namespace Logic { bool CanBlastOrSmash = false; bool CanChildAttack = false; bool CanChildDamage = false; + bool CanAdultAttack = false; + bool CanAdultDamage = false; bool CanCutShrubs = false; bool CanDive = false; bool CanLeaveForest = false; @@ -511,7 +513,6 @@ namespace Logic { SilverScale = ProgressiveScale >= 1; GoldScale = ProgressiveScale >= 2; AdultsWallet = ProgressiveWallet >= 1; - MasterSword = MasterSword || IsAdult; BiggoronSword = BiggoronSword || ProgressiveGiantKnife >= 2; ScarecrowSong = ScarecrowSong || FreeScarecrow || (ChildScarecrow && AdultScarecrow); @@ -560,8 +561,10 @@ namespace Logic { CanBlastOrSmash = HasExplosives || CanUse(MEGATON_HAMMER); CanChildAttack = IsChild && (Slingshot || Boomerang || Sticks || KokiriSword || HasExplosives || CanUse(DINS_FIRE) || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD)); CanChildDamage = IsChild && (Slingshot || Sticks || KokiriSword || HasExplosives || CanUse(DINS_FIRE) || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD)); - CanStunDeku = IsAdult || CanChildAttack || Nuts || HasShield; - CanCutShrubs = IsAdult /*|| Sticks*/ || KokiriSword || Boomerang || HasExplosives || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD); + CanAdultAttack = IsAdult && (CanUse(BOW) || CanUse(BOOMERANG) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || HasExplosives || CanUse(DINS_FIRE) || MasterSword || Hammer || BiggoronSword || Hookshot); + CanAdultDamage = IsAdult && (CanUse(BOW) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || HasExplosives || CanUse(DINS_FIRE) || MasterSword || Hammer || BiggoronSword); + CanStunDeku = CanAdultAttack || CanChildAttack || Nuts || HasShield; + CanCutShrubs = CanUse(KOKIRI_SWORD) || CanUse(BOOMERANG) || HasExplosives || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD); CanDive = ProgressiveScale >= 1; CanLeaveForest = OpenForest.IsNot(OPENFOREST_CLOSED) || IsAdult || DekuTreeClear || ShuffleInteriorEntrances || ShuffleOverworldEntrances; CanPlantBugs = IsChild && Bugs; @@ -588,8 +591,8 @@ namespace Logic { HasFireSourceWithTorch = HasFireSource || CanUse(STICKS); //Gerudo Fortress - CanFinishGerudoFortress = (GerudoFortress.Is(GERUDOFORTRESS_NORMAL) && GerudoFortressKeys >= 4 && (IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen)) || - (GerudoFortress.Is(GERUDOFORTRESS_FAST) && GerudoFortressKeys >= 1 && (IsAdult || KokiriSword || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))) || + CanFinishGerudoFortress = (GerudoFortress.Is(GERUDOFORTRESS_NORMAL) && GerudoFortressKeys >= 4 && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen)) || + (GerudoFortress.Is(GERUDOFORTRESS_FAST) && GerudoFortressKeys >= 1 && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))) || (GerudoFortress.IsNot(GERUDOFORTRESS_NORMAL) && GerudoFortress.IsNot(GERUDOFORTRESS_FAST)); HasShield = CanUse(HYLIAN_SHIELD) || CanUse(DEKU_SHIELD); //Mirror shield can't reflect attacks @@ -598,7 +601,7 @@ namespace Logic { AdultReflectShield = IsAdult && CanUse(HYLIAN_SHIELD); //Mirror shield can't reflect attacks AdultShield = IsAdult && (CanUse(HYLIAN_SHIELD) || CanUse(MIRROR_SHIELD)); CanShieldFlick = ChildShield || AdultShield; - CanJumpslash = IsAdult || Sticks || KokiriSword; + CanJumpslash = CanUse(STICKS) || CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD); // Not including hammer as hammer jump attacks can be weird CanUseProjectile = HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(SLINGSHOT) || CanUse(BOOMERANG); CanUseMagicArrow = CanUse(FIRE_ARROWS) || CanUse(ICE_ARROWS) || CanUse(LIGHT_ARROWS); diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.hpp b/soh/soh/Enhancements/randomizer/3drando/logic.hpp index 21776af5e..2c5bca890 100644 --- a/soh/soh/Enhancements/randomizer/3drando/logic.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/logic.hpp @@ -247,6 +247,8 @@ extern bool IsGlitched; extern bool CanBlastOrSmash; extern bool CanChildAttack; extern bool CanChildDamage; +extern bool CanAdultAttack; +extern bool CanAdultDamage; extern bool CanCutShrubs; extern bool CanDive; extern bool CanLeaveForest; diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 2cd894ffd..08d09cfa8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -176,26 +176,28 @@ namespace Settings { }; //Shuffle Settings - Option RandomizeShuffle = Option::Bool("Randomize Settings", {"No","Yes"}, OptionCategory::Toggle); - Option ShuffleRewards = Option::U8 ("Shuffle Dungeon Rewards",{"End of dungeons", "Any dungeon", "Overworld", "Anywhere"}); - Option LinksPocketItem = Option::U8 ("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}); - Option ShuffleSongs = Option::U8 ("Shuffle Songs", {"Song locations", "Dungeon rewards", "Anywhere"}); - Option Shopsanity = Option::U8 ("Shopsanity", {"Off","0 Items","1 Item","2 Items","3 Items","4 Items","Random"}); - Option ShopsanityPrices = Option::U8 ("Shopsanity Prices", {"Balanced", "Starting Wallet", "Adult Wallet", "Giant's Wallet", "Tycoon's Wallet" }); - Option ShopsanityPricesAffordable = Option::Bool("Affordable Prices", {"Off", "On"}); - Option Tokensanity = Option::U8 ("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}); - Option Scrubsanity = Option::U8 ("Scrub Shuffle", {"Off", "Affordable", "Expensive", "Random Prices"}); - Option ShuffleCows = Option::Bool("Shuffle Cows", {"Off", "On"}); - Option ShuffleKokiriSword = Option::Bool("Shuffle Kokiri Sword", {"Off", "On"}); - Option ShuffleOcarinas = Option::Bool("Shuffle Ocarinas", {"Off", "On"}); - Option ShuffleWeirdEgg = Option::Bool("Shuffle Weird Egg", {"Off", "On"}); - Option ShuffleGerudoToken = Option::Bool("Shuffle Gerudo Card", {"Off", "On"}); - Option ShuffleMagicBeans = Option::Bool("Shuffle Magic Beans", {"Off", "On"}); - Option ShuffleMerchants = Option::U8 ("Shuffle Merchants", {"Off", "On (No Hints)", "On (With Hints)"}); - Option ShuffleFrogSongRupees = Option::Bool("Shuffle Frog Song Rupees",{"Off", "On"}); - Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"}); - Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); - Option Shuffle100GSReward = Option::Bool("Shuffle 100 GS Reward", {"Off", "On"}); + Option RandomizeShuffle = Option::Bool("Randomize Settings", {"No","Yes"}, OptionCategory::Toggle); + Option ShuffleRewards = Option::U8 ("Shuffle Dungeon Rewards",{"End of dungeons", "Any dungeon", "Overworld", "Anywhere"}); + Option LinksPocketItem = Option::U8 ("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}); + Option ShuffleSongs = Option::U8 ("Shuffle Songs", {"Song locations", "Dungeon rewards", "Anywhere"}); + Option Shopsanity = Option::U8 ("Shopsanity", {"Off","0 Items","1 Item","2 Items","3 Items","4 Items","Random"}); + Option ShopsanityPrices = Option::U8 ("Shopsanity Prices", {"Balanced", "Starting Wallet", "Adult Wallet", "Giant's Wallet", "Tycoon's Wallet" }); + Option ShopsanityPricesAffordable = Option::Bool("Affordable Prices", {"Off", "On"}); + Option Tokensanity = Option::U8 ("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}); + Option Scrubsanity = Option::U8 ("Scrub Shuffle", {"Off", "Affordable", "Expensive", "Random Prices"}); + Option ShuffleCows = Option::Bool("Shuffle Cows", {"Off", "On"}); + Option ShuffleKokiriSword = Option::Bool("Shuffle Kokiri Sword", {"Off", "On"}); + Option ShuffleMasterSword = Option::Bool("Shuffle Master Sword", {"Off", "On"}); + Option ShuffleOcarinas = Option::Bool("Shuffle Ocarinas", {"Off", "On"}); + Option ShuffleWeirdEgg = Option::Bool("Shuffle Weird Egg", {"Off", "On"}); + Option ShuffleGerudoToken = Option::Bool("Shuffle Gerudo Card", {"Off", "On"}); + Option ShuffleMagicBeans = Option::Bool("Shuffle Magic Beans", {"Off", "On"}); + Option ShuffleMerchants = Option::U8 ("Shuffle Merchants", {"Off", "On (No Hints)", "On (With Hints)"}); + Option ShuffleFrogSongRupees = Option::Bool("Shuffle Frog Song Rupees",{"Off", "On"}); + Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"}); + Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); + Option Shuffle100GSReward = Option::Bool("Shuffle 100 GS Reward", {"Off", "On"}); + std::vector<Option *> shuffleOptions = { &RandomizeShuffle, &ShuffleRewards, @@ -208,6 +210,7 @@ namespace Settings { &Scrubsanity, &ShuffleCows, &ShuffleKokiriSword, + &ShuffleMasterSword, &ShuffleOcarinas, &ShuffleWeirdEgg, &ShuffleGerudoToken, @@ -569,6 +572,7 @@ namespace Settings { }; Option StartingKokiriSword = Option::U8 ("Start with Kokiri Sword", {"Off", "On"}); + Option StartingMasterSword = Option::U8 ("Start with Master Sword", {"Off", "On"}); Option StartingBiggoronSword = Option::U8 ("Biggoron Sword", {"Off", "Giant's Knife", "Biggoron Sword"}); Option StartingDekuShield = Option::U8 ("Start with Deku Shield", {"Off", "On"}); Option StartingHylianShield = Option::U8 ("Hylian Shield", {"Off", "On"}); @@ -582,6 +586,7 @@ namespace Settings { Option StartingHearts = Option::U8 ("Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, 2); // Default 3 hearts Option StartingMagicMeter = Option::U8 ("Magic Meter", {"Off", "Single Magic", "Double Magic"}); Option StartingDoubleDefense = Option::U8 ("Double Defense", {"Off", "On"}); + std::vector<Option *> startingEquipmentOptions = { &StartingKokiriSword, &StartingBiggoronSword, @@ -2277,6 +2282,7 @@ namespace Settings { Scrubsanity.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_SCRUBS]); ShuffleCows.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_COWS]); ShuffleKokiriSword.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD]); + ShuffleMasterSword.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_MASTER_SWORD]); ShuffleOcarinas.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_OCARINA]); // Shuffle Entrances diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.hpp b/soh/soh/Enhancements/randomizer/3drando/settings.hpp index 0d3d3c898..fc1df2959 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.hpp @@ -802,6 +802,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin extern Option Scrubsanity; extern Option ShuffleCows; extern Option ShuffleKokiriSword; + extern Option ShuffleMasterSword; extern Option ShuffleOcarinas; extern Option ShuffleWeirdEgg; extern Option ShuffleGerudoToken; diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 8c47ac976..4199a9b2c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -224,11 +224,11 @@ void InitTrickNames() { trickNameTable[GI_SWORD_KOKIRI] = { Text{"Korok Sword", "Épée Korok", "Espada Korok"}, Text{"Hero's Sword", "Épée du Héros", "Espada del héroe"}, - Text{"Butter Knife","Couteau à Beurre","cuchillo de mantequilla"}}; -/* trickNameTable[GI_SWORD_MASTER] = { + Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}}; + trickNameTable[0xE0] = { //Master Sword without the GI enum Text{"Goddess Sword", "Épée de la déesse", "Espada Divina"}, Text{"Gilded Sword", "Excalibur", "Espada de los Sabios"}, - Text{"Magical Sword", "Lame dorée", "Fay"}};*/ + Text{"Magical Sword", "Lame dorée", "Fay"}}; trickNameTable[GI_SWORD_KNIFE] = { Text{"Medigoron's Sword", "l'Épée de Medigoron", "La espada de Medigoron"}, Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}, diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 2884dd6e7..3bd3dc44d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -744,6 +744,7 @@ static void WriteHints(int language) { jsonData["ganonText"] = ganonText; jsonData["ganonHintText"] = ganonHintText; jsonData["lightArrowHintLoc"] = GetLightArrowHintLoc(); + jsonData["masterSwordHintLoc"] = GetMasterSwordHintLoc(); jsonData["dampeText"] = dampesText; jsonData["dampeHintLoc"] = GetDampeHintLoc(); jsonData["gregText"] = gregText; diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp index 03bc2077e..bae03817a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp @@ -24,6 +24,7 @@ typedef enum { SPOILER_CHK_POE_POINTS, SPOILER_CHK_SHOP_ITEM, SPOILER_CHK_MAGIC_BEANS, + SPOILER_CHK_MASTER_SWORD, SPOILER_CHK_MERCHANT, SPOILER_CHK_GRAVEDIGGER, SPOILER_CHK_RANDOMIZER_INF, diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index c2895dd62..eacc62725 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -10,6 +10,7 @@ #include "objects/object_gi_key/object_gi_key.h" #include "objects/object_gi_bosskey/object_gi_bosskey.h" #include "objects/object_gi_hearts/object_gi_hearts.h" +#include "objects/object_toki_objects/object_toki_objects.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh_assets.h" @@ -176,6 +177,27 @@ extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getIt CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, + (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 1), + 0 * (play->state.frames * 1), 32, 32, 1, 0 * (play->state.frames * 1), + 0 * (play->state.frames * 1), 32, 32)); + + Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); + Matrix_RotateZ(2.1f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_toki_objects_DL_001BD0); + + CLOSE_DISPS(play->state.gfxCtx); +} + Gfx* Randomizer_GetTriforcePieceDL(uint8_t index) { switch (index) { case 1: @@ -253,6 +275,5 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get } else if (current == required && triforcePieceScale > 0.00008f) { gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gTriforcePieceCompletedDL); } - CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 19510c2f4..d9134573d 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -13,11 +13,11 @@ void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry); +void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); #ifdef __cplusplus }; #endif - #endif diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 578532a33..9050fcd80 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -253,6 +253,7 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn { "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE }, { "Shuffle Settings:Shuffle Magic Beans", RSK_SHUFFLE_MAGIC_BEANS }, { "Shuffle Settings:Shuffle Kokiri Sword", RSK_SHUFFLE_KOKIRI_SWORD }, + { "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD }, { "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG }, { "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES }, { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, @@ -844,6 +845,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { case RSK_SHUFFLE_ADULT_TRADE: case RSK_SHUFFLE_MAGIC_BEANS: case RSK_SHUFFLE_KOKIRI_SWORD: + case RSK_SHUFFLE_MASTER_SWORD: case RSK_SHUFFLE_WEIRD_EGG: case RSK_SHUFFLE_FROG_SONG_RUPEES: case RSK_SHUFFLE_100_GS_REWARD: @@ -1325,7 +1327,8 @@ void Randomizer::ParseHintLocationsFile(const char* spoilerFileName) { std::string formattedGanonHintJsonText = FormatJsonHintText(ganonHintJsonText); strncpy(gSaveContext.ganonHintText, formattedGanonHintJsonText.c_str(), sizeof(gSaveContext.ganonHintText) - 1); gSaveContext.ganonHintText[sizeof(gSaveContext.ganonHintText) - 1] = 0; - gSaveContext.lightArrowHintCheck = SpoilerfileCheckNameToEnum[spoilerFileJson["lightArrowHintLoc"]]; + + gSaveContext.masterSwordHintCheck = SpoilerfileCheckNameToEnum[spoilerFileJson["masterSwordHintLoc"]]; std::string ganonJsonText = spoilerFileJson["ganonText"].get<std::string>(); std::string formattedGanonJsonText = FormatJsonHintText(ganonJsonText); @@ -1665,6 +1668,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // Equipment case RG_KOKIRI_SWORD: return !CHECK_OWNED_EQUIP(EQUIP_SWORD, 0) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + case RG_MASTER_SWORD: + return !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_BIGGORON_SWORD: return !gSaveContext.bgsFlag ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_DEKU_SHIELD: @@ -2560,6 +2565,7 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = { { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, + { RC_TOT_MASTER_SWORD, RAND_INF_TOT_MASTER_SWORD }, { RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON }, { RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP }, { RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN }, @@ -2873,6 +2879,7 @@ void GenerateRandomizerImgui(std::string seed = "") { cvarSettings[RSK_STARTING_KOKIRI_SWORD] = CVarGetInteger("gRandomizeStartingKokiriSword", 0); cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD] = CVarGetInteger("gRandomizeShuffleKokiriSword", 0) || CVarGetInteger("gRandomizeStartingKokiriSword", 0); + cvarSettings[RSK_SHUFFLE_MASTER_SWORD] = CVarGetInteger("gRandomizeShuffleMasterSword", 0); cvarSettings[RSK_STARTING_DEKU_SHIELD] = CVarGetInteger("gRandomizeStartingDekuShield", 0); cvarSettings[RSK_STARTING_ZELDAS_LULLABY] = CVarGetInteger("gRandomizeStartingZeldasLullaby", 0); cvarSettings[RSK_STARTING_EPONAS_SONG] = CVarGetInteger("gRandomizeStartingEponasSong", 0); @@ -3832,6 +3839,20 @@ void RandomizerSettingsWindow::DrawElement() { UIWidgets::PaddedSeparator(); + //Shuffle Master Sword + //RANDOTODO: Disable when Start with Master Sword is active + // bool disableShuffleMasterSword = CvarGetInteger("gRandomizeStartingMasterSword", 0); + // static const char* disableShuffleMasterSwordText = "This option is disabled because \"Start with Master Sword\" is enabled."; + UIWidgets::EnhancementCheckbox(Settings::ShuffleMasterSword.GetName().c_str(), "gRandomizeShuffleMasterSword"); + UIWidgets::InsertHelpHoverText( + "Shuffles the Master Sword into the item pool.\n" + "\n" + "Adult Link will start with a second free item instead of the Master Sword.\n" + "If you haven't found the Master Sword before facing Ganon, you won't receive it during the fight." + ); + + UIWidgets::PaddedSeparator(); + // Shuffle Ocarinas // Disabled when Start with Ocarina is active bool disableShuffleOcarinas = CVarGetInteger("gRandomizeStartingOcarina", 0); @@ -5317,7 +5338,12 @@ CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { break; case SCENE_INSIDE_GANONS_CASTLE: if (originalTextId == TEXT_SHEIK_NEED_HOOK) { - if (INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) { + //If MS shuffle is on, Sheik will hint both MS and LA as long as Link doesn't have both, to prevent hint lockout. + //Otherwise, she'll only give LA hint so only LA is required to move on. + bool needRequirements = GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) ? + (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 1) || INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) : + (INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT); + if (needRequirements) { messageEntry.Replace("{{message}}", gSaveContext.sheikText, gSaveContext.sheikText, gSaveContext.sheikText); } else { messageEntry.Replace("{{message}}", "You are still ill-equipped to&face %rGanondorf%w." @@ -5328,10 +5354,17 @@ CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { "Cherche l'%cÉpée de Légende%w,&%rquelque chose pour ranger tes flèches%w&et de la %gmagie%w pour invoquer la&%ylumière%w."); } } else { - messageEntry.Replace("{{message}}", - "If you're ready, then proceed.^Good luck.", - "Wenn Du bereit bist, so schreite&voran.^Viel Glück.", - "Si tu es prêt, tu peux y aller.^Bonne chance."); + if (!Flags_GetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER)) { + messageEntry.Replace("{{message}}", + "You may have what you need to defeat&%rthe Evil King%w, but the %cbarrier%w still&stands.^Complete the remaining %gtrials%w&to destroy it." + ); + + } else { + messageEntry.Replace("{{message}}", + "If you're ready, then proceed.^Good luck.", + "Wenn Du bereit bist, so schreite&voran.^Viel Glück.", + "Si tu es prêt, tu peux y aller.^Bonne chance."); + } } break; } @@ -5866,11 +5899,15 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array<GetItemMessage, 56> getItemMessages = {{ + const std::array<GetItemMessage, 57> getItemMessages = {{ GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), + GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, + "You found the %gMaster Sword%w!", + "Du erhältst dem %gMaster-Schwert%w!", + "Vous obtenez %gl'Épée de Légende%w!"), GIMESSAGE(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", "Du erhältst eine %rFlasche mit&blauem Feuer%w! Nutze es um&%rRotes Eis%w zu schmelzen!", @@ -6155,6 +6192,7 @@ void InitRandoItemTable() { GET_ITEM(RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, RG_MAGIC_DOUBLE), GET_ITEM(RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, RG_DOUBLE_DEFENSE), GET_ITEM(RG_GREG_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_GREG_RUPEE), + GET_ITEM(RG_MASTER_SWORD, OBJECT_TOKI_OBJECTS,GID_SWORD_BGS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_MASTER_SWORD), GET_ITEM(RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_BOTTLE_WITH_RED_POTION), GET_ITEM(RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_BOTTLE_WITH_GREEN_POTION), GET_ITEM(RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_BOTTLE_WITH_BLUE_POTION), @@ -6227,6 +6265,8 @@ void InitRandoItemTable() { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey; } else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawDoubleDefense; + } else if (randoGetItemTable[i].itemId == RG_MASTER_SWORD) { + randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawMasterSword; } else if (randoGetItemTable[i].itemId == RG_TRIFORCE_PIECE) { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawTriforcePiece; } diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index b1e843497..ce0659170 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -221,6 +221,7 @@ typedef enum { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RC_MARKET_BOMBCHU_SHOP_ITEM_8, RC_TOT_LIGHT_ARROWS_CUTSCENE, + RC_TOT_MASTER_SWORD, RC_HC_MALON_EGG, RC_HC_ZELDAS_LETTER, RC_HC_GREAT_FAIRY_REWARD, @@ -1123,6 +1124,7 @@ typedef enum { typedef enum { RG_NONE, RG_KOKIRI_SWORD, + RG_MASTER_SWORD, RG_GIANTS_KNIFE, RG_BIGGORON_SWORD, RG_DEKU_SHIELD, @@ -1360,6 +1362,7 @@ typedef enum { RSK_STARTING_NOCTURNE_OF_SHADOW, RSK_STARTING_PRELUDE_OF_LIGHT, RSK_SHUFFLE_KOKIRI_SWORD, + RSK_SHUFFLE_MASTER_SWORD, RSK_STARTING_MAPS_COMPASSES, RSK_SHUFFLE_DUNGEON_REWARDS, RSK_SHUFFLE_SONGS, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index be05be35d..9a3669582 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -28,7 +28,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_EN_GS, SCENE_KOKIRI_FOREST, 14880, GI_NONE, "Deku Tree Right Gossip Stone", "KF Deku Tree Right Gossip Stone", false), RC_OBJECT(RC_KF_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_EN_GS, SCENE_KOKIRI_FOREST, 14366, GI_NONE, "Gossip Stone", "KF Gossip Stone", false), RC_OBJECT(RC_KF_STORMS_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_EN_GS, SCENE_GROTTOS, -22988, GI_NONE, "Storms Gossip Stone", "KF Storms Gossip Stone", false), - RC_OBJECT(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, GI_RUPEE_BLUE, "Near Shortcuts Grotto Chest", "LW Near Shortcuts Grotto Chest", false), RC_OBJECT(RC_LW_SKULL_KID, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, GI_HEART_PIECE, "Skull Kid", "LW Skull Kid", true), @@ -50,7 +49,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_LW_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LOST_WOODS, ACTOR_EN_GS, SCENE_LOST_WOODS, 14365, GI_NONE, "Gossip Stone", "LW Gossip Stone", false), RC_OBJECT(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LOST_WOODS, ACTOR_EN_GS, SCENE_GROTTOS, -22964, GI_NONE, "Near Shortcuts Gossip Stone", "LW Near Shortcuts Gossip Stone", false), - RC_OBJECT(RC_SFM_WOLFOS_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, GI_RUPEE_PURPLE, "Wolfos Grotto Chest", "SFM Wolfos Grotto Chest", false), RC_OBJECT(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07,0xEE), GI_POTION_RED, "Deku Scrub Grotto Rear", "SFM Deku Scrub Grotto Rear", false), RC_OBJECT(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08,0xEE), GI_POTION_GREEN, "Deku Scrub Grotto Front", "SFM Deku Scrub Grotto Front", false), @@ -77,7 +75,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_HYRULE_FIELD, ACTOR_EN_GS, SCENE_GROTTOS, -22947, GI_NONE, "Open Grotto Gossip Stone", "HF Open Grotto Gossip Stone", false), RC_OBJECT(RC_HF_SOUTHEAST_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_HYRULE_FIELD, ACTOR_EN_GS, SCENE_GROTTOS, -22978, GI_NONE, "Southeast Gossip Stone", "HF Southeast Gossip Stone", false), - RC_OBJECT(RC_LH_CHILD_FISHING, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, GI_HEART_PIECE, "Child Fishing", "LH Child Fishing", true), RC_OBJECT(RC_LH_ADULT_FISHING, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, GI_SCALE_GOLD, "Adult Fishing", "LH Adult Fishing", true), RC_OBJECT(RC_LH_LAB_DIVE, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, GI_HEART_PIECE, "Lab Dive", "LH Lab Dive", true), @@ -97,7 +94,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_LH_SOUTHEAST_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_EN_GS, SCENE_LAKE_HYLIA, 14863, GI_NONE, "Southeast Gossip Stone", "LH Southeast Gossip Stone", false), RC_OBJECT(RC_LH_SOUTHWEST_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_EN_GS, SCENE_LAKE_HYLIA, 14600, GI_NONE, "Southwest Gossip Stone", "LH Southwest Gossip Stone", false), - RC_OBJECT(RC_GV_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, GI_RUPEE_PURPLE, "Chest", "GV Chest", false), RC_OBJECT(RC_GV_TRADE_SAW, RCVORMQ_BOTH, RCTYPE_ADULT_TRADE, RCAREA_GERUDO_VALLEY, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, GI_NONE, "Trade Saw", "GV Trade Saw", true), RC_OBJECT(RC_GV_WATERFALL_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, GI_HEART_PIECE, "Waterfall Freestanding PoH", "GV Waterfall Freestanding PoH", true), @@ -111,7 +107,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_GV_COW, RCVORMQ_BOTH, RCTYPE_COW, RCAREA_GERUDO_VALLEY, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, GI_MILK, "Cow", "GV Cow", false), RC_OBJECT(RC_GV_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GERUDO_VALLEY, ACTOR_EN_GS, SCENE_GERUDO_VALLEY, 14353, GI_NONE, "Gossip Stone", "GV Gossip Stone", false), - RC_OBJECT(RC_GF_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, GI_HEART_PIECE, "Chest", "GF Chest", true), RC_OBJECT(RC_GF_HBA_1000_POINTS, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, GI_HEART_PIECE, "GF HBA 1000 Points", "GF HBA 1000 Points", true), RC_OBJECT(RC_GF_HBA_1500_POINTS, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, GI_QUIVER_50, "GF HBA 1500 Points", "GF HBA 1500 Points", true), @@ -123,12 +118,10 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_GF_GS_ARCHERY_RANGE, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GERUDO_FORTRESS, ACTOR_EN_SI, SCENE_GERUDOS_FORTRESS, 21505, GI_SKULL_TOKEN, "GS Archery Range", "GF GS Archery Range", true), RC_OBJECT(RC_GF_GS_TOP_FLOOR, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GERUDO_FORTRESS, ACTOR_EN_SI, SCENE_GERUDOS_FORTRESS, 21506, GI_SKULL_TOKEN, "GS Top Floor", "GF GS Top Floor", true), - RC_OBJECT(RC_WASTELAND_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, GI_RUPEE_PURPLE, "Chest", "Wasteland Chest", false), RC_OBJECT(RC_WASTELAND_BOMBCHU_SALESMAN, RCVORMQ_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, GI_NONE, "Carpet Salesman", "Wasteland Carpet Salesman", false), RC_OBJECT(RC_WASTELAND_GS, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_WASTELAND, ACTOR_EN_SI, SCENE_HAUNTED_WASTELAND, 13570, GI_SKULL_TOKEN, "GS", "Wasteland GS", true), - RC_OBJECT(RC_COLOSSUS_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, GI_HEART_PIECE, "Freestanding PoH", "Colossus Freestanding PoH", true), RC_OBJECT(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07,0xFD), GI_POTION_RED, "Deku Scrub Grotto Rear", "Colossus Deku Scrub Grotto Rear", false), RC_OBJECT(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08,0xFD), GI_POTION_GREEN, "Deku Scrub Grotto Front", "Colossus Deku Scrub Grotto Front", false), @@ -139,7 +132,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_SHEIK_AT_COLOSSUS, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DESERT_COLOSSUS, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, GI_NONE, "Sheik at Colossus", "Sheik at Colossus", true), RC_OBJECT(RC_COLOSSUS_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_DESERT_COLOSSUS, ACTOR_EN_GS, SCENE_DESERT_COLOSSUS, 14362, GI_NONE, "Gossip Stone", "Colossus Gossip Stone", false), - RC_OBJECT(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, GI_HEART_PIECE, "Treasure Chest Game Reward", "MK Treasure Chest Game Reward", true), RC_OBJECT(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, GI_NONE, "Bombchu Bowling First Prize", "MK Bombchu Bowling First Prize", true), RC_OBJECT(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, GI_HEART_PIECE, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", true), @@ -153,6 +145,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCVORMQ_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, GI_NONE, "Chest Game Fifth Room Chest", "MK Chest Game Fifth Room Chest", false), RC_OBJECT(RC_MARKET_GS_GUARD_HOUSE, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_MARKET, ACTOR_EN_SI, SCENE_MARKET_GUARD_HOUSE, -29176, GI_SKULL_TOKEN, "Market GS Guard House", "Market GS Guard House", true), RC_OBJECT(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_ARROW_LIGHT, "ToT Light Arrow Cutscene", "ToT Light Arrow Cutscene", true), + RC_OBJECT(RC_TOT_MASTER_SWORD, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "ToT Master Sword", "ToT Master Sword", true), RC_OBJECT(RC_SHEIK_AT_TEMPLE, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Sheik at Temple", "Sheik at Temple", true), RC_OBJECT(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCVORMQ_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, GI_BOMBCHUS_10, "Bombchu Shop Item 1", "MK Bombchu Shop Item 1", false), RC_OBJECT(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCVORMQ_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, GI_BOMBCHUS_10, "Bombchu Shop Item 2", "MK Bombchu Shop Item 2", false), @@ -183,7 +176,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_GS, SCENE_ID_MAX, 0x00, GI_NONE, "ToT Right Center Gossip Stone", "ToT Right Center Gossip Stone", false), RC_OBJECT(RC_TOT_RIGHT_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_GS, SCENE_ID_MAX, 0x00, GI_NONE, "ToT Right Gossip Stone", "ToT Right Gossip Stone", false), - RC_OBJECT(RC_HC_MALON_EGG, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, GI_NONE, "Malon Egg", "HC Malon Egg", true), RC_OBJECT(RC_HC_ZELDAS_LETTER, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, GI_LETTER_ZELDA, "Zeldas Letter", "HC Zeldas Letter", true), RC_OBJECT(RC_OGC_GS, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_HYRULE_CASTLE, ACTOR_EN_SI, SCENE_OUTSIDE_GANONS_CASTLE, 11777, GI_SKULL_TOKEN, "OGC GS", "OGC GS", true), @@ -196,7 +188,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_HC_ROCK_WALL_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_HYRULE_CASTLE, ACTOR_EN_GS, SCENE_HYRULE_CASTLE, 14347, GI_NONE, "Rock Wall Gossip Stone", "HC Rock Wall Gossip Stone", false), RC_OBJECT(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_HYRULE_CASTLE, ACTOR_EN_GS, SCENE_GROTTOS, 14355, GI_NONE, "Storms Grotto Gossip Stone", "HC Storms Grotto Gossip Stone", false), - RC_OBJECT(RC_KAK_REDEAD_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, GI_RUPEE_GOLD, "Redead Grotto Chest", "Kak Redead Grotto Chest", false), RC_OBJECT(RC_KAK_OPEN_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, GI_RUPEE_RED, "Open Grotto Chest", "Kak Open Grotto Chest", false), RC_OBJECT(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, GI_WALLET_ADULT, "10 Gold Skulltula Reward", "Kak 10 Gold Skulltula Reward", true), @@ -241,7 +232,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_KAK_BAZAAR_ITEM_8, RCVORMQ_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, GI_ARROWS_MEDIUM, "Bazaar Item 8", "Kak Bazaar Item 8", false), RC_OBJECT(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GS, SCENE_GROTTOS, -22984, GI_NONE, "Open Grotto Gossip Stone", "Kak Open Grotto Gossip Stone", false), - RC_OBJECT(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 21824, GI_SHIELD_HYLIAN, "Shield Grave Chest", "GY Shield Grave Chest", false), RC_OBJECT(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_REDEAD_GRAVE, -22592, GI_HEART_PIECE, "Heart Piece Grave Chest", "GY Heart Piece Grave Chest", true), RC_OBJECT(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_ROYAL_FAMILYS_TOMB, -32736, GI_BOMBS_5, "Composers Grave Chest", "GY Composers Grave Chest", false), @@ -254,7 +244,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Song from Composers Grave", "Song from Composers Grave", true), RC_OBJECT(RC_GY_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GRAVEYARD, ACTOR_EN_GS, SCENE_GRAVEYARD, 14346, GI_NONE, "Gossip Stone", "GY Gossip Stone", false), - RC_OBJECT(RC_DMT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, GI_RUPEE_PURPLE, "Chest", "DMT Chest", false), RC_OBJECT(RC_DMT_STORMS_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, GI_RUPEE_GOLD, "Storms Grotto Chest", "DMT Storms Grotto Chest", false), RC_OBJECT(RC_DMT_TRADE_BROKEN_SWORD, RCVORMQ_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, GI_NONE, "Trade Broken Sword", "DMT Trade Broken Sword", true), @@ -270,7 +259,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_DMT_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_GS, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, GI_NONE, "Gossip Stone", "DMT Gossip Stone", false), RC_OBJECT(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_GS, SCENE_GROTTOS, -23255, GI_NONE, "Storms Grotto Gossip Stone", "DMT Storms Grotto Gossip Stone", false), - RC_OBJECT(RC_GC_MAZE_LEFT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, GI_RUPEE_GOLD, "Maze Left Chest", "GC Maze Left Chest", false), RC_OBJECT(RC_GC_MAZE_RIGHT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, GI_RUPEE_PURPLE, "Maze Right Chest", "GC Maze Right Chest", false), RC_OBJECT(RC_GC_MAZE_CENTER_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, GI_RUPEE_PURPLE, "Maze Center Chest", "GC Maze Center Chest", false), @@ -295,7 +283,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_GC_MAZE_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GORON_CITY, ACTOR_EN_GS, SCENE_GORON_CITY, 14357, GI_NONE, "Maze Gossip Stone", "GC Maze Gossip Stone", false), RC_OBJECT(RC_GC_MEDIGORON_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GORON_CITY, ACTOR_EN_GS, SCENE_GORON_CITY, 14873, GI_NONE, "Medigoron Gossip Stone", "GC Medigoron Gossip Stone", false), - RC_OBJECT(RC_DMC_UPPER_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, GI_BOMBS_20, "Upper Grotto Chest", "DMC Upper Grotto Chest", false), RC_OBJECT(RC_DMC_WALL_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, GI_HEART_PIECE, "Wall Freestanding PoH", "DMC Wall Freestanding PoH", true), RC_OBJECT(RC_DMC_VOLCANO_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, GI_HEART_PIECE, "Volcano Freestanding PoH", "DMC Volcano Freestanding PoH", true), @@ -310,7 +297,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_DMC_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_GS, SCENE_DEATH_MOUNTAIN_CRATER, 14341, GI_NONE, "Gossip Stone", "DMC Gossip Stone", false), RC_OBJECT(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_GS, SCENE_GROTTOS, -23802, GI_NONE, "Upper Grotto Gossip Stone", "DMC Upper Grotto Gossip Stone", false), - RC_OBJECT(RC_ZR_OPEN_GROTTO_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, GI_RUPEE_RED, "Open Grotto Chest", "ZR Open Grotto Chest", false), RC_OBJECT(RC_ZR_MAGIC_BEAN_SALESMAN, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, GI_NONE, "Magic Bean Salesman", "ZR Magic Bean Salesman", true), RC_OBJECT(RC_ZR_FROGS_ZELDAS_LULLABY, RCVORMQ_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, GI_NONE, "Frogs Zelda's Lullaby", "ZR Frogs Zelda's Lullaby", false), @@ -332,7 +318,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_ZORAS_RIVER, ACTOR_EN_GS, SCENE_ZORAS_RIVER, 14605, GI_NONE, "Near Grottos Gossip Stone", "ZR Near Grottos Gossip Stone", false), RC_OBJECT(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_ZORAS_RIVER, ACTOR_EN_GS, SCENE_GROTTOS, -22985, GI_NONE, "Open Grotto Gossip Stone", "ZR Open Grotto Gossip Stone", false), - RC_OBJECT(RC_ZD_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, GI_HEART_PIECE, "Chest", "ZD Chest", true), RC_OBJECT(RC_ZD_DIVING_MINIGAME, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, GI_NONE, "Diving Minigame", "ZD Diving Minigame", true), RC_OBJECT(RC_ZD_KING_ZORA_THAWED, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, GI_NONE, "King Zora Thawed", "ZD King Zora Thawed", true), @@ -348,7 +333,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_ZD_SHOP_ITEM_8, RCVORMQ_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, GI_POTION_RED, "Shop Item 8", "ZD Shop Item 8", false), RC_OBJECT(RC_ZD_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GS, SCENE_ZORAS_DOMAIN, 14345, GI_NONE, "Gossip Stone", "ZD Gossip Stone", false), - RC_OBJECT(RC_ZF_ICEBERC_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, GI_HEART_PIECE, "Iceberg Freestanding PoH", "ZF Iceberg Freestanding PoH", true), RC_OBJECT(RC_ZF_BOTTOM_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, GI_HEART_PIECE, "Bottom Freestanding PoH", "ZF Bottom Freestanding PoH", true), RC_OBJECT(RC_ZF_GS_ABOVE_THE_LOG, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_SI, SCENE_ZORAS_FOUNTAIN, 20740, GI_SKULL_TOKEN, "GS Above The Log", "ZF GS Above The Log", true), @@ -358,7 +342,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_FAIRY_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_GS, SCENE_ZORAS_FOUNTAIN, 0x00, GI_NONE, "Fairy Gossip Stone", "Fairy Gossip Stone", false), RC_OBJECT(RC_JABU_GOSSIP_STONE, RCVORMQ_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_GS, SCENE_ZORAS_FOUNTAIN, 0x00, GI_NONE, "Jabu Gossip Stone", "Jabu Gossip Stone", false), - RC_OBJECT(RC_LLR_TALONS_CHICKENS, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, GI_NONE, "Talons Chickens", "LLR Talons Chickens", true), RC_OBJECT(RC_LLR_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, GI_HEART_PIECE, "Freestanding PoH", "LLR Freestanding PoH", true), RC_OBJECT(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00,0xFC), GI_NUTS_5_2, "Deku Scrub Grotto Left", "LLR Deku Scrub Grotto Left", false), @@ -374,7 +357,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_LLR_TOWER_LEFT_COW, RCVORMQ_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229,157), GI_MILK, "Tower Left Cow", "LLR Tower Left Cow", false), RC_OBJECT(RC_LLR_TOWER_RIGHT_COW, RCVORMQ_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142,-140), GI_MILK, "Tower Right Cow", "LLR Tower Right Cow", false), - RC_OBJECT(RC_DEKU_TREE_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, GI_MAP, "Map Chest", "Deku Tree Map Chest", true), RC_OBJECT(RC_DEKU_TREE_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2050, GI_COMPASS, "Compass Chest", "Deku Tree Compass Chest", true), RC_OBJECT(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22790, GI_HEART, "Compass Room Side Chest", "Deku Tree Compass Room Side Chest", false), @@ -400,7 +382,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_QUEEN_GOHMA, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, GI_NONE, "Queen Gohma", "Queen Gohma", true), RC_OBJECT(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DEKU_TREE, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, GI_HEART_CONTAINER, "Queen Gohma Heart Container", "Deku Tree Queen Gohma Heart Container", true), - RC_OBJECT(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, GI_BOMBS_5, "Boss Room Chest", "Dodongos Cavern Boss Room Chest", false), RC_OBJECT(RC_DODONGOS_CAVERN_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2088, GI_MAP, "Map Chest", "Dodongos Cavern Map Chest", true), RC_OBJECT(RC_DODONGOS_CAVERN_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2053, GI_COMPASS, "Compass Chest", "Dodongos Cavern Compass Chest", true), @@ -435,7 +416,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, GI_HEART_CONTAINER, "King Dodongo Heart Container", "Dodongos Cavern King Dodongo Heart Container", true), RC_OBJECT(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCVORMQ_VANILLA, RCTYPE_GOSSIP_STONE, RCAREA_DODONGOS_CAVERN, ACTOR_EN_GS, SCENE_DODONGOS_CAVERN, 4372, GI_NONE, "Gossip Stone", "Dodongo's Cavern Gossip Stone", false), - RC_OBJECT(RC_JABU_JABUS_BELLY_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, GI_MAP, "Map Chest", "Jabu Jabus Belly Map Chest", true), RC_OBJECT(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, GI_COMPASS, "Compass Chest", "Jabu Jabus Belly Compass Chest", true), RC_OBJECT(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, GI_BOOMERANG, "Boomerang Chest", "Jabu Jabus Belly Boomerang Chest", true), @@ -463,7 +443,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_BARINADE, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, GI_NONE, "Barinade", "Barinade", true), RC_OBJECT(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, GI_HEART_CONTAINER, "Barinade Heart Container", "Jabu Jabus Belly Barinade Heart Container", true), - RC_OBJECT(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22595, GI_KEY_SMALL, "First Room Chest", "Forest Temple First Room Chest", true), RC_OBJECT(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, GI_KEY_SMALL, "First Stalfos Chest", "Forest Temple First Stalfos Chest", true), RC_OBJECT(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22789, GI_HEART, "Raised Island Courtyard Chest", "Forest Temple Raised Island Courtyard Chest", false), @@ -502,7 +481,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_PHANTOM_GANON, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, GI_NONE, "Phantom Ganon", "Phantom Ganon", true), RC_OBJECT(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, GI_HEART_CONTAINER, "Phantom Ganon Heart Container", "Forest Temple Phantom Ganon Heart Container", true), - RC_OBJECT(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, GI_KEY_SMALL, "Near Boss Chest", "Fire Temple Near Boss Chest", true), RC_OBJECT(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 31936, GI_BOMBS_10, "Flare Dancer Chest", "Fire Temple Flare Dancer Chest", false), RC_OBJECT(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, RCVORMQ_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10220, GI_KEY_BOSS, "Boss Key Chest", "Fire Temple Boss Key Chest", true), @@ -542,7 +520,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_VOLVAGIA, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, GI_NONE, "Volvagia", "Volvagia", true), RC_OBJECT(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, GI_HEART_CONTAINER, "Volvagia Heart Container", "Fire Temple Volvagia Heart Container", true), - RC_OBJECT(RC_WATER_TEMPLE_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6178, GI_MAP, "Map Chest", "Water Temple Map Chest", true), RC_OBJECT(RC_WATER_TEMPLE_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 2057, GI_COMPASS, "Compass Chest", "Water Temple Compass Chest", true), RC_OBJECT(RC_WATER_TEMPLE_TORCHES_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 30785, GI_KEY_SMALL, "Torches Chest", "Water Temple Torches Chest", true), @@ -572,7 +549,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_MORPHA, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, GI_NONE, "Morpha", "Morpha", true), RC_OBJECT(RC_WATER_TEMPLE_MORPHA_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_WATER_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, GI_HEART_CONTAINER, "Morpha Heart Container", "Water Temple Morpha Heart Container", true), - RC_OBJECT(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 1707, GI_GAUNTLETS_SILVER, "Silver Gauntlets Chest", "Spirit Temple Silver Gauntlets Chest", true), RC_OBJECT(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 13673, GI_SHIELD_MIRROR, "Mirror Shield Chest", "Spirit Temple Mirror Shield Chest", true), RC_OBJECT(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 21800, GI_SHIELD_DEKU, "Child Bridge Chest", "Spirit Temple Child Bridge Chest", false), @@ -625,7 +601,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_TWINROVA, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, GI_NONE, "Twinrova", "Twinrova", true), RC_OBJECT(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, GI_HEART_CONTAINER, "Twinrova Heart Container", "Spirit Temple Twinrova Heart Container", true), - RC_OBJECT(RC_SHADOW_TEMPLE_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6177, GI_MAP, "Map Chest", "Shadow Temple Map Chest", true), RC_OBJECT(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, GI_BOOTS_HOVER, "Hover Boots Chest", "Shadow Temple Hover Boots Chest", true), RC_OBJECT(RC_SHADOW_TEMPLE_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6147, GI_COMPASS, "Compass Chest", "Shadow Temple Compass Chest", true), @@ -676,7 +651,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_BONGO_BONGO, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, GI_NONE, "Bongo Bongo", "Bongo Bongo", true), RC_OBJECT(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCVORMQ_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, GI_HEART_CONTAINER, "Bongo Bongo Heart Container", "Shadow Temple Bongo Bongo Heart Container", true), - RC_OBJECT(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22600, GI_KEY_SMALL, "Front Left Fake Wall Chest", "Bottom of the Well Front Left Fake Wall Chest", true), RC_OBJECT(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20578, GI_BOMBCHUS_10, "Front Center Bombable Chest", "Bottom of the Well Front Center Bombable Chest", false), RC_OBJECT(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22597, GI_KEY_SMALL, "Right Bottom Fake Wall Chest", "Bottom of the Well Right Bottom Fake Wall Chest", true), @@ -703,7 +677,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_SI, SCENE_BOTTOM_OF_THE_WELL, 10244, GI_SKULL_TOKEN, "MQ GS Coffin Room", "Bottom of the Well MQ GS Coffin Room", true), RC_OBJECT(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_SI, SCENE_BOTTOM_OF_THE_WELL, 10242, GI_SKULL_TOKEN, "MQ GS West Inner Room", "Bottom of the Well MQ GS West Inner Room", true), - RC_OBJECT(RC_ICE_CAVERN_MAP_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2080, GI_MAP, "Map Chest", "Ice Cavern Map Chest", true), RC_OBJECT(RC_ICE_CAVERN_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2049, GI_COMPASS, "Compass Chest", "Ice Cavern Compass Chest", true), RC_OBJECT(RC_ICE_CAVERN_IRON_BOOTS_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, GI_BOOTS_IRON, "Iron Boots Chest", "Ice Cavern Iron Boots Chest", true), @@ -720,7 +693,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_ICE_CAVERN, ACTOR_EN_SI, SCENE_ICE_CAVERN, 10498, GI_SKULL_TOKEN, "MQ GS Red Ice", "Ice Cavern MQ GS Red Ice", true), RC_OBJECT(RC_SHEIK_IN_ICE_CAVERN, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_ICE_CAVERN, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, GI_NONE, "Sheik in Ice Cavern", "Sheik in Ice Cavern", true), - RC_OBJECT(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, GI_MAGIC_LARGE, "Lobby Left Chest", "Gerudo Training Grounds Lobby Left Chest", false), RC_OBJECT(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, GI_ARROWS_MEDIUM, "Lobby Right Chest", "Gerudo Training Grounds Lobby Right Chest", false), RC_OBJECT(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCVORMQ_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, GI_KEY_SMALL, "Stalfos Chest", "Gerudo Training Grounds Stalfos Chest", true), @@ -761,7 +733,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RCVORMQ_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, GI_KEY_SMALL, "MQ Underwater Silver Rupee Chest", "Gerudo Training Grounds MQ Underwater Silver Rupee Chest", true), RC_OBJECT(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCVORMQ_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31394, GI_RUPEE_PURPLE, "MQ Heavy Block Chest", "Gerudo Training Grounds MQ Heavy Block Chest", false), - RC_OBJECT(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCVORMQ_BOTH, RCTYPE_GANON_BOSS_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONS_TOWER, 10219, GI_KEY_BOSS, "Boss Key Chest", "Ganon's Tower Boss Key Chest", true), RC_OBJECT(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30857, GI_MAGIC_LARGE, "Forest Trial Chest", "Ganon's Castle Forest Trial Chest", false), RC_OBJECT(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24455, GI_ICE_TRAP, "Water Trial Left Chest", "Ganon's Castle Water Trial Left Chest", false), @@ -801,7 +772,6 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { RC_OBJECT(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCVORMQ_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, GI_POTION_RED, "MQ Deku Scrub Center-Right", "Ganon's Castle MQ Deku Scrub Center-Right", false), RC_OBJECT(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCVORMQ_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, GI_POTION_GREEN, "MQ Deku Scrub Left", "Ganon's Castle MQ Deku Scrub Left", false), - RC_OBJECT(RC_UNKNOWN_CHECK, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Invalid Check", "Invalid Check", false), }; diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 0884a694f..1489b25d2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -58,6 +58,7 @@ bool showMerchants; bool showCows; bool showAdultTrade; bool showKokiriSword; +bool showMasterSword; bool showWeirdEgg; bool showGerudoCard; bool showFrogSongRupees; @@ -424,6 +425,7 @@ bool HasItemBeenCollected(RandomizerCheck rc) { case SpoilerCollectionCheckType::SPOILER_CHK_COW: case SpoilerCollectionCheckType::SPOILER_CHK_SCRUB: case SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF: + case SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD: return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)); case SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF: return gSaveContext.eventChkInf[flag / 16] & (0x01 << flag % 16); @@ -1018,6 +1020,9 @@ void LoadSettings() { showKokiriSword = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES : true; + showMasterSword = IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) == RO_GENERIC_YES + : true; showWeirdEgg = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES : true; @@ -1126,6 +1131,7 @@ bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj) { rcObj.rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off ) && (rcObj.rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && + (rcObj.rc != RC_TOT_MASTER_SWORD || showMasterSword) && (rcObj.rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && (rcObj.rc != RC_HC_MALON_EGG || showWeirdEgg) && (rcObj.rcType != RCTYPE_FROG_SONG || showFrogSongRupees) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index 4293c30ef..f2f1a8a3f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -567,6 +567,7 @@ void Entrance_HandleEponaState(void) { player->actor.parent = NULL; AREG(6) = 0; gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; //"temp B" + Interface_RandoRestoreSwordless(); } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index c5b75eef0..33c206b47 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -154,9 +154,10 @@ typedef enum { RAND_INF_GREG_FOUND, + + RAND_INF_TOT_MASTER_SWORD, RAND_INF_CHILD_FISHING, RAND_INF_ADULT_FISHING, - RAND_INF_10_BIG_POES, // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index ed7443910..33278d0b7 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -351,6 +351,12 @@ extern "C" void Randomizer_InitSaveFile() { INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); + StartingItemGive(getItemEntry); + Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); + } + HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); if (Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 8b56d352c..eee6a622a 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2043,7 +2043,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { ? CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT) : CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD); } else if (textId == TEXT_GANONDORF) { - if (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT || !Randomizer_GetSettingValue(RSK_LIGHT_ARROWS_HINT)) { + if ((INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) || + !Randomizer_GetSettingValue(RSK_LIGHT_ARROWS_HINT)) { messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT); } else { messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF); diff --git a/soh/src/code/z_game_over.c b/soh/src/code/z_game_over.c index 4b10cb5e2..2d46a1899 100644 --- a/soh/src/code/z_game_over.c +++ b/soh/src/code/z_game_over.c @@ -57,6 +57,7 @@ void GameOver_Update(PlayState* play) { if (gSaveContext.buttonStatus[0] != BTN_ENABLED) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + Interface_RandoRestoreSwordless(); } else { gSaveContext.equips.buttonItems[0] = ITEM_NONE; } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index c41d1c188..cf3192c3d 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -811,6 +811,20 @@ void func_80082850(PlayState* play, s16 maxAlpha) { } } +// buttonStatus[0] is used to represent if the B button is disabled, but also tracks +// the last active B button item during mini-games/epona (temp B) +// Since ITEM_NONE is the same as BTN_DISABLED (255), we need a different value to help us track +// that the player was swordless before like ITEM_NONE_FE (254) +#define SWORDLESS_STATUS ITEM_NONE_FE + +// Restores swordless state when using the custom value for temp B and then clears temp B +void Interface_RandoRestoreSwordless(void) { + if (IS_RANDO && gSaveContext.buttonStatus[0] == SWORDLESS_STATUS) { + gSaveContext.equips.buttonItems[0] = ITEM_NONE; + gSaveContext.buttonStatus[0] = BTN_ENABLED; + } +} + void func_80083108(PlayState* play) { MessageContext* msgCtx = &play->msgCtx; Player* player = GET_PLAYER(play); @@ -818,13 +832,20 @@ void func_80083108(PlayState* play) { s16 i; s16 sp28 = 0; + // Check for the player being swordless in rando (no item on B and swordless flag set) + // Child is always assumed due to not finding kokiri sword yet. Adult is only checked with MS shuffle on. + u8 randoIsSwordless = IS_RANDO && (LINK_IS_CHILD || Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) && + gSaveContext.equips.buttonItems[0] == ITEM_NONE && Flags_GetInfTable(INFTABLE_SWORDLESS); + u8 randoWasSwordlessBefore = IS_RANDO && gSaveContext.buttonStatus[0] == SWORDLESS_STATUS; + u8 randoCanTrackSwordless = randoIsSwordless && !randoWasSwordlessBefore; + if ((gSaveContext.cutsceneIndex < 0xFFF0) || ((play->sceneNum == SCENE_LON_LON_RANCH) && (gSaveContext.cutsceneIndex == 0xFFF0))) { gSaveContext.unk_13E7 = 0; - if ((player->stateFlags1 & 0x00800000) || (play->shootingGalleryStatus > 1) || + if ((player->stateFlags1 & PLAYER_STATE1_ON_HORSE) || (play->shootingGalleryStatus > 1) || ((play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) && Flags_GetSwitch(play, 0x38))) { - if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) { + if (gSaveContext.equips.buttonItems[0] != ITEM_NONE || randoCanTrackSwordless) { gSaveContext.unk_13E7 = 1; if (gSaveContext.buttonStatus[0] == BTN_DISABLED) { @@ -837,9 +858,14 @@ void func_80083108(PlayState* play) { if ((gSaveContext.equips.buttonItems[0] != ITEM_SLINGSHOT) && (gSaveContext.equips.buttonItems[0] != ITEM_BOW) && (gSaveContext.equips.buttonItems[0] != ITEM_BOMBCHU) && - (gSaveContext.equips.buttonItems[0] != ITEM_NONE)) { + (gSaveContext.equips.buttonItems[0] != ITEM_NONE || randoCanTrackSwordless)) { gSaveContext.buttonStatus[0] = gSaveContext.equips.buttonItems[0]; + // Track swordless status for restoration later + if (randoCanTrackSwordless) { + gSaveContext.buttonStatus[0] = SWORDLESS_STATUS; + } + if ((play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) && Flags_GetSwitch(play, 0x38)) { gSaveContext.equips.buttonItems[0] = ITEM_BOMBCHU; Interface_LoadItemIcon1(play, 0); @@ -875,11 +901,11 @@ void func_80083108(PlayState* play) { Interface_ChangeAlpha(8); } else if ((play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) && Flags_GetSwitch(play, 0x38)) { Interface_ChangeAlpha(8); - } else if (player->stateFlags1 & 0x00800000) { + } else if (player->stateFlags1 & PLAYER_STATE1_ON_HORSE) { Interface_ChangeAlpha(12); } } else { - if (player->stateFlags1 & 0x00800000) { + if (player->stateFlags1 & PLAYER_STATE1_ON_HORSE) { Interface_ChangeAlpha(12); } } @@ -891,6 +917,12 @@ void func_80083108(PlayState* play) { if (play->interfaceCtx.unk_260 != 0) { if (gSaveContext.equips.buttonItems[0] != ITEM_FISHING_POLE) { gSaveContext.buttonStatus[0] = gSaveContext.equips.buttonItems[0]; + + // Track swordless status for restoration later + if (randoCanTrackSwordless) { + gSaveContext.buttonStatus[0] = SWORDLESS_STATUS; + } + gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE; gSaveContext.unk_13EA = 0; Interface_LoadItemIcon1(play, 0); @@ -904,6 +936,8 @@ void func_80083108(PlayState* play) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; gSaveContext.unk_13EA = 0; + Interface_RandoRestoreSwordless(); + if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) { Interface_LoadItemIcon1(play, 0); } @@ -974,7 +1008,7 @@ void func_80083108(PlayState* play) { } Interface_ChangeAlpha(50); - } else if ((player->stateFlags1 & 0x00200000) || (player->stateFlags2 & PLAYER_STATE2_CRAWLING)) { + } else if ((player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER) || (player->stateFlags2 & PLAYER_STATE2_CRAWLING)) { if (gSaveContext.buttonStatus[0] != BTN_DISABLED) { gSaveContext.buttonStatus[0] = BTN_DISABLED; gSaveContext.buttonStatus[1] = BTN_DISABLED; @@ -988,7 +1022,7 @@ void func_80083108(PlayState* play) { Interface_ChangeAlpha(50); } } else if ((gSaveContext.eventInf[0] & 0xF) == 1) { - if (player->stateFlags1 & 0x00800000) { + if (player->stateFlags1 & PLAYER_STATE1_ON_HORSE) { if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) && (gSaveContext.equips.buttonItems[0] != ITEM_BOW)) { if (gSaveContext.inventory.items[SLOT_BOW] == ITEM_NONE) { @@ -1009,6 +1043,8 @@ void func_80083108(PlayState* play) { (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_BGS) && (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KNIFE)) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + + Interface_RandoRestoreSwordless(); } else { gSaveContext.buttonStatus[0] = gSaveContext.equips.buttonItems[0]; } @@ -1048,8 +1084,12 @@ void func_80083108(PlayState* play) { (gSaveContext.equips.buttonItems[0] == ITEM_BOW) || (gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU) || (gSaveContext.equips.buttonItems[0] == ITEM_NONE)) { - if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) || (gSaveContext.infTable[29] == 0)) { + if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) || (gSaveContext.infTable[29] == 0) || + randoWasSwordlessBefore) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + + Interface_RandoRestoreSwordless(); + sp28 = 1; if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) { @@ -1071,8 +1111,12 @@ void func_80083108(PlayState* play) { (gSaveContext.equips.buttonItems[0] == ITEM_BOW) || (gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU) || (gSaveContext.equips.buttonItems[0] == ITEM_NONE)) { - if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) || (gSaveContext.infTable[29] == 0)) { + if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) || (gSaveContext.infTable[29] == 0) || + randoWasSwordlessBefore) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + + Interface_RandoRestoreSwordless(); + sp28 = 1; if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) { @@ -1412,15 +1456,20 @@ void Inventory_SwapAgeEquipment(void) { } // When becoming adult, remove swordless flag since we'll get master sword + // (Unless Master Sword is shuffled) // Only in rando to keep swordless link bugs in vanilla - if (IS_RANDO) { + if (IS_RANDO && !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { Flags_UnsetInfTable(INFTABLE_SWORDLESS); } gSaveContext.childEquips.equipment = gSaveContext.equips.equipment; - if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE) { - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; + if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE && !(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && gSaveContext.adultEquips.equipment)) { + if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; + } else { + gSaveContext.equips.buttonItems[0] = ITEM_NONE; + } if (gSaveContext.inventory.items[SLOT_NUT] != ITEM_NONE) { gSaveContext.equips.buttonItems[1] = ITEM_NUT; @@ -1433,7 +1482,9 @@ void Inventory_SwapAgeEquipment(void) { gSaveContext.equips.buttonItems[3] = gSaveContext.inventory.items[SLOT_OCARINA]; gSaveContext.equips.cButtonSlots[1] = SLOT_BOMB; gSaveContext.equips.cButtonSlots[2] = SLOT_OCARINA; - gSaveContext.equips.equipment = 0x1122; + + gSaveContext.equips.equipment = (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && + gSaveContext.equips.buttonItems[0] == ITEM_NONE) ? 0x1120 :0x1122; // Set the dpad to nothing gSaveContext.equips.buttonItems[4] = ITEM_NONE; @@ -1626,11 +1677,13 @@ void func_80084BF4(PlayState* play, u16 flag) { (gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU) || (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE)) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + Interface_RandoRestoreSwordless(); Interface_LoadItemIcon1(play, 0); } } else if (gSaveContext.equips.buttonItems[0] == ITEM_NONE) { if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) || (gSaveContext.infTable[29] == 0)) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + Interface_RandoRestoreSwordless(); Interface_LoadItemIcon1(play, 0); } } @@ -2556,6 +2609,13 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return Return_Item_Entry(giEntry, RG_NONE); } + if (item == RG_MASTER_SWORD) { + if (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; + } + return Return_Item_Entry(giEntry, RG_NONE); + } + temp = gSaveContext.inventory.items[slot]; osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); INV_CONTENT(item) = item; @@ -5723,6 +5783,7 @@ void Interface_Draw(PlayState* play) { (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KNIFE)) { if (gSaveContext.buttonStatus[0] != BTN_ENABLED) { gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0]; + Interface_RandoRestoreSwordless(); } else { gSaveContext.equips.buttonItems[0] = ITEM_NONE; } diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 817c90ecf..112a71888 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -265,6 +265,19 @@ void GivePlayerRandoRewardRequiem(PlayState* play, RandomizerCheck check) { } } +void GivePlayerRandoRewardMasterSword(PlayState* play, RandomizerCheck check) { + Player* player = GET_PLAYER(play); + + if (gSaveContext.entranceIndex == 0x02CA && LINK_IS_ADULT && player != NULL && + !Player_InBlockingCsMode(play, player) && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && + !Flags_GetRandomizerInf(RAND_INF_TOT_MASTER_SWORD)) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_MASTER_SWORD); + GiveItemEntryWithoutActor(play, getItemEntry); + player->pendingFlag.flagID = RAND_INF_TOT_MASTER_SWORD; + player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; + } +} + u8 CheckStoneCount() { u8 stoneCount = 0; @@ -1433,6 +1446,7 @@ skip: GivePlayerRandoRewardZeldaLightArrowsGift(play, RC_TOT_LIGHT_ARROWS_CUTSCENE); GivePlayerRandoRewardNocturne(play, RC_SHEIK_IN_KAKARIKO); GivePlayerRandoRewardRequiem(play, RC_SHEIK_AT_COLOSSUS); + GivePlayerRandoRewardMasterSword(play, RC_TOT_MASTER_SWORD); } } @@ -2315,17 +2329,8 @@ void Play_PerformSave(PlayState* play) { if (play != NULL && gSaveContext.fileNum != 0xFF) { Play_SaveSceneFlags(play); gSaveContext.savedSceneNum = play->sceneNum; - if (gSaveContext.temporaryWeapon) { - gSaveContext.equips.buttonItems[0] = ITEM_NONE; - GET_PLAYER(play)->currentSwordItemId = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); - Save_SaveFile(); - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - GET_PLAYER(play)->currentSwordItemId = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); - } else { - Save_SaveFile(); - } + Save_SaveFile(); + uint8_t triforceHuntCompleted = IS_RANDO && gSaveContext.triforcePiecesCollected == Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) && diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 1612c0fdc..225b29dc7 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -170,10 +170,12 @@ void Sram_OpenSave() { // check for owning kokiri sword.. to restore master sword? bug or debug feature? if (LINK_AGE_IN_YEARS == YEARS_ADULT && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { - gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - gSaveContext.equips.equipment &= ~0xF; - gSaveContext.equips.equipment |= 2; + if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; + gSaveContext.equips.equipment &= ~0xF; + gSaveContext.equips.equipment |= 2; + } } if (!(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) { diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 7680adb6f..b4e62d070 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -122,7 +122,9 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { if (!LINK_IS_ADULT || (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && !IS_RANDO) || IS_RANDO) { if (Actor_HasParent(&this->actor, play)) { if (!LINK_IS_ADULT) { - Item_Give(play, ITEM_SWORD_MASTER); + if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { + Item_Give(play, ITEM_SWORD_MASTER); + } play->csCtx.segment = D_808BB2F0; } else { play->csCtx.segment = D_808BB7A0; @@ -184,6 +186,11 @@ void BgTokiSwd_Draw(Actor* thisx, PlayState* play2) { BgTokiSwd* this = (BgTokiSwd*)thisx; s32 pad[3]; + // Do not draw the Master Sword in the pedestal if the player has not found it yet + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + return; + } + OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 13cc46e38..ea506ffbd 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -153,6 +153,8 @@ void func_808FD27C(PlayState* play, Vec3f* position, Vec3f* velocity, f32 scale) } } +static u8 hasFoundMasterSword; + void BossGanon2_Init(Actor* thisx, PlayState* play) { BossGanon2* this = (BossGanon2*)thisx; s32 pad; @@ -175,6 +177,11 @@ void BossGanon2_Init(Actor* thisx, PlayState* play) { func_808FD5C4(this, play); this->actor.naviEnemyId = 0x3E; this->actor.gravity = 0.0f; + + hasFoundMasterSword = 1; + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + hasFoundMasterSword = 0; + } } void BossGanon2_Destroy(Actor* thisx, PlayState* play) { @@ -2895,6 +2902,11 @@ void func_80905DA8(BossGanon2* this, PlayState* play) { effect->velocity.y += effect->accel.y; effect->velocity.z += effect->accel.z; if (effect->type == 1) { + // Prevent invisible master sword from making spark effect/sound when landing in the ground + // and prevent the player from picking it up if the player has not found the master sword + if (IS_RANDO && !hasFoundMasterSword) { + continue; + } if (effect->unk_2E == 0) { effect->unk_38.z += 1.0f; effect->unk_38.y = (2.0f * M_PI) / 5.0f; @@ -2955,6 +2967,11 @@ void func_809060E8(PlayState* play) { for (i = 0; i < 1; i++) { if (effect->type == 1) { + // Do not draw the master sword in the ground if the player has not found it yet + if (IS_RANDO && !hasFoundMasterSword) { + continue; + } + FrameInterpolation_RecordOpenChild("Ganon 809060E8 0", i); Vec3f spA0; diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index ecb16dcb6..3f8de83ba 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -5125,16 +5125,6 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) { this->unk_15C = 0; - - Player* player = GET_PLAYER(play); - - if (gSaveContext.temporaryWeapon) { - player->currentSwordItemId = ITEM_NONE; - gSaveContext.equips.buttonItems[0] = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); - gSaveContext.temporaryWeapon = false; - } - if (D_80B7A68C != 0) { D_80B7A688 = 1; D_80B7A68C = 0; diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index f4f465204..b575a0084 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -14946,6 +14946,16 @@ void func_80852648(PlayState* play, Player* this, CsCmdActorAction* arg2) { this->heldItemId = ITEM_NONE; this->modelGroup = this->nextModelGroup = Player_ActionToModelGroup(this, PLAYER_IA_NONE); this->leftHandDLists = gPlayerLeftHandOpenDLs; + + // If MS sword is shuffled and not in the players inventory, then we need to unequip the current sword + // and set swordless flag to mimic Link having his weapon knocked out of his hand in the Ganon fight + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + Inventory_ChangeEquipment(EQUIP_SWORD, 0); + gSaveContext.equips.buttonItems[0] = ITEM_NONE; + Flags_SetInfTable(INFTABLE_SWORDLESS); + return; + } + Inventory_ChangeEquipment(EQUIP_SWORD, 2); gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; Inventory_DeleteEquipment(play, 0); @@ -15135,17 +15145,6 @@ s32 Player_IsDroppingFish(PlayState* play) { s32 Player_StartFishing(PlayState* play) { Player* this = GET_PLAYER(play); - if (gSaveContext.linkAge == 1) { - if (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 0)) { - gSaveContext.temporaryWeapon = true; - } - if (this->heldItemId == ITEM_NONE) { - this->currentSwordItemId = ITEM_SWORD_KOKIRI; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); - } - } - func_80832564(play, this); func_80835F44(play, this, ITEM_FISHING_POLE); return 1; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 1229da3c3..95c8f7740 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -4378,6 +4378,9 @@ void KaleidoScope_Update(PlayState* play) gSaveContext.buttonStatus[buttonIndex] = sButtonStatusSave[buttonIndex]; } + // Used to clear swordless temp B after unpause so minigame/epona handling restarts + Interface_RandoRestoreSwordless(); + interfaceCtx->unk_1FA = interfaceCtx->unk_1FC = 0; osSyncPrintf(VT_FGCOL(YELLOW)); osSyncPrintf("i=%d LAST_TIME_TYPE=%d\n", i, gSaveContext.unk_13EE); |
