diff --git a/mods/randomizer/generator/data/flow_patches.yaml b/mods/randomizer/generator/data/flow_patches.yaml index 9354d1e3bb..3a4e6fd491 100644 --- a/mods/randomizer/generator/data/flow_patches.yaml +++ b/mods/randomizer/generator/data/flow_patches.yaml @@ -296,7 +296,58 @@ message: 0x25B next: 0x202 -#6: # zel_06.bmg +6: # zel_06.bmg - Faron Woods interiors and other shared areas + # Modify Coro's flow so that all 3 items can be collected at any time + # Change all start indices to first check for first item flag + - index: + - 0x4F + - 0xEE + - 0xFF + - 0x1C2 + type: branch + query: event flag + parameters: 0x0080 + results: + - 0x1B3 # Got first item + - 0x1AA # Haven't gotten first item + + # Set flag for getting first item + - index: 0x1A9 + type: event + event: set event flag + parameters: 0x0080 + next: 0x1A5 + + - index: 0x1AA + type: message + message: 0x125 + next: 0x1A6 + + # Check if we've gotten 2nd item + - index: 0x1B3 + type: branch + query: save switch + parameters: 0x0032 + results: + - 0x79 # Got 2nd item + - 0x1A4 # Haven't gotten 2nd item + + - index: 0x1A4 + type: message + message: 0xC2 + next: 0xA1 + + - index: 0xA5 + type: message + message: 0xC5 + next: 0xB4 + + # Patch Coro waking up to jump to one of our flow entry points + - index: 0x78 + type: message + message: 0xCD + next: 0x1C2 + #7: # zel_07.bmg 8: # zel_08.bmg - HF, Outside CT, LH, UZR, Zora's River, KB2, Title Screen # Skip over the node which deletes auru's memo from the inventory after showing it to Fyer diff --git a/mods/randomizer/generator/data/items.yaml b/mods/randomizer/generator/data/items.yaml index 31e90f8b79..83d285b31e 100644 --- a/mods/randomizer/generator/data/items.yaml +++ b/mods/randomizer/generator/data/items.yaml @@ -1056,7 +1056,7 @@ # Importance: Major # Id: 0xFD -- Name: Coro Key +- Name: Faron Woods Coro Key Importance: Major Id: 0xFE diff --git a/mods/randomizer/generator/data/locations.yaml b/mods/randomizer/generator/data/locations.yaml index 95dcecd310..e4e811c0a0 100644 --- a/mods/randomizer/generator/data/locations.yaml +++ b/mods/randomizer/generator/data/locations.yaml @@ -487,6 +487,30 @@ Metadata: - None +- Name: Coro Lantern + Original Item: Lantern + Categories: + - Overworld + - Npc + - Faron Woods + - ARC + Metadata: + Name Lookup: + - Coro Lantern + Event Flag: 0x0F01 + +- Name: Coro Gate Key + Original Item: Faron Woods Coro Key + Categories: + - Overworld + - Npc + - Faron Woods + - ARC + Metadata: + Name Lookup: + - Coro Gate Key + Event Flag: 0x1A10 + - Name: Coro Bottle Original Item: Bottle with Lantern Oil Categories: diff --git a/mods/randomizer/generator/data/macros.yaml b/mods/randomizer/generator/data/macros.yaml index a5766aaa39..bdb731327b 100644 --- a/mods/randomizer/generator/data/macros.yaml +++ b/mods/randomizer/generator/data/macros.yaml @@ -204,7 +204,9 @@ Can Defeat Zant: Master_Sword and Gale_Boomerang and (Iron_Boots or (Can_Do_Nich Can_Refill_Air and Clawshot and Ball_and_Chain Can Open North Faron Woods Gate: North_Faron_Woods_Gate_Key or Small_Keys == Keysy -Can Complete Prologue: Skip_Prologue == On or (Sword and Slingshot and Can_Open_North_Faron_Woods_Gate) +# Check for shadow crystal instead of Can_Dig so we aren't checking for wolf and human simultaneously +Can Pass Faron Woods Coro Gate: Shadow_Crystal or Faron_Woods_Coro_Key or Small_Keys == Keysy +Can Complete Prologue: Skip_Prologue == On or (Sword and Slingshot and Can_Open_North_Faron_Woods_Gate and Can_Pass_Faron_Woods_Coro_Gate) # You can only use warp portals from certain stages. # 'Can_Warp' is an event added to any logical area diff --git a/mods/randomizer/generator/data/object_patches.yaml b/mods/randomizer/generator/data/object_patches.yaml index 74da6574a9..56d4d4961d 100644 --- a/mods/randomizer/generator/data/object_patches.yaml +++ b/mods/randomizer/generator/data/object_patches.yaml @@ -589,6 +589,29 @@ F_SP104: # Faron Woods F_SP108: + # Room 3 - Area near South Faron Woods Gate + 3: + # Patch the gate before the tunnel to respect the open/closed flag + # used on other layers + - action: patch + name: K_Gate + parameters: 0x0FF0FFFF + position: + x: -17520.0 + y: 200 + z: -11195 + angle: + x: 0x0000 + y: 0x2666 + z: 0x0000 + set id: 0xFFFF + patch: + # Give this gate the flag for it being open/closed + parameters: 0x0FF0FF0C + layers: + - 1 + - 5 + # Room 4 - Coro's Clearing 4: # Add hint sign near on platform south of Coro's hut @@ -689,6 +712,22 @@ F_SP108: - 9 - 14 + # Add Coro actor to twilight layer + - action: add + name: Kkri + parameters: 0x174EFF01 + position: + x: -13505.0 + y: 250.0 + z: -14405.0 + angle: + x: 0x0065 + y: 0xC889 + z: 0x0000 + set id: 0xFFFF + layers: + - 14 + # Room 6 - North Faron Woods 6: # Spawn Item for Golden Wolf in North Faron Woods layer 3 @@ -707,6 +746,44 @@ F_SP108: layers: - 3 + # Room 8 - Statue Path + 8: + # Add the bird statue to every layer + - action: add + name: CstaF + parameters: 0xFFFFFFF1 + position: + x: -17500 + y: -310 + z: -20950 + angle: + x: 0x0000 + y: 0x3555 + z: 0x0000 + set id: 0xFFFF + layers: + - 0 + - 1 + - 14 + + # Add the sky character tag to every layer + - action: add + name: TagStat + parameters: 0x0001A0FF + position: + x: -17500 + y: -310 + z: -20950 + angle: + x: 0x0000 + y: 0x3555 + z: 0x0000 + set id: 0xFFFF + layers: + - 0 + - 1 + - 14 + # Kakariko Village F_SP109: # Room 0 - Main Village @@ -4760,6 +4837,26 @@ F_SP128: - 1 - 2 +# Faron Woods Interiors +R_SP108: + # Room 0 - Coro's Hut + 0: + # Delete Coro actor from Twilight layer because we put him outside instead + - action: delete + name: Kkri + parameters: 0x174EFF01 + position: + x: 477.466552734375 + y: 150.0 + z: 378.840606689453 + angle: + x: 0x006C + y: 0xA16D + z: 0x0000 + set id: 0xFFFF + layers: + - 14 + # Kakariko Village Interiors R_SP109: # Room 2 - Elde Inn diff --git a/mods/randomizer/generator/data/startflags.yaml b/mods/randomizer/generator/data/startflags.yaml index b58890e45d..c06d9ce295 100644 --- a/mods/randomizer/generator/data/startflags.yaml +++ b/mods/randomizer/generator/data/startflags.yaml @@ -6,7 +6,6 @@ EventFlags: - 0x0F40 # Talked to Doctor for the first time. - 0x1208 # Can use Sera's Shop. - 0x1410 # Put Bo outside, ready to wrestle - - 0x0F01 # Got Lantern from Coro (Remove when adding Coro checks) - 0x0A2F # Bridge of Eldin Stolen, KB1 defeated, KB1 started - 0x0F68 # Bridge of Eldin Warped Back, forced text when entering dr. clinic, talked to dr before giving invoice - 0x4088 # Saved monkey from puppets, Visited Gerudo Desert for the first time. @@ -184,9 +183,9 @@ RegionFlags: - 0x47 # Midna jump 1 mist area. - 0x98 # South Faron Portal. # Re-enable once key situation is sorted out - # - Small_Keys == Keysy: - # - 0x53 # Coro gate unlocked. - # - 0x4B # North Faron Gate Unlocked. + - Small_Keys == Keysy: + - 0x53 # Coro gate unlocked. + - 0x4B # North Faron Gate Unlocked. Kakariko and Death Mountain: Index: 0x03 diff --git a/mods/randomizer/generator/data/world/overworld/Faron Province.yaml b/mods/randomizer/generator/data/world/overworld/Faron Province.yaml index 8f4f5df758..69f75c687c 100644 --- a/mods/randomizer/generator/data/world/overworld/Faron Province.yaml +++ b/mods/randomizer/generator/data/world/overworld/Faron Province.yaml @@ -1,4 +1,32 @@ +# PROLOGUE WOODS +# A special region only available if the prologue isn't skipped that +# allows prologue items to be placed in Faron Woods. All of Faron Woods +# normally requires the Twilight to be completed before it's in logic +# The prologue requires that none of the entrances necessary to complete +# it are randomized, so we don't have to reproduce the whole region graph +- Name: Prologue Woods + Map Sector: Faron Province + Region: Faron Woods + Can Warp: True + Can Change Time: True + Events: + Can Refill Lantern Oil: "'Can_Farm_Rupees'" + Locations: + Faron Woods Coro Boulder Rupee 1: Can_Smash + Faron Woods Coro Boulder Rupee 2: Can_Smash + Faron Woods Coro Boulder Rupee 3: Can_Smash + Faron Woods Coro Boulder Rupee 4: Can_Smash + Coro Lantern: Nothing + Coro Gate Key: Nothing + Coro Bottle: "'Can_Farm_Rupees'" + Faron Woods Owl Statue Sky Character: Restored_Dominion_Rod + Faron Woods Owl Statue Chest: Restored_Dominion_Rod and Can_Midna_Jump + South Faron Cave Chest: Can_Pass_Faron_Woods_Coro_Gate + Faron Mist Cave Open Chest: Can_Pass_Faron_Woods_Coro_Gate and Lantern # Not requiring lantern could lock this check out after completing the prologue + Faron Mist Cave Lantern Chest: Can_Pass_Faron_Woods_Coro_Gate and Lantern + North Faron Woods Deku Baba Chest: Can_Pass_Faron_Woods_Coro_Gate + # SOUTH FARON WOODS - Name: South Faron Woods @@ -15,7 +43,9 @@ Faron Woods Coro Boulder Rupee 2: Can_Smash Faron Woods Coro Boulder Rupee 3: Can_Smash Faron Woods Coro Boulder Rupee 4: Can_Smash - Coro Bottle: Can_Complete_Prologue + Coro Lantern: Nothing + Coro Gate Key: Nothing + Coro Bottle: "'Can_Farm_Rupees'" South Faron Woods Twilit Insect in Tunnel 1: Can_Defeat_Faron_Twilit_Insect South Faron Woods Twilit Insect in Tunnel 2: Can_Defeat_Faron_Twilit_Insect South Faron Woods Coros House Exterior Twilit Insect: Can_Defeat_Faron_Twilit_Insect @@ -23,7 +53,7 @@ Exits: South Faron Woods Coros Ledge: Can_Midna_Jump or Twilight Faron Woods Coros House Lower: Can_Open_Doors - South Faron Woods Behind Gate: Nothing # Coro Key is Vanilla if forest is closed + South Faron Woods Behind Gate: Can_Dig or Faron_Woods_Coro_Key or Small_Keys == Keysy South Faron Woods Owl Statue Area: Can_Smash Faron Field: Can_Clear_Forest Ordon Bridge: Nothing @@ -60,9 +90,9 @@ Can Warp: True Can Change Time: True Events: - Can Move Faron Woods Owl Statue: Can_Clear_Forest and Restored_Dominion_Rod + Can Move Faron Woods Owl Statue: Restored_Dominion_Rod Locations: - Faron Woods Owl Statue Sky Character: Can_Clear_Forest and Restored_Dominion_Rod + Faron Woods Owl Statue Sky Character: Restored_Dominion_Rod Exits: South Faron Woods Above Owl Statue: Can_Midna_Jump and 'Can_Move_Faron_Woods_Owl_Statue' South Faron Woods: Can_Smash @@ -88,7 +118,7 @@ South Faron Woods Twilit Insect Behind Gate 2: Can_Defeat_Faron_Twilit_Insect Exits: Faron Woods Cave South: Nothing - South Faron Woods: Can_Dig or Can_Clear_Forest or 'Can_Access_South_Faron_Woods' + South Faron Woods: Can_Dig or Faron_Woods_Coro_Key or Small_Keys == Keysy # FARON WOODS CAVE diff --git a/mods/randomizer/generator/data/world/overworld/Ordona Province.yaml b/mods/randomizer/generator/data/world/overworld/Ordona Province.yaml index ff80eda567..371c2ae60e 100644 --- a/mods/randomizer/generator/data/world/overworld/Ordona Province.yaml +++ b/mods/randomizer/generator/data/world/overworld/Ordona Province.yaml @@ -41,6 +41,7 @@ Exits: South Faron Woods: Can_Complete_Prologue Ordon Spring: Skip_Prologue == On or ('Can_Access_Outside_Links_House' and Sword and Slingshot) + Prologue Woods: Skip_Prologue == Off # ORDON VILLAGE @@ -100,7 +101,7 @@ - Name: Ordon Shield House Exits: - Ordon Shield House Upper Ledge: Wolf_Link + Ordon Shield House Upper Ledge: Can_Midna_Jump Ordon Village: Can_Open_Doors - Name: Ordon Shield House Upper Ledge @@ -143,7 +144,7 @@ Wrestling With Bo: Human_Link Exits: Ordon Bos House Right Door Interior: Nothing - Ordon Bos House Right Door Interior: Nothing + Ordon Bos House Left Door Interior: Nothing # ORDON RANCH diff --git a/mods/randomizer/generator/logic/fill.cpp b/mods/randomizer/generator/logic/fill.cpp index addea1e31f..90674e7288 100644 --- a/mods/randomizer/generator/logic/fill.cpp +++ b/mods/randomizer/generator/logic/fill.cpp @@ -244,7 +244,7 @@ namespace randomizer::logic::fill { return item->GetName() == "Slingshot" || item->GetName() == "Progressive Sword" || item->GetName() == "Lantern" || item->GetName() == "Progressive Fishing Rod" || - item->GetName() == "North Faron Woods Gate Key" || + item->GetName() == "North Faron Woods Gate Key" || item->GetName() == "Faron Woods Coro Key" || item->IsShadowCrystal(); }); auto completeItemPool = item_pool::GetCompleteItemPool(worlds); diff --git a/mods/randomizer/generator/logic/item_pool.cpp b/mods/randomizer/generator/logic/item_pool.cpp index 30eaa7d82d..856746dfec 100644 --- a/mods/randomizer/generator/logic/item_pool.cpp +++ b/mods/randomizer/generator/logic/item_pool.cpp @@ -71,6 +71,7 @@ namespace randomizer::logic::item_pool {"Gate Keys", 1}, {"Gerudo Desert Bulblin Camp Key", 1}, {"North Faron Woods Gate Key", 1}, + {"Faron Woods Coro Key", 1}, {"Forest Temple Small Key", 4}, {"Goron Mines Small Key", 3}, {"Lakebed Temple Small Key", 3}, @@ -311,6 +312,7 @@ namespace randomizer::logic::item_pool std::list smallKeys = { {"Gate Keys"}, {"Gerudo Desert Bulblin Camp Key"}, + {"Faron Woods Coro Key"}, {"Forest Temple Small Key"}, {"Goron Mines Small Key"}, {"Lakebed Temple Small Key"}, diff --git a/mods/randomizer/generator/logic/world.cpp b/mods/randomizer/generator/logic/world.cpp index 63c1a0c3ee..b8ec4b881d 100644 --- a/mods/randomizer/generator/logic/world.cpp +++ b/mods/randomizer/generator/logic/world.cpp @@ -815,6 +815,8 @@ namespace randomizer::logic::world "Ordon Pumpkin", "Ordon Cheese", "North Faron Woods Gate Key", + "Faron Woods Coro Key", + "Gate Keys", "Gerudo Desert Bulblin Camp Key")) { smallKeys.push_back(item.get()); diff --git a/mods/randomizer/src/messages.cpp b/mods/randomizer/src/messages.cpp index 36df8c6593..0bc2e7aa6b 100644 --- a/mods/randomizer/src/messages.cpp +++ b/mods/randomizer/src/messages.cpp @@ -227,6 +227,7 @@ bool resolve_query(const std::string& name, FlowQueryId& out) { {"event flag", FLOW_QUERY_EVENT_FLAG}, {"rupees", FLOW_QUERY_RUPEES}, {"item owned", FLOW_QUERY_ITEM_OWNED}, + {"save switch", FLOW_QUERY_SAVE_SWITCH}, {"empty bottles", FLOW_QUERY_EMPTY_BOTTLES}, {"select 2", FLOW_QUERY_SELECT_2}, {"select 2 cancel", FLOW_QUERY_SELECT_2_CANCEL}, diff --git a/mods/randomizer/src/tools.cpp b/mods/randomizer/src/tools.cpp index f2feaf5674..14f3db406a 100644 --- a/mods/randomizer/src/tools.cpp +++ b/mods/randomizer/src/tools.cpp @@ -512,6 +512,8 @@ std::string nameLookupOverride(const std::string& locationName) { {"Cave of Ordeals Great Fairy Reward", ITEM_CHECK_FAIRY_REWARD}, {"Charlo Donation Blessing", ITEM_CHECK_PRAYER_REWARD}, {"Coro Bottle", ITEM_CHECK_CORO_BOTTLE}, + {"Coro Gate Key", ITEM_CHECK_CORO_GATE_KEY}, + {"Coro Lantern", ITEM_CHECK_CORO_LANTERN}, {"Fishing Hole Bottle", ITEM_CHECK_FISHING_BOTTLE}, {"Fishing Hole Heart Piece", ITEM_CHECK_FISHING_HEART_PIECE}, {"Forest Temple Dungeon Reward", ITEM_CHECK_DUNGEON_REWARD_FOREST}, diff --git a/mods/randomizer/src/ui/rando_config.cpp b/mods/randomizer/src/ui/rando_config.cpp index 54818c57c2..36f1388d46 100644 --- a/mods/randomizer/src/ui/rando_config.cpp +++ b/mods/randomizer/src/ui/rando_config.cpp @@ -71,6 +71,7 @@ const std::vector>& GetStartingInventoryLayo {"Poe Souls", "Poe Soul"}, {"Fused Shadows", "Progressive Fused Shadow"}, {"Mirror Shards", "Progressive Mirror Shard"}, + {"Faron Woods Coro Key", "Faron Woods Coro Key"}, {"Gate Keys", "Gate Keys"}, {"Gerudo Desert Bulblin Camp Key", "Gerudo Desert Bulblin Camp Key"}, {"Forest Temple Small Keys", "Forest Temple Small Key"}, @@ -1036,6 +1037,7 @@ ModResult buildStartingInventoryTab(ModContext* ctx, UiWindowHandle, UiElementHa add_starting_inventory_item<4>(leftPane, "Mirror Shards", "Progressive Mirror Shard"); add_section(leftPane, "Overworld Keys"); + add_starting_inventory_item(leftPane, "Faron Woods Coro Key"); add_starting_inventory_item(leftPane, "Gate Keys"); add_starting_inventory_item(leftPane, "Gerudo Desert Bulblin Camp Key"); diff --git a/sdk/include/mods/items.h b/sdk/include/mods/items.h index b79563026c..b1f0a183a6 100644 --- a/sdk/include/mods/items.h +++ b/sdk/include/mods/items.h @@ -21,6 +21,8 @@ #define ITEM_CHECK_BULBLIN_KEY "bulblin_key:D_MN09" #define ITEM_CHECK_CORAL_EARRING "coral_earring" #define ITEM_CHECK_CORO_BOTTLE "coro_bottle" +#define ITEM_CHECK_CORO_GATE_KEY "coro_gate_key" +#define ITEM_CHECK_CORO_LANTERN "coro_lantern" #define ITEM_CHECK_DUNGEON_MAP_SNOWPEAK "dungeon_map:D_MN11" #define ITEM_CHECK_FAIRY_REWARD "fairy_reward:D_SB01" #define ITEM_CHECK_FISHING_BOTTLE "fishing_bottle" diff --git a/src/d/actor/d_a_npc_kkri.cpp b/src/d/actor/d_a_npc_kkri.cpp index 755257bff7..97e375e4ec 100644 --- a/src/d/actor/d_a_npc_kkri.cpp +++ b/src/d/actor/d_a_npc_kkri.cpp @@ -7,6 +7,9 @@ #include "d/actor/d_a_npc_kkri.h" #include "d/actor/d_a_e_ym.h" +#if TARGET_PC +#include "mods/items.h" +#endif #include static DUSK_CONSTEXPR int l_bmdData[2][2] = { @@ -1183,16 +1186,39 @@ int daNpc_Kkri_c::talk(void*) { if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) { #if TARGET_PC u32 itemGiveTag = 0; - if (item_no == dItemNo_OIL_BOTTLE3_e) { - const auto itemCheck = - dusk::mods::item_check_commit("coro_bottle", item_no, this); + const char* itemCheckName = nullptr; + switch (item_no) { + case dItemNo_OIL_BOTTLE3_e: + itemCheckName = ITEM_CHECK_CORO_BOTTLE; + break; + case dItemNo_KANTERA_e: + itemCheckName = ITEM_CHECK_CORO_LANTERN; + break; + case dItemNo_KEY_OF_FILONE_e: + itemCheckName = ITEM_CHECK_CORO_GATE_KEY; + break; + } + + if (itemCheckName != nullptr) { + const auto itemCheck = dusk::mods::item_check_commit( + itemCheckName, item_no, this); item_no = itemCheck.itemNo; itemGiveTag = itemCheck.tag; } + + if (item_no == dItemNo_NONE_e && itemCheckName != nullptr) { + dusk::mods::item_check_complete({itemGiveTag, dItemNo_NONE_e}, this); + field_0xfd5 = 1; + mEvtNo = 1; + evtChange(); + } else { + mItemPartnerId = fopAcM_createItemForPresentDemo( + ¤t.pos, item_no, 0, -1, -1, NULL, NULL, itemGiveTag); + } +#else + mItemPartnerId = fopAcM_createItemForPresentDemo( + ¤t.pos, item_no, 0, -1, -1, NULL, NULL); #endif - mItemPartnerId = fopAcM_createItemForPresentDemo(¤t.pos, item_no, - 0, -1, -1, NULL, - NULL IF_DUSK_ARG(itemGiveTag)); } if (fopAcM_IsExecuting(mItemPartnerId)) {