Skip to content

Commit 66aadb9

Browse files
committed
Require Gohma setting and ER compatibility
1 parent 6aeb13a commit 66aadb9

20 files changed

Lines changed: 198 additions & 87 deletions

EntranceShuffle.py

Lines changed: 77 additions & 43 deletions
Large diffs are not rendered by default.

HintList.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ def rainbow_bridge_hint_kind(world: World) -> str:
332332
'Magic Meter': (["mystic training", "pixie dust", "a green rectangle"], "a Magic Meter", 'item'),
333333
'Double Defense': (["a white outline", "damage decrease", "strengthened love"], "Double Defense", 'item'),
334334
'Slingshot': (["a seed shooter", "a rubberband", "a child's catapult"], "a Slingshot", 'item'),
335+
'Deku Seed Bag': (["a seed shooter", "a rubberband", "a child's catapult"], "a Slingshot", 'item'),
335336
'Boomerang': (["a banana", "a stun stick"], "the Boomerang", 'item'),
336337
'Bow': (["an archery enabler", "a danger dart launcher"], "a Bow", 'item'),
337338
'Bomb Bag': (["an explosive container", "a blast bag"], "a Bomb Bag", 'item'),

ItemList.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ class GetItemId(IntEnum):
422422
'Bomb Bag': ('Item', True, GetItemId.GI_PROGRESSIVE_BOMB_BAG, None),
423423
'Bow': ('Item', True, GetItemId.GI_PROGRESSIVE_BOW, None),
424424
'Slingshot': ('Item', True, GetItemId.GI_PROGRESSIVE_SLINGSHOT, None),
425+
'Deku Seed Bag': ('Item', True, GetItemId.GI_PROGRESSIVE_SLINGSHOT, {'alias': ('Slingshot', 1)}),
425426
'Progressive Wallet': ('Item', True, GetItemId.GI_PROGRESSIVE_WALLET, {'progressive': 3}),
426427
'Progressive Scale': ('Item', True, GetItemId.GI_PROGRESSIVE_SCALE, {'progressive': 2}),
427428
'Deku Nut Capacity': ('Item', None, GetItemId.GI_PROGRESSIVE_NUT_CAPACITY, None),
@@ -549,6 +550,7 @@ class GetItemId(IntEnum):
549550

550551
# Event items otherwise generated by generic event logic
551552
# can be defined here to enforce their appearance in playthroughs.
553+
'Deku Tree Clear': ('Event', True, None, None),
552554
'Water Temple Clear': ('Event', True, None, None),
553555
'Forest Trial Clear': ('Event', True, None, None),
554556
'Fire Trial Clear': ('Event', True, None, None),

ItemPool.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@
1616
from World import World
1717

1818

19+
closed_forest_restricted_items: tuple[str, ...] = (
20+
'Bomb Bag',
21+
'Bombchus (5)',
22+
'Bombchus (10)',
23+
'Bombchus (20)',
24+
'Bombchus',
25+
'Dins Fire',
26+
'Progressive Scale',
27+
'Bolero of Fire',
28+
'Serenade of Water',
29+
'Nocturne of Shadow',
30+
'Requiem of Spirit',
31+
'Prelude of Light',
32+
)
33+
1934
plentiful_items: list[str] = [
2035
'Biggoron Sword',
2136
'Boomerang',
@@ -37,7 +52,7 @@
3752
'Deku Stick Capacity',
3853
'Deku Nut Capacity',
3954
'Bow',
40-
'Slingshot',
55+
'Deku Seed Bag',
4156
'Bomb Bag',
4257
'Double Defense',
4358
]
@@ -67,7 +82,7 @@
6782
'Progressive Wallet',
6883
'Magic Meter',
6984
'Bow',
70-
'Slingshot',
85+
'Deku Seed Bag',
7186
'Bomb Bag',
7287
'Bombchus (10)',
7388
'Lens of Truth',
@@ -228,7 +243,7 @@
228243
'Deku Stick Capacity': 1,
229244
'Deku Nut Capacity': 1,
230245
'Bow': 2,
231-
'Slingshot': 2,
246+
'Deku Seed Bag': 1,
232247
'Bomb Bag': 2,
233248
'Heart Container': 0,
234249
},
@@ -242,7 +257,7 @@
242257
'Deku Stick Capacity': 0,
243258
'Deku Nut Capacity': 0,
244259
'Bow': 1,
245-
'Slingshot': 1,
260+
'Deku Seed Bag': 0,
246261
'Bomb Bag': 1,
247262
'Heart Container': 0,
248263
'Piece of Heart': 0,

LocationList.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def shop_address(shop_id: int, shelf_id: int) -> int:
164164
# Lost Woods
165165
("LW Gift from Saria", ("Cutscene", 0xFF, 0x02, None, 'Ocarina', ("Lost Woods", "Forest Area", "NPCs",))),
166166
("LW Ocarina Memory Game", ("NPC", 0x5B, 0x76, None, 'Piece of Heart', ("Lost Woods", "Forest Area", "Minigames",))),
167-
("LW Target in Woods", ("NPC", 0x5B, 0x60, None, 'Slingshot', ("Lost Woods", "Forest Area", "NPCs",))),
167+
("LW Target in Woods", ("NPC", 0x5B, 0x60, None, 'Deku Seed Bag', ("Lost Woods", "Forest Area", "NPCs",))),
168168
("LW Near Shortcuts Grotto Chest", ("Chest", 0x3E, 0x14, None, 'Rupees (5)', ("Lost Woods", "Forest Area", "Grottos", "Chests",))),
169169
("LW Trade Cojiro", ("NPC", 0x5B, 0x1F, None, 'Odd Mushroom', ("Lost Woods", "Forest",))),
170170
("LW Trade Odd Potion", ("NPC", 0x5B, 0x21, None, 'Poachers Saw', ("Lost Woods", "Forest",))),
@@ -248,7 +248,7 @@ def shop_address(shop_id: int, shelf_id: int) -> int:
248248
("HF Child Above Drawbridge Wonderitem 2", ("Wonderitem", 0x51, [(0,0,54),(0,1,52)], None, 'Rupees (20)', ("Hyrule Field", "Wonderitem"))),
249249
("HF Child Above Drawbridge Wonderitem 3", ("Wonderitem", 0x51, [(0,0,55),(0,1,53)], None, 'Rupees (20)', ("Hyrule Field", "Wonderitem"))),
250250

251-
("Market Shooting Gallery Reward", ("NPC", 0x42, 0x60, None, 'Slingshot', ("Market", "Minigames",))),
251+
("Market Shooting Gallery Reward", ("NPC", 0x42, 0x60, None, 'Deku Seed Bag', ("Market", "Minigames",))),
252252
("Market Bombchu Bowling First Prize", ("NPC", 0x4B, 0x34, None, 'Bomb Bag', ("Market", "Minigames",))),
253253
("Market Bombchu Bowling Second Prize", ("NPC", 0x4B, 0x3E, None, 'Piece of Heart', ("Market", "Minigames",))),
254254
("Market Bombchu Bowling Bombchus", ("NPC", 0x4B, 0x03, None, 'Bombchus (10)', None)),

Patches.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ def make_bytes(txt: str, size: int) -> list[int]:
589589
rom.write_bytes(0xE5400E, [0xB4, 0xA4])
590590
if world.settings.open_forest != 'closed':
591591
rom.write_bytes(0xE5401C, [0x14, 0x0B])
592+
# Move Link spawn 40 units forwards to prevent Pokey trap
593+
rom.write_byte(0x206F0C7, 0xA3)
592594

593595
# Remove the check on the number of days that passed for claim check.
594596
rom.write_bytes(0xED4470, [0x00, 0x00, 0x00, 0x00])

Region.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def alt_hint(self) -> Optional[HintArea]:
9393

9494
def can_fill(self, item: Item, manual: bool = False) -> bool:
9595
from Hints import HintArea
96+
from ItemPool import closed_forest_restricted_items
9697

9798
if not manual and self.world.settings.empty_dungeons_mode != 'none' and item.dungeonitem:
9899
# An empty dungeon can only store its own dungeon items
@@ -103,6 +104,18 @@ def can_fill(self, item: Item, manual: bool = False) -> bool:
103104
if item.world.precompleted_dungeons.get(dungeon.name, False) and dungeon.is_dungeon_item(item):
104105
return False
105106

107+
if not manual and self.world.settings.require_gohma and item.name in (*closed_forest_restricted_items, 'Slingshot'):
108+
hint_area = HintArea.at(self)
109+
if hint_area.color == 'Green' and hint_area != HintArea.FOREST_TEMPLE and self.name != 'Queen Gohma Boss Room':
110+
# Don't place items that can be used to escape the forest in Forest areas of worlds with Require Gohma
111+
if item.name in closed_forest_restricted_items:
112+
return False
113+
else:
114+
# Place at least one slingshot for each player in the Forest area, to avoid requiring one player to leave the forest to get another player's slingshot.
115+
# This is still not a 100% guarantee because the slingshot could be behind an item that's not in the forest, such as in a bombable grotto entrance in the Lost Woods.
116+
if item.name == 'Slingshot' and 'Deku Tree' not in item.world.settings.dungeon_shortcuts and 'logic_deku_b1_skip' not in item.world.settings.allowed_tricks:
117+
return False
118+
106119
is_self_dungeon_restricted = False
107120
is_self_region_restricted = None
108121
is_hint_color_restricted = None

Rules.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from collections.abc import Callable, Collection, Iterable
44
from typing import TYPE_CHECKING, Optional
55

6-
from ItemPool import song_list
6+
from ItemPool import closed_forest_restricted_items, song_list
77
from Location import Location, DisableType
88
from RulesCommon import AccessRule
99
from Search import Search
@@ -79,6 +79,9 @@ def set_rules(world: World) -> None:
7979
if location.name in world.always_hints:
8080
location.add_rule(guarantee_hint)
8181

82+
if world.settings.require_gohma and location in world.distribution.skipped_locations:
83+
add_item_rule(location, lambda location, item: item.name not in closed_forest_restricted_items)
84+
8285
for location in world.settings.disabled_locations:
8386
try:
8487
world.get_location(location).disabled = DisableType.PENDING

SaveContext.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,10 @@ def get_save_context_addresses() -> AddressesDict:
11401140
'item_slot.slingshot' : 'slingshot',
11411141
'upgrades.bullet_bag' : None,
11421142
},
1143+
"Deku Seed Bag" : {
1144+
'item_slot.slingshot' : 'slingshot',
1145+
'upgrades.bullet_bag' : None,
1146+
},
11431147
"Deku Seeds" : {
11441148
'ammo.slingshot' : None,
11451149
},

SettingsList.py

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,31 +1216,27 @@ class SettingInfos:
12161216
'closed': 'Closed Forest',
12171217
},
12181218
gui_tooltip = '''\
1219-
'Open Forest': Mido no longer blocks the path to the
1220-
Deku Tree, and the Kokiri boy no longer blocks the path
1221-
out of the forest.
1219+
'Closed Forest': In the child era, Mido blocks the path
1220+
to the Deku Tree, requiring Kokiri Sword and Deku Shield
1221+
to access the Deku Tree, and another Kokiri boy blocks
1222+
the path out of the forest until Queen Gohma is defeated.
1223+
It may be logically required to "escape" the forest
1224+
(via one of the shortcuts in the Lost Woods, for example);
1225+
the setting "Closed Forest Requires Gohma" can be used to
1226+
prevent this.
12221227
12231228
'Closed Deku': The Kokiri boy no longer blocks the path
12241229
out of the forest, but Mido still blocks the path to the
12251230
Deku Tree, requiring Kokiri Sword and Deku Shield to access
12261231
the Deku Tree.
12271232
1228-
'Closed Forest': Beating Deku Tree is logically required
1229-
to leave the forest area (Kokiri Forest/Lost Woods/Sacred Forest
1230-
Meadow/Deku Tree), while the Kokiri Sword and a Deku Shield are
1231-
required to access the Deku Tree. Items needed for this will be
1232-
guaranteed inside the forest area. This setting is incompatible
1233-
with starting as adult, and so Starting Age will be locked to Child.
1234-
With any of "Shuffle Interior Entrances" set to "All", "Shuffle
1235-
Overworld Entrances" on, "Randomize Warp Song Destinations" on,
1236-
"Randomize Overworld Spawns" on, or "Shuffle Grottos" in Advanced
1237-
Logic, Closed Forest will instead be treated as Closed Deku with
1238-
starting age Child and WILL NOT guarantee that these items are
1239-
available in the forest area.
1233+
'Open Forest': Mido no longer blocks the path to the
1234+
Deku Tree, and the Kokiri boy no longer blocks the path
1235+
out of the forest.
12401236
''',
12411237
shared = True,
12421238
disable = {
1243-
'closed': {'settings': ['starting_age']}
1239+
'closed': {'settings': ['starting_age']},
12441240
},
12451241
gui_params = {
12461242
'randomize_key': 'randomize_settings',
@@ -1252,6 +1248,37 @@ class SettingInfos:
12521248
},
12531249
)
12541250

1251+
require_gohma = Checkbutton(
1252+
gui_text = 'Closed Forest Requires Gohma',
1253+
gui_tooltip = '''\
1254+
Defeating Queen Gohma is required to leave the forest area
1255+
(Kokiri Forest/Lost Woods/Sacred Forest Meadow/Deku Tree).
1256+
Items needed for this will be guaranteed inside the forest area,
1257+
and items that could be used to escape the forest without
1258+
defeating Queen Gohma (such as explosives to enter Goron City)
1259+
will be prevented from appearing inside the forest area.
1260+
1261+
If entrances are shuffled, entrances inside and outside the
1262+
forest area will be shuffled separately. For example, "Shuffle
1263+
Dungeon Entrances" and "Shuffle Boss Entrances" don't affect the
1264+
Deku Tree. As an exception, grottos are not shuffled separately
1265+
(except in Advanced Logic), and neither are interiors if only
1266+
simple interiors are shuffled.
1267+
1268+
This setting is incompatible with starting as adult, and so
1269+
Starting Age will be locked to Child.
1270+
''',
1271+
default = True,
1272+
disabled_default = False,
1273+
shared = True,
1274+
disable = {
1275+
True : {'settings' : ['open_forest']},
1276+
},
1277+
gui_params = {
1278+
'optional': True,
1279+
},
1280+
)
1281+
12551282
open_kakariko = Combobox(
12561283
gui_text = 'Kakariko Gate',
12571284
default = 'closed',

0 commit comments

Comments
 (0)