diff --git a/EntranceShuffle.py b/EntranceShuffle.py index c373ab78..553eac31 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -5,6 +5,8 @@ from collections import defaultdict def link_entrances(world, player): + invFlag = world.mode[player] == 'inverted' + connect_exit(world, 'Chris Houlihan Room Exit', 'Links House', player) # should always match link's house, except for plandos Dungeon_Exits = Dungeon_Exits_Base.copy() @@ -18,6 +20,13 @@ def link_entrances(world, player): for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) + if not invFlag: + for exitname, regionname in open_mandatory_connections: + connect_simple(world, exitname, regionname, player) + else: + for exitname, regionname in inverted_mandatory_connections: + connect_simple(world, exitname, regionname, player) + connect_custom(world, player) # if we do not shuffle, set default connections @@ -26,22 +35,56 @@ def link_entrances(world, player): connect_simple(world, exitname, regionname, player) for exitname, regionname in default_dungeon_connections: connect_simple(world, exitname, regionname, player) + if not invFlag: + for exitname, regionname in open_default_connections: + connect_simple(world, exitname, regionname, player) + for exitname, regionname in open_default_dungeon_connections: + connect_simple(world, exitname, regionname, player) + else: + for exitname, regionname in inverted_default_connections: + connect_simple(world, exitname, regionname, player) + for exitname, regionname in inverted_default_dungeon_connections: + connect_simple(world, exitname, regionname, player) elif world.shuffle[player] == 'dungeonssimple': for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) + if not invFlag: + for exitname, regionname in open_default_connections: + connect_simple(world, exitname, regionname, player) + else: + for exitname, regionname in inverted_default_connections: + connect_simple(world, exitname, regionname, player) simple_shuffle_dungeons(world, player) elif world.shuffle[player] == 'dungeonsfull': for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) + if not invFlag: + for exitname, regionname in open_default_connections: + connect_simple(world, exitname, regionname, player) + else: + for exitname, regionname in inverted_default_connections: + connect_simple(world, exitname, regionname, player) skull_woods_shuffle(world, player) dungeon_exits = list(Dungeon_Exits) - lw_entrances = list(LW_Dungeon_Entrances) - dw_entrances = list(DW_Dungeon_Entrances) + lw_entrances = list(LW_Dungeon_Entrances) if not invFlag else list(Inverted_LW_Dungeon_Entrances) + dw_entrances = list(DW_Dungeon_Entrances) if not invFlag else list(Inverted_DW_Dungeon_Entrances) - if world.mode[player] == 'standard': + if invFlag: + lw_dungeon_entrances_must_exit = list(Inverted_LW_Dungeon_Entrances_Must_Exit) + + # randomize which desert ledge door is a must-exit + if random.randint(0, 1) == 0: + lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') + lw_entrances.append('Desert Palace Entrance (West)') + else: + lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (West)') + lw_entrances.append('Desert Palace Entrance (North)') + dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) + lw_entrances.append('Hyrule Castle Entrance (South)') + elif world.mode[player] == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) elif world.doorShuffle[player] != 'vanilla': @@ -51,12 +94,42 @@ def link_entrances(world, player): lw_entrances.append('Hyrule Castle Entrance (South)') if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Agahnims Tower' if world.is_atgt_swapped(player) else 'Ganons Tower', 'Ganons Tower Exit', player) + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: - dw_entrances.append('Ganons Tower') + if not invFlag: + dw_entrances.append('Ganons Tower') + else: + lw_entrances.append('Agahnims Tower') dungeon_exits.append('Ganons Tower Exit') + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] - if world.mode[player] == 'standard': + if invFlag: + # shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit + all_entrances_aga = lw_entrances + dw_entrances + aga_doors = [i for i in all_entrances_aga] + random.shuffle(aga_doors) + aga_door = aga_doors.pop() + + if aga_door in hc_ledge_entrances: + lw_entrances.remove(aga_door) + hc_ledge_entrances.remove(aga_door) + + random.shuffle(hc_ledge_entrances) + hc_ledge_must_exit = hc_ledge_entrances.pop() + lw_entrances.remove(hc_ledge_must_exit) + lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit) + + if aga_door in lw_entrances: + lw_entrances.remove(aga_door) + elif aga_door in dw_entrances: + dw_entrances.remove(aga_door) + + connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) + dungeon_exits.remove('Agahnims Tower Exit') + + connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) + elif world.mode[player] == 'standard': # rest of hyrule castle must be in light world, so it has to be the one connected to east exit of desert hyrule_castle_exits = [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')] connect_mandatory_exits(world, lw_entrances, hyrule_castle_exits, list(LW_Dungeon_Entrances_Must_Exit), player) @@ -69,23 +142,25 @@ def link_entrances(world, player): connect_caves(world, lw_entrances, [], hyrule_castle_exits, player) else: connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) - connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) + + if not invFlag: + connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) elif world.shuffle[player] == 'simple': simple_shuffle_dungeons(world, player) - old_man_entrances = list(Old_Man_Entrances) + old_man_entrances = list(Old_Man_Entrances) if not invFlag else list(Inverted_Old_Man_Entrances) caves = list(Cave_Exits) three_exit_caves = list(Cave_Three_Exits) single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) + ['Links House'] - door_targets = list(Single_Cave_Targets) + bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) if not invFlag else list(Inverted_Bomb_Shop_Single_Cave_Doors) + blacksmith_doors = list(Blacksmith_Single_Cave_Doors) + (['Links House'] if not invFlag else []) + door_targets = list(Single_Cave_Targets) if not invFlag else list(Inverted_Single_Cave_Targets) # we shuffle all 2 entrance caves as pairs as a start # start with the ones that need to be directed - two_door_caves = list(Two_Door_Caves_Directional) + two_door_caves = list(Two_Door_Caves_Directional) if not invFlag else list(Inverted_Two_Door_Caves_Directional) random.shuffle(two_door_caves) random.shuffle(caves) while two_door_caves: @@ -95,7 +170,7 @@ def link_entrances(world, player): connect_two_way(world, entrance2, exit2, player) # now the remaining pairs - two_door_caves = list(Two_Door_Caves) + two_door_caves = list(Two_Door_Caves) if not invFlag else list(Inverted_Two_Door_Caves) random.shuffle(two_door_caves) while two_door_caves: entrance1, entrance2 = two_door_caves.pop() @@ -105,9 +180,12 @@ def link_entrances(world, player): # place links house if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' + links_house = 'Links House' if not invFlag else 'Big Bomb Shop' else: - links_house_doors = [i for i in LW_Single_Cave_Doors if i not in Isolated_LH_Doors_Open] + if not invFlag: + links_house_doors = [i for i in LW_Single_Cave_Doors if i not in Isolated_LH_Doors_Open] + else: + links_house_doors = [i for i in DW_Single_Cave_Doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house @@ -115,19 +193,46 @@ def link_entrances(world, player): bomb_shop_doors.remove(links_house) if links_house in blacksmith_doors: blacksmith_doors.remove(links_house) + if links_house in old_man_entrances: + old_man_entrances.remove(links_house) + if links_house in single_doors: + single_doors.remove(links_house) + + if invFlag: + # place dark sanc + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in bomb_shop_doors] + sanc_door = random.choice(sanc_doors) + bomb_shop_doors.remove(sanc_door) + + connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) + world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) # at this point only Light World death mountain entrances remain # place old man, has limited options - remaining_entrances = ['Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', - 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)'] random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() - remaining_entrances.extend(old_man_entrances) - random.shuffle(remaining_entrances) - old_man_entrance = remaining_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + if not invFlag: + remaining_entrances = ['Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', + 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)'] + + remaining_entrances.extend(old_man_entrances) + random.shuffle(remaining_entrances) + old_man_entrance = remaining_entrances.pop() + connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + else: + remaining_entrances = ['Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Old Man House (Bottom)', + 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave (Bottom)', 'Old Man Cave (East)', + 'Death Mountain Return Cave (East)', 'Spiral Cave', 'Old Man House (Top)', 'Spectacle Rock Cave', + 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)'] + + # place old man, bumper cave bottom to DDM entrances not in east bottom + connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player) connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) + if invFlag and old_man_exit == 'Spike Cave': + bomb_shop_doors.remove('Spike Cave') + bomb_shop_doors.extend(old_man_entrances) + # add old man house to ensure it is always somewhere on light death mountain caves.extend(list(Old_Man_House)) caves.extend(list(three_exit_caves)) @@ -153,49 +258,83 @@ def link_entrances(world, player): # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) + assert(len(single_doors) == len(door_targets)) + # place remaining doors connect_doors(world, single_doors, door_targets, player) elif world.shuffle[player] == 'restricted': simple_shuffle_dungeons(world, player) - lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) - dw_entrances = list(DW_Entrances + DW_Single_Cave_Doors) - dw_must_exits = list(DW_Entrances_Must_Exit) - old_man_entrances = list(Old_Man_Entrances) - caves = list(Cave_Exits + Cave_Three_Exits) - single_doors = list(Single_Cave_Doors) - 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) + if not invFlag: + lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) + dw_entrances = list(DW_Entrances + DW_Single_Cave_Doors) + dw_must_exits = list(DW_Entrances_Must_Exit) + old_man_entrances = list(Old_Man_Entrances) + caves = list(Cave_Exits + Cave_Three_Exits) + single_doors = list(Single_Cave_Doors) + 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) + else: + lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Single_Cave_Doors) + dw_entrances = list(Inverted_DW_Entrances + Inverted_DW_Single_Cave_Doors + Inverted_Old_Man_Entrances) + lw_must_exits = list(Inverted_LW_Entrances_Must_Exit) + old_man_entrances = list(Inverted_Old_Man_Entrances) + caves = list(Cave_Exits + Cave_Three_Exits + Old_Man_House) + single_doors = list(Single_Cave_Doors) + bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) + door_targets = list(Inverted_Single_Cave_Targets) # place links house if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' + links_house = 'Links House' if not invFlag else 'Big Bomb Shop' else: - links_house_doors = [i for i in lw_entrances if i not in Isolated_LH_Doors_Open] + if not invFlag: + links_house_doors = [i for i in lw_entrances if i not in Isolated_LH_Doors_Open] + else: + links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in lw_entrances: - lw_entrances.remove(links_house) + if not invFlag: + if links_house in lw_entrances: + lw_entrances.remove(links_house) + else: + if links_house in dw_entrances: + dw_entrances.remove(links_house) + + if invFlag: + # place dark sanc + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] + sanc_door = random.choice(sanc_doors) + dw_entrances.remove(sanc_door) + connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) + world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) - # in restricted, the only mandatory exits are in dark world - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + # in restricted, the only mandatory exits are in dark world (lw in inverted) + if not invFlag: + connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + else: + connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) # 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] + old_man_entrances = [door for door in old_man_entrances if door in (lw_entrances if not invFlag else dw_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)', player) - lw_entrances.remove(old_man_exit) + if not invFlag: + lw_entrances.remove(old_man_exit) + else: + dw_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) + # cannot place it anywhere already taken (or that are otherwise not eligible for placement) blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances] random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() @@ -208,7 +347,7 @@ def link_entrances(world, player): # place bomb shop, has limited options all_entrances = lw_entrances + dw_entrances - # cannot place it anywhere already taken (or that are otherwise not eligable for placement) + # cannot place it anywhere already taken (or that are otherwise not eligible 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() @@ -226,13 +365,17 @@ def link_entrances(world, player): removed = True # place the old man cave's entrance somewhere in the light world - random.shuffle(lw_entrances) - old_man_entrance = lw_entrances.pop() + if not invFlag: + random.shuffle(lw_entrances) + old_man_entrance = lw_entrances.pop() + else: + random.shuffle(dw_entrances) + old_man_entrance = dw_entrances.pop() connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - # place Old Man House in Light World - connect_caves(world, lw_entrances, [], list(Old_Man_House), player) #for multiple seeds - + if not invFlag: + # place Old Man House in Light World + connect_caves(world, lw_entrances, [], list(Old_Man_House), player) #for multiple seeds # now scramble the rest connect_caves(world, lw_entrances, dw_entrances, caves, player) @@ -249,16 +392,35 @@ def link_entrances(world, player): elif world.shuffle[player] == 'full': skull_woods_shuffle(world, player) - 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) - old_man_house = list(Old_Man_House) + if not invFlag: + 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) + old_man_house = list(Old_Man_House) + else: + lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors) + dw_entrances = list(Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors + Inverted_Old_Man_Entrances) + lw_must_exits = list(Inverted_LW_Dungeon_Entrances_Must_Exit + Inverted_LW_Entrances_Must_Exit) + old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Ganons Tower', '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(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) + door_targets = list(Inverted_Single_Cave_Targets) + old_man_house = list(Old_Man_House) + + # randomize which desert ledge door is a must-exit + if random.randint(0, 1) == 0: + lw_must_exits.append('Desert Palace Entrance (North)') + lw_entrances.append('Desert Palace Entrance (West)') + else: + lw_must_exits.append('Desert Palace Entrance (West)') + lw_entrances.append('Desert Palace Entrance (North)') # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) @@ -266,33 +428,75 @@ def link_entrances(world, player): if world.mode[player] == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - elif world.doorShuffle[player] != 'vanilla': + elif not invFlag and world.doorShuffle[player] != 'vanilla': lw_entrances.append('Hyrule Castle Entrance (South)') else: caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3))) lw_entrances.append('Hyrule Castle Entrance (South)') if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: - dw_entrances.append('Ganons Tower') + if not invFlag: + dw_entrances.append('Ganons Tower') + else: + lw_entrances.append('Agahnims Tower') caves.append('Ganons Tower Exit') + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] + + if invFlag: + # shuffle aga door first. if it's on hc ledge, then one other hc ledge door has to be must_exit + all_entrances_aga = lw_entrances + dw_entrances + aga_doors = [i for i in all_entrances_aga if world.shufflelinks[player] or i != 'Big Bomb Shop'] + random.shuffle(aga_doors) + aga_door = aga_doors.pop() + + if aga_door in hc_ledge_entrances: + lw_entrances.remove(aga_door) + hc_ledge_entrances.remove(aga_door) + + random.shuffle(hc_ledge_entrances) + hc_ledge_must_exit = hc_ledge_entrances.pop() + lw_entrances.remove(hc_ledge_must_exit) + lw_must_exits.append(hc_ledge_must_exit) + if aga_door in lw_entrances: + lw_entrances.remove(aga_door) + elif aga_door in dw_entrances: + dw_entrances.remove(aga_door) + connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) + caves.remove('Agahnims Tower Exit') # place links house if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' + links_house = 'Links House' if not invFlag else 'Big Bomb Shop' else: - links_house_doors = [i for i in lw_entrances + lw_must_exits if i not in Isolated_LH_Doors_Open] + if not invFlag: + links_house_doors = [i for i in lw_entrances + lw_must_exits if i not in Isolated_LH_Doors_Open] + else: + links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in lw_entrances: - lw_entrances.remove(links_house) - if links_house in lw_must_exits: - lw_must_exits.remove(links_house) + if not invFlag: + if links_house in lw_entrances: + lw_entrances.remove(links_house) + if links_house in lw_must_exits: + lw_must_exits.remove(links_house) + else: + if links_house in dw_entrances: + dw_entrances.remove(links_house) + + # place dark sanc + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] + sanc_door = random.choice(sanc_doors) + dw_entrances.remove(sanc_door) + connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) + world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) # we randomize which world requirements we fulfill first so we get better dungeon distribution - #we also places the Old Man House at this time to make sure he can be connected to the desert one way + # we also places the Old Man House at this time to make sure he can be connected to the desert one way + # no dw must exits in inverted, but we randomize whether cave is in light or dark world if random.randint(0, 1) == 0: caves += old_man_house connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) @@ -302,35 +506,46 @@ def link_entrances(world, player): pass else: #if the cave wasn't placed we get here connect_caves(world, lw_entrances, [], old_man_house, player) - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + if not invFlag: + connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) else: - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) - caves += old_man_house - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - try: - caves.remove(old_man_house[0]) - except ValueError: - pass - else: # if the cave wasn't placed we get here - connect_caves(world, lw_entrances, [], old_man_house, player) + if not invFlag: + connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + caves += old_man_house + connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + try: + caves.remove(old_man_house[0]) + except ValueError: + pass + else: # if the cave wasn't placed we get here + connect_caves(world, lw_entrances, [], old_man_house, player) + else: + connect_caves(world, dw_entrances, [], old_man_house, player) + connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + if world.mode[player] == 'standard': # rest of hyrule castle must be in light world connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) # in full, Sanc must be in light world, so must all of HC if door shuffle is on - elif world.doorShuffle[player] != 'vanilla': + elif not invFlag and world.doorShuffle[player] != 'vanilla': connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)')], player) # 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] + old_man_entrances = [door for door in old_man_entrances if door in lw_entrances + (dw_entrances if invFlag else [])] random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - lw_entrances.remove(old_man_exit) + if old_man_exit in dw_entrances: + dw_entrances.remove(old_man_exit) + old_man_world = 'dark' + elif old_man_exit in lw_entrances: + lw_entrances.remove(old_man_exit) + old_man_world = 'light' # 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) + # cannot place it anywhere already taken (or that are otherwise not eligible for placement) blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances] random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() @@ -343,7 +558,7 @@ def link_entrances(world, player): # place bomb shop, has limited options all_entrances = lw_entrances + dw_entrances - # cannot place it anywhere already taken (or that are otherwise not eligable for placement) + # cannot place it anywhere already taken (or that are otherwise not eligible 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() @@ -360,8 +575,13 @@ def link_entrances(world, player): lw_entrances.remove('Bonk Fairy (Light)') removed = True - # place the old man cave's entrance somewhere in the light world - old_man_entrance = lw_entrances.pop() + # place the old man cave's entrance somewhere in the same world he'll exit from + if old_man_world == 'light': + random.shuffle(lw_entrances) + old_man_entrance = lw_entrances.pop() + elif old_man_world == 'dark': + random.shuffle(dw_entrances) + old_man_entrance = dw_entrances.pop() connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest @@ -380,14 +600,32 @@ def link_entrances(world, player): elif world.shuffle[player] == 'crossed': skull_woods_shuffle(world, player) - 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) + if not invFlag: + 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 + Old_Man_House) # 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) + old_man_entrances = list(Old_Man_Entrances + ['Tower of Hera']) + caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits + Old_Man_House) # 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) + else: + entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors) + must_exits = list(Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit) + + old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Ganons Tower', 'Tower of Hera']) + caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits + Old_Man_House) # don't need to consider three exit caves, have one exit caves to avoid parity issues + bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) + door_targets = list(Inverted_Single_Cave_Targets) + + # randomize which desert ledge door is a must-exit + if random.randint(0, 1) == 0: + must_exits.append('Desert Palace Entrance (North)') + entrances.append('Desert Palace Entrance (West)') + else: + must_exits.append('Desert Palace Entrance (West)') + entrances.append('Desert Palace Entrance (North)') # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) @@ -400,17 +638,39 @@ def link_entrances(world, player): entrances.append('Hyrule Castle Entrance (South)') if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: - entrances.append('Ganons Tower') + entrances.append('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower') caves.append('Ganons Tower Exit') + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] + if invFlag: + # shuffle aga door. if it's on hc ledge, then one other hc ledge door has to be must_exit + aga_choices = [x for x in entrances if world.shufflelinks[player] or x != 'Big Bomb Shop'] + aga_door = random.choice(aga_choices) + + if aga_door in hc_ledge_entrances: + hc_ledge_entrances.remove(aga_door) + + random.shuffle(hc_ledge_entrances) + hc_ledge_must_exit = hc_ledge_entrances.pop() + entrances.remove(hc_ledge_must_exit) + must_exits.append(hc_ledge_must_exit) + + entrances.remove(aga_door) + connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) + caves.remove('Agahnims Tower Exit') + # place links house if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' + links_house = 'Links House' if not invFlag else 'Big Bomb Shop' else: - links_house_doors = [i for i in entrances + must_exits if i not in Isolated_LH_Doors_Open] - if world.doorShuffle[player] == 'crossed' and world.intensity[player] >= 3: + if not invFlag: + links_house_doors = [i for i in entrances + must_exits if i not in Isolated_LH_Doors_Open] + else: + links_house_doors = [i for i in entrances + must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] + if not invFlag and world.doorShuffle[player] == 'crossed' and world.intensity[player] >= 3: exclusions = DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors\ + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Ganons Tower'] links_house_doors = [i for i in links_house_doors if i not in exclusions] @@ -422,6 +682,14 @@ def link_entrances(world, player): elif links_house in must_exits: must_exits.remove(links_house) + if invFlag: + # place dark sanc + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances] + sanc_door = random.choice(sanc_doors) + entrances.remove(sanc_door) + connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) + world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + #place must-exit caves connect_mandatory_exits(world, entrances, caves, must_exits, player) @@ -438,17 +706,17 @@ def link_entrances(world, player): entrances.remove(old_man_exit) # place blacksmith, has limited options - # cannot place it anywhere already taken (or that are otherwise not eligable for placement) + # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) entrances.remove(blacksmith_hut) - bomb_shop_doors.extend(blacksmith_doors) + if not invFlag: + bomb_shop_doors.extend(blacksmith_doors) # place bomb shop, has limited options - - # cannot place it anywhere already taken (or that are otherwise not eligable for placement) + # cannot place it anywhere already taken (or that are otherwise not eligible 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() @@ -481,31 +749,54 @@ def link_entrances(world, player): elif world.shuffle[player] == 'insanity': # beware ye who enter here - entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)'] + if not invFlag: + 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'] + Old_Man_Entrances +\ - DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\ - LW_Single_Cave_Doors + DW_Single_Cave_Doors - exit_pool = list(doors) + 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'] + Old_Man_Entrances +\ + DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\ + LW_Single_Cave_Doors + DW_Single_Cave_Doors + exit_pool = list(doors) - # TODO: there are other possible entrances we could support here by way of exiting from a connector, - # and rentering to find bomb shop. However appended list here is all those that we currently have - # bomb shop logic for. - # Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors + Bomb_Shop_Multi_Cave_Doors+['Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance']) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) - door_targets = list(Single_Cave_Targets) + # TODO: there are other possible entrances we could support here by way of exiting from a connector, + # and rentering to find bomb shop. However appended list here is all those that we currently have + # bomb shop logic for. + # Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits + bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors + Bomb_Shop_Multi_Cave_Doors+['Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance']) + blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) + door_targets = list(Single_Cave_Targets) + else: + entrances_must_exits = Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit + + doors = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Entrances_Must_Exit + Inverted_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'] + Inverted_Old_Man_Entrances +\ + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\ + Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'] + exit_pool = list(doors) + + # TODO: there are other possible entrances we could support here by way of exiting from a connector, + # and rentering to find bomb shop. However appended list here is all those that we currently have + # bomb shop logic for. + # Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits + bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + ['Turtle Rock Isolated Ledge Entrance', 'Hookshot Cave Back Entrance']) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) + door_targets = list(Inverted_Single_Cave_Targets) + + # randomize which desert ledge door is a must-exit + if random.randint(0, 1) == 0: + entrances_must_exits.append('Desert Palace Entrance (North)') + else: + entrances_must_exits.append('Desert Palace Entrance (West)') random.shuffle(doors) old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera'] + if invFlag: + old_man_entrances += list(Inverted_Old_Man_Entrances) + ['Ganons Tower'] 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'] # shuffle up holes - hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] @@ -523,21 +814,23 @@ def link_entrances(world, player): else: hole_entrances.append('Hyrule Castle Secret Entrance Drop') hole_targets.append('Hyrule Castle Secret Entrance') - doors.append('Hyrule Castle Secret Entrance Stairs') - exit_pool.append('Hyrule Castle Secret Entrance Stairs') caves.append('Hyrule Castle Secret Entrance Exit') + if not invFlag: + doors.append('Hyrule Castle Secret Entrance Stairs') + exit_pool.append('Hyrule Castle Secret Entrance Stairs') if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) - connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Pyramid Hole', 'Pyramid', player) + connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Pyramid Entrance' if not invFlag else 'Inverted Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(world, 'Pyramid Hole' if not invFlag else 'Inverted Pyramid Hole', 'Pyramid', player) else: caves.extend(['Ganons Tower Exit', 'Pyramid Exit']) - hole_entrances.append('Pyramid Hole') + hole_entrances.append('Pyramid Hole' if not invFlag else 'Inverted Pyramid Hole') hole_targets.append('Pyramid') - entrances_must_exits.append('Pyramid Entrance') - exit_pool.extend(['Ganons Tower', 'Pyramid Entrance']) - doors.extend(['Ganons Tower', 'Pyramid Entrance']) + if not invFlag: + entrances_must_exits.append('Pyramid Entrance') + exit_pool.extend(['Ganons Tower', 'Pyramid Entrance'] if not invFlag else ['Agahnims Tower', 'Inverted Pyramid Entrance']) + doors.extend(['Ganons Tower', 'Pyramid Entrance'] if not invFlag else ['Agahnims Tower', 'Inverted Pyramid Entrance']) random.shuffle(hole_entrances) random.shuffle(hole_targets) @@ -555,15 +848,19 @@ def link_entrances(world, player): caves.append(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) else: doors.append('Hyrule Castle Entrance (South)') - exit_pool.append('Hyrule Castle Entrance (South)') caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) + if not invFlag: + exit_pool.append('Hyrule Castle Entrance (South)') # place links house if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' + links_house = 'Links House' if not invFlag else 'Big Bomb Shop' else: - links_house_doors = [i for i in doors if i not in Isolated_LH_Doors_Open] - if world.doorShuffle[player] == 'crossed' and world.intensity[player] >= 3: + if not invFlag: + links_house_doors = [i for i in doors if i not in Isolated_LH_Doors_Open] + else: + links_house_doors = [i for i in doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] + if not invFlag and world.doorShuffle[player] == 'crossed' and world.intensity[player] >= 3: exclusions = DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors \ + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Ganons Tower'] links_house_doors = [i for i in links_house_doors if i not in exclusions] @@ -573,6 +870,15 @@ def link_entrances(world, player): exit_pool.remove(links_house) doors.remove(links_house) + if invFlag: + # place dark sanc + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in exit_pool] + sanc_door = random.choice(sanc_doors) + exit_pool.remove(sanc_door) + doors.remove(sanc_door) + connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) + world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + # now let's deal with mandatory reachable stuff def extract_reachable_exit(cavelist): random.shuffle(cavelist) @@ -663,713 +969,11 @@ def link_entrances(world, player): world.powder_patch_required[player] = True # check for ganon location - if world.get_entrance('Pyramid Hole', player).connected_region.name != 'Pyramid': + if world.get_entrance('Pyramid Hole' if not invFlag else 'Inverted Pyramid Hole', player).connected_region.name != 'Pyramid': world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - if world.get_entrance('Ganons Tower', player).connected_region.name != 'Ganons Tower Portal': - world.ganonstower_vanilla[player] = False - -def link_inverted_entrances(world, player): - # Link's house shuffled freely, Houlihan set in mandatory_connections - - Dungeon_Exits = Inverted_Dungeon_Exits_Base.copy() - Cave_Exits = Cave_Exits_Base.copy() - Old_Man_House = Old_Man_House_Base.copy() - Cave_Three_Exits = Cave_Three_Exits_Base.copy() - - unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) - - # setup mandatory connections - for exitname, regionname in inverted_mandatory_connections: - connect_simple(world, exitname, regionname, player) - - # if we do not shuffle, set default connections - if world.shuffle[player] == 'vanilla': - for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) - for exitname, regionname in inverted_default_dungeon_connections: - connect_simple(world, exitname, regionname, player) - elif world.shuffle[player] == 'dungeonssimple': - for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) - - simple_shuffle_dungeons(world, player) - elif world.shuffle[player] == 'dungeonsfull': - for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) - - skull_woods_shuffle(world, player) - - dungeon_exits = list(Dungeon_Exits) - lw_entrances = list(Inverted_LW_Dungeon_Entrances) - lw_dungeon_entrances_must_exit = list(Inverted_LW_Dungeon_Entrances_Must_Exit) - dw_entrances = list(Inverted_DW_Dungeon_Entrances) - - # randomize which desert ledge door is a must-exit - if random.randint(0, 1) == 0: - lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') - lw_entrances.append('Desert Palace Entrance (West)') - else: - lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (West)') - lw_entrances.append('Desert Palace Entrance (North)') - - dungeon_exits.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, 'Agahnims Tower', 'Ganons Tower Exit', player) - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] - else: - lw_entrances.append('Agahnims Tower') - dungeon_exits.append('Ganons Tower Exit') - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] - - # shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit - all_entrances_aga = lw_entrances + dw_entrances - aga_doors = [i for i in all_entrances_aga] - random.shuffle(aga_doors) - aga_door = aga_doors.pop() - - if aga_door in hc_ledge_entrances: - lw_entrances.remove(aga_door) - hc_ledge_entrances.remove(aga_door) - - random.shuffle(hc_ledge_entrances) - hc_ledge_must_exit = hc_ledge_entrances.pop() - lw_entrances.remove(hc_ledge_must_exit) - lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit) - - if aga_door in lw_entrances: - lw_entrances.remove(aga_door) - elif aga_door in dw_entrances: - dw_entrances.remove(aga_door) - - connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) - dungeon_exits.remove('Agahnims Tower Exit') - - connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) - - connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) - - elif world.shuffle[player] == 'simple': - simple_shuffle_dungeons(world, player) - - old_man_entrances = list(Inverted_Old_Man_Entrances) - caves = list(Cave_Exits) - three_exit_caves = list(Cave_Three_Exits) - - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) - door_targets = list(Inverted_Single_Cave_Targets) - - # we shuffle all 2 entrance caves as pairs as a start - # start with the ones that need to be directed - two_door_caves = list(Inverted_Two_Door_Caves_Directional) - random.shuffle(two_door_caves) - random.shuffle(caves) - while two_door_caves: - entrance1, entrance2 = two_door_caves.pop() - exit1, exit2 = caves.pop() - connect_two_way(world, entrance1, exit1, player) - connect_two_way(world, entrance2, exit2, player) - - # now the remaining pairs - two_door_caves = list(Inverted_Two_Door_Caves) - random.shuffle(two_door_caves) - while two_door_caves: - entrance1, entrance2 = two_door_caves.pop() - exit1, exit2 = caves.pop() - connect_two_way(world, entrance1, exit1, player) - connect_two_way(world, entrance2, exit2, player) - - # place links house - if not world.shufflelinks[player]: - links_house = 'Big Bomb Shop' - else: - links_house_doors = [i for i in DW_Single_Cave_Doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) - connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in bomb_shop_doors: - bomb_shop_doors.remove(links_house) - if links_house in blacksmith_doors: - blacksmith_doors.remove(links_house) - if links_house in old_man_entrances: - old_man_entrances.remove(links_house) - - # place dark sanc - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in bomb_shop_doors] - sanc_door = random.choice(sanc_doors) - bomb_shop_doors.remove(sanc_door) - - connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) - world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) - - lw_dm_entrances = ['Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Old Man House (Bottom)', - 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave (Bottom)', 'Old Man Cave (East)', - 'Death Mountain Return Cave (East)', 'Spiral Cave', 'Old Man House (Top)', 'Spectacle Rock Cave', - 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)'] - - # place old man, bumper cave bottom to DDM entrances not in east bottom - - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player) - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - if old_man_exit == 'Spike Cave': - bomb_shop_doors.remove('Spike Cave') - bomb_shop_doors.extend(old_man_entrances) - - # add old man house to ensure it is always somewhere on light death mountain - caves.extend(list(Old_Man_House)) - caves.extend(list(three_exit_caves)) - - # connect rest - connect_caves(world, lw_dm_entrances, [], caves, player) - - # scramble holes - scramble_inverted_holes(world, player) - - # place blacksmith, has limited options - blacksmith_doors = [door for door in blacksmith_doors[:]] - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - bomb_shop_doors.extend(blacksmith_doors) - - # place bomb shop, has limited options - bomb_shop_doors = [door for door in bomb_shop_doors[:]] - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - single_doors.extend(bomb_shop_doors) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place remaining doors - connect_doors(world, single_doors, door_targets, player) - - elif world.shuffle[player] == 'restricted': - simple_shuffle_dungeons(world, player) - - lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Single_Cave_Doors) - dw_entrances = list(Inverted_DW_Entrances + Inverted_DW_Single_Cave_Doors + Inverted_Old_Man_Entrances) - lw_must_exits = list(Inverted_LW_Entrances_Must_Exit) - old_man_entrances = list(Inverted_Old_Man_Entrances) - caves = list(Cave_Exits + Cave_Three_Exits + Old_Man_House) - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) - door_targets = list(Inverted_Single_Cave_Targets) - - # place links house - if not world.shufflelinks[player]: - links_house = 'Big Bomb Shop' - else: - links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) - connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in dw_entrances: - dw_entrances.remove(links_house) - - # place dark sanc - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] - sanc_door = random.choice(sanc_doors) - dw_entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) - world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place must exits - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - - # 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 dw_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)', player) - dw_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 eligible 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', player) - 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 bomb shop, has limited options - all_entrances = lw_entrances + dw_entrances - # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) - 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 dark world - random.shuffle(dw_entrances) - old_man_entrance = dw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - - # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) - - # scramble holes - scramble_inverted_holes(world, player) - - doors = lw_entrances + dw_entrances - # place remaining doors - connect_doors(world, doors, door_targets, player) - elif world.shuffle[player] == 'full': - skull_woods_shuffle(world, player) - - lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors) - dw_entrances = list(Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors + Inverted_Old_Man_Entrances) - lw_must_exits = list(Inverted_LW_Dungeon_Entrances_Must_Exit + Inverted_LW_Entrances_Must_Exit) - old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Ganons Tower', '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(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) - door_targets = list(Inverted_Single_Cave_Targets) - old_man_house = list(Old_Man_House) - - # randomize which desert ledge door is a must-exit - if random.randint(0, 1) == 0: - lw_must_exits.append('Desert Palace Entrance (North)') - lw_entrances.append('Desert Palace Entrance (West)') - else: - lw_must_exits.append('Desert Palace Entrance (West)') - lw_entrances.append('Desert Palace Entrance (North)') - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3))) - lw_entrances.append('Hyrule Castle Entrance (South)') - - - if not world.shuffle_ganon: - connect_two_way(world, 'Agahnims Tower', 'Ganons Tower Exit', player) - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] - else: - lw_entrances.append('Agahnims Tower') - caves.append('Ganons Tower Exit') - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] - - # shuffle aga door first. if it's on hc ledge, then one other hc ledge door has to be must_exit - all_entrances_aga = lw_entrances + dw_entrances - aga_doors = [i for i in all_entrances_aga if world.shufflelinks[player] or i != 'Big Bomb Shop'] - random.shuffle(aga_doors) - aga_door = aga_doors.pop() - - if aga_door in hc_ledge_entrances: - lw_entrances.remove(aga_door) - hc_ledge_entrances.remove(aga_door) - - random.shuffle(hc_ledge_entrances) - hc_ledge_must_exit = hc_ledge_entrances.pop() - lw_entrances.remove(hc_ledge_must_exit) - lw_must_exits.append(hc_ledge_must_exit) - - if aga_door in lw_entrances: - lw_entrances.remove(aga_door) - elif aga_door in dw_entrances: - dw_entrances.remove(aga_door) - - connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) - caves.remove('Agahnims Tower Exit') - - # place links house - if not world.shufflelinks[player]: - links_house = 'Big Bomb Shop' - else: - links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) - connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in dw_entrances: - dw_entrances.remove(links_house) - - # place dark sanc - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] - sanc_door = random.choice(sanc_doors) - dw_entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) - world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) - - # place old man house - # no dw must exits in inverted, but we randomize whether cave is in light or dark world - if random.randint(0, 1) == 0: - caves += old_man_house - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - try: - caves.remove(old_man_house[0]) - except ValueError: - pass - else: #if the cave wasn't placed we get here - connect_caves(world, lw_entrances, [], old_man_house, player) - else: - connect_caves(world, dw_entrances, [], old_man_house, player) - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - - # 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 dw_entrances + 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)', player) - if old_man_exit in dw_entrances: - dw_entrances.remove(old_man_exit) - old_man_world = 'dark' - elif old_man_exit in lw_entrances: - lw_entrances.remove(old_man_exit) - old_man_world = 'light' - - # place blacksmith, has limited options - all_entrances = lw_entrances + dw_entrances - # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) - 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 bomb shop, has limited options - all_entrances = lw_entrances + dw_entrances - # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) - 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 same world he'll exit from - if old_man_world == 'light': - random.shuffle(lw_entrances) - old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - elif old_man_world == 'dark': - random.shuffle(dw_entrances) - old_man_entrance = dw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - - # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) - - # scramble holes - scramble_inverted_holes(world, player) - - doors = lw_entrances + dw_entrances - - # place remaining doors - connect_doors(world, doors, door_targets, player) - elif world.shuffle[player] == 'crossed': - skull_woods_shuffle(world, player) - - entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors) - must_exits = list(Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit) - - old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Ganons Tower', 'Tower of Hera']) - caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits + Old_Man_House) # don't need to consider three exit caves, have one exit caves to avoid parity issues - bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) - door_targets = list(Inverted_Single_Cave_Targets) - - # randomize which desert ledge door is a must-exit - if random.randint(0, 1) == 0: - must_exits.append('Desert Palace Entrance (North)') - entrances.append('Desert Palace Entrance (West)') - else: - must_exits.append('Desert Palace Entrance (West)') - entrances.append('Desert Palace Entrance (North)') - - caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3))) - entrances.append('Hyrule Castle Entrance (South)') - - if not world.shuffle_ganon: - connect_two_way(world, 'Agahnims Tower', 'Ganons Tower Exit', player) - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] - else: - entrances.append('Agahnims Tower') - caves.append('Ganons Tower Exit') - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] - - # shuffle aga door. if it's on hc ledge, then one other hc ledge door has to be must_exit - aga_choices = [x for x in entrances if world.shufflelinks[player] or x != 'Big Bomb Shop'] - aga_door = random.choice(aga_choices) - - if aga_door in hc_ledge_entrances: - hc_ledge_entrances.remove(aga_door) - - random.shuffle(hc_ledge_entrances) - hc_ledge_must_exit = hc_ledge_entrances.pop() - entrances.remove(hc_ledge_must_exit) - must_exits.append(hc_ledge_must_exit) - - entrances.remove(aga_door) - connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) - caves.remove('Agahnims Tower Exit') - - # place links house - if not world.shufflelinks[player]: - links_house = 'Big Bomb Shop' - else: - links_house_doors = [i for i in entrances + must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) - connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - if links_house in entrances: - entrances.remove(links_house) - elif links_house in must_exits: - must_exits.remove(links_house) - - # place dark sanc - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances] - sanc_door = random.choice(sanc_doors) - entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) - world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - - #place must-exit caves - connect_mandatory_exits(world, entrances, caves, must_exits, player) - - - # 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)', player) - entrances.remove(old_man_exit) - - # place blacksmith, has limited options - # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) - entrances.remove(blacksmith_hut) - - # place bomb shop, has limited options - - # cannot place it anywhere already taken (or that are otherwise not eligible 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', player) - entrances.remove(bomb_shop) - - # place the old man cave's entrance somewhere - random.shuffle(entrances) - old_man_entrance = entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - - # now scramble the rest - connect_caves(world, entrances, [], caves, player) - - # scramble holes - scramble_inverted_holes(world, player) - - # place remaining doors - connect_doors(world, entrances, door_targets, player) - elif world.shuffle[player] == 'insanity': - # beware ye who enter here - - entrances_must_exits = Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit - - doors = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Entrances_Must_Exit + Inverted_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'] + Inverted_Old_Man_Entrances +\ - Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\ - Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'] - exit_pool = list(doors) - - # randomize which desert ledge door is a must-exit - if random.randint(0, 1) == 0: - entrances_must_exits.append('Desert Palace Entrance (North)') - else: - entrances_must_exits.append('Desert Palace Entrance (West)') - - # TODO: there are other possible entrances we could support here by way of exiting from a connector, - # and rentering to find bomb shop. However appended list here is all those that we currently have - # bomb shop logic for. - # Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits - bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + ['Turtle Rock Isolated Ledge Entrance', 'Hookshot Cave Back Entrance']) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) - door_targets = list(Inverted_Single_Cave_Targets) - - random.shuffle(doors) - - old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances) + ['Tower of Hera', 'Ganons Tower'] - - 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'] - - - # shuffle up holes - hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', - 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - - hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop', - 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle'] - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - hole_entrances.append('Hyrule Castle Secret Entrance Drop') - hole_targets.append('Hyrule Castle Secret Entrance') - caves.append('Hyrule Castle Secret Entrance Exit') - - if not world.shuffle_ganon: - connect_two_way(world, 'Agahnims Tower', 'Ganons Tower Exit', player) - connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player) - else: - caves.extend(['Ganons Tower Exit', 'Pyramid Exit']) - hole_entrances.append('Inverted Pyramid Hole') - hole_targets.append('Pyramid') - doors.extend(['Agahnims Tower', 'Inverted Pyramid Entrance']) - exit_pool.extend(['Agahnims Tower', 'Inverted Pyramid Entrance']) - - random.shuffle(hole_entrances) - random.shuffle(hole_targets) - random.shuffle(exit_pool) - - # fill up holes - for hole in hole_entrances: - connect_entrance(world, hole, hole_targets.pop(), player) - - doors.append('Hyrule Castle Entrance (South)') - caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - - # place links house and dark sanc - if not world.shufflelinks[player]: - links_house = 'Big Bomb Shop' - else: - links_house_doors = [i for i in doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) - connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house - doors.remove(links_house) - exit_pool.remove(links_house) - - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in exit_pool] - sanc_door = random.choice(sanc_doors) - exit_pool.remove(sanc_door) - doors.remove(sanc_door) - connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player) - world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) - - # now let's deal with mandatory reachable stuff - def extract_reachable_exit(cavelist): - random.shuffle(cavelist) - candidate = None - for cave in cavelist: - if isinstance(cave, tuple) and len(cave) > 1: - # special handling: TRock has two entries that we should consider entrance only - # ToDo this should be handled in a more sensible manner - if cave[0] in ['Turtle Rock Exit (Front)', 'Spectacle Rock Cave Exit (Peak)'] and len(cave) == 2: - continue - candidate = cave - break - if candidate is None: - raise RuntimeError('No suitable cave.') - cavelist.remove(candidate) - return candidate - - def connect_reachable_exit(entrance, caves, doors, exit_pool): - cave = extract_reachable_exit(caves) - - exit = cave[-1] - cave = cave[:-1] - connect_exit(world, exit, entrance, player) - connect_entrance(world, doors.pop(), exit, player) - # rest of cave now is forced to be in this world - exit_pool.remove(entrance) - caves.append(cave) - - # connect mandatory exits - for entrance in entrances_must_exits: - connect_reachable_exit(entrance, caves, doors, exit_pool) - - # 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 = [entrance for entrance in old_man_entrances if entrance in exit_pool] - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - exit_pool.remove(old_man_exit) - - connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player) - connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)', player) - caves.append('Old Man Cave Exit (West)') - - # place blacksmith, has limited options - blacksmith_doors = [door for door in blacksmith_doors if door in doors] - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - doors.remove(blacksmith_hut) - - # place dam and pyramid fairy, have limited options - bomb_shop_doors = [door for door in bomb_shop_doors if door in doors] - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - doors.remove(bomb_shop) - - # handle remaining caves - for cave in caves: - if isinstance(cave, str): - cave = (cave,) - - for exit in cave: - connect_exit(world, exit, exit_pool.pop(), player) - connect_entrance(world, doors.pop(), exit, player) - - # place remaining doors - connect_doors(world, doors, door_targets, player) - else: - raise NotImplementedError('Shuffling not supported yet') - - # check for swamp palace fix - if world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Portal': - world.swamp_patch_required[player] = True - - # check for potion shop location - if world.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': - world.powder_patch_required[player] = True - - # check for ganon location - if world.get_entrance('Inverted Pyramid Hole', player).connected_region.name != 'Pyramid': - world.ganon_at_pyramid[player] = False - - # check for Ganon's Tower location - if world.get_entrance('Agahnims Tower', player).connected_region.name != 'GT Lobby': + if world.get_entrance('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal': world.ganonstower_vanilla[player] = False @@ -1447,8 +1051,12 @@ def scramble_holes(world, player): ('Lumberjack Tree Exit', 'Lumberjack Tree (top)')] if not world.shuffle_ganon: - connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Pyramid Hole', 'Pyramid', player) + if world.mode[player] == 'inverted': + connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player) + else: + connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(world, 'Pyramid Hole', 'Pyramid', player) else: hole_targets.append(('Pyramid Exit', 'Pyramid')) @@ -1466,8 +1074,12 @@ def scramble_holes(world, player): if world.shuffle_ganon: random.shuffle(hole_targets) exit, target = hole_targets.pop() - connect_two_way(world, 'Pyramid Entrance', exit, player) - connect_entrance(world, 'Pyramid Hole', target, player) + if world.mode[player] == 'inverted': + connect_two_way(world, 'Inverted Pyramid Entrance', exit, player) + connect_entrance(world, 'Inverted Pyramid Hole', target, player) + else: + connect_two_way(world, 'Pyramid Entrance', exit, player) + connect_entrance(world, 'Pyramid Hole', target, player) if world.shuffle[player] != 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) @@ -1478,47 +1090,6 @@ def scramble_holes(world, player): connect_entrance(world, drop, target, player) -def scramble_inverted_holes(world, player): - hole_entrances = [('Kakariko Well Cave', 'Kakariko Well Drop'), - ('Bat Cave Cave', 'Bat Cave Drop'), - ('North Fairy Cave', 'North Fairy Cave Drop'), - ('Lost Woods Hideout Stump', 'Lost Woods Hideout Drop'), - ('Lumberjack Tree Cave', 'Lumberjack Tree Tree'), - ('Sanctuary', 'Sanctuary Grave')] - - hole_targets = [('Kakariko Well Exit', 'Kakariko Well (top)'), - ('Bat Cave Exit', 'Bat Cave (right)'), - ('North Fairy Cave Exit', 'North Fairy Cave'), - ('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'), - ('Lumberjack Tree Exit', 'Lumberjack Tree (top)')] - - if not world.shuffle_ganon: - connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player) - else: - hole_targets.append(('Pyramid Exit', 'Pyramid')) - - - hole_entrances.append(('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Drop')) - hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) - - # do not shuffle sanctuary into pyramid hole unless shuffle is crossed - if world.shuffle[player] == 'crossed': - hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - if world.shuffle_ganon: - random.shuffle(hole_targets) - exit, target = hole_targets.pop() - connect_two_way(world, 'Inverted Pyramid Entrance', exit, player) - connect_entrance(world, 'Inverted Pyramid Hole', target, player) - if world.shuffle[player] != 'crossed': - hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - - random.shuffle(hole_targets) - for entrance, drop in hole_entrances: - exit, target = hole_targets.pop() - connect_two_way(world, entrance, exit, player) - connect_entrance(world, drop, target, player) - def connect_random(world, exitlist, targetlist, player, two_way=False): targetlist = list(targetlist) random.shuffle(targetlist) @@ -2494,17 +2065,10 @@ Inverted_Must_Exit_Invalid_Connections = defaultdict(set, { # these are connections that cannot be shuffled and always exist. # They link together separate parts of the world we need to divide into regions mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Other World S&Q', 'East Dark World'), ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), ('Zoras River', 'Zoras River'), - ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), - ('Zora Waterfall Water Drop', 'Light World'), ('Kings Grave Outer Rocks', 'Kings Grave Area'), ('Kings Grave Inner Rocks', 'Light World'), - ('Kings Grave Mirror Spot', 'Kings Grave Area'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), ('Master Sword Meadow', 'Master Sword Meadow'), @@ -2518,10 +2082,7 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Desert Palace Stairs Drop', 'Light World'), ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), ('Sewer Drop', 'Sewers Rat Path'), - ('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)'), @@ -2541,29 +2102,19 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('East Death Mountain (Top)', 'East Death Mountain (Top)'), ('Death Mountain (Top)', 'Death Mountain (Top)'), ('Death Mountain Drop', 'Death Mountain'), - ('Spectacle Rock Drop', 'Death Mountain (Top)'), - - ('Top of Pyramid', 'East Dark World'), ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), ('East Dark World Pier', 'East Dark World'), - ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), - ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), - ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), ('South Dark World Bridge', 'South Dark World'), ('East Dark World Bridge', 'East Dark World'), - ('Maze Race Mirror Spot', 'Maze Race Ledge'), ('Village of Outcasts Heavy Rock', 'West Dark World'), ('Village of Outcasts Drop', 'South Dark World'), ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), ('Peg Area Rocks', 'West Dark World'), ('Grassy Lawn Pegs', 'West Dark World'), - ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), - ('East Dark World River Pier', 'East Dark World'), ('West Dark World Gap', 'West Dark World'), ('East Dark World Broken Bridge Pass', 'East Dark World'), ('Catfish Exit Rock', 'Northeast Dark World'), @@ -2571,21 +2122,10 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Northeast Dark World Broken Bridge Pass', 'Northeast 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 Mirror Spot', 'Death Mountain Return Ledge'), ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Skull Woods Forest', 'Skull Woods Forest'), - ('Desert Ledge Mirror Spot', 'Desert Ledge'), - ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), - ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), - ('Dark Desert Teleporter', 'Dark Desert'), - ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), - ('East Hyrule Teleporter', 'East Dark World'), - ('South Hyrule Teleporter', 'South Dark World'), - ('Kakariko Teleporter', 'West Dark World'), - ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), ('Paradox Cave Push Block', 'Paradox Cave Front'), ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), @@ -2593,17 +2133,12 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Paradox Cave Drop', 'Paradox Cave Chest Area'), ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), - ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), @@ -2611,118 +2146,95 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), - ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), - ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), - ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), - ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), - ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), - ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), ('Ganon Drop', 'Bottom of Pyramid'), ('Pyramid Drop', 'East Dark World'), ('Maze Race Ledge Drop', 'Light World'), - ('Graveyard Ledge Drop', 'Light World'), - ('Cave 45 Ledge Drop', 'Light World'), - ('Checkerboard Ledge Drop', 'Light World'), - ('Desert Ledge Drop', 'Light World'), - ('Hyrule Castle Main Gate (North)', 'Light World'), - ('Hyrule Castle Ledge Drop', 'Light World'), - ] + ('Desert Ledge Drop', 'Light World') + ] -inverted_mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Dark Sanctuary Hint'), +open_mandatory_connections = [('Sanctuary S&Q', 'Sanctuary'), + ('Old Man S&Q', 'Old Man House'), + ('Other World S&Q', 'East Dark World'), + ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), + ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), + ('Zora Waterfall Water Drop', 'Light World'), + ('Kings Grave Mirror Spot', 'Kings Grave Area'), + ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), + ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), + ('Flute Spot 1', 'Death Mountain'), + ('Spectacle Rock Drop', 'Death Mountain (Top)'), + ('Top of Pyramid', 'East Dark World'), + ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), + ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), + ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), + ('Maze Race Mirror Spot', 'Maze Race Ledge'), + ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), + ('East Dark World River Pier', 'East Dark World'), + ('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'), + ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), + ('Desert Ledge Mirror Spot', 'Desert Ledge'), + ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), + ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), + ('Dark Desert Teleporter', 'Dark Desert'), + ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), + ('East Hyrule Teleporter', 'East Dark World'), + ('South Hyrule Teleporter', 'South Dark World'), + ('Kakariko Teleporter', 'West Dark World'), + ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), + ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), + ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), + ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), + ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), + ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), + ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), + ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), + ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), + ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), + ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), + ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), + ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), + ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), + ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), + ('Graveyard Ledge Drop', 'Light World'), + ('Cave 45 Ledge Drop', 'Light World'), + ('Checkerboard Ledge Drop', 'Light World'), + ('Hyrule Castle Main Gate (North)', 'Light World'), + ('Hyrule Castle Ledge Drop', 'Light World'), + ] + +inverted_mandatory_connections = [('Sanctuary S&Q', 'Dark Sanctuary Hint'), ('Old Man S&Q', 'Old Man House'), ('Other World S&Q', 'Hyrule Castle Ledge'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), ('Lake Hylia Island Pier', 'Lake Hylia Island'), ('Lake Hylia Warp', 'Northeast Light World'), ('Northeast Light World Warp', 'Light World'), - ('Zoras River', 'Zoras River'), ('Waterfall of Wishing Cave', 'Waterfall of Wishing Cave'), ('Northeast Light World Return', 'Northeast Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), - ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), - ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), - ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Sewer Drop', 'Sewers Rat Path'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), - ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), - ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), + ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), + ('DDM Flute', 'The Sky'), + ('DDM Landing', 'Dark Death Mountain'), + ('NEDW Flute', 'The Sky'), + ('NEDW Landing', 'Northeast Dark World'), + ('WDW Flute', 'The Sky'), + ('WDW Landing', 'West Dark World'), + ('SDW Flute', 'The Sky'), + ('SDW Landing', 'South Dark World'), + ('EDW Flute', 'The Sky'), + ('EDW Landing', 'East Dark World'), + ('DLHL Flute', 'The Sky'), + ('DLHL Landing', 'Dark Lake Hylia Ledge'), + ('DD Flute', 'The Sky'), + ('DD Landing', 'Dark Desert Ledge'), + ('EDDM Flute', 'The Sky'), + ('Dark Grassy Lawn Flute', 'The Sky'), + ('Hammer Peg Area Flute', 'The Sky'), ('Dark Lake Hylia Ledge Pier', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), ('Ice Palace Missing Wall', 'Dark Lake Hylia Central Island'), ('Dark Lake Hylia Shallows', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), ('East Dark World River Pier', 'Northeast Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), - ('Paradox Cave Push Block', 'Paradox Cave Front'), - ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), - ('Paradox Cave Bomb Jump', 'Paradox Cave'), - ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), ('Fairy Ascension Ledge Access', 'Fairy Ascension Ledge'), - ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), - ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), - ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), ('Post Aga Teleporter', 'Light World'), ('Secret Passage Inner Bushes', 'Light World'), ('Secret Passage Outer Bushes', 'Hyrule Castle Secret Entrance Area'), @@ -2737,19 +2249,10 @@ inverted_mandatory_connections = [('Links House S&Q', 'Links House'), ('Light World River Drop', 'River'), ('Light World Pier', 'Light World'), ('Potion Shop Pier', 'Potion Shop Area'), - ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), ('Mimic Cave Ledge Access', 'Mimic Cave Ledge'), ('Mimic Cave Ledge Drop', 'East Death Mountain (Bottom)'), ('Turtle Rock Tail Drop', 'Turtle Rock (Top)'), ('Turtle Rock Drop', 'Dark Death Mountain'), - ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), - ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), - ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), - ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), - ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Desert Ledge Drop', 'Light World'), ('Floating Island Drop', 'Dark Death Mountain'), ('Dark Lake Hylia Central Island Teleporter', 'Lake Hylia Central Island'), ('Dark Desert Teleporter', 'Light World'), @@ -2783,40 +2286,21 @@ inverted_mandatory_connections = [('Links House S&Q', 'Links House'), ('Catfish Mirror Spot', 'Catfish'), ('Shopping Mall Mirror Spot', 'Dark Lake Hylia Ledge'), ('Skull Woods Mirror Spot', 'Skull Woods Forest (West)'), - ('DDM Flute', 'The Sky'), - ('DDM Landing', 'Dark Death Mountain'), - ('NEDW Flute', 'The Sky'), - ('NEDW Landing', 'Northeast Dark World'), - ('WDW Flute', 'The Sky'), - ('WDW Landing', 'West Dark World'), - ('SDW Flute', 'The Sky'), - ('SDW Landing', 'South Dark World'), - ('EDW Flute', 'The Sky'), - ('EDW Landing', 'East Dark World'), - ('DLHL Flute', 'The Sky'), - ('DLHL Landing', 'Dark Lake Hylia Ledge'), - ('DD Flute', 'The Sky'), - ('DD Landing', 'Dark Desert Ledge'), - ('EDDM Flute', 'The Sky'), - ('Dark Grassy Lawn Flute', 'The Sky'), - ('Hammer Peg Area Flute', 'The Sky'), ('Bush Covered Lawn Inner Bushes', 'Light World'), ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), ('Bomb Hut Inner Bushes', 'Light World'), ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), - ('Bomb Hut Mirror Spot', 'West Dark World'), - ('Maze Race Ledge Drop', 'Light World')] + ('Bomb Hut Mirror Spot', 'West Dark World') + ] + # non-shuffled entrance links -default_connections = [('Links House', 'Links House'), - ('Links House Exit', 'Light World'), - ('Waterfall of Wishing', 'Waterfall of Wishing'), - ("Blinds Hideout", "Blinds Hideout"), +default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), + ('Blinds Hideout', 'Blinds Hideout'), ('Dam', 'Dam'), ('Lumberjack House', 'Lumberjack House'), - ("Hyrule Castle Secret Entrance Drop", "Hyrule Castle Secret Entrance"), - ("Hyrule Castle Secret Entrance Stairs", "Hyrule Castle Secret Entrance"), - ("Hyrule Castle Secret Entrance Exit", "Hyrule Castle Courtyard"), + ('Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance'), + ('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance'), ('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), ('Lake Hylia Fairy', 'Lake Hylia Healer Fairy'), ('Lake Hylia Fortune Teller', 'Lake Hylia Fortune Teller'), @@ -2862,7 +2346,7 @@ default_connections = [('Links House', 'Links House'), ('Graveyard Cave', 'Graveyard Cave'), ('Checkerboard Cave', 'Checkerboard Cave'), ('Mini Moldorm Cave', 'Mini Moldorm Cave'), - ('Long Fairy Cave', 'Long Fairy Cave'), # near East Light World Teleporter + ('Long Fairy Cave', 'Long Fairy Cave'), ('Good Bee Cave', 'Good Bee Cave'), ('20 Rupee Cave', '20 Rupee Cave'), ('50 Rupee Cave', '50 Rupee Cave'), @@ -2875,22 +2359,14 @@ default_connections = [('Links House', 'Links House'), ('Two Brothers House (West)', 'Two Brothers House'), ('Two Brothers House Exit (East)', 'Light World'), ('Two Brothers House Exit (West)', 'Maze Race Ledge'), - ('Sanctuary', 'Sanctuary Portal'), ('Sanctuary Grave', 'Sewer Drop'), ('Sanctuary Exit', 'Light World'), - - ('Old Man Cave (West)', 'Old Man Cave Ledge'), - ('Old Man Cave (East)', 'Old Man Cave'), - ('Old Man Cave Exit (West)', 'Light World'), - ('Old Man Cave Exit (East)', 'Death Mountain'), ('Old Man House (Bottom)', 'Old Man House'), ('Old Man House Exit (Bottom)', 'Death Mountain'), ('Old Man House (Top)', 'Old Man House Back'), ('Old Man House Exit (Top)', 'Death Mountain'), ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave (West)', 'Death Mountain Return Cave (left)'), - ('Death Mountain Return Cave Exit (West)', 'Death Mountain Return Ledge'), ('Death Mountain Return Cave Exit (East)', 'Death Mountain'), ('Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Peak)'), ('Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave (Bottom)'), @@ -2913,11 +2389,9 @@ default_connections = [('Links House', 'Links House'), ('Spiral Cave (Bottom)', 'Spiral Cave (Bottom)'), ('Spiral Cave Exit', 'East Death Mountain (Bottom)'), ('Spiral Cave Exit (Top)', 'Spiral Cave Ledge'), - ('Pyramid Fairy', 'Pyramid Fairy'), ('East Dark World Hint', 'East Dark World Hint'), ('Palace of Darkness Hint', 'Palace of Darkness Hint'), - ('Big Bomb Shop', 'Big Bomb Shop'), ('Dark Lake Hylia Shop', 'Dark Lake Hylia Shop'), ('Dark Lake Hylia Fairy', 'Dark Lake Hylia Healer Fairy'), ('Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Healer Fairy'), @@ -2929,8 +2403,6 @@ default_connections = [('Links House', 'Links House'), ('C-Shaped House', 'C-Shaped House'), ('Chest Game', 'Chest Game'), ('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'), - ('Bumper Cave (Bottom)', 'Bumper Cave (bottom)'), - ('Bumper Cave (Top)', 'Bumper Cave (top)'), ('Red Shield Shop', 'Red Shield Shop'), ('Dark Sanctuary Hint', 'Dark Sanctuary Hint'), ('Fortune Teller (Dark)', 'Fortune Teller (Dark)'), @@ -2938,8 +2410,6 @@ default_connections = [('Links House', 'Links House'), ('Dark World Lumberjack Shop', 'Dark World Lumberjack Shop'), ('Dark World Potion Shop', 'Dark World Potion Shop'), ('Archery Game', 'Archery Game'), - ('Bumper Cave Exit (Top)', 'Bumper Cave Ledge'), - ('Bumper Cave Exit (Bottom)', 'West Dark World'), ('Mire Shed', 'Mire Shed'), ('Dark Desert Hint', 'Dark Desert Hint'), ('Dark Desert Fairy', 'Dark Desert Healer Fairy'), @@ -2947,168 +2417,57 @@ default_connections = [('Links House', 'Links House'), ('Hookshot Cave', 'Hookshot Cave (Front)'), ('Superbunny Cave (Top)', 'Superbunny Cave (Top)'), ('Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)'), - ('Dark Death Mountain Fairy', 'Dark Death Mountain Healer Fairy'), ('Superbunny Cave (Bottom)', 'Superbunny Cave (Bottom)'), - ('Superbunny Cave Exit (Top)', 'Dark Death Mountain (Top)'), ('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'), - ('Hookshot Cave Front Exit', 'Dark Death Mountain (Top)'), ('Hookshot Cave Back Exit', 'Death Mountain Floating Island (Dark World)'), ('Hookshot Cave Back Entrance', 'Hookshot Cave (Back)'), - ('Mimic Cave', 'Mimic Cave'), - - ('Pyramid Hole', 'Pyramid'), - ('Pyramid Exit', 'Pyramid Ledge'), - ('Pyramid Entrance', 'Bottom of Pyramid') + ('Mimic Cave', 'Mimic Cave') ] -inverted_default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), - ('Blinds Hideout', 'Blinds Hideout'), - ('Dam', 'Dam'), - ('Lumberjack House', 'Lumberjack House'), - ('Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance'), - ('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance'), - ('Hyrule Castle Secret Entrance Exit', 'Light World'), - ('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), - ('Lake Hylia Fairy', 'Lake Hylia Healer Fairy'), - ('Lake Hylia Fortune Teller', 'Lake Hylia Fortune Teller'), - ('Light Hype Fairy', 'Swamp Healer Fairy'), - ('Desert Fairy', 'Desert Healer Fairy'), - ('Kings Grave', 'Kings Grave'), - ('Tavern North', 'Tavern'), - ('Chicken House', 'Chicken House'), - ('Aginahs Cave', 'Aginahs Cave'), - ('Sahasrahlas Hut', 'Sahasrahlas Hut'), - ('Cave Shop (Lake Hylia)', 'Cave Shop (Lake Hylia)'), - ('Capacity Upgrade', 'Capacity Upgrade'), - ('Kakariko Well Drop', 'Kakariko Well (top)'), - ('Kakariko Well Cave', 'Kakariko Well (bottom)'), - ('Kakariko Well Exit', 'Light World'), - ('Blacksmiths Hut', 'Blacksmiths Hut'), - ('Bat Cave Drop', 'Bat Cave (right)'), - ('Bat Cave Cave', 'Bat Cave (left)'), - ('Bat Cave Exit', 'Light World'), - ('Sick Kids House', 'Sick Kids House'), - ('Elder House (East)', 'Elder House'), - ('Elder House (West)', 'Elder House'), - ('Elder House Exit (East)', 'Light World'), - ('Elder House Exit (West)', 'Light World'), - ('North Fairy Cave Drop', 'North Fairy Cave'), - ('North Fairy Cave', 'North Fairy Cave'), - ('North Fairy Cave Exit', 'Light World'), - ('Lost Woods Gamble', 'Lost Woods Gamble'), - ('Fortune Teller (Light)', 'Fortune Teller (Light)'), - ('Snitch Lady (East)', 'Snitch Lady (East)'), - ('Snitch Lady (West)', 'Snitch Lady (West)'), - ('Bush Covered House', 'Bush Covered House'), - ('Tavern (Front)', 'Tavern (Front)'), - ('Light World Bomb Hut', 'Light World Bomb Hut'), - ('Kakariko Shop', 'Kakariko Shop'), - ('Lost Woods Hideout Drop', 'Lost Woods Hideout (top)'), - ('Lost Woods Hideout Stump', 'Lost Woods Hideout (bottom)'), - ('Lost Woods Hideout Exit', 'Light World'), - ('Lumberjack Tree Tree', 'Lumberjack Tree (top)'), - ('Lumberjack Tree Cave', 'Lumberjack Tree (bottom)'), - ('Lumberjack Tree Exit', 'Light World'), - ('Cave 45', 'Cave 45'), - ('Graveyard Cave', 'Graveyard Cave'), - ('Checkerboard Cave', 'Checkerboard Cave'), - ('Mini Moldorm Cave', 'Mini Moldorm Cave'), - ('Long Fairy Cave', 'Long Fairy Cave'), - ('Good Bee Cave', 'Good Bee Cave'), - ('20 Rupee Cave', '20 Rupee Cave'), - ('50 Rupee Cave', '50 Rupee Cave'), - ('Ice Rod Cave', 'Ice Rod Cave'), - ('Bonk Rock Cave', 'Bonk Rock Cave'), - ('Library', 'Library'), - ('Kakariko Gamble Game', 'Kakariko Gamble Game'), - ('Potion Shop', 'Potion Shop'), - ('Two Brothers House (East)', 'Two Brothers House'), - ('Two Brothers House (West)', 'Two Brothers House'), - ('Two Brothers House Exit (East)', 'Light World'), - ('Two Brothers House Exit (West)', 'Maze Race Ledge'), - ('Sanctuary', 'Sanctuary Portal'), - ('Sanctuary Grave', 'Sewer Drop'), - ('Sanctuary Exit', 'Light World'), - ('Old Man House (Bottom)', 'Old Man House'), - ('Old Man House Exit (Bottom)', 'Death Mountain'), - ('Old Man House (Top)', 'Old Man House Back'), - ('Old Man House Exit (Top)', 'Death Mountain'), - ('Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Peak)'), - ('Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave (Bottom)'), - ('Spectacle Rock Cave', 'Spectacle Rock Cave (Top)'), - ('Spectacle Rock Cave Exit', 'Death Mountain'), - ('Spectacle Rock Cave Exit (Top)', 'Death Mountain'), - ('Spectacle Rock Cave Exit (Peak)', 'Death Mountain'), - ('Paradox Cave (Bottom)', 'Paradox Cave Front'), - ('Paradox Cave (Middle)', 'Paradox Cave'), - ('Paradox Cave (Top)', 'Paradox Cave'), - ('Paradox Cave Exit (Bottom)', 'East Death Mountain (Bottom)'), - ('Paradox Cave Exit (Middle)', 'East Death Mountain (Bottom)'), - ('Paradox Cave Exit (Top)', 'East Death Mountain (Top)'), - ('Hookshot Fairy', 'Hookshot Fairy'), - ('Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Bottom)'), - ('Fairy Ascension Cave (Top)', 'Fairy Ascension Cave (Top)'), - ('Fairy Ascension Cave Exit (Bottom)', 'Fairy Ascension Plateau'), - ('Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Ledge'), - ('Spiral Cave', 'Spiral Cave (Top)'), - ('Spiral Cave (Bottom)', 'Spiral Cave (Bottom)'), - ('Spiral Cave Exit', 'East Death Mountain (Bottom)'), - ('Spiral Cave Exit (Top)', 'Spiral Cave Ledge'), - ('Pyramid Fairy', 'Pyramid Fairy'), - ('East Dark World Hint', 'East Dark World Hint'), - ('Palace of Darkness Hint', 'Palace of Darkness Hint'), - ('Dark Lake Hylia Shop', 'Dark Lake Hylia Shop'), - ('Dark Lake Hylia Fairy', 'Dark Lake Hylia Healer Fairy'), - ('Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Healer Fairy'), - ('Dark Lake Hylia Ledge Spike Cave', 'Dark Lake Hylia Ledge Spike Cave'), - ('Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Hint'), - ('Hype Cave', 'Hype Cave'), - ('Bonk Fairy (Dark)', 'Bonk Fairy (Dark)'), - ('Brewery', 'Brewery'), - ('C-Shaped House', 'C-Shaped House'), - ('Chest Game', 'Chest Game'), - ('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'), - ('Red Shield Shop', 'Red Shield Shop'), - ('Fortune Teller (Dark)', 'Fortune Teller (Dark)'), - ('Dark World Shop', 'Village of Outcasts Shop'), - ('Dark World Lumberjack Shop', 'Dark World Lumberjack Shop'), - ('Dark World Potion Shop', 'Dark World Potion Shop'), - ('Archery Game', 'Archery Game'), - ('Mire Shed', 'Mire Shed'), - ('Dark Desert Hint', 'Dark Desert Hint'), - ('Dark Desert Fairy', 'Dark Desert Healer Fairy'), - ('Spike Cave', 'Spike Cave'), - ('Hookshot Cave', 'Hookshot Cave (Front)'), - ('Superbunny Cave (Top)', 'Superbunny Cave (Top)'), - ('Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)'), - ('Superbunny Cave (Bottom)', 'Superbunny Cave (Bottom)'), - ('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'), - ('Hookshot Cave Back Exit', 'Death Mountain Floating Island (Dark World)'), - ('Hookshot Cave Back Entrance', 'Hookshot Cave (Back)'), - ('Mimic Cave', 'Mimic Cave'), - ('Inverted Pyramid Hole', 'Pyramid'), - ('Links House', 'Big Bomb Shop'), - ('Links House Exit', 'South Dark World'), - ('Big Bomb Shop', 'Links House'), - ('Dark Sanctuary Hint', 'Dark Sanctuary Hint'), - ('Dark Sanctuary Hint Exit', 'West Dark World'), - ('Old Man Cave (West)', 'Bumper Cave (bottom)'), - ('Old Man Cave (East)', 'Death Mountain Return Cave (left)'), - ('Old Man Cave Exit (West)', 'West Dark World'), - ('Old Man Cave Exit (East)', 'Dark Death Mountain'), - ('Dark Death Mountain Fairy', 'Old Man Cave'), - ('Bumper Cave (Bottom)', 'Old Man Cave Ledge'), - ('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'), - ('Bumper Cave Exit (Top)', 'Death Mountain Return Ledge'), - ('Bumper Cave Exit (Bottom)', 'Light World'), - ('Death Mountain Return Cave (West)', 'Bumper Cave (top)'), - ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave Exit (West)', 'Death Mountain'), - ('Death Mountain Return Cave Exit (East)', 'Death Mountain'), - ('Hookshot Cave Front Exit', 'Dark Death Mountain'), - ('Superbunny Cave Exit (Top)', 'Dark Death Mountain'), - ('Pyramid Exit', 'Light World'), - ('Inverted Pyramid Entrance', 'Bottom of Pyramid')] +open_default_connections = [('Links House', 'Links House'), + ('Links House Exit', 'Light World'), + ('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Courtyard'), + ('Old Man Cave (West)', 'Old Man Cave Ledge'), + ('Old Man Cave (East)', 'Old Man Cave'), + ('Old Man Cave Exit (West)', 'Light World'), + ('Old Man Cave Exit (East)', 'Death Mountain'), + ('Death Mountain Return Cave (West)', 'Death Mountain Return Cave (left)'), + ('Death Mountain Return Cave Exit (West)', 'Death Mountain Return Ledge'), + ('Big Bomb Shop', 'Big Bomb Shop'), + ('Bumper Cave (Bottom)', 'Bumper Cave (bottom)'), + ('Bumper Cave (Top)', 'Bumper Cave (top)'), + ('Bumper Cave Exit (Top)', 'Bumper Cave Ledge'), + ('Bumper Cave Exit (Bottom)', 'West Dark World'), + ('Dark Death Mountain Fairy', 'Dark Death Mountain Healer Fairy'), + ('Superbunny Cave Exit (Top)', 'Dark Death Mountain (Top)'), + ('Hookshot Cave Front Exit', 'Dark Death Mountain (Top)'), + ('Pyramid Hole', 'Pyramid'), + ('Pyramid Exit', 'Pyramid Ledge'), + ('Pyramid Entrance', 'Bottom of Pyramid') + ] + +inverted_default_connections = [('Links House', 'Big Bomb Shop'), + ('Links House Exit', 'South Dark World'), + ('Hyrule Castle Secret Entrance Exit', 'Light World'), + ('Old Man Cave (West)', 'Bumper Cave (bottom)'), + ('Old Man Cave (East)', 'Death Mountain Return Cave (left)'), + ('Old Man Cave Exit (West)', 'West Dark World'), + ('Old Man Cave Exit (East)', 'Dark Death Mountain'), + ('Death Mountain Return Cave (West)', 'Bumper Cave (top)'), + ('Death Mountain Return Cave Exit (West)', 'Death Mountain'), + ('Big Bomb Shop', 'Links House'), + ('Bumper Cave (Bottom)', 'Old Man Cave Ledge'), + ('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'), + ('Dark Sanctuary Hint Exit', 'West Dark World'), + ('Bumper Cave Exit (Top)', 'Death Mountain Return Ledge'), + ('Bumper Cave Exit (Bottom)', 'Light World'), + ('Dark Death Mountain Fairy', 'Old Man Cave'), + ('Superbunny Cave Exit (Top)', 'Dark Death Mountain'), + ('Hookshot Cave Front Exit', 'Dark Death Mountain'), + ('Inverted Pyramid Hole', 'Pyramid'), + ('Pyramid Exit', 'Light World'), + ('Inverted Pyramid Entrance', 'Bottom of Pyramid') + ] # non shuffled dungeons default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), @@ -3119,7 +2478,6 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Desert Palace Exit (West)', 'Desert Ledge'), ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), ('Eastern Palace Exit', 'Light World'), ('Tower of Hera', 'Hera Portal'), @@ -3128,66 +2486,9 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Agahnims Tower', 'Agahnims Tower Portal'), - ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), - - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - ('Swamp Palace', 'Swamp Portal'), # requires additional patch for flooding moat if moved - ('Swamp Palace Exit', 'South Dark World'), - - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - - ('Ganons Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Dark Death Mountain (Top)') - ] - -inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Light World'), ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), + ('Thieves Town', 'Thieves Town Portal'), ('Thieves Town Exit', 'West Dark World'), ('Skull Woods First Section Hole (East)', 'Skull Pinball'), @@ -3209,21 +2510,34 @@ inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Dese ('Palace of Darkness Exit', 'East Dark World'), ('Swamp Palace', 'Swamp Portal'), # requires additional patch for flooding moat if moved ('Swamp Palace Exit', 'South Dark World'), + ('Turtle Rock', 'Turtle Rock Main Portal'), ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - ('Agahnims Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Hyrule Castle Ledge'), - ('Ganons Tower', 'Agahnims Tower Portal'), - ('Agahnims Tower Exit', 'Dark Death Mountain'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), - ('Ice Palace Exit', 'Dark Lake Hylia') + ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal') ] +open_default_dungeon_connections = [('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), + ('Agahnims Tower', 'Agahnims Tower Portal'), + ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), + ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), + ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), + ('Ganons Tower', 'Ganons Tower Portal'), + ('Ganons Tower Exit', 'Dark Death Mountain (Top)') + ] + +inverted_default_dungeon_connections = [('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), + ('Agahnims Tower', 'Ganons Tower Portal'), + ('Agahnims Tower Exit', 'Dark Death Mountain'), + ('Ice Palace Exit', 'Dark Lake Hylia'), + ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), + ('Ganons Tower', 'Agahnims Tower Portal'), + ('Ganons Tower Exit', 'Hyrule Castle Ledge') + ] + indirect_connections = { 'Turtle Rock (Top)': 'Turtle Rock', 'East Dark World': 'Pyramid Fairy', diff --git a/Main.py b/Main.py index 9c2f1441..da28d6b3 100644 --- a/Main.py +++ b/Main.py @@ -16,7 +16,7 @@ from OverworldGlitchRules import create_owg_connections from PotShuffle import shuffle_pots, shuffle_pot_switches from Regions import create_regions, create_shops, mark_light_world_regions, create_dungeon_regions, adjust_locations from InvertedRegions import create_inverted_regions, mark_dark_world_regions -from EntranceShuffle import link_entrances, link_inverted_entrances +from EntranceShuffle import link_entrances from Rom import patch_rom, patch_race_rom, patch_enemizer, apply_rom_settings, LocalRom, JsonRom, get_hash_string from Doors import create_doors from DoorShuffle import link_doors, connect_portal, link_doors_prep @@ -224,10 +224,7 @@ def main(args, seed=None, fish=None): if world.experimental[player] or world.shuffle[player] in ['lite', 'lean'] or world.shuffletavern[player] or (world.customizer and world.customizer.get_entrances()): link_entrances_new(world, player) else: - if world.mode[player] != 'inverted': - link_entrances(world, player) - else: - link_inverted_entrances(world, player) + link_entrances(world, player) logger.info(world.fish.translate("cli", "cli", "shuffling.prep")) for player in range(1, world.players + 1): diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index a5a66c54..403b5488 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -68,8 +68,10 @@ def link_entrances_new(world, player): avail_pool.one_way_map = one_way_map # setup mandatory connections + for exit_name, region_name in mandatory_connections: + connect_simple(world, exit_name, region_name, player) if not avail_pool.inverted: - for exit_name, region_name in mandatory_connections: + for exit_name, region_name in open_mandatory_connections: connect_simple(world, exit_name, region_name, player) else: for exit_name, region_name in inverted_mandatory_connections: @@ -772,7 +774,7 @@ def do_vanilla_connect(pool_def, avail): elif pool_def['condition'] == 'pottery': # this condition involves whether caves with pots are shuffled or not if avail.world.pottery[avail.player] not in ['none', 'keys', 'dungeon']: return - defaults = inverted_default_connections if avail.inverted else default_connections + defaults = default_connections + (inverted_default_connections if avail.inverted else open_default_connections) for entrance in pool_def['entrances']: if entrance in avail.entrances: target = defaults[entrance] @@ -1842,17 +1844,10 @@ Inverted_Bomb_Shop_Options = [ # these are connections that cannot be shuffled and always exist. # They link together separate parts of the world we need to divide into regions mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Other World S&Q', 'East Dark World'), ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), ('Zoras River', 'Zoras River'), - ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), - ('Zora Waterfall Water Drop', 'Light World'), ('Kings Grave Outer Rocks', 'Kings Grave Area'), ('Kings Grave Inner Rocks', 'Light World'), - ('Kings Grave Mirror Spot', 'Kings Grave Area'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), ('Master Sword Meadow', 'Master Sword Meadow'), @@ -1866,10 +1861,7 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Desert Palace Stairs Drop', 'Light World'), ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), ('Sewer Drop', 'Sewers Rat Path'), - ('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)'), @@ -1889,29 +1881,19 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('East Death Mountain (Top)', 'East Death Mountain (Top)'), ('Death Mountain (Top)', 'Death Mountain (Top)'), ('Death Mountain Drop', 'Death Mountain'), - ('Spectacle Rock Drop', 'Death Mountain (Top)'), - - ('Top of Pyramid', 'East Dark World'), ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), ('East Dark World Pier', 'East Dark World'), - ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), - ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), - ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), ('South Dark World Bridge', 'South Dark World'), ('East Dark World Bridge', 'East Dark World'), - ('Maze Race Mirror Spot', 'Maze Race Ledge'), ('Village of Outcasts Heavy Rock', 'West Dark World'), ('Village of Outcasts Drop', 'South Dark World'), ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), ('Peg Area Rocks', 'West Dark World'), ('Grassy Lawn Pegs', 'West Dark World'), - ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), - ('East Dark World River Pier', 'East Dark World'), ('West Dark World Gap', 'West Dark World'), ('East Dark World Broken Bridge Pass', 'East Dark World'), ('Catfish Exit Rock', 'Northeast Dark World'), @@ -1919,21 +1901,10 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Northeast Dark World Broken Bridge Pass', 'Northeast 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 Mirror Spot', 'Death Mountain Return Ledge'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), + ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Skull Woods Forest', 'Skull Woods Forest'), - ('Desert Ledge Mirror Spot', 'Desert Ledge'), - ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), - ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), - ('Dark Desert Teleporter', 'Dark Desert'), - ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), - ('East Hyrule Teleporter', 'East Dark World'), - ('South Hyrule Teleporter', 'South Dark World'), - ('Kakariko Teleporter', 'West Dark World'), - ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), ('Paradox Cave Push Block', 'Paradox Cave Front'), ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), @@ -1941,17 +1912,12 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Paradox Cave Drop', 'Paradox Cave Chest Area'), ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), - ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), @@ -1959,118 +1925,95 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), - ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), - ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), - ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), - ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), - ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), - ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), ('Ganon Drop', 'Bottom of Pyramid'), ('Pyramid Drop', 'East Dark World'), ('Maze Race Ledge Drop', 'Light World'), - ('Graveyard Ledge Drop', 'Light World'), - ('Cave 45 Ledge Drop', 'Light World'), - ('Checkerboard Ledge Drop', 'Light World'), - ('Desert Ledge Drop', 'Light World'), - ('Hyrule Castle Main Gate (North)', 'Light World'), - ('Hyrule Castle Ledge Drop', 'Light World'), - ] + ('Desert Ledge Drop', 'Light World') + ] -inverted_mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Dark Sanctuary Hint'), +open_mandatory_connections = [('Sanctuary S&Q', 'Sanctuary'), + ('Old Man S&Q', 'Old Man House'), + ('Other World S&Q', 'East Dark World'), + ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), + ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), + ('Zora Waterfall Water Drop', 'Light World'), + ('Kings Grave Mirror Spot', 'Kings Grave Area'), + ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), + ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), + ('Flute Spot 1', 'Death Mountain'), + ('Spectacle Rock Drop', 'Death Mountain (Top)'), + ('Top of Pyramid', 'East Dark World'), + ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), + ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), + ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), + ('Maze Race Mirror Spot', 'Maze Race Ledge'), + ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), + ('East Dark World River Pier', 'East Dark World'), + ('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'), + ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), + ('Desert Ledge Mirror Spot', 'Desert Ledge'), + ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), + ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), + ('Dark Desert Teleporter', 'Dark Desert'), + ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), + ('East Hyrule Teleporter', 'East Dark World'), + ('South Hyrule Teleporter', 'South Dark World'), + ('Kakariko Teleporter', 'West Dark World'), + ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), + ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), + ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), + ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), + ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), + ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), + ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), + ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), + ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), + ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), + ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), + ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), + ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), + ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), + ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), + ('Graveyard Ledge Drop', 'Light World'), + ('Cave 45 Ledge Drop', 'Light World'), + ('Checkerboard Ledge Drop', 'Light World'), + ('Hyrule Castle Main Gate (North)', 'Light World'), + ('Hyrule Castle Ledge Drop', 'Light World'), + ] + +inverted_mandatory_connections = [('Sanctuary S&Q', 'Dark Sanctuary Hint'), ('Old Man S&Q', 'Old Man House'), ('Other World S&Q', 'Hyrule Castle Ledge'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), ('Lake Hylia Island Pier', 'Lake Hylia Island'), ('Lake Hylia Warp', 'Northeast Light World'), ('Northeast Light World Warp', 'Light World'), - ('Zoras River', 'Zoras River'), ('Waterfall of Wishing Cave', 'Waterfall of Wishing Cave'), ('Northeast Light World Return', 'Northeast Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), - ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), - ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), - ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Sewer Drop', 'Sewers Rat Path'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), - ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), - ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), + ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), + ('DDM Flute', 'The Sky'), + ('DDM Landing', 'Dark Death Mountain'), + ('NEDW Flute', 'The Sky'), + ('NEDW Landing', 'Northeast Dark World'), + ('WDW Flute', 'The Sky'), + ('WDW Landing', 'West Dark World'), + ('SDW Flute', 'The Sky'), + ('SDW Landing', 'South Dark World'), + ('EDW Flute', 'The Sky'), + ('EDW Landing', 'East Dark World'), + ('DLHL Flute', 'The Sky'), + ('DLHL Landing', 'Dark Lake Hylia Ledge'), + ('DD Flute', 'The Sky'), + ('DD Landing', 'Dark Desert Ledge'), + ('EDDM Flute', 'The Sky'), + ('Dark Grassy Lawn Flute', 'The Sky'), + ('Hammer Peg Area Flute', 'The Sky'), ('Dark Lake Hylia Ledge Pier', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), ('Ice Palace Missing Wall', 'Dark Lake Hylia Central Island'), ('Dark Lake Hylia Shallows', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), ('East Dark World River Pier', 'Northeast Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), - ('Paradox Cave Push Block', 'Paradox Cave Front'), - ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), - ('Paradox Cave Bomb Jump', 'Paradox Cave'), - ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), ('Fairy Ascension Ledge Access', 'Fairy Ascension Ledge'), - ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), - ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), - ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), ('Post Aga Teleporter', 'Light World'), ('Secret Passage Inner Bushes', 'Light World'), ('Secret Passage Outer Bushes', 'Hyrule Castle Secret Entrance Area'), @@ -2085,19 +2028,10 @@ inverted_mandatory_connections = [('Links House S&Q', 'Links House'), ('Light World River Drop', 'River'), ('Light World Pier', 'Light World'), ('Potion Shop Pier', 'Potion Shop Area'), - ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), ('Mimic Cave Ledge Access', 'Mimic Cave Ledge'), ('Mimic Cave Ledge Drop', 'East Death Mountain (Bottom)'), ('Turtle Rock Tail Drop', 'Turtle Rock (Top)'), ('Turtle Rock Drop', 'Dark Death Mountain'), - ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), - ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), - ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), - ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), - ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Desert Ledge Drop', 'Light World'), ('Floating Island Drop', 'Dark Death Mountain'), ('Dark Lake Hylia Central Island Teleporter', 'Lake Hylia Central Island'), ('Dark Desert Teleporter', 'Light World'), @@ -2131,41 +2065,21 @@ inverted_mandatory_connections = [('Links House S&Q', 'Links House'), ('Catfish Mirror Spot', 'Catfish'), ('Shopping Mall Mirror Spot', 'Dark Lake Hylia Ledge'), ('Skull Woods Mirror Spot', 'Skull Woods Forest (West)'), - ('DDM Flute', 'The Sky'), - ('DDM Landing', 'Dark Death Mountain'), - ('NEDW Flute', 'The Sky'), - ('NEDW Landing', 'Northeast Dark World'), - ('WDW Flute', 'The Sky'), - ('WDW Landing', 'West Dark World'), - ('SDW Flute', 'The Sky'), - ('SDW Landing', 'South Dark World'), - ('EDW Flute', 'The Sky'), - ('EDW Landing', 'East Dark World'), - ('DLHL Flute', 'The Sky'), - ('DLHL Landing', 'Dark Lake Hylia Ledge'), - ('DD Flute', 'The Sky'), - ('DD Landing', 'Dark Desert Ledge'), - ('EDDM Flute', 'The Sky'), - ('Dark Grassy Lawn Flute', 'The Sky'), - ('Hammer Peg Area Flute', 'The Sky'), ('Bush Covered Lawn Inner Bushes', 'Light World'), ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), ('Bomb Hut Inner Bushes', 'Light World'), ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), - ('Bomb Hut Mirror Spot', 'West Dark World'), - ('Maze Race Ledge Drop', 'Light World')] + ('Bomb Hut Mirror Spot', 'West Dark World') + ] # non-shuffled entrance links -default_connections = {'Links House': 'Links House', - 'Links House Exit': 'Light World', - 'Waterfall of Wishing': 'Waterfall of Wishing', +default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', 'Blinds Hideout': 'Blinds Hideout', 'Dam': 'Dam', 'Lumberjack House': 'Lumberjack House', 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Exit': 'Hyrule Castle Courtyard', 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', @@ -2211,7 +2125,7 @@ default_connections = {'Links House': 'Links House', 'Graveyard Cave': 'Graveyard Cave', 'Checkerboard Cave': 'Checkerboard Cave', 'Mini Moldorm Cave': 'Mini Moldorm Cave', - 'Long Fairy Cave': 'Long Fairy Cave', # near East Light World Teleporter + 'Long Fairy Cave': 'Long Fairy Cave', 'Good Bee Cave': 'Good Bee Cave', '20 Rupee Cave': '20 Rupee Cave', '50 Rupee Cave': '50 Rupee Cave', @@ -2224,22 +2138,14 @@ default_connections = {'Links House': 'Links House', 'Two Brothers House (West)': 'Two Brothers House', 'Two Brothers House Exit (East)': 'Light World', 'Two Brothers House Exit (West)': 'Maze Race Ledge', - 'Sanctuary': 'Sanctuary Portal', 'Sanctuary Grave': 'Sewer Drop', 'Sanctuary Exit': 'Light World', - - 'Old Man Cave (West)': 'Old Man Cave Ledge', - 'Old Man Cave (East)': 'Old Man Cave', - 'Old Man Cave Exit (West)': 'Light World', - 'Old Man Cave Exit (East)': 'Death Mountain', 'Old Man House (Bottom)': 'Old Man House', 'Old Man House Exit (Bottom)': 'Death Mountain', 'Old Man House (Top)': 'Old Man House Back', 'Old Man House Exit (Top)': 'Death Mountain', 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', - 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave (left)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain Return Ledge', 'Death Mountain Return Cave Exit (East)': 'Death Mountain', 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', @@ -2262,11 +2168,9 @@ default_connections = {'Links House': 'Links House', 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', 'Spiral Cave Exit': 'East Death Mountain (Bottom)', 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', - 'Pyramid Fairy': 'Pyramid Fairy', 'East Dark World Hint': 'East Dark World Hint', 'Palace of Darkness Hint': 'Palace of Darkness Hint', - 'Big Bomb Shop': 'Big Bomb Shop', 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', @@ -2278,18 +2182,13 @@ default_connections = {'Links House': 'Links House', 'C-Shaped House': 'C-Shaped House', 'Chest Game': 'Chest Game', 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', - 'Bumper Cave (Bottom)': 'Bumper Cave (bottom)', - 'Bumper Cave (Top)': 'Bumper Cave (top)', 'Red Shield Shop': 'Red Shield Shop', 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', - 'Dark Sanctuary Hint Exit': 'West Dark World', 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', 'Dark World Shop': 'Village of Outcasts Shop', 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', 'Dark World Potion Shop': 'Dark World Potion Shop', 'Archery Game': 'Archery Game', - 'Bumper Cave Exit (Top)': 'Bumper Cave Ledge', - 'Bumper Cave Exit (Bottom)': 'West Dark World', 'Mire Shed': 'Mire Shed', 'Dark Desert Hint': 'Dark Desert Hint', 'Dark Desert Fairy': 'Dark Desert Healer Fairy', @@ -2297,167 +2196,57 @@ default_connections = {'Links House': 'Links House', 'Hookshot Cave': 'Hookshot Cave (Front)', 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', - 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Top)': 'Dark Death Mountain (Top)', 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Front Exit': 'Dark Death Mountain (Top)', 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', + 'Mimic Cave': 'Mimic Cave' + } - 'Pyramid Hole': 'Pyramid', - 'Pyramid Exit': 'Pyramid Ledge', - 'Pyramid Entrance': 'Bottom of Pyramid'} +open_default_connections = {'Links House': 'Links House', + 'Links House Exit': 'Light World', + 'Hyrule Castle Secret Entrance Exit': 'Hyrule Castle Courtyard', + 'Old Man Cave (West)': 'Old Man Cave Ledge', + 'Old Man Cave (East)': 'Old Man Cave', + 'Old Man Cave Exit (West)': 'Light World', + 'Old Man Cave Exit (East)': 'Death Mountain', + 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave (left)', + 'Death Mountain Return Cave Exit (West)': 'Death Mountain Return Ledge', + 'Big Bomb Shop': 'Big Bomb Shop', + 'Bumper Cave (Bottom)': 'Bumper Cave (bottom)', + 'Bumper Cave (Top)': 'Bumper Cave (top)', + 'Bumper Cave Exit (Top)': 'Bumper Cave Ledge', + 'Bumper Cave Exit (Bottom)': 'West Dark World', + 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', + 'Superbunny Cave Exit (Top)': 'Dark Death Mountain (Top)', + 'Hookshot Cave Front Exit': 'Dark Death Mountain (Top)', + 'Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Pyramid Ledge', + 'Pyramid Entrance': 'Bottom of Pyramid' + } -inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', - 'Blinds Hideout': 'Blinds Hideout', - 'Dam': 'Dam', - 'Lumberjack House': 'Lumberjack House', - 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Exit': 'Light World', - 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', - 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', - 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', - 'Light Hype Fairy': 'Swamp Healer Fairy', - 'Desert Fairy': 'Desert Healer Fairy', - 'Kings Grave': 'Kings Grave', - 'Tavern North': 'Tavern', - 'Chicken House': 'Chicken House', - 'Aginahs Cave': 'Aginahs Cave', - 'Sahasrahlas Hut': 'Sahasrahlas Hut', - 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', - 'Capacity Upgrade': 'Capacity Upgrade', - 'Kakariko Well Drop': 'Kakariko Well (top)', - 'Kakariko Well Cave': 'Kakariko Well (bottom)', - 'Kakariko Well Exit': 'Light World', - 'Blacksmiths Hut': 'Blacksmiths Hut', - 'Bat Cave Drop': 'Bat Cave (right)', - 'Bat Cave Cave': 'Bat Cave (left)', - 'Bat Cave Exit': 'Light World', - 'Sick Kids House': 'Sick Kids House', - 'Elder House (East)': 'Elder House', - 'Elder House (West)': 'Elder House', - 'Elder House Exit (East)': 'Light World', - 'Elder House Exit (West)': 'Light World', - 'North Fairy Cave Drop': 'North Fairy Cave', - 'North Fairy Cave': 'North Fairy Cave', - 'North Fairy Cave Exit': 'Light World', - 'Lost Woods Gamble': 'Lost Woods Gamble', - 'Fortune Teller (Light)': 'Fortune Teller (Light)', - 'Snitch Lady (East)': 'Snitch Lady (East)', - 'Snitch Lady (West)': 'Snitch Lady (West)', - 'Bush Covered House': 'Bush Covered House', - 'Tavern (Front)': 'Tavern (Front)', - 'Light World Bomb Hut': 'Light World Bomb Hut', - 'Kakariko Shop': 'Kakariko Shop', - 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', - 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', - 'Lost Woods Hideout Exit': 'Light World', - 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', - 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', - 'Lumberjack Tree Exit': 'Light World', - 'Cave 45': 'Cave 45', - 'Graveyard Cave': 'Graveyard Cave', - 'Checkerboard Cave': 'Checkerboard Cave', - 'Mini Moldorm Cave': 'Mini Moldorm Cave', - 'Long Fairy Cave': 'Long Fairy Cave', - 'Good Bee Cave': 'Good Bee Cave', - '20 Rupee Cave': '20 Rupee Cave', - '50 Rupee Cave': '50 Rupee Cave', - 'Ice Rod Cave': 'Ice Rod Cave', - 'Bonk Rock Cave': 'Bonk Rock Cave', - 'Library': 'Library', - 'Kakariko Gamble Game': 'Kakariko Gamble Game', - 'Potion Shop': 'Potion Shop', - 'Two Brothers House (East)': 'Two Brothers House', - 'Two Brothers House (West)': 'Two Brothers House', - 'Two Brothers House Exit (East)': 'Light World', - 'Two Brothers House Exit (West)': 'Maze Race Ledge', - 'Sanctuary': 'Sanctuary Portal', - 'Sanctuary Grave': 'Sewer Drop', - 'Sanctuary Exit': 'Light World', - 'Old Man House (Bottom)': 'Old Man House', - 'Old Man House Exit (Bottom)': 'Death Mountain', - 'Old Man House (Top)': 'Old Man House Back', - 'Old Man House Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', - 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', - 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', - 'Spectacle Rock Cave Exit': 'Death Mountain', - 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', - 'Paradox Cave (Bottom)': 'Paradox Cave Front', - 'Paradox Cave (Middle)': 'Paradox Cave', - 'Paradox Cave (Top)': 'Paradox Cave', - 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', - 'Hookshot Fairy': 'Hookshot Fairy', - 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', - 'Fairy Ascension Cave Exit (Bottom)': 'Fairy Ascension Plateau', - 'Fairy Ascension Cave Exit (Top)': 'Fairy Ascension Ledge', - 'Spiral Cave': 'Spiral Cave (Top)', - 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', - 'Spiral Cave Exit': 'East Death Mountain (Bottom)', - 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', - 'Pyramid Fairy': 'Pyramid Fairy', - 'East Dark World Hint': 'East Dark World Hint', - 'Palace of Darkness Hint': 'Palace of Darkness Hint', - 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', - 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', - 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', - 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', - 'Hype Cave': 'Hype Cave', - 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', - 'Brewery': 'Brewery', - 'C-Shaped House': 'C-Shaped House', - 'Chest Game': 'Chest Game', - 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', - 'Red Shield Shop': 'Red Shield Shop', - 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', - 'Dark World Shop': 'Village of Outcasts Shop', - 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', - 'Dark World Potion Shop': 'Dark World Potion Shop', - 'Archery Game': 'Archery Game', - 'Mire Shed': 'Mire Shed', - 'Dark Desert Hint': 'Dark Desert Hint', - 'Dark Desert Fairy': 'Dark Desert Healer Fairy', - 'Spike Cave': 'Spike Cave', - 'Hookshot Cave': 'Hookshot Cave (Front)', - 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', - 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', - 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', - 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', - 'Inverted Pyramid Hole': 'Pyramid', - 'Links House': 'Links House', +inverted_default_connections = {'Links House': 'Big Bomb Shop', 'Links House Exit': 'South Dark World', - 'Big Bomb Shop': 'Big Bomb Shop', - 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', - 'Dark Sanctuary Hint Exit': 'West Dark World', + 'Hyrule Castle Secret Entrance Exit': 'Light World', 'Old Man Cave (West)': 'Bumper Cave (bottom)', 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', 'Old Man Cave Exit (West)': 'West Dark World', 'Old Man Cave Exit (East)': 'Dark Death Mountain', - 'Dark Death Mountain Fairy': 'Old Man Cave', + 'Death Mountain Return Cave (West)': 'Bumper Cave (top)', + 'Death Mountain Return Cave Exit (West)': 'Death Mountain', + 'Big Bomb Shop': 'Links House', 'Bumper Cave (Bottom)': 'Old Man Cave Ledge', 'Bumper Cave (Top)': 'Dark Death Mountain Healer Fairy', + 'Dark Sanctuary Hint Exit': 'West Dark World', 'Bumper Cave Exit (Top)': 'Death Mountain Return Ledge', 'Bumper Cave Exit (Bottom)': 'Light World', - 'Death Mountain Return Cave (West)': 'Bumper Cave (top)', - 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain', - 'Death Mountain Return Cave Exit (East)': 'Death Mountain', - 'Hookshot Cave Front Exit': 'Dark Death Mountain', + 'Dark Death Mountain Fairy': 'Old Man Cave', 'Superbunny Cave Exit (Top)': 'Dark Death Mountain', + 'Hookshot Cave Front Exit': 'Dark Death Mountain', + 'Inverted Pyramid Hole': 'Pyramid', 'Pyramid Exit': 'Light World', - 'Inverted Pyramid Entrance': 'Bottom of Pyramid'} + 'Inverted Pyramid Entrance': 'Bottom of Pyramid' + } # non shuffled dungeons default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), @@ -2468,7 +2257,6 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Desert Palace Exit (West)', 'Desert Ledge'), ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), ('Eastern Palace Exit', 'Light World'), ('Tower of Hera', 'Hera Portal'), @@ -2477,12 +2265,9 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Hyrule Castle Courtyard'), ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Agahnims Tower', 'Agahnims Tower Portal'), - ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), - + ('Thieves Town', 'Thieves Town Portal'), ('Thieves Town Exit', 'West Dark World'), ('Skull Woods First Section Hole (East)', 'Skull Pinball'), @@ -2498,7 +2283,6 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Skull Woods Final Section', 'Skull 3 Portal'), ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), ('Ice Palace', 'Ice Portal'), - ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), ('Misery Mire', 'Mire Portal'), ('Misery Mire Exit', 'Dark Desert'), ('Palace of Darkness', 'Palace of Darkness Portal'), @@ -2507,72 +2291,31 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South ('Swamp Palace Exit', 'South Dark World'), ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), + ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal') + ] - ('Ganons Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Dark Death Mountain (Top)') - ] +open_default_dungeon_connections = [('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), + ('Agahnims Tower', 'Agahnims Tower Portal'), + ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), + ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), + ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), + ('Ganons Tower', 'Ganons Tower Portal'), + ('Ganons Tower Exit', 'Dark Death Mountain (Top)') + ] -inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Light World'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - # requires additional patch for flooding moat if moved - ('Swamp Palace', 'Swamp Portal'), - ('Swamp Palace Exit', 'South Dark World'), - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), +inverted_default_dungeon_connections = [('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), ('Agahnims Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Hyrule Castle Ledge'), - ('Ganons Tower', 'Agahnims Tower Portal'), ('Agahnims Tower Exit', 'Dark Death Mountain'), + ('Ice Palace Exit', 'Dark Lake Hylia'), ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), - ('Ice Palace Exit', 'Dark Lake Hylia') - ] + ('Ganons Tower', 'Agahnims Tower Portal'), + ('Ganons Tower Exit', 'Hyrule Castle Ledge') + ] indirect_connections = { 'Turtle Rock (Top)': 'Turtle Rock', diff --git a/test/inverted/TestInverted.py b/test/inverted/TestInverted.py index 06d7a655..6861329d 100644 --- a/test/inverted/TestInverted.py +++ b/test/inverted/TestInverted.py @@ -2,7 +2,7 @@ from BaseClasses import World from DoorShuffle import link_doors from Doors import create_doors from Dungeons import create_dungeons, get_dungeon_item_pool -from EntranceShuffle import link_inverted_entrances +from EntranceShuffle import link_entrances from InvertedRegions import create_inverted_regions from ItemList import generate_itempool, difficulties from Items import ItemFactory @@ -24,7 +24,7 @@ class TestInverted(TestBase): create_doors(self.world, 1) create_rooms(self.world, 1) create_dungeons(self.world, 1) - link_inverted_entrances(self.world, 1) + link_entrances(self.world, 1) link_doors(self.world, 1) generate_itempool(self.world, 1) self.world.required_medallions[1] = ['Ether', 'Quake'] diff --git a/test/inverted_owg/TestInvertedOWG.py b/test/inverted_owg/TestInvertedOWG.py index b772468f..d0d938f6 100644 --- a/test/inverted_owg/TestInvertedOWG.py +++ b/test/inverted_owg/TestInvertedOWG.py @@ -2,7 +2,7 @@ from BaseClasses import World from DoorShuffle import link_doors from Doors import create_doors from Dungeons import create_dungeons, get_dungeon_item_pool -from EntranceShuffle import link_inverted_entrances +from EntranceShuffle import link_entrances from InvertedRegions import create_inverted_regions from ItemList import generate_itempool, difficulties from Items import ItemFactory @@ -26,7 +26,7 @@ class TestInvertedOWG(TestBase): create_rooms(self.world, 1) create_dungeons(self.world, 1) create_owg_connections(self.world, 1) - link_inverted_entrances(self.world, 1) + link_entrances(self.world, 1) link_doors(self.world, 1) generate_itempool(self.world, 1) self.world.required_medallions[1] = ['Ether', 'Quake'] diff --git a/test/stats/EntranceShuffleStats.py b/test/stats/EntranceShuffleStats.py index 2be02071..16ab90e5 100644 --- a/test/stats/EntranceShuffleStats.py +++ b/test/stats/EntranceShuffleStats.py @@ -5,7 +5,7 @@ import time from collections import Counter, defaultdict from source.overworld.EntranceShuffle2 import link_entrances_new -from EntranceShuffle import link_entrances, link_inverted_entrances +from EntranceShuffle import link_entrances from BaseClasses import World from Regions import create_regions, create_dungeon_regions from InvertedRegions import create_inverted_regions @@ -30,10 +30,7 @@ def run_stats(): link_entrances_new(world, 1) def runner_old(world): - if main_mode == 'inverted': - link_inverted_entrances(world, 1) - else: - link_entrances(world, 1) + link_entrances(world, 1) compare_tests(tests, shuffle_mode, main_mode, ls, runner_old, runner_new) @@ -68,10 +65,7 @@ def run_old_stats(): continue def runner(world): - if main_mode == 'inverted': - link_inverted_entrances(world, 1) - else: - link_entrances(world, 1) + link_entrances(world, 1) run_tests(tests, shuffle_mode, main_mode, ls, runner)