Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2022-01-19 04:09:14 -06:00
17 changed files with 456 additions and 398 deletions

View File

@@ -61,6 +61,7 @@ class World(object):
self.lock_aga_door_in_escape = False self.lock_aga_door_in_escape = False
self.save_and_quit_from_boss = True self.save_and_quit_from_boss = True
self.accessibility = accessibility.copy() self.accessibility = accessibility.copy()
self.initial_overworld_flags = {}
self.fix_skullwoods_exit = {} self.fix_skullwoods_exit = {}
self.fix_palaceofdarkness_exit = {} self.fix_palaceofdarkness_exit = {}
self.fix_trock_exit = {} self.fix_trock_exit = {}
@@ -118,6 +119,7 @@ class World(object):
set_player_attr('ganon_at_pyramid', True) set_player_attr('ganon_at_pyramid', True)
set_player_attr('ganonstower_vanilla', True) set_player_attr('ganonstower_vanilla', True)
set_player_attr('sewer_light_cone', self.mode[player] == 'standard') set_player_attr('sewer_light_cone', self.mode[player] == 'standard')
set_player_attr('initial_overworld_flags', [0] * 0x80)
set_player_attr('fix_trock_doors', self.shuffle[player] != 'vanilla' or ((self.mode[player] == 'inverted') != 0x05 in self.owswaps[player][0])) set_player_attr('fix_trock_doors', self.shuffle[player] != 'vanilla' or ((self.mode[player] == 'inverted') != 0x05 in self.owswaps[player][0]))
set_player_attr('fix_skullwoods_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] or self.doorShuffle[player] not in ['vanilla']) set_player_attr('fix_skullwoods_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] or self.doorShuffle[player] not in ['vanilla'])
set_player_attr('fix_palaceofdarkness_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) set_player_attr('fix_palaceofdarkness_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'])
@@ -302,6 +304,9 @@ class World(object):
def is_tile_swapped(self, owid, player): def is_tile_swapped(self, owid, player):
return (self.mode[player] == 'inverted') != (owid in self.owswaps[player][0] and self.owMixed[player]) return (self.mode[player] == 'inverted') != (owid in self.owswaps[player][0] and self.owMixed[player])
def is_bombshop_start(self, player):
return self.is_tile_swapped(0x2c, player) and (self.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not self.shufflelinks[player])
def check_for_door(self, doorname, player): def check_for_door(self, doorname, player):
if isinstance(doorname, Door): if isinstance(doorname, Door):
return doorname return doorname
@@ -1310,10 +1315,10 @@ class CollectionState(object):
return self.has('Fire Rod', player) or self.has('Lamp', player) return self.has('Fire Rod', player) or self.has('Lamp', player)
def can_flute(self, player): def can_flute(self, player):
if any(map(lambda i: i.name == 'Ocarina', self.world.precollected_items)): if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], self.world.precollected_items)):
return True return True
lw = self.world.get_region('Kakariko Area', player) lw = self.world.get_region('Kakariko Area', player)
return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player) return self.has('Ocarina Activated', player) or (self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player))
def can_melt_things(self, player): def can_melt_things(self, player):
return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player)) return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player))
@@ -1661,7 +1666,7 @@ class Entrance(object):
# this is checked first as this often the shortest path # this is checked first as this often the shortest path
follower_region = start_region follower_region = start_region
if follower_region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: if follower_region.type not in [RegionType.LightWorld, RegionType.DarkWorld]:
follower_region = start_region.entrances[0].parent_region follower_region = [i for i in start_region.entrances if i.parent_region.name != 'Menu'][0].parent_region
if (follower_region.world.mode[self.player] != 'inverted') == (follower_region.type == RegionType.LightWorld): if (follower_region.world.mode[self.player] != 'inverted') == (follower_region.type == RegionType.LightWorld):
from OWEdges import OWTileRegions from OWEdges import OWTileRegions
from OverworldShuffle import ow_connections from OverworldShuffle import ow_connections

View File

@@ -1,5 +1,24 @@
# Changelog # Changelog
### 0.2.5.0
- Many updates to Inverted OW Terrain:
- Links House start now spawns in Big Bomb Shop
- Old Man Cave/Bumper Cave returned to vanilla
- Mountain Cave S+Q now spawns in his usual Cave
- Flute Spot 1 is moved to Top of Dark Death Mountain
- Ladder is removed from West Dark Death Mountain
- When finding Flute, it comes pre-activated (will hear SFX on collecting)
- Spiral and Mimic Cave are now bridged together
- TR Peg Puzzle is restored but instead reveals a ladder
- Houlihan now exits same place as Big Bomb Shop does (OWR branch always had this)
- Ice Palace has been re-sealed to vanilla, portal moved to outer edge of moat
- Glitched modes will now use vanilla terrain except where necessary
- Fixed errors with OW Layout Shuffle
- Fixed issue with incorrect Mirror bonking
- Fixed issue with old man follower death to Pyramid
- Fixed Hera boss music not playing when boss not defeated
- ~~Merged DR v0.5.1.7 - TT boss trap door fix/Applied Glitched flag~~
### 0.2.4.0 ### 0.2.4.0
- Added Guaranteed OWR Reachability - Added Guaranteed OWR Reachability
- Fixed incorrect parity calc for Whirlpool Shuffle - Fixed incorrect parity calc for Whirlpool Shuffle

View File

@@ -1815,10 +1815,7 @@ def remove_pair_type_if_present(door, world, player):
def find_inaccessible_regions(world, player): def find_inaccessible_regions(world, player):
world.inaccessible_regions[player] = [] world.inaccessible_regions[player] = []
if world.mode[player] != 'inverted': start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint']
start_regions = ['Links House', 'Sanctuary']
else:
start_regions = ['Links House', 'Dark Sanctuary Hint']
regs = convert_regions(start_regions, world, player) regs = convert_regions(start_regions, world, player)
all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon] all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon]
visited_regions = set() visited_regions = set()
@@ -1836,7 +1833,7 @@ def find_inaccessible_regions(world, player):
if connect and connect not in queue and connect not in visited_regions: if connect and connect not in queue and connect not in visited_regions:
if connect.type is not RegionType.Dungeon or connect.name.endswith(' Portal'): if connect.type is not RegionType.Dungeon or connect.name.endswith(' Portal'):
queue.append(connect) queue.append(connect)
world.inaccessible_regions[player].extend([r.name for r in all_regions if r not in visited_regions and valid_inaccessible_region(r)]) world.inaccessible_regions[player].extend([r.name for r in all_regions if r not in visited_regions and valid_inaccessible_region(world, r, player)])
if world.is_tile_swapped(0x1b, player): if world.is_tile_swapped(0x1b, player):
ledge = world.get_region('Hyrule Castle Ledge', player) ledge = world.get_region('Hyrule Castle Ledge', player)
if any(x for x in ledge.exits if x.connected_region and x.connected_region.name == 'Agahnims Tower Portal'): if any(x for x in ledge.exits if x.connected_region and x.connected_region.name == 'Agahnims Tower Portal'):
@@ -1853,10 +1850,8 @@ def find_accessible_entrances(world, player, builder):
if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle': if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle':
start_regions = ['Hyrule Castle Courtyard'] start_regions = ['Hyrule Castle Courtyard']
elif world.mode[player] != 'inverted':
start_regions = ['Links House', 'Sanctuary']
else: else:
start_regions = ['Links House', 'Dark Sanctuary Hint'] start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint']
if world.is_tile_swapped(0x1b, player): if world.is_tile_swapped(0x1b, player):
start_regions.append('Hyrule Castle Ledge') start_regions.append('Hyrule Castle Ledge')
regs = convert_regions(start_regions, world, player) regs = convert_regions(start_regions, world, player)
@@ -1890,8 +1885,8 @@ def find_accessible_entrances(world, player, builder):
return visited_entrances return visited_entrances
def valid_inaccessible_region(r): def valid_inaccessible_region(world, r, player):
return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House', 'Chris Houlihan Room']) return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Chris Houlihan Room'])
def add_inaccessible_doors(world, player): def add_inaccessible_doors(world, player):

View File

@@ -47,11 +47,6 @@ def link_entrances(world, player):
dropexit_connections.append(tuple(('Inverted Pyramid Entrance', 'Pyramid Exit'))) dropexit_connections.append(tuple(('Inverted Pyramid Entrance', 'Pyramid Exit')))
connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player)
if not world.is_tile_swapped(0x03, player):
connect_simple(world, 'Old Man S&Q', 'Old Man House', player)
else:
connect_simple(world, 'Old Man S&Q', 'West Dark Death Mountain (Bottom)', player)
unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits)
Cave_Exits.extend(Cave_Exits_Directional) Cave_Exits.extend(Cave_Exits_Directional)
@@ -59,47 +54,33 @@ def link_entrances(world, player):
for exitname, regionname in mandatory_connections: for exitname, regionname in mandatory_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
if not invFlag: if not world.is_bombshop_start(player):
for exitname, regionname in open_mandatory_connections: connect_simple(world, 'Links House S&Q', 'Links House', player)
connect_simple(world, exitname, regionname, player)
else: else:
for exitname, regionname in inverted_mandatory_connections: connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player)
connect_simple(world, exitname, regionname, player)
if not invFlag:
connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player)
else:
connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player)
connect_simple(world, 'Tavern North', 'Tavern', player) connect_simple(world, 'Tavern North', 'Tavern', player)
suppress_spoiler = False
connect_custom(world, player) connect_custom(world, player)
suppress_spoiler = True
# if we do not shuffle, set default connections # if we do not shuffle, set default connections
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections: for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections:
connect_logical(world, entrancename, exitname, player, False) connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit'))
for entrancename, exitname in default_connector_connections + dropexit_connections: for entrancename, exitname in default_connector_connections + dropexit_connections:
connect_logical(world, entrancename, exitname, player, True) connect_logical(world, entrancename, exitname, player, True)
if invFlag: if invFlag:
world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region) world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region)
if world.is_bombshop_start(player):
world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance('Big Bomb Shop', player).parent_region)
if not invFlag:
for entrancename, exitname in open_default_connections:
connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit'))
else:
for entrancename, exitname in inverted_default_connections:
connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit'))
# inverted entrance mods
ignore_pool = True
for owid in swapped_connections.keys():
if world.is_tile_swapped(owid, player):
for (entrancename, exitname) in swapped_connections[owid]:
try:
connect_two_way(world, entrancename, exitname, player)
except RuntimeError:
connect_entrance(world, entrancename, exitname, player)
if world.is_tile_swapped(0x03, player) and not world.is_tile_swapped(0x0a, player):
connect_entrance(world, 'Death Mountain Return Cave (West)', 'Dark Death Mountain Healer Fairy', player)
elif world.is_tile_swapped(0x0a, player) and not world.is_tile_swapped(0x03, player):
connect_two_way(world, 'Bumper Cave (Top)', 'Death Mountain Return Cave Exit (West)', player)
ignore_pool = False ignore_pool = False
# dungeon entrance shuffle # dungeon entrance shuffle
@@ -129,7 +110,8 @@ def link_entrances(world, player):
scramble_holes(world, player) scramble_holes(world, player)
# list modification # list modification
lw_wdm_entrances = ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', lw_wdm_entrances = ['Old Man Cave (West)', 'Death Mountain Return Cave (West)',
'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)',
'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave',
'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)'] 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)']
lw_edm_entrances = ['Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Spiral Cave', lw_edm_entrances = ['Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Spiral Cave',
@@ -139,13 +121,9 @@ def link_entrances(world, player):
caves = list(Cave_Exits) caves = list(Cave_Exits)
three_exit_caves = list(Cave_Three_Exits) three_exit_caves = list(Cave_Three_Exits)
Two_Door_Caves_Directional = list() Two_Door_Caves_Directional = [('Bumper Cave (Bottom)', 'Bumper Cave (Top)')]
Two_Door_Caves = [('Elder House (East)', 'Elder House (West)'), Two_Door_Caves = [('Elder House (East)', 'Elder House (West)'),
('Superbunny Cave (Bottom)', 'Superbunny Cave (Top)')] ('Superbunny Cave (Bottom)', 'Superbunny Cave (Top)')]
if not world.is_tile_swapped(0x0a, player):
Two_Door_Caves_Directional.append(tuple({'Bumper Cave (Bottom)', 'Bumper Cave (Top)'}))
else:
Two_Door_Caves_Directional.append(tuple({'Old Man Cave (West)', 'Death Mountain Return Cave (West)'}))
if not world.is_tile_swapped(0x05, player): if not world.is_tile_swapped(0x05, player):
Two_Door_Caves_Directional.append(tuple({'Hookshot Cave', 'Hookshot Cave Back Entrance'})) Two_Door_Caves_Directional.append(tuple({'Hookshot Cave', 'Hookshot Cave Back Entrance'}))
else: else:
@@ -179,43 +157,25 @@ def link_entrances(world, player):
caves.extend(list(Old_Man_House)) caves.extend(list(Old_Man_House))
caves.extend(list(three_exit_caves)) caves.extend(list(three_exit_caves))
if (not world.is_tile_swapped(0x18, player)) or (not world.is_tile_swapped(0x03, player)): # ability to activate flute in LW candidates = [e for e in lw_wdm_entrances if e != 'Old Man House (Bottom)']
candidates = [e for e in lw_wdm_entrances if e != 'Old Man House (Bottom)'] random.shuffle(candidates)
old_man_exit = candidates.pop()
lw_wdm_entrances.remove(old_man_exit)
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world
candidates = lw_wdm_entrances + lw_edm_entrances
random.shuffle(candidates) random.shuffle(candidates)
old_man_exit = candidates.pop() old_man_entrance = candidates.pop()
lw_wdm_entrances.remove(old_man_exit) if old_man_entrance in lw_wdm_entrances:
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
if not world.is_tile_swapped(0x0a, player):
lw_wdm_entrances.extend(['Old Man Cave (West)', 'Death Mountain Return Cave (West)'])
else:
lw_wdm_entrances.extend(['Bumper Cave (Bottom)', 'Bumper Cave (Top)'])
if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world
candidates = lw_wdm_entrances + lw_edm_entrances
random.shuffle(candidates)
old_man_entrance = candidates.pop()
lw_wdm_entrances.remove(old_man_entrance) lw_wdm_entrances.remove(old_man_entrance)
if old_man_entrance in lw_wdm_entrances: elif old_man_entrance in lw_edm_entrances:
lw_wdm_entrances.remove(old_man_entrance) lw_edm_entrances.remove(old_man_entrance)
elif old_man_entrance in lw_edm_entrances:
lw_edm_entrances.remove(old_man_entrance)
else:
random.shuffle(lw_wdm_entrances)
old_man_entrance = lw_wdm_entrances.pop()
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
else: else:
# force connection to DM random.shuffle(lw_wdm_entrances)
random.shuffle(ddm_entrances) old_man_entrance = lw_wdm_entrances.pop()
old_man_exit = ddm_entrances.pop() connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
# place old man, bumper cave bottom to DDM entrances not in east bottom
if not world.is_tile_swapped(0x0a, player):
connect_two_way(world, 'Old Man Cave (West)', 'Old Man Cave Exit (West)', player)
else:
connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player)
# connect remaining LW DM entrances # connect remaining LW DM entrances
if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world
connect_caves(world, lw_wdm_entrances + lw_edm_entrances, [], caves, player) connect_caves(world, lw_wdm_entrances + lw_edm_entrances, [], caves, player)
@@ -255,11 +215,12 @@ def link_entrances(world, player):
junk_fill_inaccessible(world, player) junk_fill_inaccessible(world, player)
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# place remaining doors # place remaining doors
connect_doors(world, list(entrance_pool), list(exit_pool), player) connect_doors(world, list(entrance_pool), list(exit_pool), player)
@@ -300,11 +261,12 @@ def link_entrances(world, player):
place_old_man(world, lw_entrances if not invFlag else dw_entrances, player) place_old_man(world, lw_entrances if not invFlag else dw_entrances, player)
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# shuffle connectors # shuffle connectors
lw_entrances = [e for e in lw_entrances if e in entrance_pool] lw_entrances = [e for e in lw_entrances if e in entrance_pool]
@@ -357,11 +319,12 @@ def link_entrances(world, player):
place_old_man(world, lw_entrances if not invFlag else dw_entrances, player, list(zip(*drop_connections + dropexit_connections))[0]) place_old_man(world, lw_entrances if not invFlag else dw_entrances, player, list(zip(*drop_connections + dropexit_connections))[0])
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]] if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]]
bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# shuffle connectors # shuffle connectors
lw_entrances = [e for e in lw_entrances if e in entrance_pool] lw_entrances = [e for e in lw_entrances if e in entrance_pool]
@@ -459,11 +422,12 @@ def link_entrances(world, player):
connect_caves(world, lw_entrances, dw_entrances, caves, player) connect_caves(world, lw_entrances, dw_entrances, caves, player)
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# place remaining doors # place remaining doors
connect_doors(world, list(entrance_pool), list(exit_pool), player) connect_doors(world, list(entrance_pool), list(exit_pool), player)
@@ -513,11 +477,12 @@ def link_entrances(world, player):
connect_caves(world, connector_entrances, [], caves, player) connect_caves(world, connector_entrances, [], caves, player)
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# place remaining doors # place remaining doors
connect_doors(world, list(entrance_pool), list(exit_pool), player) connect_doors(world, list(entrance_pool), list(exit_pool), player)
@@ -562,11 +527,12 @@ def link_entrances(world, player):
place_old_man(world, pool, player) place_old_man(world, pool, player)
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
bomb_shop = random.choice(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) bomb_shop = random.choice(bomb_shop_doors)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# shuffle connectors # shuffle connectors
pool = [e for e in pool if e in entrance_pool] pool = [e for e in pool if e in entrance_pool]
@@ -645,13 +611,14 @@ def link_entrances(world, player):
caves.append('Old Man Cave Exit (West)') caves.append('Old Man Cave Exit (West)')
# place bomb shop, has limited options # place bomb shop, has limited options
bomb_shop_doors = list(entrance_pool) if not world.is_bombshop_start(player):
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = list(entrance_pool)
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
random.shuffle(bomb_shop_doors) bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
bomb_shop = bomb_shop_doors.pop() random.shuffle(bomb_shop_doors)
pool.remove(bomb_shop) bomb_shop = bomb_shop_doors.pop()
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) pool.remove(bomb_shop)
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
# shuffle connectors # shuffle connectors
doors = list(entrance_pool) doors = list(entrance_pool)
@@ -675,8 +642,8 @@ def link_entrances(world, player):
# ensure Houlihan exits where Links House does # ensure Houlihan exits where Links House does
# TODO: Plando should overrule this # TODO: Plando should overrule this
if not links_house: if not links_house:
for links_house in world.get_entrance('Links House Exit', player).connected_region.exits: for links_house in world.get_entrance('Links House Exit' if not world.is_bombshop_start(player) else 'Big Bomb Shop Exit', player).connected_region.exits:
if links_house.connected_region and links_house.connected_region.name == 'Links House': if links_house.connected_region and links_house.connected_region.name == ('Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop'):
links_house = links_house.name links_house = links_house.name
break break
connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) connect_exit(world, 'Chris Houlihan Room Exit', links_house, player)
@@ -1375,7 +1342,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
def place_links_house(world, player, ignore_list=[]): def place_links_house(world, player, ignore_list=[]):
invFlag = world.mode[player] == 'inverted' invFlag = world.mode[player] == 'inverted'
if world.mode[player] == 'standard' or not world.shufflelinks[player]: if world.mode[player] == 'standard' or not world.shufflelinks[player]:
links_house = 'Links House' if not invFlag else 'Big Bomb Shop' links_house = 'Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop'
else: else:
if invFlag: if invFlag:
for dark_sanc in world.get_entrance('Dark Sanctuary Hint Exit', player).connected_region.exits: for dark_sanc in world.get_entrance('Dark Sanctuary Hint Exit', player).connected_region.exits:
@@ -1394,7 +1361,11 @@ def place_links_house(world, player, ignore_list=[]):
links_house_doors = [e for e in links_house_doors if e not in ignore_list] links_house_doors = [e for e in links_house_doors if e not in ignore_list]
assert len(links_house_doors), 'No valid candidates to place Links House' assert len(links_house_doors), 'No valid candidates to place Links House'
links_house = random.choice(links_house_doors) links_house = random.choice(links_house_doors)
connect_two_way(world, links_house, 'Links House Exit', player) if not world.is_bombshop_start(player):
connect_two_way(world, links_house, 'Links House Exit', player)
else:
connect_entrance(world, links_house, 'Big Bomb Shop', player)
world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance(links_house, player).parent_region)
return links_house return links_house
@@ -2077,7 +2048,7 @@ Exit_Pool_Base = ['Links House Exit',
'Pyramid'] 'Pyramid']
# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions # these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions
mandatory_connections = [('Links House S&Q', 'Links House'), mandatory_connections = [('Old Man S&Q', 'Old Man House'),
# UW Connections # UW Connections
('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'),
@@ -2108,10 +2079,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'),
('Ganon Drop', 'Bottom of Pyramid') ('Ganon Drop', 'Bottom of Pyramid')
] ]
open_mandatory_connections = [('Sanctuary S&Q', 'Sanctuary')]
inverted_mandatory_connections = [('Sanctuary S&Q', 'Dark Sanctuary Hint')]
# non-shuffled entrance links # non-shuffled entrance links
default_connections = [('Lumberjack House', 'Lumberjack House'), default_connections = [('Lumberjack House', 'Lumberjack House'),
('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), ('Bonk Fairy (Light)', 'Bonk Fairy (Light)'),
@@ -2176,7 +2143,8 @@ default_connector_connections = [('Old Man Cave (West)', 'Old Man Cave Exit (Wes
('Hookshot Cave Back Entrance', 'Hookshot Cave Back Exit') ('Hookshot Cave Back Entrance', 'Hookshot Cave Back Exit')
] ]
default_item_connections = [('Mimic Cave', 'Mimic Cave'), default_item_connections = [('Links House', 'Links House Exit'),
('Mimic Cave', 'Mimic Cave'),
('Waterfall of Wishing', 'Waterfall of Wishing'), ('Waterfall of Wishing', 'Waterfall of Wishing'),
('Bonk Rock Cave', 'Bonk Rock Cave'), ('Bonk Rock Cave', 'Bonk Rock Cave'),
('Graveyard Cave', 'Graveyard Cave'), ('Graveyard Cave', 'Graveyard Cave'),
@@ -2200,6 +2168,7 @@ default_item_connections = [('Mimic Cave', 'Mimic Cave'),
('Brewery', 'Brewery'), ('Brewery', 'Brewery'),
('Pyramid Fairy', 'Pyramid Fairy'), ('Pyramid Fairy', 'Pyramid Fairy'),
('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'), ('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'),
('Big Bomb Shop', 'Big Bomb Shop'),
('Mire Shed', 'Mire Shed'), ('Mire Shed', 'Mire Shed'),
('Hype Cave', 'Hype Cave') ('Hype Cave', 'Hype Cave')
] ]
@@ -2235,28 +2204,6 @@ default_dropexit_connections = [('Lost Woods Hideout Stump', 'Lost Woods Hideout
#('Pyramid Entrance', 'Pyramid Exit') # this is dynamically added because of Inverted/OW Mixed #('Pyramid Entrance', 'Pyramid Exit') # this is dynamically added because of Inverted/OW Mixed
] ]
swapped_connections = {
0x03: [
('Old Man Cave (East)', 'Death Mountain Return Cave Exit (West)'),
#('Death Mountain Return Cave (East)', 'Death Mountain Return Cave Exit (East)'),
('Dark Death Mountain Fairy', 'Old Man Cave Exit (East)')
],
0x0a: [
('Old Man Cave (West)', 'Bumper Cave Exit (Bottom)'),
('Death Mountain Return Cave (West)', 'Bumper Cave Exit (Top)'),
('Bumper Cave (Bottom)', 'Old Man Cave Exit (West)'),
('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy')
]
}
open_default_connections = [('Links House', 'Links House Exit'),
('Big Bomb Shop', 'Big Bomb Shop')
]
inverted_default_connections = [('Big Bomb Shop', 'Links House Exit'),
('Links House', 'Big Bomb Shop')
]
# non shuffled dungeons # non shuffled dungeons
default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace Exit (South)'), default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace Exit (South)'),
('Desert Palace Entrance (West)', 'Desert Palace Exit (West)'), ('Desert Palace Entrance (West)', 'Desert Palace Exit (West)'),
@@ -2349,177 +2296,175 @@ one_way_ledges = {
indirect_connections = { indirect_connections = {
'Turtle Rock Ledge': 'Turtle Rock', 'Turtle Rock Ledge': 'Turtle Rock',
'Big Bomb Shop': 'Pyramid Fairy', #'Big Bomb Shop': 'Pyramid Fairy',
#'East Dark World': 'Pyramid Fairy', #'East Dark World': 'Pyramid Fairy',
'Pyramid Area': 'Pyramid Fairy', # HC Ledge/Courtyard 'Pyramid Area': 'Pyramid Fairy', # HC Ledge/Courtyard
#'Dark Desert': 'Pyramid Fairy', #'Dark Desert': 'Pyramid Fairy',
'Misery Mire Area': 'Pyramid Fairy', # Desert/Checkerboard Ledge #'Misery Mire Area': 'Pyramid Fairy', # Desert/Checkerboard Ledge
#'West Dark World': 'Pyramid Fairy', #'West Dark World': 'Pyramid Fairy',
'Dark Chapel Area': 'Pyramid Fairy', # Bonk Rocks #'Dark Chapel Area': 'Pyramid Fairy', # Bonk Rocks
'Dark Graveyard North': 'Pyramid Fairy', # Graveyard Ledge/Kings Tomb #'Dark Graveyard North': 'Pyramid Fairy', # Graveyard Ledge/Kings Tomb
#'South Dark World': 'Pyramid Fairy', #'South Dark World': 'Pyramid Fairy',
'Dig Game Ledge': 'Pyramid Fairy', # Brother House Left #'Dig Game Ledge': 'Pyramid Fairy', # Brother House Left
'Stumpy Approach Area': 'Pyramid Fairy', # Cave 45 #'Stumpy Approach Area': 'Pyramid Fairy', # Cave 45
# Inverted Cases # Inverted Cases
#'Light World': 'Pyramid Fairy', #'Light World': 'Pyramid Fairy',
'Lost Woods West Area': 'Pyramid Fairy', # Skull Woods Back #'Lost Woods West Area': 'Pyramid Fairy', # Skull Woods Back
'East Death Mountain (Top East)': 'Pyramid Fairy', # Floating Island #'East Death Mountain (Top East)': 'Pyramid Fairy', # Floating Island
'Blacksmith Area': 'Pyramid Fairy', # Hammerpegs #'Blacksmith Area': 'Pyramid Fairy', # Hammerpegs
'Forgotten Forest Area': 'Pyramid Fairy', # Shield Shop #'Forgotten Forest Area': 'Pyramid Fairy', # Shield Shop
'Desert Area': 'Pyramid Fairy', # Mire Area #'Desert Area': 'Pyramid Fairy', # Mire Area
'Old Man Cave': 'Old Man S&Q' 'Old Man Cave': 'Old Man S&Q'
} }
# format: # format:
# Key=Name # Key=Name
# addr = (door_index, exitdata) # multiexit # addr = (door_index, exitdata, ow_flag) # multiexit
# | ([addr], None) # holes # | ([addr], None) # holes
# exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2) # exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2)
# ToDo somehow merge this with creation of the locations # ToDo somehow merge this with creation of the locations
door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000), 0x00),
# ToDo somehow merge this with creation of the locations 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000), 0x00),
door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000), 0x00),
'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)), 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000), 0x00),
'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)), 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000), 0x00),
'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)), 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x00),
'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)), 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000), 0x00),
'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be), 0x00),
'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)), 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124), 0x00),
'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)), 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158), 0x00),
'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)), 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c), 0x00),
'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)), 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be), 0x40),
'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c)), 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000), 0x00),
'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)), 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000), 0x00),
'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)), 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00),
'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)), 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000), 0x20),
'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)), 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000), 0x00),
'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)), 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000), 0x20),
'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)), 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x20),
'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)), 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000), 0x00),
'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)), 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000), 0x00),
'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)), 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)), 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000), 0x00),
'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)), 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000), 0x00),
'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)), 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000), 0x00),
'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)), 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000), 0x00),
'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)), 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000), 0x00),
'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)), 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00),
'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)), 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000), 0x00),
'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)), 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000), 0x00),
'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)), 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000), 0x00),
'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)), 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa), 0x00),
'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)), 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000), 0x00),
'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)), 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000), 0x00),
'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)), 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000), 0x00),
'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)), 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000), 0x00),
'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)), 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000), 0x00),
'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)), 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)), 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00),
'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00),
'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000), 0x00),
'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)), 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00),
'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00),
'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000), 0x00),
'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)), 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000), 0x00),
'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)), 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)), 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000), 0x00),
'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00),
'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)), 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00),
'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000), 0x20),
'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000), 0x00),
'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)), 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000), 0x20),
'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)), 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)),
'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000)),
'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None),
'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None),
'Skull Woods First Section Hole (North)': ([0xDB84C], None), 'Skull Woods First Section Hole (North)': ([0xDB84C], None),
'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None),
'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None),
'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None),
'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)), 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)), 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None),
'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)), 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000), 0x02),
'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000), 0x20),
'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), # do not use, buggy 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000), 0x00), # do not use, buggy
'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000), 0x00),
'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000), 0x00),
'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)), 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)), 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None),
'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)), 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000), 0x00),
'Bat Cave Drop': ([0xDB859, 0xDB85A], None), 'Bat Cave Drop': ([0xDB859, 0xDB85A], None),
'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)), 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000), 0x00),
'North Fairy Cave Drop': ([0xDB857], None), 'North Fairy Cave Drop': ([0xDB857], None),
'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)), 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)), 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)), 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000), 0x00),
'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)), 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000), 0x00),
'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)), 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000), 0x00),
'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)), 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000), 0x00),
'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)), 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000), 0x02),
'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)), 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000), 0x00),
'Lost Woods Hideout Drop': ([0xDB853], None), 'Lost Woods Hideout Drop': ([0xDB853], None),
'Lumberjack Tree Tree': ([0xDB85B], None), 'Lumberjack Tree Tree': ([0xDB85B], None),
'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)), 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000), 0x00),
'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)), 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)), 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)), 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000), 0x02),
'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)), '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000), 0x20),
'50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)), '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02),
'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)), 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000), 0x20),
'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)), 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000), 0x00),
'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)), 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000), 0x00),
'Sanctuary Grave': ([0xDB85E], None), 'Sanctuary Grave': ([0xDB85E], None),
'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)), 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000), 0x02),
'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)), 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02),
'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)), 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000), 0x20),
'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)), 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000), 0x02),
'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)), 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000), 0x20),
'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)), 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000), 0x02),
'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)), 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000), 0x00),
'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)), 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000), 0x00),
'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)), 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000), 0x20),
'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)), 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000), 0x00),
'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000), 0x00),
'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)), 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000), 0x00),
'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)), 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)), 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)), 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)), 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00),
'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)), 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000), 0x00),
'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)), 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000), 0x00),
'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)), 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)), 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)), 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000), 0x00),
'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)), 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000), 0x00),
'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))} 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)}
# format: # format:
# Key=Name # Key=Name

View File

@@ -266,7 +266,7 @@ def generate_itempool(world, player):
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray[player]) (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray[player])
world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999)
else: else:
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player]) (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.is_tile_swapped(0x18, player))
if player in world.pool_adjustment.keys(): if player in world.pool_adjustment.keys():
amt = world.pool_adjustment[player] amt = world.pool_adjustment[player]
@@ -749,7 +749,7 @@ rupee_chart = {'Rupee (1)': 1, 'Rupees (5)': 5, 'Rupees (20)': 20, 'Rupees (50)'
'Rupees (100)': 100, 'Rupees (300)': 300} 'Rupees (100)': 100, 'Rupees (300)': 300}
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic): def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, flute_activated):
pool = [] pool = []
placed_items = {} placed_items = {}
precollected_items = [] precollected_items = []
@@ -761,6 +761,10 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
pool.extend(alwaysitems) pool.extend(alwaysitems)
if flute_activated:
pool.remove('Ocarina')
pool.append('Ocarina (Activated)')
def place_item(loc, item): def place_item(loc, item):
assert loc not in placed_items assert loc not in placed_items
placed_items[loc] = item placed_items[loc] = item
@@ -1022,7 +1026,7 @@ def test():
for retro in [True, False]: for retro in [True, False]:
for door_shuffle in ['basic', 'crossed', 'vanilla']: for door_shuffle in ['basic', 'crossed', 'vanilla']:
for bombbag in [True, False]: for bombbag in [True, False]:
out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic) out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, False)
count = len(out[0]) + len(out[1]) count = len(out[0]) + len(out[1])
correct_count = total_items_to_place correct_count = total_items_to_place

View File

@@ -31,6 +31,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'), 'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'),
'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'), 'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'),
'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'), 'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'),
'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'),
'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'), 'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'),
'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the glove'), 'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the glove'),
'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'), 'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'),

View File

@@ -30,7 +30,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
from Utils import output_path, parse_player_names from Utils import output_path, parse_player_names
__version__ = '0.5.1.6-u' __version__ = '0.5.1.7-u'
from source.classes.BabelFish import BabelFish from source.classes.BabelFish import BabelFish

View File

@@ -703,6 +703,7 @@ OWTileRegions = bidict({
'East Death Mountain (Top East)': 0x05, 'East Death Mountain (Top East)': 0x05,
'Spiral Cave Ledge': 0x05, 'Spiral Cave Ledge': 0x05,
'Mimic Cave Ledge': 0x05, 'Mimic Cave Ledge': 0x05,
'Spiral Mimic Ledge Extend': 0x05,
'Fairy Ascension Ledge': 0x05, 'Fairy Ascension Ledge': 0x05,
'Fairy Ascension Plateau': 0x05, 'Fairy Ascension Plateau': 0x05,
'East Death Mountain (Bottom Left)': 0x05, 'East Death Mountain (Bottom Left)': 0x05,
@@ -819,6 +820,7 @@ OWTileRegions = bidict({
'Lake Hylia Central Island': 0x35, 'Lake Hylia Central Island': 0x35,
'Lake Hylia Island': 0x35, 'Lake Hylia Island': 0x35,
'Lake Hylia Water': 0x35, 'Lake Hylia Water': 0x35,
'Lake Hylia Water D': 0x35,
'Ice Cave Area': 0x37, 'Ice Cave Area': 0x37,
@@ -991,7 +993,7 @@ OWTileGroups = {
0x42 0x42
] ]
), ),
("West Mountain", "Regular", "None"): ( ("Mountain Entry", "Entrance", "None"): (
[ [
0x03 0x03
], ],
@@ -1183,14 +1185,14 @@ OWTileGroups = {
0x6b 0x6b
] ]
), ),
# ("Links", "Regular", "None"): ( ("Links", "Regular", "None"): (
# [ [
# 0x2c 0x2c
# ], ],
# [ [
# 0x6c 0x6c
# ] ]
# ), ),
("Tree Line", "Regular", "None"): ( ("Tree Line", "Regular", "None"): (
[ [
0x2e 0x2e
@@ -1402,6 +1404,7 @@ OWExitTypes = {
'East Death Mountain Mimic Ledge Drop', 'East Death Mountain Mimic Ledge Drop',
'Spiral Ledge Drop', 'Spiral Ledge Drop',
'Mimic Ledge Drop', 'Mimic Ledge Drop',
'Spiral Mimic Ledge Drop',
'Fairy Ascension Ledge Drop', 'Fairy Ascension Ledge Drop',
'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Plateau Ledge Drop',
'TR Pegs Ledge Drop', 'TR Pegs Ledge Drop',
@@ -1514,6 +1517,10 @@ OWExitTypes = {
'Fairy Ascension Rocks (North)', 'Fairy Ascension Rocks (North)',
'DM Broken Bridge (West)', 'DM Broken Bridge (West)',
'DM Broken Bridge (East)', 'DM Broken Bridge (East)',
'Spiral Mimic Bridge (West)',
'Spiral Mimic Bridge (East)',
'Spiral Ledge Approach',
'Mimic Ledge Approach',
'Fairy Ascension Rocks (South)', 'Fairy Ascension Rocks (South)',
'Floating Island Bridge (West)', 'Floating Island Bridge (West)',
'TR Pegs Ledge Entry', 'TR Pegs Ledge Entry',
@@ -1578,6 +1585,7 @@ OWExitTypes = {
'Lake Hylia West Pier', 'Lake Hylia West Pier',
'Lake Hylia Northeast Water Drop', 'Lake Hylia Northeast Water Drop',
'Lake Hylia East Pier', 'Lake Hylia East Pier',
'Lake Hylia Water D Entry',
'Desert Pass Ladder (South)', 'Desert Pass Ladder (South)',
'Desert Pass Rocks (North)', 'Desert Pass Rocks (North)',
'Desert Pass Rocks (South)', 'Desert Pass Rocks (South)',
@@ -1590,9 +1598,7 @@ OWExitTypes = {
'Skull Woods Forgotten Bush (West)', 'Skull Woods Forgotten Bush (West)',
'Skull Woods Forgotten Bush (East)', 'Skull Woods Forgotten Bush (East)',
'GT Entry Approach', 'GT Entry Approach',
'Dark Death Mountain Ladder (North)',
'GT Entry Leave', 'GT Entry Leave',
'Dark Death Mountain Ladder (South)',
'Bumper Cave Entrance Rock', 'Bumper Cave Entrance Rock',
'Skull Woods Pass Bush Row (West)', 'Skull Woods Pass Bush Row (West)',
'Skull Woods Pass Bush Row (East)', 'Skull Woods Pass Bush Row (East)',
@@ -1635,8 +1641,6 @@ OWExitTypes = {
'Ice Lake Northeast Pier', 'Ice Lake Northeast Pier',
'Ice Lake Northeast Pier Hop', 'Ice Lake Northeast Pier Hop',
'Ice Lake Moat Water Entry', 'Ice Lake Moat Water Entry',
'Ice Palace Approach',
'Ice Palace Leave',
'Bomber Corner Water Drop', 'Bomber Corner Water Drop',
'Bomber Corner Pier' 'Bomber Corner Pier'
], ],
@@ -1756,6 +1760,7 @@ OWExitTypes = {
'Ice Lake Southeast Mirror Spot', 'Ice Lake Southeast Mirror Spot',
'Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Mirror Spot',
'Ice Palace Mirror Spot', 'Ice Palace Mirror Spot',
'Ice Lake Moat Mirror Spot',
'Shopping Mall Mirror Spot', 'Shopping Mall Mirror Spot',
'Swamp Nook Mirror Spot', 'Swamp Nook Mirror Spot',
'Swamp Nook Southeast Mirror Spot', 'Swamp Nook Southeast Mirror Spot',

View File

@@ -150,6 +150,7 @@ def get_boots_clip_exits_lw(inverted = False):
yield ('WDM DMD To River Bend Clip', 'East Death Mountain (Bottom Left)', 'River Bend Area') yield ('WDM DMD To River Bend Clip', 'East Death Mountain (Bottom Left)', 'River Bend Area')
yield ('EDM DMD To River Bend Clip', 'East Death Mountain (Bottom)', 'River Bend Area') yield ('EDM DMD To River Bend Clip', 'East Death Mountain (Bottom)', 'River Bend Area')
yield ('TR Pegs Ledge Clip', 'Death Mountain TR Pegs', 'Death Mountain TR Pegs Ledge') yield ('TR Pegs Ledge Clip', 'Death Mountain TR Pegs', 'Death Mountain TR Pegs Ledge')
yield ('TR Pegs Ledge Descent Clip', 'Death Mountain TR Pegs Ledge', 'Death Mountain TR Pegs')
yield ('TR Pegs To EDM Clip', 'Death Mountain TR Pegs', 'East Death Mountain (Top East)') yield ('TR Pegs To EDM Clip', 'Death Mountain TR Pegs', 'East Death Mountain (Top East)')
yield ('Zora DMD Clip', 'Death Mountain TR Pegs', 'Zora Waterfall Area') yield ('Zora DMD Clip', 'Death Mountain TR Pegs', 'Zora Waterfall Area')
yield ('Mountain Entry To Ledge Clip', 'Mountain Entry Area', 'Mountain Entry Ledge') yield ('Mountain Entry To Ledge Clip', 'Mountain Entry Area', 'Mountain Entry Ledge')

View File

@@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl
from Regions import mark_dark_world_regions, mark_light_world_regions from Regions import mark_dark_world_regions, mark_light_world_regions
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
__version__ = '0.2.4.0-u' __version__ = '0.2.5.0-u'
def link_overworld(world, player): def link_overworld(world, player):
# setup mandatory connections # setup mandatory connections
@@ -817,7 +817,7 @@ def can_reach_smith(world, player):
region = world.get_region(region_name, player) region = world.get_region(region_name, player)
for exit in region.exits: for exit in region.exits:
if not found and exit.connected_region is not None: if not found and exit.connected_region is not None:
if any(map(lambda i: i.name == 'Ocarina', world.precollected_items)) and exit.spot_type == 'Flute': if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], world.precollected_items)) and exit.spot_type == 'Flute':
fluteregion = exit.connected_region fluteregion = exit.connected_region
for flutespot in fluteregion.exits: for flutespot in fluteregion.exits:
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions: if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
@@ -841,7 +841,11 @@ def can_reach_smith(world, player):
found = False found = False
explored_regions = list() explored_regions = list()
explore_region('Links House') if not world.is_bombshop_start(player):
start_region = 'Links House'
else:
start_region = 'Big Bomb Shop'
explore_region(start_region)
if not found: if not found:
if not invFlag: if not invFlag:
explore_region('Sanctuary') explore_region('Sanctuary')
@@ -869,7 +873,7 @@ def build_sectors(world, player):
if (any(r in unique_regions for r in explored_regions)): if (any(r in unique_regions for r in explored_regions)):
for s in range(len(sectors)): for s in range(len(sectors)):
if (any(r in sectors[s] for r in explored_regions)): if (any(r in sectors[s] for r in explored_regions)):
sectors[s] = list(list(sectors[s]) + list(explored_regions)) sectors[s] = list(dict.fromkeys(list(sectors[s]) + list(explored_regions)))
break break
else: else:
sectors.append(explored_regions) sectors.append(explored_regions)
@@ -895,7 +899,7 @@ def build_sectors(world, player):
if (any(r in unique_regions for r in explored_regions)): if (any(r in unique_regions for r in explored_regions)):
for s2 in range(len(sectors2)): for s2 in range(len(sectors2)):
if (any(r in sectors2[s2] for r in explored_regions)): if (any(r in sectors2[s2] for r in explored_regions)):
sectors2[s2] = list(sectors2[s2] + explored_regions) sectors2[s2] = list(dict.fromkeys(sectors2[s2] + explored_regions))
break break
else: else:
sectors2.append(explored_regions) sectors2.append(explored_regions)
@@ -918,7 +922,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
region = base_world.get_region(region_name, player) region = base_world.get_region(region_name, player)
for exit in region.exits: for exit in region.exits:
if exit.connected_region is not None: if exit.connected_region is not None:
if any(map(lambda i: i.name == 'Ocarina', base_world.precollected_items)) and exit.spot_type == 'Flute': if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], base_world.precollected_items)) and exit.spot_type == 'Flute':
fluteregion = exit.connected_region fluteregion = exit.connected_region
for flutespot in fluteregion.exits: for flutespot in fluteregion.exits:
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions: if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
@@ -1027,7 +1031,7 @@ def validate_layout(world, player):
explored_regions = list() explored_regions = list()
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]:
if not world.is_tile_swapped(0x2c, player): if not world.is_bombshop_start(player):
start_region = 'Links House Area' start_region = 'Links House Area'
else: else:
start_region = 'Big Bomb Shop Area' start_region = 'Big Bomb Shop Area'
@@ -1049,7 +1053,7 @@ def validate_layout(world, player):
start_region = 'Hyrule Castle Ledge' start_region = 'Hyrule Castle Ledge'
explore_region(start_region) explore_region(start_region)
unreachable_regions = {} unreachable_regions = OrderedDict()
unreachable_count = -1 unreachable_count = -1
while unreachable_count != len(unreachable_regions): while unreachable_count != len(unreachable_regions):
# find unreachable regions # find unreachable regions
@@ -1204,6 +1208,7 @@ mandatory_connections = [# Intra-tile OW Connections
('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
('Lake Hylia West Pier', 'Lake Hylia Area'), ('Lake Hylia West Pier', 'Lake Hylia Area'),
('Lake Hylia East Pier', 'Lake Hylia Northeast Bank'), ('Lake Hylia East Pier', 'Lake Hylia Northeast Bank'),
('Lake Hylia Water D Entry', 'Lake Hylia Water'), #flippers
('Desert Pass Ledge Drop', 'Desert Pass Area'), ('Desert Pass Ledge Drop', 'Desert Pass Area'),
('Desert Pass Rocks (North)', 'Desert Pass Southeast'), #glove ('Desert Pass Rocks (North)', 'Desert Pass Southeast'), #glove
('Desert Pass Rocks (South)', 'Desert Pass Area'), #glove ('Desert Pass Rocks (South)', 'Desert Pass Area'), #glove
@@ -1381,8 +1386,6 @@ ow_connections = {
], [ ], [
('Spectacle Rock Leave', 'West Death Mountain (Top)'), ('Spectacle Rock Leave', 'West Death Mountain (Top)'),
('Spectacle Rock Approach', 'Spectacle Rock Ledge'), ('Spectacle Rock Approach', 'Spectacle Rock Ledge'),
('Dark Death Mountain Ladder (North)', 'West Dark Death Mountain (Bottom)'),
('Dark Death Mountain Ladder (South)', 'West Dark Death Mountain (Top)'),
('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'), ('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'),
('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'), ('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'),
('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'), ('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'),
@@ -1403,6 +1406,11 @@ ow_connections = {
('Floating Island Bridge (East)', 'Death Mountain Floating Island'), ('Floating Island Bridge (East)', 'Death Mountain Floating Island'),
('East Death Mountain Mimic Ledge Drop', 'Mimic Cave Ledge'), ('East Death Mountain Mimic Ledge Drop', 'Mimic Cave Ledge'),
('Mimic Ledge Drop', 'East Death Mountain (Bottom)'), ('Mimic Ledge Drop', 'East Death Mountain (Bottom)'),
('Spiral Mimic Bridge (West)', 'Spiral Mimic Ledge Extend'),
('Spiral Mimic Bridge (East)', 'Spiral Mimic Ledge Extend'),
('Spiral Ledge Approach', 'Spiral Cave Ledge'),
('Mimic Ledge Approach', 'Mimic Cave Ledge'),
('Spiral Mimic Ledge Drop', 'Fairy Ascension Ledge'),
('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'), ('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'),
('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'), ('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'),
('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'), ('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'),
@@ -1662,14 +1670,13 @@ ow_connections = {
('Lake Hylia Teleporter', 'Ice Palace Area') ('Lake Hylia Teleporter', 'Ice Palace Area')
], [ ], [
('Lake Hylia Island Pier', 'Lake Hylia Island'), ('Lake Hylia Island Pier', 'Lake Hylia Island'),
('Ice Palace Approach', 'Ice Palace Area'),
('Ice Palace Leave', 'Ice Lake Moat'),
('Ice Lake Mirror Spot', 'Ice Lake Area'), ('Ice Lake Mirror Spot', 'Ice Lake Area'),
('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'), ('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'),
('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'), ('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'),
('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'), ('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'),
('Ice Palace Mirror Spot', 'Ice Palace Area'), ('Ice Palace Mirror Spot', 'Ice Palace Area'),
('Ice Palace Teleporter', 'Lake Hylia Central Island') ('Ice Lake Moat Mirror Spot', 'Ice Lake Moat'),
('Ice Palace Teleporter', 'Lake Hylia Water D')
]), ]),
0x37: ([ 0x37: ([
('Ice Cave Mirror Spot', 'Ice Cave Area') ('Ice Cave Mirror Spot', 'Ice Cave Area')
@@ -1868,10 +1875,10 @@ isolated_regions = [
] ]
flute_data = { flute_data = {
#Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX #Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX AltVRAM AltBGY AltBGX AltCamY AltCamX AltUnk1 AltUnk2 AltIconY AltIconX
0x09: (['Lost Woods East Area', 'Skull Woods Forest'], 0x00, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290), 0x09: (['Lost Woods East Area', 'Skull Woods Forest'], 0x00, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290),
0x02: (['Lumberjack Area', 'Dark Lumberjack Area'], 0x02, 0x059c, 0x00d6, 0x04e6, 0x0138, 0x0558, 0x0143, 0x0563, 0xfffa, 0xfffa, 0x0138, 0x0550), 0x02: (['Lumberjack Area', 'Dark Lumberjack Area'], 0x02, 0x059c, 0x00d6, 0x04e6, 0x0138, 0x0558, 0x0143, 0x0563, 0xfffa, 0xfffa, 0x0138, 0x0550),
0x0b: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], 0x03, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x035b, 0x0680), 0x0b: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Top)'], 0x03, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x035b, 0x0680, 0x0118, 0x0860, 0x05c0, 0x00b8, 0x07ec, 0x0127, 0x086b, 0xfff8, 0x0004, 0x0148, 0x0850),
0x0e: (['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], 0x05, 0x1860, 0x031e, 0x0d00, 0x0388, 0x0da8, 0x038d, 0x0d7d, 0x0000, 0x0000, 0x0388, 0x0da8), 0x0e: (['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], 0x05, 0x1860, 0x031e, 0x0d00, 0x0388, 0x0da8, 0x038d, 0x0d7d, 0x0000, 0x0000, 0x0388, 0x0da8),
0x07: (['Death Mountain TR Pegs', 'Turtle Rock Area'], 0x07, 0x0804, 0x0102, 0x0e1a, 0x0160, 0x0e90, 0x016f, 0x0e97, 0xfffe, 0x0006, 0x0160, 0x0f20), 0x07: (['Death Mountain TR Pegs', 'Turtle Rock Area'], 0x07, 0x0804, 0x0102, 0x0e1a, 0x0160, 0x0e90, 0x016f, 0x0e97, 0xfffe, 0x0006, 0x0160, 0x0f20),
0x0a: (['Mountain Entry Area', 'Bumper Cave Area'], 0x0a, 0x0180, 0x0220, 0x0406, 0x0280, 0x0488, 0x028f, 0x0493, 0x0000, 0xfffa, 0x0280, 0x0488), 0x0a: (['Mountain Entry Area', 'Bumper Cave Area'], 0x0a, 0x0180, 0x0220, 0x0406, 0x0280, 0x0488, 0x028f, 0x0493, 0x0000, 0xfffa, 0x0280, 0x0488),

View File

@@ -15,6 +15,13 @@ CLI: ```--bombbag```
# Bug Fixes and Notes. # Bug Fixes and Notes.
* 0.5.1.7
* Baserom update
* Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion
* Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint if Blind is shuffled to Theives' Town in boss shuffle + crossed mode
* No logic now sets the AllowAccidentalMajorGlitches flag in the rom appropriately
* Houlihan room now exits wherever Link's House is shuffled to
* Rom fixes from Catobat and Codemann8. Thanks!
* 0.5.1.6 * 0.5.1.6
* Rules fixes for TT (Boss and Cell) can now have TT Big Key if not otherwise required (boss shuffle + crossed dungeon) * Rules fixes for TT (Boss and Cell) can now have TT Big Key if not otherwise required (boss shuffle + crossed dungeon)
* BUg fix for money balancing * BUg fix for money balancing

View File

@@ -17,8 +17,9 @@ def create_regions(world, player):
create_lw_region(player, 'West Death Mountain (Bottom)', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), create_lw_region(player, 'West Death Mountain (Bottom)', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']),
create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Dark Death Mountain (Top West) Mirror Spot', 'East Death Mountain WN']), create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Dark Death Mountain (Top West) Mirror Spot', 'East Death Mountain WN']),
create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Dark Death Mountain (Top East) Mirror Spot', 'East Death Mountain EN']), create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Dark Death Mountain (Top East) Mirror Spot', 'East Death Mountain EN']),
create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']),
create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Mimic Cave', 'TR Ledge (East) Mirror Spot']), create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Spiral Mimic Bridge (East)', 'Mimic Cave', 'TR Ledge (East) Mirror Spot']),
create_lw_region(player, 'Spiral Mimic Ledge Extend', None, ['Spiral Ledge Approach', 'Mimic Ledge Approach', 'Spiral Mimic Ledge Drop']),
create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'TR Isolated Mirror Spot']), create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'TR Isolated Mirror Spot']),
create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Rocks (North)', 'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Cave (Bottom)', 'East Dark Death Mountain (Bottom Plateau) Mirror Spot']), create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Rocks (North)', 'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Cave (Bottom)', 'East Dark Death Mountain (Bottom Plateau) Mirror Spot']),
create_lw_region(player, 'East Death Mountain (Bottom Left)', None, ['DM Broken Bridge (West)', 'East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Death Mountain WS']), create_lw_region(player, 'East Death Mountain (Bottom Left)', None, ['DM Broken Bridge (West)', 'East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Death Mountain WS']),
@@ -111,6 +112,7 @@ def create_regions(world, player):
create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Ice Palace Mirror Spot', 'Lake Hylia Teleporter']), create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Ice Palace Mirror Spot', 'Lake Hylia Teleporter']),
create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']), create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']),
create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], Terrain.Water), create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], Terrain.Water),
create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Entry', 'Ice Lake Moat Mirror Spot'], Terrain.Water),
create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']), create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']),
create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']),
create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None), create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None),
@@ -129,9 +131,9 @@ def create_regions(world, player):
create_dw_region(player, 'Skull Woods Forgotten Path (Southwest)', None, ['Skull Woods Forgotten Bush (West)', 'Lost Woods Southwest Mirror Spot', 'Skull Woods SW']), create_dw_region(player, 'Skull Woods Forgotten Path (Southwest)', None, ['Skull Woods Forgotten Bush (West)', 'Lost Woods Southwest Mirror Spot', 'Skull Woods SW']),
create_dw_region(player, 'Skull Woods Forgotten Path (Northeast)', None, ['Skull Woods Forgotten Bush (East)', 'Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods West (Forgotten) Mirror Spot', 'Skull Woods EN']), create_dw_region(player, 'Skull Woods Forgotten Path (Northeast)', None, ['Skull Woods Forgotten Bush (East)', 'Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods West (Forgotten) Mirror Spot', 'Skull Woods EN']),
create_dw_region(player, 'Dark Lumberjack Area', None, ['Dark World Lumberjack Shop', 'Lumberjack Mirror Spot', 'Dark Lumberjack WN', 'Dark Lumberjack SW']), create_dw_region(player, 'Dark Lumberjack Area', None, ['Dark World Lumberjack Shop', 'Lumberjack Mirror Spot', 'Dark Lumberjack WN', 'Dark Lumberjack SW']),
create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'Dark Death Mountain Ladder (North)', 'West Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain EN']), create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'West Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain EN']),
create_dw_region(player, 'GT Approach', None, ['GT Entry Leave', 'Ganons Tower']), create_dw_region(player, 'GT Approach', None, ['GT Entry Leave', 'Ganons Tower']),
create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Dark Death Mountain Ladder (South)', 'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Spectacle Rock Mirror Spot', 'West Dark Death Mountain ES']), create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Spectacle Rock Mirror Spot', 'West Dark Death Mountain ES']),
create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']), create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']),
create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)', 'Fairy Ascension Mirror Spot']), create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)', 'Fairy Ascension Mirror Spot']),
create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['Death Mountain Bridge Mirror Spot', 'East Dark Death Mountain WS']), create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['Death Mountain Bridge Mirror Spot', 'East Dark Death Mountain WS']),
@@ -211,8 +213,8 @@ def create_regions(world, player):
create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']), create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']),
create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']), create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']),
create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], Terrain.Water), create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], Terrain.Water),
create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Ice Palace Approach', 'Lake Hylia Water Mirror Spot']), create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Lake Hylia Water Mirror Spot']),
create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace Leave', 'Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']), create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']),
create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']), create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']),
create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']), create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']),
create_dw_region(player, 'Swamp Area', None, ['Swamp Palace', 'Dam Mirror Spot', 'Swamp WC', 'Swamp WS', 'Swamp NC', 'Swamp EC']), create_dw_region(player, 'Swamp Area', None, ['Swamp Palace', 'Dam Mirror Spot', 'Swamp WC', 'Swamp WS', 'Swamp NC', 'Swamp EC']),
@@ -326,7 +328,7 @@ def create_regions(world, player):
create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']),
create_cave_region(player, 'Archery Game', 'a game of skill'), create_cave_region(player, 'Archery Game', 'a game of skill'),
create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'), create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'),
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb']), create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb'], ['Big Bomb Shop Exit']),
create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'East Dark World Hint', 'a storyteller'), create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
@@ -1125,8 +1127,8 @@ def create_shops(world, player):
if (0x35 not in world.owswaps[player][0] and region_name == 'Dark Lake Hylia Shop') \ if (0x35 not in world.owswaps[player][0] and region_name == 'Dark Lake Hylia Shop') \
or (0x35 in world.owswaps[player][0] and region_name == 'Cave Shop (Lake Hylia)'): or (0x35 in world.owswaps[player][0] and region_name == 'Cave Shop (Lake Hylia)'):
locked = True locked = True
custom = True
inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)] inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
custom = True
region = world.get_region(region_name, player) region = world.get_region(region_name, player)
shop = Shop(region, room_id, type, shopkeeper, custom, locked, sram) shop = Shop(region, room_id, type, shopkeeper, custom, locked, sram)
region.shop = shop region.shop = shop

151
Rom.py
View File

@@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'c1a00c60144c6cc5a6ef5f00617a9b38' RANDOMIZERBASEHASH = 'b300438a7242825e33300f9d155814ef'
class JsonRom(object): class JsonRom(object):
@@ -334,6 +334,7 @@ def patch_enemizer(world, player, rom, local_rom, enemizercli, random_sprite_on_
rom.write_bytes(0xEA081, [0x5c, 0x00, 0x80, 0xb7, 0xc9, 0x6, 0xf0, 0x24, rom.write_bytes(0xEA081, [0x5c, 0x00, 0x80, 0xb7, 0xc9, 0x6, 0xf0, 0x24,
0xad, 0x3, 0x4, 0x29, 0x20, 0xf0, 0x1d]) 0xad, 0x3, 0x4, 0x29, 0x20, 0xf0, 0x1d])
rom.write_byte(0x200101, 0) # Do not close boss room door on entry. rom.write_byte(0x200101, 0) # Do not close boss room door on entry.
rom.write_byte(0x1B0101, 0) # Do not close boss room door on entry. (for Ijwu's enemizer)
if random_sprite_on_hit: if random_sprite_on_hit:
_populate_sprite_table() _populate_sprite_table()
@@ -628,21 +629,33 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
offset = 0x40 offset = 0x40
write_int16(rom, snes_to_pc(0x02E849 + (o * 2)), data[1] + offset) # owid write_int16(rom, snes_to_pc(0x02E849 + (o * 2)), data[1] + offset) # owid
write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[2]) #vram
write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[3]) # BG scroll Y
write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[4]) # BG scroll X
write_int16(rom, snes_to_pc(0x02E8D1 + (o * 2)), data[13] if offset > 0 and len(data) > 13 else data[5]) # link Y write_int16(rom, snes_to_pc(0x02E8D1 + (o * 2)), data[13] if offset > 0 and len(data) > 13 else data[5]) # link Y
write_int16(rom, snes_to_pc(0x02E8F3 + (o * 2)), data[14] if offset > 0 and len(data) > 13 else data[6]) # link X write_int16(rom, snes_to_pc(0x02E8F3 + (o * 2)), data[14] if offset > 0 and len(data) > 13 else data[6]) # link X
write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[7]) # cam Y
write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[8]) # cam X if offset == 0 or len(data) <= 15:
write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[9]) # unknown 1 write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[2]) # vram
write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[10]) # unknown 2 write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[3]) # BG scroll Y
write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[4]) # BG scroll X
# flute menu blips write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[7]) # cam Y
rom.write_byte(snes_to_pc(0x0AB783 + o), data[12] & 0xff) # X low byte write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[8]) # cam X
rom.write_byte(snes_to_pc(0x0AB78B + o), data[12] // 0x100) # X high byte write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[9]) # unknown 1
rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # Y low byte write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[10]) # unknown 2
rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # Y high byte rom.write_byte(snes_to_pc(0x0AB783 + o), data[12] & 0xff) # flute menu blip - X low byte
rom.write_byte(snes_to_pc(0x0AB78B + o), data[12] // 0x100) # flute menu blip - X high byte
rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # flute menu blip - Y low byte
rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # flute menu blip - Y high byte
else: # use alternate flute data
write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[15]) # vram
write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[16]) # BG scroll Y
write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[17]) # BG scroll X
write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[18]) # cam Y
write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[19]) # cam X
write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[20]) # unknown 1
write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[21]) # unknown 2
rom.write_byte(snes_to_pc(0x0AB783 + o), data[23] & 0xff) # flute menu blip - X low byte
rom.write_byte(snes_to_pc(0x0AB78B + o), data[23] // 0x100) # flute menu blip - X high byte
rom.write_byte(snes_to_pc(0x0AB793 + o), data[22] & 0xff) # flute menu blip - Y low byte
rom.write_byte(snes_to_pc(0x0AB79B + o), data[22] // 0x100) # flute menu blip - Y high byte
# patch whirlpools # patch whirlpools
if world.owWhirlpoolShuffle[player]: if world.owWhirlpoolShuffle[player]:
@@ -799,10 +812,13 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
if should_be_bunny(sanc_region, world.mode[player]): if should_be_bunny(sanc_region, world.mode[player]):
rom.write_bytes(0x13fff2, [0x12, 0x00]) rom.write_bytes(0x13fff2, [0x12, 0x00])
lh_name = 'Links House' if not world.is_bombshop_start(player):
lh_name = 'Links House'
else:
lh_name = 'Big Bomb Shop'
links_house = world.get_region(lh_name, player) links_house = world.get_region(lh_name, player)
if should_be_bunny(links_house, world.mode[player]): if should_be_bunny(links_house, world.mode[player]):
rom.write_bytes(0x13fff0, [0x04, 0x01]) rom.write_bytes(0x13fff0, [0x04 if lh_name == 'Links House' else 0x1C, 0x01])
old_man_house = world.get_region('Old Man House', player) old_man_house = world.get_region('Old Man House', player)
if should_be_bunny(old_man_house, world.mode[player]): if should_be_bunny(old_man_house, world.mode[player]):
@@ -1248,6 +1264,13 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
gametype |= 0x01 # enemizer gametype |= 0x01 # enemizer
rom.write_byte(0x180211, gametype) # Game type rom.write_byte(0x180211, gametype) # Game type
warningflags = 0x00 # none
if world.logic[player] in ['owglitches', 'nologic']:
warningflags |= 0x20
if world.logic[player] in ['minorglitches', 'owglitches', 'nologic']:
warningflags |= 0x40
rom.write_byte(0x180212, warningflags) # Warning flags
# assorted fixes # assorted fixes
rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1 rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1
rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence. rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence.
@@ -1271,6 +1294,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x180174, 0x01 if world.fix_fake_world[player] else 0x00) rom.write_byte(0x180174, 0x01 if world.fix_fake_world[player] else 0x00)
rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles
# starting overworld flags
assert len(world.initial_overworld_flags[player]) == 0x80 and all([i < 0x100 for i in world.initial_overworld_flags[player]])
rom.write_bytes(0x183280, world.initial_overworld_flags[player])
# Starting equipment # Starting equipment
if world.pseudoboots[player]: if world.pseudoboots[player]:
rom.write_byte(0x18008E, 0x01) rom.write_byte(0x18008E, 0x01)
@@ -1427,9 +1454,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x180043, equip[0x359]) rom.write_byte(0x180043, equip[0x359])
assert equip[:0x340] == [0] * 0x340 assert equip[:0x340] == [0] * 0x340
rom.write_bytes(0x183000, equip[0x340:]) rom.write_bytes(0x183340, equip[0x340:])
rom.write_bytes(0x271A6, equip[0x340:0x340+60]) rom.write_bytes(0x271A6, equip[0x340:0x340+60])
rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode
rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier
rom.write_byte(0x03A943, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both) rom.write_byte(0x03A943, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both)
@@ -1550,6 +1577,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills
rom.write_byte(0x1800A4, 0x01 if world.logic[player] != 'nologic' else 0x00) # enable POD EG fix rom.write_byte(0x1800A4, 0x01 if world.logic[player] != 'nologic' else 0x00) # enable POD EG fix
rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill
rom.write_byte(0x180358, 0x01 if world.logic[player] == 'nologic' else 0x00)
# remove shield from uncle # remove shield from uncle
rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E]) rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E])
@@ -2186,14 +2214,10 @@ def write_strings(rom, world, player, team):
elif world.shopsanity[player]: elif world.shopsanity[player]:
entrances_to_hint.update(ShopEntrances) entrances_to_hint.update(ShopEntrances)
if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
if world.is_tile_swapped(0x2c, player): if not world.is_bombshop_start(player):
entrances_to_hint.update({'Links House': 'The hero\'s old residence'})
if world.shufflelinks[player]:
entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'})
else:
entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'})
if world.shufflelinks[player]: else:
entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) entrances_to_hint.update({'Links House': 'The hero\'s old residence'})
entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'})
if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']: if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']:
entrances_to_hint.update(InsanityEntrances) entrances_to_hint.update(InsanityEntrances)
@@ -2269,13 +2293,18 @@ def write_strings(rom, world, player, team):
# Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well. # Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well.
items_to_hint = RelevantItems.copy() items_to_hint = RelevantItems.copy()
flute_item = 'Ocarina'
if world.is_tile_swapped(0x18, player):
items_to_hint.remove(flute_item)
flute_item = 'Ocarina (Activated)'
items_to_hint.append(flute_item)
if world.owShuffle[player] != 'vanilla' or world.owMixed[player]: if world.owShuffle[player] != 'vanilla' or world.owMixed[player]:
# Adding a guaranteed hint for the Flute in overworld shuffle. # Adding a guaranteed hint for the Flute in overworld shuffle.
this_location = world.find_items_not_key_only('Ocarina', player) this_location = world.find_items_not_key_only(flute_item, player)
if this_location: if this_location:
this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.'
tt[hint_locations.pop(0)] = this_hint tt[hint_locations.pop(0)] = this_hint
items_to_hint.remove('Ocarina') items_to_hint.remove(flute_item)
if world.keyshuffle[player]: if world.keyshuffle[player]:
items_to_hint.extend(SmallKeys) items_to_hint.extend(SmallKeys)
if world.bigkeyshuffle[player]: if world.bigkeyshuffle[player]:
@@ -2499,30 +2528,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) write_int16(rom, 0x15AEE + 2*0x38, 0x00E0)
write_int16(rom, 0x15AEE + 2*0x25, 0x000C) write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
if world.is_tile_swapped(0x03, player):
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \
or (world.shuffle[player] == 'simple' and world.is_tile_swapped(0x05, player)):
rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW
write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave
rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03])
write_int16(rom, snes_to_pc(0x02D924), 0x0300)
write_int16(rom, snes_to_pc(0x02D932), 0x1F10)
write_int16(rom, snes_to_pc(0x02D940), 0x1FC0)
write_int16(rom, snes_to_pc(0x02D94E), 0x0378)
write_int16(rom, snes_to_pc(0x02D95C), 0x0187)
write_int16(rom, snes_to_pc(0x02D96A), 0x017F)
rom.write_byte(snes_to_pc(0x02D972), 0x06)
rom.write_byte(snes_to_pc(0x02D979), 0x00)
rom.write_byte(snes_to_pc(0x02D980), 0xFF)
rom.write_byte(snes_to_pc(0x02D987), 0x00)
rom.write_byte(snes_to_pc(0x02D98E), 0x22)
rom.write_byte(snes_to_pc(0x02D995), 0x12)
write_int16(rom, snes_to_pc(0x02D9A2), 0x0000)
write_int16(rom, snes_to_pc(0x02D9B0), 0x0007)
rom.write_byte(snes_to_pc(0x02D9B8), 0x12)
rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) # indicates the overworld door being used for the single entrance spawn point
if world.is_tile_swapped(0x05, player): if world.is_tile_swapped(0x05, player):
rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock
rom.write_byte(snes_to_pc(0x1BC428), 0x00) # remove secret portal rom.write_byte(snes_to_pc(0x1BC428), 0x00) # remove secret portal
@@ -2531,6 +2537,8 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks
rom.write_byte(0x180089, 0x01) # open TR after exit rom.write_byte(0x180089, 0x01) # open TR after exit
rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail
rom.write_bytes(snes_to_pc(0x04E7A3), [0x20, 0x06]) # Top peg moved down, for peg puzzle
rom.write_byte(snes_to_pc(0x04E7E4), 0x10) # Remove TR portal overlay
if world.shuffle[player] in ['vanilla']: if world.shuffle[player] in ['vanilla']:
world.fix_trock_doors[player] = True world.fix_trock_doors[player] = True
if world.is_tile_swapped(0x10, player): if world.is_tile_swapped(0x10, player):
@@ -2644,10 +2652,25 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
if world.is_tile_swapped(0x29, player): if world.is_tile_swapped(0x29, player):
rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact
if world.is_tile_swapped(0x2c, player): if world.is_tile_swapped(0x2c, player):
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.is_bombshop_start(player):
rom.write_byte(0x15B8C, 0x6C) # exit links at bomb shop area rom.write_bytes(snes_to_pc(0x03F484), [0xFD, 0x4B, 0x68]) # place bed in bomb shop
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
rom.write_byte(0xDBB73 + 0x52, 0x01) # spawn in bomb shop
patch_shuffled_bomb_shop(world, rom, player)
rom.write_byte(snes_to_pc(0x02D8D2), 0x1C)
rom.write_bytes(snes_to_pc(0x02D8E0), [0x23, 0x22, 0x23, 0x23, 0x18, 0x18, 0x18, 0x19])
rom.write_byte(snes_to_pc(0x02D919), 0x18)
rom.write_byte(snes_to_pc(0x02D927), 0x23)
write_int16(rom, snes_to_pc(0x02D934), 0x2398)
rom.write_byte(snes_to_pc(0x02D943), 0x18)
write_int16(rom, snes_to_pc(0x02D950), 0x0087)
write_int16(rom, snes_to_pc(0x02D95E), 0x0081)
rom.write_byte(snes_to_pc(0x02D9A4), 0x53)
# disable custom exit on links house exit
rom.write_byte(snes_to_pc(0x02E225), 0x1C)
rom.write_byte(snes_to_pc(0x02DAEE), 0x1C)
rom.write_byte(snes_to_pc(0x02DB8C), 0x6C)
if world.is_tile_swapped(0x2f, player): if world.is_tile_swapped(0x2f, player):
rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock
rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal
@@ -2659,7 +2682,8 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock
rom.write_byte(snes_to_pc(0x1BC5B1), 0x00) # remove secret portal rom.write_byte(snes_to_pc(0x1BC5B1), 0x00) # remove secret portal
if world.is_tile_swapped(0x35, player): if world.is_tile_swapped(0x35, player):
rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock #rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock
rom.write_bytes(snes_to_pc(0x1BC85A), [0x52, 0x13, 0x82]) # add warp under rock
rom.write_byte(snes_to_pc(0x1BC5C7), 0x00) # remove secret portal rom.write_byte(snes_to_pc(0x1BC5C7), 0x00) # remove secret portal
# apply inverted map changes # apply inverted map changes
@@ -2671,6 +2695,7 @@ def patch_shuffled_dark_sanc(world, rom, player):
dark_sanc_entrance = str([i for i in dark_sanc.entrances if i.parent_region.name != 'Menu'][0].name) dark_sanc_entrance = str([i for i in dark_sanc.entrances if i.parent_region.name != 'Menu'][0].name)
room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[dark_sanc_entrance][1] room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[dark_sanc_entrance][1]
door_index = door_addresses[str(dark_sanc_entrance)][0] door_index = door_addresses[str(dark_sanc_entrance)][0]
world.initial_overworld_flags[player][ow_area] |= door_addresses[dark_sanc_entrance][2]
rom.write_byte(0x180241, 0x01) rom.write_byte(0x180241, 0x01)
rom.write_byte(0x180248, door_index + 1) rom.write_byte(0x180248, door_index + 1)
@@ -2680,6 +2705,22 @@ def patch_shuffled_dark_sanc(world, rom, player):
rom.write_bytes(0x180262, [unknown_1, unknown_2, 0x00]) rom.write_bytes(0x180262, [unknown_1, unknown_2, 0x00])
def patch_shuffled_bomb_shop(world, rom, player):
bomb_shop = world.get_region('Big Bomb Shop', player)
bomb_shop_entrance = str([i for i in bomb_shop.entrances if i.parent_region.name != 'Menu'][0].name)
room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[bomb_shop_entrance][1]
door_index = door_addresses[str(bomb_shop_entrance)][0]
world.initial_overworld_flags[player][ow_area] |= door_addresses[bomb_shop_entrance][2]
rom.write_byte(0x180240, 0x02)
rom.write_byte(0x180247, door_index + 1)
write_int16(rom, 0x180264, room_id)
rom.write_byte(0x180266, ow_area)
write_int16s(rom, 0x180267, [vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x])
rom.write_bytes(0x180275, [unknown_1, unknown_2, 0x00])
write_int16(rom, snes_to_pc(0x02D996), door_1)
def update_compasses(rom, world, player): def update_compasses(rom, world, player):
layouts = world.dungeon_layouts[player] layouts = world.dungeon_layouts[player]
provided_dungeon = False provided_dungeon = False

View File

@@ -825,6 +825,7 @@ def default_rules(world, player):
set_rule(world.get_entrance('Lake Hylia Northeast Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Lake Hylia Northeast Water Drop', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Lake Hylia Central Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Lake Hylia Central Water Drop', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Lake Hylia Island Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Lake Hylia Island Water Drop', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Lake Hylia Water D Entry', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Ice Cave SW', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Ice Cave SW', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Octoballoon Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Octoballoon Water Drop', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Octoballoon Waterfall Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Octoballoon Waterfall Water Drop', player), lambda state: state.has('Flippers', player))
@@ -887,6 +888,8 @@ def ow_rules(world, player):
set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Spectacle Rock Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player))
set_rule(world.get_entrance('Spectacle Rock Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player))
if not world.is_tile_swapped(0x05, player): if not world.is_tile_swapped(0x05, player):
set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -916,7 +919,10 @@ def ow_rules(world, player):
else: else:
set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
set_rule(world.get_entrance('TR Pegs Ledge Drop', player), lambda state: False)
set_rule(world.get_entrance('TR Pegs Ledge Leave', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player))
set_rule(world.get_entrance('Turtle Rock Tail Ledge Drop', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
if not world.is_tile_swapped(0x0a, player): if not world.is_tile_swapped(0x0a, player):
set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -965,8 +971,8 @@ def ow_rules(world, player):
set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player))
set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player))
else: else:
set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: state.has_Pearl(player)) set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player))
set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: state.has_Pearl(player)) set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player))
set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -1126,6 +1132,8 @@ def ow_rules(world, player):
set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
set_rule(world.get_entrance('Checkerboard Ledge Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
set_rule(world.get_entrance('Checkerboard Ledge Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
if not world.is_tile_swapped(0x32, player): if not world.is_tile_swapped(0x32, player):
set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -1133,6 +1141,8 @@ def ow_rules(world, player):
else: else:
set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Cave 45 Inverted Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
set_rule(world.get_entrance('Cave 45 Inverted Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
if not world.is_tile_swapped(0x33, player): if not world.is_tile_swapped(0x33, player):
set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -1166,6 +1176,7 @@ def ow_rules(world, player):
set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
if not world.is_tile_swapped(0x37, player): if not world.is_tile_swapped(0x37, player):
set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player))
@@ -1179,6 +1190,8 @@ def ow_rules(world, player):
set_rule(world.get_entrance('Swamp Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Swamp Nook Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player))
set_rule(world.get_entrance('Desert Pass Ladder (South)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
set_rule(world.get_entrance('Desert Pass Ladder (North)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'])
if not world.is_tile_swapped(0x3b, player): if not world.is_tile_swapped(0x3b, player):
set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player))

View File

@@ -76,6 +76,9 @@ nop : jsl OverridePaletteHeader
org $02817e ; Bank02.asm : 414 (LDA $02811E, X) org $02817e ; Bank02.asm : 414 (LDA $02811E, X)
jsl FixAnimatedTiles jsl FixAnimatedTiles
org $0aef43 ; UnderworldMap_RecoverGFX
jsl FixCloseDungeonMap
org $028a06 ; Bank02.asm : 1941 Dungeon_ResetTorchBackgroundAndPlayer org $028a06 ; Bank02.asm : 1941 Dungeon_ResetTorchBackgroundAndPlayer
JSL FixWallmasterLamp JSL FixWallmasterLamp
@@ -186,9 +189,9 @@ Main_ShowTextMessage:
; Conditionally disable UW music changes in Door Rando ; Conditionally disable UW music changes in Door Rando
org $028ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...) org $028ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...)
JSL.l Underworld_DoorDown_Entry : CPX #$10 JSL.l Underworld_DoorDown_Entry : CPX #$FF
db $B0, $21 ; BCS $028B04 BEQ + : db $80, $1C ; BRA $028B04
BRA + : NOP #6 : + NOP #6 : +
org $02C3F2 ; <- Bank02.asm:10521 Unused call org $02C3F2 ; <- Bank02.asm:10521 Unused call
Underworld_DoorDown_Call: Underworld_DoorDown_Call:

View File

@@ -45,6 +45,16 @@ FixAnimatedTiles:
+ LDA $02802E, X ; what we wrote over + LDA $02802E, X ; what we wrote over
RTL RTL
FixCloseDungeonMap:
LDA.l DRMode : CMP #$02 : BNE .vanilla
LDA $040C : BMI .vanilla
LSR : TAX
LDA.l DungeonTilesets,x
RTL
.vanilla
LDA $7EC20E
RTL
FixWallmasterLamp: FixWallmasterLamp:
ORA $0458 ORA $0458
STY $1C : STA $1D : RTL ; what we wrote over STY $1C : STA $1D : RTL ; what we wrote over

Binary file not shown.