Mixed caves and various fixes merge

Mixed caves and other fixes merge
This commit is contained in:
AmazingAmpharos 2018-02-08 04:34:02 -06:00 committed by GitHub
commit 57cc94501f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1113 additions and 578 deletions

View File

@ -1,4 +1,5 @@
import copy import copy
from enum import Enum, unique
import logging import logging
import json import json
from collections import OrderedDict from collections import OrderedDict
@ -251,19 +252,31 @@ class World(object):
@property @property
def option_identifier(self): def option_identifier(self):
logic = 0 if self.logic == 'noglitches' else 1 id_value = 0
mode = ['standard', 'open', 'swordless'].index(self.mode) id_value_max = 1
dungeonitems = 0 if self.place_dungeon_items else 1
goal = ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'].index(self.goal) def markbool(value):
shuffle = ['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'].index(self.shuffle) nonlocal id_value, id_value_max
difficulty = ['easy', 'normal', 'hard', 'expert', 'insane'].index(self.difficulty) id_value += id_value_max * bool(value)
timer = ['none', 'display', 'timed', 'timed-ohko', 'timed-countdown', 'ohko'].index(self.timer) id_value_max *= 2
progressive = ['on', 'off', 'random'].index(self.progressive) def marksequence(options, value):
algorithm = ['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'].index(self.algorithm) nonlocal id_value, id_value_max
beatableonly = 1 if self.check_beatable_only else 0 id_value += id_value_max * options.index(value)
shuffleganon = 1 if self.shuffle_ganon else 0 id_value_max *= len(options)
keysanity = 1 if self.keysanity else 0 markbool(self.logic == 'noglitches')
return logic | (beatableonly << 1) | (dungeonitems << 2) | (shuffleganon << 3) | (goal << 4) | (shuffle << 7) | (difficulty << 11) | (algorithm << 13) | (mode << 16) | (keysanity << 18) | (timer << 19) | (progressive << 21) marksequence(['standard', 'open', 'swordless'], self.mode)
markbool(self.place_dungeon_items)
marksequence(['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'], self.goal)
marksequence(['vanilla', 'simple', 'restricted', 'full', 'full_cross_worlds','full_legacy', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'], self.shuffle)
marksequence(['easy', 'normal', 'hard', 'expert', 'insane'], self.difficulty)
marksequence(['none', 'display', 'timed', 'timed-ohko', 'timed-countdown', 'ohko'], self.timer)
marksequence(['on', 'off', 'random'], self.progressive)
marksequence(['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'], self.algorithm)
markbool(self.check_beatable_only)
markbool(self.shuffle_ganon)
markbool(self.keysanity)
assert id_value_max <= 0xFFFFFFFF
return id_value
class CollectionState(object): class CollectionState(object):
@ -536,17 +549,32 @@ class CollectionState(object):
raise RuntimeError('Cannot parse %s.' % item) raise RuntimeError('Cannot parse %s.' % item)
@unique
class RegionType(Enum):
LightWorld = 1
DarkWorld = 2
Cave = 3 # Also includes Houses
Dungeon = 4
@property
def is_indoors(self):
"""Shorthand for checking if Cave or Dungeon"""
return self in (RegionType.Cave, RegionType.Dungeon)
class Region(object): class Region(object):
def __init__(self, name): def __init__(self, name, type):
self.name = name self.name = name
self.type = type
self.entrances = [] self.entrances = []
self.exits = [] self.exits = []
self.locations = [] self.locations = []
self.dungeon = None self.dungeon = None
self.world = None self.world = None
self.is_light_world = False # will be set aftermaking connections. self.is_light_world = False # will be set aftermaking connections.
self.is_dark_world = False
self.spot_type = 'Region' self.spot_type = 'Region'
self.hint_text = 'Hyrule' self.hint_text = 'Hyrule'
self.recursion_count = 0 self.recursion_count = 0

View File

@ -12,7 +12,7 @@ def create_dungeons(world):
world.get_region(region).dungeon = dungeon world.get_region(region).dungeon = dungeon
return dungeon return dungeon
ES = make_dungeon('Hyrule Castle', ['Hyrule Castle', 'Sewers', 'Sewers (Dark)', 'Sanctuary'], None, [ItemFactory('Small Key (Escape)')], [ItemFactory('Map (Escape)')]) ES = make_dungeon('Hyrule Castle', ['Hyrule Castle', 'Sewers', 'Sewer Drop', 'Sewers (Dark)', 'Sanctuary'], None, [ItemFactory('Small Key (Escape)')], [ItemFactory('Map (Escape)')])
EP = make_dungeon('Eastern Palace', ['Eastern Palace'], ItemFactory('Big Key (Eastern Palace)'), [], ItemFactory(['Map (Eastern Palace)', 'Compass (Eastern Palace)'])) EP = make_dungeon('Eastern Palace', ['Eastern Palace'], ItemFactory('Big Key (Eastern Palace)'), [], ItemFactory(['Map (Eastern Palace)', 'Compass (Eastern Palace)']))
DP = make_dungeon('Desert Palace', ['Desert Palace North', 'Desert Palace Main', 'Desert Palace East'], ItemFactory('Big Key (Desert Palace)'), [ItemFactory('Small Key (Desert Palace)')], ItemFactory(['Map (Desert Palace)', 'Compass (Desert Palace)'])) DP = make_dungeon('Desert Palace', ['Desert Palace North', 'Desert Palace Main', 'Desert Palace East'], ItemFactory('Big Key (Desert Palace)'), [ItemFactory('Small Key (Desert Palace)')], ItemFactory(['Map (Desert Palace)', 'Compass (Desert Palace)']))
ToH = make_dungeon('Tower of Hera', ['Tower of Hera (Bottom)', 'Tower of Hera (Basement)', 'Tower of Hera (Top)'], ItemFactory('Big Key (Tower of Hera)'), [ItemFactory('Small Key (Tower of Hera)')], ItemFactory(['Map (Tower of Hera)', 'Compass (Tower of Hera)'])) ToH = make_dungeon('Tower of Hera', ['Tower of Hera (Bottom)', 'Tower of Hera (Basement)', 'Tower of Hera (Top)'], ItemFactory('Big Key (Tower of Hera)'), [ItemFactory('Small Key (Tower of Hera)')], ItemFactory(['Map (Tower of Hera)', 'Compass (Tower of Hera)']))

View File

@ -120,7 +120,7 @@ def start():
slightly biased to placing progression items with slightly biased to placing progression items with
less restrictions. less restrictions.
''') ''')
parser.add_argument('--shuffle', default='full', const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'], parser.add_argument('--shuffle', default='full', const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full','full_cross_worlds','full_legacy', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'],
help='''\ help='''\
Select Entrance Shuffling Algorithm. (default: %(default)s) Select Entrance Shuffling Algorithm. (default: %(default)s)
Full: Mix cave and dungeon entrances freely. Full: Mix cave and dungeon entrances freely.

View File

@ -125,6 +125,10 @@ def link_entrances(world):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets) connect_doors(world, single_doors, door_targets)
elif world.shuffle == 'new_restricted':
# TODO
raise NotImplementedError()
# TODO: decide if we need a new restricted cross_worlds mode
elif world.shuffle == 'restricted': elif world.shuffle == 'restricted':
simple_shuffle_dungeons(world) simple_shuffle_dungeons(world)
@ -184,11 +188,180 @@ def link_entrances(world):
elif world.shuffle == 'full': elif world.shuffle == 'full':
skull_woods_shuffle(world) skull_woods_shuffle(world)
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances)
dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors)
dw_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit)
lw_must_exits = list(LW_Dungeon_Entrances_Must_Exit)
old_man_entrances = list(Old_Man_Entrances + ['Tower of Hera'])
caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues
bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors + Bomb_Shop_Multi_Cave_Doors)
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
door_targets = list(Single_Cave_Targets)
# tavern back door cannot be shuffled yet
connect_doors(world, ['Tavern North'], ['Tavern'])
if world.mode == 'standard':
# must connect front of hyrule castle to do escape
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)')
else:
caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
lw_entrances.append('Hyrule Castle Entrance (South)')
if not world.shuffle_ganon:
connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit')
else:
dw_entrances.append('Ganons Tower')
caves.append('Ganons Tower Exit')
# we randomize which world requirements we fulfill first so we get better dungeon distribution
if random.randint(0, 1) == 0:
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits)
connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits)
else:
connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits)
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits)
if world.mode == 'standard':
# rest of hyrule castle must be in light world to avoid fake darkworld stuff
connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')])
connect_caves(world, lw_entrances, [], list(LW_Dungeon_Exits)) # Agahnim must be light world
# place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [door for door in old_man_entrances if door in lw_entrances]
random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop()
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)')
lw_entrances.remove(old_man_exit)
# place blacksmith, has limited options
all_entrances = lw_entrances + dw_entrances
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances]
random.shuffle(blacksmith_doors)
blacksmith_hut = blacksmith_doors.pop()
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut')
if blacksmith_hut in lw_entrances:
lw_entrances.remove(blacksmith_hut)
if blacksmith_hut in dw_entrances:
dw_entrances.remove(blacksmith_hut)
bomb_shop_doors.extend(blacksmith_doors)
# place dam and pyramid fairy, have limited options
all_entrances = lw_entrances + dw_entrances
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances]
random.shuffle(bomb_shop_doors)
bomb_shop = bomb_shop_doors.pop()
connect_entrance(world, bomb_shop, 'Big Bomb Shop')
if bomb_shop in lw_entrances:
lw_entrances.remove(bomb_shop)
if bomb_shop in dw_entrances:
dw_entrances.remove(bomb_shop)
# place the old man cave's entrance somewhere in the light world
random.shuffle(lw_entrances)
old_man_entrance = lw_entrances.pop()
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)')
# place Old Man House in Light World, so using the s&q point does not cause fake dark world
connect_caves(world, lw_entrances, [], [('Old Man House Exit (Bottom)', 'Old Man House Exit (Top)')])
# now scramble the rest
connect_caves(world, lw_entrances, dw_entrances, caves)
# scramble holes
scramble_holes(world)
doors = lw_entrances + dw_entrances
# place remaining doors
connect_doors(world, doors, door_targets)
elif world.shuffle == 'full_cross_worlds':
skull_woods_shuffle(world)
entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances + DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors)
must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit)
old_man_entrances = list(Old_Man_Entrances + ['Tower of Hera'])
caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues
bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors + Bomb_Shop_Multi_Cave_Doors)
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
door_targets = list(Single_Cave_Targets)
# tavern back door cannot be shuffled yet
connect_doors(world, ['Tavern North'], ['Tavern'])
if world.mode == 'standard':
# must connect front of hyrule castle to do escape
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)')
else:
caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
entrances.append('Hyrule Castle Entrance (South)')
if not world.shuffle_ganon:
connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit')
else:
entrances.append('Ganons Tower')
caves.append('Ganons Tower Exit')
connect_mandatory_exits(world, entrances, caves, must_exits)
if world.mode == 'standard':
# rest of hyrule castle must be in light world to avoid fake darkworld stuff
connect_caves(world, entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')])
# place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [door for door in old_man_entrances if door in entrances]
random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop()
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)')
entrances.remove(old_man_exit)
# place blacksmith, has limited options
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
blacksmith_doors = [door for door in blacksmith_doors if door in entrances]
random.shuffle(blacksmith_doors)
blacksmith_hut = blacksmith_doors.pop()
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut')
entrances.remove(blacksmith_hut)
bomb_shop_doors.extend(blacksmith_doors)
# place dam and pyramid fairy, have limited options
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
bomb_shop_doors = [door for door in bomb_shop_doors if door in entrances]
random.shuffle(bomb_shop_doors)
bomb_shop = bomb_shop_doors.pop()
connect_entrance(world, bomb_shop, 'Big Bomb Shop')
entrances.remove(bomb_shop)
# place the old man cave's entrance somewhere in the light world
random.shuffle(entrances)
old_man_entrance = entrances.pop()
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)')
# place Old Man House in Light World, so using the s&q point does not cause fake dark world
connect_caves(world, entrances, [], [('Old Man House Exit (Bottom)', 'Old Man House Exit (Top)')])
# now scramble the rest
connect_caves(world, entrances, [], caves)
# scramble holes
scramble_holes(world)
# place remaining doors
connect_doors(world, entrances, door_targets)
elif world.shuffle == 'full_legacy':
skull_woods_shuffle(world)
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances)
dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances) dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances)
dw_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) dw_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit)
lw_must_exits = list(LW_Dungeon_Entrances_Must_Exit) lw_must_exits = list(LW_Dungeon_Entrances_Must_Exit)
old_man_entrances = list(Old_Man_Entrances) old_man_entrances = list(Old_Man_Entrances + ['Tower of Hera'])
caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues
single_doors = list(Single_Cave_Doors) single_doors = list(Single_Cave_Doors)
bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors)
@ -222,9 +395,11 @@ def link_entrances(world):
# place old man, has limited options # place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about # exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [door for door in old_man_entrances if door in lw_entrances]
random.shuffle(old_man_entrances) random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop() old_man_exit = old_man_entrances.pop()
lw_entrances.extend(old_man_entrances) lw_entrances.remove(old_man_exit)
random.shuffle(lw_entrances) random.shuffle(lw_entrances)
old_man_entrance = lw_entrances.pop() old_man_entrance = lw_entrances.pop()
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)') connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)')
@ -259,7 +434,7 @@ def link_entrances(world):
elif world.shuffle == 'madness': elif world.shuffle == 'madness':
# here lie dragons, connections are no longer two way # here lie dragons, connections are no longer two way
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances)
dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances) dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances)
dw_entrances_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) dw_entrances_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit)
@ -277,7 +452,8 @@ def link_entrances(world):
lw_entrances.extend(['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)']) lw_entrances.extend(['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'])
lw_entrances_must_exits = list(LW_Dungeon_Entrances_Must_Exit) lw_entrances_must_exits = list(LW_Dungeon_Entrances_Must_Exit)
old_man_entrances = list(Old_Man_Entrances)
old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera']
mandatory_light_world = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'] mandatory_light_world = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)']
mandatory_dark_world = [] mandatory_dark_world = []
@ -410,10 +586,10 @@ def link_entrances(world):
# place old man, has limited options # place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about # exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [entrance for entrance in old_man_entrances if entrance in lw_entrances]
random.shuffle(old_man_entrances) random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop() old_man_exit = old_man_entrances.pop()
lw_entrances.extend(old_man_entrances) lw_entrances.remove(old_man_exit)
random.shuffle(lw_entrances)
connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit) connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit)
connect_entrance(world, lw_doors.pop(), 'Old Man Cave Exit (East)') connect_entrance(world, lw_doors.pop(), 'Old Man Cave Exit (East)')
@ -497,12 +673,14 @@ def link_entrances(world):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets) connect_doors(world, single_doors, door_targets)
elif world.shuffle == 'new_insanity':
# TODO
raise NotImplementedError()
elif world.shuffle == 'insanity': elif world.shuffle == 'insanity':
world.fix_fake_world = False world.fix_fake_world = False
# beware ye who enter here # beware ye who enter here
entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'] entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)']
entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)'] entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)']
doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Secret Entrance Stairs'] + Old_Man_Entrances +\ doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Secret Entrance Stairs'] + Old_Man_Entrances +\
@ -510,7 +688,7 @@ def link_entrances(world):
random.shuffle(doors) random.shuffle(doors)
old_man_entrances = list(Old_Man_Entrances) old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera']
caves = Cave_Exits + Dungeon_Exits + Cave_Three_Exits + ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)', caves = Cave_Exits + Dungeon_Exits + Cave_Three_Exits + ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)',
'Kakariko Well Exit', 'Bat Cave Exit', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', 'Sanctuary Exit'] 'Kakariko Well Exit', 'Bat Cave Exit', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', 'Sanctuary Exit']
@ -597,10 +775,10 @@ def link_entrances(world):
# place old man, has limited options # place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about # exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [entrance for entrance in old_man_entrances if entrance in entrances]
random.shuffle(old_man_entrances) random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop() old_man_exit = old_man_entrances.pop()
entrances.extend(old_man_entrances) entrances.remove(old_man_exit)
random.shuffle(entrances)
connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit) connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit)
connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)') connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)')
@ -671,14 +849,9 @@ def connect_entrance(world, entrancename, exitname):
entrance.connected_region.entrances.remove(entrance) entrance.connected_region.entrances.remove(entrance)
target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None) target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None)
addresses = door_addresses[entrance.name][0][0] if exit is not None else door_addresses[entrance.name][0] addresses = door_addresses[entrance.name][0]
try:
vanilla_ref = door_addresses[entrance.name][1]
vanilla = exit_ids[vanilla_ref]
except IndexError:
vanilla = None
entrance.connect(region, addresses, target, vanilla) entrance.connect(region, addresses, target)
world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance') world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance')
@ -690,7 +863,7 @@ def connect_exit(world, exitname, entrancename):
if exit.connected_region is not None: if exit.connected_region is not None:
exit.connected_region.entrances.remove(exit) exit.connected_region.entrances.remove(exit)
exit.connect(entrance.parent_region, door_addresses[entrance.name][0][1], exit_ids[exit.name][1]) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1])
world.spoiler.set_entrance(entrance.name, exit.name, 'exit') world.spoiler.set_entrance(entrance.name, exit.name, 'exit')
@ -704,8 +877,8 @@ def connect_two_way(world, entrancename, exitname):
if exit.connected_region is not None: if exit.connected_region is not None:
exit.connected_region.entrances.remove(exit) exit.connected_region.entrances.remove(exit)
entrance.connect(exit.parent_region, door_addresses[entrance.name][0][0], exit_ids[exit.name][0]) entrance.connect(exit.parent_region, door_addresses[entrance.name][0], exit_ids[exit.name][0])
exit.connect(entrance.parent_region, door_addresses[entrance.name][0][1], exit_ids[exit.name][1]) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1])
world.spoiler.set_entrance(entrance.name, exit.name, 'both') world.spoiler.set_entrance(entrance.name, exit.name, 'both')
@ -780,7 +953,6 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits):
raise RuntimeError('No more caves left. Should not happen!') raise RuntimeError('No more caves left. Should not happen!')
else: else:
caves.remove(cave) caves.remove(cave)
# all caves are sorted so that the last exit is always reachable # all caves are sorted so that the last exit is always reachable
for i in range(len(cave) - 1): for i in range(len(cave) - 1):
entrance = entrances.pop() entrance = entrances.pop()
@ -1005,6 +1177,136 @@ DW_Entrances = ['Bumper Cave (Bottom)',
'Superbunny Cave (Bottom)', 'Superbunny Cave (Bottom)',
'Hookshot Cave'] 'Hookshot Cave']
Bomb_Shop_Multi_Cave_Doors = ['Hyrule Castle Entrance (South)',
'Misery Mire',
'Thieves Town',
'Bumper Cave (Bottom)',
'Swamp Palace',
'Hyrule Castle Secret Entrance Stairs',
'Skull Woods First Section Door',
'Skull Woods Second Section Door (East)',
'Skull Woods Second Section Door (West)',
'Skull Woods Final Section',
'Ice Palace',
'Turtle Rock',
'Dark Death Mountain Ledge (West)',
'Dark Death Mountain Ledge (East)',
'Superbunny Cave (Top)',
'Superbunny Cave (Bottom)',
'Hookshot Cave',
'Ganons Tower',
'Desert Palace Entrance (South)',
'Tower of Hera',
'Two Brothers House (West)',
'Old Man Cave (East)',
'Old Man House (Bottom)',
'Old Man House (Top)',
'Death Mountain Return Cave (East)',
'Death Mountain Return Cave (West)',
'Spectacle Rock Cave Peak',
'Spectacle Rock Cave',
'Spectacle Rock Cave (Bottom)',
'Paradox Cave (Bottom)',
'Paradox Cave (Middle)',
'Paradox Cave (Top)',
'Fairy Ascension Cave (Bottom)',
'Fairy Ascension Cave (Top)',
'Spiral Cave',
'Spiral Cave (Bottom)',
'Palace of Darkness',
'Hyrule Castle Entrance (West)',
'Hyrule Castle Entrance (East)',
'Agahnims Tower',
'Desert Palace Entrance (West)',
'Desert Palace Entrance (North)',
'Old Man Cave (West)',
# all entrances below this line would be possible for blacksmith_hut
# if it were not for dwarf checking multi-entrance caves
'Eastern Palace',
'Elder House (East)',
'Elder House (West)',
'Two Brothers House (East)',
'Old Man Cave (West)',
'Sanctuary',
'Lumberjack Tree Cave',
'Lost Woods Hideout Stump',
'North Fairy Cave',
'Bat Cave Cave',
'Kakariko Well Cave']
#unfortunately blacksmith cannot occur in multi entrance caves, because the dwarf would refuse to enter.
Blacksmith_Multi_Cave_Doors = []
LW_Single_Cave_Doors = ['Blinds Hideout',
'Lake Hylia Fairy',
'Swamp Fairy',
'Desert Fairy',
'Chicken House',
'Aginahs Cave',
'Sahasrahlas Hut',
'Cave Shop (Lake Hylia)',
'Blacksmiths Hut',
'Sick Kids House',
'Lost Woods Gamble',
'Fortune Teller (Light)',
'Snitch Lady (East)',
'Snitch Lady (West)',
'Bush Covered House',
'Tavern (Front)',
'Light World Bomb Hut',
'Kakariko Shop',
'Mini Moldorm Cave',
'Long Fairy Cave',
'Good Bee Cave',
'20 Rupee Cave',
'50 Rupee Cave',
'Ice Rod Cave',
'Library',
'Potion Shop',
'Dam',
'Lumberjack House',
'Lake Hylia Fortune Teller',
'Kakariko Gamble Game',
'Waterfall of Wishing',
'Capacity Upgrade',
'Bonk Rock Cave',
'Graveyard Cave',
'Checkerboard Cave',
'Cave 45',
'Kings Grave',
'Bonk Fairy (Light)',
'Hookshot Fairy',
'Mimic Cave']
DW_Single_Cave_Doors = ['Bonk Fairy (Dark)',
'Dark Sanctuary Hint',
'Dark Lake Hylia Fairy',
'C-Shaped House',
'Big Bomb Shop',
'Dark Death Mountain Fairy',
'Dark Lake Hylia Shop',
'Dark World Shop',
'Red Shield Shop',
'Mire Shed',
'East Dark World Hint',
'Dark Desert Hint',
'Spike Cave',
'Palace of Darkness Hint',
'Dark Lake Hylia Ledge Spike Cave',
'Cave Shop (Dark Death Mountain)',
'Dark World Potion Shop',
'Pyramid Fairy',
'Archery Game',
'Dark World Lumberjack Shop',
'Hype Cave',
'Brewery',
'Dark Lake Hylia Ledge Hint',
'Chest Game',
'Dark Desert Fairy',
'Dark Lake Hylia Ledge Fairy',
'Fortune Teller (Dark)',
'Dark World Hammer Peg Cave']
Blacksmith_Single_Cave_Doors = ['Blinds Hideout', Blacksmith_Single_Cave_Doors = ['Blinds Hideout',
'Lake Hylia Fairy', 'Lake Hylia Fairy',
'Swamp Fairy', 'Swamp Fairy',
@ -1171,6 +1473,8 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
('Sewers Back Door', 'Sewers (Dark)'), ('Sewers Back Door', 'Sewers (Dark)'),
('Agahnim 1', 'Agahnim 1'), ('Agahnim 1', 'Agahnim 1'),
('Flute Spot 1', 'Death Mountain'), ('Flute Spot 1', 'Death Mountain'),
('Death Mountain Entrance Rock', 'Death Mountain Entrance'),
('Death Mountain Entrance Drop', 'Light World'),
('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'),
('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'),
('Death Mountain Return Ledge Drop', 'Light World'), ('Death Mountain Return Ledge Drop', 'Light World'),
@ -1207,6 +1511,9 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'),
('East Dark World River Pier', 'East Dark World'), ('East Dark World River Pier', 'East Dark World'),
('West Dark World Gap', 'West Dark World'), ('West Dark World Gap', 'West Dark World'),
('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'),
('Bumper Cave Entrance Drop', 'West Dark World'),
('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'),
('Bumper Cave Ledge Drop', 'West Dark World'), ('Bumper Cave Ledge Drop', 'West Dark World'),
('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'),
('Skull Woods Forest', 'Skull Woods Forest'), ('Skull Woods Forest', 'Skull Woods Forest'),
@ -1517,205 +1824,215 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace
] ]
# ToDo somehow merge this with creation of the locations # format:
door_addresses = {'Desert Palace Entrance (South)': ((0xDBB7B, 0x15B02),), # Key=Name
'Desert Palace Entrance (West)': ((0xDBB7D, 0x15B06),), # addr = (door_index, exitdata) # multiexit
'Desert Palace Entrance (North)': ((0xDBB7E, 0x15B08),), # | ([addr], None) # holes
'Desert Palace Entrance (East)': ((0xDBB7C, 0x15B04),), # 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)
'Eastern Palace': ((0xDBB7A, 0x15B00),),
'Tower of Hera': ((0xDBBA5, 0x15B48),),
'Hyrule Castle Entrance (South)': ((0xDBB76, 0x15AF4),),
'Hyrule Castle Entrance (West)': ((0xDBB75, 0x15AF2),),
'Hyrule Castle Entrance (East)': ((0xDBB77, 0x15AF6),),
'Agahnims Tower': ((0xDBB96, 0x15B38),),
'Thieves Town': ((0xDBBA6, 0x15B58),),
'Skull Woods First Section Door': ((0xDBB9C, 0x15B44),),
'Skull Woods Second Section Door (East)': ((0xDBB9B, 0x15B42),),
'Skull Woods Second Section Door (West)': ((0xDBB9A, 0x15B40),),
'Skull Woods Final Section': ((0xDBB9D, 0x15B46),),
'Ice Palace': ((0xDBB9F, 0x15B4A),),
'Misery Mire': ((0xDBB99, 0x15B3E),),
'Palace of Darkness': ((0xDBB98, 0x15B3C),),
'Swamp Palace': ((0xDBB97, 0x15B3A),),
'Turtle Rock': ((0xDBBA7, 0x15B56),),
'Dark Death Mountain Ledge (West)': ((0xDBB87, 0x15B1A),),
'Dark Death Mountain Ledge (East)': ((0xDBB8B, 0x15B22),),
'Turtle Rock Isolated Ledge Entrance': ((0xDBB8A, 0x15B20),),
'Hyrule Castle Secret Entrance Stairs': ((0xDBBA4, 0x15B54),),
'Kakariko Well Cave': ((0xDBBAB, 0x15B62),),
'Bat Cave Cave': ((0xDBB83, 0x15B12),),
'Elder House (East)': ((0xDBB80, 0x15B0C),),
'Elder House (West)': ((0xDBB7F, 0x15B0A),),
'North Fairy Cave': ((0xDBBAA, 0x15B60),),
'Lost Woods Hideout Stump': ((0xDBB9E, 0x15B5A),),
'Lumberjack Tree Cave': ((0xDBB84, 0x15B14),),
'Two Brothers House (East)': ((0xDBB82, 0x15B10),),
'Two Brothers House (West)': ((0xDBB81, 0x15B0E),),
'Sanctuary': ((0xDBB74, 0x15AF0),),
'Old Man Cave (West)': ((0xDBB78, 0x15AFC),),
'Old Man Cave (East)': ((0xDBB79, 0x15AFE),),
'Old Man House (Bottom)': ((0xDBBA2, 0x15B50),),
'Old Man House (Top)': ((0xDBBA3, 0x15B52),),
'Death Mountain Return Cave (East)': ((0xDBBA1, 0x15B4E),),
'Death Mountain Return Cave (West)': ((0xDBBA0, 0x15B4C),),
'Spectacle Rock Cave Peak': ((0xDBB95, 0x15B36),),
'Spectacle Rock Cave': ((0xDBB94, 0x15B34),),
'Spectacle Rock Cave (Bottom)': ((0xDBB93, 0x15B32),),
'Paradox Cave (Bottom)': ((0xDBB90, 0x15B2C),),
'Paradox Cave (Middle)': ((0xDBB91, 0x15B2E),),
'Paradox Cave (Top)': ((0xDBB92, 0x15B30),),
'Fairy Ascension Cave (Bottom)': ((0xDBB8C, 0x15B24),),
'Fairy Ascension Cave (Top)': ((0xDBB8D, 0x15B26),),
'Spiral Cave': ((0xDBB8F, 0x15B2A),),
'Spiral Cave (Bottom)': ((0xDBB8E, 0x15B28),),
'Bumper Cave (Bottom)': ((0xDBB88, 0x15B1C),),
'Bumper Cave (Top)': ((0xDBB89, 0x15B1E),),
'Superbunny Cave (Top)': ((0xDBB86, 0x15B18),),
'Superbunny Cave (Bottom)': ((0xDBB85, 0x15B16),),
'Hookshot Cave': ((0xDBBAC, 0x15B64),),
'Hookshot Cave Back Entrance': ((0xDBBAD, 0x15B66),),
'Ganons Tower': ((0xDBBA9, 0x15B5E),),
'Pyramid Entrance': ((0xDBBA8, 0x15B5C),),
'Skull Woods First Section Hole (East)': ((0xDB84D, 0xDB84E),),
'Skull Woods First Section Hole (West)': ((0xDB84F, 0xDB850),),
'Skull Woods First Section Hole (North)': (0xDB84C,),
'Skull Woods Second Section Hole': ((0xDB851, 0xDB852),),
'Pyramid Hole': ((0xDB854, 0xDB855, 0xDB856),),
'Waterfall of Wishing': (0xDBBCE, 'Waterfall of Wishing'),
'Dam': (0xDBBC0, 'Dam'),
'Blinds Hideout': (0xDBBD3, 'Blinds Hideout'),
'Hyrule Castle Secret Entrance Drop': (0xDB858,),
'Bonk Fairy (Light)': (0xDBBE9, 'Bonk Fairy'),
'Lake Hylia Fairy': (0xDBBD0, 'Healer Fairy'),
'Swamp Fairy': (0xDBBDE, 'Healer Fairy'),
'Desert Fairy': (0xDBBE4, 'Healer Fairy'),
'Kings Grave': (0xDBBCD, 'Kings Grave'),
'Tavern North': (0xDBBB5, 'Tavern'), # do not use, buggy
'Chicken House': (0xDBBBD, 'Chicken House'),
'Aginahs Cave': (0xDBBE3, 'Aginahs Cave'),
'Sahasrahlas Hut': (0xDBBB7, 'Sahasrahlas Hut'),
'Cave Shop (Lake Hylia)': (0xDBBCA, 'Cave Shop'),
'Capacity Upgrade': (0xDBBCF, 'Capacity Upgrade'),
'Kakariko Well Drop': ((0xDB85C, 0xDB85D),),
'Blacksmiths Hut': (0xDBBD6, 'Blacksmiths Hut'),
'Bat Cave Drop': ((0xDB859, 0xDB85A),),
'Sick Kids House': (0xDBBB2, 'Sick Kids House'),
'North Fairy Cave Drop': (0xDB857,),
'Lost Woods Gamble': (0xDBBAE, 'Lost Woods Gamble'),
'Fortune Teller (Light)': (0xDBBD7, 'Fortune Teller (Light)'),
'Snitch Lady (East)': (0xDBBB0, 'Snitch Lady (East)'),
'Snitch Lady (West)': (0xDBBB1, 'Snitch Lady (West)'),
'Bush Covered House': (0xDBBB6, 'Bush Covered House'),
'Tavern (Front)': (0xDBBB4, 'Tavern (Front)'),
'Light World Bomb Hut': (0xDBBBC, 'Light World Bomb Hut'),
'Kakariko Shop': (0xDBBB8, 'Kakariko Shop'),
'Lost Woods Hideout Drop': (0xDB853,),
'Lumberjack Tree Tree': (0xDB85B,),
'Cave 45': (0xDBBC3, 'Cave 45'),
'Graveyard Cave': (0xDBBC4, 'Graveyard Cave'),
'Checkerboard Cave': (0xDBBF0, 'Checkerboard Cave'),
'Mini Moldorm Cave': (0xDBBEF, 'Mini Moldorm Cave'),
'Long Fairy Cave': (0xDBBC7, 'Long Fairy Cave'),
'Good Bee Cave': (0xDBBDD, 'Good Bee Cave'),
'20 Rupee Cave': (0xDBBED, '20 Rupee Cave'),
'50 Rupee Cave': (0xDBBEB, '50 Rupee Cave'),
'Ice Rod Cave': (0xDBBF2, 'Ice Rod Cave'),
'Bonk Rock Cave': (0xDBBEC, 'Bonk Rock Cave'),
'Library': (0xDBBBB, 'Library'),
'Potion Shop': (0xDBBBE, 'Potion Shop'),
'Sanctuary Grave': (0xDB85E,),
'Hookshot Fairy': (0xDBBC2, 'Hookshot Fairy'),
'Pyramid Fairy': (0xDBBD5, 'Pyramid Fairy'),
'East Dark World Hint': (0xDBBDB, 'East Dark World Hint'),
'Palace of Darkness Hint': (0xDBBDA, 'Palace of Darkness Hint'),
'Dark Lake Hylia Fairy': (0xDBBDF, 'Healer Fairy'),
'Dark Lake Hylia Ledge Fairy': (0xDBBF3, 'Healer Fairy'),
'Dark Lake Hylia Ledge Spike Cave': (0xDBBEE, 'Dark Lake Hylia Ledge Spike Cave'),
'Dark Lake Hylia Ledge Hint': (0xDBBDC, 'Dark Lake Hylia Ledge Hint'),
'Hype Cave': (0xDBBAF, 'Hype Cave'),
'Bonk Fairy (Dark)': (0xDBBEA, 'Bonk Fairy'),
'Brewery': (0xDBBBA, 'Brewery'),
'C-Shaped House': (0xDBBC6, 'C-Shaped House'),
'Chest Game': (0xDBBB9, 'Chest Game'),
'Dark World Hammer Peg Cave': (0xDBBF1, 'Dark World Hammer Peg Cave'),
'Red Shield Shop': (0xDBBE7, 'Red Shield Shop'),
'Dark Sanctuary Hint': (0xDBBCC, 'Dark Sanctuary Hint'),
'Fortune Teller (Dark)': (0xDBBD8, 'Fortune Teller (Dark)'),
'Dark World Shop': (0xDBBD2, 'Dark World Shop'),
'Dark World Lumberjack Shop': (0xDBBC9, 'Dark World Shop'),
'Dark World Potion Shop': (0xDBBE1, 'Dark World Shop'),
'Archery Game': (0xDBBCB, 'Archery Game'),
'Mire Shed': (0xDBBD1, 'Mire Shed'),
'Dark Desert Hint': (0xDBBD4, 'Dark Desert Hint'),
'Dark Desert Fairy': (0xDBBC8, 'Healer Fairy'),
'Spike Cave': (0xDBBB3, 'Spike Cave'),
'Cave Shop (Dark Death Mountain)': (0xDBBE0, 'Cave Shop'),
'Dark Death Mountain Fairy': (0xDBBE2, 'Healer Fairy'),
'Mimic Cave': (0xDBBC1, 'Mimic Cave'),
'Big Bomb Shop': (0xDBBC5, 'Big Bomb Shop'),
'Dark Lake Hylia Shop': (0xDBBE6, 'Dark World Shop'),
'Lumberjack House': (0xDBBE8, 'Lumberjack House'),
'Lake Hylia Fortune Teller': (0xDBBE5, 'Fortune Teller (Light)'),
'Kakariko Gamble Game': (0xDBBD9, 'Kakariko Gamble Game')}
exit_ids = {'Desert Palace Exit (South)': (0x09, 0x84), # ToDo somehow merge this with creation of the locations
'Desert Palace Exit (West)': (0x0B, 0x83), door_addresses = {'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)),
'Desert Palace Exit (East)': (0x0A, 0x85), 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)),
'Desert Palace Exit (North)': (0x0C, 0x63), 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)),
'Eastern Palace Exit': (0x08, 0xC9), 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)),
'Tower of Hera Exit': (0x33, 0x77), 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)),
'Hyrule Castle Exit (South)': (0x04, 0x61), 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)),
'Hyrule Castle Exit (West)': (0x03, 0x60), 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)),
'Hyrule Castle Exit (East)': (0x05, 0x62), 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)),
'Agahnims Tower Exit': (0x24, 0xE0), 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)),
'Thieves Town Exit': (0x34, 0xDB), 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)),
'Skull Woods First Section Exit': (0x2A, 0x58), 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)),
'Skull Woods Second Section Exit (East)': (0x29, 0x57), 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)),
'Skull Woods Second Section Exit (West)': (0x28, 0x56), 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)),
'Skull Woods Final Section Exit': (0x2B, 0x59), 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)),
'Ice Palace Exit': (0x2D, 0x0E), 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)),
'Misery Mire Exit': (0x27, 0x98), 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)),
'Palace of Darkness Exit': (0x26, 0x4A), 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)),
'Swamp Palace Exit': (0x25, 0x28), 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)),
'Turtle Rock Exit (Front)': (0x35, 0xD6), 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)),
'Turtle Rock Ledge Exit (West)': (0x15, 0x23), 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)),
'Turtle Rock Ledge Exit (East)': (0x19, 0x24), 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)),
'Turtle Rock Isolated Ledge Exit': (0x18, 0xD5), 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)),
'Hyrule Castle Secret Entrance Exit': (0x32, 0x55), 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)),
'Kakariko Well Exit': (0x39, 0x2F), 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)),
'Bat Cave Exit': (0x11, 0xE3), 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)),
'Elder House Exit (East)': (0x0E, 0xF3), 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)),
'Elder House Exit (West)': (0x0D, 0xF2), 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)),
'North Fairy Cave Exit': (0x38, 0x08), 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)),
'Lost Woods Hideout Exit': (0x2C, 0xE1), 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)),
'Lumberjack Tree Exit': (0x12, 0xE2), 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)),
'Two Brothers House Exit (East)': (0x10, 0xF5), 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)),
'Two Brothers House Exit (West)': (0x0F, 0xF4), 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)),
'Sanctuary Exit': (0x02, 0x12), 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)),
'Old Man Cave Exit (East)': (0x07, 0xF1), 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)),
'Old Man Cave Exit (West)': (0x06, 0xF0), 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)),
'Old Man House Exit (Bottom)': (0x30, 0xE4), 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)),
'Old Man House Exit (Top)': (0x31, 0xE5), 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)),
'Death Mountain Return Cave Exit (West)': (0x2E, 0xE6), 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)),
'Death Mountain Return Cave Exit (East)': (0x2F, 0xE7), 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)),
'Spectacle Rock Cave Exit': (0x21, 0xF9), 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)),
'Spectacle Rock Cave Exit (Top)': (0x22, 0xFA), 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)),
'Spectacle Rock Cave Exit (Peak)': (0x23, 0xEA), 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)),
'Paradox Cave Exit (Bottom)': (0x1E, 0xFF), 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)),
'Paradox Cave Exit (Middle)': (0x1F, 0xEF), 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)),
'Paradox Cave Exit (Top)': (0x20, 0xDF), 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)),
'Fairy Ascension Cave Exit (Bottom)': (0x1A, 0xFD), 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)),
'Fairy Ascension Cave Exit (Top)': (0x1B, 0xED), 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)),
'Spiral Cave Exit': (0x1C, 0xFE), 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)),
'Spiral Cave Exit (Top)': (0x1D, 0xEE), 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)),
'Bumper Cave Exit (Top)': (0x17, 0xEB), 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)),
'Bumper Cave Exit (Bottom)': (0x16, 0xFB), 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)),
'Superbunny Cave Exit (Top)': (0x14, 0xE8), 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)),
'Superbunny Cave Exit (Bottom)': (0x13, 0xF8), 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)),
'Hookshot Cave Exit (South)': (0x3A, 0x3C), 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)),
'Hookshot Cave Exit (North)': (0x3B, 0x2C), 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)),
'Ganons Tower Exit': (0x37, 0x0C), 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)),
'Pyramid Exit': (0x36, 0x10), '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 (East)': ([0xDB84F, 0xDB850], None),
'Skull Woods First Section Hole (North)': ([0xDB84C], None),
'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None),
'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None),
'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)),
'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)),
'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)),
'Hyrule Castle Secret Entrance Drop': ([0xDB858], None),
'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)),
'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)),
'Swamp Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)),
'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)),
'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)),
'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), # do not use, buggy
'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)),
'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)),
'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)),
'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)),
'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)),
'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None),
'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)),
'Bat Cave Drop': ([0xDB859, 0xDB85A], None),
'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)),
'North Fairy Cave Drop': ([0xDB857], None),
'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)),
'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)),
'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)),
'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)),
'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)),
'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)),
'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)),
'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)),
'Lost Woods Hideout Drop': ([0xDB853], None),
'Lumberjack Tree Tree': ([0xDB85B], None),
'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)),
'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)),
'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)),
'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)),
'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)),
'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)),
'20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)),
'50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)),
'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)),
'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)),
'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)),
'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)),
'Sanctuary Grave': ([0xDB85E], None),
'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)),
'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)),
'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)),
'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)),
'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)),
'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)),
'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)),
'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)),
'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)),
'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)),
'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)),
'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)),
'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)),
'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)),
'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)),
'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)),
'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)),
'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)),
'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)),
'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)),
'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)),
'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)),
'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)),
'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)),
'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)),
'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)),
'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)),
'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)),
'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)),
'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)),
'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)),
'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)),
'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))}
# format:
# Key=Name
# value = entrance #
# | (entrance #, exit #)
exit_ids = {'Desert Palace Exit (South)': (0x09, 0x0A),
'Desert Palace Exit (West)': (0x0B, 0x0C),
'Desert Palace Exit (East)': (0x0A, 0x0B),
'Desert Palace Exit (North)': (0x0C, 0x0D),
'Eastern Palace Exit': (0x08, 0x09),
'Tower of Hera Exit': (0x33, 0x2D),
'Hyrule Castle Exit (South)': (0x04, 0x03),
'Hyrule Castle Exit (West)': (0x03, 0x02),
'Hyrule Castle Exit (East)': (0x05, 0x04),
'Agahnims Tower Exit': (0x24, 0x25),
'Thieves Town Exit': (0x34, 0x35),
'Skull Woods First Section Exit': (0x2A, 0x2B),
'Skull Woods Second Section Exit (East)': (0x29, 0x2A),
'Skull Woods Second Section Exit (West)': (0x28, 0x29),
'Skull Woods Final Section Exit': (0x2B, 0x2C),
'Ice Palace Exit': (0x2D, 0x2E),
'Misery Mire Exit': (0x27, 0x28),
'Palace of Darkness Exit': (0x26, 0x27),
'Swamp Palace Exit': (0x25, 0x26),
'Turtle Rock Exit (Front)': (0x35, 0x34),
'Turtle Rock Ledge Exit (West)': (0x15, 0x16),
'Turtle Rock Ledge Exit (East)': (0x19, 0x1A),
'Turtle Rock Isolated Ledge Exit': (0x18, 0x19),
'Hyrule Castle Secret Entrance Exit': (0x32, 0x33),
'Kakariko Well Exit': (0x39, 0x3A),
'Bat Cave Exit': (0x11, 0x12),
'Elder House Exit (East)': (0x0E, 0x0F),
'Elder House Exit (West)': (0x0D, 0x0E),
'North Fairy Cave Exit': (0x38, 0x39),
'Lost Woods Hideout Exit': (0x2C, 0x36),
'Lumberjack Tree Exit': (0x12, 0x13),
'Two Brothers House Exit (East)': (0x10, 0x11),
'Two Brothers House Exit (West)': (0x0F, 0x10),
'Sanctuary Exit': (0x02, 0x01),
'Old Man Cave Exit (East)': (0x07, 0x08),
'Old Man Cave Exit (West)': (0x06, 0x07),
'Old Man House Exit (Bottom)': (0x30, 0x31),
'Old Man House Exit (Top)': (0x31, 0x32),
'Death Mountain Return Cave Exit (West)': (0x2E, 0x2F),
'Death Mountain Return Cave Exit (East)': (0x2F, 0x30),
'Spectacle Rock Cave Exit': (0x21, 0x22),
'Spectacle Rock Cave Exit (Top)': (0x22, 0x23),
'Spectacle Rock Cave Exit (Peak)': (0x23, 0x24),
'Paradox Cave Exit (Bottom)': (0x1E, 0x1F),
'Paradox Cave Exit (Middle)': (0x1F, 0x20),
'Paradox Cave Exit (Top)': (0x20, 0x21),
'Fairy Ascension Cave Exit (Bottom)': (0x1A, 0x1B),
'Fairy Ascension Cave Exit (Top)': (0x1B, 0x1C),
'Spiral Cave Exit': (0x1C, 0x1D),
'Spiral Cave Exit (Top)': (0x1D, 0x1E),
'Bumper Cave Exit (Top)': (0x17, 0x18),
'Bumper Cave Exit (Bottom)': (0x16, 0x17),
'Superbunny Cave Exit (Top)': (0x14, 0x15),
'Superbunny Cave Exit (Bottom)': (0x13, 0x14),
'Hookshot Cave Exit (South)': (0x3A, 0x3B),
'Hookshot Cave Exit (North)': (0x3B, 0x3C),
'Ganons Tower Exit': (0x37, 0x38),
'Pyramid Exit': (0x36, 0x37),
'Waterfall of Wishing': 0x5C, 'Waterfall of Wishing': 0x5C,
'Dam': 0x4E, 'Dam': 0x4E,
'Blinds Hideout': 0x61, 'Blinds Hideout': 0x61,

2
Gui.py
View File

@ -194,7 +194,7 @@ def guiMain(args=None):
shuffleFrame = Frame(drowDownFrame) shuffleFrame = Frame(drowDownFrame)
shuffleVar = StringVar() shuffleVar = StringVar()
shuffleVar.set('full') shuffleVar.set('full')
shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple') shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'full_cross_worlds', 'full_legacy', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple')
shuffleOptionMenu.pack(side=RIGHT) shuffleOptionMenu.pack(side=RIGHT)
shuffleLabel = Label(shuffleFrame, text='Entrance shuffle algorithm') shuffleLabel = Label(shuffleFrame, text='Entrance shuffle algorithm')
shuffleLabel.pack(side=LEFT) shuffleLabel.pack(side=LEFT)

View File

@ -146,6 +146,7 @@ def copy_world(world):
ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge
ret.can_take_damage = world.can_take_damage ret.can_take_damage = world.can_take_damage
ret.difficulty_requirements = world.difficulty_requirements ret.difficulty_requirements = world.difficulty_requirements
ret.fix_fake_world = ret.fix_fake_world
create_regions(ret) create_regions(ret)
create_dungeons(ret) create_dungeons(ret)
@ -153,6 +154,7 @@ def copy_world(world):
for region in world.regions: for region in world.regions:
copied_region = ret.get_region(region.name) copied_region = ret.get_region(region.name)
copied_region.is_light_world = region.is_light_world copied_region.is_light_world = region.is_light_world
copied_region.is_dark_world = region.is_dark_world
for entrance in region.entrances: for entrance in region.entrances:
ret.get_entrance(entrance.name).connect(copied_region) ret.get_entrance(entrance.name).connect(copied_region)
@ -285,7 +287,6 @@ def create_playthrough(world):
old_world.spoiler.paths = {location.name : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere} old_world.spoiler.paths = {location.name : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere}
if any(exit == 'Pyramid Fairy' for path in old_world.spoiler.paths.values() for (_, exit) in path): if any(exit == 'Pyramid Fairy' for path in old_world.spoiler.paths.values() for (_, exit) in path):
old_world.spoiler.paths['Big Bomb Shop'] = get_path(state, world.get_region('Big Bomb Shop')) old_world.spoiler.paths['Big Bomb Shop'] = get_path(state, world.get_region('Big Bomb Shop'))
print(world.seed)
# we can finally output our playthrough # we can finally output our playthrough
old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)]) old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)])

View File

@ -1,280 +1,293 @@
import collections import collections
from BaseClasses import Region, Location, Entrance from BaseClasses import Region, Location, Entrance, RegionType
def create_regions(world): def create_regions(world):
world.regions = [ world.regions = [
create_region('Light World', 'Light', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest'], create_lw_region('Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest'],
["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Zoras River', 'Kings Grave', 'Dam', ["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Zoras River', 'Kings Grave', 'Dam',
'Links House', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave', 'Links House', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave',
'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump', 'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump',
'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier', 'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier',
'Bonk Rock Cave', 'Library', 'Potion Shop', 'Two Brothers House (East)', 'Desert Palace Stairs', 'Eastern Palace', 'Master Sword Meadow', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Two Brothers House (East)', 'Desert Palace Stairs', 'Eastern Palace', 'Master Sword Meadow',
'Sanctuary', 'Sanctuary Grave', 'Old Man Cave (West)', 'Flute Spot 1', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter', 'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Flute Spot 1', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter',
'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)', 'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing', 'Hyrule Castle Main Gate', 'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing', 'Hyrule Castle Main Gate',
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']), 'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']),
create_region('Lake Hylia Central Island', 'Light', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']), create_lw_region('Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop']),
create_region('Blinds Hideout', 'Inside', ["Blind\'s Hideout - Top", create_lw_region('Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']),
"Blind\'s Hideout - Left", create_cave_region('Blinds Hideout', ["Blind\'s Hideout - Top",
"Blind\'s Hideout - Right", "Blind\'s Hideout - Left",
"Blind\'s Hideout - Far Left", "Blind\'s Hideout - Right",
"Blind\'s Hideout - Far Right"]), "Blind\'s Hideout - Far Left",
create_region('Hyrule Castle Secret Entrance', 'Inside', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']), "Blind\'s Hideout - Far Right"]),
create_region('Zoras River', 'Light', ['King Zora', 'Zora\'s Ledge']), create_cave_region('Hyrule Castle Secret Entrance', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']),
create_region('Waterfall of Wishing', 'Inside', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']), create_lw_region('Zoras River', ['King Zora', 'Zora\'s Ledge']),
create_region('Kings Grave', 'Inside', ['King\'s Tomb']), create_cave_region('Waterfall of Wishing', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']),
create_region('North Fairy Cave', 'Inside', None, ['North Fairy Cave Exit']), create_cave_region('Kings Grave', ['King\'s Tomb']),
create_region('Dam', 'Inside', ['Floodgate Chest']), create_cave_region('North Fairy Cave', None, ['North Fairy Cave Exit']),
create_region('Links House', 'Inside', ['Link\'s House'], ['Links House Exit']), create_cave_region('Dam', ['Floodgate Chest']),
create_region('Tavern', 'Inside', ['Kakariko Tavern']), create_cave_region('Links House', ['Link\'s House'], ['Links House Exit']),
create_region('Elder House', 'Inside', None, ['Elder House Exit (East)', 'Elder House Exit (West)']), create_cave_region('Tavern', ['Kakariko Tavern']),
create_region('Snitch Lady (East)', 'Inside'), create_cave_region('Elder House', None, ['Elder House Exit (East)', 'Elder House Exit (West)']),
create_region('Snitch Lady (West)', 'Inside'), create_cave_region('Snitch Lady (East)'),
create_region('Bush Covered House', 'Inside'), create_cave_region('Snitch Lady (West)'),
create_region('Tavern (Front)', 'Inside'), create_cave_region('Bush Covered House'),
create_region('Light World Bomb Hut', 'Inside'), create_cave_region('Tavern (Front)'),
create_region('Kakariko Shop', 'Inside'), create_cave_region('Light World Bomb Hut'),
create_region('Fortune Teller (Light)', 'Inside'), create_cave_region('Kakariko Shop'),
create_region('Lumberjack House', 'Inside'), create_cave_region('Fortune Teller (Light)'),
create_region('Bonk Fairy', 'Inside'), # near links house both worlds create_cave_region('Lumberjack House'),
create_region('Healer Fairy', 'Inside'), # 8 entrances? create_cave_region('Bonk Fairy'), # near links house both worlds
create_region('Chicken House', 'Inside', ['Chicken House']), create_cave_region('Healer Fairy'), # 8 entrances?
create_region('Aginahs Cave', 'Inside', ['Aginah\'s Cave']), create_cave_region('Chicken House', ['Chicken House']),
create_region('Sahasrahlas Hut', 'Inside', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']), create_cave_region('Aginahs Cave', ['Aginah\'s Cave']),
create_region('Kakariko Well (top)', 'Inside', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle', create_cave_region('Sahasrahlas Hut', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']),
'Kakariko Well - Right', 'Kakariko Well - Bottom'], ['Kakariko Well (top to bottom)']), create_cave_region('Kakariko Well (top)', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle',
create_region('Kakariko Well (bottom)', 'Inside', None, ['Kakariko Well Exit']), 'Kakariko Well - Right', 'Kakariko Well - Bottom'], ['Kakariko Well (top to bottom)']),
create_region('Blacksmiths Hut', 'Inside', ['Blacksmith']), create_cave_region('Kakariko Well (bottom)', None, ['Kakariko Well Exit']),
create_region('Bat Cave Drop Ledge', 'Light', None, ['Bat Cave Drop']), create_cave_region('Blacksmiths Hut', ['Blacksmith']),
create_region('Bat Cave (right)', 'Inside', ['Magic Bat'], ['Bat Cave Door']), create_lw_region('Bat Cave Drop Ledge', None, ['Bat Cave Drop']),
create_region('Bat Cave (left)', 'Inside', None, ['Bat Cave Exit']), create_cave_region('Bat Cave (right)', ['Magic Bat'], ['Bat Cave Door']),
create_region('Sick Kids House', 'Inside', ['Sick Kid']), create_cave_region('Bat Cave (left)', None, ['Bat Cave Exit']),
create_region('Hobo Bridge', 'Light', ['Hobo']), create_cave_region('Sick Kids House', ['Sick Kid']),
create_region('Lost Woods Hideout (top)', 'Inside', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']), create_lw_region('Hobo Bridge', ['Hobo']),
create_region('Lost Woods Hideout (bottom)', 'Inside', None, ['Lost Woods Hideout Exit']), create_cave_region('Lost Woods Hideout (top)', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']),
create_region('Lumberjack Tree (top)', 'Inside', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']), create_cave_region('Lost Woods Hideout (bottom)', None, ['Lost Woods Hideout Exit']),
create_region('Lumberjack Tree (bottom)', 'Inside', None, ['Lumberjack Tree Exit']), create_cave_region('Lumberjack Tree (top)', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']),
create_region('Cave 45 Ledge', 'Light', None, ['Cave 45']), create_cave_region('Lumberjack Tree (bottom)', None, ['Lumberjack Tree Exit']),
create_region('Cave 45', 'Inside', ['Cave 45']), create_lw_region('Cave 45 Ledge', None, ['Cave 45']),
create_region('Graveyard Ledge', 'Light', None, ['Graveyard Cave']), create_cave_region('Cave 45', ['Cave 45']),
create_region('Graveyard Cave', 'Inside', ['Graveyard Cave']), create_lw_region('Graveyard Ledge', None, ['Graveyard Cave']),
create_region('Checkerboard Cave', 'Inside', ['Checkerboard Cave']), create_cave_region('Graveyard Cave', ['Graveyard Cave']),
create_region('Long Fairy Cave', 'Inside'), create_cave_region('Checkerboard Cave', ['Checkerboard Cave']),
create_region('Mini Moldorm Cave', 'Inside', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', create_cave_region('Long Fairy Cave'),
'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']), create_cave_region('Mini Moldorm Cave', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right',
create_region('Ice Rod Cave', 'Inside', ['Ice Rod Cave']), 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']),
create_region('Good Bee Cave', 'Inside'), create_cave_region('Ice Rod Cave', ['Ice Rod Cave']),
create_region('20 Rupee Cave', 'Inside'), create_cave_region('Good Bee Cave'),
create_region('Cave Shop', 'Inside'), # two connectors in vanilla create_cave_region('20 Rupee Cave'),
create_region('Bonk Rock Cave', 'Inside', ['Bonk Rock Cave']), create_cave_region('Cave Shop'), # two connectors in vanilla
create_region('Library', 'Inside', ['Library']), create_cave_region('Bonk Rock Cave', ['Bonk Rock Cave']),
create_region('Kakariko Gamble Game', 'Inside'), create_cave_region('Library', ['Library']),
create_region('Potion Shop', 'Inside', ['Potion Shop']), create_cave_region('Kakariko Gamble Game'),
create_region('Lake Hylia Island', 'Light', ['Lake Hylia Island']), create_cave_region('Potion Shop', ['Potion Shop']),
create_region('Capacity Upgrade', 'Inside'), create_lw_region('Lake Hylia Island', ['Lake Hylia Island']),
create_region('Two Brothers House', 'Inside', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']), create_cave_region('Capacity Upgrade'),
create_region('Maze Race Ledge', 'Light', ['Maze Race'], ['Two Brothers House (West)']), create_cave_region('Two Brothers House', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']),
create_region('50 Rupee Cave', 'Inside'), create_lw_region('Maze Race Ledge', ['Maze Race'], ['Two Brothers House (West)']),
create_region('Desert Ledge', 'Light', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)']), create_cave_region('50 Rupee Cave'),
create_region('Desert Ledge (Northeast)', 'Light', None, ['Checkerboard Cave']), create_lw_region('Desert Ledge', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)']),
create_region('Desert Palace Stairs', 'Light', None, ['Desert Palace Entrance (South)']), create_lw_region('Desert Ledge (Northeast)', None, ['Checkerboard Cave']),
create_region('Desert Palace Lone Stairs', 'Light', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']), create_lw_region('Desert Palace Stairs', None, ['Desert Palace Entrance (South)']),
create_region('Desert Palace Entrance (North) Spot', 'Light', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks']), create_lw_region('Desert Palace Lone Stairs', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']),
create_region('Desert Palace Main', 'Inside', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'], create_lw_region('Desert Palace Entrance (North) Spot', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks']),
['Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', 'Desert Palace East Wing']), create_dungeon_region('Desert Palace Main', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'],
create_region('Desert Palace East', 'Inside', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']), ['Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', 'Desert Palace East Wing']),
create_region('Desert Palace North', 'Inside', ['Desert Palace - Lanmolas', 'Desert Palace - Prize'], ['Desert Palace Exit (North)']), create_dungeon_region('Desert Palace East', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']),
create_region('Eastern Palace', 'Inside', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest', create_dungeon_region('Desert Palace North', ['Desert Palace - Lanmolas', 'Desert Palace - Prize'], ['Desert Palace Exit (North)']),
'Eastern Palace - Big Key Chest', 'Eastern Palace - Map Chest', 'Eastern Palace - Armos Knights', 'Eastern Palace - Prize'], ['Eastern Palace Exit']), create_dungeon_region('Eastern Palace', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest',
create_region('Master Sword Meadow', 'Light', ['Master Sword Pedestal']), 'Eastern Palace - Big Key Chest', 'Eastern Palace - Map Chest', 'Eastern Palace - Armos Knights', 'Eastern Palace - Prize'], ['Eastern Palace Exit']),
create_region('Lost Woods Gamble', 'Inside'), create_lw_region('Master Sword Meadow', ['Master Sword Pedestal']),
create_region('Hyrule Castle Courtyard', 'Light', None, ['Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Entrance (South)']), create_cave_region('Lost Woods Gamble'),
create_region('Hyrule Castle Ledge', 'Light', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Ledge Courtyard Drop']), create_lw_region('Hyrule Castle Courtyard', None, ['Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Entrance (South)']),
create_region('Hyrule Castle', 'Inside', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest'], create_lw_region('Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Ledge Courtyard Drop']),
['Hyrule Castle Exit (East)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (South)', 'Throne Room']), create_dungeon_region('Hyrule Castle', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest'],
create_region('Sewer Drop', 'Inside', None, ['Sewer Drop']), # This exists only to be referenced for access checks ['Hyrule Castle Exit (East)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (South)', 'Throne Room']),
create_region('Sewers (Dark)', 'Inside', ['Sewers - Dark Cross'], ['Sewers Door']), create_dungeon_region('Sewer Drop', None, ['Sewer Drop']), # This exists only to be referenced for access checks
create_region('Sewers', 'Inside', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', create_dungeon_region('Sewers (Dark)', ['Sewers - Dark Cross'], ['Sewers Door']),
'Sewers - Secret Room - Right'], ['Sanctuary Push Door', 'Sewers Back Door']), create_dungeon_region('Sewers', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle',
create_region('Sanctuary', 'Inside', ['Sanctuary'], ['Sanctuary Exit']), 'Sewers - Secret Room - Right'], ['Sanctuary Push Door', 'Sewers Back Door']),
create_region('Agahnims Tower', 'Inside', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze'], ['Agahnim 1', 'Agahnims Tower Exit']), create_dungeon_region('Sanctuary', ['Sanctuary'], ['Sanctuary Exit']),
create_region('Agahnim 1', 'Inside', ['Agahnim 1'], None), create_dungeon_region('Agahnims Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze'], ['Agahnim 1', 'Agahnims Tower Exit']),
create_region('Old Man Cave', 'Inside', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']), create_dungeon_region('Agahnim 1', ['Agahnim 1'], None),
create_region('Old Man House', 'Inside', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), create_cave_region('Old Man Cave', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']),
create_region('Old Man House Back', 'Inside', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), create_cave_region('Old Man House', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']),
create_region('Death Mountain', 'Light', 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)', 'Broken Bridge (West)', 'Death Mountain Teleporter']), create_cave_region('Old Man House Back', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']),
create_region('Death Mountain Return Cave', 'Inside', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), create_lw_region('Death Mountain', 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)', 'Broken Bridge (West)', 'Death Mountain Teleporter']),
create_region('Death Mountain Return Ledge', 'Light', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']), create_cave_region('Death Mountain Return Cave', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']),
create_region('Spectacle Rock Cave (Top)', 'Inside', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), create_lw_region('Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']),
create_region('Spectacle Rock Cave (Bottom)', 'Inside', None, ['Spectacle Rock Cave Exit']), create_cave_region('Spectacle Rock Cave (Top)', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']),
create_region('Spectacle Rock Cave (Peak)', 'Inside', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']), create_cave_region('Spectacle Rock Cave (Bottom)', None, ['Spectacle Rock Cave Exit']),
create_region('East Death Mountain (Bottom)', 'Light', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Teleporter', 'Hookshot Fairy', 'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']), create_cave_region('Spectacle Rock Cave (Peak)', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']),
create_region('Hookshot Fairy', 'Inside'), create_lw_region('East Death Mountain (Bottom)', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Teleporter', 'Hookshot Fairy', 'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']),
create_region('Paradox Cave Front', 'Inside', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)']), create_cave_region('Hookshot Fairy'),
create_region('Paradox Cave Chest Area', 'Inside', ['Paradox Cave Lower - Far Left', create_cave_region('Paradox Cave Front', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)']),
'Paradox Cave Lower - Left', create_cave_region('Paradox Cave Chest Area', ['Paradox Cave Lower - Far Left',
'Paradox Cave Lower - Right', 'Paradox Cave Lower - Left',
'Paradox Cave Lower - Far Right', 'Paradox Cave Lower - Right',
'Paradox Cave Lower - Middle', 'Paradox Cave Lower - Far Right',
'Paradox Cave Upper - Left', 'Paradox Cave Lower - Middle',
'Paradox Cave Upper - Right'], 'Paradox Cave Upper - Left',
['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']), 'Paradox Cave Upper - Right'],
create_region('Paradox Cave', 'Inside', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), ['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']),
create_region('East Death Mountain (Top)', 'Light', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']), create_cave_region('Paradox Cave', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']),
create_region('Spiral Cave Ledge', 'Light', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']), create_lw_region('East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']),
create_region('Spiral Cave (Top)', 'Inside', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']), create_lw_region('Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']),
create_region('Spiral Cave (Bottom)', 'Inside', None, ['Spiral Cave Exit']), create_cave_region('Spiral Cave (Top)', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']),
create_region('Fairy Ascension Plateau', 'Light', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']), create_cave_region('Spiral Cave (Bottom)', None, ['Spiral Cave Exit']),
create_region('Fairy Ascension Cave', 'Inside', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Exit (Bottom)']), create_lw_region('Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']),
create_region('Fairy Ascension Ledge', 'Light', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']), create_cave_region('Fairy Ascension Cave', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Exit (Bottom)']),
create_region('Death Mountain (Top)', 'Light', ['Ether Tablet'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop']), create_lw_region('Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']),
create_region('Spectacle Rock', 'Light', ['Spectacle Rock'], ['Spectacle Rock Drop']), create_lw_region('Death Mountain (Top)', ['Ether Tablet'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop']),
create_region('Tower of Hera (Bottom)', 'Inside', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']), create_lw_region('Spectacle Rock', ['Spectacle Rock'], ['Spectacle Rock Drop']),
create_region('Tower of Hera (Basement)', 'Inside', ['Tower of Hera - Big Key Chest']), create_dungeon_region('Tower of Hera (Bottom)', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']),
create_region('Tower of Hera (Top)', 'Inside', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Moldorm', 'Tower of Hera - Prize']), create_dungeon_region('Tower of Hera (Basement)', ['Tower of Hera - Big Key Chest']),
create_dungeon_region('Tower of Hera (Top)', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Moldorm', 'Tower of Hera - Prize']),
create_region('East Dark World', 'Dark', ['Pyramid', 'Catfish'], ['Pyramid Fairy', 'South Dark World Bridge', 'West Dark World Gap', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Teleporter', create_dw_region('East Dark World', ['Pyramid', 'Catfish'], ['Pyramid Fairy', 'South Dark World Bridge', 'West Dark World Gap', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Teleporter',
'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Dark World Potion Shop', 'Pyramid Hole']), 'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Dark World Potion Shop', 'Pyramid Hole']),
create_region('Palace of Darkness Hint', 'Inside'), create_cave_region('Palace of Darkness Hint'),
create_region('East Dark World Hint', 'Inside'), create_cave_region('East Dark World Hint'),
create_region('South Dark World', 'Dark', ['Stumpy', 'Digging Game', 'Bombos Tablet'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', create_dw_region('South Dark World', ['Stumpy', 'Digging Game', 'Bombos Tablet'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock',
'Maze Race Mirror Spot', 'Cave 45 Mirror Spot', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop']), 'Maze Race Mirror Spot', 'Cave 45 Mirror Spot', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop']),
create_region('Big Bomb Shop', 'Inside'), create_cave_region('Big Bomb Shop'),
create_region('Archery Game', 'Inside'), create_cave_region('Archery Game'),
create_region('Dark Lake Hylia', 'Dark', None, ['Lake Hylia Island Mirror Spot', 'East Dark World Pier', 'Dark Lake Hylia Ledge']), create_dw_region('Dark Lake Hylia', None, ['Lake Hylia Island Mirror Spot', 'East Dark World Pier', 'Dark Lake Hylia Ledge']),
create_region('Dark Lake Hylia Central Island', 'Dark', None, ['Ice Palace', 'Lake Hylia Central Island Mirror Spot']), create_dw_region('Dark Lake Hylia Central Island', None, ['Ice Palace', 'Lake Hylia Central Island Mirror Spot']),
create_region('Dark Lake Hylia Ledge', 'Dark', None, ['Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave']), create_dw_region('Dark Lake Hylia Ledge', None, ['Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave']),
create_region('Dark Lake Hylia Ledge Hint', 'Inside'), create_cave_region('Dark Lake Hylia Ledge Hint'),
create_region('Dark Lake Hylia Ledge Spike Cave', 'Inside'), create_cave_region('Dark Lake Hylia Ledge Spike Cave'),
create_region('Hype Cave', 'Inside', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', create_cave_region('Hype Cave', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']), 'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
create_region('West Dark World', 'Dark', None, ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Graveyard Ledge Mirror Spot', 'Bumper Cave (Bottom)', 'Skull Woods Forest', create_dw_region('West Dark World', None, ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Graveyard Ledge Mirror Spot', 'Bumper Cave Entrance Rock', 'Skull Woods Forest',
'Bat Cave Drop Ledge Mirror Spot', 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Shop', 'Dark World Lumberjack Shop']), 'Bat Cave Drop Ledge Mirror Spot', 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Shop', 'Dark World Lumberjack Shop']),
create_region('Fortune Teller (Dark)', 'Inside'), create_dw_region('Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance Drop']),
create_region('Dark World Shop', 'Inside'), create_cave_region('Fortune Teller (Dark)'),
create_region('Dark World Hammer Peg Cave', 'Inside', ['Peg Cave']), create_cave_region('Dark World Shop'),
create_region('Pyramid Fairy', 'Inside', ['Pyramid Fairy - Left', 'Pyramid Fairy - Right']), create_cave_region('Dark World Hammer Peg Cave', ['Peg Cave']),
create_region('Brewery', 'Inside', ['Brewery']), create_cave_region('Pyramid Fairy', ['Pyramid Fairy - Left', 'Pyramid Fairy - Right']),
create_region('C-Shaped House', 'Inside', ['C-Shaped House']), create_cave_region('Brewery', ['Brewery']),
create_region('Chest Game', 'Inside', ['Chest Game']), create_cave_region('C-Shaped House', ['C-Shaped House']),
create_region('Red Shield Shop', 'Inside'), create_cave_region('Chest Game', ['Chest Game']),
create_region('Dark Sanctuary Hint', 'Inside'), create_cave_region('Red Shield Shop'),
create_region('Bumper Cave', 'Inside', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']), create_cave_region('Dark Sanctuary Hint'),
create_region('Bumper Cave Ledge', 'Dark', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)', 'Bumper Cave Ledge Mirror Spot']), create_cave_region('Bumper Cave', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']),
create_region('Skull Woods Forest', 'Dark', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', create_dw_region('Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)', 'Bumper Cave Ledge Mirror Spot']),
'Skull Woods Second Section Door (East)']), create_dw_region('Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door',
create_region('Skull Woods Forest (West)', 'Dark', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']), 'Skull Woods Second Section Door (East)']),
create_region('Dark Desert', 'Dark', None, ['Misery Mire', 'Mire Shed', 'Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge Mirror Spot', 'Desert Palace Stairs Mirror Spot', 'Desert Palace Entrance (North) Mirror Spot', create_dw_region('Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']),
'Dark Desert Hint', 'Dark Desert Fairy']), create_dw_region('Dark Desert', None, ['Misery Mire', 'Mire Shed', 'Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge Mirror Spot', 'Desert Palace Stairs Mirror Spot', 'Desert Palace Entrance (North) Mirror Spot',
create_region('Mire Shed', 'Inside', ['Mire Shed - Left', 'Mire Shed - Right']), 'Dark Desert Hint', 'Dark Desert Fairy']),
create_region('Dark Desert Hint', 'Inside'), create_cave_region('Mire Shed', ['Mire Shed - Left', 'Mire Shed - Right']),
create_region('Dark Death Mountain (West Bottom)', 'Dark', None, ['Spike Cave', 'Spectacle Rock Mirror Spot', 'Dark Death Mountain Fairy']), create_cave_region('Dark Desert Hint'),
create_region('Dark Death Mountain (Top)', 'Dark', None, ['Dark Death Mountain Drop (East)', 'Dark Death Mountain Drop (West)', 'Ganons Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', create_dw_region('Dark Death Mountain (West Bottom)', None, ['Spike Cave', 'Spectacle Rock Mirror Spot', 'Dark Death Mountain Fairy']),
'East Death Mountain (Top) Mirror Spot', 'Turtle Rock']), create_dw_region('Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Dark Death Mountain Drop (West)', 'Ganons Tower', 'Superbunny Cave (Top)', 'Hookshot Cave',
create_region('Dark Death Mountain Ledge', 'Dark', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Mimic Cave Mirror Spot', 'Spiral Cave Mirror Spot']), 'East Death Mountain (Top) Mirror Spot', 'Turtle Rock']),
create_region('Dark Death Mountain Isolated Ledge', 'Dark', None, ['Isolated Ledge Mirror Spot', 'Turtle Rock Isolated Ledge Entrance']), create_dw_region('Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Mimic Cave Mirror Spot', 'Spiral Cave Mirror Spot']),
create_region('Dark Death Mountain (East Bottom)', 'Dark', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Fairy Ascension Mirror Spot']), create_dw_region('Dark Death Mountain Isolated Ledge', None, ['Isolated Ledge Mirror Spot', 'Turtle Rock Isolated Ledge Entrance']),
create_region('Superbunny Cave', 'Inside', ['Superbunny Cave - Top', 'Superbunny Cave - Bottom'], create_dw_region('Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Fairy Ascension Mirror Spot']),
['Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)']), create_cave_region('Superbunny Cave', ['Superbunny Cave - Top', 'Superbunny Cave - Bottom'],
create_region('Spike Cave', 'Inside', ['Spike Cave']), ['Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)']),
create_region('Hookshot Cave', 'Inside', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], create_cave_region('Spike Cave', ['Spike Cave']),
['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']), create_cave_region('Hookshot Cave', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'],
create_region('Death Mountain Floating Island (Dark World)', 'Dark', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']), ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']),
create_region('Death Mountain Floating Island (Light World)', 'Light', ['Floating Island']), create_dw_region('Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']),
create_region('Turtle Rock (Top)', 'Dark', None, ['Turtle Rock Drop']), create_lw_region('Death Mountain Floating Island (Light World)', ['Floating Island']),
create_region('Mimic Cave Ledge', 'Light', None, ['Mimic Cave']), create_dw_region('Turtle Rock (Top)', None, ['Turtle Rock Drop']),
create_region('Mimic Cave', 'Inside', ['Mimic Cave']), create_lw_region('Mimic Cave Ledge', None, ['Mimic Cave']),
create_cave_region('Mimic Cave', ['Mimic Cave']),
create_region('Swamp Palace (Entrance)', 'Inside', None, ['Swamp Palace Moat', 'Swamp Palace Exit']), create_dungeon_region('Swamp Palace (Entrance)', None, ['Swamp Palace Moat', 'Swamp Palace Exit']),
create_region('Swamp Palace (First Room)', 'Inside', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']), create_dungeon_region('Swamp Palace (First Room)', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']),
create_region('Swamp Palace (Starting Area)', 'Inside', ['Swamp Palace - Map Chest'], ['Swamp Palace (Center)']), create_dungeon_region('Swamp Palace (Starting Area)', ['Swamp Palace - Map Chest'], ['Swamp Palace (Center)']),
create_region('Swamp Palace (Center)', 'Inside', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest', create_dungeon_region('Swamp Palace (Center)', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest',
'Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest'], ['Swamp Palace (North)']), 'Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest'], ['Swamp Palace (North)']),
create_region('Swamp Palace (North)', 'Inside', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right', create_dungeon_region('Swamp Palace (North)', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right',
'Swamp Palace - Waterfall Room', 'Swamp Palace - Arrghus', 'Swamp Palace - Prize']), 'Swamp Palace - Waterfall Room', 'Swamp Palace - Arrghus', 'Swamp Palace - Prize']),
create_region('Thieves Town (Entrance)', 'Inside', ['Thieves\' Town - Big Key Chest', create_dungeon_region('Thieves Town (Entrance)', ['Thieves\' Town - Big Key Chest',
'Thieves\' Town - Map Chest', 'Thieves\' Town - Map Chest',
'Thieves\' Town - Compass Chest', 'Thieves\' Town - Compass Chest',
'Thieves\' Town - Ambush Chest'], ['Thieves Town Big Key Door', 'Thieves Town Exit']), 'Thieves\' Town - Ambush Chest'], ['Thieves Town Big Key Door', 'Thieves Town Exit']),
create_region('Thieves Town (Deep)', 'Inside', ['Thieves\' Town - Attic', create_dungeon_region('Thieves Town (Deep)', ['Thieves\' Town - Attic',
'Thieves\' Town - Big Chest', 'Thieves\' Town - Big Chest',
'Thieves\' Town - Blind\'s Cell'], ['Blind Fight']), 'Thieves\' Town - Blind\'s Cell'], ['Blind Fight']),
create_region('Blind Fight', 'Inside', ['Thieves Town - Blind', 'Thieves Town - Prize']), create_dungeon_region('Blind Fight', ['Thieves Town - Blind', 'Thieves Town - Prize']),
create_region('Skull Woods First Section', 'Inside', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']), create_dungeon_region('Skull Woods First Section', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']),
create_region('Skull Woods First Section (Right)', 'Inside', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), create_dungeon_region('Skull Woods First Section (Right)', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']),
create_region('Skull Woods First Section (Left)', 'Inside', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), create_dungeon_region('Skull Woods First Section (Left)', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']),
create_region('Skull Woods First Section (Top)', 'Inside', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), create_dungeon_region('Skull Woods First Section (Top)', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']),
create_region('Skull Woods Second Section (Drop)', 'Inside', None, ['Skull Woods Second Section (Drop)']), create_dungeon_region('Skull Woods Second Section (Drop)', None, ['Skull Woods Second Section (Drop)']),
create_region('Skull Woods Second Section', 'Inside', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), create_dungeon_region('Skull Woods Second Section', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']),
create_region('Skull Woods Final Section (Entrance)', 'Inside', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), create_dungeon_region('Skull Woods Final Section (Entrance)', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']),
create_region('Skull Woods Final Section (Mothula)', 'Inside', ['Skull Woods - Mothula', 'Skull Woods - Prize']), create_dungeon_region('Skull Woods Final Section (Mothula)', ['Skull Woods - Mothula', 'Skull Woods - Prize']),
create_region('Ice Palace (Entrance)', 'Inside', None, ['Ice Palace Entrance Room', 'Ice Palace Exit']), create_dungeon_region('Ice Palace (Entrance)', None, ['Ice Palace Entrance Room', 'Ice Palace Exit']),
create_region('Ice Palace (Main)', 'Inside', ['Ice Palace - Compass Chest', 'Ice Palace - Freezor Chest', create_dungeon_region('Ice Palace (Main)', ['Ice Palace - Compass Chest', 'Ice Palace - Freezor Chest',
'Ice Palace - Big Chest', 'Ice Palace - Iced T Room'], ['Ice Palace (East)', 'Ice Palace (Kholdstare)']), 'Ice Palace - Big Chest', 'Ice Palace - Iced T Room'], ['Ice Palace (East)', 'Ice Palace (Kholdstare)']),
create_region('Ice Palace (East)', 'Inside', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']), create_dungeon_region('Ice Palace (East)', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']),
create_region('Ice Palace (East Top)', 'Inside', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']), create_dungeon_region('Ice Palace (East Top)', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']),
create_region('Ice Palace (Kholdstare)', 'Inside', ['Ice Palace - Kholdstare', 'Ice Palace - Prize']), create_dungeon_region('Ice Palace (Kholdstare)', ['Ice Palace - Kholdstare', 'Ice Palace - Prize']),
create_region('Misery Mire (Entrance)', 'Inside', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']), create_dungeon_region('Misery Mire (Entrance)', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']),
create_region('Misery Mire (Main)', 'Inside', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby', create_dungeon_region('Misery Mire (Main)', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby',
'Misery Mire - Bridge Chest', 'Misery Mire - Spike Chest'], ['Misery Mire (West)', 'Misery Mire Big Key Door']), 'Misery Mire - Bridge Chest', 'Misery Mire - Spike Chest'], ['Misery Mire (West)', 'Misery Mire Big Key Door']),
create_region('Misery Mire (West)', 'Inside', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']), create_dungeon_region('Misery Mire (West)', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']),
create_region('Misery Mire (Final Area)', 'Inside', None, ['Misery Mire (Vitreous)']), create_dungeon_region('Misery Mire (Final Area)', None, ['Misery Mire (Vitreous)']),
create_region('Misery Mire (Vitreous)', 'Inside', ['Misery Mire - Vitreous', 'Misery Mire - Prize']), create_dungeon_region('Misery Mire (Vitreous)', ['Misery Mire - Vitreous', 'Misery Mire - Prize']),
create_region('Turtle Rock (Entrance)', 'Inside', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']), create_dungeon_region('Turtle Rock (Entrance)', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']),
create_region('Turtle Rock (First Section)', 'Inside', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', create_dungeon_region('Turtle Rock (First Section)', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left',
'Turtle Rock - Roller Room - Right'], ['Turtle Rock Pokey Room', 'Turtle Rock Entrance Gap Reverse']), 'Turtle Rock - Roller Room - Right'], ['Turtle Rock Pokey Room', 'Turtle Rock Entrance Gap Reverse']),
create_region('Turtle Rock (Chain Chomp Room)', 'Inside', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']), create_dungeon_region('Turtle Rock (Chain Chomp Room)', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']),
create_region('Turtle Rock (Second Section)', 'Inside', ['Turtle Rock - Big Key Chest'], ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door']), create_dungeon_region('Turtle Rock (Second Section)', ['Turtle Rock - Big Key Chest'], ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door']),
create_region('Turtle Rock (Big Chest)', 'Inside', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']), create_dungeon_region('Turtle Rock (Big Chest)', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']),
create_region('Turtle Rock (Crystaroller Room)', 'Inside', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']), create_dungeon_region('Turtle Rock (Crystaroller Room)', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']),
create_region('Turtle Rock (Dark Room)', 'Inside', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']), create_dungeon_region('Turtle Rock (Dark Room)', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']),
create_region('Turtle Rock (Eye Bridge)', 'Inside', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', create_dungeon_region('Turtle Rock (Eye Bridge)', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right',
'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'], 'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'],
['Turtle Rock Dark Room (South)', 'Turtle Rock (Trinexx)', 'Turtle Rock Isolated Ledge Exit']), ['Turtle Rock Dark Room (South)', 'Turtle Rock (Trinexx)', 'Turtle Rock Isolated Ledge Exit']),
create_region('Turtle Rock (Trinexx)', 'Inside', ['Turtle Rock - Trinexx', 'Turtle Rock - Prize']), create_dungeon_region('Turtle Rock (Trinexx)', ['Turtle Rock - Trinexx', 'Turtle Rock - Prize']),
create_region('Palace of Darkness (Entrance)', 'Inside', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']), create_dungeon_region('Palace of Darkness (Entrance)', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']),
create_region('Palace of Darkness (Center)', 'Inside', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'], create_dungeon_region('Palace of Darkness (Center)', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'],
['Palace of Darkness Big Key Chest Staircase', 'Palace of Darkness (North)', 'Palace of Darkness Big Key Door']), ['Palace of Darkness Big Key Chest Staircase', 'Palace of Darkness (North)', 'Palace of Darkness Big Key Door']),
create_region('Palace of Darkness (Big Key Chest)', 'Inside', ['Palace of Darkness - Big Key Chest']), create_dungeon_region('Palace of Darkness (Big Key Chest)', ['Palace of Darkness - Big Key Chest']),
create_region('Palace of Darkness (Bonk Section)', 'Inside', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']), create_dungeon_region('Palace of Darkness (Bonk Section)', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']),
create_region('Palace of Darkness (North)', 'Inside', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], create_dungeon_region('Palace of Darkness (North)', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'],
['Palace of Darkness Spike Statue Room Door', 'Palace of Darkness Maze Door']), ['Palace of Darkness Spike Statue Room Door', 'Palace of Darkness Maze Door']),
create_region('Palace of Darkness (Maze)', 'Inside', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']), create_dungeon_region('Palace of Darkness (Maze)', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']),
create_region('Palace of Darkness (Harmless Hellway)', 'Inside', ['Palace of Darkness - Harmless Hellway']), create_dungeon_region('Palace of Darkness (Harmless Hellway)', ['Palace of Darkness - Harmless Hellway']),
create_region('Palace of Darkness (Final Section)', 'Inside', ['Palace of Darkness - Helmasaur', 'Palace of Darkness - Prize']), create_dungeon_region('Palace of Darkness (Final Section)', ['Palace of Darkness - Helmasaur', 'Palace of Darkness - Prize']),
create_region('Ganons Tower (Entrance)', 'Inside', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right'], create_dungeon_region('Ganons Tower (Entrance)', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right'],
['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Ganons Tower Exit']), ['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Ganons Tower Exit']),
create_region('Ganons Tower (Tile Room)', 'Inside', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']), create_dungeon_region('Ganons Tower (Tile Room)', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']),
create_region('Ganons Tower (Compass Room)', 'Inside', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', create_dungeon_region('Ganons Tower (Compass Room)', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right',
'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right'], 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right'],
['Ganons Tower (Bottom) (East)']), ['Ganons Tower (Bottom) (East)']),
create_region('Ganons Tower (Hookshot Room)', 'Inside', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', create_dungeon_region('Ganons Tower (Hookshot Room)', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right',
'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'], 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'],
['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']), ['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']),
create_region('Ganons Tower (Map Room)', 'Inside', ['Ganons Tower - Map Chest']), create_dungeon_region('Ganons Tower (Map Room)', ['Ganons Tower - Map Chest']),
create_region('Ganons Tower (Firesnake Room)', 'Inside', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']), create_dungeon_region('Ganons Tower (Firesnake Room)', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']),
create_region('Ganons Tower (Teleport Room)', 'Inside', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', create_dungeon_region('Ganons Tower (Teleport Room)', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right',
'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'], 'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'],
['Ganons Tower (Bottom) (West)']), ['Ganons Tower (Bottom) (West)']),
create_region('Ganons Tower (Bottom)', 'Inside', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left', create_dungeon_region('Ganons Tower (Bottom)', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left',
'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']), 'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']),
create_region('Ganons Tower (Top)', 'Inside', None, ['Ganons Tower Torch Rooms']), create_dungeon_region('Ganons Tower (Top)', None, ['Ganons Tower Torch Rooms']),
create_region('Ganons Tower (Before Moldorm)', 'Inside', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', create_dungeon_region('Ganons Tower (Before Moldorm)', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
'Ganons Tower - Pre-Moldorm Chest'], ['Ganons Tower Moldorm Door']), 'Ganons Tower - Pre-Moldorm Chest'], ['Ganons Tower Moldorm Door']),
create_region('Ganons Tower (Moldorm)', 'Inside', None, ['Ganons Tower Moldorm Gap']), create_dungeon_region('Ganons Tower (Moldorm)', None, ['Ganons Tower Moldorm Gap']),
create_region('Agahnim 2', 'Inside', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None), create_dungeon_region('Agahnim 2', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None),
create_region('Pyramid', 'Inside', ['Ganon'], ['Ganon Drop']), create_cave_region('Pyramid', ['Ganon'], ['Ganon Drop']),
create_region('Bottom of Pyramid', 'Inside', None, ['Pyramid Exit']), create_cave_region('Bottom of Pyramid', None, ['Pyramid Exit']),
create_region('Pyramid Ledge', 'Dark', None, ['Pyramid Entrance', 'Pyramid Drop']) create_dw_region('Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop'])
] ]
world.intialize_regions() world.intialize_regions()
def create_lw_region(name, locations=None, exits=None):
return _create_region(name, RegionType.LightWorld, locations, exits)
def create_region(name, world='Inside', locations=None, exits=None): def create_dw_region(name, locations=None, exits=None):
ret = Region(name) return _create_region(name, RegionType.DarkWorld, locations, exits)
def create_cave_region(name, locations=None, exits=None):
return _create_region(name, RegionType.Cave, locations, exits)
def create_dungeon_region(name, locations=None, exits=None):
return _create_region(name, RegionType.Dungeon, locations, exits)
def _create_region(name, type, locations=None, exits=None):
ret = Region(name, type)
if locations is None: if locations is None:
locations = [] locations = []
if exits is None: if exits is None:
@ -287,22 +300,30 @@ def create_region(name, world='Inside', locations=None, exits=None):
ret.locations.append(Location(location, address, crystal, hint_text, ret)) ret.locations.append(Location(location, address, crystal, hint_text, ret))
return ret return ret
def mark_light_world_regions(world): def mark_light_world_regions(world):
# Note that in "inanity" shuffle this code may mark some dark world locations as being in light world. That is fine because this flag # cross world caves may have some sections marked as both in_light_world, and in_dark_work.
# is only used for bunny logic, and you start with a Moon pearl immediately availible in Insanity shuffle. # That is ok. the bunny logic will check for this case and incorporate special rules.
queue = collections.deque(region for region in world.regions if region.type == RegionType.LightWorld)
# Exclude entrances that represent connections from the light world to the dark world
excluded_entrances = set(['Top of Pyramid', 'Lake Hylia Central Island Teleporter', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter', 'Death Mountain Teleporter', 'East Death Mountain Teleporter', 'Turtle Rock Teleporter'])
starting_regions = ['Links House', 'Cave 45 Ledge', 'Graveyard Ledge', 'Mimic Cave Ledge', 'Death Mountain Floating Island (Light World)', 'Desert Ledge', 'Desert Ledge (Northeast)', 'Lake Hylia Island', 'Spectacle Rock', 'Death Mountain Return Ledge', 'Hyrule Castle Ledge','Maze Race Ledge']
queue = collections.deque([world.get_region(region) for region in starting_regions])
seen = set(queue) seen = set(queue)
while queue: while queue:
current = queue.popleft() current = queue.popleft()
current.is_light_world = True current.is_light_world = True
for exit in current.exits: for exit in current.exits:
if exit.name in excluded_entrances: if exit.connected_region.type == RegionType.DarkWorld:
# Don't venture into the dark world
continue
if exit.connected_region not in seen:
seen.add(exit.connected_region)
queue.append(exit.connected_region)
queue = collections.deque(region for region in world.regions if region.type == RegionType.DarkWorld)
seen = set(queue)
while queue:
current = queue.popleft()
current.is_dark_world = True
for exit in current.exits:
if exit.connected_region.type == RegionType.LightWorld:
# Don't venture into the light world
continue continue
if exit.connected_region not in seen: if exit.connected_region not in seen:
seen.add(exit.connected_region) seen.add(exit.connected_region)

62
Rom.py
View File

@ -15,7 +15,7 @@ from Items import ItemFactory
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '214e4b2a50cb65cd13a8194bc88cb030' RANDOMIZERBASEHASH = '4027d54ccf5c3713dacf7c0d4ef72d75'
class JsonRom(object): class JsonRom(object):
@ -297,13 +297,51 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
if world.keysanity: if world.keysanity:
rom.write_byte(0x155C9, random.choice([0x11, 0x16])) # Randomize GT music too in keysanity mode rom.write_byte(0x155C9, random.choice([0x11, 0x16])) # Randomize GT music too in keysanity mode
# patch entrances # patch entrance/exits/holess
for region in world.regions: for region in world.regions:
for exit in region.exits: for exit in region.exits:
if exit.target is not None: if exit.target is not None:
addresses = [exit.addresses] if isinstance(exit.addresses, int) else exit.addresses if isinstance(exit.addresses, tuple):
for address in addresses: offset = exit.target
rom.write_byte(address, exit.target) 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 = exit.addresses
#room id is deliberately not written
rom.write_byte(0x15B8C + offset, ow_area)
rom.write_int16_to_rom(0x15BDB + 2 * offset, vram_loc)
rom.write_int16_to_rom(0x15C79 + 2 * offset, scroll_y)
rom.write_int16_to_rom(0x15D17 + 2 * offset, scroll_x)
# for positioning fixups we abuse the roomid as a way of identifying which exit data we are appling
# Thanks to Zarby89 for originally finding these values
# todo fix screen scrolling
if room_id == 0x0059 and world.fix_skullwoods_exit:
rom.write_int16_to_rom(0x15DB5 + 2 * offset, 0x00F8)
elif room_id == 0x004a and world.fix_palaceofdarkness_exit:
rom.write_int16_to_rom(0x15DB5 + 2 * offset, 0x0640)
elif room_id == 0x00d6 and world.fix_trock_exit:
rom.write_int16_to_rom(0x15DB5 + 2 * offset, 0x0134)
elif room_id == 0x000c and world.fix_gtower_exit: # fix ganons tower exit point
rom.write_byte(0x15DB5 + 2 * offset, 0x00A4)
else:
rom.write_int16_to_rom(0x15DB5 + 2 * offset, link_y)
rom.write_int16_to_rom(0x15E53 + 2 * offset, link_x)
rom.write_int16_to_rom(0x15EF1 + 2 * offset, camera_y)
rom.write_int16_to_rom(0x15F8F + 2 * offset, camera_x)
rom.write_byte(0x1602D + offset, unknown_1)
rom.write_byte(0x1607C + offset, unknown_2)
rom.write_int16_to_rom(0x160CB + 2 * offset, door_1)
rom.write_int16_to_rom(0x16169 + 2 * offset, door_2)
elif isinstance(exit.addresses, list):
# is hole
for address in exit.addresses:
rom.write_byte(address, exit.target)
else:
# patch door table
rom.write_byte(0xDBB73 + exit.addresses, exit.target)
# patch medallion requirements # patch medallion requirements
if world.required_medallions[0] == 'Bombos': if world.required_medallions[0] == 'Bombos':
@ -721,20 +759,6 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
rom.write_byte(0xFED31, 0x2A) # preopen bombable exit rom.write_byte(0xFED31, 0x2A) # preopen bombable exit
rom.write_byte(0xFEE41, 0x2A) # preopen bombable exit rom.write_byte(0xFEE41, 0x2A) # preopen bombable exit
# Thanks to Zarby89 for finding these values
# fix skull woods exit point
rom.write_byte(0x15E0D, 0xF8 if world.fix_skullwoods_exit else 0xB8)
# fix palace of darkness exit point
rom.write_byte(0x15E03, 0x40 if world.fix_palaceofdarkness_exit else 0x28)
# fix turtle rock exit point
rom.write_byte(0x15E1D, 0x34 if world.fix_trock_exit else 0x28)
# fix ganons tower exit point
rom.write_byte(0x15E25, 0xA4 if world.fix_gtower_exit else 0x28)
# todo fix screen scrolling
write_strings(rom, world) write_strings(rom, world)
# set rom name # set rom name

234
Rules.py
View File

@ -1,3 +1,4 @@
import collections
import logging import logging
@ -86,7 +87,8 @@ def global_rules(world):
world.get_region('Old Man House').can_reach = lambda state: state.can_reach('Old Man', 'Location') or old_rule(state) world.get_region('Old Man House').can_reach = lambda state: state.can_reach('Old Man', 'Location') or old_rule(state)
# overworld requirements # overworld requirements
set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Pearl() and state.has_Mirror() and state.can_reach('West Dark World')))) set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Pearl() and state.has_Mirror() and state.can_reach('West Dark World', 'Region'))))
# Caution: If king's grave is releaxed at all to account for reaching it via a two way cave's exit in insanity mode, then the bomb shop logic will need to be updated (that would involve create a small ledge-like Region for it)
set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots()) set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots())
set_rule(world.get_location('Sunken Treasure'), lambda state: state.can_reach('Dam')) set_rule(world.get_location('Sunken Treasure'), lambda state: state.can_reach('Dam'))
set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer')) set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer'))
@ -96,7 +98,8 @@ def global_rules(world):
set_rule(world.get_entrance('Sanctuary Grave'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('Sanctuary Grave'), lambda state: state.can_lift_rocks())
set_rule(world.get_entrance('20 Rupee Cave'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('20 Rupee Cave'), lambda state: state.can_lift_rocks())
set_rule(world.get_entrance('50 Rupee Cave'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('50 Rupee Cave'), lambda state: state.can_lift_rocks())
set_rule(world.get_entrance('Old Man Cave (West)'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('Death Mountain Entrance Rock'), lambda state: state.can_lift_rocks())
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Flute Spot 1'), lambda state: state.has('Ocarina')) set_rule(world.get_entrance('Flute Spot 1'), lambda state: state.has('Ocarina'))
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter'), lambda state: state.can_lift_heavy_rocks()) set_rule(world.get_entrance('Lake Hylia Central Island Teleporter'), lambda state: state.can_lift_heavy_rocks())
set_rule(world.get_entrance('Dark Desert Teleporter'), lambda state: state.has('Ocarina') and state.can_lift_heavy_rocks()) set_rule(world.get_entrance('Dark Desert Teleporter'), lambda state: state.has('Ocarina') and state.can_lift_heavy_rocks())
@ -159,7 +162,7 @@ def global_rules(world):
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up? set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up?
set_rule(world.get_entrance('Graveyard Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.has_Mirror()) set_rule(world.get_entrance('Graveyard Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.has_Mirror())
set_rule(world.get_entrance('Bumper Cave (Bottom)'), lambda state: state.has_Pearl() and state.can_lift_rocks()) set_rule(world.get_entrance('Bumper Cave Entrance Rock'), lambda state: state.has_Pearl() and state.can_lift_rocks())
set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has_Mirror()) set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has_Mirror())
set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has('Hammer')) set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has('Hammer'))
@ -566,14 +569,26 @@ def set_big_bomb_rules(world):
'Dam', 'Dam',
'Lumberjack House', 'Lumberjack House',
'Lake Hylia Fortune Teller', 'Lake Hylia Fortune Teller',
'Kakariko Gamble Game'] 'Eastern Palace'
'Kakariko Gamble Game',
'Kakariko Well Cave',
'Bat Cave Cave',
'Elder House (East)',
'Elder House (West)',
'North Fairy Cave',
'Lost Woods Hideout Stump',
'Lumberjack Tree Cave',
'Two Brothers House (East)',
'Sanctuary',
'Hyrule Castle Entrance (South)',
'Hyrule Castle Secret Entrance Stairs']
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy', LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
'Dark Lake Hylia Ledge Spike Cave', 'Dark Lake Hylia Ledge Spike Cave',
'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Hint',
'Mire Shed', 'Mire Shed',
'Dark Desert Hint', 'Dark Desert Hint',
'Dark Desert Fairy', 'Dark Desert Fairy',
'Checkerboard Cave'] 'Misery Mire']
Northern_DW_entrances = ['Brewery', Northern_DW_entrances = ['Brewery',
'C-Shaped House', 'C-Shaped House',
'Chest Game', 'Chest Game',
@ -583,65 +598,154 @@ def set_big_bomb_rules(world):
'Fortune Teller (Dark)', 'Fortune Teller (Dark)',
'Dark World Shop', 'Dark World Shop',
'Dark World Lumberjack Shop', 'Dark World Lumberjack Shop',
'Graveyard Cave'] 'Thieves Town',
'Skull Woods First Section Door',
'Skull Woods Second Section Door (East)']
Southern_DW_entrances = ['Hype Cave', Southern_DW_entrances = ['Hype Cave',
'Bonk Fairy (Dark)', 'Bonk Fairy (Dark)',
'Archery Game', 'Archery Game',
'Big Bomb Shop', 'Big Bomb Shop',
'Dark Lake Hylia Shop', 'Dark Lake Hylia Shop',
'Cave 45'] 'Swamp Palace']
Isolated_DW_entrances = ['Spike Cave', Isolated_DW_entrances = ['Spike Cave',
'Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)',
'Dark Death Mountain Fairy', 'Dark Death Mountain Fairy',
'Mimic Cave'] 'Mimic Cave',
'Skull Woods Second Section Door (West)'
'Skull Woods Final Section',
'Ice Palace',
'Turtle Rock',
'Dark Death Mountain Ledge (West)',
'Dark Death Mountain Ledge (East)',
'Bumper Cave (Top)',
'Superbunny Cave (Top)',
'Superbunny Cave (Bottom)',
'Hookshot Cave',
'Ganons Tower']
Isolated_LW_entrances = ['Capacity Upgrade', Isolated_LW_entrances = ['Capacity Upgrade',
'Hookshot Fairy'] 'Hookshot Fairy',
'Tower of Hera',
'Old Man Cave (East)',
'Old Man House (Bottom)',
'Old Man House (Top)',
'Death Mountain Return Cave (East)',
'Death Mountain Return Cave (West)',
'Spectacle Rock Cave Peak',
'Spectacle Rock Cave',
'Spectacle Rock Cave (Bottom)',
'Paradox Cave (Bottom)',
'Paradox Cave (Middle)',
'Paradox Cave (Top)',
'Fairy Ascension Cave (Bottom)',
'Fairy Ascension Cave (Top)',
'Spiral Cave',
'Spiral Cave (Bottom)']
Mirror_from_SDW_entrances = ['Two Brothers House (West)',
'Cave 45']
Castle_ledge_entrances = ['Hyrule Castle Entrance (West)',
'Hyrule Castle Entrance (East)',
'Agahnims Tower']
Desert_mirrorable_ledge_entrances = ['Desert Palace Entrance (West)',
'Desert Palace Entrance (North)',
'Desert Palace Entrance (South)',
'Checkerboard Cave',]
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('East Dark World', 'Region') and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6')) set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('East Dark World', 'Region') and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
#crossing peg bridge starting from the southern dark world
def cross_peg_bridge(state):
return state.has('Hammer') and state.has_Pearl()
# returning via the eastern and southern teleporters needs the same items, so we use the southern teleporter for out routing.
# crossing preg bridge already requires hammer so we just add the gloves to the requirement
def southern_teleporter(state):
return state.can_lift_rocks() and cross_peg_bridge(state)
# the basic routes assume you can reach eastern light world with the bomb.
# you can then use the southern teleporter, or (if you have beaten Aga1) the hyrule castle gate warp
def basic_routes(state):
return southern_teleporter(state) or state.can_reach('Top of Pyramid', 'Entrance')
# Key for below abbreviations:
# P = pearl
# A = Aga1
# H = hammer
# M = Mirror
# G = Glove
if bombshop_entrance.name in Normal_LW_entrances: if bombshop_entrance.name in Normal_LW_entrances:
#1. Enter via gate: Needs Aga1 #1. basic routes
#2. south hyrule teleporter and cross peg bridge: Hammer and moon pearl #2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
#3. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror # -> M or BR
# -> A or (H and P)) or (M) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: basic_routes(state) or state.has_Mirror())
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or state.has_Mirror())
elif bombshop_entrance.name in LW_walkable_entrances: elif bombshop_entrance.name in LW_walkable_entrances:
#1. Mirror then gate: Needs mirror and Aga1 #1. Mirror then basic routes
#2. Mirror then go to south hyrule teleporter and cross peg bridge: Needs Mirror and Hammer and moon pearl # -> M and BR
# -> M and (A or (H and P)) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and basic_routes(state))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
elif bombshop_entrance.name in Northern_DW_entrances: elif bombshop_entrance.name in Northern_DW_entrances:
#1. Mirror and enter via gate: Need mirror and Aga1 #1. Mirror and basic routes
#2. Mirror and enter via south hyrule teleporter: Need mirror and hammer and moon pearl #2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
# -> (Mitts and CPB) or (M and BR)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and cross_peg_bridge(state)) or (state.has_Mirror() and basic_routes(state)))
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
#1. Mirror and Lift rock and basic_routes
#2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case)
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl #3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
# -> (Mitts and P and H) or (M and (A or (H and P))) # -> (Mitts and CPB) or (((G or Flute) and M) and BR))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has_Pearl() and state.has('Hammer')) or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and cross_peg_bridge(state)) or (((state.can_lift_rocks() or state.has('Ocarina')) and state.has_Mirror()) and basic_routes(state)))
elif bombshop_entrance.name in Southern_DW_entrances: elif bombshop_entrance.name in Southern_DW_entrances:
#1. Mirror and enter via gate: Need mirror and Aga1 #1. Mirror and enter via gate: Need mirror and Aga1
#2. cross peg bridge: Need hammer and moon pearl #2. cross peg bridge: Need hammer and moon pearl
# -> (H and P) or (M and A) # -> CPB or (M and A)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Hammer') and state.has_Pearl()) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance'))) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: cross_peg_bridge(state) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
elif bombshop_entrance.name in Isolated_DW_entrances: elif bombshop_entrance.name in Isolated_DW_entrances:
# 1. mirror then flute then enter via gate: Needs mirror and flute and Aga 1 # 1. mirror then flute then basic routes
# 2. mirror then flute then enter via south hyrule teleporter: Needs mirror and Flute and hammer and moon pearl # -> M and Flute and BR
# -> M and Flute and (A or (H and P)) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and basic_routes(state))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
elif bombshop_entrance.name in Isolated_LW_entrances: elif bombshop_entrance.name in Isolated_LW_entrances:
# 1. flute then enter via gate: Needs flute and Aga 1 # 1. flute then basic routes
# 2. flute then enter via south hyrule teleporter: Needs Flute and hammer and moon pearl
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations. # Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
# -> Flute and (A or (H and P)) # -> Flute and BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()))) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and basic_routes(state))
elif bombshop_entrance.name in Castle_ledge_entrances:
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
# 2. flute then basic routes
# -> M or (Flute and BR)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() or (state.has('Ocarina') and basic_routes(state)))
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances:
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
# 2. flute then basic routes
# -> (Mire access and M) or Flute) and BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: ((state.can_reach('Dark Desert', 'Region') and state.has_Mirror()) or state.has('Ocarina')) and basic_routes(state))
elif bombshop_entrance.name == 'Old Man Cave (West)':
# 1. Lift rock then basic_routes
# 2. flute then basic_routes
# -> (Flute or G) and BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Ocarina') or state.can_lift_rocks()) and basic_routes(state))
elif bombshop_entrance.name == 'Graveyard Cave':
# 1. flute then basic routes
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
# -> (Flute or (M and P and West Dark World access) and BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Ocarina') or (state.can_reach('West Dark World', 'Region') and state.has_Pearl() and state.has_Mirror())) and basic_routes(state))
elif bombshop_entrance.name in Mirror_from_SDW_entrances:
# 1. flute then basic routes
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
# -> (Flute or (M and South Dark World access) and BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Ocarina') or (state.can_reach('South Dark World', 'Region') and state.has_Mirror())) and basic_routes(state))
elif bombshop_entrance.name == 'Dark World Potion Shop': elif bombshop_entrance.name == 'Dark World Potion Shop':
# 1. walk down by lifting rock: needs gloves and pearl` # 1. walk down by lifting rock: needs gloves and pearl`
# 2. walk down by hammering peg: needs hammer and pearl # 2. walk down by hammering peg: needs hammer and pearl
# 3. mirror and eneter via gate: needs Mirror and Aga1 # 3. mirror and basic routes
# (south hyrule teleporter would be redundant with #2) # -> (P and (H or Gloves)) or (M and BR)
# -> P and (H or H) or (M and A) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) or (state.has_Mirror() and basic_routes(state)))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
elif bombshop_entrance.name == 'Kings Grave': elif bombshop_entrance.name == 'Kings Grave':
# same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts # same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot) # (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
# -> A or (H and P) or (M and Mitts) # -> (M and Mitts) or BR
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or (state.can_lift_heavy_rocks() and state.has_Mirror())) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has_Mirror()) or basic_routes(state))
#TODO: add logic for reaching the following locations via an exit from a multi-entrace cave in mixed cave insianity: 'Desert Palace Entrance (East)','Turtle Rock Isolated Ledge Entrance','Hookshot Cave Back Entrance'
def set_bunny_rules(world): def set_bunny_rules(world):
@ -652,25 +756,65 @@ def set_bunny_rules(world):
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge'] bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge']
if not world.get_region('Dam').is_light_world: if world.get_region('Dam').is_dark_world:
# if Dam is is dark world, then it is required to have the pearl to get the sunken item # if Dam is is dark world, then it is required to have the pearl to get the sunken item
add_rule(world.get_location('Sunken Treasure'), lambda state: state.has_Pearl()) add_rule(world.get_location('Sunken Treasure'), lambda state: state.has_Pearl())
# similarly we need perl to get across the swamp palace moat # similarly we need perl to get across the swamp palace moat
add_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has_Pearl()) add_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has_Pearl())
# Add pearl requirements for bunny-impassible caves if they occur in the dark world def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path)
def options_to_access_rule(options):
return lambda state: any(rule(state) for rule in options)
def get_rule_to_add(region):
if not region.is_light_world:
return lambda state: state.has_Pearl()
# in this case we are mixed region.
# we collect possible options.
# The base option is having the moon pearl
possible_options = [lambda state: state.has_Pearl()]
# We will search entrances recursively until we find
# one that leads to an exclusively light world region
# for each such entrance a new option ios aded that consist of:
# a) being able to reach it, and
# b) being able to access all entrances from there to `region`
seen = set([region])
queue = collections.deque([(region, [])])
while queue:
(current, path) = queue.popleft()
for entrance in current.entrances:
new_region = entrance.parent_region
if new_region in seen:
continue
new_path = path + [entrance.access_rule]
seen.add(new_region)
if not new_region.is_light_world:
continue # we don't care about pure dark world entrances
if new_region.is_dark_world:
queue.append((new_region, new_path))
else:
# we have reached pure light world, so we have a new possible option
possible_options.append(path_to_access_rule(new_path, entrance))
return options_to_access_rule(possible_options)
# Add requirements for bunny-impassible caves if they occur in the dark world
for region in [world.get_region(name) for name in bunny_impassable_caves]: for region in [world.get_region(name) for name in bunny_impassable_caves]:
if region.is_light_world: if not region.is_dark_world:
continue continue
rule = get_rule_to_add(region)
for exit in region.exits: for exit in region.exits:
add_rule(exit, lambda state: state.has_Pearl()) add_rule(exit, rule)
# Add a moon pearl requirement for all locations that are actually in the dark world, except those available to the bunny # Add requirements for all locations that are actually in the dark world, except those available to the bunny
for location in world.get_locations(): for location in world.get_locations():
if not location.parent_region.is_light_world: if location.parent_region.is_dark_world:
if location.name in bunny_accessible_locations: if location.name in bunny_accessible_locations:
continue continue
add_rule(location, lambda state: state.has_Pearl()) add_rule(location, get_rule_to_add(location.parent_region))

File diff suppressed because one or more lines are too long