diff --git a/soh/assets/custom/objects/object_housekey/Hilite_new b/soh/assets/custom/objects/object_housekey/Hilite_new new file mode 100644 index 000000000..5438695fa Binary files /dev/null and b/soh/assets/custom/objects/object_housekey/Hilite_new differ diff --git a/soh/assets/custom/objects/object_housekey/HouseKey_Tag b/soh/assets/custom/objects/object_housekey/HouseKey_Tag new file mode 100644 index 000000000..4939ef966 Binary files /dev/null and b/soh/assets/custom/objects/object_housekey/HouseKey_Tag differ diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL b/soh/assets/custom/objects/object_housekey/gHouseKeyDL new file mode 100644 index 000000000..3d6787c3c --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_0 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_0 new file mode 100644 index 000000000..4c8002a6a --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_0 @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_1 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_1 new file mode 100644 index 000000000..06fdafc2d --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_1 @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_2 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_2 new file mode 100644 index 000000000..a606298d1 --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_tri_2 @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_0 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_0 new file mode 100644 index 000000000..cd0885c1c --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_0 @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_1 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_1 new file mode 100644 index 000000000..c4f2d8850 --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_1 @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_2 b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_2 new file mode 100644 index 000000000..dc377511e --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/gHouseKeyDL_vtx_2 @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeymetal b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeymetal new file mode 100644 index 000000000..90c65bd06 --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeymetal @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeyringmetal b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeyringmetal new file mode 100644 index 000000000..d7d19e315 --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeyringmetal @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeytag b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeytag new file mode 100644 index 000000000..05f2afc64 --- /dev/null +++ b/soh/assets/custom/objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeytag @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 78f4d281e..4cf6a4266 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -237,6 +237,9 @@ static const ALIGN_ASSET(2) char gKeyringKeysShadowTempleMQDL[] = dgKeyringKeysS #define dgKeyringKeysGanonsCastleMQDL "__OTR__objects/object_keyring/gKeyringKeysGanonsCastleMQDL" static const ALIGN_ASSET(2) char gKeyringKeysGanonsCastleMQDL[] = dgKeyringKeysGanonsCastleMQDL; +#define dgHouseKeyDL "__OTR__objects/object_housekey/gHouseKeyDL" +static const ALIGN_ASSET(2) char gHouseKeyDL[] = dgHouseKeyDL; + // overlays #define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx" static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 8eb939ec8..2a77b9b0a 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -1551,6 +1551,55 @@ const std::vector flagTables = { { RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" }, { RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" }, { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" }, + + { RAND_INF_GUARD_HOUSE_UNLOCKED, "RAND_INF_GUARD_HOUSE_UNLOCKED" }, + { RAND_INF_GUARD_HOUSE_KEY_OBTAINED, "RAND_INF_GUARD_HOUSE_KEY_OBTAINED" }, + { RAND_INF_MARKET_BAZAAR_UNLOCKED, "RAND_INF_MARKET_BAZAAR_UNLOCKED" }, + { RAND_INF_MARKET_BAZAAR_KEY_OBTAINED, "RAND_INF_MARKET_BAZAAR_KEY_OBTAINED" }, + { RAND_INF_MARKET_POTION_SHOP_UNLOCKED, "RAND_INF_MARKET_POTION_SHOP_UNLOCKED" }, + { RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED, "RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_MASK_SHOP_UNLOCKED, "RAND_INF_MASK_SHOP_UNLOCKED" }, + { RAND_INF_MASK_SHOP_KEY_OBTAINED, "RAND_INF_MASK_SHOP_KEY_OBTAINED" }, + { RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED" }, + { RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED" }, + { RAND_INF_BOMBCHU_BOWLING_UNLOCKED, "RAND_INF_BOMBCHU_BOWLING_UNLOCKED" }, + { RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED, "RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED" }, + { RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED" }, + { RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED" }, + { RAND_INF_BOMBCHU_SHOP_UNLOCKED, "RAND_INF_BOMBCHU_SHOP_UNLOCKED" }, + { RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED, "RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED" }, + { RAND_INF_RICHARDS_HOUSE_UNLOCKED, "RAND_INF_RICHARDS_HOUSE_UNLOCKED" }, + { RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED, "RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_ALLEY_HOUSE_UNLOCKED, "RAND_INF_ALLEY_HOUSE_UNLOCKED" }, + { RAND_INF_ALLEY_HOUSE_KEY_OBTAINED, "RAND_INF_ALLEY_HOUSE_KEY_OBTAINED" }, + { RAND_INF_KAK_BAZAAR_UNLOCKED, "RAND_INF_KAK_BAZAAR_UNLOCKED" }, + { RAND_INF_KAK_BAZAAR_KEY_OBTAINED, "RAND_INF_KAK_BAZAAR_KEY_OBTAINED" }, + { RAND_INF_KAK_POTION_SHOP_UNLOCKED, "RAND_INF_KAK_POTION_SHOP_UNLOCKED" }, + { RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED, "RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_BOSS_HOUSE_UNLOCKED, "RAND_INF_BOSS_HOUSE_UNLOCKED" }, + { RAND_INF_BOSS_HOUSE_KEY_OBTAINED, "RAND_INF_BOSS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED, "RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED" }, + { RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED, "RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_SKULLTULA_HOUSE_UNLOCKED, "RAND_INF_SKULLTULA_HOUSE_UNLOCKED" }, + { RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED, "RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED" }, + { RAND_INF_IMPAS_HOUSE_UNLOCKED, "RAND_INF_IMPAS_HOUSE_UNLOCKED" }, + { RAND_INF_IMPAS_HOUSE_KEY_OBTAINED, "RAND_INF_IMPAS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_WINDMILL_UNLOCKED, "RAND_INF_WINDMILL_UNLOCKED" }, + { RAND_INF_WINDMILL_KEY_OBTAINED, "RAND_INF_WINDMILL_KEY_OBTAINED" }, + { RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED" }, + { RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED" }, + { RAND_INF_DAMPES_HUT_UNLOCKED, "RAND_INF_DAMPES_HUT_UNLOCKED" }, + { RAND_INF_DAMPES_HUT_KEY_OBTAINED, "RAND_INF_DAMPES_HUT_KEY_OBTAINED" }, + { RAND_INF_TALONS_HOUSE_UNLOCKED, "RAND_INF_TALONS_HOUSE_UNLOCKED" }, + { RAND_INF_TALONS_HOUSE_KEY_OBTAINED, "RAND_INF_TALONS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_STABLES_UNLOCKED, "RAND_INF_STABLES_UNLOCKED" }, + { RAND_INF_STABLES_KEY_OBTAINED, "RAND_INF_STABLES_KEY_OBTAINED" }, + { RAND_INF_BACK_TOWER_UNLOCKED, "RAND_INF_BACK_TOWER_UNLOCKED" }, + { RAND_INF_BACK_TOWER_KEY_OBTAINED, "RAND_INF_BACK_TOWER_KEY_OBTAINED" }, + { RAND_INF_HYLIA_LAB_UNLOCKED, "RAND_INF_HYLIA_LAB_UNLOCKED" }, + { RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" }, + { RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" }, + { RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" }, } }, }; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 8c449ccdb..8810a2301 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -304,6 +304,13 @@ typedef enum { VB_FROGS_GO_TO_IDLE, // Vanilla condition: var >= gSaveContext.health) && (gSaveContext.health > 0 VB_HEALTH_METER_BE_CRITICAL, + VB_CONSUME_SMALL_KEY, + // Vanilla condition: gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0 + VB_NOT_HAVE_SMALL_KEY, + // Vanilla condition: !Flags_GetSwitch(play, this->actor.params & 0x3F) + VB_DOOR_BE_LOCKED, + // Vanilla condition: ((doorActor->params >> 7) & 7) == 3 + VB_DOOR_PLAY_SCENE_TRANSITION, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 1753dc30c..90b8272da 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1133,7 +1133,7 @@ void RegisterOpenAllHours() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { Actor* actor = static_cast(refActor); - if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR) && (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOCK_OVERWORLD_DOORS))) { switch (actor->params) { case 4753: // Night Market Bazaar case 1678: // Night Potion Shop diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 89c290a40..867da2b2c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -1361,7 +1361,18 @@ void StaticData::HintTable_Init_Item() { // /*spanish*/un destructor de cerraduras final CustomMessage("a final lockpick", /*german*/"ein finaler Dietrich", /*french*/"un crochet à porte final")}); // /*spanish*/una apertura portentosa final - + hintTextTable[RHT_OVERWORLD_KEY] = HintText(CustomMessage("an Overworld Key", /*german*/"ein Überwelt-Schlüssel", /*french*/"une clé de l'Overworld"), + // /*spanish*/una llave del mundo exterior + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave + }, { + CustomMessage("a key to the world", /*german*/"ein Schlüssel zur Welt", /*french*/"une clé du monde"), + // /*spanish*/una llave al mundo + CustomMessage("a key to the kingdom", /*german*/"ein Schlüssel zum Königreich", /*french*/"une clé du royaume"), + // /*spanish*/una llave al reino + CustomMessage("a key to the universe", /*german*/"ein Schlüssel zum Universum", /*french*/"une clé de l'univers")}); + // /*spanish*/una llave al universo hintTextTable[RHT_FOREST_TEMPLE_KEY_RING] = HintText(CustomMessage("a Forest Temple Key Ring", /*german*/"ein Schlüsselbund des Waldtempels", /*french*/"un trousseau de clés du Temple de la Forêt"), // /*spanish*/un llavero del Templo del Bosque { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index cee278220..b09d57dc4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -1276,6 +1276,33 @@ void GenerateItemPool() { } } + if (ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { + AddItemToPool(ItemPool, RG_GUARD_HOUSE_KEY); + AddItemToPool(ItemPool, RG_MARKET_BAZAAR_KEY); + AddItemToPool(ItemPool, RG_MARKET_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_MASK_SHOP_KEY); + AddItemToPool(ItemPool, RG_MARKET_SHOOTING_GALLERY_KEY); + AddItemToPool(ItemPool, RG_BOMBCHU_BOWLING_KEY); + AddItemToPool(ItemPool, RG_TREASURE_CHEST_GAME_BUILDING_KEY); + AddItemToPool(ItemPool, RG_BOMBCHU_SHOP_KEY); + AddItemToPool(ItemPool, RG_RICHARDS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_ALLEY_HOUSE_KEY); + AddItemToPool(ItemPool, RG_KAK_BAZAAR_KEY); + AddItemToPool(ItemPool, RG_KAK_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_BOSS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_GRANNYS_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_SKULLTULA_HOUSE_KEY); + AddItemToPool(ItemPool, RG_IMPAS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_WINDMILL_KEY); + AddItemToPool(ItemPool, RG_KAK_SHOOTING_GALLERY_KEY); + AddItemToPool(ItemPool, RG_DAMPES_HUT_KEY); + AddItemToPool(ItemPool, RG_TALONS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_STABLES_KEY); + AddItemToPool(ItemPool, RG_BACK_TOWER_KEY); + AddItemToPool(ItemPool, RG_HYLIA_LAB_KEY); + AddItemToPool(ItemPool, RG_FISHING_HOLE_KEY); + } + //Shopsanity if ( ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || diff --git a/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp new file mode 100644 index 000000000..e48a5763f --- /dev/null +++ b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp @@ -0,0 +1,154 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +extern PlayState* gPlayState; +#include "macros.h" +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex() + +using SceneDoorParamsPair = std::pair; +std::map lookupTable = { + {{ SCENE_MARKET_ENTRANCE_DAY, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED }, + {{ SCENE_MARKET_ENTRANCE_NIGHT, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED }, + {{ SCENE_MARKET_ENTRANCE_RUINS, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED }, + {{ SCENE_MARKET_GUARD_HOUSE, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED }, + {{ SCENE_MARKET_DAY, 4543 }, RAND_INF_MARKET_BAZAAR_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 4753 }, RAND_INF_MARKET_BAZAAR_UNLOCKED }, + {{ SCENE_MARKET_DAY, 1471 }, RAND_INF_MARKET_POTION_SHOP_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 1678 }, RAND_INF_MARKET_POTION_SHOP_UNLOCKED }, + {{ SCENE_MARKET_DAY, 3519 }, RAND_INF_MASK_SHOP_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 3728 }, RAND_INF_MASK_SHOP_UNLOCKED }, + {{ SCENE_MARKET_DAY, 2495 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 2703 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED }, + {{ SCENE_SHOOTING_GALLERY, 447 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED }, + {{ SCENE_MARKET_DAY, 5567 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 5567 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED }, + {{ SCENE_BOMBCHU_BOWLING_ALLEY, 447 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED }, + {{ SCENE_MARKET_DAY, 653 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED }, + {{ SCENE_MARKET_NIGHT, 447 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED }, + {{ SCENE_TREASURE_BOX_SHOP, 6591 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED }, + {{ SCENE_BACK_ALLEY_DAY, 2689 }, RAND_INF_BOMBCHU_SHOP_UNLOCKED }, + {{ SCENE_BACK_ALLEY_NIGHT, 2495 }, RAND_INF_BOMBCHU_SHOP_UNLOCKED }, + {{ SCENE_BACK_ALLEY_DAY, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED }, + {{ SCENE_BACK_ALLEY_NIGHT, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED }, + {{ SCENE_DOG_LADY_HOUSE, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED }, + {{ SCENE_DOG_LADY_HOUSE, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED }, + {{ SCENE_BACK_ALLEY_HOUSE, 447 }, RAND_INF_ALLEY_HOUSE_UNLOCKED }, + {{ SCENE_BACK_ALLEY_DAY, 1665 }, RAND_INF_ALLEY_HOUSE_UNLOCKED }, + {{ SCENE_BACK_ALLEY_NIGHT, 1471 }, RAND_INF_ALLEY_HOUSE_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 6801 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Adult Night + {{ SCENE_KAKARIKO_VILLAGE, 6591 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Adult Day + {{ SCENE_KAKARIKO_VILLAGE, 6813 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Child Day + {{ SCENE_KAKARIKO_VILLAGE, 6814 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Child Night + {{ SCENE_KAKARIKO_VILLAGE, 8871 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Child Day/Night Rear + {{ SCENE_KAKARIKO_VILLAGE, 8846 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Night Rear + {{ SCENE_KAKARIKO_VILLAGE, 8639 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Day Rear + {{ SCENE_KAKARIKO_VILLAGE, 7822 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Night + {{ SCENE_KAKARIKO_VILLAGE, 7615 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Child Day/Night and Adult Day + {{ SCENE_KAKARIKO_VILLAGE, 2495 }, RAND_INF_BOSS_HOUSE_UNLOCKED }, + {{ SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 447 }, RAND_INF_BOSS_HOUSE_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 3750 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED }, // Child + {{ SCENE_KAKARIKO_VILLAGE, 3519 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED }, // Adult + {{ SCENE_POTION_SHOP_GRANNY, 447 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 5567 }, RAND_INF_SKULLTULA_HOUSE_UNLOCKED }, + {{ SCENE_HOUSE_OF_SKULLTULA, 447 }, RAND_INF_SKULLTULA_HOUSE_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 1471 }, RAND_INF_IMPAS_HOUSE_UNLOCKED }, + {{ SCENE_IMPAS_HOUSE, 447 }, RAND_INF_IMPAS_HOUSE_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 447 }, RAND_INF_WINDMILL_UNLOCKED }, + {{ SCENE_WINDMILL_AND_DAMPES_GRAVE, 2495 }, RAND_INF_WINDMILL_UNLOCKED }, + {{ SCENE_KAKARIKO_VILLAGE, 4543 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED }, // Day + {{ SCENE_KAKARIKO_VILLAGE, 4751 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED }, // Night + {{ SCENE_SHOOTING_GALLERY, 447 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED }, + {{ SCENE_GRAVEYARD, 645 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Day + {{ SCENE_GRAVEYARD, 447 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Evening & Adult + {{ SCENE_GRAVEYARD, 774 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Night (After Dampes Tour) + {{ SCENE_GRAVEKEEPERS_HUT, 447 }, RAND_INF_DAMPES_HUT_UNLOCKED }, + {{ SCENE_LON_LON_RANCH, 2495 }, RAND_INF_TALONS_HOUSE_UNLOCKED }, + {{ SCENE_LON_LON_RANCH, 2473 }, RAND_INF_TALONS_HOUSE_UNLOCKED }, + {{ SCENE_LON_LON_RANCH, 2729 }, RAND_INF_TALONS_HOUSE_UNLOCKED }, + {{ SCENE_LON_LON_BUILDINGS, 1471 }, RAND_INF_TALONS_HOUSE_UNLOCKED }, + {{ SCENE_LON_LON_RANCH, 1471 }, RAND_INF_STABLES_UNLOCKED }, + {{ SCENE_STABLE, 447 }, RAND_INF_STABLES_UNLOCKED }, + {{ SCENE_LON_LON_RANCH, 447 }, RAND_INF_BACK_TOWER_UNLOCKED }, + {{ SCENE_LON_LON_BUILDINGS, 447 }, RAND_INF_BACK_TOWER_UNLOCKED }, + {{ SCENE_LAKE_HYLIA, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED }, + {{ SCENE_LAKESIDE_LABORATORY, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED }, + {{ SCENE_LAKE_HYLIA, 1471 }, RAND_INF_FISHING_HOLE_UNLOCKED }, + {{ SCENE_FISHING_POND, 447 }, RAND_INF_FISHING_HOLE_UNLOCKED }, +}; + +static void OnDoorInit(void* actorRef) { + EnDoor* enDoor = static_cast(actorRef); + enDoor->randomizerInf = RAND_INF_MAX; + + auto it = lookupTable.find({gPlayState->sceneNum, enDoor->actor.params}); + if (it != lookupTable.end()) { + if (it->second == RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED && gSaveContext.entranceIndex == 0x3B) { + // Adult shooting gallery uses same scene and door params as child, so we manually handle it + enDoor->randomizerInf = RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED; + } else { + enDoor->randomizerInf = it->second; + } + if (!Flags_GetRandomizerInf(enDoor->randomizerInf)) { + // We don't want to override checkable doors, we still want those to not be openable even if they have a key + if (((enDoor->actor.params >> 7) & 7) != DOOR_CHECKABLE) { + enDoor->actor.params = (enDoor->actor.params & ~0x380) | (DOOR_LOCKED << 7); + enDoor->actionFunc = EnDoor_SetupType; + } else { + enDoor->lockTimer = 10; + } + } + } +} + +void RegisterLockOverworldDoors() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_LOCK_OVERWORLD_DOORS); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_DOOR, shouldRegister, OnDoorInit); + + COND_VB_SHOULD(VB_CONSUME_SMALL_KEY, shouldRegister, { + EnDoor* enDoor = va_arg(args, EnDoor*); + + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + Flags_SetRandomizerInf(enDoor->randomizerInf); + *should = false; + } + }); + + COND_VB_SHOULD(VB_NOT_HAVE_SMALL_KEY, shouldRegister, { + EnDoor* enDoor = va_arg(args, EnDoor*); + + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + *should = !Flags_GetRandomizerInf((RandomizerInf)(enDoor->randomizerInf + 1)); + } + }); + + COND_VB_SHOULD(VB_DOOR_BE_LOCKED, shouldRegister, { + EnDoor* enDoor = va_arg(args, EnDoor*); + + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + *should = !Flags_GetRandomizerInf(enDoor->randomizerInf); + } + }); + + // The door actor uses the same param to indicate if a door should be locked or be a scene transition, so it cannot be both. Here we're + // overriding the check for scene transition to also check if the door is being unlocked and should be a scene transition. + COND_VB_SHOULD(VB_DOOR_PLAY_SCENE_TRANSITION, shouldRegister, { + EnDoor* enDoor = va_arg(args, EnDoor*); + + if (!*should && ( + enDoor->actor.id == ACTOR_EN_DOOR && + ((enDoor->actor.params >> 7) & 7) == 1 && + enDoor->randomizerInf != RAND_INF_MAX + )) { + *should = true; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterLockOverworldDoors, { "IS_RANDO" }); diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index fd07fe3fd..0a89e4dae 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -1229,3 +1229,18 @@ extern "C" void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* CLOSE_DISPS(play->state.gfxCtx); } } + +extern "C" void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gHouseKeyDL); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 31ac2c1fb..3fc5c86b4 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -25,6 +25,7 @@ void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry); #define GET_ITEM_MYSTERY \ { ITEM_NONE_FE, 0, 0, 0, 0, MOD_RANDOMIZER, MOD_RANDOMIZER, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE_FE, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem } diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d1ba2f9ea..689d1c396 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2370,6 +2370,8 @@ void RandomizerRegisterHooks() { static uint32_t shuffleFreestandingOnVanillaBehaviorHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + ShipInit::Init("IS_RANDO"); + randomizerQueuedChecks = std::queue(); randomizerQueuedCheck = RC_UNKNOWN_CHECK; randomizerQueuedItemEntry = GET_ITEM_NONE; diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 6aee0a775..0b94aab39 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -159,6 +159,54 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Kleiner Schlüssel für das Truhenspiel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE); + itemTable[RG_GUARD_HOUSE_KEY] = Item(RG_GUARD_HOUSE_KEY, Text{ "Guard House Key", "", "Schlüssel für das Haus der Wachen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GUARD_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_GUARD_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GUARD_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_MARKET_BAZAAR_KEY] = Item(RG_MARKET_BAZAAR_KEY, Text{ "Market Bazaar Key", "", "Schlüssel für den Basar des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_MARKET_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_MARKET_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_MARKET_POTION_SHOP_KEY] = Item(RG_MARKET_POTION_SHOP_KEY, Text{ "Market Potion Shop Key", "", "Schlüssel für den Magie-Laden des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MARKET_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_MARKET_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_MASK_SHOP_KEY] = Item(RG_MASK_SHOP_KEY, Text{ "Mask Shop Key", "", "Schlüssel für den Maskenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MASK_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MASK_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_MASK_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_MARKET_SHOOTING_GALLERY_KEY] = Item(RG_MARKET_SHOOTING_GALLERY_KEY, Text{ "Market Shooting Gallery Key", "", "Schlüssel für die Schießbude des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_MARKET_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_MARKET_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_BOMBCHU_BOWLING_KEY] = Item(RG_BOMBCHU_BOWLING_KEY, Text{ "Bombchu Bowling Alley Key", "", "Schlüssel für die Minenbowlingbahn" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_BOWLING_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_BOWLING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_BOWLING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY] = Item(RG_TREASURE_CHEST_GAME_BUILDING_KEY, Text{ "Treasure Chest Game Building Key", "", "Schlüssel für das Haus des Schatzkisten-Pokers" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TREASURE_CHEST_GAME_BUILDING_KEY,RHT_OVERWORLD_KEY, RG_TREASURE_CHEST_GAME_BUILDING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_BOMBCHU_SHOP_KEY] = Item(RG_BOMBCHU_SHOP_KEY, Text{ "Bombchu Shop Key", "", "Schlüssel für den Krabbelminenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_SHOP_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_RICHARDS_HOUSE_KEY] = Item(RG_RICHARDS_HOUSE_KEY, Text{ "Richard's House Key", "", "Schlüssel für das Haus von Richard" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_RICHARDS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_RICHARDS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_RICHARDS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_ALLEY_HOUSE_KEY] = Item(RG_ALLEY_HOUSE_KEY, Text{ "Alley House Key", "", "Schlüssel für das Gäßchenhaus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_ALLEY_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_ALLEY_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_ALLEY_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_KAK_BAZAAR_KEY] = Item(RG_KAK_BAZAAR_KEY, Text{ "Kakariko Bazaar Key", "", "Schlüssel für den Basar von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_KAK_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_KAK_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_KAK_POTION_SHOP_KEY] = Item(RG_KAK_POTION_SHOP_KEY, Text{ "Kakariko Potion Shop Key", "", "Schlüssel für den Magie-Laden von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_KAK_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_KAK_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_BOSS_HOUSE_KEY] = Item(RG_BOSS_HOUSE_KEY, Text{ "Boss's House Key", "", "Schlüssel für das Haus des Chefs" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOSS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_BOSS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_BOSS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_GRANNYS_POTION_SHOP_KEY] = Item(RG_GRANNYS_POTION_SHOP_KEY, Text{ "Granny's Potion Shop Key", "", "Schlüssel für Asas Hexenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GRANNYS_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_GRANNYS_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GRANNYS_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_SKULLTULA_HOUSE_KEY] = Item(RG_SKULLTULA_HOUSE_KEY, Text{ "Skulltula House Key", "", "Schlüssel für das Skulltula-Haus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_SKULLTULA_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_SKULLTULA_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SKULLTULA_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_IMPAS_HOUSE_KEY] = Item(RG_IMPAS_HOUSE_KEY, Text{ "Impa's House Key", "", "Schlüssel für das Haus von Impa" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_IMPAS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_IMPAS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_IMPAS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_WINDMILL_KEY] = Item(RG_WINDMILL_KEY, Text{ "Windmill Key", "", "Schlüssel für die Windmühle" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_WINDMILL_KEY, RHT_OVERWORLD_KEY, RG_WINDMILL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_WINDMILL_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_KAK_SHOOTING_GALLERY_KEY] = Item(RG_KAK_SHOOTING_GALLERY_KEY, Text{ "Kakariko Shooting Gallery Key", "", "Schlüssel für die Schießbude von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_KAK_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_KAK_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_DAMPES_HUT_KEY] = Item(RG_DAMPES_HUT_KEY, Text{ "Dampe's Hut Key", "", "Schlüssel für die Hütte von Boris" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_DAMPES_HUT_KEY, RHT_OVERWORLD_KEY, RG_DAMPES_HUT_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_DAMPES_HUT_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_TALONS_HOUSE_KEY] = Item(RG_TALONS_HOUSE_KEY, Text{ "Talon's House Key", "", "Schlüssel für das Haus von Talon" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TALONS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_TALONS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_TALONS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_STABLES_KEY] = Item(RG_STABLES_KEY, Text{ "Stables Key", "", "Schlüssel für die Ställe" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_STABLES_KEY, RHT_OVERWORLD_KEY, RG_STABLES_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_STABLES_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_BACK_TOWER_KEY] = Item(RG_BACK_TOWER_KEY, Text{ "Back Tower Key", "", "Schlüssel für den hinteren Turm" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BACK_TOWER_KEY, RHT_OVERWORLD_KEY, RG_BACK_TOWER_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_BACK_TOWER_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_HYLIA_LAB_KEY] = Item(RG_HYLIA_LAB_KEY, Text{ "Hylia Laboratory Key", "", "Schlüssel für das Hylia-Labor" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_HYLIA_LAB_KEY, RHT_OVERWORLD_KEY, RG_HYLIA_LAB_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_HYLIA_LAB_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); + itemTable[RG_FISHING_HOLE_KEY] = Item(RG_FISHING_HOLE_KEY, Text{ "Fishing Hole Key", "", "Schlüssel für den Fischweiher" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_FISHING_HOLE_KEY, RHT_OVERWORLD_KEY, RG_FISHING_HOLE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_FISHING_HOLE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); // Key Rings itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Schlüsselbund für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xD5, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index d6ded1312..eb906d227 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -24,7 +24,7 @@ void RegionTable_Init_Graveyard() { Entrance(RR_GRAVEYARD_COMPOSERS_GRAVE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), Entrance(RR_GRAVEYARD_HEART_PIECE_GRAVE, []{return logic->IsAdult || logic->AtNight;}), Entrance(RR_GRAVEYARD_DAMPES_GRAVE, []{return logic->IsAdult;}), - Entrance(RR_GRAVEYARD_DAMPES_HOUSE, []{return logic->IsAdult /*|| logic->AtDampeTime*/;}), //TODO: This needs to be handled in ToD rework + Entrance(RR_GRAVEYARD_DAMPES_HOUSE, []{return logic->IsAdult && logic->CanOpenOverworldDoor(RG_DAMPES_HUT_KEY) /*|| logic->AtDampeTime*/;}), //TODO: This needs to be handled in ToD rework Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return false;}), }); @@ -103,7 +103,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_DAMPE_HINT, logic->IsAdult), }, { //Exits - Entrance(RR_THE_GRAVEYARD, []{return true;}), + Entrance(RR_THE_GRAVEYARD, []{return logic->CanOpenOverworldDoor(RG_DAMPES_HUT_KEY);}), }); areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Region("Graveyard Warp Pad Region", "Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 7d22f30a0..d41055f95 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -33,14 +33,14 @@ void RegionTable_Init_Kakariko() { }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), - Entrance(RR_KAK_CARPENTER_BOSS_HOUSE, []{return true;}), - Entrance(RR_KAK_HOUSE_OF_SKULLTULA, []{return true;}), - Entrance(RR_KAK_IMPAS_HOUSE, []{return true;}), - Entrance(RR_KAK_WINDMILL, []{return true;}), - Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay;}), - Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay;}), + Entrance(RR_KAK_CARPENTER_BOSS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_BOSS_HOUSE_KEY);}), + Entrance(RR_KAK_HOUSE_OF_SKULLTULA, []{return logic->CanOpenOverworldDoor(RG_SKULLTULA_HOUSE_KEY);}), + Entrance(RR_KAK_IMPAS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_IMPAS_HOUSE_KEY);}), + Entrance(RR_KAK_WINDMILL, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}), + Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_BAZAAR_KEY);}), + Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}), Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS);}), - Entrance(RR_KAK_POTION_SHOP_FRONT, []{return logic->AtDay || logic->IsChild;}), + Entrance(RR_KAK_POTION_SHOP_FRONT, []{return logic->AtDay || logic->IsChild && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}), Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}), Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}), Entrance(RR_KAK_WATCHTOWER, []{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}), @@ -95,8 +95,8 @@ void RegionTable_Init_Kakariko() { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), Entrance(RR_KAK_OPEN_GROTTO, []{return true;}), - Entrance(RR_KAK_ODD_POTION_BUILDING, []{return logic->IsAdult;}), - Entrance(RR_KAK_POTION_SHOP_BACK, []{return logic->IsAdult && logic->AtDay;}), + Entrance(RR_KAK_ODD_POTION_BUILDING, []{return logic->IsAdult && logic->CanOpenOverworldDoor(RG_GRANNYS_POTION_SHOP_KEY);}), + Entrance(RR_KAK_POTION_SHOP_BACK, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}), }); areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", "Kak Carpenter Boss House", {}, NO_DAY_NIGHT_CYCLE, { @@ -104,7 +104,7 @@ void RegionTable_Init_Kakariko() { EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}), }, {}, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_BOSS_HOUSE_KEY);}), }); areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Region("Kak House of Skulltula", "Kak House of Skulltula", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -117,7 +117,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_100_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 100), }, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_SKULLTULA_HOUSE_KEY);}), }); areaTable[RR_KAK_IMPAS_HOUSE] = Region("Kak Impas House", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -125,7 +125,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)), }, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_IMPAS_HOUSE_KEY);}), }); areaTable[RR_KAK_IMPAS_HOUSE_BACK] = Region("Kak Impas House Back", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -146,7 +146,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}), }); areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", "Kak Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -169,7 +169,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}), }); areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", "Kak Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -203,7 +203,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), }, { // Exits - Entrance(RR_KAK_BACKYARD, []{return true;}), + Entrance(RR_KAK_BACKYARD, []{return logic->CanOpenOverworldDoor(RG_GRANNYS_POTION_SHOP_KEY);}), }); areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 148acad13..8833441e9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -44,7 +44,7 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_ZORAS_DOMAIN, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), - Entrance(RR_LH_LAB, []{return true;}), + Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), Entrance(RR_LH_GROTTO, []{return true;}), }); @@ -52,7 +52,7 @@ void RegionTable_Init_LakeHylia() { areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), - Entrance(RR_LH_FISHING_POND, []{return true;}), + Entrance(RR_LH_FISHING_POND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}), }); areaTable[RR_LH_OWL_FLIGHT] = Region("LH Owl Flight", "Lake Hylia", {RA_LAKE_HYLIA}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -70,7 +70,7 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_LAB_RIGHT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), }, { //Exits - Entrance(RR_LAKE_HYLIA, []{return true;}), + Entrance(RR_LAKE_HYLIA, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), }); // TODO: should some of these helpers be done via events instead? @@ -115,7 +115,7 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_FISHING_POLE_HINT, true), }, { //Exits - Entrance(RR_LH_FISHING_ISLAND, []{return true;}), + Entrance(RR_LH_FISHING_ISLAND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}), }); areaTable[RR_LH_GROTTO] = Region("LH Grotto", "LH Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index df73b78d9..fa1d7451e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -25,9 +25,9 @@ void RegionTable_Init_LonLonRanch() { }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), - Entrance(RR_LLR_TALONS_HOUSE, []{return true;}), - Entrance(RR_LLR_STABLES, []{return true;}), - Entrance(RR_LLR_TOWER, []{return true;}), + Entrance(RR_LLR_TALONS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_TALONS_HOUSE_KEY);}), + Entrance(RR_LLR_STABLES, []{return logic->CanOpenOverworldDoor(RG_STABLES_KEY);}), + Entrance(RR_LLR_TOWER, []{return logic->CanOpenOverworldDoor(RG_BACK_TOWER_KEY);}), Entrance(RR_LLR_GROTTO, []{return logic->IsChild;}), }); @@ -39,7 +39,7 @@ void RegionTable_Init_LonLonRanch() { LOCATION(RC_LLR_TALONS_HOUSE_POT_3, logic->CanBreakPots()), }, { //Exits - Entrance(RR_LON_LON_RANCH, []{return true;}), + Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_TALONS_HOUSE_KEY);}), }); areaTable[RR_LLR_STABLES] = Region("LLR Stables", "LLR Stables", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -48,7 +48,7 @@ void RegionTable_Init_LonLonRanch() { LOCATION(RC_LLR_STABLES_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), }, { //Exits - Entrance(RR_LON_LON_RANCH, []{return true;}), + Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_STABLES_KEY);}), }); areaTable[RR_LLR_TOWER] = Region("LLR Tower", "LLR Tower", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -58,7 +58,7 @@ void RegionTable_Init_LonLonRanch() { LOCATION(RC_LLR_TOWER_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), }, { //Exits - Entrance(RR_LON_LON_RANCH, []{return true;}), + Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_BACK_TOWER_KEY);}), }); areaTable[RR_LLR_GROTTO] = Region("LLR Grotto", "LLR Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 384485730..e0ef67aa5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -8,7 +8,7 @@ void RegionTable_Init_Market() { //Exits Entrance(RR_HYRULE_FIELD, []{return logic->IsAdult || logic->AtDay;}), Entrance(RR_THE_MARKET, []{return true;}), - Entrance(RR_MARKET_GUARD_HOUSE, []{return true;}), + Entrance(RR_MARKET_GUARD_HOUSE, []{return logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}), }); areaTable[RR_THE_MARKET] = Region("Market", "Market", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -16,21 +16,21 @@ void RegionTable_Init_Market() { Entrance(RR_MARKET_ENTRANCE, []{return true;}), Entrance(RR_TOT_ENTRANCE, []{return true;}), Entrance(RR_CASTLE_GROUNDS, []{return true;}), - Entrance(RR_MARKET_BAZAAR, []{return logic->IsChild && logic->AtDay;}), - Entrance(RR_MARKET_MASK_SHOP, []{return logic->IsChild && logic->AtDay;}), - Entrance(RR_MARKET_SHOOTING_GALLERY, []{return logic->IsChild && logic->AtDay;}), - Entrance(RR_MARKET_BOMBCHU_BOWLING, []{return logic->IsChild;}), - Entrance(RR_MARKET_TREASURE_CHEST_GAME, []{return logic->IsChild && logic->AtNight;}), - Entrance(RR_MARKET_POTION_SHOP, []{return logic->IsChild && logic->AtDay;}), + Entrance(RR_MARKET_BAZAAR, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_BAZAAR_KEY);}), + Entrance(RR_MARKET_MASK_SHOP, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MASK_SHOP_KEY);}), + Entrance(RR_MARKET_SHOOTING_GALLERY, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_SHOOTING_GALLERY_KEY);}), + Entrance(RR_MARKET_BOMBCHU_BOWLING, []{return logic->IsChild && logic->CanOpenOverworldDoor(RG_BOMBCHU_BOWLING_KEY);}), + Entrance(RR_MARKET_TREASURE_CHEST_GAME, []{return logic->IsChild && logic->AtNight && logic->CanOpenOverworldDoor(RG_TREASURE_CHEST_GAME_BUILDING_KEY);}), + Entrance(RR_MARKET_POTION_SHOP, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_POTION_SHOP_KEY);}), Entrance(RR_MARKET_BACK_ALLEY, []{return logic->IsChild;}), }); areaTable[RR_MARKET_BACK_ALLEY] = Region("Market Back Alley", "Market", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_THE_MARKET, []{return true;}), - Entrance(RR_MARKET_BOMBCHU_SHOP, []{return logic->AtNight;}), - Entrance(RR_MARKET_DOG_LADY_HOUSE, []{return true;}), - Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, []{return logic->AtNight;}), + Entrance(RR_MARKET_BOMBCHU_SHOP, []{return logic->AtNight && logic->CanOpenOverworldDoor(RG_BOMBCHU_SHOP_KEY);}), + Entrance(RR_MARKET_DOG_LADY_HOUSE, []{return logic->CanOpenOverworldDoor(RG_RICHARDS_HOUSE_KEY);}), + Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, []{return logic->AtNight && logic->CanOpenOverworldDoor(RG_ALLEY_HOUSE_KEY);}), }); areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", "Market Guard House", {}, NO_DAY_NIGHT_CYCLE, { @@ -98,7 +98,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_11, logic->IsAdult && logic->CanBreakPots()), }, { //Exits - Entrance(RR_MARKET_ENTRANCE, []{return true;}), + Entrance(RR_MARKET_ENTRANCE, []{return logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}), }); areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", "Market Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -133,7 +133,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)), }, { //Exits - Entrance(RR_THE_MARKET, []{return true;}), + Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_MARKET_SHOOTING_GALLERY_KEY);}), }); areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", "Market Bombchu Bowling", {}, NO_DAY_NIGHT_CYCLE, { @@ -145,7 +145,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), }, { //Exits - Entrance(RR_THE_MARKET, []{return true;}), + Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_BOMBCHU_BOWLING_KEY);}), }); areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", "Market Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -179,7 +179,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits - Entrance(RR_THE_MARKET, []{return true;}), + Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_TREASURE_CHEST_GAME_BUILDING_KEY);}), }); areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", "Market Bombchu Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -202,7 +202,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), }, { //Exits - Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), + Entrance(RR_MARKET_BACK_ALLEY, []{return logic->CanOpenOverworldDoor(RG_RICHARDS_HOUSE_KEY);}), }); areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Region("Market Man in Green House", "Market Man in Green House", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -212,6 +212,6 @@ void RegionTable_Init_Market() { LOCATION(RC_MK_BACK_ALLEY_HOUSE_POT_3, logic->CanBreakPots()), }, { //Exits - Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), + Entrance(RR_MARKET_BACK_ALLEY, []{return logic->CanOpenOverworldDoor(RG_ALLEY_HOUSE_KEY);}), }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index cd65fd006..1be61ccae 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -140,6 +140,31 @@ namespace Rando { case RG_TWINROVA_SOUL: case RG_GANON_SOUL: case RG_SKELETON_KEY: + // Overworld Keys + case RG_GUARD_HOUSE_KEY: + case RG_MARKET_BAZAAR_KEY: + case RG_MARKET_POTION_SHOP_KEY: + case RG_MASK_SHOP_KEY: + case RG_MARKET_SHOOTING_GALLERY_KEY: + case RG_BOMBCHU_BOWLING_KEY: + case RG_TREASURE_CHEST_GAME_BUILDING_KEY: + case RG_BOMBCHU_SHOP_KEY: + case RG_RICHARDS_HOUSE_KEY: + case RG_ALLEY_HOUSE_KEY: + case RG_KAK_BAZAAR_KEY: + case RG_KAK_POTION_SHOP_KEY: + case RG_BOSS_HOUSE_KEY: + case RG_GRANNYS_POTION_SHOP_KEY: + case RG_SKULLTULA_HOUSE_KEY: + case RG_IMPAS_HOUSE_KEY: + case RG_WINDMILL_KEY: + case RG_KAK_SHOOTING_GALLERY_KEY: + case RG_DAMPES_HUT_KEY: + case RG_TALONS_HOUSE_KEY: + case RG_STABLES_KEY: + case RG_BACK_TOWER_KEY: + case RG_HYLIA_LAB_KEY: + case RG_FISHING_HOLE_KEY: return CheckRandoInf(RandoGetToRandInf.at(itemName)); // Boss Keys case RG_EPONA: @@ -382,6 +407,18 @@ namespace Rando { } } + bool Logic::CanOpenOverworldDoor(RandomizerGet key) { + if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { + return true; + } + + if (HasItem(RG_SKELETON_KEY)) { + return true; + } + + return HasItem(key); + } + uint8_t GetDifficultyValueFromString(Rando::Option& glitchOption) { return 0; } @@ -1293,7 +1330,31 @@ namespace Rando { { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, - { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND } + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED }, + { RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED }, + { RG_MARKET_POTION_SHOP_KEY, RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED }, + { RG_MASK_SHOP_KEY, RAND_INF_MASK_SHOP_KEY_OBTAINED }, + { RG_MARKET_SHOOTING_GALLERY_KEY, RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED }, + { RG_BOMBCHU_BOWLING_KEY, RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED }, + { RG_TREASURE_CHEST_GAME_BUILDING_KEY, RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED }, + { RG_BOMBCHU_SHOP_KEY, RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED }, + { RG_RICHARDS_HOUSE_KEY, RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED }, + { RG_ALLEY_HOUSE_KEY, RAND_INF_ALLEY_HOUSE_KEY_OBTAINED }, + { RG_KAK_BAZAAR_KEY, RAND_INF_KAK_BAZAAR_KEY_OBTAINED }, + { RG_KAK_POTION_SHOP_KEY, RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED }, + { RG_BOSS_HOUSE_KEY, RAND_INF_BOSS_HOUSE_KEY_OBTAINED }, + { RG_GRANNYS_POTION_SHOP_KEY, RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED }, + { RG_SKULLTULA_HOUSE_KEY, RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED }, + { RG_IMPAS_HOUSE_KEY, RAND_INF_IMPAS_HOUSE_KEY_OBTAINED }, + { RG_WINDMILL_KEY, RAND_INF_WINDMILL_KEY_OBTAINED }, + { RG_KAK_SHOOTING_GALLERY_KEY, RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED }, + { RG_DAMPES_HUT_KEY, RAND_INF_DAMPES_HUT_KEY_OBTAINED }, + { RG_TALONS_HOUSE_KEY, RAND_INF_TALONS_HOUSE_KEY_OBTAINED }, + { RG_STABLES_KEY, RAND_INF_STABLES_KEY_OBTAINED }, + { RG_BACK_TOWER_KEY, RAND_INF_BACK_TOWER_KEY_OBTAINED }, + { RG_HYLIA_LAB_KEY, RAND_INF_HYLIA_LAB_KEY_OBTAINED }, + { RG_FISHING_HOLE_KEY, RAND_INF_FISHING_HOLE_KEY_OBTAINED }, }; std::map Logic::RandoGetToDungeonScene = { @@ -1635,6 +1696,30 @@ namespace Rando { case RG_OCARINA_C_RIGHT_BUTTON: case RG_GREG_RUPEE: case RG_FISHING_POLE: + case RG_GUARD_HOUSE_KEY: + case RG_MARKET_BAZAAR_KEY: + case RG_MARKET_POTION_SHOP_KEY: + case RG_MASK_SHOP_KEY: + case RG_MARKET_SHOOTING_GALLERY_KEY: + case RG_BOMBCHU_BOWLING_KEY: + case RG_TREASURE_CHEST_GAME_BUILDING_KEY: + case RG_BOMBCHU_SHOP_KEY: + case RG_RICHARDS_HOUSE_KEY: + case RG_ALLEY_HOUSE_KEY: + case RG_KAK_BAZAAR_KEY: + case RG_KAK_POTION_SHOP_KEY: + case RG_BOSS_HOUSE_KEY: + case RG_GRANNYS_POTION_SHOP_KEY: + case RG_SKULLTULA_HOUSE_KEY: + case RG_IMPAS_HOUSE_KEY: + case RG_WINDMILL_KEY: + case RG_KAK_SHOOTING_GALLERY_KEY: + case RG_DAMPES_HUT_KEY: + case RG_TALONS_HOUSE_KEY: + case RG_STABLES_KEY: + case RG_BACK_TOWER_KEY: + case RG_HYLIA_LAB_KEY: + case RG_FISHING_HOLE_KEY: SetRandoInf(RandoGetToRandInf.at(randoGet), state); break; case RG_TRIFORCE_PIECE: diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 3aff99d67..ea9d51801 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -186,6 +186,7 @@ class Logic { bool HasProjectile(HasProjectileAge age); bool HasItem(RandomizerGet itemName); bool HasBossSoul(RandomizerGet itemName); + bool CanOpenOverworldDoor(RandomizerGet itemName); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool CanDoGlitch(GlitchType glitch); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 2e577c51e..ee59b1be4 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -41,6 +41,7 @@ void Settings::CreateOptionDescriptions() { "\n" "Open - Sleeping Waterfall is always open. " "Link may always enter Zora's Domain."; + mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] = "Add locks to all wooden overworld doors, requiring specific small keys to open them"; mOptionDescriptions[RSK_STARTING_AGE] = "Choose which age Link will start as.\n\n" "Starting as adult means you start with the Master Sword in your inventory.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 301498bf8..2d0ceb48a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3338,7 +3338,7 @@ 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 getItemMessages = {{ + const std::array getItemMessages = {{ GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn wirklich gefunden!", @@ -3386,40 +3386,140 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für das %yDiebesversteck%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %yDiebesversteck%w!", "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), GIMESSAGE(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %gWaldtempel%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gWaldtempel%w!", "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), GIMESSAGE(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %rFeuertempel%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %rFeuertempel%w!", "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), GIMESSAGE(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %bWassertempel%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %bWassertempel%w!", "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), GIMESSAGE(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %yGeistertempel%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %yGeistertempel%w!", "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), GIMESSAGE(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %pSchattentempel%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %pSchattentempel%w!", "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), GIMESSAGE(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für den %pGrund des Brunnens%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %pGrund des Brunnens%w!", "Vous obtenez une %rPetite Clé %w&du %pPuits%w!"), GIMESSAGE(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für die %yGerudo-Trainingsarena%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %yGerudo-Trainingsarena%w!", "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), GIMESSAGE(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!", - "Du erhältst einen %rKleinen&Schlüssel%w für %rGanons Schloß%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für %rGanons Schloß%w!", "Vous obtenez une %rPetite Clé %w&du %rChâteau de Ganon%w!"), + GIMESSAGE(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gGuard House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus der Wachen%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison des Gardes%w!"), + GIMESSAGE(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gMarket Bazaar%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar des Marktes%w!", + "Vous obtenez une %rPetite Clé %w&du %gMarché%w!"), + GIMESSAGE(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gMarket Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden des Marktes%w!", + "Vous obtenez une %rPetite Clé %w&du %gMarché%w!"), + GIMESSAGE(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gMask Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMaskenladen%w!", + "Vous obtenez une %rPetite Clé %w&du %gMagasin de Masques%w!"), + GIMESSAGE(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gMarket Shooting Gallery%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude des Marktes%w!", + "Vous obtenez une %rPetite Clé %w&du %gStand de Tir%w!"), + GIMESSAGE(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gBombchu Bowling Alley%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gMinenbowlingbahn%w!", + "Vous obtenez une %rPetite Clé %w&du %gBowling Bombchu%w!"), + GIMESSAGE(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gTreasure Chest Game Building%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Schatzkisten-Pokers%w!", + "Vous obtenez une %rPetite Clé %w&du %gJeu de la Chasse au Trésor%w!"), + GIMESSAGE(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gBombchu Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gKrabbelminenladen%w!", + "Vous obtenez une %rPetite Clé %w&du %gMagasin de Bombchu%w!"), + GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to&%gRichard's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison de Richard%w!"), + GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to&%gRichard's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison de Richard%w!"), + GIMESSAGE(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to&the %gAlley House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus in der Gasse%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison de la Ruelle%w!"), + GIMESSAGE(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gKakariko Bazaar%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar von Kakariko%w!", + "Vous obtenez une %rPetite Clé %w&du %gMarché de Cocorico%w!"), + GIMESSAGE(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gKakariko Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden von Kakariko%w!", + "Vous obtenez une %rPetite Clé %w&du %gMagasin de Potions de Cocorico%w!"), + GIMESSAGE(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gBoss's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Chefs%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison du Boss%w!"), + GIMESSAGE(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, + "You found the key to&%gGranny's Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für %gAsas Hexenladen%w!", + "Vous obtenez une %rPetite Clé %w&du %gMagasin de Potions de Grand-mère%w!"), + GIMESSAGE(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gSkulltula House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gSkulltula-Haus%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison des Skulltulas%w!"), + GIMESSAGE(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to&%gImpa's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Impa%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison d'Impa%w!"), + GIMESSAGE(RG_WINDMILL_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gWindmill%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gWindmühle%w!", + "Vous obtenez une %rPetite Clé %w&du %gMoulin à Vent%w!"), + GIMESSAGE(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gKakariko Shooting Gallery%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude von Kakariko%w!", + "Vous obtenez une %rPetite Clé %w&du %gStand de Tir de Cocorico%w!"), + GIMESSAGE(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, + "You found the key to&%gDampe's Hut%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gHütte von Boris%w!", + "Vous obtenez une %rPetite Clé %w&du %gChalet de Dampe%w!"), + GIMESSAGE(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, + "You found the key to&%gTalon's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Talon%w!", + "Vous obtenez une %rPetite Clé %w&de la %gMaison de Talon%w!"), + GIMESSAGE(RG_STABLES_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gStables%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gStälle%w!", + "Vous obtenez une %rPetite Clé %w&des %gÉcuries%w!"), + GIMESSAGE(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gBack Tower%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %ghinteren Turm%w!", + "Vous obtenez une %rPetite Clé %w&du %gTour Arrière%w!"), + GIMESSAGE(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gHylia Laboratory%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHylia-Labor%w!", + "Vous obtenez une %rPetite Clé %w&du %gLaboratoire d'Hylia%w!"), + GIMESSAGE(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, + "You found the key to the&%gFishing Hole%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gFischweiher%w!", + "Vous obtenez une %rPetite Clé %w&du %gTrou de Pêche%w!"), GIMESSAGE(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wKeyring!", @@ -3953,6 +4053,9 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; return Return_Item_Entry(giEntry, RG_NONE); + } else if (item >= RG_GUARD_HOUSE_KEY && item <= RG_FISHING_HOLE_KEY) { + Flags_SetRandomizerInf((RandomizerInf)((int)RAND_INF_GUARD_HOUSE_UNLOCKED + ((item - RG_GUARD_HOUSE_KEY) * 2) + 1)); + return Return_Item_Entry(giEntry, RG_NONE); } switch (item) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index d7edb01df..b30ee48ce 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -148,6 +148,30 @@ typedef enum { LOGIC_GANONS_CASTLE_KEYS, LOGIC_TREASURE_GAME_KEYS, LOGIC_SKELETON_KEY, + LOGIC_GUARD_HOUSE_KEY, + LOGIC_MARKET_BAZAAR_KEY, + LOGIC_MARKET_POTION_SHOP_KEY, + LOGIC_MASK_SHOP_KEY, + LOGIC_MARKET_SHOOTING_GALLERY_KEY, + LOGIC_BOMBCHU_BOWLING_KEY, + LOGIC_TREASURE_CHEST_GAME_BUILDING_KEY, + LOGIC_BOMBCHU_SHOP_KEY, + LOGIC_RICHARDS_HOUSE_KEY, + LOGIC_ALLEY_HOUSE_KEY, + LOGIC_KAK_BAZAAR_KEY, + LOGIC_KAK_POTION_SHOP_KEY, + LOGIC_BOSS_HOUSE_KEY, + LOGIC_GRANNYS_POTION_SHOP_KEY, + LOGIC_SKULLTULA_HOUSE_KEY, + LOGIC_IMPAS_HOUSE_KEY, + LOGIC_WINDMILL_KEY, + LOGIC_KAK_SHOOTING_GALLERY_KEY, + LOGIC_DAMPES_HUT_KEY, + LOGIC_TALONS_HOUSE_KEY, + LOGIC_STABLES_KEY, + LOGIC_BACK_TOWER_KEY, + LOGIC_HYLIA_LAB_KEY, + LOGIC_FISHING_HOLE_KEY, LOGIC_KOKIRI_EMERALD, LOGIC_GORON_RUBY, LOGIC_ZORA_SAPPHIRE, @@ -3341,6 +3365,30 @@ typedef enum { RG_HOOKSHOT, RG_LONGSHOT, RG_SCARECROW, + RG_GUARD_HOUSE_KEY, + RG_MARKET_BAZAAR_KEY, + RG_MARKET_POTION_SHOP_KEY, + RG_MASK_SHOP_KEY, + RG_MARKET_SHOOTING_GALLERY_KEY, + RG_BOMBCHU_BOWLING_KEY, + RG_TREASURE_CHEST_GAME_BUILDING_KEY, + RG_BOMBCHU_SHOP_KEY, + RG_RICHARDS_HOUSE_KEY, + RG_ALLEY_HOUSE_KEY, + RG_KAK_BAZAAR_KEY, + RG_KAK_POTION_SHOP_KEY, + RG_BOSS_HOUSE_KEY, + RG_GRANNYS_POTION_SHOP_KEY, + RG_SKULLTULA_HOUSE_KEY, + RG_IMPAS_HOUSE_KEY, + RG_WINDMILL_KEY, + RG_KAK_SHOOTING_GALLERY_KEY, + RG_DAMPES_HUT_KEY, + RG_TALONS_HOUSE_KEY, + RG_STABLES_KEY, + RG_BACK_TOWER_KEY, + RG_HYLIA_LAB_KEY, + RG_FISHING_HOLE_KEY, // Logic Only RG_DISTANT_SCARECROW, RG_STICKS, @@ -4614,6 +4662,7 @@ typedef enum { RHT_FISHING_POLE, RHT_SKELETON_KEY, RHT_EPONA, + RHT_OVERWORLD_KEY, RHT_HINT_MYSTERIOUS, RHT_MYSTERIOUS_ITEM, RHT_MYSTERIOUS_ITEM_CAPITAL, @@ -5300,6 +5349,7 @@ typedef enum { RSK_SHUFFLE_DEKU_NUT_BAG, RSK_SHUFFLE_FREESTANDING, RSK_SHUFFLE_FAIRIES, + RSK_LOCK_OVERWORLD_DOORS, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index c66c06fab..4140752e0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1272,6 +1272,56 @@ typedef enum { RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, + + RAND_INF_GUARD_HOUSE_UNLOCKED, + RAND_INF_GUARD_HOUSE_KEY_OBTAINED, + RAND_INF_MARKET_BAZAAR_UNLOCKED, + RAND_INF_MARKET_BAZAAR_KEY_OBTAINED, + RAND_INF_MARKET_POTION_SHOP_UNLOCKED, + RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED, + RAND_INF_MASK_SHOP_UNLOCKED, + RAND_INF_MASK_SHOP_KEY_OBTAINED, + RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED, + RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED, + RAND_INF_BOMBCHU_BOWLING_UNLOCKED, + RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED, + RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED, + RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED, + RAND_INF_BOMBCHU_SHOP_UNLOCKED, + RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED, + RAND_INF_RICHARDS_HOUSE_UNLOCKED, + RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED, + RAND_INF_ALLEY_HOUSE_UNLOCKED, + RAND_INF_ALLEY_HOUSE_KEY_OBTAINED, + RAND_INF_KAK_BAZAAR_UNLOCKED, + RAND_INF_KAK_BAZAAR_KEY_OBTAINED, + RAND_INF_KAK_POTION_SHOP_UNLOCKED, + RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED, + RAND_INF_BOSS_HOUSE_UNLOCKED, + RAND_INF_BOSS_HOUSE_KEY_OBTAINED, + RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED, + RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED, + RAND_INF_SKULLTULA_HOUSE_UNLOCKED, + RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED, + RAND_INF_IMPAS_HOUSE_UNLOCKED, + RAND_INF_IMPAS_HOUSE_KEY_OBTAINED, + RAND_INF_WINDMILL_UNLOCKED, + RAND_INF_WINDMILL_KEY_OBTAINED, + RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED, + RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED, + RAND_INF_DAMPES_HUT_UNLOCKED, + RAND_INF_DAMPES_HUT_KEY_OBTAINED, + RAND_INF_TALONS_HOUSE_UNLOCKED, + RAND_INF_TALONS_HOUSE_KEY_OBTAINED, + RAND_INF_STABLES_UNLOCKED, + RAND_INF_STABLES_KEY_OBTAINED, + RAND_INF_BACK_TOWER_UNLOCKED, + RAND_INF_BACK_TOWER_KEY_OBTAINED, + RAND_INF_HYLIA_LAB_UNLOCKED, + RAND_INF_HYLIA_LAB_KEY_OBTAINED, + RAND_INF_FISHING_HOLE_UNLOCKED, + RAND_INF_FISHING_HOLE_KEY_OBTAINED, + // 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) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index ef7cb0cd5..b29cccf97 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -110,6 +110,7 @@ void Settings::CreateOptions() { mOptions[RSK_DOOR_OF_TIME] = Option::U8("Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox); mOptions[RSK_ZORAS_FOUNTAIN] = Option::U8("Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]); mOptions[RSK_SLEEPING_WATERFALL] = Option::U8("Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]); + mOptions[RSK_LOCK_OVERWORLD_DOORS] = Option::Bool("Lock Overworld Doors", CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS]); mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]); mOptions[RSK_RAINBOW_BRIDGE] = Option::U8("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WidgetType::Combobox, RO_BRIDGE_VANILLA, false, IMFLAG_NONE); mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); @@ -551,6 +552,7 @@ void Settings::CreateOptions() { &mOptions[RSK_DOOR_OF_TIME], &mOptions[RSK_ZORAS_FOUNTAIN], &mOptions[RSK_SLEEPING_WATERFALL], + &mOptions[RSK_LOCK_OVERWORLD_DOORS], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", { &mOptions[RSK_STARTING_AGE], @@ -805,6 +807,7 @@ void Settings::CreateOptions() { &mOptions[RSK_DOOR_OF_TIME], &mOptions[RSK_ZORAS_FOUNTAIN], &mOptions[RSK_SLEEPING_WATERFALL], + &mOptions[RSK_LOCK_OVERWORLD_DOORS], &mOptions[RSK_GERUDO_FORTRESS], &mOptions[RSK_RAINBOW_BRIDGE], &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 1edb7e461..1bb47877b 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -773,7 +773,9 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("The default response to Kaepora Gaebora is always that you understood what he said"); UIWidgets::PaddedEnhancementCheckbox("Exit Market at Night", CVAR_ENHANCEMENT("MarketSneak"), true, false); UIWidgets::Tooltip("Allows exiting Hyrule Castle Market Town to Hyrule Field at night by speaking to the guard next to the gate."); - UIWidgets::PaddedEnhancementCheckbox("Shops and Games Always Open", CVAR_ENHANCEMENT("OpenAllHours"), true, false); + bool randoLockedOverworldDoors = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOCK_OVERWORLD_DOORS); + UIWidgets::PaddedEnhancementCheckbox("Shops and Games Always Open", CVAR_ENHANCEMENT("OpenAllHours"), true, false, randoLockedOverworldDoors, + "This is not compatible with the Locked Overworld Doors Randomizer option", UIWidgets::CheckboxGraphics::Checkmark); UIWidgets::Tooltip("Shops and minigames are open both day and night. Requires scene reload to take effect."); UIWidgets::PaddedEnhancementCheckbox("Link as default file name", CVAR_ENHANCEMENT("LinkDefaultName"), true, false); UIWidgets::Tooltip("Allows you to have \"Link\" as a premade file name"); diff --git a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c index 99ce9729f..8208881d2 100644 --- a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c +++ b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c @@ -11,6 +11,7 @@ #include "objects/object_mizu_objects/object_mizu_objects.h" #include "objects/object_haka_door/object_haka_door.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -162,7 +163,7 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) { } this->actor.world.rot.y = 0x0000; if (doorType == DOOR_LOCKED) { - if (!Flags_GetSwitch(play, this->actor.params & 0x3F)) { + if (GameInteractor_Should(VB_DOOR_BE_LOCKED, !Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { this->lockTimer = 10; } } else if (doorType == DOOR_AJAR) { @@ -201,8 +202,10 @@ void EnDoor_Idle(EnDoor* this, PlayState* play) { Animation_PlayOnceSetSpeed(&this->skelAnime, D_809FCECC[this->animStyle], (player->stateFlags1 & PLAYER_STATE1_IN_WATER) ? 0.75f : 1.5f); if (this->lockTimer != 0) { - gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--; - Flags_SetSwitch(play, this->actor.params & 0x3F); + if (GameInteractor_Should(VB_CONSUME_SMALL_KEY, true, this)) { + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--; + Flags_SetSwitch(play, this->actor.params & 0x3F); + } Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIN_KEY_UNLOCK); } } else if (!Player_InCsMode(play)) { @@ -214,7 +217,7 @@ void EnDoor_Idle(EnDoor* this, PlayState* play) { } if (ABS(phi_v0) < 0x3000) { if (this->lockTimer != 0) { - if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0) { + if (GameInteractor_Should(VB_NOT_HAVE_SMALL_KEY, gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0, this)) { Player* player2 = GET_PLAYER(play); player2->naviTextId = -0x203; diff --git a/soh/src/overlays/actors/ovl_En_Door/z_en_door.h b/soh/src/overlays/actors/ovl_En_Door/z_en_door.h index 4e7ef1279..a21047d74 100644 --- a/soh/src/overlays/actors/ovl_En_Door/z_en_door.h +++ b/soh/src/overlays/actors/ovl_En_Door/z_en_door.h @@ -55,6 +55,9 @@ typedef struct EnDoor { /* 0x0198 */ Vec3s jointTable[5]; /* 0x01B6 */ Vec3s morphTable[5]; /* 0x01D4 */ EnDoorActionFunc actionFunc; + // #region SOH [Randomizer] + /* */ RandomizerInf randomizerInf; + // #endregion } EnDoor; // size = 0x01D8 #ifdef __cplusplus 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 7b1454aaf..97a57caeb 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5418,7 +5418,7 @@ s32 Player_ActionHandler_1(Player* this, PlayState* play) { this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; Actor_DisableLens(play); - if (((doorActor->params >> 7) & 7) == 3) { + if (GameInteractor_Should(VB_DOOR_PLAY_SCENE_TRANSITION, ((doorActor->params >> 7) & 7) == 3, doorActor)) { checkPos.x = doorActor->world.pos.x - (sp6C * sp74); checkPos.y = doorActor->world.pos.y + 10.0f; checkPos.z = doorActor->world.pos.z - (sp6C * sp78);