From 6ea6f8025017c4c76c16eab55578cf762e5232fb Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Wed, 9 Jul 2025 04:46:11 +0000 Subject: [PATCH 1/3] refactor ice cavern fixes blue rupee logic at beginning makes structure usable for doorsanity & silver shuffle --- .../location_access/dungeons/ice_cavern.cpp | 132 ++++++++++++++---- .../Enhancements/randomizer/randomizerTypes.h | 11 +- 2 files changed, 114 insertions(+), 29 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 5151377ce..fc2ab41a7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -19,42 +19,105 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", SCENE_ICE_CAVERN, {}, { //Locations LOCATION(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), }, { //Exits - Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}), - Entrance(RR_ICE_CAVERN_MAIN, []{return Here(RR_ICE_CAVERN_BEGINNING, []{return logic->CanKillEnemy(RE_FREEZARD, ED_CLOSE, true, 4);});}), + Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}), + Entrance(RR_ICE_CAVERN_HUB, []{return Here(RR_ICE_CAVERN_BEGINNING, []{return logic->CanKillEnemy(RE_FREEZARD, ED_CLOSE, true, 4);});}), + Entrance(RR_ICE_CAVERN_ABOVE_BEGINNING, []{return false;}), }); - areaTable[RR_ICE_CAVERN_MAIN] = Region("Ice Cavern", SCENE_ICE_CAVERN, { - //Events - EventAccess(&logic->BlueFireAccess, []{return logic->IsAdult;}), - }, { + areaTable[RR_ICE_CAVERN_ABOVE_BEGINNING] = Region("Ice Cavern Above Beginning", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), + }); + + areaTable[RR_ICE_CAVERN_HUB] = Region("Ice Cavern Hub", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), - LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), - LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->BlueFire() && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), LOCATION(RC_ICE_CAVERN_HALL_POT_1, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_HALL_POT_2, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult), - LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, logic->IsAdult), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, logic->IsAdult), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, logic->IsAdult), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), - }, {}); + }, { + //Exits + Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), + Entrance(RR_ICE_CAVERN_MAP_ROOM, []{return logic->IsAdult;}), + Entrance(RR_ICE_CAVERN_COMPASS_ROOM, []{return logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();}), + }); + areaTable[RR_ICE_CAVERN_MAP_ROOM] = Region("Ice Cavern Map Room", SCENE_ICE_CAVERN, { + //Events + EventAccess(&logic->BlueFireAccess, []{return true;}), + }, { + //Locations + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, true), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, true), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, true), + }, { + //Exits + Entrance(RR_ICE_CAVERN_HUB, []{return true;}), + }); + + areaTable[RR_ICE_CAVERN_COMPASS_ROOM] = Region("Ice Cavern Map Room", SCENE_ICE_CAVERN, { + //Events + EventAccess(&logic->BlueFireAccess, []{return true;}), + }, { + //Locations + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), + }, { + //Exits + Entrance(RR_ICE_CAVERN_HUB, []{return true;}), + }); + + areaTable[RR_ICE_CAVERN_BLOCK_ROOM] = Region("Ice Cavern Block Room", SCENE_ICE_CAVERN, { + //Events + EventAccess(&logic->BlueFireAccess, []{return true;}), + }, { + //Locations + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + }, { + //Exits + Entrance(RR_ICE_CAVERN_HUB, []{return true;}), + Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->BlueFire();}), + }); + + // this represents being past the red ice barricade, not just past the silver rupee door + areaTable[RR_ICE_CAVERN_BEFORE_FINAL_ROOM] = Region("Ice Cavern Before Final Room", SCENE_ICE_CAVERN, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), + }, { + //Exits + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_FINAL_ROOM, []{return true;}), + }); + + areaTable[RR_ICE_CAVERN_FINAL_ROOM] = Region("Ice Cavern Final Room", SCENE_ICE_CAVERN, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_WOLFOS)), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), + }, { + //Exits + Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);}), + Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return logic->CanKillEnemy(RE_WOLFOS) && logic->CanUse(RG_IRON_BOOTS);}), + }); + + areaTable[RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER] = Region("Ice Cavern Final Room Underwater", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanUse(RG_BRONZE_SCALE);}), + Entrance(RR_ICE_CAVERN_ABOVE_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS);}), + }); #pragma endregion #pragma region MQ @@ -64,9 +127,16 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}), + Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}), //It is in logic to use a pot to hit the toggle switch here. - Entrance(RR_ICE_CAVERN_MQ_HUB, []{return true;}), + Entrance(RR_ICE_CAVERN_MQ_HUB, []{return true;}), + Entrance(RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, []{return false;}), + }); + + areaTable[RR_ICE_CAVERN_MQ_ABOVE_BEGINNING] = Region("Ice Cavern MQ Above Beginning", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return true;}), }); areaTable[RR_ICE_CAVERN_MQ_HUB] = Region("Ice Cavern MQ Hub", SCENE_ICE_CAVERN, { @@ -126,8 +196,14 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)), }, { //Exits - Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), - Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS) && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), + Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), + Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS) && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), + }); + + areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER] = Region("Ice Cavern MQ Stalfos Room Underwater", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanUse(RG_BRONZE_SCALE);}), + Entrance(RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS);}), }); areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", SCENE_ICE_CAVERN, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..81b689b61 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -990,13 +990,22 @@ typedef enum { RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, RR_ICE_CAVERN_BEGINNING, - RR_ICE_CAVERN_MAIN, + RR_ICE_CAVERN_HUB, + RR_ICE_CAVERN_MAP_ROOM, + RR_ICE_CAVERN_COMPASS_ROOM, + RR_ICE_CAVERN_BLOCK_ROOM, + RR_ICE_CAVERN_BEFORE_FINAL_ROOM, + RR_ICE_CAVERN_FINAL_ROOM, + RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, + RR_ICE_CAVERN_ABOVE_BEGINNING, RR_ICE_CAVERN_MQ_BEGINNING, + RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, RR_ICE_CAVERN_MQ_HUB, RR_ICE_CAVERN_MQ_MAP_ROOM, RR_ICE_CAVERN_MQ_SCARECROW_ROOM, RR_ICE_CAVERN_MQ_STALFOS_ROOM, + RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, RR_ICE_CAVERN_MQ_WEST_CORRIDOR, RR_ICE_CAVERN_MQ_COMPASS_ROOM, From 4119cfb0bb4785cc6f89d9d6a653bb803d448e78 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Thu, 10 Jul 2025 01:37:05 +0000 Subject: [PATCH 2/3] feedback --- .../location_access/dungeons/ice_cavern.cpp | 86 ++++++++++--------- soh/soh/Enhancements/randomizer/logic.cpp | 4 + soh/soh/Enhancements/randomizer/logic.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 6 +- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index fc2ab41a7..941892c72 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -27,12 +27,6 @@ void RegionTable_Init_IceCavern() { Entrance(RR_ICE_CAVERN_ABOVE_BEGINNING, []{return false;}), }); - areaTable[RR_ICE_CAVERN_ABOVE_BEGINNING] = Region("Ice Cavern Above Beginning", SCENE_ICE_CAVERN, {}, {}, { - //Exits - Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), - Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), - }); - areaTable[RR_ICE_CAVERN_HUB] = Region("Ice Cavern Hub", SCENE_ICE_CAVERN, {}, { //Locations LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), @@ -44,9 +38,9 @@ void RegionTable_Init_IceCavern() { }, { //Exits Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), - Entrance(RR_ICE_CAVERN_MAP_ROOM, []{return logic->IsAdult;}), - Entrance(RR_ICE_CAVERN_COMPASS_ROOM, []{return logic->BlueFire();}), - Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_MAP_ROOM, []{return logic->IsAdult && logic->CanClearStalagmite();}), + Entrance(RR_ICE_CAVERN_COMPASS_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();})}), + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();})}), }); areaTable[RR_ICE_CAVERN_MAP_ROOM] = Region("Ice Cavern Map Room", SCENE_ICE_CAVERN, { @@ -69,27 +63,29 @@ void RegionTable_Init_IceCavern() { EventAccess(&logic->BlueFireAccess, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_ICE_CAVERN_HUB, []{return true;}), }); + // heavily relies on str0 areaTable[RR_ICE_CAVERN_BLOCK_ROOM] = Region("Ice Cavern Block Room", SCENE_ICE_CAVERN, { //Events EventAccess(&logic->BlueFireAccess, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + // trick involves backflip, could be merged into general trick + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOMB_THROW))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_ICE_CAVERN_HUB, []{return true;}), - Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return Here(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();});}), }); // this represents being past the red ice barricade, not just past the silver rupee door @@ -99,18 +95,18 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), }, { //Exits - Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->BlueFire()});}), Entrance(RR_ICE_CAVERN_FINAL_ROOM, []{return true;}), }); areaTable[RR_ICE_CAVERN_FINAL_ROOM] = Region("Ice Cavern Final Room", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_WOLFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);})), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);}) && logic->IsAdult), }, { //Exits - Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);}), - Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return logic->CanKillEnemy(RE_WOLFOS) && logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);});}), + Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);}) && logic->CanUse(RG_IRON_BOOTS);}), }); areaTable[RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER] = Region("Ice Cavern Final Room Underwater", SCENE_ICE_CAVERN, {}, {}, { @@ -118,6 +114,12 @@ void RegionTable_Init_IceCavern() { Entrance(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanUse(RG_BRONZE_SCALE);}), Entrance(RR_ICE_CAVERN_ABOVE_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS);}), }); + + areaTable[RR_ICE_CAVERN_ABOVE_BEGINNING] = Region("Ice Cavern Above Beginning", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), + }); #pragma endregion #pragma region MQ @@ -133,12 +135,6 @@ void RegionTable_Init_IceCavern() { Entrance(RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, []{return false;}), }); - areaTable[RR_ICE_CAVERN_MQ_ABOVE_BEGINNING] = Region("Ice Cavern MQ Above Beginning", SCENE_ICE_CAVERN, {}, {}, { - //Exits - Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), - Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return true;}), - }); - areaTable[RR_ICE_CAVERN_MQ_HUB] = Region("Ice Cavern MQ Hub", SCENE_ICE_CAVERN, { //Events EventAccess(&logic->FairyPot, []{return true;}), @@ -163,7 +159,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_MAP_ROOM] = Region("Ice Cavern MQ Map Room", SCENE_ICE_CAVERN, { //Events //Child can fit between the stalagmites on the left hand side - EventAccess(&logic->BlueFireAccess, []{return logic->IsChild || logic->CanJumpslash() || logic->HasExplosives();}), + EventAccess(&logic->BlueFireAccess, []{return logic->IsChild || logic->CanClearStalagmite();}), }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return logic->CanHitSwitch();})), @@ -190,6 +186,20 @@ void RegionTable_Init_IceCavern() { Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return true;}), }); + areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", SCENE_ICE_CAVERN, { + //Events + EventAccess(&logic->BlueFireAccess, []{return true;}), + }, { + //Locations + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), + //It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick + LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), + //doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult + LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA))), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_2, logic->CanBreakPots()), + }, {}); + areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", SCENE_ICE_CAVERN, {}, { //Locations LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS)), @@ -206,19 +216,11 @@ void RegionTable_Init_IceCavern() { Entrance(RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS);}), }); - areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", SCENE_ICE_CAVERN, { - //Events - EventAccess(&logic->BlueFireAccess, []{return true;}), - }, { - //Locations - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), - //It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick - LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), - //doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult - LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA))), - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_2, logic->CanBreakPots()), - }, {}); + areaTable[RR_ICE_CAVERN_MQ_ABOVE_BEGINNING] = Region("Ice Cavern MQ Above Beginning", SCENE_ICE_CAVERN, {}, {}, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return true;}), + }); #pragma endregion // clang-format on diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..e0d8cfa23 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1075,6 +1075,10 @@ bool Logic::CanJumpslash() { return CanJumpslashExceptHammer() || CanUse(RG_MEGATON_HAMMER); } +bool Logic::CanClearStalagmite() { + return CanJumpslash() || HasExplosives(); +} + bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { bool hit = false; switch (distance) { diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 2bfea75e9..8296a9a49 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -217,6 +217,7 @@ class Logic { bool CanUseSword(); bool CanJumpslashExceptHammer(); bool CanJumpslash(); + bool CanClearStalagmite(); bool CanHitSwitch(EnemyDistance distance = ED_CLOSE, bool inWater = false); bool CanDamage(); bool CanAttack(); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 81b689b61..3874438ed 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1000,14 +1000,14 @@ typedef enum { RR_ICE_CAVERN_ABOVE_BEGINNING, RR_ICE_CAVERN_MQ_BEGINNING, - RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, RR_ICE_CAVERN_MQ_HUB, RR_ICE_CAVERN_MQ_MAP_ROOM, RR_ICE_CAVERN_MQ_SCARECROW_ROOM, - RR_ICE_CAVERN_MQ_STALFOS_ROOM, - RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, RR_ICE_CAVERN_MQ_WEST_CORRIDOR, RR_ICE_CAVERN_MQ_COMPASS_ROOM, + RR_ICE_CAVERN_MQ_STALFOS_ROOM, + RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER, + RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, RR_GERUDO_TRAINING_GROUND_LOBBY, RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE, From 169a4091a13be2cd57053ebcf4707455c5cc3eb1 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Thu, 10 Jul 2025 13:40:35 +0000 Subject: [PATCH 3/3] feedback2 --- .../location_access/dungeons/ice_cavern.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 941892c72..163d8e89d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -39,8 +39,8 @@ void RegionTable_Init_IceCavern() { //Exits Entrance(RR_ICE_CAVERN_BEGINNING, []{return true;}), Entrance(RR_ICE_CAVERN_MAP_ROOM, []{return logic->IsAdult && logic->CanClearStalagmite();}), - Entrance(RR_ICE_CAVERN_COMPASS_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();})}), - Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();})}), + Entrance(RR_ICE_CAVERN_COMPASS_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();});}), + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_HUB, []{return logic->BlueFire();}) && logic->CanClearStalagmite();}), }); areaTable[RR_ICE_CAVERN_MAP_ROOM] = Region("Ice Cavern Map Room", SCENE_ICE_CAVERN, { @@ -63,8 +63,8 @@ void RegionTable_Init_IceCavern() { EventAccess(&logic->BlueFireAccess, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->CanClearStalagmite()), - LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->CanClearStalagmite() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->CanClearStalagmite() && logic->BlueFire()), LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), }, { //Exits @@ -78,13 +78,13 @@ void RegionTable_Init_IceCavern() { }, { //Locations // trick involves backflip, could be merged into general trick - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOMB_THROW))), + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH))), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(RR_ICE_CAVERN_HUB, []{return true;}), + Entrance(RR_ICE_CAVERN_HUB, []{return logic->CanClearStalagmite();}), Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return Here(RR_ICE_CAVERN_BLOCK_ROOM, []{return logic->BlueFire();});}), }); @@ -95,7 +95,7 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), }, { //Exits - Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->BlueFire()});}), + Entrance(RR_ICE_CAVERN_BLOCK_ROOM, []{return Here(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return logic->BlueFire();});}), Entrance(RR_ICE_CAVERN_FINAL_ROOM, []{return true;}), });