Skip to content

Commit 0eb9b9b

Browse files
committed
Merge 'Fix key rings being hinted as small key when keys are in their own dungeons' (#2317)
2 parents c7b035d + 457f0a6 commit 0eb9b9b

10 files changed

Lines changed: 35 additions & 31 deletions

File tree

Fill.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def fill_dungeons_restrictive(worlds: list[World], search: Search, shuffled_loca
249249
# sort in the order Other, Small Key, Boss Key before placing dungeon items
250250
# python sort is stable, so the ordering is still random within groups
251251
# fill_restrictive processes the resulting list backwards so the Boss Keys will actually be placed first
252-
sort_order = {"BossKey": 3, "GanonBossKey": 3, "SmallKey": 2}
252+
sort_order = {"BossKey": 3, "GanonBossKey": 3, "SmallKey": 2, "SmallKeyRing": 2}
253253
dungeon_items.sort(key=lambda item: sort_order.get(item.type, 1))
254254

255255
# place dungeon items

HintList.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ def tokens_required_by_settings(world: World) -> int:
439439
'SmallKey': (["a tool for unlocking", "a dungeon pass", "a lock remover", "a lockpick"], "a Small Key", 'item'),
440440
'HideoutSmallKey': (["a get out of jail free card"], "a Jail Key", 'item'),
441441
'TCGSmallKey': (["a key to becoming a winner"], "a Game Key", 'item'),
442+
'SmallKeyRing': (["a toolbox for unlocking", "a dungeon season pass", "a jingling ring", "a skeleton key"], "a Small Key Ring", 'item'),
443+
'HideoutSmallKeyRing': (["a deck of get out of jail free cards"], "a Jail Key Ring", 'item'),
444+
'TCGSmallKeyRing': (["the keys to becoming a winner"], "a Game Key Ring", 'item'),
442445
'SilverRupee': (["an entry fee", "a priced artifact"], "a Silver Rupee", 'item'),
443446
'Boss Key (Forest Temple)': (["a master of unlocking for a deep forest", "a master pass for a deep forest"], "the Forest Temple Boss Key", 'item'),
444447
'Boss Key (Fire Temple)': (["a master of unlocking for a high mountain", "a master pass for a high mountain"], "the Fire Temple Boss Key", 'item'),
@@ -465,7 +468,7 @@ def tokens_required_by_settings(world: World) -> int:
465468
'Small Key Ring (Gerudo Training Ground)': (["a toolbox for unlocking the test of thieves", "a dungeon season pass for the test of thieves", "a jingling ring for the test of thieves", "a skeleton key for the test of thieves"], "a Gerudo Training Ground Small Key Ring", 'item'),
466469
'Small Key Ring (Ganons Castle)': (["a toolbox for unlocking a conquered citadel", "a dungeon season pass for a conquered citadel", "a jingling ring for a conquered citadel", "a skeleton key for a conquered citadel"], "a Ganon's Castle Small Key Ring", 'item'),
467470
'Small Key Ring (Thieves Hideout)': (["a deck of get out of jail free cards"], "a Jail Key Ring", 'item'),
468-
'Small Key Ring (Treasure Chest Game)': (["an abundance of keys to becoming a winner"], "a Game Key Ring", 'item'),
471+
'Small Key Ring (Treasure Chest Game)': (["the keys to becoming a winner"], "a Game Key Ring", 'item'),
469472
'Silver Rupee (Dodongos Cavern Staircase)': (["an entry fee for an immense cavern", "a priced artifact from an immense cavern"], "a Silver Rupee for Dodongo's Cavern", 'item'),
470473
'Silver Rupee (Ice Cavern Spinning Scythe)': (["an entry fee for a frozen maze", "a priced artifact from a frozen maze"], "a Silver Rupee for the Ice Cavern", 'item'),
471474
'Silver Rupee (Ice Cavern Push Block)': (["an entry fee for a frozen maze", "a priced artifact from a frozen maze"], "a Silver Rupee for the Ice Cavern", 'item'),

Hints.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def is_restricted_dungeon_item(item: Item) -> bool:
177177
return False
178178
return (
179179
((item.map or item.compass) and item.world.settings.shuffle_mapcompass == 'dungeon') or
180-
(item.type == 'SmallKey' and item.world.settings.shuffle_smallkeys == 'dungeon') or
180+
(item.type in ('SmallKey', 'SmallKeyRing') and item.world.settings.shuffle_smallkeys == 'dungeon') or
181181
(item.type == 'BossKey' and item.world.settings.shuffle_bosskeys == 'dungeon') or
182182
(item.type == 'GanonBossKey' and item.world.settings.shuffle_ganon_bosskey == 'dungeon') or
183183
(item.type == 'SilverRupee' and item.world.settings.shuffle_silver_rupees == 'dungeon') or
@@ -1159,9 +1159,9 @@ def get_important_check_hint(spoiler: Spoiler, world: World, checked: set[str])
11591159
or location.item.name == 'Biggoron Sword'
11601160
or location.item.name == 'Double Defense'
11611161
# Handle make keys not in own dungeon major items
1162-
or (location.item.type == 'SmallKey' and not (world.settings.shuffle_smallkeys == 'dungeon' or world.settings.shuffle_smallkeys == 'vanilla'))
1163-
or (location.item.type == 'HideoutSmallKey' and not world.settings.shuffle_hideoutkeys == 'vanilla')
1164-
or (location.item.type == 'TCGSmallKey' and not world.settings.shuffle_tcgkeys == 'vanilla')
1162+
or (location.item.type in ('SmallKey', 'SmallKeyRing') and not (world.settings.shuffle_smallkeys == 'dungeon' or world.settings.shuffle_smallkeys == 'vanilla'))
1163+
or (location.item.type in ('HideoutSmallKey', 'HideoutSmallKeyRing') and not world.settings.shuffle_hideoutkeys == 'vanilla')
1164+
or (location.item.type in ('TCGSmallKey', 'TCGSmallKeyRing') and not world.settings.shuffle_tcgkeys == 'vanilla')
11651165
or (location.item.type == 'BossKey' and not (world.settings.shuffle_bosskeys == 'dungeon' or world.settings.shuffle_bosskeys == 'vanilla'))
11661166
or (location.item.type == 'GanonBossKey' and not (world.settings.shuffle_ganon_bosskey == 'vanilla'
11671167
or world.settings.shuffle_ganon_bosskey == 'dungeon' or world.settings.shuffle_ganon_bosskey == 'on_lacs'

Item.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def key(self) -> bool:
114114

115115
@property
116116
def smallkey(self) -> bool:
117-
return self.type == 'SmallKey' or self.type == 'HideoutSmallKey' or self.type == 'TCGSmallKey'
117+
return self.type in ('SmallKey', 'HideoutSmallKey', 'TCGSmallKey', 'SmallKeyRing', 'HideoutSmallKeyRing','TCGSmallKeyRing')
118118

119119
@property
120120
def bosskey(self) -> bool:
@@ -136,9 +136,9 @@ def dungeonitem(self) -> bool:
136136
def unshuffled_dungeon_item(self) -> bool:
137137
if self.world is None:
138138
return False
139-
return ((self.type == 'SmallKey' and self.world.settings.shuffle_smallkeys in ('remove', 'vanilla', 'dungeon')) or
140-
(self.type == 'HideoutSmallKey' and self.world.settings.shuffle_hideoutkeys == 'vanilla') or
141-
(self.type == 'TCGSmallKey' and self.world.settings.shuffle_tcgkeys in ('remove', 'vanilla')) or
139+
return ((self.type in ('SmallKey', 'SmallKeyRing') and self.world.settings.shuffle_smallkeys in ('remove', 'vanilla', 'dungeon')) or
140+
(self.type in ('HideoutSmallKey', 'HideoutSmallKeyRing') and self.world.settings.shuffle_hideoutkeys == 'vanilla') or
141+
(self.type in ('TCGSmallKey', 'HideoutSmallKeyRing') and self.world.settings.shuffle_tcgkeys in ('remove', 'vanilla')) or
142142
(self.type == 'BossKey' and self.world.settings.shuffle_bosskeys in ('remove', 'vanilla', 'dungeon')) or
143143
(self.type == 'GanonBossKey' and self.world.settings.shuffle_ganon_bosskey in ('remove', 'vanilla', 'dungeon')) or
144144
((self.map or self.compass) and (self.world.settings.shuffle_mapcompass in ('remove', 'startwith', 'vanilla', 'dungeon'))) or
@@ -167,11 +167,11 @@ def majoritem(self) -> bool:
167167
return False
168168
if self.type == 'DungeonReward' and self.world.settings.shuffle_dungeon_rewards in ('vanilla', 'reward', 'dungeon'):
169169
return False
170-
if self.type == 'SmallKey' and self.world.settings.shuffle_smallkeys in ('dungeon', 'vanilla'):
170+
if self.type in ('SmallKey', 'SmallKeyRing') and self.world.settings.shuffle_smallkeys in ('dungeon', 'vanilla'):
171171
return False
172-
if self.type == 'HideoutSmallKey' and self.world.settings.shuffle_hideoutkeys == 'vanilla':
172+
if self.type in ('HideoutSmallKey', 'HideoutSmallKeyRing') and self.world.settings.shuffle_hideoutkeys == 'vanilla':
173173
return False
174-
if self.type == 'TCGSmallKey' and self.world.settings.shuffle_tcgkeys == 'vanilla':
174+
if self.type in ('TCGSmallKey','TCGSmallKeyRing') and self.world.settings.shuffle_tcgkeys == 'vanilla':
175175
return False
176176
if self.type == 'BossKey' and self.world.settings.shuffle_bosskeys in ('dungeon', 'vanilla'):
177177
return False

ItemList.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -481,16 +481,16 @@ class GetItemId(IntEnum):
481481
'Scarecrow Song': ('Event', True, None, None),
482482
'Triforce': ('Event', True, None, None),
483483

484-
'Small Key Ring (Forest Temple)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_FOREST_TEMPLE, {'alias': ('Small Key (Forest Temple)', 10), 'progressive': float('Inf')}),
485-
'Small Key Ring (Fire Temple)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_FIRE_TEMPLE, {'alias': ('Small Key (Fire Temple)', 10), 'progressive': float('Inf')}),
486-
'Small Key Ring (Water Temple)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_WATER_TEMPLE, {'alias': ('Small Key (Water Temple)', 10), 'progressive': float('Inf')}),
487-
'Small Key Ring (Spirit Temple)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_SPIRIT_TEMPLE, {'alias': ('Small Key (Spirit Temple)', 10), 'progressive': float('Inf')}),
488-
'Small Key Ring (Shadow Temple)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_SHADOW_TEMPLE, {'alias': ('Small Key (Shadow Temple)', 10), 'progressive': float('Inf')}),
489-
'Small Key Ring (Bottom of the Well)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_BOTTOM_OF_THE_WELL, {'alias': ('Small Key (Bottom of the Well)', 10), 'progressive': float('Inf')}),
490-
'Small Key Ring (Gerudo Training Ground)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_GERUDO_TRAINING, {'alias': ('Small Key (Gerudo Training Ground)', 10), 'progressive': float('Inf')}),
491-
'Small Key Ring (Thieves Hideout)': ('HideoutSmallKey', True, GetItemId.GI_SMALL_KEY_RING_THIEVES_HIDEOUT, {'alias': ('Small Key (Thieves Hideout)', 10), 'progressive': float('Inf')}),
492-
'Small Key Ring (Ganons Castle)': ('SmallKey', True, GetItemId.GI_SMALL_KEY_RING_GANONS_CASTLE, {'alias': ('Small Key (Ganons Castle)', 10), 'progressive': float('Inf')}),
493-
'Small Key Ring (Treasure Chest Game)': ('TCGSmallKey', True, GetItemId.GI_SMALL_KEY_RING_TREASURE_CHEST_GAME, {'alias': ('Small Key (Treasure Chest Game)', 10), 'progressive': float('Inf')}),
484+
'Small Key Ring (Forest Temple)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_FOREST_TEMPLE, {'alias': ('Small Key (Forest Temple)', 10), 'progressive': float('Inf')}),
485+
'Small Key Ring (Fire Temple)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_FIRE_TEMPLE, {'alias': ('Small Key (Fire Temple)', 10), 'progressive': float('Inf')}),
486+
'Small Key Ring (Water Temple)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_WATER_TEMPLE, {'alias': ('Small Key (Water Temple)', 10), 'progressive': float('Inf')}),
487+
'Small Key Ring (Spirit Temple)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_SPIRIT_TEMPLE, {'alias': ('Small Key (Spirit Temple)', 10), 'progressive': float('Inf')}),
488+
'Small Key Ring (Shadow Temple)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_SHADOW_TEMPLE, {'alias': ('Small Key (Shadow Temple)', 10), 'progressive': float('Inf')}),
489+
'Small Key Ring (Bottom of the Well)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_BOTTOM_OF_THE_WELL, {'alias': ('Small Key (Bottom of the Well)', 10), 'progressive': float('Inf')}),
490+
'Small Key Ring (Gerudo Training Ground)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_GERUDO_TRAINING, {'alias': ('Small Key (Gerudo Training Ground)', 10), 'progressive': float('Inf')}),
491+
'Small Key Ring (Thieves Hideout)': ('HideoutSmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_THIEVES_HIDEOUT, {'alias': ('Small Key (Thieves Hideout)', 10), 'progressive': float('Inf')}),
492+
'Small Key Ring (Ganons Castle)': ('SmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_GANONS_CASTLE, {'alias': ('Small Key (Ganons Castle)', 10), 'progressive': float('Inf')}),
493+
'Small Key Ring (Treasure Chest Game)': ('TCGSmallKeyRing', True, GetItemId.GI_SMALL_KEY_RING_TREASURE_CHEST_GAME, {'alias': ('Small Key (Treasure Chest Game)', 10), 'progressive': float('Inf')}),
494494

495495
'Silver Rupee (Dodongos Cavern Staircase)': ('SilverRupee', True, GetItemId.GI_SILVER_RUPEE_DODONGOS_CAVERN_STAIRCASE, {'progressive': 5}),
496496
'Silver Rupee (Ice Cavern Spinning Scythe)': ('SilverRupee', True, GetItemId.GI_SILVER_RUPEE_ICE_CAVERN_SPINNING_SCYTHE, {'progressive': 5}),

ItemPool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@
375375
'Map': sorted([name for name, item in ItemInfo.items.items() if item.type == 'Map']),
376376
'Compass': sorted([name for name, item in ItemInfo.items.items() if item.type == 'Compass']),
377377
'BossKey': sorted([name for name, item in ItemInfo.items.items() if item.type == 'BossKey']),
378-
'SmallKey': sorted([name for name, item in ItemInfo.items.items() if item.type == 'SmallKey']),
378+
'SmallKey': sorted([name for name, item in ItemInfo.items.items() if item.type in ('SmallKey', 'SmallKeyRing')]),
379379

380380
'ForestFireWater': ('Forest Medallion', 'Fire Medallion', 'Water Medallion'),
381381
'FireWater': ('Fire Medallion', 'Water Medallion'),

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ issue. You should always Hard Reset to avoid this issue entirely.
123123

124124
* Ocarina buttons required to play the Song of Time are now part of the `path of time` goal.
125125
* The `Frogs Ocarina Game` misc. hint text box has been moved slightly so it no longer requires reloading the area to reread.
126+
* Fix key rings being hinted as small keys when keys are in their own dungeons.
126127

127128
#### Other Changes
128129
* Now supports custom music written for the Majora's Mask Randomizer.

Region.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,20 @@ def can_fill(self, item: Item, manual: bool = False) -> bool:
109109
is_dungeon_restricted = False
110110
is_overworld_restricted = False
111111

112-
if item.type in ('Map', 'Compass', 'SmallKey', 'HideoutSmallKey', 'TCGSmallKey', 'BossKey', 'GanonBossKey', 'SilverRupee', 'DungeonReward'):
112+
if item.type in ('Map', 'Compass', 'SmallKey', 'HideoutSmallKey', 'TCGSmallKey', 'SmallKeyRing', 'HideoutSmallKeyRing', 'TCGSmallKeyRing', 'BossKey', 'GanonBossKey', 'SilverRupee', 'DungeonReward'):
113113
shuffle_setting = (
114114
self.world.settings.shuffle_mapcompass if item.type in ('Map', 'Compass') else
115-
self.world.settings.shuffle_smallkeys if item.type == 'SmallKey' else
116-
self.world.settings.shuffle_hideoutkeys if item.type == 'HideoutSmallKey' else
117-
self.world.settings.shuffle_tcgkeys if item.type == 'TCGSmallKey' else
115+
self.world.settings.shuffle_smallkeys if item.type in ('SmallKey', 'SmallKeyRing') else
116+
self.world.settings.shuffle_hideoutkeys if item.type in ('HideoutSmallKey', 'HideoutSmallKeyRing') else
117+
self.world.settings.shuffle_tcgkeys if item.type in ('TCGSmallKey', 'TCGSmallKeyRing') else
118118
self.world.settings.shuffle_bosskeys if item.type == 'BossKey' else
119119
self.world.settings.shuffle_ganon_bosskey if item.type == 'GanonBossKey' else
120120
self.world.settings.shuffle_silver_rupees if item.type == 'SilverRupee' else
121121
self.world.settings.shuffle_dungeon_rewards if item.type == 'DungeonReward' else
122122
None
123123
)
124124

125-
is_self_dungeon_restricted = (shuffle_setting == 'dungeon' or (shuffle_setting == 'vanilla' and item.type != 'DungeonReward')) and item.type not in ('HideoutSmallKey', 'TCGSmallKey')
125+
is_self_dungeon_restricted = (shuffle_setting == 'dungeon' or (shuffle_setting == 'vanilla' and item.type != 'DungeonReward')) and item.type not in ('HideoutSmallKey', 'TCGSmallKey', 'HideoutSmallKeyRing', 'TCGSmallKeyRing')
126126
is_self_region_restricted = [HintArea.GERUDO_FORTRESS, HintArea.THIEVES_HIDEOUT] if shuffle_setting == 'fortress' else None
127127
if item.name in REWARD_COLORS:
128128
is_hint_color_restricted = [REWARD_COLORS[item.name]] if shuffle_setting == 'regional' else None

World.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ def initialize_items(self, items: Optional[list[Item]] = None) -> None:
667667
item_dict = defaultdict(list)
668668
for item in items:
669669
item_dict[item.name].append(item)
670-
if (self.settings.shuffle_hideoutkeys in ('fortress', 'regional') and item.type == 'HideoutSmallKey') or (self.settings.shuffle_tcgkeys == 'regional' and item.type == 'TCGSmallKey'):
670+
if (self.settings.shuffle_hideoutkeys in ('fortress', 'regional') and item.type in ('HideoutSmallKey', 'HideoutSmallKeyRing')) or (self.settings.shuffle_tcgkeys == 'regional' and item.type in ('TCGSmallKey', 'TCGSmallKeyRing')):
671671
item.priority = True
672672

673673
for dungeon in self.dungeons:

version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = '8.2.18'
1+
__version__ = '8.2.19'
22

33
# This is a supplemental version number for branches based off of main dev.
44
supplementary_version = 0

0 commit comments

Comments
 (0)