Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2026-01-08 16:23:08 -06:00
7 changed files with 341 additions and 243 deletions

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.6.1.9
- Fixed follower shuffle placement errors
- Fixed pseudoboots ability to open Kings Tomb
- Implemented better accurate coordinates on map check locations
- Fixed janky icons on zoomed-in map check screen
## 0.6.1.8 ## 0.6.1.8
- Fixed follower placement and logic - Fixed follower placement and logic
- Fixed error with HC Courtyard Tree Pull - Fixed error with HC Courtyard Tree Pull

View File

@@ -1054,6 +1054,8 @@ def balance_money_progression(world):
return [loc for loc in locations if sphere_state.can_reach(loc) and sphere_state.not_flooding_a_key(sphere_state.world, loc)] return [loc for loc in locations if sphere_state.can_reach(loc) and sphere_state.not_flooding_a_key(sphere_state.world, loc)]
def interesting_item(location, item, world, player): def interesting_item(location, item, world, player):
if location.event or location.locked:
return True
if item.advancement: if item.advancement:
return True return True
if item.type is not None or item.name.startswith('Rupee'): if item.type is not None or item.name.startswith('Rupee'):

View File

@@ -1695,7 +1695,6 @@ def set_event_item(world, player, location_name, item_name=None):
def shuffle_event_items(world, player): def shuffle_event_items(world, player):
if world.shuffle_followers[player]: if world.shuffle_followers[player]:
all_state = world.get_all_state(keys=True)
available_quests = follower_quests.copy() available_quests = follower_quests.copy()
available_pickups = [quests[0] for quests in available_quests.values()] available_pickups = [quests[0] for quests in available_quests.values()]
@@ -1716,22 +1715,39 @@ def shuffle_event_items(world, player):
available_pickups.remove(zelda_pickup) available_pickups.remove(zelda_pickup)
set_event_item(world, player, zelda_dropoff, zelda_pickup) set_event_item(world, player, zelda_dropoff, zelda_pickup)
# randomize the follower pickups, but ensure that the last items are the unrestrictive ones
unrestrictive_pickups = [p for p in ['Zelda Herself', 'Sign Vandalized'] if p in available_pickups]
restrictive_pickups = [p for p in available_pickups if p not in unrestrictive_pickups]
random.shuffle(restrictive_pickups)
random.shuffle(unrestrictive_pickups)
available_pickups = restrictive_pickups + unrestrictive_pickups
pickup_items = ItemFactory(available_pickups, player)
follower_locations = [world.get_location(loc_name, player) for loc_name in available_quests.keys()] follower_locations = [world.get_location(loc_name, player) for loc_name in available_quests.keys()]
random.shuffle(follower_locations)
fill_restrictive(world, all_state, follower_locations, pickup_items, single_player_placement=True) attempts = 10
for loc_name in available_quests.keys(): for attempt in range(attempts):
loc = world.get_location(loc_name, player) try:
if loc.item: all_state = world.get_all_state(keys=True)
set_event_item(world, player, loc_name) if world.prizeshuffle[player] != 'wild':
from Items import prize_item_table
prizes = ItemFactory(list(prize_item_table.keys()), player)
for prize in prizes:
all_state.collect(prize, True)
# randomize the follower pickups, but ensure that the last items are the unrestrictive ones
unrestrictive_pickups = ItemFactory([p for p in ['Zelda Herself', 'Sign Vandalized'] if p in available_pickups], player)
restrictive_pickups = ItemFactory([p for p in available_pickups if p not in unrestrictive_pickups], player)
random.shuffle(restrictive_pickups)
random.shuffle(unrestrictive_pickups)
pickup_items = unrestrictive_pickups + restrictive_pickups
random.shuffle(follower_locations)
fill_restrictive(world, all_state, follower_locations, pickup_items, single_player_placement=True)
for loc_name in available_quests.keys():
loc = world.get_location(loc_name, player)
if loc.item:
set_event_item(world, player, loc_name)
except FillError as e:
logging.getLogger('').info("Failed to place followers (%s). Will retry %s more times", e, attempts - attempt - 1)
for loc in follower_locations:
loc.item = None
continue
break
else:
raise FillError(f'Unable to place followers: {", ".join(list(map(lambda d: d.hint_text, follower_locations)))}')
def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool): def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool):

View File

@@ -8,7 +8,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
from OverworldGlitchRules import create_owg_connections from OverworldGlitchRules import create_owg_connections
from Utils import bidict from Utils import bidict
version_number = '0.6.1.8' version_number = '0.6.1.9'
# branch indicator is intentionally different across branches # branch indicator is intentionally different across branches
version_branch = '' version_branch = ''
@@ -2540,46 +2540,107 @@ isolated_regions = [
flute_data = { flute_data = {
#OWID LW Region DW Region Slot VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX AltVRAM AltBGY AltBGX AltCamY AltCamX AltUnk1 AltUnk2 AltIconY AltIconX #OWID LW Region DW Region Slot VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX AltVRAM AltBGY AltBGX AltCamY AltCamX AltUnk1 AltUnk2 AltIconY AltIconX
0x00: (['Lost Woods East Area', 'Skull Woods Forest'], 0x09, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290), 0x00: (['Lost Woods East Area', 'Skull Woods Forest'], 0x09, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290),
0x02: (['Lumberjack Area', 'Dark Lumberjack Area'], 0x02, 0x059c, 0x00d6, 0x04e6, 0x0138, 0x0558, 0x0143, 0x0563, 0xfffa, 0xfffa, 0x0138, 0x0550), 0x02: (['Lumberjack Area', 'Dark Lumberjack Area'], 0x02, 0x059c, 0x00d6, 0x04e6, 0x0138, 0x0558, 0x0143, 0x0563, 0xfffa, 0xfffa, 0x01d8, 0x0518),
0x03: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Top)'], 0x0b, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x035b, 0x0680, 0x0118, 0x0860, 0x05c0, 0x00b8, 0x07ec, 0x0127, 0x086b, 0xfff8, 0x0004, 0x0148, 0x0850), 0x03: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Top)'], 0x0b, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x03bb, 0x0680, 0x0118, 0x0860, 0x05c0, 0x00b8, 0x07ec, 0x0127, 0x086b, 0xfff8, 0x0004, 0x0148, 0x0850),
0x05: (['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], 0x0e, 0x1860, 0x031e, 0x0d00, 0x0388, 0x0da8, 0x038d, 0x0d7d, 0x0000, 0x0000, 0x0388, 0x0da8), 0x05: (['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], 0x0e, 0x1860, 0x031e, 0x0d00, 0x0388, 0x0da8, 0x038d, 0x0d7d, 0x0000, 0x0000, 0x03c8, 0x0d98),
0x07: (['Death Mountain TR Pegs Area', 'Turtle Rock Area'], 0x07, 0x0804, 0x0102, 0x0e1a, 0x0160, 0x0e90, 0x016f, 0x0e97, 0xfffe, 0x0006, 0x0160, 0x0f20), 0x07: (['Death Mountain TR Pegs Area', 'Turtle Rock Area'], 0x07, 0x0804, 0x0102, 0x0e1a, 0x0160, 0x0e90, 0x016f, 0x0e97, 0xfffe, 0x0006, 0x0150, 0x0ea0),
0x0a: (['Mountain Pass Area', 'Bumper Cave Area'], 0x0a, 0x0180, 0x0220, 0x0406, 0x0280, 0x0488, 0x028f, 0x0493, 0x0000, 0xfffa, 0x0280, 0x0488), 0x0a: (['Mountain Pass Area', 'Bumper Cave Area'], 0x0a, 0x0180, 0x0220, 0x0406, 0x0280, 0x0488, 0x028f, 0x0493, 0x0000, 0xfffa, 0x0390, 0x04d8),
0x0f: (['Zora Waterfall Area', 'Catfish Area'], 0x0f, 0x0316, 0x025c, 0x0eb2, 0x02c0, 0x0f28, 0x02cb, 0x0f2f, 0x0002, 0xfffe, 0x02d0, 0x0f38), 0x0f: (['Zora Waterfall Area', 'Catfish Area'], 0x0f, 0x0316, 0x025c, 0x0eb2, 0x02c0, 0x0f28, 0x02cb, 0x0f2f, 0x0002, 0xfffe, 0x0360, 0x0f58),
0x10: (['Lost Woods Pass West Area', 'Skull Woods Pass West Area'], 0x10, 0x0080, 0x0400, 0x0000, 0x0448, 0x0058, 0x046f, 0x0085, 0x0000, 0x0000, 0x0448, 0x0058), 0x10: (['Lost Woods Pass West Area', 'Skull Woods Pass West Area'], 0x10, 0x0080, 0x0400, 0x0000, 0x0448, 0x0058, 0x046f, 0x0085, 0x0000, 0x0000, 0x04f8, 0x0088),
0x11: (['Kakariko Fortune Area', 'Dark Fortune Area'], 0x11, 0x0912, 0x051e, 0x0292, 0x0588, 0x0318, 0x058d, 0x031f, 0x0000, 0xfffe, 0x0588, 0x0318), 0x11: (['Kakariko Fortune Area', 'Dark Fortune Area'], 0x11, 0x0912, 0x051e, 0x0292, 0x0588, 0x0318, 0x058d, 0x031f, 0x0000, 0xfffe, 0x05f8, 0x0318),
0x12: (['Kakariko Pond Area', 'Outcast Pond Area'], 0x12, 0x0890, 0x051a, 0x0476, 0x0578, 0x04f8, 0x0587, 0x0503, 0xfff6, 0x000a, 0x0578, 0x04f8), 0x12: (['Kakariko Pond Area', 'Outcast Pond Area'], 0x12, 0x0890, 0x051a, 0x0476, 0x0578, 0x04f8, 0x0587, 0x0503, 0xfff6, 0x000a, 0x05b8, 0x04f8),
0x13: (['Sanctuary Area', 'Dark Chapel Area'], 0x13, 0x051c, 0x04aa, 0x06de, 0x0508, 0x0758, 0x0517, 0x0763, 0xfff6, 0x0002, 0x0508, 0x0758), 0x13: (['Sanctuary Area', 'Dark Chapel Area'], 0x13, 0x051c, 0x04aa, 0x06de, 0x0508, 0x0758, 0x0517, 0x0763, 0xfff6, 0x0002, 0x05b8, 0x0738),
0x14: (['Graveyard Area', 'Dark Graveyard Area'], 0x14, 0x089c, 0x051e, 0x08e6, 0x0580, 0x0958, 0x058b, 0x0963, 0x0000, 0xfffa, 0x0580, 0x0928, 0x0580, 0x0948), 0x14: (['Graveyard Area', 'Dark Graveyard Area'], 0x14, 0x089c, 0x051e, 0x08e6, 0x0580, 0x0958, 0x058b, 0x0963, 0x0000, 0xfffa, 0x05f0, 0x0918, 0x0580, 0x0948),
0x15: (['River Bend East Bank', 'Qirn Jump East Bank'], 0x15, 0x041a, 0x0486, 0x0ad2, 0x04e8, 0x0b48, 0x04f3, 0x0b4f, 0x0008, 0xfffe, 0x04f8, 0x0b60), 0x15: (['River Bend East Bank', 'Qirn Jump East Bank'], 0x15, 0x041a, 0x0486, 0x0ad2, 0x04e8, 0x0b48, 0x04f3, 0x0b4f, 0x0008, 0xfffe, 0x0548, 0x0b78),
0x16: (['Potion Shop Area', 'Dark Witch Area'], 0x16, 0x0888, 0x0516, 0x0c4e, 0x0578, 0x0cc8, 0x0583, 0x0cd3, 0xfffa, 0xfff2, 0x0598, 0x0ccf), 0x16: (['Potion Shop Area', 'Dark Witch Area'], 0x16, 0x0888, 0x0516, 0x0c4e, 0x0578, 0x0cc8, 0x0583, 0x0cd3, 0xfffa, 0xfff2, 0x05e8, 0x0c9f),
0x17: (['Zora Approach Ledge', 'Catfish Approach Ledge'], 0x17, 0x039e, 0x047e, 0x0ef2, 0x04e0, 0x0f68, 0x04eb, 0x0f6f, 0x0000, 0xfffe, 0x04e0, 0x0f68), 0x17: (['Zora Approach Ledge', 'Catfish Approach Ledge'], 0x17, 0x039e, 0x047e, 0x0ef2, 0x04e0, 0x0f68, 0x04eb, 0x0f6f, 0x0000, 0xfffe, 0x0580, 0x0f48),
0x18: (['Kakariko Village', 'Village of Outcasts'], 0x18, 0x0b30, 0x0759, 0x017e, 0x07b7, 0x0200, 0x07c6, 0x020b, 0x0007, 0x0002, 0x07c0, 0x0210, 0x07c8, 0x01f8), 0x18: (['Kakariko Village', 'Village of Outcasts'], 0x18, 0x0b30, 0x0759, 0x017e, 0x07b7, 0x0200, 0x07c6, 0x020b, 0x0007, 0x0002, 0x0830, 0x0240, 0x07c8, 0x01f8),
0x1a: (['Forgotten Forest Area', 'Shield Shop Fence'], 0x1a, 0x081a, 0x070f, 0x04d2, 0x0770, 0x0548, 0x077c, 0x054f, 0xffff, 0xfffe, 0x0770, 0x0548), 0x1a: (['Forgotten Forest Area', 'Shield Shop Fence'], 0x1a, 0x081a, 0x070f, 0x04d2, 0x0770, 0x0548, 0x077c, 0x054f, 0xffff, 0xfffe, 0x0770, 0x0518),
0x1b: (['Hyrule Castle Courtyard', 'Pyramid Area'], 0x1b, 0x0c30, 0x077a, 0x0786, 0x07d8, 0x07f8, 0x07e7, 0x0803, 0x0006, 0xfffa, 0x07d8, 0x07f8), 0x1b: (['Hyrule Castle Courtyard', 'Pyramid Area'], 0x1b, 0x0c30, 0x077a, 0x0786, 0x07d8, 0x07f8, 0x07e7, 0x0803, 0x0006, 0xfffa, 0x07f8, 0x07f8),
0x1d: (['Wooden Bridge Area', 'Broken Bridge Northeast'], 0x1d, 0x0602, 0x06c2, 0x0a0e, 0x0720, 0x0a80, 0x072f, 0x0a8b, 0xfffe, 0x0002, 0x0720, 0x0a80), 0x1d: (['Wooden Bridge Area', 'Broken Bridge Northeast'], 0x1d, 0x0602, 0x06c2, 0x0a0e, 0x0720, 0x0a80, 0x072f, 0x0a8b, 0xfffe, 0x0002, 0x0750, 0x0a70),
0x1e: (['Eastern Palace Area', 'Palace of Darkness Area'], 0x26, 0x1802, 0x091e, 0x0c0e, 0x09c0, 0x0c80, 0x098b, 0x0c8b, 0x0000, 0x0002, 0x09c0, 0x0c80), 0x1e: (['Eastern Palace Area', 'Palace of Darkness Area'], 0x26, 0x1802, 0x091e, 0x0c0e, 0x09c0, 0x0c80, 0x098b, 0x0c8b, 0x0000, 0x0002, 0x09a0, 0x0cb0),
0x22: (['Blacksmith Area', 'Hammer Pegs Area'], 0x22, 0x058c, 0x08aa, 0x0462, 0x0908, 0x04d8, 0x0917, 0x04df, 0x0006, 0xfffe, 0x0908, 0x04d8), 0x22: (['Blacksmith Area', 'Hammer Pegs Area'], 0x22, 0x058c, 0x08aa, 0x0462, 0x0908, 0x04d8, 0x0917, 0x04df, 0x0006, 0xfffe, 0x0978, 0x04e8),
0x25: (['Sand Dunes Area', 'Dark Dunes Area'], 0x25, 0x030e, 0x085a, 0x0a76, 0x08b8, 0x0ae8, 0x08c7, 0x0af3, 0x0006, 0xfffa, 0x08b8, 0x0b08), 0x25: (['Sand Dunes Area', 'Dark Dunes Area'], 0x25, 0x030e, 0x085a, 0x0a76, 0x08b8, 0x0ae8, 0x08c7, 0x0af3, 0x0006, 0xfffa, 0x0918, 0x0b18),
0x28: (['Maze Race Area', 'Dig Game Area'], 0x28, 0x0908, 0x0b1e, 0x003a, 0x0b88, 0x00b8, 0x0b8d, 0x00bf, 0x0000, 0x0006, 0x0b88, 0x00b8), 0x28: (['Maze Race Area', 'Dig Game Area'], 0x28, 0x0908, 0x0b1e, 0x003a, 0x0b88, 0x00b8, 0x0b8d, 0x00bf, 0x0000, 0x0006, 0x0ba8, 0x00b8),
0x29: (['Kakariko Suburb Area', 'Frog Area'], 0x29, 0x0408, 0x0a7c, 0x0242, 0x0ae0, 0x02c0, 0x0aeb, 0x02c7, 0x0002, 0xfffe, 0x0ae0, 0x02c0), 0x29: (['Kakariko Suburb Area', 'Frog Area'], 0x29, 0x0408, 0x0a7c, 0x0242, 0x0ae0, 0x02c0, 0x0aeb, 0x02c7, 0x0002, 0xfffe, 0x0b30, 0x02e0),
0x2a: (['Flute Boy Area', 'Stumpy Area'], 0x2a, 0x058e, 0x0aac, 0x046e, 0x0b10, 0x04e8, 0x0b1b, 0x04f3, 0x0002, 0x0002, 0x0b10, 0x04e8), 0x2a: (['Flute Boy Area', 'Stumpy Area'], 0x2a, 0x058e, 0x0aac, 0x046e, 0x0b10, 0x04e8, 0x0b1b, 0x04f3, 0x0002, 0x0002, 0x0b60, 0x04f8),
0x2b: (['Central Bonk Rocks Area', 'Dark Bonk Rocks Area'], 0x2b, 0x0620, 0x0acc, 0x0700, 0x0b30, 0x0790, 0x0b3b, 0x0785, 0xfff2, 0x0000, 0x0b30, 0x0770), 0x2b: (['Central Bonk Rocks Area', 'Dark Bonk Rocks Area'], 0x2b, 0x0620, 0x0acc, 0x0700, 0x0b30, 0x0790, 0x0b3b, 0x0785, 0xfff2, 0x0000, 0x0b80, 0x0760),
0x2c: (['Links House Area', 'Big Bomb Shop Area'], 0x2c, 0x0588, 0x0ab9, 0x0840, 0x0b17, 0x08b8, 0x0b26, 0x08bf, 0xfff7, 0x0000, 0x0b20, 0x08b8), 0x2c: (['Links House Area', 'Big Bomb Shop Area'], 0x2c, 0x0588, 0x0ab9, 0x0840, 0x0b17, 0x08b8, 0x0b26, 0x08bf, 0xfff7, 0x0000, 0x0bb0, 0x08a8),
0x2d: (['Stone Bridge South Area', 'Hammer Bridge South Area'], 0x2d, 0x0886, 0x0b1e, 0x0a2a, 0x0ba0, 0x0aa8, 0x0b8b, 0x0aaf, 0x0000, 0x0006, 0x0bc4, 0x0ad0), 0x2d: (['Stone Bridge South Area', 'Hammer Bridge South Area'], 0x2d, 0x0886, 0x0b1e, 0x0a2a, 0x0ba0, 0x0aa8, 0x0b8b, 0x0aaf, 0x0000, 0x0006, 0x0bf0, 0x0ab8),
0x2e: (['Tree Line Area', 'Dark Tree Line Area'], 0x2e, 0x0100, 0x0a1a, 0x0c00, 0x0a78, 0x0c30, 0x0a87, 0x0c7d, 0x0006, 0x0000, 0x0a78, 0x0c58), 0x2e: (['Tree Line Area', 'Dark Tree Line Area'], 0x2e, 0x0100, 0x0a1a, 0x0c00, 0x0a78, 0x0c30, 0x0a87, 0x0c7d, 0x0006, 0x0000, 0x0ac8, 0x0c70),
0x2f: (['Eastern Nook Area', 'Darkness Nook Area'], 0x2f, 0x0798, 0x0afa, 0x0eb2, 0x0b58, 0x0f30, 0x0b67, 0x0f37, 0xfff6, 0x000e, 0x0b50, 0x0f30), 0x2f: (['Eastern Nook Area', 'Darkness Nook Area'], 0x2f, 0x0798, 0x0afa, 0x0eb2, 0x0b58, 0x0f30, 0x0b67, 0x0f37, 0xfff6, 0x000e, 0x0bc0, 0x0f00),
0x30: (['Desert Teleporter Ledge', 'Mire Teleporter Ledge'], 0x38, 0x1880, 0x0f1e, 0x0000, 0x0fa8, 0x0078, 0x0f8d, 0x008d, 0x0000, 0x0000, 0x0fb0, 0x0070), 0x30: (['Desert Teleporter Ledge', 'Mire Teleporter Ledge'], 0x38, 0x1880, 0x0f1e, 0x0000, 0x0fa8, 0x0078, 0x0f8d, 0x008d, 0x0000, 0x0000, 0x0ff0, 0x0070),
0x32: (['Flute Boy Approach Area', 'Stumpy Approach Area'], 0x32, 0x03a0, 0x0c6c, 0x0500, 0x0cd0, 0x05a8, 0x0cdb, 0x0585, 0x0002, 0x0000, 0x0cd6, 0x0568), 0x32: (['Flute Boy Approach Area', 'Stumpy Approach Area'], 0x32, 0x03a0, 0x0c6c, 0x0500, 0x0cd0, 0x05a8, 0x0cdb, 0x0585, 0x0002, 0x0000, 0x0d00, 0x0528),
0x33: (['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], 0x33, 0x0180, 0x0c20, 0x0600, 0x0c80, 0x0628, 0x0c8f, 0x067d, 0x0000, 0x0000, 0x0c80, 0x0628), 0x33: (['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], 0x33, 0x0180, 0x0c20, 0x0600, 0x0c80, 0x0628, 0x0c8f, 0x067d, 0x0000, 0x0000, 0x0ce0, 0x0688),
0x34: (['Statues Area', 'Hype Cave Area'], 0x34, 0x088e, 0x0d00, 0x0866, 0x0d60, 0x08d8, 0x0d6f, 0x08e3, 0x0000, 0x000a, 0x0d60, 0x08d8), 0x34: (['Statues Area', 'Hype Cave Area'], 0x34, 0x088e, 0x0d00, 0x0866, 0x0d60, 0x08d8, 0x0d6f, 0x08e3, 0x0000, 0x000a, 0x0dd0, 0x08e8),
#0x35: (['Lake Hylia Northwest Bank', 'Ice Lake Northwest Bank'], 0x35, 0x0d00, 0x0da6, 0x0a06, 0x0e08, 0x0a80, 0x0e13, 0x0a8b, 0xfffa, 0xfffa, 0x0d88, 0x0a88), #0x35: (['Lake Hylia Northwest Bank', 'Ice Lake Northwest Bank'], 0x35, 0x0d00, 0x0da6, 0x0a06, 0x0e08, 0x0a80, 0x0e13, 0x0a8b, 0xfffa, 0xfffa, 0x0dc8, 0x0a90),
0x35: (['Lake Hylia South Shore', 'Ice Lake Southeast Ledge'], 0x3e, 0x1860, 0x0f1e, 0x0d00, 0x0f98, 0x0da8, 0x0f8b, 0x0d85, 0x0000, 0x0000, 0x0f90, 0x0da4), 0x35: (['Lake Hylia South Shore', 'Ice Lake Southeast Ledge'], 0x3e, 0x1860, 0x0f1e, 0x0d00, 0x0f98, 0x0da8, 0x0f8b, 0x0d85, 0x0000, 0x0000, 0x0fd8, 0x0da8),
0x37: (['Ice Cave Area', 'Shopping Mall Area'], 0x37, 0x0786, 0x0cf6, 0x0e2e, 0x0d58, 0x0ea0, 0x0d63, 0x0eab, 0x000a, 0x0002, 0x0d48, 0x0ed0), 0x37: (['Ice Cave Area', 'Shopping Mall Area'], 0x37, 0x0786, 0x0cf6, 0x0e2e, 0x0d58, 0x0ea0, 0x0d63, 0x0eab, 0x000a, 0x0002, 0x0d98, 0x0ed0),
0x3a: (['Desert Pass Area', 'Swamp Nook Area'], 0x3a, 0x001a, 0x0e08, 0x04c6, 0x0e70, 0x0540, 0x0e7d, 0x054b, 0x0006, 0x000a, 0x0e70, 0x0540), 0x3a: (['Desert Pass Area', 'Swamp Nook Area'], 0x3a, 0x001a, 0x0e08, 0x04c6, 0x0e70, 0x0540, 0x0e7d, 0x054b, 0x0006, 0x000a, 0x0ee0, 0x0570),
0x3b: (['Dam Area', 'Swamp Area'], 0x3b, 0x069e, 0x0edf, 0x06f2, 0x0f3d, 0x0778, 0x0f4c, 0x077f, 0xfff1, 0xfffe, 0x0f30, 0x0770), 0x3b: (['Dam Area', 'Swamp Area'], 0x3b, 0x069e, 0x0edf, 0x06f2, 0x0f3d, 0x0778, 0x0f4c, 0x077f, 0xfff1, 0xfffe, 0x0fd0, 0x0770),
0x3c: (['South Pass Area', 'Dark South Pass Area'], 0x3c, 0x0584, 0x0ed0, 0x081e, 0x0f38, 0x0898, 0x0f45, 0x08a3, 0xfffe, 0x0002, 0x0f38, 0x0898), 0x3c: (['South Pass Area', 'Dark South Pass Area'], 0x3c, 0x0584, 0x0ed0, 0x081e, 0x0f38, 0x0898, 0x0f45, 0x08a3, 0xfffe, 0x0002, 0x0fa8, 0x0898),
0x3f: (['Octoballoon Area', 'Bomber Corner Area'], 0x3f, 0x0810, 0x0f05, 0x0e75, 0x0f67, 0x0ef3, 0x0f72, 0x0efa, 0xfffb, 0x000b, 0x0f80, 0x0ef0) 0x3f: (['Octoballoon Area', 'Bomber Corner Area'], 0x3f, 0x0810, 0x0f05, 0x0e75, 0x0f67, 0x0ef3, 0x0f72, 0x0efa, 0xfffb, 0x000b, 0x0fd0, 0x0ef0)
}
ow_loc_prize_table = {
'Master Sword Pedestal': (0x06d, 0x070),
'Hobo': (0xb80, 0xb90),
'Mushroom': (0x180, 0x140),
'Lost Woods Hideout Tree': (0x200, 0x320),
'Ether Tablet': (0x728, 0x017),
'Spectacle Rock': (0x7F8, 0x128),
'Old Man': (0x6A8, 0x3FF),
'Floating Island': (0xD38, 0x038),
'Death Mountain Bonk Rocks': (0xD48, 0x107),
'Mountain Pass Pull Tree': (0x4E0, 0x380),
'Mountain Pass Southeast Tree': (0x5A0, 0x3FF),
'Lost Woods Pass West Tree': (0x080, 0x540),
'Kakariko Portal Tree': (0x190, 0x540),
'Fortune Bonk Rocks': (0x288, 0x558),
'Bonk Rocks Tree': (0x680, 0x520),
'Sanctuary Tree': (0x788, 0x594),
'River Bend West Tree': (0xA38, 0x5FF),
'River Bend East Tree': (0xB88, 0x558),
'Bottle Merchant': (0x178, 0x7E8),
'Blinds Hideout Tree': (0x118, 0x6F7),
'Kakariko Welcome Tree': (0x358, 0x988),
'Hyrule Castle Tree': (0x730, 0x780),
'Wooden Bridge Tree': (0xA78, 0x6F0),
'Eastern Palace Tree': (0xEC0, 0x968),
'Maze Race': (0x0C0, 0xB00),
'Flute Spot': (0x480, 0xAC0),
'Flute Boy East Tree': (0x540, 0xB80),
'Flute Boy South Tree': (0x540, 0xB80),
'Central Bonk Rocks Tree': (0x768, 0xB37),
'Tree Line Tree 2': (0xCD8, 0xB00),
'Tree Line Tree 4': (0xCD8, 0xB00),
'Desert Ledge': (0x018, 0xE88),
'Bombos Tablet': (0x3E8, 0xEF8),
'Flute Boy Approach North Tree': (0x588, 0xD07),
'Flute Boy Approach South Tree': (0x588, 0xD07),
'Lake Hylia Island': (0xB98, 0xD88),
'Purple Chest': (0x588, 0xE96),
'Sunken Treasure': (0x6F8, 0xF48),
'Dark Lumberjack Tree': (0x438, 0x1F7),
'Bumper Cave Ledge': (0x538, 0x277),
'Catfish': (0xE80, 0x368),
'Dark Fortune Bonk Rocks (Drop 1)': (0x288, 0x558),
'Dark Fortune Bonk Rocks (Drop 2)': (0x288, 0x558),
'Dark Graveyard West Bonk Rocks': (0x900, 0x580),
'Dark Graveyard North Bonk Rocks': (0x900, 0x580),
'Dark Graveyard Tomb Bonk Rocks': (0x900, 0x580),
'Qirn Jump West Tree': (0xA98, 0x5FF),
'Qirn Jump East Tree': (0xB88, 0x558),
'Dark Witch Tree': (0xC28, 0x558),
'Pyramid': (0x998, 0x778),
'Pyramid Tree': (0x738, 0x908),
'Palace of Darkness Tree': (0xEC0, 0x968),
'Digging Game': (0x0C0, 0xB00),
'Dark Tree Line Tree 2': (0xCD8, 0xB00),
'Dark Tree Line Tree 3': (0xCD8, 0xB00),
'Dark Tree Line Tree 4': (0xCD8, 0xB00),
'Hype Cave Statue': (0x900, 0xDB0)
} }
tile_swap_spoiler_table = \ tile_swap_spoiler_table = \

109
Rom.py
View File

@@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'b2b8b42d575dd9825f2d8c424a4abb21' RANDOMIZERBASEHASH = 'd2f1b8b15480a08856f6902c74adfc02'
class JsonRom(object): class JsonRom(object):
@@ -532,30 +532,22 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
write_int16(rom, snes_to_pc(0x02E8D1 + (o * 2)), data[13] if offset > 0 and len(data) > 13 else data[5]) # link Y write_int16(rom, snes_to_pc(0x02E8D1 + (o * 2)), data[13] if offset > 0 and len(data) > 13 else data[5]) # link Y
write_int16(rom, snes_to_pc(0x02E8F3 + (o * 2)), data[14] if offset > 0 and len(data) > 13 else data[6]) # link X write_int16(rom, snes_to_pc(0x02E8F3 + (o * 2)), data[14] if offset > 0 and len(data) > 13 else data[6]) # link X
if offset == 0 or len(data) <= 15: base_index = 0
write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[2]) # vram if not (offset == 0 or len(data) <= 15):
write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[3]) # BG scroll Y base_index = 13 # use alternate flute data
write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[4]) # BG scroll X write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[base_index + 2]) # vram
write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[7]) # cam Y write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[base_index + 3]) # BG scroll Y
write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[8]) # cam X write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[base_index + 4]) # BG scroll X
write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[9]) # unknown 1 if base_index > 0:
write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[10]) # unknown 2 base_index -= 2
rom.write_byte(snes_to_pc(0x0AB783 + o), data[12] & 0xff) # flute menu blip - X low byte write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[base_index + 7]) # cam Y
rom.write_byte(snes_to_pc(0x0AB78B + o), data[12] // 0x100) # flute menu blip - X high byte write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[base_index + 8]) # cam X
rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # flute menu blip - Y low byte write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[base_index + 9]) # unknown 1
rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # flute menu blip - Y high byte write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[base_index + 10]) # unknown 2
else: # use alternate flute data rom.write_byte(snes_to_pc(0x0AB783 + o), data[base_index + 12] & 0xff) # flute menu blip - X low byte
write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[15]) # vram rom.write_byte(snes_to_pc(0x0AB78B + o), data[base_index + 12] // 0x100) # flute menu blip - X high byte
write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[16]) # BG scroll Y rom.write_byte(snes_to_pc(0x0AB793 + o), data[base_index + 11] & 0xff) # flute menu blip - Y low byte
write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[17]) # BG scroll X rom.write_byte(snes_to_pc(0x0AB79B + o), data[base_index + 11] // 0x100) # flute menu blip - Y high byte
write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[18]) # cam Y
write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[19]) # cam X
write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[20]) # unknown 1
write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[21]) # unknown 2
rom.write_byte(snes_to_pc(0x0AB783 + o), data[23] & 0xff) # flute menu blip - X low byte
rom.write_byte(snes_to_pc(0x0AB78B + o), data[23] // 0x100) # flute menu blip - X high byte
rom.write_byte(snes_to_pc(0x0AB793 + o), data[22] & 0xff) # flute menu blip - Y low byte
rom.write_byte(snes_to_pc(0x0AB79B + o), data[22] // 0x100) # flute menu blip - Y high byte
# patch whirlpools # patch whirlpools
if world.owWhirlpoolShuffle[player]: if world.owWhirlpoolShuffle[player]:
@@ -1412,34 +1404,45 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
rom.write_byte(0x18003C, compass_mode) rom.write_byte(0x18003C, compass_mode)
def get_entrance_coords(ent): def get_entrance_coords(ent):
if ent is None: if ent is None or isinstance(ent, int):
owid_map = [0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47] owid_map = [ 0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47 ]
x_map_position_generic = [0x03c0, 0x0740, 0xff00, 0x03c0, 0x01c0, 0x0bc0, 0x05c0, 0x09c0, 0x0ac0, 0x07c0, 0x0dc0] coord_flags = 0x0000
y_map_position_generic = [0xff00, 0xff00, 0xff00, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0xff00, 0x0fc0, 0x0fc0] if ent is None:
world_indicator = 0x0000 # HUD-style dislocated icons
idx = int((map_index-2)/2) x_map_position = [0x0050, 0x0080, 0xFF00, 0x0040, 0x0020, 0x00C0, 0x0060, 0x00A0, 0x00B0, 0x0080, 0x00E0]
y_map_position = [0x000C, 0x000C, 0xFF00, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x000C, 0x00D4, 0x00D4]
coord_flags = 0x4000 # raw OAM coord flag
idx = int((map_index-2)/2)
elif isinstance(ent, int):
# vanilla icon positions
x_map_position = [0x0F30, 0x0170, 0xFF00, 0x0790, 0x0F30, 0x0160, 0x00F0, 0x0CB0, 0x0900, 0x0240, 0x0F30]
y_map_position = [0x06E0, 0x0E50, 0xFF00, 0x0FD0, 0x06E0, 0x0D80, 0x0160, 0x0E80, 0x0130, 0x0840, 0x01B0]
idx = ent
owid = owid_map[idx] owid = owid_map[idx]
if owid != 0xFF: if owid != 0xFF:
if (owid < 0x40) == (world.is_tile_swapped(owid, player)): if (owid < 0x40) == (world.is_tile_swapped(owid, player)):
world_indicator = 0x8000 coord_flags |= 0x8000 # world indicator flag
return [world_indicator | x_map_position_generic[idx], y_map_position_generic[idx]] return (coord_flags | x_map_position[idx], y_map_position[idx])
if type(ent) is Location: elif type(ent) is Location:
from OverworldShuffle import OWTileRegions from OverworldShuffle import OWTileRegions, ow_loc_prize_table
if ent.name == 'Hobo': if ent.name in ow_loc_prize_table:
coords = (0xb80, 0xb80) coords = ow_loc_prize_table[ent.name]
elif ent.name == 'Master Sword Pedestal':
coords = (0x06d, 0x070)
else: else:
owid = OWTileRegions[ent.parent_region.name] owid = OWTileRegions[ent.parent_region.name]
if owid == 0x81: if owid == 0x81:
coords = (0x220, 0xf40) coords = (0xF60, 0x280)
else: else:
owid = owid % 0x40 owid = owid % 0x40
coords = (0x200 * (owid % 0x08) + 0x100, 0x200 * int(owid / 0x08) + 0x100) coords = (0x200 * (owid % 0x08) + 0x100, 0x200 * int(owid / 0x08) + 0x100)
if owid in [0x00, 0x03, 0x05, 0x18, 0x1b, 0x1e, 0x30, 0x35]: if owid in [0x00, 0x03, 0x05, 0x18, 0x1B, 0x1E, 0x30, 0x35]:
coords = (coords[0] + 0x100, coords[1] + 0x100) coords = (coords[0] + 0x100, coords[1] + 0x100)
else: else:
coords = ow_prize_table[ent.name] if ent.name in ow_prize_table:
coords = ow_prize_table[ent.name]
elif door_addresses[ent.name][1] is not None:
coords = (door_addresses[ent.name][1][6], door_addresses[ent.name][1][5])
else:
raise Exception(f"No overworld map coordinates for entrance {ent.name}")
coords = ((0x8000 if ent.parent_region.type == RegionType.DarkWorld else 0x0000) | coords[0], coords[1]) coords = ((0x8000 if ent.parent_region.type == RegionType.DarkWorld else 0x0000) | coords[0], coords[1])
return coords return coords
if world.overworld_map[player] == 'default': if world.overworld_map[player] == 'default':
@@ -1468,16 +1471,16 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
# prize location # prize location
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords) write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords)
if world.shuffle[player] == 'vanilla' or world.overworld_map[player] == 'default': if world.shuffle[player] == 'vanilla' or world.overworld_map[player] == 'default':
# TODO: I think this is logically the same as some of the vanilla stuff below swap_entrances = { 'Agahnims Tower': 'Ganons Tower',
vanilla_entrances = { 'Hyrule Castle': 'Hyrule Castle Entrance (South)', 'Ganons Tower': 'Agahnims Tower' }
'Desert Palace': 'Desert Palace Entrance (North)', if dungeon in swap_entrances:
'Skull Woods': 'Skull Woods Final Section' } entrance_name = dungeon
entrance_name = vanilla_entrances[dungeon] if dungeon in vanilla_entrances else dungeon if world.is_atgt_swapped(player):
if world.is_atgt_swapped(player): entrance_name = swap_entrances[dungeon]
swap_entrances = { 'Agahnims Tower': 'Ganons Tower', entrance = world.get_entrance(entrance_name, player)
'Ganons Tower': 'Agahnims Tower' } coords = get_entrance_coords(entrance)
entrance_name = swap_entrances[dungeon] if dungeon in swap_entrances else entrance_name else:
entrance = world.get_entrance(entrance_name, player) coords = get_entrance_coords(int((map_index-2)/2))
else: else:
if len(portal_list) == 1: if len(portal_list) == 1:
portal_idx = 0 portal_idx = 0
@@ -1497,7 +1500,7 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
offset += 4 offset += 4
portal = world.get_portal(portal_list[portal_idx], player) portal = world.get_portal(portal_list[portal_idx], player)
entrance = portal.find_portal_entrance() entrance = portal.find_portal_entrance()
coords = get_entrance_coords(entrance) coords = get_entrance_coords(entrance)
# figure out compass entrances and what world (light/dark) # figure out compass entrances and what world (light/dark)
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6), coords) write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6), coords)

Binary file not shown.

View File

@@ -147,139 +147,149 @@ door_addresses = {'Links House': (0x00, (0x0104, 0x2c
'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)} 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)}
ow_prize_table = {'Links House': (0x8b1, 0xb2d), ow_prize_table = {'Lost Woods Gamble': (0x2A0, 0x080),
'Desert Palace Entrance (South)': (0x108, 0xd70), 'Desert Palace Entrance (West)': (0x031, 0xca0), 'Lost Woods Hideout Drop': (0x338, 0x218),
'Desert Palace Entrance (North)': (0x0e1, 0xba0), 'Desert Palace Entrance (East)': (0x191, 0xca0), 'Lost Woods Hideout Stump': (0x2A0, 0x2E0),
'Eastern Palace': (0xf31, 0x620), 'Tower of Hera': (0x8D0, 0x080), 'Lumberjack House': (0x538, 0x158),
'Hyrule Castle Entrance (South)': (0x820, 0x730), 'Hyrule Castle Entrance (West)': (0x740, 0x5D0), 'Lumberjack Tree Tree': (0x4A0, 0x160),
'Hyrule Castle Entrance (East)': (0x8f0, 0x5D0), 'Lumberjack Tree Cave': (0x550, 0x004),
'Agahnims Tower': (0x820, 0x5D0), 'Tower of Hera': (0x900, 0x0E0),
'Thieves Town': (0x1d0, 0x780), 'Skull Woods First Section Door': (0x2e0, 0x280), 'Spectacle Rock Cave Peak': (0x758, 0x1B7),
'Skull Woods Second Section Door (East)': (0x200, 0x240), 'Spectacle Rock Cave (Bottom)': (0x6F0, 0x257),
'Skull Woods Second Section Door (West)': (0x0c0, 0x1c0), 'Spectacle Rock Cave': (0x7C8, 0x257),
'Skull Woods Final Section': (0x082, 0x0b0), 'Death Mountain Return Cave (East)': (0x648, 0x278),
'Skull Woods First Section Hole (West)': (0x200, 0x2b0), 'Old Man Cave (East)': (0x658, 0x387),
'Skull Woods First Section Hole (East)': (0x340, 0x2e0), 'Old Man House (Top)': (0x8C8, 0x2D8),
'Skull Woods First Section Hole (North)': (0x320, 0x1e0), 'Old Man House (Bottom)': (0x728, 0x3A7),
'Skull Woods Second Section Hole': (0x0f0, 0x0b0), 'Paradox Cave (Top)': (0xDE0, 0x100),
'Ice Palace': (0xca0, 0xda0), 'Paradox Cave (Bottom)': (0xDC8, 0x358),
'Misery Mire': (0x100, 0xca0), 'Paradox Cave (Middle)': (0xDDF, 0x3FF),
'Palace of Darkness': (0xf40, 0x620), 'Swamp Palace': (0x759, 0xED0), 'Fairy Ascension Cave (Top)': (0xCD8, 0x2B8),
'Turtle Rock': (0xf11, 0x103), 'Fairy Ascension Cave (Bottom)': (0xC78, 0x358),
'Dark Death Mountain Ledge (West)': (0xb80, 0x180), 'Spiral Cave': (0xC78, 0x207),
'Dark Death Mountain Ledge (East)': (0xc80, 0x180), 'Spiral Cave (Bottom)': (0xBC8, 0x2F7),
'Turtle Rock Isolated Ledge Entrance': (0xc00, 0x240), 'Mimic Cave': (0xD38, 0x207),
'Hookshot Fairy': (0xD38, 0x358),
'Death Mountain Return Cave (West)': (0x5B8, 0x247),
'Old Man Cave (West)': (0x5B8, 0x348),
'Waterfall of Wishing': (0xE80, 0x2C7),
'Fortune Teller (Light)': (0x308, 0x5A8),
'Bonk Rock Cave': (0x600, 0x517),
'Sanctuary': (0x748, 0x4F4),
'Sanctuary Grave': (0x860, 0x550),
'Graveyard Cave': (0x8F8, 0x4A6),
'Kings Grave': (0x978, 0x566),
'North Fairy Cave Drop': (0xA40, 0x580),
'North Fairy Cave': (0xAA8, 0x4A8),
'Potion Shop': (0xCB8, 0x598),
'Kakariko Well Drop': (0x030, 0x6C0),
'Kakariko Well Cave': (0x0D8, 0x6F7),
'Blinds Hideout': (0x1B8, 0x6F7),
'Elder House (West)': (0x258, 0x6F7),
'Elder House (East)': (0x2E8, 0x6F7),
'Snitch Lady (West)': (0x0C8, 0x7E8),
'Snitch Lady (East)': (0x338, 0x7E8),
'Chicken House': (0x188, 0x8E8),
'Sick Kids House': (0x278, 0x8E8),
'Bush Covered House': (0x338, 0x8E8),
'Light World Bomb Hut': (0x068, 0x9D7),
'Kakariko Shop': (0x1C8, 0x9D7),
'Tavern North': (0x2B8, 0x977),
'Tavern (Front)': (0x2B8, 0x9F7),
'Agahnims Tower': (0x7F0, 0x630),
'Hyrule Castle Entrance (South)': (0x7F0, 0x750),
'Hyrule Castle Entrance (West)': (0x758, 0x644),
'Hyrule Castle Entrance (East)': (0x8E8, 0x644),
'Hyrule Castle Secret Entrance Drop': (0x9D0, 0x680), 'Hyrule Castle Secret Entrance Drop': (0x9D0, 0x680),
'Hyrule Castle Secret Entrance Stairs': (0x8D0, 0x700), 'Hyrule Castle Secret Entrance Stairs': (0x8C8, 0x718),
'Kakariko Well Drop': (0x030, 0x680), 'Inverted Pyramid Hole': (0x7F0, 0x6B0),
'Kakariko Well Cave': (0x060, 0x680), 'Inverted Pyramid Entrance': (0x6E8, 0x644),
'Bat Cave Drop': (0x520, 0x8f0), 'Sahasrahlas Hut': (0xCF0, 0x747),
'Bat Cave Cave': (0x560, 0x940), 'Eastern Palace': (0xF40, 0x680),
'Elder House (East)': (0x2b0, 0x6a0), 'Blacksmiths Hut': (0x4E8, 0x8C8),
'Elder House (West)': (0x230, 0x6a0), 'Bat Cave Drop': (0x538, 0x9A8),
'North Fairy Cave Drop': (0xa40, 0x500), 'Bat Cave Cave': (0x510, 0x930),
'North Fairy Cave': (0xa80, 0x440), 'Two Brothers House (West)': (0x1B8, 0xB88),
'Lost Woods Hideout Drop': (0x290, 0x200), 'Two Brothers House (East)': (0x238, 0xB88),
'Lost Woods Hideout Stump': (0x240, 0x280), 'Library': (0x2B8, 0xAA7),
'Lumberjack Tree Tree': (0x4e0, 0x140), 'Kakariko Gamble Game': (0x348, 0xB78),
'Lumberjack Tree Cave': (0x560, 0x004), 'Bonk Fairy (Light)': (0x788, 0xA87),
'Two Brothers House (East)': (0x200, 0x0b60), 'Links House': (0x8B8, 0xB58),
'Two Brothers House (West)': (0x180, 0x0b60), 'Lake Hylia Fairy': (0xD58, 0xA57),
'Sanctuary Grave': (0x820, 0x4c0), 'Long Fairy Cave': (0xF68, 0xB58),
'Sanctuary': (0x720, 0x4a0), 'Desert Palace Entrance (North)': (0x148, 0xC28),
'Old Man Cave (West)': (0x580, 0x2c0), 'Desert Palace Entrance (West)': (0x088, 0xCF8),
'Old Man Cave (East)': (0x620, 0x2c0), 'Desert Palace Entrance (East)': (0x1E8, 0xCF8),
'Old Man House (Bottom)': (0x720, 0x320), 'Desert Palace Entrance (South)': (0x138, 0xD18),
'Old Man House (Top)': (0x820, 0x220), 'Checkerboard Cave': (0x2E8, 0xCF7),
'Death Mountain Return Cave (East)': (0x600, 0x220), 'Aginahs Cave': (0x388, 0xDE8),
'Death Mountain Return Cave (West)': (0x500, 0x1c0), 'Cave 45': (0x448, 0xD86),
'Spectacle Rock Cave Peak': (0x720, 0x0a0), 'Light Hype Fairy': (0x988, 0xCF8),
'Spectacle Rock Cave': (0x790, 0x1a0), 'Lake Hylia Fortune Teller': (0xA68, 0xCC8),
'Spectacle Rock Cave (Bottom)': (0x710, 0x0a0), 'Lake Hylia Shop': (0xBF8, 0xC66),
'Paradox Cave (Bottom)': (0xd80, 0x180), 'Capacity Upgrade': (0xCC8, 0xDE8),
'Paradox Cave (Middle)': (0xd80, 0x380), 'Mini Moldorm Cave': (0xA88, 0xEF8),
'Paradox Cave (Top)': (0xd80, 0x020), 'Ice Rod Cave': (0xE68, 0xC37),
'Fairy Ascension Cave (Bottom)': (0xcc8, 0x2a0), 'Good Bee Cave': (0xEF8, 0xC36),
'Fairy Ascension Cave (Top)': (0xc00, 0x240), '20 Rupee Cave': (0xEB8, 0xCC6),
'Spiral Cave': (0xb80, 0x180), 'Desert Fairy': (0x488, 0xE76),
'Spiral Cave (Bottom)': (0xb80, 0x2c0), '50 Rupee Cave': (0x4F8, 0xF47),
'Bumper Cave (Bottom)': (0x580, 0x2c0), 'Dam': (0x778, 0xF68),
'Bumper Cave (Top)': (0x500, 0x1c0),
'Superbunny Cave (Top)': (0xd80, 0x020), 'Skull Woods Final Section': (0x078, 0x0A8),
'Superbunny Cave (Bottom)': (0xd00, 0x180), 'Skull Woods Second Section Door (West)': (0x0E0, 0x1C0),
'Hookshot Cave': (0xc80, 0x0c0), 'Skull Woods Second Section Hole': (0x150, 0x120),
'Hookshot Cave Back Entrance': (0xcf0, 0x004), 'Skull Woods Second Section Door (East)': (0x208, 0x208),
'Ganons Tower': (0x8D0, 0x080), 'Skull Woods First Section Door': (0x2C8, 0x2A8),
'Pyramid Hole': (0x820, 0x680), 'Skull Woods First Section Hole (North)': (0x320, 0x1e0),
'Inverted Pyramid Hole': (0x820, 0x680), 'Skull Woods First Section Hole (West)': (0x240, 0x380),
'Pyramid Entrance': (0x640, 0x7c0), 'Skull Woods First Section Hole (East)': (0x340, 0x380),
'Inverted Pyramid Entrance': (0x6C0, 0x5D0), 'Dark Lumberjack Shop': (0x538, 0x177),
'Waterfall of Wishing': (0xe80, 0x280), 'Ganons Tower': (0x900, 0x0E0),
'Dam': (0x759, 0xED0), 'Dark Death Mountain Fairy': (0x658, 0x387),
'Blinds Hideout': (0x190, 0x6c0), 'Spike Cave': (0x9F8, 0x268),
'Bonk Fairy (Light)': (0x740, 0xa80), 'Hookshot Cave Back Entrance': (0xD38, 0x038),
'Lake Hylia Fairy': (0xd40, 0x9f0), 'Hookshot Cave': (0xD48, 0x107),
'Light Hype Fairy': (0x940, 0xc80), 'Superbunny Cave (Top)': (0xDE0, 0x100),
'Desert Fairy': (0x420, 0xe00), 'Superbunny Cave (Bottom)': (0xD38, 0x358),
'Kings Grave': (0x920, 0x520), 'Dark Death Mountain Ledge (West)': (0xC78, 0x207),
'Tavern North': (0x270, 0x900), 'Dark Death Mountain Ledge (East)': (0xD38, 0x207),
'Chicken House': (0x120, 0x880), 'Turtle Rock Isolated Ledge Entrance': (0xCD8, 0x2B8),
'Aginahs Cave': (0x2e0, 0xd00), 'Dark Death Mountain Shop': (0xDC8, 0x358),
'Sahasrahlas Hut': (0xcf0, 0x6c0), 'Turtle Rock': (0xF48, 0x108),
'Lake Hylia Shop': (0xbc0, 0xc00), 'Bumper Cave (Top)': (0x5B8, 0x247),
'Capacity Upgrade': (0xca0, 0xda0), 'Bumper Cave (Bottom)': (0x5B8, 0x348),
'Blacksmiths Hut': (0x4a0, 0x880), 'Fortune Teller (Dark)': (0x308, 0x5A8),
'Sick Kids House': (0x220, 0x880), 'Dark Sanctuary Hint': (0x748, 0x4F4),
'Lost Woods Gamble': (0x240, 0x080), 'Dark Potion Shop': (0xCB8, 0x598),
'Fortune Teller (Light)': (0x2c0, 0x4c0), 'Chest Game': (0x0C8, 0x7E8),
'Snitch Lady (East)': (0x310, 0x7a0), 'Thieves Town': (0x1F0, 0x7E8),
'Snitch Lady (West)': (0x080, 0x7a0), 'C-Shaped House': (0x338, 0x7E8),
'Bush Covered House': (0x2e0, 0x880), 'Brewery': (0x1C8, 0x9D7),
'Tavern (Front)': (0x270, 0x980), 'Dark World Shop': (0x338, 0x8E8),
'Light World Bomb Hut': (0x070, 0x980), 'Red Shield Shop': (0x538, 0x778),
'Kakariko Shop': (0x170, 0x980), 'Pyramid Hole': (0x800, 0x680),
'Cave 45': (0x440, 0xca0), 'Graveyard Cave': (0x8f0, 0x430), 'Pyramid Entrance': (0x718, 0x7A8),
'Checkerboard Cave': (0x260, 0xc00), 'Pyramid Fairy': (0x7B8, 0x7A8),
'Mini Moldorm Cave': (0xa40, 0xe80), 'Palace of Darkness': (0xF40, 0x680),
'Long Fairy Cave': (0xf60, 0xb00), 'Palace of Darkness Hint': (0xD70, 0x878),
'Good Bee Cave': (0xec0, 0xc00), 'Hammer Peg Cave': (0x528, 0x9B6),
'20 Rupee Cave': (0xe80, 0xca0), 'Archery Game': (0x348, 0xB78),
'50 Rupee Cave': (0x4d0, 0xed0), 'Bonk Fairy (Dark)': (0x788, 0xA87),
'Ice Rod Cave': (0xe00, 0xc00), 'Big Bomb Shop': (0x8B8, 0xB58),
'Bonk Rock Cave': (0x5f0, 0x460), 'Dark Lake Hylia Fairy': (0xD58, 0xA57),
'Library': (0x270, 0xaa0), 'East Dark World Hint': (0xF68, 0xB58),
'Potion Shop': (0xc80, 0x4c0), 'Mire Shed': (0x0A8, 0xCC7),
'Hookshot Fairy': (0xd00, 0x180), 'Misery Mire': (0x148, 0xCC7),
'Pyramid Fairy': (0x740, 0x740), 'Mire Fairy': (0x1E8, 0xCC7),
'East Dark World Hint': (0xf60, 0xb00), 'Mire Hint': (0x388, 0xDE8),
'Palace of Darkness Hint': (0xd60, 0x7c0), 'Hype Cave': (0x988, 0xCF8),
'Dark Lake Hylia Fairy': (0xd40, 0x9f0), 'Dark Lake Hylia Shop': (0xA68, 0xCC8),
'Dark Lake Hylia Ledge Fairy': (0xe00, 0xc00), 'Ice Palace': (0xCA8, 0xE28),
'Dark Lake Hylia Ledge Spike Cave': (0xe80, 0xca0), 'Dark Lake Hylia Ledge Fairy': (0xE68, 0xC37),
'Dark Lake Hylia Ledge Hint': (0xec0, 0xc00), 'Dark Lake Hylia Ledge Hint': (0xEF8, 0xC36),
'Hype Cave': (0x940, 0xc80), 'Dark Lake Hylia Ledge Spike Cave': (0xEB8, 0xCC6),
'Bonk Fairy (Dark)': (0x740, 0xa80), 'Swamp Palace': (0x778, 0xF68)}
'Brewery': (0x170, 0x980), 'C-Shaped House': (0x310, 0x7a0), 'Chest Game': (0x080, 0x7a0),
'Hammer Peg Cave': (0x4c0, 0x940),
'Red Shield Shop': (0x500, 0x680),
'Dark Sanctuary Hint': (0x720, 0x4a0),
'Fortune Teller (Dark)': (0x2c0, 0x4c0),
'Dark World Shop': (0x2e0, 0x880),
'Dark Lumberjack Shop': (0x4e0, 0x0d0),
'Dark Potion Shop': (0xc80, 0x4c0),
'Archery Game': (0x2f0, 0xaf0),
'Mire Shed': (0x060, 0xc90),
'Mire Hint': (0x2e0, 0xd00),
'Mire Fairy': (0x1c0, 0xc90),
'Spike Cave': (0x860, 0x180),
'Dark Death Mountain Shop': (0xd80, 0x180),
'Dark Death Mountain Fairy': (0x620, 0x2c0),
'Mimic Cave': (0xc80, 0x180),
'Big Bomb Shop': (0x8b1, 0xb2d),
'Dark Lake Hylia Shop': (0xa40, 0xc40),
'Lumberjack House': (0x580, 0x100),
'Lake Hylia Fortune Teller': (0xa40, 0xc40),
'Kakariko Gamble Game': (0x2f0, 0xaf0)}
default_connector_connections = [('Death Mountain Return Cave (West)', 'Death Mountain Return Cave Exit (West)'), default_connector_connections = [('Death Mountain Return Cave (West)', 'Death Mountain Return Cave Exit (West)'),
('Death Mountain Return Cave (East)', 'Death Mountain Return Cave Exit (East)'), ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave Exit (East)'),