diff --git a/worlds/alttp/EntranceShuffle.py b/worlds/alttp/EntranceShuffle.py index c062a17ea6..550e4878aa 100644 --- a/worlds/alttp/EntranceShuffle.py +++ b/worlds/alttp/EntranceShuffle.py @@ -1,74 +1,75 @@ # ToDo: With shuffle_ganon option, prevent gtower from linking to an exit only location through a 2 entrance cave. from collections import defaultdict +from BaseClasses import MultiWorld from .OverworldGlitchRules import overworld_glitch_connections from .UnderworldGlitchRules import underworld_glitch_connections from .Regions import mark_light_world_regions from .InvertedRegions import mark_dark_world_regions -def link_entrances(world, player): - connect_two_way(world, 'Links House', 'Links House Exit', player) # unshuffled. For now - connect_exit(world, 'Chris Houlihan Room Exit', 'Links House', player) # should always match link's house, except for plandos +def link_entrances(multiworld: MultiWorld, player: int): + connect_two_way(multiworld, 'Links House', 'Links House Exit', player) # unshuffled. For now + connect_exit(multiworld, 'Chris Houlihan Room Exit', 'Links House', player) # should always match link's house, except for plandos Dungeon_Exits = 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(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) + unbias_some_entrances(multiworld, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) # setup mandatory connections for exitname, regionname in mandatory_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) # if we do not shuffle, set default connections - if world.worlds[player].options.entrance_shuffle == 'vanilla': + if multiworld.worlds[player].options.entrance_shuffle == 'vanilla': for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) for exitname, regionname in default_dungeon_connections: - connect_simple(world, exitname, regionname, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_simple': + connect_simple(multiworld, exitname, regionname, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_simple': for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - simple_shuffle_dungeons(world, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_full': + simple_shuffle_dungeons(multiworld, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_full': for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - skull_woods_shuffle(world, player) + skull_woods_shuffle(multiworld, player) dungeon_exits = list(Dungeon_Exits) lw_entrances = list(LW_Dungeon_Entrances) dw_entrances = list(DW_Dungeon_Entrances) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: 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, 'Ganons Tower', 'Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) else: dw_entrances.append('Ganons Tower') dungeon_exits.append('Ganons Tower Exit') - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == '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) - connect_caves(world, lw_entrances, [], hyrule_castle_exits, player) + connect_mandatory_exits(multiworld, lw_entrances, hyrule_castle_exits, list(LW_Dungeon_Entrances_Must_Exit), player) + connect_caves(multiworld, 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) - connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_crossed': - crossed_shuffle_dungeons(world, player) - elif world.worlds[player].options.entrance_shuffle == 'simple': - simple_shuffle_dungeons(world, player) + connect_mandatory_exits(multiworld, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) + connect_mandatory_exits(multiworld, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) + connect_caves(multiworld, lw_entrances, dw_entrances, dungeon_exits, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_crossed': + crossed_shuffle_dungeons(multiworld, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'simple': + simple_shuffle_dungeons(multiworld, player) old_man_entrances = list(Old_Man_Entrances) caves = list(Cave_Exits) @@ -82,64 +83,64 @@ def link_entrances(world, player): # 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) - world.random.shuffle(two_door_caves) - world.random.shuffle(caves) + multiworld.random.shuffle(two_door_caves) + multiworld.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) + connect_two_way(multiworld, entrance1, exit1, player) + connect_two_way(multiworld, entrance2, exit2, player) # now the remaining pairs two_door_caves = list(Two_Door_Caves) - world.random.shuffle(two_door_caves) + multiworld.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) + connect_two_way(multiworld, entrance1, exit1, player) + connect_two_way(multiworld, entrance2, exit2, player) # 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)'] - world.random.shuffle(old_man_entrances) + multiworld.random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() remaining_entrances.extend(old_man_entrances) - world.random.shuffle(remaining_entrances) + multiworld.random.shuffle(remaining_entrances) old_man_entrance = remaining_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_exit, 'Old Man Cave Exit (East)', player) # 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, remaining_entrances, [], caves, player) + connect_caves(multiworld, remaining_entrances, [], caves, player) # scramble holes - scramble_holes(world, player) + scramble_holes(multiworld, player) # place blacksmith, has limited options - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) bomb_shop_doors.extend(blacksmith_doors) # place bomb shop, has limited options - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + connect_entrance(multiworld, 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) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) # place remaining doors - connect_doors(world, single_doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'restricted': - simple_shuffle_dungeons(world, player) + connect_doors(multiworld, single_doors, door_targets, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'restricted': + simple_shuffle_dungeons(multiworld, player) lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) dw_entrances = list(DW_Entrances + DW_Single_Cave_Doors) @@ -152,26 +153,26 @@ def link_entrances(world, player): door_targets = list(Single_Cave_Targets) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['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) + connect_mandatory_exits(multiworld, dw_entrances, caves, dw_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] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, old_man_exit, 'Old Man Cave Exit (East)', player) lw_entrances.remove(old_man_exit) # place blacksmith, has limited options all_entrances = lw_entrances + dw_entrances # cannot place it anywhere already taken (or that are otherwise not eligable for placement) blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) if blacksmith_hut in lw_entrances: lw_entrances.remove(blacksmith_hut) if blacksmith_hut in dw_entrances: @@ -182,36 +183,36 @@ def link_entrances(world, player): all_entrances = lw_entrances + dw_entrances # cannot place it anywhere already taken (or that are otherwise not eligable for placement) bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + connect_entrance(multiworld, 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 light world - world.random.shuffle(lw_entrances) + multiworld.random.shuffle(lw_entrances) old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, 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 + connect_caves(multiworld, lw_entrances, [], list(Old_Man_House), player) #for multiple seeds # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) + connect_caves(multiworld, lw_entrances, dw_entrances, caves, player) # scramble holes - scramble_holes(world, player) + scramble_holes(multiworld, player) doors = lw_entrances + dw_entrances # place remaining doors - connect_doors(world, doors, door_targets, player) + connect_doors(multiworld, doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'full': - skull_woods_shuffle(world, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'full': + skull_woods_shuffle(multiworld, 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) @@ -225,18 +226,18 @@ def link_entrances(world, player): old_man_house = list(Old_Man_House) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: - caves.append(tuple(world.random.sample( + caves.append(tuple(multiworld.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) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) else: dw_entrances.append('Ganons Tower') caves.append('Ganons Tower Exit') @@ -244,45 +245,45 @@ def link_entrances(world, player): # 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 - if world.random.randint(0, 1) == 0: + if multiworld.random.randint(0, 1) == 0: caves += old_man_house - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + connect_mandatory_exits(multiworld, 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) - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + connect_caves(multiworld, lw_entrances, [], old_man_house, player) + connect_mandatory_exits(multiworld, dw_entrances, caves, dw_must_exits, player) else: - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) + connect_mandatory_exits(multiworld, dw_entrances, caves, dw_must_exits, player) caves += old_man_house - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + connect_mandatory_exits(multiworld, 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 world.worlds[player].options.mode == 'standard': + connect_caves(multiworld, lw_entrances, [], old_man_house, player) + if multiworld.worlds[player].options.mode == 'standard': # rest of hyrule castle must be in light world - connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) + connect_caves(multiworld, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], 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] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, old_man_exit, 'Old Man Cave Exit (East)', player) lw_entrances.remove(old_man_exit) # place blacksmith, has limited options all_entrances = lw_entrances + dw_entrances # cannot place it anywhere already taken (or that are otherwise not eligable for placement) blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) if blacksmith_hut in lw_entrances: lw_entrances.remove(blacksmith_hut) if blacksmith_hut in dw_entrances: @@ -293,9 +294,9 @@ def link_entrances(world, player): all_entrances = lw_entrances + dw_entrances # cannot place it anywhere already taken (or that are otherwise not eligable for placement) bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Big Bomb Shop', player) if bomb_shop in lw_entrances: lw_entrances.remove(bomb_shop) if bomb_shop in dw_entrances: @@ -303,21 +304,21 @@ def link_entrances(world, player): # place the old man cave's entrance somewhere in the light world old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) + connect_caves(multiworld, lw_entrances, dw_entrances, caves, player) # scramble holes - scramble_holes(world, player) + scramble_holes(multiworld, player) doors = lw_entrances + dw_entrances # place remaining doors - connect_doors(world, doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'crossed': - skull_woods_shuffle(world, player) + connect_doors(multiworld, doors, door_targets, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'crossed': + skull_woods_shuffle(multiworld, 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) @@ -329,43 +330,43 @@ def link_entrances(world, player): door_targets = list(Single_Cave_Targets) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: - caves.append(tuple(world.random.sample( + caves.append(tuple(multiworld.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, 'Ganons Tower', 'Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) else: entrances.append('Ganons Tower') caves.append('Ganons Tower Exit') #place must-exit caves - connect_mandatory_exits(world, entrances, caves, must_exits, player) + connect_mandatory_exits(multiworld, entrances, caves, must_exits, player) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # rest of hyrule castle must be dealt with - connect_caves(world, entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) + connect_caves(multiworld, entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], 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] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, 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 eligable for placement) blacksmith_doors = [door for door in blacksmith_doors if door in entrances] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) entrances.remove(blacksmith_hut) bomb_shop_doors.extend(blacksmith_doors) @@ -373,28 +374,28 @@ def link_entrances(world, player): # cannot place it anywhere already taken (or that are otherwise not eligable for placement) bomb_shop_doors = [door for door in bomb_shop_doors if door in entrances] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Big Bomb Shop', player) entrances.remove(bomb_shop) # place the old man cave's entrance somewhere - world.random.shuffle(entrances) + multiworld.random.shuffle(entrances) old_man_entrance = entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest - connect_caves(world, entrances, [], caves, player) + connect_caves(multiworld, entrances, [], caves, player) # scramble holes - scramble_holes(world, player) + scramble_holes(multiworld, player) # place remaining doors - connect_doors(world, entrances, door_targets, player) + connect_doors(multiworld, entrances, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'insanity': + elif multiworld.worlds[player].options.entrance_shuffle == 'insanity': # beware ye who enter here entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] @@ -412,7 +413,7 @@ def link_entrances(world, player): blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) door_targets = list(Single_Cave_Targets) - world.random.shuffle(doors) + multiworld.random.shuffle(doors) old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera'] @@ -429,13 +430,13 @@ def link_entrances(world, player): 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # cannot move uncle cave - connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) - connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player) - connect_entrance(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) + connect_entrance(multiworld, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) + connect_exit(multiworld, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player) + connect_entrance(multiworld, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) else: hole_entrances.append('Hyrule Castle Secret Entrance Drop') hole_targets.append('Hyrule Castle Secret Entrance') @@ -443,10 +444,10 @@ def link_entrances(world, player): entrances.append('Hyrule Castle Secret Entrance Stairs') caves.append('Hyrule Castle Secret Entrance Exit') - 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) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) + connect_two_way(multiworld, 'Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(multiworld, 'Pyramid Hole', 'Pyramid', player) else: entrances.append('Ganons Tower') caves.extend(['Ganons Tower Exit', 'Pyramid Exit']) @@ -455,19 +456,19 @@ def link_entrances(world, player): entrances_must_exits.append('Pyramid Entrance') doors.extend(['Ganons Tower', 'Pyramid Entrance']) - world.random.shuffle(hole_entrances) - world.random.shuffle(hole_targets) - world.random.shuffle(entrances) + multiworld.random.shuffle(hole_entrances) + multiworld.random.shuffle(hole_targets) + multiworld.random.shuffle(entrances) # fill up holes for hole in hole_entrances: - connect_entrance(world, hole, hole_targets.pop(), player) + connect_entrance(multiworld, hole, hole_targets.pop(), player) # hyrule castle handling - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape - connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player) + connect_entrance(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_exit(multiworld, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player) caves.append(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) else: doors.append('Hyrule Castle Entrance (South)') @@ -476,7 +477,7 @@ def link_entrances(world, player): # now let's deal with mandatory reachable stuff def extract_reachable_exit(cavelist): - world.random.shuffle(cavelist) + multiworld.random.shuffle(cavelist) candidate = None for cave in cavelist: if isinstance(cave, tuple) and len(cave) > 1: @@ -496,8 +497,8 @@ def link_entrances(world, player): exit = cave[-1] cave = cave[:-1] - connect_exit(world, exit, entrance, player) - connect_entrance(world, doors.pop(), exit, player) + connect_exit(multiworld, exit, entrance, player) + connect_entrance(multiworld, doors.pop(), exit, player) # rest of cave now is forced to be in this world caves.append(cave) @@ -508,26 +509,26 @@ def link_entrances(world, 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 = [entrance for entrance in old_man_entrances if entrance in entrances] - world.random.shuffle(old_man_entrances) + multiworld.random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() entrances.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) + connect_exit(multiworld, 'Old Man Cave Exit (East)', old_man_exit, player) + connect_entrance(multiworld, 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] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, 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] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Big Bomb Shop', player) doors.remove(bomb_shop) # handle remaining caves @@ -536,40 +537,40 @@ def link_entrances(world, player): cave = (cave,) for exit in cave: - connect_exit(world, exit, entrances.pop(), player) - connect_entrance(world, doors.pop(), exit, player) + connect_exit(multiworld, exit, entrances.pop(), player) + connect_entrance(multiworld, doors.pop(), exit, player) # place remaining doors - connect_doors(world, doors, door_targets, player) + connect_doors(multiworld, doors, door_targets, player) else: raise NotImplementedError( - f'{world.worlds[player].options.entrance_shuffle} Shuffling not supported yet. Player {world.get_player_name(player)}') + f'{multiworld.worlds[player].options.entrance_shuffle} Shuffling not supported yet. Player {multiworld.get_player_name(player)}') - if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: - overworld_glitch_connections(world, player) + if multiworld.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + overworld_glitch_connections(multiworld, player) # mandatory hybrid major glitches connections - if world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: - underworld_glitch_connections(world, player) + if multiworld.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: + underworld_glitch_connections(multiworld, player) # 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 Palace (Entrance)': - world.worlds[player].swamp_patch_required = True + if multiworld.get_entrance('Dam', player).connected_region.name != 'Dam' or multiworld.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Palace (Entrance)': + multiworld.worlds[player].swamp_patch_required = True # check for potion shop location - if world.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': - world.worlds[player].powder_patch_required = True + if multiworld.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': + multiworld.worlds[player].powder_patch_required = True # check for ganon location - if world.get_entrance('Pyramid Hole', player).connected_region.name != 'Pyramid': - world.worlds[player].ganon_at_pyramid = False + if multiworld.get_entrance('Pyramid Hole', player).connected_region.name != 'Pyramid': + multiworld.worlds[player].ganon_at_pyramid = False # check for Ganon's Tower location - if world.get_entrance('Ganons Tower', player).connected_region.name != 'Ganons Tower (Entrance)': - world.worlds[player].ganonstower_vanilla = False + if multiworld.get_entrance('Ganons Tower', player).connected_region.name != 'Ganons Tower (Entrance)': + multiworld.worlds[player].ganonstower_vanilla = False -def link_inverted_entrances(world, player): +def link_inverted_entrances(multiworld: MultiWorld, player: int): # Link's house shuffled freely, Houlihan set in mandatory_connections Dungeon_Exits = Inverted_Dungeon_Exits_Base.copy() @@ -577,28 +578,28 @@ def link_inverted_entrances(world, player): Old_Man_House = Old_Man_House_Base.copy() Cave_Three_Exits = Cave_Three_Exits_Base.copy() - unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) + unbias_some_entrances(multiworld, 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) + connect_simple(multiworld, exitname, regionname, player) # if we do not shuffle, set default connections - if world.worlds[player].options.entrance_shuffle == 'vanilla': + if multiworld.worlds[player].options.entrance_shuffle == 'vanilla': for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) for exitname, regionname in inverted_default_dungeon_connections: - connect_simple(world, exitname, regionname, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_simple': + connect_simple(multiworld, exitname, regionname, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_simple': for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - simple_shuffle_dungeons(world, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_full': + simple_shuffle_dungeons(multiworld, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_full': for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - skull_woods_shuffle(world, player) + skull_woods_shuffle(multiworld, player) dungeon_exits = list(Dungeon_Exits) lw_entrances = list(Inverted_LW_Dungeon_Entrances) @@ -606,7 +607,7 @@ def link_inverted_entrances(world, player): dw_entrances = list(Inverted_DW_Dungeon_Entrances) # randomize which desert ledge door is a must-exit - if world.random.randint(0, 1): + if multiworld.random.randint(0, 1): lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') lw_entrances.append('Desert Palace Entrance (West)') else: @@ -616,8 +617,8 @@ def link_inverted_entrances(world, player): 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, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: lw_entrances.append('Inverted Ganons Tower') @@ -627,14 +628,14 @@ def link_inverted_entrances(world, player): # 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] - world.random.shuffle(aga_doors) + multiworld.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) - world.random.shuffle(hc_ledge_entrances) + multiworld.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) @@ -643,16 +644,16 @@ def link_inverted_entrances(world, player): else: dw_entrances.remove(aga_door) - connect_two_way(world, aga_door, 'Inverted Agahnims Tower Exit', player) + connect_two_way(multiworld, aga_door, 'Inverted Agahnims Tower Exit', player) dungeon_exits.remove('Inverted Agahnims Tower Exit') - connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) + connect_mandatory_exits(multiworld, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) - connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) - elif world.worlds[player].options.entrance_shuffle == 'dungeons_crossed': - inverted_crossed_shuffle_dungeons(world, player) - elif world.worlds[player].options.entrance_shuffle == 'simple': - simple_shuffle_dungeons(world, player) + connect_caves(multiworld, lw_entrances, dw_entrances, dungeon_exits, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'dungeons_crossed': + inverted_crossed_shuffle_dungeons(multiworld, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'simple': + simple_shuffle_dungeons(multiworld, player) old_man_entrances = list(Inverted_Old_Man_Entrances) caves = list(Cave_Exits) @@ -666,28 +667,28 @@ def link_inverted_entrances(world, player): # 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) - world.random.shuffle(two_door_caves) - world.random.shuffle(caves) + multiworld.random.shuffle(two_door_caves) + multiworld.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) + connect_two_way(multiworld, entrance1, exit1, player) + connect_two_way(multiworld, entrance2, exit2, player) # now the remaining pairs two_door_caves = list(Inverted_Two_Door_Caves) - world.random.shuffle(two_door_caves) + multiworld.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) + connect_two_way(multiworld, entrance1, exit1, player) + connect_two_way(multiworld, entrance2, exit2, player) # place links house links_house_doors = [i for i in bomb_shop_doors + blacksmith_doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = world.random.choice(list(links_house_doors)) - connect_two_way(world, links_house, 'Inverted Links House Exit', player) + links_house = multiworld.random.choice(list(links_house_doors)) + connect_two_way(multiworld, links_house, 'Inverted Links House Exit', player) if links_house in bomb_shop_doors: bomb_shop_doors.remove(links_house) if links_house in blacksmith_doors: @@ -697,11 +698,11 @@ def link_inverted_entrances(world, player): # place dark sanc sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in bomb_shop_doors] - sanc_door = world.random.choice(sanc_doors) + sanc_door = multiworld.random.choice(sanc_doors) bomb_shop_doors.remove(sanc_door) - connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) - world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + connect_entrance(multiworld, sanc_door, 'Inverted Dark Sanctuary', player) + multiworld.get_entrance('Inverted Dark Sanctuary Exit', player).connect(multiworld.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)', @@ -710,10 +711,10 @@ def link_inverted_entrances(world, player): # place old man, bumper cave bottom to DDM entrances not in east bottom - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, 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) @@ -723,33 +724,33 @@ def link_inverted_entrances(world, player): caves.extend(list(three_exit_caves)) # connect rest - connect_caves(world, lw_dm_entrances, [], caves, player) + connect_caves(multiworld, lw_dm_entrances, [], caves, player) # scramble holes - scramble_inverted_holes(world, player) + scramble_inverted_holes(multiworld, player) # place blacksmith, has limited options blacksmith_doors = [door for door in blacksmith_doors[:]] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, 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[:]] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Inverted Big Bomb Shop', player) single_doors.extend(bomb_shop_doors) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) # place remaining doors - connect_doors(world, single_doors, door_targets, player) + connect_doors(multiworld, single_doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'restricted': - simple_shuffle_dungeons(world, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'restricted': + simple_shuffle_dungeons(multiworld, 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) @@ -764,8 +765,8 @@ def link_inverted_entrances(world, player): # place links house links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = world.random.choice(list(links_house_doors)) - connect_two_way(world, links_house, 'Inverted Links House Exit', player) + links_house = multiworld.random.choice(list(links_house_doors)) + connect_two_way(multiworld, links_house, 'Inverted Links House Exit', player) if links_house in lw_entrances: lw_entrances.remove(links_house) elif links_house in dw_entrances: @@ -775,32 +776,32 @@ def link_inverted_entrances(world, player): # place dark sanc sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] - sanc_door = world.random.choice(sanc_doors) + sanc_door = multiworld.random.choice(sanc_doors) dw_entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) - world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + connect_entrance(multiworld, sanc_door, 'Inverted Dark Sanctuary', player) + multiworld.get_entrance('Inverted Dark Sanctuary Exit', player).connect(multiworld.get_entrance(sanc_door, player).parent_region) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) # place must exits - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + connect_mandatory_exits(multiworld, 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] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, 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] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) if blacksmith_hut in lw_entrances: lw_entrances.remove(blacksmith_hut) if blacksmith_hut in dw_entrances: @@ -811,30 +812,30 @@ def link_inverted_entrances(world, player): 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] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Inverted 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 - world.random.shuffle(dw_entrances) + multiworld.random.shuffle(dw_entrances) old_man_entrance = dw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) + connect_caves(multiworld, lw_entrances, dw_entrances, caves, player) # scramble holes - scramble_inverted_holes(world, player) + scramble_inverted_holes(multiworld, player) doors = lw_entrances + dw_entrances # place remaining doors - connect_doors(world, doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'full': - skull_woods_shuffle(world, player) + connect_doors(multiworld, doors, door_targets, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'full': + skull_woods_shuffle(multiworld, 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) @@ -847,7 +848,7 @@ def link_inverted_entrances(world, player): old_man_house = list(Old_Man_House) # randomize which desert ledge door is a must-exit - if world.random.randint(0, 1) == 0: + if multiworld.random.randint(0, 1) == 0: lw_must_exits.append('Desert Palace Entrance (North)') lw_entrances.append('Desert Palace Entrance (West)') else: @@ -855,12 +856,12 @@ def link_inverted_entrances(world, player): lw_entrances.append('Desert Palace Entrance (North)') # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) lw_entrances.append('Hyrule Castle Entrance (South)') - if not world.shuffle_ganon: - connect_two_way(world, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: lw_entrances.append('Inverted Ganons Tower') @@ -870,14 +871,14 @@ def link_inverted_entrances(world, player): # 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] - world.random.shuffle(aga_doors) + multiworld.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) - world.random.shuffle(hc_ledge_entrances) + multiworld.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) @@ -886,14 +887,14 @@ def link_inverted_entrances(world, player): else: dw_entrances.remove(aga_door) - connect_two_way(world, aga_door, 'Inverted Agahnims Tower Exit', player) + connect_two_way(multiworld, aga_door, 'Inverted Agahnims Tower Exit', player) caves.remove('Inverted Agahnims Tower Exit') # place links house links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = world.random.choice(list(links_house_doors)) - connect_two_way(world, links_house, 'Inverted Links House Exit', player) + links_house = multiworld.random.choice(list(links_house_doors)) + connect_two_way(multiworld, links_house, 'Inverted Links House Exit', player) if links_house in lw_entrances: lw_entrances.remove(links_house) if links_house in dw_entrances: @@ -903,35 +904,35 @@ def link_inverted_entrances(world, player): # place dark sanc sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances] - sanc_door = world.random.choice(sanc_doors) + sanc_door = multiworld.random.choice(sanc_doors) dw_entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) - world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + connect_entrance(multiworld, sanc_door, 'Inverted Dark Sanctuary', player) + multiworld.get_entrance('Inverted Dark Sanctuary Exit', player).connect(multiworld.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 world.random.randint(0, 1) == 0: + if multiworld.random.randint(0, 1) == 0: caves += old_man_house - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) + connect_mandatory_exits(multiworld, 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) + connect_caves(multiworld, 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) + connect_caves(multiworld, dw_entrances, [], old_man_house, player) + connect_mandatory_exits(multiworld, lw_entrances, caves, lw_must_exits, player) # put all HC exits in LW in inverted full shuffle - connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)')], player) + connect_caves(multiworld, 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 dw_entrances + lw_entrances] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, 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' @@ -943,9 +944,9 @@ def link_inverted_entrances(world, player): 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] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, blacksmith_hut, 'Blacksmiths Hut', player) if blacksmith_hut in lw_entrances: lw_entrances.remove(blacksmith_hut) if blacksmith_hut in dw_entrances: @@ -956,36 +957,36 @@ def link_inverted_entrances(world, player): 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] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Inverted 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 + # place the old man cave's entrance somewhere in the same multiworld he'll exit from if old_man_world == 'light': - world.random.shuffle(lw_entrances) + multiworld.random.shuffle(lw_entrances) old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) elif old_man_world == 'dark': - world.random.shuffle(dw_entrances) + multiworld.random.shuffle(dw_entrances) old_man_entrance = dw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) + connect_caves(multiworld, lw_entrances, dw_entrances, caves, player) # scramble holes - scramble_inverted_holes(world, player) + scramble_inverted_holes(multiworld, player) doors = lw_entrances + dw_entrances # place remaining doors - connect_doors(world, doors, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'crossed': - skull_woods_shuffle(world, player) + connect_doors(multiworld, doors, door_targets, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'crossed': + skull_woods_shuffle(multiworld, 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) @@ -997,19 +998,19 @@ def link_inverted_entrances(world, player): door_targets = list(Inverted_Single_Cave_Targets) # randomize which desert ledge door is a must-exit - if world.random.randint(0, 1) == 0: + if multiworld.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(world.random.sample( + caves.append(tuple(multiworld.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, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: entrances.append('Inverted Ganons Tower') @@ -1017,26 +1018,26 @@ def link_inverted_entrances(world, player): hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'] # shuffle aga door. if it's on hc ledge, then one other hc ledge door has to be must_exit - aga_door = world.random.choice(list(entrances)) + aga_door = multiworld.random.choice(list(entrances)) if aga_door in hc_ledge_entrances: hc_ledge_entrances.remove(aga_door) - world.random.shuffle(hc_ledge_entrances) + multiworld.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, 'Inverted Agahnims Tower Exit', player) + connect_two_way(multiworld, aga_door, 'Inverted Agahnims Tower Exit', player) caves.remove('Inverted Agahnims Tower Exit') # place links house links_house_doors = [i for i in entrances + must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = world.random.choice(list(links_house_doors)) - connect_two_way(world, links_house, 'Inverted Links House Exit', player) + links_house = multiworld.random.choice(list(links_house_doors)) + connect_two_way(multiworld, links_house, 'Inverted Links House Exit', player) if links_house in entrances: entrances.remove(links_house) elif links_house in must_exits: @@ -1044,58 +1045,58 @@ def link_inverted_entrances(world, player): # place dark sanc sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances] - sanc_door = world.random.choice(sanc_doors) + sanc_door = multiworld.random.choice(sanc_doors) entrances.remove(sanc_door) - connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) - world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + connect_entrance(multiworld, sanc_door, 'Inverted Dark Sanctuary', player) + multiworld.get_entrance('Inverted Dark Sanctuary Exit', player).connect(multiworld.get_entrance(sanc_door, player).parent_region) # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) #place must-exit caves - connect_mandatory_exits(world, entrances, caves, must_exits, player) + connect_mandatory_exits(multiworld, 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] - world.random.shuffle(old_man_entrances) + multiworld.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) + connect_two_way(multiworld, 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] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, 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] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Inverted Big Bomb Shop', player) entrances.remove(bomb_shop) # place the old man cave's entrance somewhere - world.random.shuffle(entrances) + multiworld.random.shuffle(entrances) old_man_entrance = entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + connect_two_way(multiworld, old_man_entrance, 'Old Man Cave Exit (West)', player) # now scramble the rest - connect_caves(world, entrances, [], caves, player) + connect_caves(multiworld, entrances, [], caves, player) # scramble holes - scramble_inverted_holes(world, player) + scramble_inverted_holes(multiworld, player) # place remaining doors - connect_doors(world, entrances, door_targets, player) - elif world.worlds[player].options.entrance_shuffle == 'insanity': + connect_doors(multiworld, entrances, door_targets, player) + elif multiworld.worlds[player].options.entrance_shuffle == 'insanity': # beware ye who enter here entrances = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'] @@ -1106,7 +1107,7 @@ def link_inverted_entrances(world, player): Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'] # randomize which desert ledge door is a must-exit - if world.random.randint(0, 1) == 0: + if multiworld.random.randint(0, 1) == 0: entrances_must_exits.append('Desert Palace Entrance (North)') entrances.append('Desert Palace Entrance (West)') else: @@ -1121,7 +1122,7 @@ def link_inverted_entrances(world, player): blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) door_targets = list(Inverted_Single_Cave_Targets) - world.random.shuffle(doors) + multiworld.random.shuffle(doors) old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances) + ['Tower of Hera', 'Inverted Agahnims Tower'] @@ -1137,17 +1138,17 @@ def link_inverted_entrances(world, player): 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) + connect_doors(multiworld, ['Tavern North'], ['Tavern'], player) hole_entrances.append('Hyrule Castle Secret Entrance Drop') hole_targets.append('Hyrule Castle Secret Entrance') entrances.append('Hyrule Castle Secret Entrance Stairs') caves.append('Hyrule Castle Secret Entrance Exit') - if not world.shuffle_ganon: - connect_two_way(world, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) - connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + connect_two_way(multiworld, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(multiworld, 'Inverted Pyramid Hole', 'Pyramid', player) else: entrances.append('Inverted Ganons Tower') caves.extend(['Inverted Ganons Tower Exit', 'Pyramid Exit']) @@ -1155,13 +1156,13 @@ def link_inverted_entrances(world, player): hole_targets.append('Pyramid') doors.extend(['Inverted Ganons Tower', 'Inverted Pyramid Entrance']) - world.random.shuffle(hole_entrances) - world.random.shuffle(hole_targets) - world.random.shuffle(entrances) + multiworld.random.shuffle(hole_entrances) + multiworld.random.shuffle(hole_targets) + multiworld.random.shuffle(entrances) # fill up holes for hole in hole_entrances: - connect_entrance(world, hole, hole_targets.pop(), player) + connect_entrance(multiworld, 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)')) @@ -1169,8 +1170,8 @@ def link_inverted_entrances(world, player): # place links house and dark sanc links_house_doors = [i for i in entrances + entrances_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] - links_house = world.random.choice(list(links_house_doors)) - connect_two_way(world, links_house, 'Inverted Links House Exit', player) + links_house = multiworld.random.choice(list(links_house_doors)) + connect_two_way(multiworld, links_house, 'Inverted Links House Exit', player) if links_house in entrances: entrances.remove(links_house) elif links_house in entrances_must_exits: @@ -1178,15 +1179,15 @@ def link_inverted_entrances(world, player): doors.remove(links_house) sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances] - sanc_door = world.random.choice(sanc_doors) + sanc_door = multiworld.random.choice(sanc_doors) entrances.remove(sanc_door) doors.remove(sanc_door) - connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) - world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) + connect_entrance(multiworld, sanc_door, 'Inverted Dark Sanctuary', player) + multiworld.get_entrance('Inverted Dark Sanctuary Exit', player).connect(multiworld.get_entrance(sanc_door, player).parent_region) # now let's deal with mandatory reachable stuff def extract_reachable_exit(cavelist): - world.random.shuffle(cavelist) + multiworld.random.shuffle(cavelist) candidate = None for cave in cavelist: if isinstance(cave, tuple) and len(cave) > 1: @@ -1206,9 +1207,9 @@ def link_inverted_entrances(world, player): 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 + connect_exit(multiworld, exit, entrance, player) + connect_entrance(multiworld, doors.pop(), exit, player) + # rest of cave now is forced to be in this multiworld caves.append(cave) # connect mandatory exits @@ -1218,26 +1219,26 @@ def link_inverted_entrances(world, 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 = [entrance for entrance in old_man_entrances if entrance in entrances] - world.random.shuffle(old_man_entrances) + multiworld.random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() entrances.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) + connect_exit(multiworld, 'Old Man Cave Exit (East)', old_man_exit, player) + connect_entrance(multiworld, 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] - world.random.shuffle(blacksmith_doors) + multiworld.random.shuffle(blacksmith_doors) blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) + connect_entrance(multiworld, 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] - world.random.shuffle(bomb_shop_doors) + multiworld.random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) + connect_entrance(multiworld, bomb_shop, 'Inverted Big Bomb Shop', player) doors.remove(bomb_shop) # handle remaining caves @@ -1246,49 +1247,49 @@ def link_inverted_entrances(world, player): cave = (cave,) for exit in cave: - connect_exit(world, exit, entrances.pop(), player) - connect_entrance(world, doors.pop(), exit, player) + connect_exit(multiworld, exit, entrances.pop(), player) + connect_entrance(multiworld, doors.pop(), exit, player) # place remaining doors - connect_doors(world, doors, door_targets, player) + connect_doors(multiworld, doors, door_targets, player) else: raise NotImplementedError('Shuffling not supported yet') - if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: - overworld_glitch_connections(world, player) + if multiworld.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + overworld_glitch_connections(multiworld, player) # mandatory hybrid major glitches connections - if world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: - underworld_glitch_connections(world, player) + if multiworld.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: + underworld_glitch_connections(multiworld, player) # patch swamp drain - if world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Palace (Entrance)': - world.worlds[player].swamp_patch_required = True + if multiworld.get_entrance('Dam', player).connected_region.name != 'Dam' or multiworld.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Palace (Entrance)': + multiworld.worlds[player].swamp_patch_required = True # check for potion shop location - if world.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': - world.worlds[player].powder_patch_required = True + if multiworld.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': + multiworld.worlds[player].powder_patch_required = True # check for ganon location - if world.get_entrance('Inverted Pyramid Hole', player).connected_region.name != 'Pyramid': - world.worlds[player].ganon_at_pyramid = False + if multiworld.get_entrance('Inverted Pyramid Hole', player).connected_region.name != 'Pyramid': + multiworld.worlds[player].ganon_at_pyramid = False # check for Ganon's Tower location - if world.get_entrance('Inverted Ganons Tower', player).connected_region.name != 'Ganons Tower (Entrance)': - world.worlds[player].ganonstower_vanilla = False + if multiworld.get_entrance('Inverted Ganons Tower', player).connected_region.name != 'Ganons Tower (Entrance)': + multiworld.worlds[player].ganonstower_vanilla = False -def connect_simple(world, exitname, regionname, player): - world.get_entrance(exitname, player).connect(world.get_region(regionname, player)) +def connect_simple(multiworld: MultiWorld, exitname: str, regionname: str, player: int): + multiworld.get_entrance(exitname, player).connect(multiworld.get_region(regionname, player)) -def connect_entrance(world, entrancename: str, exitname: str, player: int): - entrance = world.get_entrance(entrancename, player) +def connect_entrance(multiworld: MultiWorld, entrancename: str, exitname: str, player: int): + entrance = multiworld.get_entrance(entrancename, player) # check if we got an entrance or a region to connect to try: - region = world.get_region(exitname, player) + region = multiworld.get_region(exitname, player) exit = None except KeyError: - exit = world.get_entrance(exitname, player) + exit = multiworld.get_entrance(exitname, player) region = exit.parent_region # if this was already connected somewhere, remove the backreference @@ -1299,24 +1300,24 @@ def connect_entrance(world, entrancename: str, exitname: str, player: int): addresses = door_addresses[entrance.name][0] entrance.connect(region, addresses, target) - world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) + multiworld.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) -def connect_exit(world, exitname, entrancename, player): - entrance = world.get_entrance(entrancename, player) - exit = world.get_entrance(exitname, player) +def connect_exit(multiworld: MultiWorld, exitname: str, entrancename: str, player: int): + entrance = multiworld.get_entrance(entrancename, player) + exit = multiworld.get_entrance(exitname, player) # if this was already connected somewhere, remove the backreference if exit.connected_region is not None: exit.connected_region.entrances.remove(exit) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) + multiworld.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) -def connect_two_way(world, entrancename, exitname, player): - entrance = world.get_entrance(entrancename, player) - exit = world.get_entrance(exitname, player) +def connect_two_way(multiworld: MultiWorld, entrancename: str, exitname: str, player: int): + entrance = multiworld.get_entrance(entrancename, player) + exit = multiworld.get_entrance(exitname, player) # if these were already connected somewhere, remove the backreference if entrance.connected_region is not None: @@ -1326,10 +1327,10 @@ def connect_two_way(world, entrancename, exitname, player): entrance.connect(exit.parent_region, door_addresses[entrance.name][0], exit_ids[exit.name][0]) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - world.spoiler.set_entrance(entrance.name, exit.name, 'both', player) + multiworld.spoiler.set_entrance(entrance.name, exit.name, 'both', player) -def scramble_holes(world, player): +def scramble_holes(multiworld: MultiWorld, player: int): hole_entrances = [('Kakariko Well Cave', 'Kakariko Well Drop'), ('Bat Cave Cave', 'Bat Cave Drop'), ('North Fairy Cave', 'North Fairy Cave Drop'), @@ -1343,39 +1344,39 @@ def scramble_holes(world, player): ('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'), ('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 not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(multiworld, 'Pyramid Hole', 'Pyramid', player) else: hole_targets.append(('Pyramid Exit', 'Pyramid')) - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # cannot move uncle cave - connect_two_way(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) - connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) + connect_two_way(multiworld, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) + connect_entrance(multiworld, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) else: 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.worlds[player].options.entrance_shuffle == 'crossed': + if multiworld.worlds[player].options.entrance_shuffle == 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - if world.shuffle_ganon: - world.random.shuffle(hole_targets) + if multiworld.shuffle_ganon: + multiworld.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.worlds[player].options.entrance_shuffle != 'crossed': + connect_two_way(multiworld, 'Pyramid Entrance', exit, player) + connect_entrance(multiworld, 'Pyramid Hole', target, player) + if multiworld.worlds[player].options.entrance_shuffle != 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - world.random.shuffle(hole_targets) + multiworld.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) + connect_two_way(multiworld, entrance, exit, player) + connect_entrance(multiworld, drop, target, player) -def scramble_inverted_holes(world, player): +def scramble_inverted_holes(multiworld: MultiWorld, player: int): hole_entrances = [('Kakariko Well Cave', 'Kakariko Well Drop'), ('Bat Cave Cave', 'Bat Cave Drop'), ('North Fairy Cave', 'North Fairy Cave Drop'), @@ -1389,9 +1390,9 @@ def scramble_inverted_holes(world, player): ('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) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) + connect_entrance(multiworld, 'Inverted Pyramid Hole', 'Pyramid', player) else: hole_targets.append(('Pyramid Exit', 'Pyramid')) @@ -1400,58 +1401,59 @@ def scramble_inverted_holes(world, player): 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.worlds[player].options.entrance_shuffle == 'crossed': + if multiworld.worlds[player].options.entrance_shuffle == 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - if world.shuffle_ganon: - world.random.shuffle(hole_targets) + if multiworld.shuffle_ganon: + multiworld.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.worlds[player].options.entrance_shuffle != 'crossed': + connect_two_way(multiworld, 'Inverted Pyramid Entrance', exit, player) + connect_entrance(multiworld, 'Inverted Pyramid Hole', target, player) + if multiworld.worlds[player].options.entrance_shuffle != 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) - world.random.shuffle(hole_targets) + multiworld.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) + connect_two_way(multiworld, entrance, exit, player) + connect_entrance(multiworld, drop, target, player) -def connect_random(world, exitlist, targetlist, player, two_way=False): +def connect_random(multiworld: MultiWorld, exitlist: list[str], targetlist: list[str], + player: int, two_way: bool = False): targetlist = list(targetlist) - world.random.shuffle(targetlist) + multiworld.random.shuffle(targetlist) for exit, target in zip(exitlist, targetlist): if two_way: - connect_two_way(world, exit, target, player) + connect_two_way(multiworld, exit, target, player) else: - connect_entrance(world, exit, target, player) + connect_entrance(multiworld, exit, target, player) -def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): +def connect_mandatory_exits(multiworld: MultiWorld, entrances: list[str], caves: list[tuple[str, str]], must_be_exits: list[str], player): # Keeps track of entrances that cannot be used to access each exit / cave - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy() else: invalid_connections = Must_Exit_Invalid_Connections.copy() invalid_cave_connections = defaultdict(set) - if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if multiworld.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: from . import OverworldGlitchRules - for entrance in OverworldGlitchRules.get_non_mandatory_exits(world.worlds[player].options.mode == 'inverted'): + for entrance in OverworldGlitchRules.get_non_mandatory_exits(multiworld.worlds[player].options.mode == 'inverted'): invalid_connections[entrance] = set() if entrance in must_be_exits: must_be_exits.remove(entrance) entrances.append(entrance) """This works inplace""" - world.random.shuffle(entrances) - world.random.shuffle(caves) + multiworld.random.shuffle(entrances) + multiworld.random.shuffle(caves) # Handle inverted Aga Tower - if it depends on connections, then so does Hyrule Castle Ledge - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': for entrance in invalid_connections: - if world.get_entrance(entrance, player).connected_region == world.get_region('Inverted Agahnims Tower', + if multiworld.get_entrance(entrance, player).connected_region == multiworld.get_region('Inverted Agahnims Tower', player): for exit in invalid_connections[entrance]: invalid_connections[exit] = invalid_connections[exit].union( @@ -1473,11 +1475,11 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): raise KeyError('No more caves left. Should not happen!') # all caves are sorted so that the last exit is always reachable - connect_two_way(world, exit, cave[-1], player) + connect_two_way(multiworld, exit, cave[-1], player) if len(cave) == 2: entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit] and e not in invalid_cave_connections[tuple(cave)]) entrances.remove(entrance) - connect_two_way(world, entrance, cave[0], player) + connect_two_way(multiworld, entrance, cave[0], player) if cave in used_caves: required_entrances -= 2 used_caves.remove(cave) @@ -1490,7 +1492,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit]) cave_entrances.append(entrance) entrances.remove(entrance) - connect_two_way(world, entrance, cave_exit, player) + connect_two_way(multiworld, entrance, cave_exit, player) if entrance not in invalid_connections: invalid_connections[exit] = set() if all(entrance in invalid_connections for entrance in cave_entrances): @@ -1504,7 +1506,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): else: required_entrances += len(cave)-1 caves.append(cave[0:-1]) - world.random.shuffle(caves) + multiworld.random.shuffle(caves) used_caves.append(cave[0:-1]) invalid_cave_connections[tuple(cave[0:-1])] = invalid_cave_connections[tuple(cave)].union(invalid_connections[exit]) caves.remove(cave) @@ -1514,19 +1516,20 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): entrance = next(e for e in entrances[::-1] if e not in invalid_cave_connections[tuple(cave)]) invalid_cave_connections[tuple(cave)] = set() entrances.remove(entrance) - connect_two_way(world, entrance, cave_exit, player) + connect_two_way(multiworld, entrance, cave_exit, player) caves.remove(cave) -def connect_caves(world, lw_entrances, dw_entrances, caves, player): +def connect_caves(multiworld: MultiWorld, lw_entrances: list[str], dw_entrances: list[str], + caves: list[tuple[str, str]], player: int): """This works inplace""" - world.random.shuffle(lw_entrances) - world.random.shuffle(dw_entrances) - world.random.shuffle(caves) + multiworld.random.shuffle(lw_entrances) + multiworld.random.shuffle(dw_entrances) + multiworld.random.shuffle(caves) # connect highest exit count caves first, prevent issue where we have 2 or 3 exits accross worlds left to fill caves.sort(key=lambda cave: 1 if isinstance(cave, str) else len(cave), reverse=True) for cave in caves: - target = lw_entrances if world.random.randint(0, 1) else dw_entrances + target = lw_entrances if multiworld.random.randint(0, 1) else dw_entrances if isinstance(cave, str): cave = (cave,) @@ -1536,37 +1539,37 @@ def connect_caves(world, lw_entrances, dw_entrances, caves, player): target = lw_entrances if target is dw_entrances else dw_entrances for exit in cave: - connect_two_way(world, target.pop(), exit, player) + connect_two_way(multiworld, target.pop(), exit, player) caves.clear() # emulating old behaviour of popping caves from the list in-place -def connect_doors(world, doors, targets, player): +def connect_doors(multiworld: MultiWorld, doors: list[str], targets: list[str], player: int): """This works inplace""" - world.random.shuffle(doors) - world.random.shuffle(targets) + multiworld.random.shuffle(doors) + multiworld.random.shuffle(targets) placing = min(len(doors), len(targets)) for door, target in zip(doors, targets): - connect_entrance(world, door, target, player) + connect_entrance(multiworld, door, target, player) doors[:] = doors[placing:] targets[:] = targets[placing:] -def skull_woods_shuffle(world, player): - connect_random(world, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'], +def skull_woods_shuffle(multiworld: MultiWorld, player: int): + connect_random(multiworld, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'], ['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)', 'Skull Woods Second Section (Drop)'], player) - connect_random(world, ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'], + connect_random(multiworld, ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'], ['Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'], player, True) -def simple_shuffle_dungeons(world, player): - skull_woods_shuffle(world, player) +def simple_shuffle_dungeons(multiworld: MultiWorld, player: int): + skull_woods_shuffle(multiworld, player) dungeon_entrances = ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace'] dungeon_exits = ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Palace of Darkness Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Swamp Palace Exit'] - if world.worlds[player].options.mode != 'inverted': - if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) + if multiworld.worlds[player].options.mode != 'inverted': + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) else: dungeon_entrances.append('Ganons Tower') dungeon_exits.append('Ganons Tower Exit') @@ -1575,17 +1578,17 @@ def simple_shuffle_dungeons(world, player): dungeon_exits.append('Inverted Agahnims Tower Exit') # shuffle up single entrance dungeons - connect_random(world, dungeon_entrances, dungeon_exits, player, True) + connect_random(multiworld, dungeon_entrances, dungeon_exits, player, True) # mix up 4 door dungeons multi_dungeons = ['Desert', 'Turtle Rock'] - if world.worlds[player].options.mode == 'open' or (world.worlds[player].options.mode == 'inverted' and world.shuffle_ganon): + if multiworld.worlds[player].options.mode == 'open' or (multiworld.worlds[player].options.mode == 'inverted' and multiworld.shuffle_ganon): multi_dungeons.append('Hyrule Castle') - world.random.shuffle(multi_dungeons) + multiworld.random.shuffle(multi_dungeons) dp_target = multi_dungeons[0] tr_target = multi_dungeons[1] - if world.worlds[player].options.mode not in ['open', 'inverted'] or (world.worlds[player].options.mode == 'inverted' and world.shuffle_ganon is False): + if multiworld.worlds[player].options.mode not in ['open', 'inverted'] or (multiworld.worlds[player].options.mode == 'inverted' and multiworld.shuffle_ganon is False): # place hyrule castle as intended hc_target = 'Hyrule Castle' else: @@ -1593,152 +1596,152 @@ def simple_shuffle_dungeons(world, player): # ToDo improve this? - if world.worlds[player].options.mode != 'inverted': + if multiworld.worlds[player].options.mode != 'inverted': if hc_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Agahnims Tower', 'Agahnims Tower Exit', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Agahnims Tower', 'Agahnims Tower Exit', player) elif hc_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Hyrule Castle Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Agahnims Tower Exit', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Agahnims Tower Exit', player) elif hc_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Hyrule Castle Exit (East)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Agahnims Tower Exit', player) + connect_two_way(multiworld, 'Turtle Rock', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Agahnims Tower Exit', player) if dp_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Agahnims Tower', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Agahnims Tower', 'Desert Palace Exit (North)', player) elif dp_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Desert Palace Exit (North)', player) elif dp_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Turtle Rock', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Desert Palace Exit (North)', player) if tr_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Turtle Rock Ledge Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Agahnims Tower', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Agahnims Tower', 'Turtle Rock Isolated Ledge Exit', player) elif tr_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Turtle Rock Ledge Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Exit', player) elif tr_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Isolated Ledge Exit', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Turtle Rock', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)', player) else: if hc_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) elif hc_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Hyrule Castle Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Inverted Ganons Tower Exit', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Inverted Ganons Tower Exit', player) elif hc_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Hyrule Castle Exit (South)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Inverted Ganons Tower Exit', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Hyrule Castle Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Hyrule Castle Exit (East)', player) + connect_two_way(multiworld, 'Turtle Rock', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Inverted Ganons Tower Exit', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Hyrule Castle Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Hyrule Castle Exit (East)', player) if dp_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Inverted Ganons Tower', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Desert Palace Exit (North)', player) elif dp_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Desert Palace Exit (North)', player) elif dp_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Desert Palace Exit (South)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Desert Palace Exit (East)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Desert Palace Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Desert Palace Exit (North)', player) + connect_two_way(multiworld, 'Turtle Rock', 'Desert Palace Exit (South)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Desert Palace Exit (East)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Desert Palace Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Desert Palace Exit (North)', player) if tr_target == 'Hyrule Castle': - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Turtle Rock Ledge Exit (East)', player) - connect_two_way(world, 'Hyrule Castle Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Inverted Ganons Tower', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (East)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Turtle Rock Isolated Ledge Exit', player) elif tr_target == 'Desert': - connect_two_way(world, 'Desert Palace Entrance (South)', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Desert Palace Entrance (North)', 'Turtle Rock Ledge Exit (East)', player) - connect_two_way(world, 'Desert Palace Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Desert Palace Entrance (South)', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (North)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Desert Palace Entrance (East)', 'Turtle Rock Isolated Ledge Exit', player) elif tr_target == 'Turtle Rock': - connect_two_way(world, 'Turtle Rock', 'Turtle Rock Exit (Front)', player) - connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Isolated Ledge Exit', player) - connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)', player) - connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)', player) + connect_two_way(multiworld, 'Turtle Rock', 'Turtle Rock Exit (Front)', player) + connect_two_way(multiworld, 'Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Isolated Ledge Exit', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)', player) + connect_two_way(multiworld, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)', player) -def crossed_shuffle_dungeons(world, player: int): +def crossed_shuffle_dungeons(multiworld: MultiWorld, player: int): lw_entrances = LW_Dungeon_Entrances.copy() dw_entrances = DW_Dungeon_Entrances.copy() for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - skull_woods_shuffle(world, player) + skull_woods_shuffle(multiworld, player) dungeon_exits = Dungeon_Exits_Base.copy() dungeon_entrances = lw_entrances+dw_entrances - if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Ganons Tower', 'Ganons Tower Exit', player) else: dungeon_entrances.append('Ganons Tower') dungeon_exits.append('Ganons Tower Exit') - if world.worlds[player].options.mode == 'standard': + if multiworld.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + connect_two_way(multiworld, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) dungeon_entrances.append('Hyrule Castle Entrance (South)') - connect_mandatory_exits(world, dungeon_entrances, dungeon_exits, + connect_mandatory_exits(multiworld, dungeon_entrances, dungeon_exits, LW_Dungeon_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit, player) - if world.worlds[player].options.mode == 'standard': - connect_caves(world, dungeon_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) + if multiworld.worlds[player].options.mode == 'standard': + connect_caves(multiworld, dungeon_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) - connect_caves(world, dungeon_entrances, [], dungeon_exits, player) + connect_caves(multiworld, dungeon_entrances, [], dungeon_exits, player) assert not dungeon_exits , "make sure all exits are accounted for" -def inverted_crossed_shuffle_dungeons(world, player: int): +def inverted_crossed_shuffle_dungeons(multiworld: MultiWorld, player: int): lw_entrances = Inverted_LW_Dungeon_Entrances.copy() dw_entrances = Inverted_DW_Dungeon_Entrances.copy() lw_dungeon_entrances_must_exit = list(Inverted_LW_Dungeon_Entrances_Must_Exit) for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(multiworld, exitname, regionname, player) - skull_woods_shuffle(world, player) + skull_woods_shuffle(multiworld, player) dungeon_exits = Inverted_Dungeon_Exits_Base.copy() dungeon_entrances = lw_entrances+dw_entrances # randomize which desert ledge door is a must-exit - if world.random.randint(0, 1): + if multiworld.random.randint(0, 1): lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') dungeon_entrances.append('Desert Palace Entrance (West)') else: @@ -1748,8 +1751,8 @@ def inverted_crossed_shuffle_dungeons(world, player: int): dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) dungeon_entrances.append('Hyrule Castle Entrance (South)') - if not world.shuffle_ganon: - connect_two_way(world, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) + if not multiworld.shuffle_ganon: + connect_two_way(multiworld, 'Inverted Ganons Tower', 'Inverted Ganons Tower Exit', player) hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] else: dungeon_entrances.append('Inverted Ganons Tower') @@ -1757,29 +1760,34 @@ def inverted_crossed_shuffle_dungeons(world, player: int): hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'] # shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit - world.random.shuffle(dungeon_entrances) + multiworld.random.shuffle(dungeon_entrances) aga_door = dungeon_entrances.pop() if aga_door in hc_ledge_entrances: hc_ledge_entrances.remove(aga_door) - world.random.shuffle(hc_ledge_entrances) + multiworld.random.shuffle(hc_ledge_entrances) hc_ledge_must_exit = hc_ledge_entrances.pop() dungeon_entrances.remove(hc_ledge_must_exit) lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit) - connect_two_way(world, aga_door, 'Inverted Agahnims Tower Exit', player) + connect_two_way(multiworld, aga_door, 'Inverted Agahnims Tower Exit', player) dungeon_exits.remove('Inverted Agahnims Tower Exit') - connect_mandatory_exits(world, dungeon_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) + connect_mandatory_exits(multiworld, dungeon_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) - connect_caves(world, dungeon_entrances, [], dungeon_exits, player) + connect_caves(multiworld, dungeon_entrances, [], dungeon_exits, player) assert not dungeon_exits, "make sure all exits are accounted for" -def unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits): + +def unbias_some_entrances(multiworld: MultiWorld, + Dungeon_Exits: list[list[str] | str], + Cave_Exits: list[str], + Old_Man_House: list[str], + Cave_Three_Exits: list[tuple[str, str, str]]): def shuffle_lists_in_list(ls): for i, item in enumerate(ls): if isinstance(item, list): - ls[i] = world.random.sample(item, len(item)) + ls[i] = multiworld.random.sample(item, len(item)) def tuplize_lists_in_list(ls): for i, item in enumerate(ls): @@ -1793,7 +1801,7 @@ def unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_ # paradox fixup if Cave_Three_Exits[1][0] == "Paradox Cave Exit (Bottom)": - i = world.random.randint(1, 2) + i = multiworld.random.randint(1, 2) Cave_Three_Exits[1][0] = Cave_Three_Exits[1][i] Cave_Three_Exits[1][i] = "Paradox Cave Exit (Bottom)" @@ -1822,18 +1830,18 @@ lookup = { } -def plando_connect(world, player: int): - if world.worlds[player].options.plando_connections: - for connection in world.worlds[player].options.plando_connections: +def plando_connect(multiworld: MultiWorld, player: int): + if multiworld.worlds[player].options.plando_connections: + for connection in multiworld.worlds[player].options.plando_connections: func = lookup[connection.direction] try: - func(world, connection.entrance, connection.exit, player) + func(multiworld, connection.entrance, connection.exit, player) except Exception as e: raise Exception(f"Could not connect using {connection}") from e - if world.worlds[player].options.mode != 'inverted': - mark_light_world_regions(world, player) + if multiworld.worlds[player].options.mode != 'inverted': + mark_light_world_regions(multiworld, player) else: - mark_dark_world_regions(world, player) + mark_dark_world_regions(multiworld, player) LW_Dungeon_Entrances = ['Desert Palace Entrance (South)', diff --git a/worlds/alttp/InvertedRegions.py b/worlds/alttp/InvertedRegions.py index 63a2d499e2..47e12d313f 100644 --- a/worlds/alttp/InvertedRegions.py +++ b/worlds/alttp/InvertedRegions.py @@ -1,15 +1,16 @@ import collections +from BaseClasses import MultiWorld from .Regions import create_lw_region, create_dw_region, create_cave_region, create_dungeon_region from .SubClasses import LTTPRegionType -def create_inverted_regions(world, player): +def create_inverted_regions(multiworld: MultiWorld, player: int): - world.regions += [ - create_dw_region(world, player, 'Menu', None, + multiworld.regions += [ + create_dw_region(multiworld, player, 'Menu', None, ['Links House S&Q', 'Dark Sanctuary S&Q', 'Old Man S&Q', 'Castle Ledge S&Q']), - create_lw_region(world, player, 'Light World', + create_lw_region(multiworld, player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest', 'Bombos Tablet'], ["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Kings Grave Outer Rocks', 'Dam', @@ -35,184 +36,184 @@ def create_inverted_regions(world, player): 'Hyrule Castle Entrance (South)', 'Secret Passage Outer Bushes', 'Bush Covered Lawn Outer Bushes', 'Potion Shop Outer Bushes', 'Graveyard Cave Outer Bushes', 'Bomb Hut Outer Bushes']), - create_lw_region(world, player, 'Bush Covered Lawn', None, + create_lw_region(multiworld, player, 'Bush Covered Lawn', None, ['Bush Covered House', 'Bush Covered Lawn Inner Bushes', 'Bush Covered Lawn Mirror Spot']), - create_lw_region(world, player, 'Bomb Hut Area', None, + create_lw_region(multiworld, player, 'Bomb Hut Area', None, ['Light World Bomb Hut', 'Bomb Hut Inner Bushes', 'Bomb Hut Mirror Spot']), - create_lw_region(world, player, 'Hyrule Castle Secret Entrance Area', None, + create_lw_region(multiworld, player, 'Hyrule Castle Secret Entrance Area', None, ['Hyrule Castle Secret Entrance Stairs', 'Secret Passage Inner Bushes']), - create_lw_region(world, player, 'Death Mountain Entrance', None, + create_lw_region(multiworld, player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop', 'Bumper Cave Entrance Mirror Spot']), - create_lw_region(world, player, 'Lake Hylia Central Island', None, + create_lw_region(multiworld, player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Mirror Spot']), - create_cave_region(world, player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top", + create_cave_region(multiworld, player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top", "Blind\'s Hideout - Left", "Blind\'s Hideout - Right", "Blind\'s Hideout - Far Left", "Blind\'s Hideout - Far Right"]), - create_lw_region(world, player, 'Northeast Light World', None, + create_lw_region(multiworld, player, 'Northeast Light World', None, ['Zoras River', 'Waterfall of Wishing Cave', 'Potion Shop Outer Rock', 'Catfish Mirror Spot', 'Northeast Light World Warp']), - create_lw_region(world, player, 'Waterfall of Wishing Cave', None, + create_lw_region(multiworld, player, 'Waterfall of Wishing Cave', None, ['Waterfall of Wishing', 'Northeast Light World Return']), - create_lw_region(world, player, 'Potion Shop Area', None, + create_lw_region(multiworld, player, 'Potion Shop Area', None, ['Potion Shop', 'Potion Shop Inner Bushes', 'Potion Shop Inner Rock', 'Potion Shop Mirror Spot', 'Potion Shop River Drop']), - create_lw_region(world, player, 'Graveyard Cave Area', None, + create_lw_region(multiworld, player, 'Graveyard Cave Area', None, ['Graveyard Cave', 'Graveyard Cave Inner Bushes', 'Graveyard Cave Mirror Spot']), - create_lw_region(world, player, 'River', None, ['Light World Pier', 'Potion Shop Pier']), - create_cave_region(world, player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', + create_lw_region(multiworld, player, 'River', None, ['Light World Pier', 'Potion Shop Pier']), + create_cave_region(multiworld, player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']), - create_lw_region(world, player, 'Zoras River', ['King Zora', 'Zora\'s Ledge']), - create_cave_region(world, player, 'Waterfall of Wishing', 'a cave with two chests', + create_lw_region(multiworld, player, 'Zoras River', ['King Zora', 'Zora\'s Ledge']), + create_cave_region(multiworld, player, 'Waterfall of Wishing', 'a cave with two chests', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']), - create_lw_region(world, player, 'Kings Grave Area', None, ['Kings Grave', 'Kings Grave Inner Rocks']), - create_cave_region(world, player, 'Kings Grave', 'a cave with a chest', ['King\'s Tomb']), - create_cave_region(world, player, 'North Fairy Cave', 'a drop\'s exit', None, ['North Fairy Cave Exit']), - create_cave_region(world, player, 'Dam', 'the dam', ['Floodgate', 'Floodgate Chest']), - create_cave_region(world, player, 'Inverted Links House', 'your house', ['Link\'s House'], + create_lw_region(multiworld, player, 'Kings Grave Area', None, ['Kings Grave', 'Kings Grave Inner Rocks']), + create_cave_region(multiworld, player, 'Kings Grave', 'a cave with a chest', ['King\'s Tomb']), + create_cave_region(multiworld, player, 'North Fairy Cave', 'a drop\'s exit', None, ['North Fairy Cave Exit']), + create_cave_region(multiworld, player, 'Dam', 'the dam', ['Floodgate', 'Floodgate Chest']), + create_cave_region(multiworld, player, 'Inverted Links House', 'your house', ['Link\'s House'], ['Inverted Links House Exit']), - create_cave_region(world, player, 'Chris Houlihan Room', 'I AM ERROR', None, ['Chris Houlihan Room Exit']), - create_cave_region(world, player, 'Tavern', 'the tavern', ['Kakariko Tavern']), - create_cave_region(world, player, 'Elder House', 'a connector', None, + create_cave_region(multiworld, player, 'Chris Houlihan Room', 'I AM ERROR', None, ['Chris Houlihan Room Exit']), + create_cave_region(multiworld, player, 'Tavern', 'the tavern', ['Kakariko Tavern']), + create_cave_region(multiworld, player, 'Elder House', 'a connector', None, ['Elder House Exit (East)', 'Elder House Exit (West)']), - create_cave_region(world, player, 'Snitch Lady (East)', 'a boring house'), - create_cave_region(world, player, 'Snitch Lady (West)', 'a boring house'), - create_cave_region(world, player, 'Bush Covered House', 'the grass man'), - create_cave_region(world, player, 'Tavern (Front)', 'the tavern'), - create_cave_region(world, player, 'Light World Bomb Hut', 'a restock room'), - create_cave_region(world, player, 'Kakariko Shop', 'a common shop'), - create_cave_region(world, player, 'Fortune Teller (Light)', 'a fortune teller'), - create_cave_region(world, player, 'Lake Hylia Fortune Teller', 'a fortune teller'), - create_cave_region(world, player, 'Lumberjack House', 'a boring house'), - create_cave_region(world, player, 'Bonk Fairy (Light)', 'a fairy fountain'), - create_cave_region(world, player, 'Bonk Fairy (Dark)', 'a fairy fountain'), - create_cave_region(world, player, 'Lake Hylia Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Swamp Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Desert Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Desert Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Death Mountain Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Chicken House', 'a house with a chest', ['Chicken House']), - create_cave_region(world, player, 'Aginahs Cave', 'a cave with a chest', ['Aginah\'s Cave']), - create_cave_region(world, player, 'Sahasrahlas Hut', 'Sahasrahla', + create_cave_region(multiworld, player, 'Snitch Lady (East)', 'a boring house'), + create_cave_region(multiworld, player, 'Snitch Lady (West)', 'a boring house'), + create_cave_region(multiworld, player, 'Bush Covered House', 'the grass man'), + create_cave_region(multiworld, player, 'Tavern (Front)', 'the tavern'), + create_cave_region(multiworld, player, 'Light World Bomb Hut', 'a restock room'), + create_cave_region(multiworld, player, 'Kakariko Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Fortune Teller (Light)', 'a fortune teller'), + create_cave_region(multiworld, player, 'Lake Hylia Fortune Teller', 'a fortune teller'), + create_cave_region(multiworld, player, 'Lumberjack House', 'a boring house'), + create_cave_region(multiworld, player, 'Bonk Fairy (Light)', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Bonk Fairy (Dark)', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Lake Hylia Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Swamp Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Desert Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Desert Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Death Mountain Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Chicken House', 'a house with a chest', ['Chicken House']), + create_cave_region(multiworld, player, 'Aginahs Cave', 'a cave with a chest', ['Aginah\'s Cave']), + create_cave_region(multiworld, player, 'Sahasrahlas Hut', 'Sahasrahla', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']), - create_cave_region(world, player, 'Kakariko Well (top)', 'a drop\'s exit', + create_cave_region(multiworld, player, 'Kakariko Well (top)', 'a drop\'s exit', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle', 'Kakariko Well - Right', 'Kakariko Well - Bottom'], ['Kakariko Well (top to bottom)']), - create_cave_region(world, player, 'Kakariko Well (bottom)', 'a drop\'s exit', None, ['Kakariko Well Exit']), - create_cave_region(world, player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']), - create_lw_region(world, player, 'Bat Cave Drop Ledge', None, ['Bat Cave Drop']), - create_cave_region(world, player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']), - create_cave_region(world, player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']), - create_cave_region(world, player, 'Sick Kids House', 'the sick kid', ['Sick Kid']), - create_lw_region(world, player, 'Hobo Bridge', ['Hobo']), - create_cave_region(world, player, 'Lost Woods Hideout (top)', 'a drop\'s exit', ['Lost Woods Hideout'], + create_cave_region(multiworld, player, 'Kakariko Well (bottom)', 'a drop\'s exit', None, ['Kakariko Well Exit']), + create_cave_region(multiworld, player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']), + create_lw_region(multiworld, player, 'Bat Cave Drop Ledge', None, ['Bat Cave Drop']), + create_cave_region(multiworld, player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']), + create_cave_region(multiworld, player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']), + create_cave_region(multiworld, player, 'Sick Kids House', 'the sick kid', ['Sick Kid']), + create_lw_region(multiworld, player, 'Hobo Bridge', ['Hobo']), + create_cave_region(multiworld, player, 'Lost Woods Hideout (top)', 'a drop\'s exit', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']), - create_cave_region(world, player, 'Lost Woods Hideout (bottom)', 'a drop\'s exit', None, + create_cave_region(multiworld, player, 'Lost Woods Hideout (bottom)', 'a drop\'s exit', None, ['Lost Woods Hideout Exit']), - create_cave_region(world, player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], + create_cave_region(multiworld, player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']), - create_cave_region(world, player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']), - create_cave_region(world, player, 'Cave 45', 'a cave with an item', ['Cave 45']), - create_cave_region(world, player, 'Graveyard Cave', 'a cave with an item', ['Graveyard Cave']), - create_cave_region(world, player, 'Checkerboard Cave', 'a cave with an item', ['Checkerboard Cave']), - create_cave_region(world, player, 'Long Fairy Cave', 'a fairy fountain'), - create_cave_region(world, player, 'Mini Moldorm Cave', 'a bounty of five items', + create_cave_region(multiworld, player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']), + create_cave_region(multiworld, player, 'Cave 45', 'a cave with an item', ['Cave 45']), + create_cave_region(multiworld, player, 'Graveyard Cave', 'a cave with an item', ['Graveyard Cave']), + create_cave_region(multiworld, player, 'Checkerboard Cave', 'a cave with an item', ['Checkerboard Cave']), + create_cave_region(multiworld, player, 'Long Fairy Cave', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Mini Moldorm Cave', 'a bounty of five items', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']), - create_cave_region(world, player, 'Ice Rod Cave', 'a cave with a chest', ['Ice Rod Cave']), - create_cave_region(world, player, 'Good Bee Cave', 'a cold bee'), - create_cave_region(world, player, '20 Rupee Cave', 'a cave with some cash'), - create_cave_region(world, player, 'Cave Shop (Lake Hylia)', 'a common shop'), - create_cave_region(world, player, 'Cave Shop (Dark Death Mountain)', 'a common shop'), - create_cave_region(world, player, 'Bonk Rock Cave', 'a cave with a chest', ['Bonk Rock Cave']), - create_cave_region(world, player, 'Library', 'the library', ['Library']), - create_cave_region(world, player, 'Kakariko Gamble Game', 'a game of chance'), - create_cave_region(world, player, 'Potion Shop', 'the potion shop', ['Potion Shop']), - create_lw_region(world, player, 'Lake Hylia Island', ['Lake Hylia Island']), - create_cave_region(world, player, 'Capacity Upgrade', 'the queen of fairies', ['Capacity Upgrade Shop']), - create_cave_region(world, player, 'Two Brothers House', 'a connector', None, + create_cave_region(multiworld, player, 'Ice Rod Cave', 'a cave with a chest', ['Ice Rod Cave']), + create_cave_region(multiworld, player, 'Good Bee Cave', 'a cold bee'), + create_cave_region(multiworld, player, '20 Rupee Cave', 'a cave with some cash'), + create_cave_region(multiworld, player, 'Cave Shop (Lake Hylia)', 'a common shop'), + create_cave_region(multiworld, player, 'Cave Shop (Dark Death Mountain)', 'a common shop'), + create_cave_region(multiworld, player, 'Bonk Rock Cave', 'a cave with a chest', ['Bonk Rock Cave']), + create_cave_region(multiworld, player, 'Library', 'the library', ['Library']), + create_cave_region(multiworld, player, 'Kakariko Gamble Game', 'a game of chance'), + create_cave_region(multiworld, player, 'Potion Shop', 'the potion shop', ['Potion Shop']), + create_lw_region(multiworld, player, 'Lake Hylia Island', ['Lake Hylia Island']), + create_cave_region(multiworld, player, 'Capacity Upgrade', 'the queen of fairies', ['Capacity Upgrade Shop']), + create_cave_region(multiworld, player, 'Two Brothers House', 'a connector', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']), - create_lw_region(world, player, 'Maze Race Ledge', ['Maze Race'], + create_lw_region(multiworld, player, 'Maze Race Ledge', ['Maze Race'], ['Two Brothers House (West)', 'Maze Race Mirror Spot']), - create_cave_region(world, player, '50 Rupee Cave', 'a cave with some cash'), - create_lw_region(world, player, 'Desert Ledge', ['Desert Ledge'], + create_cave_region(multiworld, player, '50 Rupee Cave', 'a cave with some cash'), + create_lw_region(multiworld, player, 'Desert Ledge', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)', 'Desert Ledge Drop']), - create_lw_region(world, player, 'Desert Palace Stairs', None, + create_lw_region(multiworld, player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)', 'Desert Palace Stairs Mirror Spot']), - create_lw_region(world, player, 'Desert Palace Lone Stairs', None, + create_lw_region(multiworld, player, 'Desert Palace Lone Stairs', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']), - create_lw_region(world, player, 'Desert Palace Entrance (North) Spot', None, + create_lw_region(multiworld, player, 'Desert Palace Entrance (North) Spot', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks', 'Desert Palace North Mirror Spot']), - create_dungeon_region(world, player, 'Desert Palace Main (Outer)', 'Desert Palace', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'], + create_dungeon_region(multiworld, player, 'Desert Palace Main (Outer)', 'Desert Palace', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'], ['Desert Palace Pots (Outer)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', 'Desert Palace East Wing']), - create_dungeon_region(world, player, 'Desert Palace Main (Inner)', 'Desert Palace', None, ['Desert Palace Exit (South)', 'Desert Palace Pots (Inner)']), - create_dungeon_region(world, player, 'Desert Palace East', 'Desert Palace', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']), - create_dungeon_region(world, player, 'Desert Palace North', 'Desert Palace', + create_dungeon_region(multiworld, player, 'Desert Palace Main (Inner)', 'Desert Palace', None, ['Desert Palace Exit (South)', 'Desert Palace Pots (Inner)']), + create_dungeon_region(multiworld, player, 'Desert Palace East', 'Desert Palace', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Desert Palace North', 'Desert Palace', ['Desert Palace - Desert Tiles 1 Pot Key', 'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key', 'Desert Palace - Boss', 'Desert Palace - Prize'], ['Desert Palace Exit (North)']), - create_dungeon_region(world, player, 'Eastern Palace', 'Eastern Palace', + create_dungeon_region(multiworld, player, 'Eastern Palace', 'Eastern Palace', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest', 'Eastern Palace - Dark Square Pot Key', 'Eastern Palace - Dark Eyegore Key Drop', 'Eastern Palace - Big Key Chest', 'Eastern Palace - Map Chest', 'Eastern Palace - Boss', 'Eastern Palace - Prize'], ['Eastern Palace Exit']), - create_lw_region(world, player, 'Master Sword Meadow', ['Master Sword Pedestal']), - create_cave_region(world, player, 'Lost Woods Gamble', 'a game of chance'), - create_lw_region(world, player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Hole']), - create_dungeon_region(world, player, 'Hyrule Castle', 'Hyrule Castle', + create_lw_region(multiworld, player, 'Master Sword Meadow', ['Master Sword Pedestal']), + create_cave_region(multiworld, player, 'Lost Woods Gamble', 'a game of chance'), + create_lw_region(multiworld, player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Hole']), + create_dungeon_region(multiworld, player, 'Hyrule Castle', 'Hyrule Castle', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Hyrule Castle - Map Guard Key Drop', 'Hyrule Castle - Boomerang Guard Key Drop', 'Hyrule Castle - Big Key Drop'], ['Hyrule Castle Exit (East)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (South)', 'Throne Room']), - create_dungeon_region(world, player, 'Sewer Drop', 'a drop\'s exit', None, ['Sewer Drop']), # This exists only to be referenced for access checks - create_dungeon_region(world, player, 'Sewers (Dark)', 'a drop\'s exit', ['Sewers - Dark Cross', 'Sewers - Key Rat Key Drop'], ['Sewers Door']), - create_dungeon_region(world, player, 'Sewers', 'a drop\'s exit', None, ['Sanctuary Push Door', 'Sewers Back Door', 'Sewers Secret Room']), - create_dungeon_region(world, player, 'Sewers Secret Room', 'a drop\'s exit', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', + create_dungeon_region(multiworld, player, 'Sewer Drop', 'a drop\'s exit', None, ['Sewer Drop']), # This exists only to be referenced for access checks + create_dungeon_region(multiworld, player, 'Sewers (Dark)', 'a drop\'s exit', ['Sewers - Dark Cross', 'Sewers - Key Rat Key Drop'], ['Sewers Door']), + create_dungeon_region(multiworld, player, 'Sewers', 'a drop\'s exit', None, ['Sanctuary Push Door', 'Sewers Back Door', 'Sewers Secret Room']), + create_dungeon_region(multiworld, player, 'Sewers Secret Room', 'a drop\'s exit', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', 'Sewers - Secret Room - Right']), - create_dungeon_region(world, player, 'Sanctuary', 'a drop\'s exit', ['Sanctuary'], ['Sanctuary Exit']), - create_dungeon_region(world, player, 'Inverted Agahnims Tower', 'Castle Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze', 'Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop'], ['Agahnim 1', 'Inverted Agahnims Tower Exit']), - create_dungeon_region(world, player, 'Agahnim 1', 'Castle Tower', ['Agahnim 1'], None), - create_cave_region(world, player, 'Old Man Cave', 'a connector', ['Old Man'], + create_dungeon_region(multiworld, player, 'Sanctuary', 'a drop\'s exit', ['Sanctuary'], ['Sanctuary Exit']), + create_dungeon_region(multiworld, player, 'Inverted Agahnims Tower', 'Castle Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze', 'Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop'], ['Agahnim 1', 'Inverted Agahnims Tower Exit']), + create_dungeon_region(multiworld, player, 'Agahnim 1', 'Castle Tower', ['Agahnim 1'], None), + create_cave_region(multiworld, player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']), - create_cave_region(world, player, 'Old Man House', 'a connector', None, + create_cave_region(multiworld, player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), - create_cave_region(world, player, 'Old Man House Back', 'a connector', None, + create_cave_region(multiworld, player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), - create_lw_region(world, player, 'Death Mountain', None, + create_lw_region(multiworld, player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Mirror Spot']), - create_cave_region(world, player, 'Death Mountain Return Cave', 'a connector', None, + create_cave_region(multiworld, player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), - create_lw_region(world, player, 'Death Mountain Return Ledge', None, + create_lw_region(multiworld, player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot']), - create_cave_region(world, player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), - create_cave_region(world, player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, ['Spectacle Rock Cave Exit']), - create_cave_region(world, player, 'Spectacle Rock Cave (Peak)', 'a connector', None, + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Peak)', 'a connector', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']), - create_lw_region(world, player, 'East Death Mountain (Bottom)', None, + create_lw_region(multiworld, player, 'East Death Mountain (Bottom)', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Mirror Spot (Bottom)', 'Hookshot Fairy', 'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']), - create_cave_region(world, player, 'Hookshot Fairy', 'fairies deep in a cave'), - create_cave_region(world, player, 'Paradox Cave Front', 'a connector', None, + create_cave_region(multiworld, player, 'Hookshot Fairy', 'fairies deep in a cave'), + create_cave_region(multiworld, player, 'Paradox Cave Front', 'a connector', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)', 'Light World Death Mountain Shop']), - create_cave_region(world, player, 'Paradox Cave Chest Area', 'a connector', ['Paradox Cave Lower - Far Left', + create_cave_region(multiworld, player, 'Paradox Cave Chest Area', 'a connector', ['Paradox Cave Lower - Far Left', 'Paradox Cave Lower - Left', 'Paradox Cave Lower - Right', 'Paradox Cave Lower - Far Right', @@ -220,273 +221,273 @@ def create_inverted_regions(world, player): 'Paradox Cave Upper - Left', 'Paradox Cave Upper - Right'], ['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']), - create_cave_region(world, player, 'Paradox Cave', 'a connector', None, + create_cave_region(multiworld, player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), - create_cave_region(world, player, 'Light World Death Mountain Shop', 'a common shop'), - create_lw_region(world, player, 'East Death Mountain (Top)', ['Floating Island'], + create_cave_region(multiworld, player, 'Light World Death Mountain Shop', 'a common shop'), + create_lw_region(multiworld, player, 'East Death Mountain (Top)', ['Floating Island'], ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'East Death Mountain Mirror Spot (Top)', 'Fairy Ascension Ledge Access', 'Mimic Cave Ledge Access', 'Floating Island Mirror Spot']), - create_lw_region(world, player, 'Spiral Cave Ledge', None, + create_lw_region(multiworld, player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (West)']), - create_lw_region(world, player, 'Mimic Cave Ledge', None, + create_lw_region(multiworld, player, 'Mimic Cave Ledge', None, ['Mimic Cave', 'Mimic Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (East)']), - create_cave_region(world, player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], + create_cave_region(multiworld, player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']), - create_cave_region(world, player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']), - create_lw_region(world, player, 'Fairy Ascension Plateau', None, + create_cave_region(multiworld, player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']), + create_lw_region(multiworld, player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']), - create_cave_region(world, player, 'Fairy Ascension Cave (Bottom)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Bottom)', 'a connector', None, ['Fairy Ascension Cave Climb', 'Fairy Ascension Cave Exit (Bottom)']), - create_cave_region(world, player, 'Fairy Ascension Cave (Drop)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Drop)', 'a connector', None, ['Fairy Ascension Cave Pots']), - create_cave_region(world, player, 'Fairy Ascension Cave (Top)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Top)', 'a connector', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Drop']), - create_lw_region(world, player, 'Fairy Ascension Ledge', None, + create_lw_region(multiworld, player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'Laser Bridge Mirror Spot']), - create_lw_region(world, player, 'Death Mountain (Top)', ['Ether Tablet', 'Spectacle Rock'], + create_lw_region(multiworld, player, 'Death Mountain (Top)', ['Ether Tablet', 'Spectacle Rock'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop', 'Death Mountain (Top) Mirror Spot']), - create_dw_region(world, player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], + create_dw_region(multiworld, player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)']), - create_dungeon_region(world, player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']), - create_dungeon_region(world, player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']), - create_dungeon_region(world, player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']), + create_dungeon_region(multiworld, player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']), + create_dungeon_region(multiworld, player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']), - create_dw_region(world, player, 'East Dark World', ['Pyramid'], + create_dw_region(multiworld, player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Northeast Dark World Broken Bridge Pass', 'East Dark World Teleporter', 'EDW Flute']), - create_dw_region(world, player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), - create_dw_region(world, player, 'Northeast Dark World', None, + create_dw_region(multiworld, player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), + create_dw_region(multiworld, player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'NEDW Flute', 'Dark Lake Hylia Teleporter', 'Catfish Entrance Rock']), - create_cave_region(world, player, 'Palace of Darkness Hint', 'a storyteller'), - create_cave_region(world, player, 'East Dark World Hint', 'a storyteller'), - create_dw_region(world, player, 'South Dark World', ['Stumpy', 'Digging Game'], + create_cave_region(multiworld, player, 'Palace of Darkness Hint', 'a storyteller'), + create_cave_region(multiworld, player, 'East Dark World Hint', 'a storyteller'), + create_dw_region(multiworld, player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'East Dark World Bridge', 'Inverted Links House', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop', 'South Dark World Teleporter', 'Post Aga Teleporter', 'SDW Flute']), - create_cave_region(world, player, 'Inverted Big Bomb Shop', 'the bomb shop'), - create_cave_region(world, player, 'Archery Game', 'a game of skill'), - create_dw_region(world, player, 'Dark Lake Hylia', None, + create_cave_region(multiworld, player, 'Inverted Big Bomb Shop', 'the bomb shop'), + create_cave_region(multiworld, player, 'Archery Game', 'a game of skill'), + create_dw_region(multiworld, player, 'Dark Lake Hylia', None, ['East Dark World Pier', 'Dark Lake Hylia Ledge Pier', 'Ice Palace Missing Wall']), - create_dw_region(world, player, 'Dark Lake Hylia Central Island', None, + create_dw_region(multiworld, player, 'Dark Lake Hylia Central Island', None, ['Dark Lake Hylia Shallows', 'Ice Palace', 'Dark Lake Hylia Central Island Teleporter']), - create_dw_region(world, player, 'Dark Lake Hylia Ledge', None, + create_dw_region(multiworld, player, 'Dark Lake Hylia Ledge', None, ['Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'DLHL Flute']), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Hint', 'a storyteller'), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'), - create_cave_region(world, player, 'Hype Cave', 'a bounty of five items', + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Hint', 'a storyteller'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'), + create_cave_region(multiworld, player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', 'Hype Cave - Bottom', 'Hype Cave - Generous Guy']), - create_dw_region(world, player, 'West Dark World', ['Frog', 'Flute Activation Spot'], + create_dw_region(multiworld, player, 'West Dark World', ['Frog', 'Flute Activation Spot'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock', 'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop', 'West Dark World Teleporter', 'WDW Flute']), - create_dw_region(world, player, 'Dark Grassy Lawn', None, + create_dw_region(multiworld, player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Village of Outcasts Shop', 'Dark Grassy Lawn Flute']), - create_dw_region(world, player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], + create_dw_region(multiworld, player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Dark World Hammer Peg Cave', 'Peg Area Rocks', 'Hammer Peg Area Flute']), - create_dw_region(world, player, 'Bumper Cave Entrance', None, + create_dw_region(multiworld, player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Drop']), - create_cave_region(world, player, 'Fortune Teller (Dark)', 'a fortune teller'), - create_cave_region(world, player, 'Village of Outcasts Shop', 'a common shop'), - create_cave_region(world, player, 'Dark Lake Hylia Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Lumberjack Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Potion Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), - create_cave_region(world, player, 'Pyramid Fairy', 'a cave with two chests', + create_cave_region(multiworld, player, 'Fortune Teller (Dark)', 'a fortune teller'), + create_cave_region(multiworld, player, 'Village of Outcasts Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Lumberjack Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Potion Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), + create_cave_region(multiworld, player, 'Pyramid Fairy', 'a cave with two chests', ['Pyramid Fairy - Left', 'Pyramid Fairy - Right']), - create_cave_region(world, player, 'Brewery', 'a house with a chest', ['Brewery']), - create_cave_region(world, player, 'C-Shaped House', 'a house with a chest', ['C-Shaped House']), - create_cave_region(world, player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), - create_cave_region(world, player, 'Red Shield Shop', 'the rare shop'), - create_cave_region(world, player, 'Inverted Dark Sanctuary', 'a storyteller', None, + create_cave_region(multiworld, player, 'Brewery', 'a house with a chest', ['Brewery']), + create_cave_region(multiworld, player, 'C-Shaped House', 'a house with a chest', ['C-Shaped House']), + create_cave_region(multiworld, player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), + create_cave_region(multiworld, player, 'Red Shield Shop', 'the rare shop'), + create_cave_region(multiworld, player, 'Inverted Dark Sanctuary', 'a storyteller', None, ['Inverted Dark Sanctuary Exit']), - create_cave_region(world, player, 'Bumper Cave', 'a connector', None, + create_cave_region(multiworld, player, 'Bumper Cave', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']), - create_dw_region(world, player, 'Skull Woods Forest', None, + create_dw_region(multiworld, player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']), - create_dw_region(world, player, 'Skull Woods Forest (West)', None, + create_dw_region(multiworld, player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']), - create_dw_region(world, player, 'Dark Desert', None, + create_dw_region(multiworld, player, 'Dark Desert', None, ['Misery Mire', 'Mire Shed', 'Dark Desert Hint', 'Dark Desert Fairy', 'DD Flute']), - create_dw_region(world, player, 'Dark Desert Ledge', None, ['Dark Desert Drop', 'Dark Desert Teleporter']), - create_cave_region(world, player, 'Mire Shed', 'a cave with two chests', + create_dw_region(multiworld, player, 'Dark Desert Ledge', None, ['Dark Desert Drop', 'Dark Desert Teleporter']), + create_cave_region(multiworld, player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']), - create_cave_region(world, player, 'Dark Desert Hint', 'a storyteller'), - create_dw_region(world, player, 'Dark Death Mountain', None, + create_cave_region(multiworld, player, 'Dark Desert Hint', 'a storyteller'), + create_dw_region(multiworld, player, 'Dark Death Mountain', None, ['Dark Death Mountain Drop (East)', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', 'Turtle Rock', 'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Turtle Rock Tail Drop', 'DDM Flute']), - create_dw_region(world, player, 'Dark Death Mountain Ledge', None, + create_dw_region(multiworld, player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)']), - create_dw_region(world, player, 'Turtle Rock (Top)', None, + create_dw_region(multiworld, player, 'Turtle Rock (Top)', None, ['Dark Death Mountain Teleporter (East)', 'Turtle Rock Drop']), - create_dw_region(world, player, 'Dark Death Mountain Isolated Ledge', None, + create_dw_region(multiworld, player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance']), - create_dw_region(world, player, 'Dark Death Mountain (East Bottom)', None, + create_dw_region(multiworld, player, 'Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East Bottom)', 'EDDM Flute']), - create_cave_region(world, player, 'Superbunny Cave (Top)', 'a connector', + create_cave_region(multiworld, player, 'Superbunny Cave (Top)', 'a connector', ['Superbunny Cave - Top', 'Superbunny Cave - Bottom'], ['Superbunny Cave Exit (Top)']), - create_cave_region(world, player, 'Superbunny Cave (Bottom)', 'a connector', None, + create_cave_region(multiworld, player, 'Superbunny Cave (Bottom)', 'a connector', None, ['Superbunny Cave Climb', 'Superbunny Cave Exit (Bottom)']), - create_cave_region(world, player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), - create_cave_region(world, player, 'Hookshot Cave', 'a connector', + create_cave_region(multiworld, player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), + create_cave_region(multiworld, player, 'Hookshot Cave', 'a connector', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], ['Hookshot Cave Exit (South)', 'Hookshot Cave Bomb Wall (South)']), - create_cave_region(world, player, 'Hookshot Cave (Upper)', 'a connector', None, ['Hookshot Cave Exit (North)', + create_cave_region(multiworld, player, 'Hookshot Cave (Upper)', 'a connector', None, ['Hookshot Cave Exit (North)', 'Hookshot Cave Bomb Wall (North)']), - create_dw_region(world, player, 'Death Mountain Floating Island (Dark World)', None, + create_dw_region(multiworld, player, 'Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance']), - create_cave_region(world, player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']), + create_cave_region(multiworld, player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']), - create_dungeon_region(world, player, 'Swamp Palace (Entrance)', 'Swamp Palace', None, ['Swamp Palace Moat', 'Swamp Palace Exit']), - create_dungeon_region(world, player, 'Swamp Palace (First Room)', 'Swamp Palace', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']), - create_dungeon_region(world, player, 'Swamp Palace (Starting Area)', 'Swamp Palace', ['Swamp Palace - Map Chest', 'Swamp Palace - Pot Row Pot Key', + create_dungeon_region(multiworld, player, 'Swamp Palace (Entrance)', 'Swamp Palace', None, ['Swamp Palace Moat', 'Swamp Palace Exit']), + create_dungeon_region(multiworld, player, 'Swamp Palace (First Room)', 'Swamp Palace', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']), + create_dungeon_region(multiworld, player, 'Swamp Palace (Starting Area)', 'Swamp Palace', ['Swamp Palace - Map Chest', 'Swamp Palace - Pot Row Pot Key', 'Swamp Palace - Trench 1 Pot Key'], ['Swamp Palace (Center)']), - create_dungeon_region(world, player, 'Swamp Palace (Center)', 'Swamp Palace', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest', 'Swamp Palace - Hookshot Pot Key', + create_dungeon_region(multiworld, player, 'Swamp Palace (Center)', 'Swamp Palace', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest', 'Swamp Palace - Hookshot Pot Key', 'Swamp Palace - Trench 2 Pot Key'], ['Swamp Palace (North)', 'Swamp Palace (West)']), - create_dungeon_region(world, player, 'Swamp Palace (West)', 'Swamp Palace', ['Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest']), - create_dungeon_region(world, player, 'Swamp Palace (North)', 'Swamp Palace', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right', + create_dungeon_region(multiworld, player, 'Swamp Palace (West)', 'Swamp Palace', ['Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest']), + create_dungeon_region(multiworld, player, 'Swamp Palace (North)', 'Swamp Palace', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right', 'Swamp Palace - Waterway Pot Key', 'Swamp Palace - Waterfall Room', 'Swamp Palace - Boss', 'Swamp Palace - Prize']), - create_dungeon_region(world, player, 'Thieves Town (Entrance)', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest', + create_dungeon_region(multiworld, player, 'Thieves Town (Entrance)', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest', 'Thieves\' Town - Map Chest', 'Thieves\' Town - Compass Chest', 'Thieves\' Town - Ambush Chest'], ['Thieves Town Big Key Door', 'Thieves Town Exit']), - create_dungeon_region(world, player, 'Thieves Town (Deep)', 'Thieves\' Town', ['Thieves\' Town - Attic', + create_dungeon_region(multiworld, player, 'Thieves Town (Deep)', 'Thieves\' Town', ['Thieves\' Town - Attic', 'Thieves\' Town - Big Chest', 'Thieves\' Town - Hallway Pot Key', 'Thieves\' Town - Spike Switch Pot Key', 'Thieves\' Town - Blind\'s Cell'], ['Blind Fight']), - create_dungeon_region(world, player, 'Blind Fight', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize']), - create_dungeon_region(world, player, 'Skull Woods First Section', 'Skull Woods', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']), - create_dungeon_region(world, player, 'Skull Woods First Section (Right)', 'Skull Woods', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), - create_dungeon_region(world, player, 'Skull Woods First Section (Left)', 'Skull Woods', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), - create_dungeon_region(world, player, 'Skull Woods First Section (Top)', 'Skull Woods', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), - create_dungeon_region(world, player, 'Skull Woods Second Section (Drop)', 'Skull Woods', None, ['Skull Woods Second Section (Drop)']), - create_dungeon_region(world, player, 'Skull Woods Second Section', 'Skull Woods', ['Skull Woods - Big Key Chest', 'Skull Woods - West Lobby Pot Key'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), - create_dungeon_region(world, player, 'Skull Woods Final Section (Entrance)', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), - create_dungeon_region(world, player, 'Skull Woods Final Section (Mothula)', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop', 'Skull Woods - Boss', 'Skull Woods - Prize']), - create_dungeon_region(world, player, 'Ice Palace (Entrance)', 'Ice Palace', ['Ice Palace - Jelly Key Drop', 'Ice Palace - Compass Chest'], ['Ice Palace (Second Section)', 'Ice Palace Exit']), - create_dungeon_region(world, player, 'Ice Palace (Second Section)', 'Ice Palace', ['Ice Palace - Conveyor Key Drop'], ['Ice Palace (Main)']), - create_dungeon_region(world, player, 'Ice Palace (Main)', 'Ice Palace', ['Ice Palace - Freezor Chest', + create_dungeon_region(multiworld, player, 'Blind Fight', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section', 'Skull Woods', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Right)', 'Skull Woods', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Left)', 'Skull Woods', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Top)', 'Skull Woods', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), + create_dungeon_region(multiworld, player, 'Skull Woods Second Section (Drop)', 'Skull Woods', None, ['Skull Woods Second Section (Drop)']), + create_dungeon_region(multiworld, player, 'Skull Woods Second Section', 'Skull Woods', ['Skull Woods - Big Key Chest', 'Skull Woods - West Lobby Pot Key'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), + create_dungeon_region(multiworld, player, 'Skull Woods Final Section (Entrance)', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), + create_dungeon_region(multiworld, player, 'Skull Woods Final Section (Mothula)', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop', 'Skull Woods - Boss', 'Skull Woods - Prize']), + create_dungeon_region(multiworld, player, 'Ice Palace (Entrance)', 'Ice Palace', ['Ice Palace - Jelly Key Drop', 'Ice Palace - Compass Chest'], ['Ice Palace (Second Section)', 'Ice Palace Exit']), + create_dungeon_region(multiworld, player, 'Ice Palace (Second Section)', 'Ice Palace', ['Ice Palace - Conveyor Key Drop'], ['Ice Palace (Main)']), + create_dungeon_region(multiworld, player, 'Ice Palace (Main)', 'Ice Palace', ['Ice Palace - Freezor Chest', 'Ice Palace - Many Pots Pot Key', 'Ice Palace - Big Chest', 'Ice Palace - Iced T Room'], ['Ice Palace (East)', 'Ice Palace (Kholdstare)']), - create_dungeon_region(world, player, 'Ice Palace (East)', 'Ice Palace', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']), - create_dungeon_region(world, player, 'Ice Palace (East Top)', 'Ice Palace', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest', 'Ice Palace - Hammer Block Key Drop']), - create_dungeon_region(world, player, 'Ice Palace (Kholdstare)', 'Ice Palace', ['Ice Palace - Boss', 'Ice Palace - Prize']), - create_dungeon_region(world, player, 'Misery Mire (Entrance)', 'Misery Mire', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']), - create_dungeon_region(world, player, 'Misery Mire (Main)', 'Misery Mire', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby', + create_dungeon_region(multiworld, player, 'Ice Palace (East)', 'Ice Palace', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']), + create_dungeon_region(multiworld, player, 'Ice Palace (East Top)', 'Ice Palace', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest', 'Ice Palace - Hammer Block Key Drop']), + create_dungeon_region(multiworld, player, 'Ice Palace (Kholdstare)', 'Ice Palace', ['Ice Palace - Boss', 'Ice Palace - Prize']), + create_dungeon_region(multiworld, player, 'Misery Mire (Entrance)', 'Misery Mire', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']), + create_dungeon_region(multiworld, player, 'Misery Mire (Main)', 'Misery Mire', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby', 'Misery Mire - Bridge Chest', 'Misery Mire - Spike Chest', 'Misery Mire - Spikes Pot Key', 'Misery Mire - Fishbone Pot Key', 'Misery Mire - Conveyor Crystal Key Drop'], ['Misery Mire (West)', 'Misery Mire Big Key Door']), - create_dungeon_region(world, player, 'Misery Mire (West)', 'Misery Mire', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']), - create_dungeon_region(world, player, 'Misery Mire (Final Area)', 'Misery Mire', None, ['Misery Mire (Vitreous)']), - create_dungeon_region(world, player, 'Misery Mire (Vitreous)', 'Misery Mire', ['Misery Mire - Boss', 'Misery Mire - Prize']), - create_dungeon_region(world, player, 'Turtle Rock (Entrance)', 'Turtle Rock', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']), - create_dungeon_region(world, player, 'Turtle Rock (First Section)', 'Turtle Rock', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', + create_dungeon_region(multiworld, player, 'Misery Mire (West)', 'Misery Mire', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Misery Mire (Final Area)', 'Misery Mire', None, ['Misery Mire (Vitreous)']), + create_dungeon_region(multiworld, player, 'Misery Mire (Vitreous)', 'Misery Mire', ['Misery Mire - Boss', 'Misery Mire - Prize']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Entrance)', 'Turtle Rock', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (First Section)', 'Turtle Rock', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right'], ['Turtle Rock Entrance to Pokey Room', 'Turtle Rock Entrance Gap Reverse']), - create_dungeon_region(world, player, 'Turtle Rock (Pokey Room)', 'Turtle Rock', ['Turtle Rock - Pokey 1 Key Drop'], ['Turtle Rock (Pokey Room) (North)', 'Turtle Rock (Pokey Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock', ['Turtle Rock - Chain Chomps'], + create_dungeon_region(multiworld, player, 'Turtle Rock (Pokey Room)', 'Turtle Rock', ['Turtle Rock - Pokey 1 Key Drop'], ['Turtle Rock (Pokey Room) (North)', 'Turtle Rock (Pokey Room) (South)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Second Section)', 'Turtle Rock', + create_dungeon_region(multiworld, player, 'Turtle Rock (Second Section)', 'Turtle Rock', ['Turtle Rock - Big Key Chest', 'Turtle Rock - Pokey 2 Key Drop'], ['Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door', 'Turtle Rock Second Section Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Second Section Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Second Section from Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Big Chest)', 'Turtle Rock', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']), - create_dungeon_region(world, player, 'Turtle Rock (Crystaroller Room)', 'Turtle Rock', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']), - create_dungeon_region(world, player, 'Turtle Rock (Dark Room)', 'Turtle Rock', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Eye Bridge Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Isolated Ledge Exit', 'Turtle Rock Eye Bridge from Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Eye Bridge)', 'Turtle Rock', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', + create_dungeon_region(multiworld, player, 'Turtle Rock (Second Section Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Second Section from Bomb Wall']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Big Chest)', 'Turtle Rock', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Crystaroller Room)', 'Turtle Rock', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Dark Room)', 'Turtle Rock', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Eye Bridge Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Isolated Ledge Exit', 'Turtle Rock Eye Bridge from Bomb Wall']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Eye Bridge)', 'Turtle Rock', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', 'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'], ['Turtle Rock Dark Room (South)', 'Turtle Rock (Trinexx)', 'Turtle Rock Eye Bridge Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Trinexx)', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize']), - create_dungeon_region(world, player, 'Palace of Darkness (Entrance)', 'Palace of Darkness', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']), - create_dungeon_region(world, player, 'Palace of Darkness (Center)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'], + create_dungeon_region(multiworld, player, 'Turtle Rock (Trinexx)', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Entrance)', 'Palace of Darkness', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Center)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'], ['Palace of Darkness Big Key Chest Staircase', 'Palace of Darkness (North)', 'Palace of Darkness Big Key Door']), - create_dungeon_region(world, player, 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness', ['Palace of Darkness - Big Key Chest']), - create_dungeon_region(world, player, 'Palace of Darkness (Bonk Section)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']), - create_dungeon_region(world, player, 'Palace of Darkness (North)', 'Palace of Darkness', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], + create_dungeon_region(multiworld, player, 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness', ['Palace of Darkness - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Bonk Section)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (North)', 'Palace of Darkness', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], ['Palace of Darkness Spike Statue Room Door', 'Palace of Darkness Maze Door']), - create_dungeon_region(world, player, 'Palace of Darkness (Maze)', 'Palace of Darkness', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']), - create_dungeon_region(world, player, 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway']), - create_dungeon_region(world, player, 'Palace of Darkness (Final Section)', 'Palace of Darkness', ['Palace of Darkness - Boss', 'Palace of Darkness - Prize']), - create_dungeon_region(world, player, 'Inverted Ganons Tower (Entrance)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Palace of Darkness (Maze)', 'Palace of Darkness', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Final Section)', 'Palace of Darkness', ['Palace of Darkness - Boss', 'Palace of Darkness - Prize']), + create_dungeon_region(multiworld, player, 'Inverted Ganons Tower (Entrance)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right', 'Ganons Tower - Conveyor Cross Pot Key'], ['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Inverted Ganons Tower Exit']), - create_dungeon_region(world, player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], + create_dungeon_region(multiworld, player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']), - create_dungeon_region(world, player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right', 'Ganons Tower - Conveyor Star Pits Pot Key'], ['Ganons Tower (Bottom) (East)']), - create_dungeon_region(world, player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right', 'Ganons Tower - Double Switch Pot Key'], ['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']), - create_dungeon_region(world, player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']), - create_dungeon_region(world, player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']), - create_dungeon_region(world, player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', 'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'], ['Ganons Tower (Bottom) (West)']), - create_dungeon_region(world, player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left', 'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']), - create_dungeon_region(world, player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']), - create_dungeon_region(world, player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', + create_dungeon_region(multiworld, player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Mini Helmasaur Key Drop'], ['Ganons Tower Moldorm Door']), - create_dungeon_region(world, player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']), - create_dungeon_region(world, player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None), - create_cave_region(world, player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), - create_cave_region(world, player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), - create_dw_region(world, player, 'Pyramid Ledge', None, ['Pyramid Drop']), # houlihan room exits here in inverted + create_dungeon_region(multiworld, player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None), + create_cave_region(multiworld, player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), + create_cave_region(multiworld, player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), + create_dw_region(multiworld, player, 'Pyramid Ledge', None, ['Pyramid Drop']), # houlihan room exits here in inverted # to simplify flute connections - create_cave_region(world, player, 'The Sky', 'A Dark Sky', None, + create_cave_region(multiworld, player, 'The Sky', 'A Dark Sky', None, ['DDM Landing', 'NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing']), - create_lw_region(world, player, 'Desert Northern Cliffs'), - create_lw_region(world, player, 'Death Mountain Bunny Descent Area') + create_lw_region(multiworld, player, 'Desert Northern Cliffs'), + create_lw_region(multiworld, player, 'Death Mountain Bunny Descent Area') ] -def mark_dark_world_regions(world, player): +def mark_dark_world_regions(multiworld: MultiWorld, player: int): # cross world caves may have some sections marked as both in_light_world, and in_dark_work. # That is ok. the bunny logic will check for this case and incorporate special rules. - queue = collections.deque(region for region in world.get_regions(player) if region.type == LTTPRegionType.DarkWorld) + queue = collections.deque(region for region in multiworld.get_regions(player) if region.type == LTTPRegionType.DarkWorld) seen = set(queue) while queue: current = queue.popleft() @@ -499,7 +500,7 @@ def mark_dark_world_regions(world, player): seen.add(exit.connected_region) queue.append(exit.connected_region) - queue = collections.deque(region for region in world.get_regions(player) if region.type == LTTPRegionType.LightWorld) + queue = collections.deque(region for region in multiworld.get_regions(player) if region.type == LTTPRegionType.LightWorld) seen = set(queue) while queue: current = queue.popleft() diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 6b0968f6e5..c7dc7a6948 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -1,8 +1,9 @@ from collections import namedtuple import logging -from BaseClasses import ItemClassification +from BaseClasses import ItemClassification, MultiWorld from Options import OptionError +from typing import TYPE_CHECKING from .SubClasses import ALttPLocation, LTTPRegion, LTTPRegionType from .Shops import TakeAny, total_shop_slots, set_up_shops, shop_table_by_location, ShopType @@ -14,6 +15,9 @@ from .Options import small_key_shuffle, compass_shuffle, big_key_shuffle, map_sh from .StateHelpers import has_triforce_pieces, has_melee_weapon from .Regions import key_drop_data +if TYPE_CHECKING: + from . import ALTTPWorld + # This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space. # Some basic items that various modes require are placed here, including pendants and crystals. Medallion requirements for the two relevant entrances are also decided. @@ -222,7 +226,7 @@ items_reduction_table = ( ) -def generate_itempool(world): +def generate_itempool(world: "ALTTPWorld"): player: int = world.player multiworld = world.multiworld @@ -531,7 +535,7 @@ take_any_locations_inverted.sort() take_any_locations.sort() -def set_up_take_anys(multiworld, world, player): +def set_up_take_anys(multiworld: MultiWorld, world: "ALTTPWorld", player: int): # these are references, do not modify these lists in-place if world.options.mode == 'inverted': take_any_locs = take_any_locations_inverted @@ -585,15 +589,15 @@ def set_up_take_anys(multiworld, world, player): location.place_locked_item(item_factory("Boss Heart Container", world)) -def get_pool_core(world, player: int): - shuffle = world.worlds[player].options.entrance_shuffle.current_key - difficulty = world.worlds[player].options.item_pool.current_key - timer = world.worlds[player].options.timer.current_key - goal = world.worlds[player].options.goal.current_key - mode = world.worlds[player].options.mode.current_key - swordless = world.worlds[player].options.swordless - retro_bow = world.worlds[player].options.retro_bow - logic = world.worlds[player].options.glitches_required +def get_pool_core(multiworld: MultiWorld, player: int): + shuffle = multiworld.worlds[player].options.entrance_shuffle.current_key + difficulty = multiworld.worlds[player].options.item_pool.current_key + timer = multiworld.worlds[player].options.timer.current_key + goal = multiworld.worlds[player].options.goal.current_key + mode = multiworld.worlds[player].options.mode.current_key + swordless = multiworld.worlds[player].options.swordless + retro_bow = multiworld.worlds[player].options.retro_bow + logic = multiworld.worlds[player].options.glitches_required pool = [] placed_items = {} @@ -610,13 +614,13 @@ def get_pool_core(world, player: int): placed_items[loc] = item # provide boots to major glitch dependent seeds - if logic.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.worlds[player].options.glitch_boots: + if logic.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and multiworld.worlds[player].options.glitch_boots: precollected_items.append('Pegasus Boots') pool.remove('Pegasus Boots') pool.append('Rupees (20)') - want_progressives = world.worlds[player].options.progressive.want_progressives + want_progressives = multiworld.worlds[player].options.progressive.want_progressives - if want_progressives(world.random): + if want_progressives(multiworld.random): pool.extend(diff.progressiveglove) else: pool.extend(diff.basicglove) @@ -640,27 +644,27 @@ def get_pool_core(world, player: int): thisbottle = None for _ in range(diff.bottle_count): if not diff.same_bottle or not thisbottle: - thisbottle = world.random.choice(diff.bottles) + thisbottle = multiworld.random.choice(diff.bottles) pool.append(thisbottle) - if want_progressives(world.random): + if want_progressives(multiworld.random): pool.extend(diff.progressiveshield) else: pool.extend(diff.basicshield) - if want_progressives(world.random): + if want_progressives(multiworld.random): pool.extend(diff.progressivearmor) else: pool.extend(diff.basicarmor) - if want_progressives(world.random): + if want_progressives(multiworld.random): pool.extend(diff.progressivemagic) else: pool.extend(diff.basicmagic) - if want_progressives(world.random): + if want_progressives(multiworld.random): pool.extend(diff.progressivebow) - world.worlds[player].has_progressive_bows = True + multiworld.worlds[player].has_progressive_bows = True elif (swordless or logic == 'no_glitches'): swordless_bows = ['Bow', 'Silver Bow'] if difficulty == "easy": @@ -672,7 +676,7 @@ def get_pool_core(world, player: int): if swordless: pool.extend(diff.swordless) else: - progressive_swords = want_progressives(world.random) + progressive_swords = want_progressives(multiworld.random) pool.extend(diff.progressivesword if progressive_swords else diff.basicsword) extraitems = total_items_to_place - len(pool) - len(placed_items) @@ -688,29 +692,29 @@ def get_pool_core(world, player: int): additional_pieces_to_place = 0 if 'triforce_hunt' in goal: - if world.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_extra: - treasure_hunt_total = (world.worlds[player].options.triforce_pieces_required.value - + world.worlds[player].options.triforce_pieces_extra.value) - elif world.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_percentage: - percentage = float(world.worlds[player].options.triforce_pieces_percentage.value) / 100 - treasure_hunt_total = int(round(world.worlds[player].options.triforce_pieces_required.value * percentage, 0)) + if multiworld.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_extra: + treasure_hunt_total = (multiworld.worlds[player].options.triforce_pieces_required.value + + multiworld.worlds[player].options.triforce_pieces_extra.value) + elif multiworld.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_percentage: + percentage = float(multiworld.worlds[player].options.triforce_pieces_percentage.value) / 100 + treasure_hunt_total = int(round(multiworld.worlds[player].options.triforce_pieces_required.value * percentage, 0)) else: # available - treasure_hunt_total = world.worlds[player].options.triforce_pieces_available.value + treasure_hunt_total = multiworld.worlds[player].options.triforce_pieces_available.value - triforce_pieces = min(90, max(treasure_hunt_total, world.worlds[player].options.triforce_pieces_required.value)) + triforce_pieces = min(90, max(treasure_hunt_total, multiworld.worlds[player].options.triforce_pieces_required.value)) pieces_in_core = min(extraitems, triforce_pieces) additional_pieces_to_place = triforce_pieces - pieces_in_core pool.extend(["Triforce Piece"] * pieces_in_core) extraitems -= pieces_in_core - treasure_hunt_required = world.worlds[player].options.triforce_pieces_required.value + treasure_hunt_required = multiworld.worlds[player].options.triforce_pieces_required.value for extra in diff.extras: if extraitems >= len(extra): pool.extend(extra) extraitems -= len(extra) elif extraitems > 0: - pool.extend(world.random.sample(extra, extraitems)) + pool.extend(multiworld.random.sample(extra, extraitems)) break else: break @@ -729,25 +733,25 @@ def get_pool_core(world, player: int): else: break - if world.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: + if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: pool.extend(diff.universal_keys) if mode == 'standard': - if world.worlds[player].options.key_drop_shuffle: + if multiworld.worlds[player].options.key_drop_shuffle: key_locations = ['Secret Passage', 'Hyrule Castle - Map Guard Key Drop'] - key_location = world.random.choice(key_locations) + key_location = multiworld.random.choice(key_locations) key_locations.remove(key_location) place_item(key_location, "Small Key (Universal)") key_locations += ['Hyrule Castle - Boomerang Guard Key Drop', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest'] - key_location = world.random.choice(key_locations) + key_location = multiworld.random.choice(key_locations) key_locations.remove(key_location) place_item(key_location, "Small Key (Universal)") key_locations += ['Hyrule Castle - Big Key Drop', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'] - key_location = world.random.choice(key_locations) + key_location = multiworld.random.choice(key_locations) key_locations.remove(key_location) place_item(key_location, "Small Key (Universal)") key_locations += ['Sewers - Key Rat Key Drop'] - key_location = world.random.choice(key_locations) + key_location = multiworld.random.choice(key_locations) place_item(key_location, "Small Key (Universal)") pool = pool[:-3] diff --git a/worlds/alttp/Items.py b/worlds/alttp/Items.py index cbe6e99642..1c173c619e 100644 --- a/worlds/alttp/Items.py +++ b/worlds/alttp/Items.py @@ -1,24 +1,24 @@ import typing -from BaseClasses import ItemClassification as IC +from BaseClasses import MultiWorld, ItemClassification as IC from worlds.AutoWorld import World -def GetBeemizerItem(world, player: int, item): +def GetBeemizerItem(multiworld: MultiWorld, player: int, item): item_name = item if isinstance(item, str) else item.name - if item_name not in trap_replaceable or player in world.groups: + if item_name not in trap_replaceable or player in multiworld.groups: return item # first roll - replaceable item should be replaced, within beemizer_total_chance - if not world.worlds[player].options.beemizer_total_chance or world.random.random() > (world.worlds[player].options.beemizer_total_chance / 100): + if not multiworld.worlds[player].options.beemizer_total_chance or multiworld.random.random() > (multiworld.worlds[player].options.beemizer_total_chance / 100): return item # second roll - bee replacement should be trap, within beemizer_trap_chance - if not world.worlds[player].options.beemizer_trap_chance or world.random.random() > (world.worlds[player].options.beemizer_trap_chance / 100): - return "Bee" if isinstance(item, str) else world.create_item("Bee", player) + if not multiworld.worlds[player].options.beemizer_trap_chance or multiworld.random.random() > (multiworld.worlds[player].options.beemizer_trap_chance / 100): + return "Bee" if isinstance(item, str) else multiworld.create_item("Bee", player) else: - return "Bee Trap" if isinstance(item, str) else world.create_item("Bee Trap", player) + return "Bee Trap" if isinstance(item, str) else multiworld.create_item("Bee Trap", player) def item_factory(items: typing.Union[str, typing.Iterable[str]], world: World): diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 519241d7f4..53bdbd6cba 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -154,13 +154,13 @@ class OpenPyramid(Choice): alias_true = option_open alias_false = option_closed - def to_bool(self, world: MultiWorld, player: int) -> bool: + def to_bool(self, multiworld: MultiWorld, player: int) -> bool: if self.value == self.option_goal: - return world.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} + return multiworld.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} elif self.value == self.option_auto: - return world.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} \ - and (world.worlds[player].options.entrance_shuffle.current_key in {'vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'} or not - world.shuffle_ganon) + return multiworld.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} \ + and (multiworld.worlds[player].options.entrance_shuffle.current_key in {'vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'} or not + multiworld.shuffle_ganon) elif self.value == self.option_open: return True else: diff --git a/worlds/alttp/OverworldGlitchRules.py b/worlds/alttp/OverworldGlitchRules.py index aeff9cb88e..a243569cca 100644 --- a/worlds/alttp/OverworldGlitchRules.py +++ b/worlds/alttp/OverworldGlitchRules.py @@ -2,6 +2,7 @@ Helper functions to deliver entrance/exit/region sets to OWG rules. """ +from BaseClasses import MultiWorld from .StateHelpers import can_lift_heavy_rocks, can_boots_clip_lw, can_boots_clip_dw, can_get_glitched_speed_dw @@ -200,7 +201,7 @@ def get_mirror_offset_spots_dw(): yield ('Dark Death Mountain Offset Mirror', 'Dark Death Mountain (West Bottom)', 'East Dark World') -def get_mirror_offset_spots_lw(player): +def get_mirror_offset_spots_lw(player: int): """ Mirror shenanigans placing a mirror portal with a broken camera """ @@ -218,54 +219,54 @@ def get_invalid_bunny_revival_dungeons(): yield 'Sanctuary' -def overworld_glitch_connections(world, player): +def overworld_glitch_connections(multiworld: MultiWorld, player: int): # Boots-accessible locations. - create_owg_connections(player, world, get_boots_clip_exits_lw(world.worlds[player].options.mode == 'inverted')) - create_owg_connections(player, world, get_boots_clip_exits_dw(world.worlds[player].options.mode == 'inverted', player)) + create_owg_connections(player, multiworld, get_boots_clip_exits_lw(multiworld.worlds[player].options.mode == 'inverted')) + create_owg_connections(player, multiworld, get_boots_clip_exits_dw(multiworld.worlds[player].options.mode == 'inverted', player)) # Glitched speed drops. - create_owg_connections(player, world, get_glitched_speed_drops_dw(world.worlds[player].options.mode == 'inverted')) + create_owg_connections(player, multiworld, get_glitched_speed_drops_dw(multiworld.worlds[player].options.mode == 'inverted')) # Mirror clip spots. - if world.worlds[player].options.mode != 'inverted': - create_owg_connections(player, world, get_mirror_clip_spots_dw()) - create_owg_connections(player, world, get_mirror_offset_spots_dw()) + if multiworld.worlds[player].options.mode != 'inverted': + create_owg_connections(player, multiworld, get_mirror_clip_spots_dw()) + create_owg_connections(player, multiworld, get_mirror_offset_spots_dw()) else: - create_owg_connections(player, world, get_mirror_offset_spots_lw(player)) + create_owg_connections(player, multiworld, get_mirror_offset_spots_lw(player)) -def overworld_glitches_rules(world, player): +def overworld_glitches_rules(multiworld: MultiWorld, player: int): # Boots-accessible locations. - set_owg_connection_rules(player, world, get_boots_clip_exits_lw(world.worlds[player].options.mode == 'inverted'), lambda state: can_boots_clip_lw(state, player)) - set_owg_connection_rules(player, world, get_boots_clip_exits_dw(world.worlds[player].options.mode == 'inverted', player), lambda state: can_boots_clip_dw(state, player)) + set_owg_connection_rules(player, multiworld, get_boots_clip_exits_lw(multiworld.worlds[player].options.mode == 'inverted'), lambda state: can_boots_clip_lw(state, player)) + set_owg_connection_rules(player, multiworld, get_boots_clip_exits_dw(multiworld.worlds[player].options.mode == 'inverted', player), lambda state: can_boots_clip_dw(state, player)) # Glitched speed drops. - set_owg_connection_rules(player, world, get_glitched_speed_drops_dw(world.worlds[player].options.mode == 'inverted'), lambda state: can_get_glitched_speed_dw(state, player)) + set_owg_connection_rules(player, multiworld, get_glitched_speed_drops_dw(multiworld.worlds[player].options.mode == 'inverted'), lambda state: can_get_glitched_speed_dw(state, player)) # Dark Death Mountain Ledge Clip Spot also accessible with mirror. - if world.worlds[player].options.mode != 'inverted': - add_alternate_rule(world.get_entrance('Dark Death Mountain Ledge Clip Spot', player), lambda state: state.has('Magic Mirror', player)) + if multiworld.worlds[player].options.mode != 'inverted': + add_alternate_rule(multiworld.get_entrance('Dark Death Mountain Ledge Clip Spot', player), lambda state: state.has('Magic Mirror', player)) # Mirror clip spots. - if world.worlds[player].options.mode != 'inverted': - set_owg_connection_rules(player, world, get_mirror_clip_spots_dw(), lambda state: state.has('Magic Mirror', player)) - set_owg_connection_rules(player, world, get_mirror_offset_spots_dw(), lambda state: state.has('Magic Mirror', player) and can_boots_clip_lw(state, player)) + if multiworld.worlds[player].options.mode != 'inverted': + set_owg_connection_rules(player, multiworld, get_mirror_clip_spots_dw(), lambda state: state.has('Magic Mirror', player)) + set_owg_connection_rules(player, multiworld, get_mirror_offset_spots_dw(), lambda state: state.has('Magic Mirror', player) and can_boots_clip_lw(state, player)) else: - set_owg_connection_rules(player, world, get_mirror_offset_spots_lw(player), lambda state: state.has('Magic Mirror', player) and can_boots_clip_dw(state, player)) + set_owg_connection_rules(player, multiworld, get_mirror_offset_spots_lw(player), lambda state: state.has('Magic Mirror', player) and can_boots_clip_dw(state, player)) # Regions that require the boots and some other stuff. - if world.worlds[player].options.mode != 'inverted': - world.get_entrance('Turtle Rock Teleporter', player).access_rule = lambda state: (can_boots_clip_lw(state, player) or can_lift_heavy_rocks(state, player)) and state.has('Hammer', player) - add_alternate_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Moon Pearl', player) or state.has('Pegasus Boots', player)) + if multiworld.worlds[player].options.mode != 'inverted': + multiworld.get_entrance('Turtle Rock Teleporter', player).access_rule = lambda state: (can_boots_clip_lw(state, player) or can_lift_heavy_rocks(state, player)) and state.has('Hammer', player) + add_alternate_rule(multiworld.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Moon Pearl', player) or state.has('Pegasus Boots', player)) else: - add_alternate_rule(world.get_entrance('Waterfall of Wishing Cave', player), lambda state: state.has('Moon Pearl', player)) + add_alternate_rule(multiworld.get_entrance('Waterfall of Wishing Cave', player), lambda state: state.has('Moon Pearl', player)) - world.get_entrance('Dark Desert Teleporter', player).access_rule = lambda state: (state.has('Flute', player) or state.has('Pegasus Boots', player)) and can_lift_heavy_rocks(state, player) - add_alternate_rule(world.get_entrance('Catfish Exit Rock', player), lambda state: can_boots_clip_dw(state, player)) - add_alternate_rule(world.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: can_boots_clip_dw(state, player)) + multiworld.get_entrance('Dark Desert Teleporter', player).access_rule = lambda state: (state.has('Flute', player) or state.has('Pegasus Boots', player)) and can_lift_heavy_rocks(state, player) + add_alternate_rule(multiworld.get_entrance('Catfish Exit Rock', player), lambda state: can_boots_clip_dw(state, player)) + add_alternate_rule(multiworld.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: can_boots_clip_dw(state, player)) # Zora's Ledge via waterwalk setup. - add_alternate_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Pegasus Boots', player)) + add_alternate_rule(multiworld.get_location('Zora\'s Ledge', player), lambda state: state.has('Pegasus Boots', player)) def add_alternate_rule(entrance, rule): @@ -273,22 +274,22 @@ def add_alternate_rule(entrance, rule): entrance.access_rule = lambda state: old_rule(state) or rule(state) -def create_no_logic_connections(player, world, connections): +def create_no_logic_connections(player: int, multiworld: MultiWorld, connections): for entrance, parent_region, target_region, *rule_override in connections: - parent = world.get_region(parent_region, player) - target = world.get_region(target_region, player) + parent = multiworld.get_region(parent_region, player) + target = multiworld.get_region(target_region, player) parent.connect(target, entrance) -def create_owg_connections(player, world, connections): +def create_owg_connections(player: int, multiworld: MultiWorld, connections): for entrance, parent_region, target_region, *rule_override in connections: - parent = world.get_region(parent_region, player) - target = world.get_region(target_region, player) + parent = multiworld.get_region(parent_region, player) + target = multiworld.get_region(target_region, player) parent.connect(target, entrance) -def set_owg_connection_rules(player, world, connections, default_rule): +def set_owg_connection_rules(player: int, multiworld: MultiWorld, connections, default_rule): for entrance, _, _, *rule_override in connections: - connection = world.get_entrance(entrance, player) + connection = multiworld.get_entrance(entrance, player) rule = rule_override[0] if len(rule_override) > 0 else default_rule connection.access_rule = rule diff --git a/worlds/alttp/Regions.py b/worlds/alttp/Regions.py index c2af795637..d3789f91ba 100644 --- a/worlds/alttp/Regions.py +++ b/worlds/alttp/Regions.py @@ -9,11 +9,11 @@ def is_main_entrance(entrance: LTTPEntrance) -> bool: return entrance.parent_region.type in {LTTPRegionType.DarkWorld, LTTPRegionType.LightWorld} if entrance.parent_region.type else True -def create_regions(world, player): +def create_regions(multiworld: MultiWorld, player: int): - world.regions += [ - create_lw_region(world, player, 'Menu', None, ['Links House S&Q', 'Sanctuary S&Q', 'Old Man S&Q']), - create_lw_region(world, player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', + multiworld.regions += [ + create_lw_region(multiworld, player, 'Menu', None, ['Links House S&Q', 'Sanctuary S&Q', 'Old Man S&Q']), + create_lw_region(multiworld, player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest', 'Flute Activation Spot'], ["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Zoras River', 'Kings Grave Outer Rocks', 'Dam', 'Links House', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave', @@ -24,122 +24,122 @@ def create_regions(world, player): 'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)', 'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing', 'Hyrule Castle Main Gate', 'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']), - create_lw_region(world, player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop']), - create_lw_region(world, player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']), - create_cave_region(world, player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top", + create_lw_region(multiworld, player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop']), + create_lw_region(multiworld, player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']), + create_cave_region(multiworld, player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top", "Blind\'s Hideout - Left", "Blind\'s Hideout - Right", "Blind\'s Hideout - Far Left", "Blind\'s Hideout - Far Right"]), - create_cave_region(world, player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']), - create_lw_region(world, player, 'Zoras River', ['King Zora', 'Zora\'s Ledge']), - create_cave_region(world, player, 'Waterfall of Wishing', 'a cave with two chests', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']), - create_lw_region(world, player, 'Kings Grave Area', None, ['Kings Grave', 'Kings Grave Inner Rocks']), - create_cave_region(world, player, 'Kings Grave', 'a cave with a chest', ['King\'s Tomb']), - create_cave_region(world, player, 'North Fairy Cave', 'a drop\'s exit', None, ['North Fairy Cave Exit']), - create_cave_region(world, player, 'Dam', 'the dam', ['Floodgate', 'Floodgate Chest']), - create_cave_region(world, player, 'Links House', 'your house', ['Link\'s House'], ['Links House Exit']), - create_cave_region(world, player, 'Chris Houlihan Room', 'I AM ERROR', None, ['Chris Houlihan Room Exit']), - create_cave_region(world, player, 'Tavern', 'the tavern', ['Kakariko Tavern']), - create_cave_region(world, player, 'Elder House', 'a connector', None, ['Elder House Exit (East)', 'Elder House Exit (West)']), - create_cave_region(world, player, 'Snitch Lady (East)', 'a boring house'), - create_cave_region(world, player, 'Snitch Lady (West)', 'a boring house'), - create_cave_region(world, player, 'Bush Covered House', 'the grass man'), - create_cave_region(world, player, 'Tavern (Front)', 'the tavern'), - create_cave_region(world, player, 'Light World Bomb Hut', 'a restock room'), - create_cave_region(world, player, 'Kakariko Shop', 'a common shop'), - create_cave_region(world, player, 'Fortune Teller (Light)', 'a fortune teller'), - create_cave_region(world, player, 'Lake Hylia Fortune Teller', 'a fortune teller'), - create_cave_region(world, player, 'Lumberjack House', 'a boring house'), - create_cave_region(world, player, 'Bonk Fairy (Light)', 'a fairy fountain'), - create_cave_region(world, player, 'Bonk Fairy (Dark)', 'a fairy fountain'), - create_cave_region(world, player, 'Lake Hylia Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Swamp Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Desert Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Desert Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Dark Death Mountain Healer Fairy', 'a fairy fountain'), - create_cave_region(world, player, 'Chicken House', 'a house with a chest', ['Chicken House']), - create_cave_region(world, player, 'Aginahs Cave', 'a cave with a chest', ['Aginah\'s Cave']), - create_cave_region(world, player, 'Sahasrahlas Hut', 'Sahasrahla', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']), - create_cave_region(world, player, 'Kakariko Well (top)', 'a drop\'s exit', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle', + create_cave_region(multiworld, player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']), + create_lw_region(multiworld, player, 'Zoras River', ['King Zora', 'Zora\'s Ledge']), + create_cave_region(multiworld, player, 'Waterfall of Wishing', 'a cave with two chests', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']), + create_lw_region(multiworld, player, 'Kings Grave Area', None, ['Kings Grave', 'Kings Grave Inner Rocks']), + create_cave_region(multiworld, player, 'Kings Grave', 'a cave with a chest', ['King\'s Tomb']), + create_cave_region(multiworld, player, 'North Fairy Cave', 'a drop\'s exit', None, ['North Fairy Cave Exit']), + create_cave_region(multiworld, player, 'Dam', 'the dam', ['Floodgate', 'Floodgate Chest']), + create_cave_region(multiworld, player, 'Links House', 'your house', ['Link\'s House'], ['Links House Exit']), + create_cave_region(multiworld, player, 'Chris Houlihan Room', 'I AM ERROR', None, ['Chris Houlihan Room Exit']), + create_cave_region(multiworld, player, 'Tavern', 'the tavern', ['Kakariko Tavern']), + create_cave_region(multiworld, player, 'Elder House', 'a connector', None, ['Elder House Exit (East)', 'Elder House Exit (West)']), + create_cave_region(multiworld, player, 'Snitch Lady (East)', 'a boring house'), + create_cave_region(multiworld, player, 'Snitch Lady (West)', 'a boring house'), + create_cave_region(multiworld, player, 'Bush Covered House', 'the grass man'), + create_cave_region(multiworld, player, 'Tavern (Front)', 'the tavern'), + create_cave_region(multiworld, player, 'Light World Bomb Hut', 'a restock room'), + create_cave_region(multiworld, player, 'Kakariko Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Fortune Teller (Light)', 'a fortune teller'), + create_cave_region(multiworld, player, 'Lake Hylia Fortune Teller', 'a fortune teller'), + create_cave_region(multiworld, player, 'Lumberjack House', 'a boring house'), + create_cave_region(multiworld, player, 'Bonk Fairy (Light)', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Bonk Fairy (Dark)', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Lake Hylia Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Swamp Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Desert Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Desert Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Dark Death Mountain Healer Fairy', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Chicken House', 'a house with a chest', ['Chicken House']), + create_cave_region(multiworld, player, 'Aginahs Cave', 'a cave with a chest', ['Aginah\'s Cave']), + create_cave_region(multiworld, player, 'Sahasrahlas Hut', 'Sahasrahla', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']), + create_cave_region(multiworld, player, 'Kakariko Well (top)', 'a drop\'s exit', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle', 'Kakariko Well - Right', 'Kakariko Well - Bottom'], ['Kakariko Well (top to bottom)']), - create_cave_region(world, player, 'Kakariko Well (bottom)', 'a drop\'s exit', None, ['Kakariko Well Exit']), - create_cave_region(world, player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']), - create_lw_region(world, player, 'Bat Cave Drop Ledge', None, ['Bat Cave Drop']), - create_cave_region(world, player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']), - create_cave_region(world, player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']), - create_cave_region(world, player, 'Sick Kids House', 'the sick kid', ['Sick Kid']), - create_lw_region(world, player, 'Hobo Bridge', ['Hobo']), - create_cave_region(world, player, 'Lost Woods Hideout (top)', 'a drop\'s exit', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']), - create_cave_region(world, player, 'Lost Woods Hideout (bottom)', 'a drop\'s exit', None, ['Lost Woods Hideout Exit']), - create_cave_region(world, player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']), - create_cave_region(world, player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']), - create_lw_region(world, player, 'Cave 45 Ledge', None, ['Cave 45']), - create_cave_region(world, player, 'Cave 45', 'a cave with an item', ['Cave 45']), - create_lw_region(world, player, 'Graveyard Ledge', None, ['Graveyard Cave']), - create_cave_region(world, player, 'Graveyard Cave', 'a cave with an item', ['Graveyard Cave']), - create_cave_region(world, player, 'Checkerboard Cave', 'a cave with an item', ['Checkerboard Cave']), - create_cave_region(world, player, 'Long Fairy Cave', 'a fairy fountain'), - create_cave_region(world, player, 'Mini Moldorm Cave', 'a bounty of five items', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', + create_cave_region(multiworld, player, 'Kakariko Well (bottom)', 'a drop\'s exit', None, ['Kakariko Well Exit']), + create_cave_region(multiworld, player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']), + create_lw_region(multiworld, player, 'Bat Cave Drop Ledge', None, ['Bat Cave Drop']), + create_cave_region(multiworld, player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']), + create_cave_region(multiworld, player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']), + create_cave_region(multiworld, player, 'Sick Kids House', 'the sick kid', ['Sick Kid']), + create_lw_region(multiworld, player, 'Hobo Bridge', ['Hobo']), + create_cave_region(multiworld, player, 'Lost Woods Hideout (top)', 'a drop\'s exit', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']), + create_cave_region(multiworld, player, 'Lost Woods Hideout (bottom)', 'a drop\'s exit', None, ['Lost Woods Hideout Exit']), + create_cave_region(multiworld, player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']), + create_cave_region(multiworld, player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']), + create_lw_region(multiworld, player, 'Cave 45 Ledge', None, ['Cave 45']), + create_cave_region(multiworld, player, 'Cave 45', 'a cave with an item', ['Cave 45']), + create_lw_region(multiworld, player, 'Graveyard Ledge', None, ['Graveyard Cave']), + create_cave_region(multiworld, player, 'Graveyard Cave', 'a cave with an item', ['Graveyard Cave']), + create_cave_region(multiworld, player, 'Checkerboard Cave', 'a cave with an item', ['Checkerboard Cave']), + create_cave_region(multiworld, player, 'Long Fairy Cave', 'a fairy fountain'), + create_cave_region(multiworld, player, 'Mini Moldorm Cave', 'a bounty of five items', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']), - create_cave_region(world, player, 'Ice Rod Cave', 'a cave with a chest', ['Ice Rod Cave']), - create_cave_region(world, player, 'Good Bee Cave', 'a cold bee'), - create_cave_region(world, player, '20 Rupee Cave', 'a cave with some cash'), - create_cave_region(world, player, 'Cave Shop (Lake Hylia)', 'a common shop'), - create_cave_region(world, player, 'Cave Shop (Dark Death Mountain)', 'a common shop'), - create_cave_region(world, player, 'Bonk Rock Cave', 'a cave with a chest', ['Bonk Rock Cave']), - create_cave_region(world, player, 'Library', 'the library', ['Library']), - create_cave_region(world, player, 'Kakariko Gamble Game', 'a game of chance'), - create_cave_region(world, player, 'Potion Shop', 'the potion shop', ['Potion Shop']), - create_lw_region(world, player, 'Lake Hylia Island', ['Lake Hylia Island']), - create_cave_region(world, player, 'Capacity Upgrade', 'the queen of fairies', ['Capacity Upgrade Shop']), - create_cave_region(world, player, 'Two Brothers House', 'a connector', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']), - create_lw_region(world, player, 'Maze Race Ledge', ['Maze Race'], ['Two Brothers House (West)']), - create_cave_region(world, player, '50 Rupee Cave', 'a cave with some cash'), - create_lw_region(world, player, 'Desert Ledge', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)']), - create_lw_region(world, player, 'Desert Ledge (Northeast)', None, ['Checkerboard Cave']), - create_lw_region(world, player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)']), - create_lw_region(world, player, 'Desert Palace Lone Stairs', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']), - create_lw_region(world, player, 'Desert Palace Entrance (North) Spot', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks']), - create_dungeon_region(world, player, 'Desert Palace Main (Outer)', 'Desert Palace', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'], + create_cave_region(multiworld, player, 'Ice Rod Cave', 'a cave with a chest', ['Ice Rod Cave']), + create_cave_region(multiworld, player, 'Good Bee Cave', 'a cold bee'), + create_cave_region(multiworld, player, '20 Rupee Cave', 'a cave with some cash'), + create_cave_region(multiworld, player, 'Cave Shop (Lake Hylia)', 'a common shop'), + create_cave_region(multiworld, player, 'Cave Shop (Dark Death Mountain)', 'a common shop'), + create_cave_region(multiworld, player, 'Bonk Rock Cave', 'a cave with a chest', ['Bonk Rock Cave']), + create_cave_region(multiworld, player, 'Library', 'the library', ['Library']), + create_cave_region(multiworld, player, 'Kakariko Gamble Game', 'a game of chance'), + create_cave_region(multiworld, player, 'Potion Shop', 'the potion shop', ['Potion Shop']), + create_lw_region(multiworld, player, 'Lake Hylia Island', ['Lake Hylia Island']), + create_cave_region(multiworld, player, 'Capacity Upgrade', 'the queen of fairies', ['Capacity Upgrade Shop']), + create_cave_region(multiworld, player, 'Two Brothers House', 'a connector', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']), + create_lw_region(multiworld, player, 'Maze Race Ledge', ['Maze Race'], ['Two Brothers House (West)']), + create_cave_region(multiworld, player, '50 Rupee Cave', 'a cave with some cash'), + create_lw_region(multiworld, player, 'Desert Ledge', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)']), + create_lw_region(multiworld, player, 'Desert Ledge (Northeast)', None, ['Checkerboard Cave']), + create_lw_region(multiworld, player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)']), + create_lw_region(multiworld, player, 'Desert Palace Lone Stairs', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']), + create_lw_region(multiworld, player, 'Desert Palace Entrance (North) Spot', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks']), + create_dungeon_region(multiworld, player, 'Desert Palace Main (Outer)', 'Desert Palace', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'], ['Desert Palace Pots (Outer)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', 'Desert Palace East Wing']), - create_dungeon_region(world, player, 'Desert Palace Main (Inner)', 'Desert Palace', None, ['Desert Palace Exit (South)', 'Desert Palace Pots (Inner)']), - create_dungeon_region(world, player, 'Desert Palace East', 'Desert Palace', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']), - create_dungeon_region(world, player, 'Desert Palace North', 'Desert Palace', ['Desert Palace - Desert Tiles 1 Pot Key', 'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key', + create_dungeon_region(multiworld, player, 'Desert Palace Main (Inner)', 'Desert Palace', None, ['Desert Palace Exit (South)', 'Desert Palace Pots (Inner)']), + create_dungeon_region(multiworld, player, 'Desert Palace East', 'Desert Palace', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Desert Palace North', 'Desert Palace', ['Desert Palace - Desert Tiles 1 Pot Key', 'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key', 'Desert Palace - Boss', 'Desert Palace - Prize'], ['Desert Palace Exit (North)']), - create_dungeon_region(world, player, 'Eastern Palace', 'Eastern Palace', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest', + create_dungeon_region(multiworld, player, 'Eastern Palace', 'Eastern Palace', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest', 'Eastern Palace - Dark Square Pot Key', 'Eastern Palace - Dark Eyegore Key Drop', 'Eastern Palace - Big Key Chest', 'Eastern Palace - Map Chest', 'Eastern Palace - Boss', 'Eastern Palace - Prize'], ['Eastern Palace Exit']), - create_lw_region(world, player, 'Master Sword Meadow', ['Master Sword Pedestal']), - create_cave_region(world, player, 'Lost Woods Gamble', 'a game of chance'), - create_lw_region(world, player, 'Hyrule Castle Courtyard', None, ['Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Entrance (South)']), - create_lw_region(world, player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Ledge Courtyard Drop']), - create_dungeon_region(world, player, 'Hyrule Castle', 'Hyrule Castle', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', + create_lw_region(multiworld, player, 'Master Sword Meadow', ['Master Sword Pedestal']), + create_cave_region(multiworld, player, 'Lost Woods Gamble', 'a game of chance'), + create_lw_region(multiworld, player, 'Hyrule Castle Courtyard', None, ['Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Entrance (South)']), + create_lw_region(multiworld, player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Ledge Courtyard Drop']), + create_dungeon_region(multiworld, player, 'Hyrule Castle', 'Hyrule Castle', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Hyrule Castle - Map Guard Key Drop', 'Hyrule Castle - Boomerang Guard Key Drop', 'Hyrule Castle - Big Key Drop'], ['Hyrule Castle Exit (East)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (South)', 'Throne Room']), - create_dungeon_region(world, player, 'Sewer Drop', 'a drop\'s exit', None, ['Sewer Drop']), # This exists only to be referenced for access checks - create_dungeon_region(world, player, 'Sewers (Dark)', 'a drop\'s exit', ['Sewers - Dark Cross', 'Sewers - Key Rat Key Drop'], ['Sewers Door']), - create_dungeon_region(world, player, 'Sewers', 'a drop\'s exit', None, ['Sanctuary Push Door', 'Sewers Back Door', 'Sewers Secret Room']), - create_dungeon_region(world, player, 'Sewers Secret Room', 'a drop\'s exit', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', + create_dungeon_region(multiworld, player, 'Sewer Drop', 'a drop\'s exit', None, ['Sewer Drop']), # This exists only to be referenced for access checks + create_dungeon_region(multiworld, player, 'Sewers (Dark)', 'a drop\'s exit', ['Sewers - Dark Cross', 'Sewers - Key Rat Key Drop'], ['Sewers Door']), + create_dungeon_region(multiworld, player, 'Sewers', 'a drop\'s exit', None, ['Sanctuary Push Door', 'Sewers Back Door', 'Sewers Secret Room']), + create_dungeon_region(multiworld, player, 'Sewers Secret Room', 'a drop\'s exit', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', 'Sewers - Secret Room - Right']), - create_dungeon_region(world, player, 'Sanctuary', 'a drop\'s exit', ['Sanctuary'], ['Sanctuary Exit']), - create_dungeon_region(world, player, 'Agahnims Tower', 'Castle Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze', 'Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop'], ['Agahnim 1', 'Agahnims Tower Exit']), - create_dungeon_region(world, player, 'Agahnim 1', 'Castle Tower', ['Agahnim 1'], None), - create_cave_region(world, player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']), - create_cave_region(world, player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), - create_cave_region(world, player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), - create_lw_region(world, player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Teleporter']), - create_cave_region(world, player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), - create_lw_region(world, player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']), - create_cave_region(world, player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), - create_cave_region(world, player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, ['Spectacle Rock Cave Exit']), - create_cave_region(world, player, 'Spectacle Rock Cave (Peak)', 'a connector', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']), - create_lw_region(world, player, 'East Death Mountain (Bottom)', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Teleporter', 'Hookshot Fairy', 'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']), - create_cave_region(world, player, 'Hookshot Fairy', 'fairies deep in a cave'), - create_cave_region(world, player, 'Paradox Cave Front', 'a connector', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)', 'Light World Death Mountain Shop']), - create_cave_region(world, player, 'Paradox Cave Chest Area', 'a connector', ['Paradox Cave Lower - Far Left', + create_dungeon_region(multiworld, player, 'Sanctuary', 'a drop\'s exit', ['Sanctuary'], ['Sanctuary Exit']), + create_dungeon_region(multiworld, player, 'Agahnims Tower', 'Castle Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze', 'Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop'], ['Agahnim 1', 'Agahnims Tower Exit']), + create_dungeon_region(multiworld, player, 'Agahnim 1', 'Castle Tower', ['Agahnim 1'], None), + create_cave_region(multiworld, player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']), + create_cave_region(multiworld, player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), + create_cave_region(multiworld, player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), + create_lw_region(multiworld, player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Teleporter']), + create_cave_region(multiworld, player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), + create_lw_region(multiworld, player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']), + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, ['Spectacle Rock Cave Exit']), + create_cave_region(multiworld, player, 'Spectacle Rock Cave (Peak)', 'a connector', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']), + create_lw_region(multiworld, player, 'East Death Mountain (Bottom)', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Teleporter', 'Hookshot Fairy', 'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']), + create_cave_region(multiworld, player, 'Hookshot Fairy', 'fairies deep in a cave'), + create_cave_region(multiworld, player, 'Paradox Cave Front', 'a connector', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)', 'Light World Death Mountain Shop']), + create_cave_region(multiworld, player, 'Paradox Cave Chest Area', 'a connector', ['Paradox Cave Lower - Far Left', 'Paradox Cave Lower - Left', 'Paradox Cave Lower - Right', 'Paradox Cave Lower - Far Right', @@ -147,267 +147,267 @@ def create_regions(world, player): 'Paradox Cave Upper - Left', 'Paradox Cave Upper - Right'], ['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']), - create_cave_region(world, player, 'Paradox Cave', 'a connector', None, + create_cave_region(multiworld, player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), - create_cave_region(world, player, 'Light World Death Mountain Shop', 'a common shop'), - create_lw_region(world, player, 'East Death Mountain (Top)', None, + create_cave_region(multiworld, player, 'Light World Death Mountain Shop', 'a common shop'), + create_lw_region(multiworld, player, 'East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']), - create_lw_region(world, player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']), - create_cave_region(world, player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], + create_lw_region(multiworld, player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']), + create_cave_region(multiworld, player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']), - create_cave_region(world, player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']), - create_lw_region(world, player, 'Fairy Ascension Plateau', None, + create_cave_region(multiworld, player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']), + create_lw_region(multiworld, player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']), - create_cave_region(world, player, 'Fairy Ascension Cave (Bottom)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Bottom)', 'a connector', None, ['Fairy Ascension Cave Climb', 'Fairy Ascension Cave Exit (Bottom)']), - create_cave_region(world, player, 'Fairy Ascension Cave (Drop)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Drop)', 'a connector', None, ['Fairy Ascension Cave Pots']), - create_cave_region(world, player, 'Fairy Ascension Cave (Top)', 'a connector', None, + create_cave_region(multiworld, player, 'Fairy Ascension Cave (Top)', 'a connector', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Drop']), - create_lw_region(world, player, 'Fairy Ascension Ledge', None, + create_lw_region(multiworld, player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']), - create_lw_region(world, player, 'Death Mountain (Top)', ['Ether Tablet'], + create_lw_region(multiworld, player, 'Death Mountain (Top)', ['Ether Tablet'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop']), - create_lw_region(world, player, 'Spectacle Rock', ['Spectacle Rock'], ['Spectacle Rock Drop']), - create_dungeon_region(world, player, 'Tower of Hera (Bottom)', 'Tower of Hera', + create_lw_region(multiworld, player, 'Spectacle Rock', ['Spectacle Rock'], ['Spectacle Rock Drop']), + create_dungeon_region(multiworld, player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']), - create_dungeon_region(world, player, 'Tower of Hera (Basement)', 'Tower of Hera', + create_dungeon_region(multiworld, player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']), - create_dungeon_region(world, player, 'Tower of Hera (Top)', 'Tower of Hera', + create_dungeon_region(multiworld, player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']), - create_dw_region(world, player, 'East Dark World', ['Pyramid'], + create_dw_region(multiworld, player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Pyramid Hole', 'Northeast Dark World Broken Bridge Pass', ]), - create_dw_region(world, player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), - create_dw_region(world, player, 'Northeast Dark World', None, + create_dw_region(multiworld, player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), + create_dw_region(multiworld, player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'Catfish Entrance Rock', 'Dark Lake Hylia Teleporter']), - create_cave_region(world, player, 'Palace of Darkness Hint', 'a storyteller'), - create_cave_region(world, player, 'East Dark World Hint', 'a storyteller'), - create_dw_region(world, player, 'South Dark World', ['Stumpy', 'Digging Game'], + create_cave_region(multiworld, player, 'Palace of Darkness Hint', 'a storyteller'), + create_cave_region(multiworld, player, 'East Dark World Hint', 'a storyteller'), + create_dw_region(multiworld, player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'Maze Race Mirror Spot', 'Cave 45 Mirror Spot', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop', 'Bombos Tablet Mirror Spot']), - create_lw_region(world, player, 'Bombos Tablet Ledge', ['Bombos Tablet']), - create_cave_region(world, player, 'Big Bomb Shop', 'the bomb shop'), - create_cave_region(world, player, 'Archery Game', 'a game of skill'), - create_dw_region(world, player, 'Dark Lake Hylia', None, + create_lw_region(multiworld, player, 'Bombos Tablet Ledge', ['Bombos Tablet']), + create_cave_region(multiworld, player, 'Big Bomb Shop', 'the bomb shop'), + create_cave_region(multiworld, player, 'Archery Game', 'a game of skill'), + create_dw_region(multiworld, player, 'Dark Lake Hylia', None, ['Lake Hylia Island Mirror Spot', 'East Dark World Pier', 'Dark Lake Hylia Ledge']), - create_dw_region(world, player, 'Dark Lake Hylia Central Island', None, + create_dw_region(multiworld, player, 'Dark Lake Hylia Central Island', None, ['Ice Palace', 'Lake Hylia Central Island Mirror Spot']), - create_dw_region(world, player, 'Dark Lake Hylia Ledge', None, + create_dw_region(multiworld, player, 'Dark Lake Hylia Ledge', None, ['Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave']), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Hint', 'a storyteller'), - create_cave_region(world, player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'), - create_cave_region(world, player, 'Hype Cave', 'a bounty of five items', + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Hint', 'a storyteller'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'), + create_cave_region(multiworld, player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', 'Hype Cave - Bottom', 'Hype Cave - Generous Guy']), - create_dw_region(world, player, 'West Dark World', ['Frog'], + create_dw_region(multiworld, player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Graveyard Ledge Mirror Spot', 'Kings Grave Mirror Spot', 'Bumper Cave Entrance Rock', 'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop']), - create_dw_region(world, player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Village of Outcasts Shop']), - create_dw_region(world, player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], + create_dw_region(multiworld, player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Village of Outcasts Shop']), + create_dw_region(multiworld, player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Bat Cave Drop Ledge Mirror Spot', 'Dark World Hammer Peg Cave', 'Peg Area Rocks']), - create_dw_region(world, player, 'Bumper Cave Entrance', None, + create_dw_region(multiworld, player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance Drop']), - create_cave_region(world, player, 'Fortune Teller (Dark)', 'a fortune teller'), - create_cave_region(world, player, 'Village of Outcasts Shop', 'a common shop'), - create_cave_region(world, player, 'Dark Lake Hylia Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Lumberjack Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Potion Shop', 'a common shop'), - create_cave_region(world, player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), - create_cave_region(world, player, 'Pyramid Fairy', 'a cave with two chests', + create_cave_region(multiworld, player, 'Fortune Teller (Dark)', 'a fortune teller'), + create_cave_region(multiworld, player, 'Village of Outcasts Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark Lake Hylia Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Lumberjack Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Potion Shop', 'a common shop'), + create_cave_region(multiworld, player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), + create_cave_region(multiworld, player, 'Pyramid Fairy', 'a cave with two chests', ['Pyramid Fairy - Left', 'Pyramid Fairy - Right']), - create_cave_region(world, player, 'Brewery', 'a house with a chest', ['Brewery']), - create_cave_region(world, player, 'C-Shaped House', 'a house with a chest', ['C-Shaped House']), - create_cave_region(world, player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), - create_cave_region(world, player, 'Red Shield Shop', 'the rare shop'), - create_cave_region(world, player, 'Dark Sanctuary Hint', 'a storyteller'), - create_cave_region(world, player, 'Bumper Cave', 'a connector', None, + create_cave_region(multiworld, player, 'Brewery', 'a house with a chest', ['Brewery']), + create_cave_region(multiworld, player, 'C-Shaped House', 'a house with a chest', ['C-Shaped House']), + create_cave_region(multiworld, player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), + create_cave_region(multiworld, player, 'Red Shield Shop', 'the rare shop'), + create_cave_region(multiworld, player, 'Dark Sanctuary Hint', 'a storyteller'), + create_cave_region(multiworld, player, 'Bumper Cave', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']), - create_dw_region(world, player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], + create_dw_region(multiworld, player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)', 'Bumper Cave Ledge Mirror Spot']), - create_dw_region(world, player, 'Skull Woods Forest', None, + create_dw_region(multiworld, player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']), - create_dw_region(world, player, 'Skull Woods Forest (West)', None, + create_dw_region(multiworld, player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']), - create_dw_region(world, player, 'Dark Desert', None, + create_dw_region(multiworld, player, 'Dark Desert', None, ['Misery Mire', 'Mire Shed', 'Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge Mirror Spot', 'Desert Palace Stairs Mirror Spot', 'Desert Palace Entrance (North) Mirror Spot', 'Dark Desert Hint', 'Dark Desert Fairy']), - create_cave_region(world, player, 'Mire Shed', 'a cave with two chests', + create_cave_region(multiworld, player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']), - create_cave_region(world, player, 'Dark Desert Hint', 'a storyteller'), - create_dw_region(world, player, 'Dark Death Mountain (West Bottom)', None, + create_cave_region(multiworld, player, 'Dark Desert Hint', 'a storyteller'), + create_dw_region(multiworld, player, 'Dark Death Mountain (West Bottom)', None, ['Spike Cave', 'Spectacle Rock Mirror Spot', 'Dark Death Mountain Fairy']), - create_dw_region(world, player, 'Dark Death Mountain (Top)', None, + create_dw_region(multiworld, player, 'Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Dark Death Mountain Drop (West)', 'Ganons Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Death Mountain (Top) Mirror Spot', 'Turtle Rock']), - create_dw_region(world, player, 'Dark Death Mountain Ledge', None, + create_dw_region(multiworld, player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Mimic Cave Mirror Spot', 'Spiral Cave Mirror Spot']), - create_dw_region(world, player, 'Dark Death Mountain Isolated Ledge', None, + create_dw_region(multiworld, player, 'Dark Death Mountain Isolated Ledge', None, ['Isolated Ledge Mirror Spot', 'Turtle Rock Isolated Ledge Entrance']), - create_dw_region(world, player, 'Dark Death Mountain (East Bottom)', None, + create_dw_region(multiworld, player, 'Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Fairy Ascension Mirror Spot']), - create_cave_region(world, player, 'Superbunny Cave (Top)', 'a connector', + create_cave_region(multiworld, player, 'Superbunny Cave (Top)', 'a connector', ['Superbunny Cave - Top', 'Superbunny Cave - Bottom'], ['Superbunny Cave Exit (Top)']), - create_cave_region(world, player, 'Superbunny Cave (Bottom)', 'a connector', None, + create_cave_region(multiworld, player, 'Superbunny Cave (Bottom)', 'a connector', None, ['Superbunny Cave Climb', 'Superbunny Cave Exit (Bottom)']), - create_cave_region(world, player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), - create_cave_region(world, player, 'Hookshot Cave', 'a connector', + create_cave_region(multiworld, player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), + create_cave_region(multiworld, player, 'Hookshot Cave', 'a connector', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], ['Hookshot Cave Exit (South)', 'Hookshot Cave Bomb Wall (South)']), - create_cave_region(world, player, 'Hookshot Cave (Upper)', 'a connector', None, ['Hookshot Cave Exit (North)', + create_cave_region(multiworld, player, 'Hookshot Cave (Upper)', 'a connector', None, ['Hookshot Cave Exit (North)', 'Hookshot Cave Bomb Wall (North)']), - create_dw_region(world, player, 'Death Mountain Floating Island (Dark World)', None, + create_dw_region(multiworld, player, 'Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']), - create_lw_region(world, player, 'Death Mountain Floating Island (Light World)', ['Floating Island']), - create_dw_region(world, player, 'Turtle Rock (Top)', None, ['Turtle Rock Drop']), - create_lw_region(world, player, 'Mimic Cave Ledge', None, ['Mimic Cave']), - create_cave_region(world, player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']), + create_lw_region(multiworld, player, 'Death Mountain Floating Island (Light World)', ['Floating Island']), + create_dw_region(multiworld, player, 'Turtle Rock (Top)', None, ['Turtle Rock Drop']), + create_lw_region(multiworld, player, 'Mimic Cave Ledge', None, ['Mimic Cave']), + create_cave_region(multiworld, player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']), - create_dungeon_region(world, player, 'Swamp Palace (Entrance)', 'Swamp Palace', None, ['Swamp Palace Moat', 'Swamp Palace Exit']), - create_dungeon_region(world, player, 'Swamp Palace (First Room)', 'Swamp Palace', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']), - create_dungeon_region(world, player, 'Swamp Palace (Starting Area)', 'Swamp Palace', ['Swamp Palace - Map Chest', 'Swamp Palace - Pot Row Pot Key', + create_dungeon_region(multiworld, player, 'Swamp Palace (Entrance)', 'Swamp Palace', None, ['Swamp Palace Moat', 'Swamp Palace Exit']), + create_dungeon_region(multiworld, player, 'Swamp Palace (First Room)', 'Swamp Palace', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']), + create_dungeon_region(multiworld, player, 'Swamp Palace (Starting Area)', 'Swamp Palace', ['Swamp Palace - Map Chest', 'Swamp Palace - Pot Row Pot Key', 'Swamp Palace - Trench 1 Pot Key'], ['Swamp Palace (Center)']), - create_dungeon_region(world, player, 'Swamp Palace (Center)', 'Swamp Palace', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest', 'Swamp Palace - Hookshot Pot Key', + create_dungeon_region(multiworld, player, 'Swamp Palace (Center)', 'Swamp Palace', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest', 'Swamp Palace - Hookshot Pot Key', 'Swamp Palace - Trench 2 Pot Key'], ['Swamp Palace (North)', 'Swamp Palace (West)']), - create_dungeon_region(world, player, 'Swamp Palace (West)', 'Swamp Palace', ['Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest']), - create_dungeon_region(world, player, 'Swamp Palace (North)', 'Swamp Palace', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right', + create_dungeon_region(multiworld, player, 'Swamp Palace (West)', 'Swamp Palace', ['Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest']), + create_dungeon_region(multiworld, player, 'Swamp Palace (North)', 'Swamp Palace', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right', 'Swamp Palace - Waterway Pot Key', 'Swamp Palace - Waterfall Room', 'Swamp Palace - Boss', 'Swamp Palace - Prize']), - create_dungeon_region(world, player, 'Thieves Town (Entrance)', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest', + create_dungeon_region(multiworld, player, 'Thieves Town (Entrance)', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest', 'Thieves\' Town - Map Chest', 'Thieves\' Town - Compass Chest', 'Thieves\' Town - Ambush Chest'], ['Thieves Town Big Key Door', 'Thieves Town Exit']), - create_dungeon_region(world, player, 'Thieves Town (Deep)', 'Thieves\' Town', ['Thieves\' Town - Attic', + create_dungeon_region(multiworld, player, 'Thieves Town (Deep)', 'Thieves\' Town', ['Thieves\' Town - Attic', 'Thieves\' Town - Big Chest', 'Thieves\' Town - Hallway Pot Key', 'Thieves\' Town - Spike Switch Pot Key', 'Thieves\' Town - Blind\'s Cell'], ['Blind Fight']), - create_dungeon_region(world, player, 'Blind Fight', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize']), - create_dungeon_region(world, player, 'Skull Woods First Section', 'Skull Woods', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']), - create_dungeon_region(world, player, 'Skull Woods First Section (Right)', 'Skull Woods', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), - create_dungeon_region(world, player, 'Skull Woods First Section (Left)', 'Skull Woods', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), - create_dungeon_region(world, player, 'Skull Woods First Section (Top)', 'Skull Woods', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), - create_dungeon_region(world, player, 'Skull Woods Second Section (Drop)', 'Skull Woods', None, ['Skull Woods Second Section (Drop)']), - create_dungeon_region(world, player, 'Skull Woods Second Section', 'Skull Woods', ['Skull Woods - Big Key Chest', 'Skull Woods - West Lobby Pot Key'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), - create_dungeon_region(world, player, 'Skull Woods Final Section (Entrance)', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), - create_dungeon_region(world, player, 'Skull Woods Final Section (Mothula)', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop', 'Skull Woods - Boss', 'Skull Woods - Prize']), - create_dungeon_region(world, player, 'Ice Palace (Entrance)', 'Ice Palace', ['Ice Palace - Jelly Key Drop', 'Ice Palace - Compass Chest'], ['Ice Palace (Second Section)', 'Ice Palace Exit']), - create_dungeon_region(world, player, 'Ice Palace (Second Section)', 'Ice Palace', ['Ice Palace - Conveyor Key Drop'], ['Ice Palace (Main)']), - create_dungeon_region(world, player, 'Ice Palace (Main)', 'Ice Palace', ['Ice Palace - Freezor Chest', + create_dungeon_region(multiworld, player, 'Blind Fight', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section', 'Skull Woods', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Right)', 'Skull Woods', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Left)', 'Skull Woods', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), + create_dungeon_region(multiworld, player, 'Skull Woods First Section (Top)', 'Skull Woods', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), + create_dungeon_region(multiworld, player, 'Skull Woods Second Section (Drop)', 'Skull Woods', None, ['Skull Woods Second Section (Drop)']), + create_dungeon_region(multiworld, player, 'Skull Woods Second Section', 'Skull Woods', ['Skull Woods - Big Key Chest', 'Skull Woods - West Lobby Pot Key'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), + create_dungeon_region(multiworld, player, 'Skull Woods Final Section (Entrance)', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), + create_dungeon_region(multiworld, player, 'Skull Woods Final Section (Mothula)', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop', 'Skull Woods - Boss', 'Skull Woods - Prize']), + create_dungeon_region(multiworld, player, 'Ice Palace (Entrance)', 'Ice Palace', ['Ice Palace - Jelly Key Drop', 'Ice Palace - Compass Chest'], ['Ice Palace (Second Section)', 'Ice Palace Exit']), + create_dungeon_region(multiworld, player, 'Ice Palace (Second Section)', 'Ice Palace', ['Ice Palace - Conveyor Key Drop'], ['Ice Palace (Main)']), + create_dungeon_region(multiworld, player, 'Ice Palace (Main)', 'Ice Palace', ['Ice Palace - Freezor Chest', 'Ice Palace - Many Pots Pot Key', 'Ice Palace - Big Chest', 'Ice Palace - Iced T Room'], ['Ice Palace (East)', 'Ice Palace (Kholdstare)']), - create_dungeon_region(world, player, 'Ice Palace (East)', 'Ice Palace', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']), - create_dungeon_region(world, player, 'Ice Palace (East Top)', 'Ice Palace', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest', 'Ice Palace - Hammer Block Key Drop']), - create_dungeon_region(world, player, 'Ice Palace (Kholdstare)', 'Ice Palace', ['Ice Palace - Boss', 'Ice Palace - Prize']), - create_dungeon_region(world, player, 'Misery Mire (Entrance)', 'Misery Mire', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']), - create_dungeon_region(world, player, 'Misery Mire (Main)', 'Misery Mire', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby', + create_dungeon_region(multiworld, player, 'Ice Palace (East)', 'Ice Palace', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']), + create_dungeon_region(multiworld, player, 'Ice Palace (East Top)', 'Ice Palace', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest', 'Ice Palace - Hammer Block Key Drop']), + create_dungeon_region(multiworld, player, 'Ice Palace (Kholdstare)', 'Ice Palace', ['Ice Palace - Boss', 'Ice Palace - Prize']), + create_dungeon_region(multiworld, player, 'Misery Mire (Entrance)', 'Misery Mire', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']), + create_dungeon_region(multiworld, player, 'Misery Mire (Main)', 'Misery Mire', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby', 'Misery Mire - Bridge Chest', 'Misery Mire - Spike Chest', 'Misery Mire - Spikes Pot Key', 'Misery Mire - Fishbone Pot Key', 'Misery Mire - Conveyor Crystal Key Drop'], ['Misery Mire (West)', 'Misery Mire Big Key Door']), - create_dungeon_region(world, player, 'Misery Mire (West)', 'Misery Mire', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']), - create_dungeon_region(world, player, 'Misery Mire (Final Area)', 'Misery Mire', None, ['Misery Mire (Vitreous)']), - create_dungeon_region(world, player, 'Misery Mire (Vitreous)', 'Misery Mire', ['Misery Mire - Boss', 'Misery Mire - Prize']), - create_dungeon_region(world, player, 'Turtle Rock (Entrance)', 'Turtle Rock', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']), - create_dungeon_region(world, player, 'Turtle Rock (First Section)', 'Turtle Rock', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', + create_dungeon_region(multiworld, player, 'Misery Mire (West)', 'Misery Mire', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Misery Mire (Final Area)', 'Misery Mire', None, ['Misery Mire (Vitreous)']), + create_dungeon_region(multiworld, player, 'Misery Mire (Vitreous)', 'Misery Mire', ['Misery Mire - Boss', 'Misery Mire - Prize']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Entrance)', 'Turtle Rock', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (First Section)', 'Turtle Rock', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right'], ['Turtle Rock Entrance to Pokey Room', 'Turtle Rock Entrance Gap Reverse']), - create_dungeon_region(world, player, 'Turtle Rock (Pokey Room)', 'Turtle Rock', ['Turtle Rock - Pokey 1 Key Drop'], ['Turtle Rock (Pokey Room) (North)', 'Turtle Rock (Pokey Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Second Section)', 'Turtle Rock', ['Turtle Rock - Big Key Chest', 'Turtle Rock - Pokey 2 Key Drop'], ['Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door', 'Turtle Rock Second Section Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Second Section Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Second Section from Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Big Chest)', 'Turtle Rock', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']), - create_dungeon_region(world, player, 'Turtle Rock (Crystaroller Room)', 'Turtle Rock', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']), - create_dungeon_region(world, player, 'Turtle Rock (Dark Room)', 'Turtle Rock', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']), - create_dungeon_region(world, player, 'Turtle Rock (Eye Bridge Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Isolated Ledge Exit', 'Turtle Rock Eye Bridge from Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Eye Bridge)', 'Turtle Rock', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', + create_dungeon_region(multiworld, player, 'Turtle Rock (Pokey Room)', 'Turtle Rock', ['Turtle Rock - Pokey 1 Key Drop'], ['Turtle Rock (Pokey Room) (North)', 'Turtle Rock (Pokey Room) (South)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Second Section)', 'Turtle Rock', ['Turtle Rock - Big Key Chest', 'Turtle Rock - Pokey 2 Key Drop'], ['Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door', 'Turtle Rock Second Section Bomb Wall']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Second Section Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Second Section from Bomb Wall']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Big Chest)', 'Turtle Rock', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Crystaroller Room)', 'Turtle Rock', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Dark Room)', 'Turtle Rock', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Eye Bridge Bomb Wall)', 'Turtle Rock', None, ['Turtle Rock Isolated Ledge Exit', 'Turtle Rock Eye Bridge from Bomb Wall']), + create_dungeon_region(multiworld, player, 'Turtle Rock (Eye Bridge)', 'Turtle Rock', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', 'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'], ['Turtle Rock Dark Room (South)', 'Turtle Rock (Trinexx)', 'Turtle Rock Eye Bridge Bomb Wall']), - create_dungeon_region(world, player, 'Turtle Rock (Trinexx)', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize']), - create_dungeon_region(world, player, 'Palace of Darkness (Entrance)', 'Palace of Darkness', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']), - create_dungeon_region(world, player, 'Palace of Darkness (Center)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'], + create_dungeon_region(multiworld, player, 'Turtle Rock (Trinexx)', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Entrance)', 'Palace of Darkness', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Center)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'], ['Palace of Darkness Big Key Chest Staircase', 'Palace of Darkness (North)', 'Palace of Darkness Big Key Door']), - create_dungeon_region(world, player, 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness', ['Palace of Darkness - Big Key Chest']), - create_dungeon_region(world, player, 'Palace of Darkness (Bonk Section)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']), - create_dungeon_region(world, player, 'Palace of Darkness (North)', 'Palace of Darkness', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], + create_dungeon_region(multiworld, player, 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness', ['Palace of Darkness - Big Key Chest']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Bonk Section)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (North)', 'Palace of Darkness', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], ['Palace of Darkness Spike Statue Room Door', 'Palace of Darkness Maze Door']), - create_dungeon_region(world, player, 'Palace of Darkness (Maze)', 'Palace of Darkness', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']), - create_dungeon_region(world, player, 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway']), - create_dungeon_region(world, player, 'Palace of Darkness (Final Section)', 'Palace of Darkness', ['Palace of Darkness - Boss', 'Palace of Darkness - Prize']), - create_dungeon_region(world, player, 'Ganons Tower (Entrance)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', + create_dungeon_region(multiworld, player, 'Palace of Darkness (Maze)', 'Palace of Darkness', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway']), + create_dungeon_region(multiworld, player, 'Palace of Darkness (Final Section)', 'Palace of Darkness', ['Palace of Darkness - Boss', 'Palace of Darkness - Prize']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Entrance)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right', 'Ganons Tower - Conveyor Cross Pot Key'], ['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Ganons Tower Exit']), - create_dungeon_region(world, player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']), - create_dungeon_region(world, player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', + create_dungeon_region(multiworld, player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right', 'Ganons Tower - Conveyor Star Pits Pot Key'], ['Ganons Tower (Bottom) (East)']), - create_dungeon_region(world, player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', + create_dungeon_region(multiworld, player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right', 'Ganons Tower - Double Switch Pot Key'], ['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']), - create_dungeon_region(world, player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']), - create_dungeon_region(world, player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']), - create_dungeon_region(world, player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', + create_dungeon_region(multiworld, player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', 'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'], ['Ganons Tower (Bottom) (West)']), - create_dungeon_region(world, player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left', + create_dungeon_region(multiworld, player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left', 'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']), - create_dungeon_region(world, player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']), - create_dungeon_region(world, player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', + create_dungeon_region(multiworld, player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']), + create_dungeon_region(multiworld, player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Mini Helmasaur Key Drop'], ['Ganons Tower Moldorm Door']), - create_dungeon_region(world, player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']), - create_dungeon_region(world, player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None), - create_cave_region(world, player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), - create_cave_region(world, player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), - create_dw_region(world, player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']), - create_lw_region(world, player, 'Desert Northern Cliffs'), - create_dw_region(world, player, 'Dark Death Mountain Bunny Descent Area') + create_dungeon_region(multiworld, player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']), + create_dungeon_region(multiworld, player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None), + create_cave_region(multiworld, player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), + create_cave_region(multiworld, player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), + create_dw_region(multiworld, player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']), + create_lw_region(multiworld, player, 'Desert Northern Cliffs'), + create_dw_region(multiworld, player, 'Dark Death Mountain Bunny Descent Area') ] -def create_lw_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): - return _create_region(world, player, name, LTTPRegionType.LightWorld, 'Light World', locations, exits) +def create_lw_region(multiworld: MultiWorld, player: int, name: str, locations=None, exits=None): + return _create_region(multiworld, player, name, LTTPRegionType.LightWorld, 'Light World', locations, exits) -def create_dw_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): - return _create_region(world, player, name, LTTPRegionType.DarkWorld, 'Dark World', locations, exits) +def create_dw_region(multiworld: MultiWorld, player: int, name: str, locations=None, exits=None): + return _create_region(multiworld, player, name, LTTPRegionType.DarkWorld, 'Dark World', locations, exits) -def create_cave_region(world: MultiWorld, player: int, name: str, hint: str, locations=None, exits=None): - return _create_region(world, player, name, LTTPRegionType.Cave, hint, locations, exits) +def create_cave_region(multiworld: MultiWorld, player: int, name: str, hint: str, locations=None, exits=None): + return _create_region(multiworld, player, name, LTTPRegionType.Cave, hint, locations, exits) -def create_dungeon_region(world: MultiWorld, player: int, name: str, hint: str, locations=None, exits=None): - return _create_region(world, player, name, LTTPRegionType.Dungeon, hint, locations, exits) +def create_dungeon_region(multiworld: MultiWorld, player: int, name: str, hint: str, locations=None, exits=None): + return _create_region(multiworld, player, name, LTTPRegionType.Dungeon, hint, locations, exits) -def _create_region(world: MultiWorld, player: int, name: str, type: LTTPRegionType, hint: str, locations=None, +def _create_region(multiworld: MultiWorld, player: int, name: str, type: LTTPRegionType, hint: str, locations=None, exits=None): from .SubClasses import ALttPLocation - ret = LTTPRegion(name, type, hint, player, world) + ret = LTTPRegion(name, type, hint, player, multiworld) if exits: for exit in exits: ret.create_exit(exit) @@ -422,10 +422,10 @@ def _create_region(world: MultiWorld, player: int, name: str, type: LTTPRegionTy return ret -def mark_light_world_regions(world, player: int): +def mark_light_world_regions(multiworld: MultiWorld, player: int): # cross world caves may have some sections marked as both in_light_world, and in_dark_work. # That is ok. the bunny logic will check for this case and incorporate special rules. - queue = collections.deque(region for region in world.get_regions(player) if region.type == LTTPRegionType.LightWorld) + queue = collections.deque(region for region in multiworld.get_regions(player) if region.type == LTTPRegionType.LightWorld) seen = set(queue) while queue: current = queue.popleft() @@ -438,7 +438,7 @@ def mark_light_world_regions(world, player: int): seen.add(exit.connected_region) queue.append(exit.connected_region) - queue = collections.deque(region for region in world.get_regions(player) if region.type == LTTPRegionType.DarkWorld) + queue = collections.deque(region for region in multiworld.get_regions(player) if region.type == LTTPRegionType.DarkWorld) seen = set(queue) while queue: current = queue.popleft() diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 2f62b37682..45b3ad39d9 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -19,7 +19,7 @@ import subprocess import threading import concurrent.futures import bsdiff4 -from typing import Collection, Optional, List, SupportsIndex +from typing import Collection, Optional, List, SupportsIndex, TYPE_CHECKING from BaseClasses import CollectionState, Region, Location, MultiWorld from Utils import local_path, user_path, int16_as_bytes, int32_as_bytes, snes_to_pc, is_frozen, parse_yaml, read_snes_rom @@ -39,6 +39,9 @@ from .Items import item_table, item_name_groups, progression_items from .EntranceShuffle import door_addresses from .Options import small_key_shuffle +if TYPE_CHECKING: + from . import ALTTPWorld + try: from maseya import z3pr from maseya.z3pr.palette_randomizer import build_offset_collections @@ -792,13 +795,13 @@ def get_nonnative_item_sprite(code: int) -> int: # https://discord.com/channels/731205301247803413/827141303330406408/852102450822905886 -def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): - local_random = world.worlds[player].random - local_world = world.worlds[player] +def patch_rom(multiworld: MultiWorld, rom: LocalRom, player: int, enemized: bool): + local_random = multiworld.worlds[player].random + local_world = multiworld.worlds[player] # patch items - for location in world.get_locations(player): + for location in multiworld.get_locations(player): if location.address is None or location.shop_slot is not None: continue @@ -852,7 +855,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle # patch entrance/exits/holes - for region in world.get_regions(player): + for region in multiworld.get_regions(player): for exit in region.exits: if exit.target is not None: if isinstance(exit.addresses, tuple): @@ -885,7 +888,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_int16(0x15DB5 + 2 * offset, 0x0640) elif room_id == 0x00d6 and local_world.fix_trock_exit: rom.write_int16(0x15DB5 + 2 * offset, 0x0134) - elif room_id == 0x000c and world.shuffle_ganon: # fix ganons tower exit point + elif room_id == 0x000c and multiworld.shuffle_ganon: # fix ganons tower exit point rom.write_int16(0x15DB5 + 2 * offset, 0x00A4) else: rom.write_int16(0x15DB5 + 2 * offset, link_y) @@ -905,9 +908,9 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): # patch door table rom.write_byte(0xDBB73 + exit.addresses, exit.target) if local_world.options.mode == 'inverted': - patch_shuffled_dark_sanc(world, rom, player) + patch_shuffled_dark_sanc(multiworld, rom, player) - write_custom_shops(rom, world, player) + write_custom_shops(rom, multiworld, player) def credits_digit(num): # top: $54 is 1, 55 2, etc , so 57=4, 5C=9 @@ -981,11 +984,11 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): if local_world.options.mode in ['open', 'inverted']: rom.write_byte(0x180032, 0x01) # open mode if local_world.options.mode == 'inverted': - set_inverted_mode(world, player, rom) + set_inverted_mode(multiworld, player, rom) elif local_world.options.mode == 'standard': rom.write_byte(0x180032, 0x00) # standard mode - uncle_location = world.get_location('Link\'s Uncle', player) + uncle_location = multiworld.get_location('Link\'s Uncle', player) if uncle_location.item is None or uncle_location.item.name not in ['Master Sword', 'Tempered Sword', 'Fighter Sword', 'Golden Sword', 'Progressive Sword']: @@ -1280,7 +1283,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): # set up goals for treasure hunt rom.write_int16(0x180163, max(0, local_world.treasure_hunt_required - - sum(1 for item in world.precollected_items[player] if item.name == "Triforce Piece"))) + sum(1 for item in multiworld.precollected_items[player] if item.name == "Triforce Piece"))) rom.write_bytes(0x180165, [0x0E, 0x28]) # Triforce Piece Sprite rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled) @@ -1309,7 +1312,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest rom.write_byte(0x50599, 0x00) # disable below ganon chest rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest - rom.write_byte(0x18008B, 0x01 if local_world.options.open_pyramid.to_bool(world, player) else 0x00) # pre-open Pyramid Hole + rom.write_byte(0x18008B, 0x01 if local_world.options.open_pyramid.to_bool(multiworld, player) else 0x00) # pre-open Pyramid Hole rom.write_byte(0x18008C, 0x01 if local_world.options.crystals_needed_for_gt == 0 else 0x00) # GT pre-opened if crystal requirement is 0 rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable @@ -1327,7 +1330,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): starting_max_bombs = 0 if local_world.options.bombless_start else 10 starting_max_arrows = 30 - startingstate = CollectionState(world) + startingstate = CollectionState(multiworld) if startingstate.has('Silver Bow', player): equip[0x340] = 1 @@ -1375,7 +1378,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): equip[0x37B] = 1 equip[0x36E] = 0x80 - for item in world.precollected_items[player]: + for item in multiworld.precollected_items[player]: if item.name in {'Bow', 'Silver Bow', 'Silver Arrows', 'Progressive Bow', 'Progressive Bow (Alt)', 'Titans Mitts', 'Power Glove', 'Progressive Glove', @@ -1590,7 +1593,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): } def get_reveal_bytes(itemName): - locations = world.find_item_locations(itemName, player) + locations = multiworld.find_item_locations(itemName, player) if len(locations) < 1: return 0x0000 location = locations[0] @@ -1667,7 +1670,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_byte(0x18004C, 0x01) # set correct flag for hera basement item - hera_basement = world.get_location('Tower of Hera - Basement Cage', player) + hera_basement = multiworld.get_location('Tower of Hera - Basement Cage', player) if hera_basement.item is not None and hera_basement.item.name == 'Small Key (Tower of Hera)' and hera_basement.item.player == player: rom.write_byte(0x4E3BB, 0xE4) else: @@ -1684,12 +1687,12 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_byte(0xFEE41, 0x2A) # bombable exit if local_world.options.tile_shuffle: - tile_set = TileSet.get_random_tile_set(world.worlds[player].random) + tile_set = TileSet.get_random_tile_set(multiworld.worlds[player].random) rom.write_byte(0x4BA21, tile_set.get_speed()) rom.write_byte(0x4BA1D, tile_set.get_len()) rom.write_bytes(0x4BA2A, tile_set.get_bytes()) - write_strings(rom, world, player) + write_strings(rom, multiworld, player) # remote items flag, does not currently work rom.write_byte(0x18637C, 0) @@ -1697,14 +1700,14 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): # set rom name # 21 bytes from Utils import __version__ - rom.name = bytearray(f'AP{__version__.replace(".", "")[0:3]}_{player}_{world.seed:11}\0', 'utf8')[:21] + rom.name = bytearray(f'AP{__version__.replace(".", "")[0:3]}_{player}_{multiworld.seed:11}\0', 'utf8')[:21] rom.name.extend([0] * (21 - len(rom.name))) rom.write_bytes(0x7FC0, rom.name) # set player names - encoded_players = world.players + len(world.groups) + encoded_players = multiworld.players + len(multiworld.groups) for p in range(1, min(encoded_players, ROM_PLAYER_LIMIT) + 1): - rom.write_bytes(0x195FFC + ((p - 1) * 32), hud_format_text(world.player_name[p])) + rom.write_bytes(0x195FFC + ((p - 1) * 32), hud_format_text(multiworld.player_name[p])) if encoded_players > ROM_PLAYER_LIMIT: rom.write_bytes(0x195FFC + ((ROM_PLAYER_LIMIT - 1) * 32), hud_format_text("Archipelago")) @@ -1723,9 +1726,9 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): return rom -def patch_race_rom(rom, world, player): +def patch_race_rom(rom: LocalRom, multiworld: MultiWorld, player: int): rom.write_bytes(0x180213, [0x01, 0x00]) # Tournament Seed - rom.encrypt(world, player) + rom.encrypt(multiworld, player) def get_price_data(price: int, price_type: int) -> List[int]: @@ -1738,8 +1741,8 @@ def get_price_data(price: int, price_type: int) -> List[int]: return int16_as_bytes(price) -def write_custom_shops(rom, world, player): - shops = sorted([shop for shop in world.worlds[player].shops if shop.custom], key=lambda shop: shop.sram_offset) +def write_custom_shops(rom: LocalRom, multiworld: MultiWorld, player: int): + shops = sorted([shop for shop in multiworld.worlds[player].shops if shop.custom], key=lambda shop: shop.sram_offset) shop_data = bytearray() items_data = bytearray() @@ -1758,9 +1761,9 @@ def write_custom_shops(rom, world, player): slot = 0 if shop.type == ShopType.TakeAny else index if item is None: break - if world.worlds[player].options.shop_item_slots or shop.type == ShopType.TakeAny: - count_shop = (shop.region.name != 'Potion Shop' or world.worlds[player].options.include_witch_hut) and \ - (shop.region.name != 'Capacity Upgrade' or world.worlds[player].options.shuffle_capacity_upgrades) + if multiworld.worlds[player].options.shop_item_slots or shop.type == ShopType.TakeAny: + count_shop = (shop.region.name != 'Potion Shop' or multiworld.worlds[player].options.include_witch_hut) and \ + (shop.region.name != 'Capacity Upgrade' or multiworld.worlds[player].options.shuffle_capacity_upgrades) rom.write_byte(0x186560 + shop.sram_offset + slot, 1 if count_shop else 0) if item['item'] == 'Single Arrow' and item['player'] == 0: arrow_mask |= 1 << index @@ -1773,11 +1776,11 @@ def write_custom_shops(rom, world, player): price_data = get_price_data(item['price'], item["price_type"]) replacement_price_data = get_price_data(item['replacement_price'], item['replacement_price_type']) slot = 0 if shop.type == ShopType.TakeAny else index - if item['player'] and world.game[item['player']] != "A Link to the Past": # item not native to ALTTP - item_code = get_nonnative_item_sprite(world.worlds[item['player']].item_name_to_id[item['item']]) + if item['player'] and multiworld.game[item['player']] != "A Link to the Past": # item not native to ALTTP + item_code = get_nonnative_item_sprite(multiworld.worlds[item['player']].item_name_to_id[item['item']]) else: item_code = item_table[item["item"]].item_code - if item['item'] == 'Single Arrow' and item['player'] == 0 and world.worlds[player].options.retro_bow: + if item['item'] == 'Single Arrow' and item['player'] == 0 and multiworld.worlds[player].options.retro_bow: rom.write_byte(0x186500 + shop.sram_offset + slot, arrow_mask) item_data = [shop_id, item_code] + price_data + \ @@ -1790,12 +1793,12 @@ def write_custom_shops(rom, world, player): items_data.extend([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) rom.write_bytes(0x184900, items_data) - if world.worlds[player].options.retro_bow: + if multiworld.worlds[player].options.retro_bow: retro_shop_slots.append(0xFF) rom.write_bytes(0x186540, retro_shop_slots) -def hud_format_text(text): +def hud_format_text(text: str): output = bytes() for char in text.lower(): if 'a' <= char <= 'z': @@ -1812,7 +1815,7 @@ def hud_format_text(text): output += b'\x7f\x00' return output[:32] -def apply_oof_sfx(rom, oof: str): +def apply_oof_sfx(rom: LocalRom, oof: str): with open(oof, 'rb') as stream: oof_bytes = bytearray(stream.read()) @@ -1862,9 +1865,10 @@ def apply_oof_sfx(rom, oof: str): rom.write_bytes(0x13000D, [0x00, 0x00, 0x00, 0x08]) -def apply_rom_settings(rom, beep, color, quickswap, menuspeed, music: bool, sprite: str, oof: str, palettes_options, - world=None, player=1, allow_random_on_event=False, reduceflashing=False, - triforcehud: str = None, deathlink: bool = False, allowcollect: bool = False): +def apply_rom_settings(rom: LocalRom, beep: str, color: str, quickswap: bool, menuspeed: str, music: bool, sprite: str, + oof: str, palettes_options: dict[str, str], world: "ALTTPWorld | None" = None, player: int = 1, + allow_random_on_event: bool = False, reduceflashing: bool = False, triforcehud: str = None, + deathlink: bool = False, allowcollect: bool = False): local_random = random if not world else world.worlds[player].random disable_music: bool = not music # enable instant item menu @@ -1948,7 +1952,7 @@ def apply_rom_settings(rom, beep, color, quickswap, menuspeed, music: bool, spri rom.write_byte(0x180167, triforce_flag) if z3pr: - def buildAndRandomize(option_name, mode): + def buildAndRandomize(option_name: str, mode: str): options = { option_name: True } @@ -2012,7 +2016,7 @@ def apply_rom_settings(rom, beep, color, quickswap, menuspeed, music: bool, spri rom.write_crc() -def restore_maseya_colors(rom, offsets_array): +def restore_maseya_colors(rom: LocalRom, offsets_array: list[list[int]]): if not rom.orig_buffer: return for offsetC in offsets_array: @@ -2020,7 +2024,7 @@ def restore_maseya_colors(rom, offsets_array): rom.write_bytes(address, rom.orig_buffer[address:address + 2]) -def set_color(rom, address, color, shade): +def set_color(rom: LocalRom, address: int, color: tuple[int, int, int], shade: int): r = round(min(color[0], 0xFF) * pow(0.8, shade) * 0x1F / 0xFF) g = round(min(color[1], 0xFF) * pow(0.8, shade) * 0x1F / 0xFF) b = round(min(color[2], 0xFF) * pow(0.8, shade) * 0x1F / 0xFF) @@ -2028,7 +2032,7 @@ def set_color(rom, address, color, shade): rom.write_bytes(address, ((b << 10) | (g << 5) | (r << 0)).to_bytes(2, byteorder='little', signed=False)) -def default_ow_palettes(rom): +def default_ow_palettes(rom: LocalRom): if not rom.orig_buffer: return rom.write_bytes(0xDE604, rom.orig_buffer[0xDE604:0xDEBB4]) @@ -2037,7 +2041,7 @@ def default_ow_palettes(rom): rom.write_bytes(address, rom.orig_buffer[address:address + 2]) -def randomize_ow_palettes(rom, local_random): +def randomize_ow_palettes(rom: LocalRom, local_random: random.Random): grass, grass2, grass3, dirt, dirt2, water, clouds, dwdirt, \ dwgrass, dwwater, dwdmdirt, dwdmgrass, dwdmclouds1, dwdmclouds2 = [[local_random.randint(60, 215) for _ in range(3)] for _ in range(14)] @@ -2113,7 +2117,7 @@ def randomize_ow_palettes(rom, local_random): set_color(rom, address, color, shade) -def blackout_ow_palettes(rom): +def blackout_ow_palettes(rom: LocalRom): rom.write_bytes(0xDE604, [0] * 0xC4) for i in range(0xDE6C8, 0xDE86C, 70): rom.write_bytes(i, [0] * 64) @@ -2124,13 +2128,13 @@ def blackout_ow_palettes(rom): rom.write_bytes(address, [0, 0]) -def default_uw_palettes(rom): +def default_uw_palettes(rom: LocalRom): if not rom.orig_buffer: return rom.write_bytes(0xDD734, rom.orig_buffer[0xDD734:0xDE544]) -def randomize_uw_palettes(rom, local_random): +def randomize_uw_palettes(rom: LocalRom, local_random: random.Random): for dungeon in range(20): wall, pot, chest, floor1, floor2, floor3 = [[local_random.randint(60, 240) for _ in range(3)] for _ in range(6)] @@ -2177,7 +2181,7 @@ def randomize_uw_palettes(rom, local_random): set_color(rom, 0x0DD796 + (0xB4 * dungeon), floor3, 4) -def blackout_uw_palettes(rom): +def blackout_uw_palettes(rom: LocalRom): for i in range(0xDD734, 0xDE544, 180): rom.write_bytes(i, [0] * 38) rom.write_bytes(i + 44, [0] * 76) @@ -2188,25 +2192,25 @@ def get_hash_string(hash): return ", ".join([hash_alphabet[code & 0x1F] for code in hash]) -def write_string_to_rom(rom, target, string): +def write_string_to_rom(rom: LocalRom, target: str, string: str): address, maxbytes = text_addresses[target] rom.write_bytes(address, MultiByteTextMapper.convert(string, maxbytes)) -def write_strings(rom, world, player): +def write_strings(rom: LocalRom, multiworld: MultiWorld, player: int): from . import ALTTPWorld - local_random = world.worlds[player].random - w: ALTTPWorld = world.worlds[player] + local_random = multiworld.worlds[player].random + w: ALTTPWorld = multiworld.worlds[player] tt = TextTable() tt.removeUnwantedText() # Let's keep this guy's text accurate to the shuffle setting. - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': tt['sign_village_of_outcasts'] = 'attention\nferal ducks sighted\nhiding in statues\n\nflute players beware\n' def hint_text(dest, ped_hint=False): @@ -2218,45 +2222,45 @@ def write_strings(rom, world, player): hint = dest.hint_text if dest.player != player: if ped_hint: - hint += f" for {world.player_name[dest.player]}!" + hint += f" for {multiworld.player_name[dest.player]}!" elif isinstance(dest, (Region, Location)): - hint += f" in {world.player_name[dest.player]}'s world" + hint += f" in {multiworld.player_name[dest.player]}'s world" else: - hint += f" for {world.player_name[dest.player]}" + hint += f" for {multiworld.player_name[dest.player]}" return hint - if world.worlds[player].options.scams.gives_king_zora_hint: + if multiworld.worlds[player].options.scams.gives_king_zora_hint: # Zora hint - zora_location = world.get_location("King Zora", player) + zora_location = multiworld.get_location("King Zora", player) tt['zora_tells_cost'] = f"You got 500 rupees to buy {hint_text(zora_location.item)}" \ f"\n ≥ Duh\n Oh carp\n{{CHOICE}}" - if world.worlds[player].options.scams.gives_bottle_merchant_hint: + if multiworld.worlds[player].options.scams.gives_bottle_merchant_hint: # Bottle Vendor hint - vendor_location = world.get_location("Bottle Merchant", player) + vendor_location = multiworld.get_location("Bottle Merchant", player) tt['bottle_vendor_choice'] = f"I gots {hint_text(vendor_location.item)}\nYous gots 100 rupees?" \ f"\n ≥ I want\n no way!\n{{CHOICE}}" # First we write hints about entrances, some from the inconvenient list others from all reasonable entrances. - if world.worlds[player].options.hints: - if world.worlds[player].options.hints.value >= 2: - if world.worlds[player].options.hints == "full": + if multiworld.worlds[player].options.hints: + if multiworld.worlds[player].options.hints.value >= 2: + if multiworld.worlds[player].options.hints == "full": tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles have hints!' else: tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles can have hints!' hint_locations = HintLocations.copy() local_random.shuffle(hint_locations) - all_entrances = list(world.get_entrances(player)) + all_entrances = list(multiworld.get_entrances(player)) local_random.shuffle(all_entrances) # First we take care of the one inconvenient dungeon in the appropriately simple shuffles. entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) - if world.shuffle_ganon: - if world.worlds[player].options.mode == 'inverted': + if multiworld.shuffle_ganon: + if multiworld.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) - if world.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: + if multiworld.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: for entrance in all_entrances: if entrance.name in entrances_to_hint: this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text( @@ -2266,9 +2270,9 @@ def write_strings(rom, world, player): break # Now we write inconvenient locations for most shuffles and finish taking care of the less chaotic ones. entrances_to_hint.update(InconvenientOtherEntrances) - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: hint_count = 0 - elif world.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: + elif multiworld.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: hint_count = 2 else: hint_count = 4 @@ -2285,31 +2289,31 @@ def write_strings(rom, world, player): # Next we handle hints for randomly selected other entrances, # curating the selection intelligently based on shuffle. - if world.worlds[player].options.entrance_shuffle not in ['simple', 'restricted']: + if multiworld.worlds[player].options.entrance_shuffle not in ['simple', 'restricted']: entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(DungeonEntrances) - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Agahnims Tower': 'The dark mountain tower'}) else: entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) - elif world.worlds[player].options.entrance_shuffle == 'restricted': + elif multiworld.worlds[player].options.entrance_shuffle == 'restricted': entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(OtherEntrances) - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'}) entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'}) entrances_to_hint.update({'Inverted Links House': 'The old hero\'s light home'}) else: entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) - if world.worlds[player].options.entrance_shuffle != 'insanity': + if multiworld.worlds[player].options.entrance_shuffle != 'insanity': entrances_to_hint.update(InsanityEntrances) - if world.shuffle_ganon: - if world.worlds[player].options.mode == 'inverted': + if multiworld.shuffle_ganon: + if multiworld.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'}) else: entrances_to_hint.update({'Pyramid Ledge': 'The pyramid ledge'}) - hint_count = 4 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 4 if multiworld.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 0 for entrance in all_entrances: if entrance.name in entrances_to_hint: @@ -2324,77 +2328,77 @@ def write_strings(rom, world, player): # Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable. locations_to_hint = InconvenientLocations.copy() - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: locations_to_hint.extend(InconvenientVanillaLocations) local_random.shuffle(locations_to_hint) - hint_count = 3 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 3 if multiworld.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 5 for location in locations_to_hint[:hint_count]: if location == 'Swamp Left': if local_random.randint(0, 1): - first_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item) - second_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item) + first_item = hint_text(multiworld.get_location('Swamp Palace - West Chest', player).item) + second_item = hint_text(multiworld.get_location('Swamp Palace - Big Key Chest', player).item) else: - second_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item) - first_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item) + second_item = hint_text(multiworld.get_location('Swamp Palace - West Chest', player).item) + first_item = hint_text(multiworld.get_location('Swamp Palace - Big Key Chest', player).item) this_hint = ('The westmost chests in Swamp Palace contain ' + first_item + ' and ' + second_item + '.') tt[hint_locations.pop(0)] = this_hint elif location == 'Mire Left': if local_random.randint(0, 1): - first_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item) - second_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item) + first_item = hint_text(multiworld.get_location('Misery Mire - Compass Chest', player).item) + second_item = hint_text(multiworld.get_location('Misery Mire - Big Key Chest', player).item) else: - second_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item) - first_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item) + second_item = hint_text(multiworld.get_location('Misery Mire - Compass Chest', player).item) + first_item = hint_text(multiworld.get_location('Misery Mire - Big Key Chest', player).item) this_hint = ('The westmost chests in Misery Mire contain ' + first_item + ' and ' + second_item + '.') tt[hint_locations.pop(0)] = this_hint elif location == 'Tower of Hera - Big Key Chest': this_hint = 'Waiting in the Tower of Hera basement leads to ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Ganons Tower - Big Chest': this_hint = 'The big chest in Ganon\'s Tower contains ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Thieves\' Town - Big Chest': this_hint = 'The big chest in Thieves\' Town contains ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Ice Palace - Big Chest': this_hint = 'The big chest in Ice Palace contains ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Eastern Palace - Big Key Chest': this_hint = 'The antifairy guarded chest in Eastern Palace contains ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Sahasrahla': this_hint = 'Sahasrahla seeks a green pendant for ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint elif location == 'Graveyard Cave': this_hint = 'The cave north of the graveyard contains ' + hint_text( - world.get_location(location, player).item) + '.' + multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint else: - this_hint = location + ' contains ' + hint_text(world.get_location(location, player).item) + '.' + this_hint = location + ' contains ' + hint_text(multiworld.get_location(location, player).item) + '.' tt[hint_locations.pop(0)] = this_hint # Lastly we write hints to show where certain interesting items are. items_to_hint = RelevantItems.copy() - if world.worlds[player].options.small_key_shuffle.hints_useful: + if multiworld.worlds[player].options.small_key_shuffle.hints_useful: items_to_hint |= item_name_groups["Small Keys"] - if world.worlds[player].options.big_key_shuffle.hints_useful: + if multiworld.worlds[player].options.big_key_shuffle.hints_useful: items_to_hint |= item_name_groups["Big Keys"] - if world.worlds[player].options.hints == "full": + if multiworld.worlds[player].options.hints == "full": hint_count = len(hint_locations) # fill all remaining hint locations with Item hints. else: - hint_count = 5 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 5 if multiworld.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 8 hint_count = min(hint_count, len(items_to_hint), len(hint_locations)) if hint_count: - locations = world.find_items_in_locations(items_to_hint, player, True) + locations = multiworld.find_items_in_locations(items_to_hint, player, True) local_random.shuffle(locations) # make locked locations less likely to appear as hint, # chances are the lock means the player already knows. @@ -2414,15 +2418,15 @@ def write_strings(rom, world, player): # We still need the older hints of course. Those are done here. - silverarrows = world.find_item_locations('Silver Bow', player, True) + silverarrows = multiworld.find_item_locations('Silver Bow', player, True) local_random.shuffle(silverarrows) silverarrow_hint = ( ' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!' tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint - if world.worlds[player].has_progressive_bows and (w.difficulty_requirements.progressive_bow_limit >= 2 or ( - world.worlds[player].options.swordless or world.worlds[player].options.glitches_required == 'no_glitches')): - prog_bow_locs = world.find_item_locations('Progressive Bow', player, True) + if multiworld.worlds[player].has_progressive_bows and (w.difficulty_requirements.progressive_bow_limit >= 2 or ( + multiworld.worlds[player].options.swordless or multiworld.worlds[player].options.glitches_required == 'no_glitches')): + prog_bow_locs = multiworld.find_item_locations('Progressive Bow', player, True) local_random.shuffle(prog_bow_locs) found_bow = False found_bow_alt = False @@ -2437,34 +2441,34 @@ def write_strings(rom, world, player): silverarrow_hint = (' %s?' % hint_text(bow_loc).replace('Ganon\'s', 'my')) tt[target] = 'Did you find the silver arrows%s' % silverarrow_hint - crystal5 = world.find_item('Crystal 5', player) - crystal6 = world.find_item('Crystal 6', player) + crystal5 = multiworld.find_item('Crystal 5', player) + crystal6 = multiworld.find_item('Crystal 6', player) tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % ( crystal5.hint_text, crystal6.hint_text) - greenpendant = world.find_item('Green Pendant', player) + greenpendant = multiworld.find_item('Green Pendant', player) tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant.hint_text - if world.worlds[player].options.crystals_needed_for_gt == 1: + if multiworld.worlds[player].options.crystals_needed_for_gt == 1: tt['sign_ganons_tower'] = 'You need a crystal to enter.' else: - tt['sign_ganons_tower'] = f'You need {world.worlds[player].options.crystals_needed_for_gt} crystals to enter.' + tt['sign_ganons_tower'] = f'You need {multiworld.worlds[player].options.crystals_needed_for_gt} crystals to enter.' - if world.worlds[player].options.goal == 'bosses': + if multiworld.worlds[player].options.goal == 'bosses': tt['sign_ganon'] = 'You need to kill all bosses, Ganon last.' - elif world.worlds[player].options.goal == 'ganon_pedestal': + elif multiworld.worlds[player].options.goal == 'ganon_pedestal': tt['sign_ganon'] = 'You need to pull the pedestal to defeat Ganon.' - elif world.worlds[player].options.goal == "ganon": - if world.worlds[player].options.crystals_needed_for_ganon == 1: + elif multiworld.worlds[player].options.goal == "ganon": + if multiworld.worlds[player].options.crystals_needed_for_ganon == 1: tt['sign_ganon'] = 'You need a crystal to beat Ganon and have beaten Agahnim atop Ganons Tower.' else: - tt['sign_ganon'] = f'You need {world.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon and ' \ + tt['sign_ganon'] = f'You need {multiworld.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon and ' \ f'have beaten Agahnim atop Ganons Tower' else: - if world.worlds[player].options.crystals_needed_for_ganon == 1: + if multiworld.worlds[player].options.crystals_needed_for_ganon == 1: tt['sign_ganon'] = 'You need a crystal to beat Ganon.' else: - tt['sign_ganon'] = f'You need {world.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon.' + tt['sign_ganon'] = f'You need {multiworld.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon.' tt['uncle_leaving_text'] = Uncle_texts[local_random.randint(0, len(Uncle_texts) - 1)] tt['end_triforce'] = "{NOBORDER}\n" + Triforce_texts[local_random.randint(0, len(Triforce_texts) - 1)] @@ -2475,12 +2479,12 @@ def write_strings(rom, world, player): tt['blind_by_the_light'] = Blind_texts[local_random.randint(0, len(Blind_texts) - 1)] triforce_pieces_required = max(0, w.treasure_hunt_required - - sum(1 for item in world.precollected_items[player] if item.name == "Triforce Piece")) + sum(1 for item in multiworld.precollected_items[player] if item.name == "Triforce Piece")) - if world.worlds[player].options.goal in ['triforce_hunt', 'local_triforce_hunt']: + if multiworld.worlds[player].options.goal in ['triforce_hunt', 'local_triforce_hunt']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' - if world.worlds[player].options.goal == 'triforce_hunt' and world.players > 1: + if multiworld.worlds[player].options.goal == 'triforce_hunt' and multiworld.players > 1: tt['sign_ganon'] = 'Go find the Triforce pieces with your friends... Ganon is invincible!' else: tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!' @@ -2494,7 +2498,7 @@ def write_strings(rom, world, player): "invisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\n" \ "hidden in a hollow tree. If you bring\n%d Triforce piece out of %d, I can reassemble it." % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.worlds[player].options.goal in ['pedestal']: + elif multiworld.worlds[player].options.goal in ['pedestal']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!' @@ -2503,44 +2507,44 @@ def write_strings(rom, world, player): tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!' tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!' if triforce_pieces_required > 1: - if world.worlds[player].options.goal == 'ganon_triforce_hunt' and world.players > 1: + if multiworld.worlds[player].options.goal == 'ganon_triforce_hunt' and multiworld.players > 1: tt['sign_ganon'] = 'You need to find %d Triforce pieces out of %d with your friends to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + elif multiworld.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: tt['sign_ganon'] = 'You need to find %d Triforce pieces out of %d to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) else: - if world.worlds[player].options.goal == 'ganon_triforce_hunt' and world.players > 1: + if multiworld.worlds[player].options.goal == 'ganon_triforce_hunt' and multiworld.players > 1: tt['sign_ganon'] = 'You need to find %d Triforce piece out of %d with your friends to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + elif multiworld.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: tt['sign_ganon'] = 'You need to find %d Triforce piece out of %d to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) tt['kakariko_tavern_fisherman'] = TavernMan_texts[local_random.randint(0, len(TavernMan_texts) - 1)] - pedestalitem = world.get_location('Master Sword Pedestal', player).item + pedestalitem = multiworld.get_location('Master Sword Pedestal', player).item pedestal_text = 'Some Hot Air' if pedestalitem is None else hint_text(pedestalitem, True) if pedestalitem.pedestal_hint_text is not None else 'Unknown Item' tt['mastersword_pedestal_translated'] = pedestal_text pedestal_credit_text = 'and the Hot Air' if pedestalitem is None else \ w.pedestal_credit_texts.get(pedestalitem.code, 'and the Unknown Item') - etheritem = world.get_location('Ether Tablet', player).item + etheritem = multiworld.get_location('Ether Tablet', player).item ether_text = 'Some Hot Air' if etheritem is None else hint_text(etheritem, True) if etheritem.pedestal_hint_text is not None else 'Unknown Item' tt['tablet_ether_book'] = ether_text - bombositem = world.get_location('Bombos Tablet', player).item + bombositem = multiworld.get_location('Bombos Tablet', player).item bombos_text = 'Some Hot Air' if bombositem is None else hint_text(bombositem, True) if bombositem.pedestal_hint_text is not None else 'Unknown Item' tt['tablet_bombos_book'] = bombos_text # inverted spawn menu changes - if world.worlds[player].options.mode == 'inverted': + if multiworld.worlds[player].options.mode == 'inverted': tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n{CHOICE3}" tt['menu_start_3'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n Mountain Cave\n{CHOICE2}" - for at, text, _ in world.worlds[player].options.plando_texts: + for at, text, _ in multiworld.worlds[player].options.plando_texts: if at not in tt: raise Exception(f"No text target \"{at}\" found.") @@ -2551,22 +2555,22 @@ def write_strings(rom, world, player): credits = Credits() - sickkiditem = world.get_location('Sick Kid', player).item + sickkiditem = multiworld.get_location('Sick Kid', player).item sickkiditem_text = local_random.choice(SickKid_texts) \ if sickkiditem is None or sickkiditem.code not in w.sickkid_credit_texts \ else w.sickkid_credit_texts[sickkiditem.code] - zoraitem = world.get_location('King Zora', player).item + zoraitem = multiworld.get_location('King Zora', player).item zoraitem_text = local_random.choice(Zora_texts) \ if zoraitem is None or zoraitem.code not in w.zora_credit_texts \ else w.zora_credit_texts[zoraitem.code] - magicshopitem = world.get_location('Potion Shop', player).item + magicshopitem = multiworld.get_location('Potion Shop', player).item magicshopitem_text = local_random.choice(MagicShop_texts) \ if magicshopitem is None or magicshopitem.code not in w.magicshop_credit_texts \ else w.magicshop_credit_texts[magicshopitem.code] - fluteboyitem = world.get_location('Flute Spot', player).item + fluteboyitem = multiworld.get_location('Flute Spot', player).item fluteboyitem_text = local_random.choice(FluteBoy_texts) \ if fluteboyitem is None or fluteboyitem.code not in w.fluteboy_credit_texts \ else w.fluteboy_credit_texts[fluteboyitem.code] @@ -2595,7 +2599,7 @@ def write_strings(rom, world, player): rom.write_bytes(0x76CC0, [byte for p in pointers for byte in [p & 0xFF, p >> 8 & 0xFF]]) -def set_inverted_mode(world, player, rom): +def set_inverted_mode(multiworld: MultiWorld, player: int, rom: LocalRom): rom.write_byte(snes_to_pc(0x0283E0), 0xF0) # residual portals rom.write_byte(snes_to_pc(0x02B34D), 0xF0) rom.write_byte(snes_to_pc(0x06DB78), 0x8B) @@ -2613,12 +2617,12 @@ def set_inverted_mode(world, player, rom): rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof # the following bytes should only be written in vanilla # or they'll overwrite the randomizer's shuffles - if world.worlds[player].options.entrance_shuffle == 'vanilla': + if multiworld.worlds[player].options.entrance_shuffle == 'vanilla': rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT rom.write_byte(0xDBB73 + 0x36, 0x24) rom.write_int16(0x15AEE + 2 * 0x38, 0x00E0) rom.write_int16(0x15AEE + 2 * 0x25, 0x000C) - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(0x15B8C, 0x6C) rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house rom.write_byte(0xDBB73 + 0x52, 0x01) @@ -2676,7 +2680,7 @@ def set_inverted_mode(world, player, rom): rom.write_int16(snes_to_pc(0x02D9A6), 0x005A) rom.write_byte(snes_to_pc(0x02D9B3), 0x12) # keep the old man spawn point at old man house unless shuffle is vanilla - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) rom.write_int16(snes_to_pc(0x02D8DE), 0x00F1) rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) @@ -2739,7 +2743,7 @@ def set_inverted_mode(world, player, rom): rom.write_int16s(snes_to_pc(0x1bb836), [0x001B, 0x001B, 0x001B]) rom.write_int16(snes_to_pc(0x308300), 0x0140) # new pyramid hole entrance rom.write_int16(snes_to_pc(0x308320), 0x001B) - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(snes_to_pc(0x308340), 0x7B) rom.write_int16(snes_to_pc(0x1af504), 0x148B) rom.write_int16(snes_to_pc(0x1af50c), 0x149B) @@ -2776,10 +2780,10 @@ def set_inverted_mode(world, player, rom): rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) rom.write_int16(0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door rom.write_int16(0xDBA71 + 2 * 0x35, 0x06A4) - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(0xDBB73 + 0x35, 0x36) rom.write_byte(snes_to_pc(0x09D436), 0xF3) # remove castle gate warp - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_int16(0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area rom.write_byte(0x15B8C + 0x37, 0x1B) rom.write_int16(0x15BDB + 2 * 0x37, 0x0418) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 18e2965d8c..bce75a157b 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -1,9 +1,9 @@ import collections import logging -from typing import Iterator, Set +from typing import Callable, Iterator, Set, TYPE_CHECKING from Options import ItemsAccessibility -from BaseClasses import MultiWorld +from BaseClasses import CollectionState, Item, Location, MultiWorld, Region from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item, item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items) @@ -21,112 +21,116 @@ from .StateHelpers import (can_extend_magic, can_kill_most_things, has_misery_mire_medallion, has_sword, has_turtle_rock_medallion, has_triforce_pieces, can_use_bombs, can_bomb_or_bonk, can_activate_crystal_switch, can_kill_standard_start) +from .SubClasses import ALttPLocation from .UnderworldGlitchRules import underworld_glitches_rules +if TYPE_CHECKING: + from . import ALTTPWorld -def set_rules(world): + +def set_rules(world: "ALTTPWorld"): player = world.player - world = world.multiworld - if world.worlds[player].options.glitches_required == 'no_logic': - if player == next(player_id for player_id in world.get_game_players("A Link to the Past") - if world.worlds[player_id].options.glitches_required == 'no_logic'): # only warn one time + multiworld = world.multiworld + if world.options.glitches_required == 'no_logic': + if player == next(player_id for player_id in multiworld.get_game_players("A Link to the Past") + if multiworld.worlds[player_id].options.glitches_required == 'no_logic'): # only warn one time logging.info( 'WARNING! Seeds generated under this logic often require major glitches and may be impossible!') - if world.players == 1: - for exit in world.get_region('Menu', player).exits: + if multiworld.players == 1: + for exit in multiworld.get_region('Menu', player).exits: exit.hide_path = True return else: # Set access rules according to max glitches for multiworld progression. # Set accessibility to none, and shuffle assuming the no logic players can always win - world.worlds[player].options.accessibility.value = ItemsAccessibility.option_minimal - world.worlds[player].options.progression_balancing.value = 0 + world.options.accessibility.value = ItemsAccessibility.option_minimal + world.options.progression_balancing.value = 0 else: - world.completion_condition[player] = lambda state: state.has('Triforce', player) + multiworld.completion_condition[player] = lambda state: state.has('Triforce', player) - dungeon_boss_rules(world, player) - global_rules(world, player) + dungeon_boss_rules(multiworld, player) + global_rules(multiworld, player) - if world.worlds[player].options.mode != 'inverted': - default_rules(world, player) + if world.options.mode != 'inverted': + default_rules(multiworld, player) - if world.worlds[player].options.mode == 'open': - open_rules(world, player) - elif world.worlds[player].options.mode == 'standard': - standard_rules(world, player) - elif world.worlds[player].options.mode == 'inverted': - open_rules(world, player) - inverted_rules(world, player) + if world.options.mode == 'open': + open_rules(multiworld, player) + elif world.options.mode == 'standard': + standard_rules(multiworld, player) + elif world.options.mode == 'inverted': + open_rules(multiworld, player) + inverted_rules(multiworld, player) else: - raise NotImplementedError(f'World state {world.worlds[player].options.mode} is not implemented yet') + raise NotImplementedError(f'World state {world.options.mode} is not implemented yet') - if world.worlds[player].options.glitches_required == 'no_glitches': - no_glitches_rules(world, player) - forbid_bomb_jump_requirements(world, player) - elif world.worlds[player].options.glitches_required == 'overworld_glitches': + if world.options.glitches_required == 'no_glitches': + no_glitches_rules(multiworld, player) + forbid_bomb_jump_requirements(multiworld, player) + elif world.options.glitches_required == 'overworld_glitches': # Initially setting no_glitches_rules to set the baseline rules for some # entrances. The overworld_glitches_rules set is primarily additive. - no_glitches_rules(world, player) - fake_flipper_rules(world, player) - overworld_glitches_rules(world, player) - forbid_bomb_jump_requirements(world, player) - elif world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: - no_glitches_rules(world, player) - fake_flipper_rules(world, player) - overworld_glitches_rules(world, player) - underworld_glitches_rules(world, player) - bomb_jump_requirements(world, player) - elif world.worlds[player].options.glitches_required == 'minor_glitches': - no_glitches_rules(world, player) - fake_flipper_rules(world, player) - forbid_bomb_jump_requirements(world, player) + no_glitches_rules(multiworld, player) + fake_flipper_rules(multiworld, player) + overworld_glitches_rules(multiworld, player) + forbid_bomb_jump_requirements(multiworld, player) + elif world.options.glitches_required in ['hybrid_major_glitches', 'no_logic']: + no_glitches_rules(multiworld, player) + fake_flipper_rules(multiworld, player) + overworld_glitches_rules(multiworld, player) + underworld_glitches_rules(multiworld, player) + bomb_jump_requirements(multiworld, player) + elif world.options.glitches_required == 'minor_glitches': + no_glitches_rules(multiworld, player) + fake_flipper_rules(multiworld, player) + forbid_bomb_jump_requirements(multiworld, player) else: - raise NotImplementedError(f'Not implemented yet: Logic - {world.worlds[player].options.glitches_required}') + raise NotImplementedError(f'Not implemented yet: Logic - {world.options.glitches_required}') - if world.worlds[player].options.goal == 'bosses': + if world.options.goal == 'bosses': # require all bosses to beat ganon - add_rule(world.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player) and state.has('Beat Agahnim 1', player) and state.has('Beat Agahnim 2', player) and has_crystals(state, 7, player)) - elif world.worlds[player].options.goal == 'ganon': + add_rule(multiworld.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player) and state.has('Beat Agahnim 1', player) and state.has('Beat Agahnim 2', player) and has_crystals(state, 7, player)) + elif world.options.goal == 'ganon': # require aga2 to beat ganon - add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) + add_rule(multiworld.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) - if world.worlds[player].options.mode != 'inverted': - set_big_bomb_rules(world, player) - if world.worlds[player].options.glitches_required.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.worlds[player].options.entrance_shuffle.current_key not in {'insanity', 'insanity_legacy', 'madness'}: - path_to_courtyard = mirrorless_path_to_castle_courtyard(world, player) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.multiworld.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard), 'or') + if world.options.mode != 'inverted': + set_big_bomb_rules(multiworld, player) + if world.options.glitches_required.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.options.entrance_shuffle.current_key not in {'insanity', 'insanity_legacy', 'madness'}: + path_to_courtyard = mirrorless_path_to_castle_courtyard(multiworld, player) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.multiworld.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard), 'or') else: - set_inverted_big_bomb_rules(world, player) + set_inverted_big_bomb_rules(multiworld, player) # if swamp and dam have not been moved we require mirror for swamp palace # however there is mirrorless swamp in hybrid MG, so we don't necessarily want this. HMG handles this requirement itself. - if not world.worlds[player].swamp_patch_required and world.worlds[player].options.glitches_required not in ['hybrid_major_glitches', 'no_logic']: - add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player)) + if not multiworld.worlds[player].swamp_patch_required and world.options.glitches_required not in ['hybrid_major_glitches', 'no_logic']: + add_rule(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player)) # GT Entrance may be required for Turtle Rock for OWG and < 7 required - ganons_tower = world.get_entrance('Inverted Ganons Tower' if world.worlds[player].options.mode == 'inverted' else 'Ganons Tower', player) - if (world.worlds[player].options.crystals_needed_for_gt == 7 - and not (world.worlds[player].options.glitches_required + ganons_tower = multiworld.get_entrance('Inverted Ganons Tower' if world.options.mode == 'inverted' else 'Ganons Tower', player) + if (world.options.crystals_needed_for_gt == 7 + and not (world.options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic'] - and world.worlds[player].options.mode != 'inverted')): + and world.options.mode != 'inverted')): set_rule(ganons_tower, lambda state: False) - set_trock_key_rules(world, player) + set_trock_key_rules(multiworld, player) - set_rule(ganons_tower, lambda state: has_crystals(state, state.multiworld.worlds[player].options.crystals_needed_for_gt, player)) - if world.worlds[player].options.mode != 'inverted' and world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: - add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.multiworld.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or') + set_rule(ganons_tower, lambda state: has_crystals(state, world.options.crystals_needed_for_gt.value, player)) + if world.options.mode != 'inverted' and world.options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + add_rule(multiworld.get_entrance('Ganons Tower', player), lambda state: state.multiworld.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or') - set_bunny_rules(world, player, world.worlds[player].options.mode == 'inverted') + set_bunny_rules(multiworld, player, world.options.mode == 'inverted') -def mirrorless_path_to_castle_courtyard(world, player): +def mirrorless_path_to_castle_courtyard(multiworld: MultiWorld, player: int): # If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch. # Only considering the secret passage for now (in non-insanity shuffle). Basically, if it's Ganon you need the master sword. - start = world.get_entrance('Hyrule Castle Secret Entrance Drop', player) - target = world.get_region('Hyrule Castle Courtyard', player) + start = multiworld.get_entrance('Hyrule Castle Secret Entrance Drop', player) + target = multiworld.get_region('Hyrule Castle Courtyard', player) seen = {start.parent_region, start.connected_region} queue = collections.deque([(start.connected_region, [])]) while queue: @@ -139,37 +143,37 @@ def mirrorless_path_to_castle_courtyard(world, player): else: queue.append((entrance.connected_region, new_path)) - raise Exception(f"Could not find mirrorless path to castle courtyard for Player {player} ({world.get_player_name(player)})") + raise Exception(f"Could not find mirrorless path to castle courtyard for Player {player} ({multiworld.get_player_name(player)})") -def set_defeat_dungeon_boss_rule(location): +def set_defeat_dungeon_boss_rule(location: ALttPLocation): # Lambda required to defer evaluation of dungeon.boss since it will change later if boss shuffle is used add_rule(location, lambda state: location.parent_region.dungeon.boss.can_defeat(state)) -def set_always_allow(spot, rule): +def set_always_allow(spot: Location, rule: Callable[[CollectionState, Item], bool]): spot.always_allow = rule -def add_lamp_requirement(world: MultiWorld, spot, player: int, has_accessible_torch: bool = False): - if world.worlds[player].options.dark_room_logic == "lamp": +def add_lamp_requirement(multiworld: MultiWorld, spot, player: int, has_accessible_torch: bool = False): + if multiworld.worlds[player].options.dark_room_logic == "lamp": add_rule(spot, lambda state: state.has('Lamp', player)) - elif world.worlds[player].options.dark_room_logic == "torches": # implicitly lamp as well + elif multiworld.worlds[player].options.dark_room_logic == "torches": # implicitly lamp as well if has_accessible_torch: add_rule(spot, lambda state: state.has('Lamp', player) or state.has('Fire Rod', player)) else: add_rule(spot, lambda state: state.has('Lamp', player)) - elif world.worlds[player].options.dark_room_logic == "none": + elif multiworld.worlds[player].options.dark_room_logic == "none": pass else: - raise ValueError(f"Unknown Dark Room Logic: {world.worlds[player].options.dark_room_logic}") + raise ValueError(f"Unknown Dark Room Logic: {multiworld.worlds[player].options.dark_room_logic}") non_crossover_items = (item_name_groups["Small Keys"] | item_name_groups["Big Keys"] | progression_items) - { "Small Key (Universal)"} -def dungeon_boss_rules(world, player): +def dungeon_boss_rules(multiworld: MultiWorld, player: int): boss_locations = { 'Agahnim 1', 'Tower of Hera - Boss', @@ -190,7 +194,7 @@ def dungeon_boss_rules(world, player): 'Palace of Darkness - Prize', } for location in boss_locations: - set_defeat_dungeon_boss_rule(world.get_location(location, player)) + set_defeat_dungeon_boss_rule(multiworld.get_location(location, player)) def global_rules(multiworld: MultiWorld, player: int): @@ -616,330 +620,332 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Flute Activation Spot', player), lambda state: state.has('Flute', player)) -def default_rules(world, player): +def default_rules(multiworld: MultiWorld, player: int): """Default world rules when world state is not inverted.""" # overworld requirements - set_rule(world.get_entrance('Light World Bomb Hut', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Light Hype Fairy', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Mini Moldorm Cave', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Ice Rod Cave', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Light World Bomb Hut', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Light Hype Fairy', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Mini Moldorm Cave', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Ice Rod Cave', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Kings Grave', player), lambda state: state.has('Pegasus Boots', player)) - set_rule(world.get_entrance('Kings Grave Outer Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Kings Grave Inner Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Kings Grave', player), lambda state: state.has('Pegasus Boots', player)) + set_rule(multiworld.get_entrance('Kings Grave Outer Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Kings Grave Inner Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) # Caution: If king's grave is releaxed at all to account for reaching it via a two way cave's exit in insanity mode, then the bomb shop logic will need to be updated (that would involve create a small ledge-like Region for it) - set_rule(world.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has('Pegasus Boots', player)) - set_rule(world.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has('Pegasus Boots', player) and state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Bonk Rock Cave', player), lambda state: state.has('Pegasus Boots', player)) - set_rule(world.get_entrance('Desert Palace Stairs', player), lambda state: state.has('Book of Mudora', player)) - set_rule(world.get_entrance('Sanctuary Grave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('20 Rupee Cave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer - set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer - set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and can_lift_rocks(state, player)) or can_lift_heavy_rocks(state, player)) and state.has('Moon Pearl', player)) # bunny cannot lift bushes - set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player)) - set_rule(world.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has('Pegasus Boots', player)) + set_rule(multiworld.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has('Pegasus Boots', player) and state.has('Beat Agahnim 1', player)) + set_rule(multiworld.get_entrance('Bonk Rock Cave', player), lambda state: state.has('Pegasus Boots', player)) + set_rule(multiworld.get_entrance('Desert Palace Stairs', player), lambda state: state.has('Book of Mudora', player)) + set_rule(multiworld.get_entrance('Sanctuary Grave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('20 Rupee Cave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('50 Rupee Cave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Death Mountain Entrance Rock', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Flute Spot 1', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer + set_rule(multiworld.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer + set_rule(multiworld.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and can_lift_rocks(state, player)) or can_lift_heavy_rocks(state, player)) and state.has('Moon Pearl', player)) # bunny cannot lift bushes + set_rule(multiworld.get_location('Flute Spot', player), lambda state: state.has('Shovel', player)) + set_rule(multiworld.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_location('Frog', player), lambda state: can_lift_heavy_rocks(state, player)) # will get automatic moon pearl requirement - set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player)) - set_rule(world.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Desert Ledge Return Rocks', player), lambda state: can_lift_rocks(state, player)) # should we decide to place something that is not a dungeon end up there at some point - set_rule(world.get_entrance('Checkerboard Cave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or has_beam_sword(state, player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle - set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Old Man Cave Exit (West)', player), lambda state: False) # drop cannot be climbed up - set_rule(world.get_entrance('Broken Bridge (West)', player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('Broken Bridge (East)', player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('East Death Mountain Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Fairy Ascension Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: state.has('Mirror', player)) # can erase block - set_rule(world.get_entrance('Death Mountain (Top)', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) - set_rule(world.get_entrance('East Death Mountain (Top)', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_location('Frog', player), lambda state: can_lift_heavy_rocks(state, player)) # will get automatic moon pearl requirement + set_rule(multiworld.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player)) + set_rule(multiworld.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Desert Ledge Return Rocks', player), lambda state: can_lift_rocks(state, player)) # should we decide to place something that is not a dungeon end up there at some point + set_rule(multiworld.get_entrance('Checkerboard Cave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or has_beam_sword(state, player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle + set_rule(multiworld.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player)) + set_rule(multiworld.get_entrance('Old Man Cave Exit (West)', player), lambda state: False) # drop cannot be climbed up + set_rule(multiworld.get_entrance('Broken Bridge (West)', player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Broken Bridge (East)', player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('East Death Mountain Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Fairy Ascension Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: state.has('Mirror', player)) # can erase block + set_rule(multiworld.get_entrance('Death Mountain (Top)', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Turtle Rock Teleporter', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) + set_rule(multiworld.get_entrance('East Death Mountain (Top)', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Catfish Exit Rock', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Catfish Entrance Rock', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Northeast Dark World Broken Bridge Pass', player), lambda state: state.has('Moon Pearl', player) and (can_lift_rocks(state, player) or state.has('Hammer', player) or state.has('Flippers', player))) - set_rule(world.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: state.has('Moon Pearl', player) and (can_lift_rocks(state, player) or state.has('Hammer', player))) - set_rule(world.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has('Moon Pearl', player) and state.has('Pegasus Boots', player)) - set_rule(world.get_entrance('West Dark World Gap', player), lambda state: state.has('Moon Pearl', player) and state.has('Hookshot', player)) - set_rule(world.get_entrance('Palace of Darkness', player), lambda state: state.has('Moon Pearl', player)) # kiki needs pearl - set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Hyrule Castle Main Gate', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: (state.has('Moon Pearl', player) and state.has('Flippers', player) or state.has('Magic Mirror', player))) # Overworld Bunny Revival - set_rule(world.get_location('Bombos Tablet', player), lambda state: can_retrieve_tablet(state, player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # ToDo any fake flipper set up? - set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Hype Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Brewery', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Thieves Town', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot pull - set_rule(world.get_entrance('Skull Woods First Section Hole (North)', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot lift bush - set_rule(world.get_entrance('Skull Woods Second Section Hole', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot lift bush - set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Bombos Tablet Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('East Dark World Bridge', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) - set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Bumper Cave Entrance Rock', player), lambda state: state.has('Moon Pearl', player) and can_lift_rocks(state, player)) - set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark World Hammer Peg Cave', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) - set_rule(world.get_entrance('Village of Outcasts Eastern Rocks', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Peg Area Rocks', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Village of Outcasts Pegs', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) - set_rule(world.get_entrance('Grassy Lawn Pegs', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Top)', player), lambda state: state.has('Cape', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Bottom)', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Catfish Exit Rock', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Catfish Entrance Rock', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Northeast Dark World Broken Bridge Pass', player), lambda state: state.has('Moon Pearl', player) and (can_lift_rocks(state, player) or state.has('Hammer', player) or state.has('Flippers', player))) + set_rule(multiworld.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: state.has('Moon Pearl', player) and (can_lift_rocks(state, player) or state.has('Hammer', player))) + set_rule(multiworld.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has('Moon Pearl', player) and state.has('Pegasus Boots', player)) + set_rule(multiworld.get_entrance('West Dark World Gap', player), lambda state: state.has('Moon Pearl', player) and state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Palace of Darkness', player), lambda state: state.has('Moon Pearl', player)) # kiki needs pearl + set_rule(multiworld.get_entrance('Hyrule Castle Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Hyrule Castle Main Gate', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: (state.has('Moon Pearl', player) and state.has('Flippers', player) or state.has('Magic Mirror', player))) # Overworld Bunny Revival + set_rule(multiworld.get_location('Bombos Tablet', player), lambda state: can_retrieve_tablet(state, player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # ToDo any fake flipper set up? + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Hype Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Brewery', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Thieves Town', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot pull + set_rule(multiworld.get_entrance('Skull Woods First Section Hole (North)', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot lift bush + set_rule(multiworld.get_entrance('Skull Woods Second Section Hole', player), lambda state: state.has('Moon Pearl', player)) # bunny cannot lift bush + set_rule(multiworld.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Bombos Tablet Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('East Dark World Bridge', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('East Dark World River Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Bumper Cave Entrance Rock', player), lambda state: state.has('Moon Pearl', player) and can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Bat Cave Drop Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark World Hammer Peg Cave', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Village of Outcasts Eastern Rocks', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Peg Area Rocks', player), lambda state: state.has('Moon Pearl', player) and can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Village of Outcasts Pegs', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Grassy Lawn Pegs', player), lambda state: state.has('Moon Pearl', player) and state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Bumper Cave Exit (Top)', player), lambda state: state.has('Cape', player)) + set_rule(multiworld.get_entrance('Bumper Cave Exit (Bottom)', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) - set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player) and state.has('Moon Pearl', player)) # bunny cannot use fire rod - set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has('Moon Pearl', player) and has_sword(state, player) and has_misery_mire_medallion(state, player)) # sword required to cast magic (!) - set_rule(world.get_entrance('Desert Ledge (Northeast) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player) and state.has('Moon Pearl', player)) # bunny cannot use fire rod + set_rule(multiworld.get_entrance('Misery Mire', player), lambda state: state.has('Moon Pearl', player) and has_sword(state, player) and has_misery_mire_medallion(state, player)) # sword required to cast magic (!) + set_rule(multiworld.get_entrance('Desert Ledge (Northeast) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Desert Palace Entrance (North) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Hookshot Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Desert Palace Stairs Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Desert Palace Entrance (North) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Hookshot Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('East Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Spiral Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Fairy Ascension Mirror Spot', player), lambda state: state.has('Magic Mirror', player) and state.has('Moon Pearl', player)) # need to lift flowers - set_rule(world.get_entrance('Isolated Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)', player), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling - set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_sword(state, player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) + set_rule(multiworld.get_entrance('East Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Spiral Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Fairy Ascension Mirror Spot', player), lambda state: state.has('Magic Mirror', player) and state.has('Moon Pearl', player)) # need to lift flowers + set_rule(multiworld.get_entrance('Isolated Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Superbunny Cave Exit (Bottom)', player), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling + set_rule(multiworld.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_sword(state, player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) - set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.worlds[player].options.open_pyramid.to_bool(world, player)) + set_rule(multiworld.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or multiworld.worlds[player].options.open_pyramid.to_bool(multiworld, player)) - if world.worlds[player].options.swordless: - swordless_rules(world, player) + if multiworld.worlds[player].options.swordless: + swordless_rules(multiworld, player) -def inverted_rules(world, player): +def inverted_rules(multiworld: MultiWorld, player: int): # s&q regions. - set_rule(world.get_entrance('Castle Ledge S&Q', player), lambda state: state.has('Magic Mirror', player) and state.has('Beat Agahnim 1', player)) + set_rule(multiworld.get_entrance('Castle Ledge S&Q', player), lambda state: state.has('Magic Mirror', player) and state.has('Beat Agahnim 1', player)) # overworld requirements - set_rule(world.get_location('Maze Race', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Mini Moldorm Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Ice Rod Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Light Hype Fairy', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('Potion Shop Pier', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Light World Pier', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Kings Grave', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Kings Grave Outer Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Kings Grave Inner Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Potion Shop Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Potion Shop Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Potion Shop Outer Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Potion Shop Inner Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Graveyard Cave Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Graveyard Cave Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Secret Passage Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Secret Passage Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player) and state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Bonk Rock Cave', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Desert Palace Stairs', player), lambda state: state.has('Book of Mudora', player)) # bunny can use book - set_rule(world.get_entrance('Sanctuary Grave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('20 Rupee Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer - set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer - set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and can_lift_rocks(state, player)) or can_lift_heavy_rocks(state, player)) and state.has('Moon Pearl', player)) - set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_location('Maze Race', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Mini Moldorm Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Ice Rod Cave', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Light Hype Fairy', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Potion Shop Pier', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Light World Pier', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Kings Grave', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Kings Grave Outer Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Kings Grave Inner Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Potion Shop Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Potion Shop Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Potion Shop Outer Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Potion Shop Inner Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Graveyard Cave Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Graveyard Cave Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Secret Passage Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Secret Passage Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player) and state.has('Beat Agahnim 1', player)) + set_rule(multiworld.get_entrance('Bonk Rock Cave', player), lambda state: state.has('Pegasus Boots', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Desert Palace Stairs', player), lambda state: state.has('Book of Mudora', player)) # bunny can use book + set_rule(multiworld.get_entrance('Sanctuary Grave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('20 Rupee Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('50 Rupee Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Death Mountain Entrance Rock', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer + set_rule(multiworld.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # bunny cannot use hammer + set_rule(multiworld.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and can_lift_rocks(state, player)) or can_lift_heavy_rocks(state, player)) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_location('Flute Spot', player), lambda state: state.has('Shovel', player) and state.has('Moon Pearl', player)) - set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Waterfall of Wishing Cave', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Northeast Light World Return', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) - set_rule(world.get_location('Frog', player), lambda state: can_lift_heavy_rocks(state, player) and (state.has('Moon Pearl', player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player) and state.has('Magic Mirror', player))) # Need LW access using Mirror or Portal - set_rule(world.get_location('Missing Smith', player), lambda state: state.has('Get Frog', player) and state.can_reach('Blacksmiths Hut', 'Region', player)) # Can't S&Q with smith - set_rule(world.get_location('Blacksmith', player), lambda state: state.has('Return Smith', player)) - set_rule(world.get_location('Magic Bat', player), lambda state: state.has('Magic Powder', player) and state.has('Moon Pearl', player)) - set_rule(world.get_location('Sick Kid', player), lambda state: state.has_group("Bottles", player)) - set_rule(world.get_location('Mushroom', player), lambda state: state.has('Moon Pearl', player)) # need pearl to pick up bushes - set_rule(world.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bush Covered Lawn Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bomb Hut Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Bomb Hut Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Light World Bomb Hut', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) - set_rule(world.get_entrance('North Fairy Cave Drop', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Lost Woods Hideout Drop', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player) and (state.can_reach('Potion Shop Area', 'Region', player))) # new inverted region, need pearl for bushes or access to potion shop door/waterfall fairy - set_rule(world.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Desert Ledge Return Rocks', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # should we decide to place something that is not a dungeon end up there at some point - set_rule(world.get_entrance('Checkerboard Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Hyrule Castle Secret Entrance Drop', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Old Man Cave Exit (West)', player), lambda state: False) # drop cannot be climbed up - set_rule(world.get_entrance('Broken Bridge (West)', player), lambda state: state.has('Hookshot', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Broken Bridge (East)', player), lambda state: state.has('Hookshot', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Dark Death Mountain Teleporter (East Bottom)', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Fairy Ascension Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: state.has('Mirror', player)) # can erase block - set_rule(world.get_entrance('Death Mountain (Top)', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Hammer', player) and state.has('Moon Pearl', player)) # bunny cannot use hammer - set_rule(world.get_entrance('East Death Mountain (Top)', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) # bunny can not use hammer + set_rule(multiworld.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Waterfall of Wishing Cave', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Northeast Light World Return', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_location('Frog', player), lambda state: can_lift_heavy_rocks(state, player) and (state.has('Moon Pearl', player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player) and state.has('Magic Mirror', player))) # Need LW access using Mirror or Portal + set_rule(multiworld.get_location('Missing Smith', player), lambda state: state.has('Get Frog', player) and state.can_reach('Blacksmiths Hut', 'Region', player)) # Can't S&Q with smith + set_rule(multiworld.get_location('Blacksmith', player), lambda state: state.has('Return Smith', player)) + set_rule(multiworld.get_location('Magic Bat', player), lambda state: state.has('Magic Powder', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_location('Sick Kid', player), lambda state: state.has_group("Bottles", player)) + set_rule(multiworld.get_location('Mushroom', player), lambda state: state.has('Moon Pearl', player)) # need pearl to pick up bushes + set_rule(multiworld.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bush Covered Lawn Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bomb Hut Inner Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Bomb Hut Outer Bushes', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Light World Bomb Hut', player), lambda state: state.has('Moon Pearl', player) and can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('North Fairy Cave Drop', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Lost Woods Hideout Drop', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player) and (state.can_reach('Potion Shop Area', 'Region', player))) # new inverted region, need pearl for bushes or access to potion shop door/waterfall fairy + set_rule(multiworld.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Desert Ledge Return Rocks', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) # should we decide to place something that is not a dungeon end up there at some point + set_rule(multiworld.get_entrance('Checkerboard Cave', player), lambda state: can_lift_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Hyrule Castle Secret Entrance Drop', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Old Man Cave Exit (West)', player), lambda state: False) # drop cannot be climbed up + set_rule(multiworld.get_entrance('Broken Bridge (West)', player), lambda state: state.has('Hookshot', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Broken Bridge (East)', player), lambda state: state.has('Hookshot', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Dark Death Mountain Teleporter (East Bottom)', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Fairy Ascension Rocks', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: state.has('Mirror', player)) # can erase block + set_rule(multiworld.get_entrance('Death Mountain (Top)', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: can_lift_heavy_rocks(state, player) and state.has('Hammer', player) and state.has('Moon Pearl', player)) # bunny cannot use hammer + set_rule(multiworld.get_entrance('East Death Mountain (Top)', player), lambda state: state.has('Hammer', player) and state.has('Moon Pearl', player)) # bunny can not use hammer - set_rule(world.get_entrance('Catfish Entrance Rock', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Northeast Dark World Broken Bridge Pass', player), lambda state: ((can_lift_rocks(state, player) or state.has('Hammer', player)) or state.has('Flippers', player))) - set_rule(world.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: (can_lift_rocks(state, player) or state.has('Hammer', player))) - set_rule(world.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has('Pegasus Boots', player)) - set_rule(world.get_entrance('West Dark World Gap', player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_location('Bombos Tablet', player), lambda state: can_retrieve_tablet(state, player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has('Flippers', player)) # ToDo any fake flipper set up? - set_rule(world.get_entrance('Dark Lake Hylia Ledge Pier', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player)) # Fake Flippers - set_rule(world.get_entrance('Dark Lake Hylia Shallows', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('East Dark World Bridge', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Bumper Cave Entrance Rock', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Hammer Peg Area Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark World Hammer Peg Cave', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Village of Outcasts Eastern Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Peg Area Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) - set_rule(world.get_entrance('Village of Outcasts Pegs', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Grassy Lawn Pegs', player), lambda state: state.has('Hammer', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Top)', player), lambda state: state.has('Cape', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Bottom)', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Catfish Entrance Rock', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Northeast Dark World Broken Bridge Pass', player), lambda state: ((can_lift_rocks(state, player) or state.has('Hammer', player)) or state.has('Flippers', player))) + set_rule(multiworld.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: (can_lift_rocks(state, player) or state.has('Hammer', player))) + set_rule(multiworld.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has('Pegasus Boots', player)) + set_rule(multiworld.get_entrance('West Dark World Gap', player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_location('Bombos Tablet', player), lambda state: can_retrieve_tablet(state, player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has('Flippers', player)) # ToDo any fake flipper set up? + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Pier', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player)) # Fake Flippers + set_rule(multiworld.get_entrance('Dark Lake Hylia Shallows', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('East Dark World Bridge', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('East Dark World River Pier', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Bumper Cave Entrance Rock', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Hammer Peg Area Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark World Hammer Peg Cave', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Village of Outcasts Eastern Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Peg Area Rocks', player), lambda state: can_lift_heavy_rocks(state, player)) + set_rule(multiworld.get_entrance('Village of Outcasts Pegs', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Grassy Lawn Pegs', player), lambda state: state.has('Hammer', player)) + set_rule(multiworld.get_entrance('Bumper Cave Exit (Top)', player), lambda state: state.has('Cape', player)) + set_rule(multiworld.get_entrance('Bumper Cave Exit (Bottom)', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) - set_rule(world.get_entrance('Hype Cave', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Brewery', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Hype Cave', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Brewery', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: can_use_bombs(state, player)) - set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player)) - set_rule(world.get_entrance('Misery Mire', player), lambda state: has_sword(state, player) and has_misery_mire_medallion(state, player)) # sword required to cast magic (!) + set_rule(multiworld.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player)) + set_rule(multiworld.get_entrance('Misery Mire', player), lambda state: has_sword(state, player) and has_misery_mire_medallion(state, player)) # sword required to cast magic (!) - set_rule(world.get_entrance('Hookshot Cave', player), lambda state: can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Hookshot Cave', player), lambda state: can_lift_rocks(state, player)) - set_rule(world.get_entrance('East Death Mountain Mirror Spot (Top)', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('East Death Mountain Mirror Spot (Top)', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('East Death Mountain Mirror Spot (Bottom)', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (East)', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (West)', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Laser Bridge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Turtle Rock', player), lambda state: has_sword(state, player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) + set_rule(multiworld.get_entrance('East Death Mountain Mirror Spot (Bottom)', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark Death Mountain Ledge Mirror Spot (East)', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Dark Death Mountain Ledge Mirror Spot (West)', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Laser Bridge Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Turtle Rock', player), lambda state: has_sword(state, player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) # new inverted spots - set_rule(world.get_entrance('Post Aga Teleporter', player), lambda state: state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Mire Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Death Mountain Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('East Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('West Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('South Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Desert Palace North Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Graveyard Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Bomb Hut Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) - set_rule(world.get_entrance('Skull Woods Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Post Aga Teleporter', player), lambda state: state.has('Beat Agahnim 1', player)) + set_rule(multiworld.get_entrance('Mire Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Desert Palace Stairs Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Death Mountain Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('East Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('West Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('South Dark World Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Catfish Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Desert Palace North Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Graveyard Cave Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Bomb Hut Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) + set_rule(multiworld.get_entrance('Skull Woods Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) # inverted flute spots - set_rule(world.get_entrance('DDM Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('NEDW Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('WDW Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('SDW Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('EDW Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('DLHL Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('DD Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('EDDM Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('DDM Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('NEDW Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('WDW Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('SDW Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('EDW Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('DLHL Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('DD Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('EDDM Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.has('Activated Flute', player)) + set_rule(multiworld.get_entrance('Hammer Peg Area Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.worlds[player].options.open_pyramid) + set_rule(multiworld.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or multiworld.worlds[player].options.open_pyramid) - if world.worlds[player].options.swordless: - swordless_rules(world, player) + if multiworld.worlds[player].options.swordless: + swordless_rules(multiworld, player) -def no_glitches_rules(world, player): + +def no_glitches_rules(multiworld: MultiWorld, player: int): """""" - if world.worlds[player].options.mode == 'inverted': - set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player) and (state.has('Flippers', player) or can_lift_rocks(state, player))) - set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to - set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to - set_rule(world.get_entrance('Lake Hylia Warp', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to - set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to - set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('East Dark World Pier', player), lambda state: state.has('Flippers', player)) + if multiworld.worlds[player].options.mode == 'inverted': + set_rule(multiworld.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player) and (state.has('Flippers', player) or can_lift_rocks(state, player))) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to + set_rule(multiworld.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to + set_rule(multiworld.get_entrance('Lake Hylia Warp', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to + set_rule(multiworld.get_entrance('Northeast Light World Warp', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to + set_rule(multiworld.get_entrance('Hobo Bridge', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('East Dark World Pier', player), lambda state: state.has('Flippers', player)) else: - set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Flippers', player) or can_lift_rocks(state, player)) - set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Flippers', player)) # can be fake flippered to - set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Zoras River', player), lambda state: state.has('Flippers', player) or can_lift_rocks(state, player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Flippers', player)) # can be fake flippered to + set_rule(multiworld.get_entrance('Hobo Bridge', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - add_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override - add_conditional_lamps(world, player) + add_rule(multiworld.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override + add_conditional_lamps(multiworld, player) -def fake_flipper_rules(world, player): - if world.worlds[player].options.mode == 'inverted': - set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Lake Hylia Warp', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: True) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: True) - set_rule(world.get_entrance('East Dark World Pier', player), lambda state: True) + +def fake_flipper_rules(multiworld: MultiWorld, player: int): + if multiworld.worlds[player].options.mode == 'inverted': + set_rule(multiworld.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Lake Hylia Warp', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Northeast Light World Warp', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Hobo Bridge', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: True) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: True) + set_rule(multiworld.get_entrance('East Dark World Pier', player), lambda state: True) #qirn jump - set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: True) + set_rule(multiworld.get_entrance('East Dark World River Pier', player), lambda state: True) else: - set_rule(world.get_entrance('Zoras River', player), lambda state: True) - set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: True) - set_rule(world.get_entrance('Hobo Bridge', player), lambda state: True) - set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player)) - set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Zoras River', player), lambda state: True) + set_rule(multiworld.get_entrance('Lake Hylia Central Island Pier', player), lambda state: True) + set_rule(multiworld.get_entrance('Hobo Bridge', player), lambda state: True) + set_rule(multiworld.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Moon Pearl', player)) #qirn jump - set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: state.has('Moon Pearl', player)) + set_rule(multiworld.get_entrance('East Dark World River Pier', player), lambda state: state.has('Moon Pearl', player)) -def bomb_jump_requirements(multiworld, player): +def bomb_jump_requirements(multiworld: MultiWorld, player: int): DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'] for location in DMs_room_chests: add_rule(multiworld.get_location(location, player), lambda state: can_use_bombs(state, player), combine="or") @@ -947,7 +953,7 @@ def bomb_jump_requirements(multiworld, player): set_rule(multiworld.get_entrance('Skull Woods First Section Bomb Jump', player), lambda state: can_use_bombs(state, player)) -def forbid_bomb_jump_requirements(multiworld, player): +def forbid_bomb_jump_requirements(multiworld: MultiWorld, player: int): DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'] for location in DMs_room_chests: add_rule(multiworld.get_location(location, player), lambda state: state.has('Hookshot', player)) @@ -972,14 +978,15 @@ DW_Entrances = ['Bumper Cave (Bottom)', 'Turtle Rock', 'Dark Death Mountain Ledge (West)'] -def check_is_dark_world(region): + +def check_is_dark_world(region: Region): for entrance in region.entrances: if entrance.name in DW_Entrances: return True return False -def add_conditional_lamps(multiworld, player): +def add_conditional_lamps(multiworld: MultiWorld, player: int): # Light cones in standard depend on which world we actually are in, not which one the location would normally be # We add Lamp requirements only to those locations which lie in the dark world (or everything if open local_world = multiworld.worlds[player] @@ -1030,7 +1037,7 @@ def add_conditional_lamps(multiworld, player): add_lamp_requirement(multiworld, local_world.get_entrance("Throne Room"), player) -def open_rules(world, player): +def open_rules(multiworld: MultiWorld, player: int): def basement_key_rule(state): if location_item_name(state, 'Sewers - Key Rat Key Drop', player) == ("Small Key (Hyrule Castle)", player): @@ -1038,96 +1045,95 @@ def open_rules(world, player): else: return state._lttp_has_key("Small Key (Hyrule Castle)", player, 3) - set_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), + set_rule(multiworld.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), lambda state: basement_key_rule(state) and can_kill_most_things(state, player, 2)) - set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: basement_key_rule(state) and can_kill_most_things(state, player, 1)) + set_rule(multiworld.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: basement_key_rule(state) and can_kill_most_things(state, player, 1)) - set_rule(world.get_location('Sewers - Key Rat Key Drop', player), + set_rule(multiworld.get_location('Sewers - Key Rat Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 3) and can_kill_most_things(state, player, 1)) - set_rule(world.get_location('Hyrule Castle - Big Key Drop', player), + set_rule(multiworld.get_location('Hyrule Castle - Big Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) and can_kill_most_things(state, player, 1)) - set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), + set_rule(multiworld.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) and state.has('Big Key (Hyrule Castle)', player) - and (world.worlds[player].options.enemy_health in ("easy", "default") + and (multiworld.worlds[player].options.enemy_health in ("easy", "default") or can_kill_most_things(state, player, 1))) -def swordless_rules(world, player): - set_rule(world.get_entrance('Agahnim 1', player), lambda state: (state.has('Hammer', player) or state.has('Fire Rod', player) or can_shoot_arrows(state, player) or state.has('Cane of Somaria', player)) and state._lttp_has_key('Small Key (Agahnims Tower)', player, 2)) - set_rule(world.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 3) and state.has('Fire Rod', player)) # no curtain +def swordless_rules(multiworld: MultiWorld, player: int): + set_rule(multiworld.get_entrance('Agahnim 1', player), lambda state: (state.has('Hammer', player) or state.has('Fire Rod', player) or can_shoot_arrows(state, player) or state.has('Cane of Somaria', player)) and state._lttp_has_key('Small Key (Agahnims Tower)', player, 2)) + set_rule(multiworld.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 3) and state.has('Fire Rod', player)) # no curtain - set_rule(world.get_location('Ice Palace - Jelly Key Drop', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player)) - set_rule(world.get_location('Ice Palace - Compass Chest', player), lambda state: (state.has('Fire Rod', player) or state.has('Bombos', player)) and state._lttp_has_key('Small Key (Ice Palace)', player)) - set_rule(world.get_entrance('Ice Palace (Second Section)', player), lambda state: (state.has('Fire Rod', player) or state.has('Bombos', player)) and state._lttp_has_key('Small Key (Ice Palace)', player)) + set_rule(multiworld.get_location('Ice Palace - Jelly Key Drop', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player)) + set_rule(multiworld.get_location('Ice Palace - Compass Chest', player), lambda state: (state.has('Fire Rod', player) or state.has('Bombos', player)) and state._lttp_has_key('Small Key (Ice Palace)', player)) + set_rule(multiworld.get_entrance('Ice Palace (Second Section)', player), lambda state: (state.has('Fire Rod', player) or state.has('Bombos', player)) and state._lttp_has_key('Small Key (Ice Palace)', player)) - set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop + set_rule(multiworld.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if world.worlds[player].options.mode != 'inverted': - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle - set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!) - set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has('Moon Pearl', player) and has_misery_mire_medallion(state, player)) # sword not required to use medallion for opening in swordless (!) + if multiworld.worlds[player].options.mode != 'inverted': + set_rule(multiworld.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle + set_rule(multiworld.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!) + set_rule(multiworld.get_entrance('Misery Mire', player), lambda state: state.has('Moon Pearl', player) and has_misery_mire_medallion(state, player)) # sword not required to use medallion for opening in swordless (!) else: # only need ddm access for aga tower in inverted - set_rule(world.get_entrance('Turtle Rock', player), lambda state: has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!) - set_rule(world.get_entrance('Misery Mire', player), lambda state: has_misery_mire_medallion(state, player)) # sword not required to use medallion for opening in swordless (!) + set_rule(multiworld.get_entrance('Turtle Rock', player), lambda state: has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!) + set_rule(multiworld.get_entrance('Misery Mire', player), lambda state: has_misery_mire_medallion(state, player)) # sword not required to use medallion for opening in swordless (!) -def add_connection(parent_name, target_name, entrance_name, world, player): - parent = world.get_region(parent_name, player) - target = world.get_region(target_name, player) +def add_connection(parent_name: str, target_name: str, entrance_name: str, multiworld: MultiWorld, player: int): + parent = multiworld.get_region(parent_name, player) + target = multiworld.get_region(target_name, player) parent.connect(target, entrance_name) +def standard_rules(multiworld: MultiWorld, player: int): + add_connection('Menu', 'Hyrule Castle Secret Entrance', 'Uncle S&Q', multiworld, player) + multiworld.get_entrance('Uncle S&Q', player).hide_path = True + set_rule(multiworld.get_entrance('Throne Room', player), lambda state: state.can_reach('Hyrule Castle - Zelda\'s Chest', 'Location', player)) + set_rule(multiworld.get_entrance('Hyrule Castle Exit (East)', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) + set_rule(multiworld.get_entrance('Hyrule Castle Exit (West)', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) + set_rule(multiworld.get_entrance('Links House S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) + set_rule(multiworld.get_entrance('Sanctuary S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) -def standard_rules(world, player): - add_connection('Menu', 'Hyrule Castle Secret Entrance', 'Uncle S&Q', world, player) - world.get_entrance('Uncle S&Q', player).hide_path = True - set_rule(world.get_entrance('Throne Room', player), lambda state: state.can_reach('Hyrule Castle - Zelda\'s Chest', 'Location', player)) - set_rule(world.get_entrance('Hyrule Castle Exit (East)', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) - set_rule(world.get_entrance('Hyrule Castle Exit (West)', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) - set_rule(world.get_entrance('Links House S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) - set_rule(world.get_entrance('Sanctuary S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) - - if world.worlds[player].options.small_key_shuffle != small_key_shuffle.option_universal: - set_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), + if multiworld.worlds[player].options.small_key_shuffle != small_key_shuffle.option_universal: + set_rule(multiworld.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1) and can_kill_standard_start(state, player, 2)) - set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), + set_rule(multiworld.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1) and can_kill_standard_start(state, player, 1)) - set_rule(world.get_location('Hyrule Castle - Map Guard Key Drop', player), + set_rule(multiworld.get_location('Hyrule Castle - Map Guard Key Drop', player), lambda state: can_kill_standard_start(state, player, 1)) - set_rule(world.get_location('Hyrule Castle - Big Key Drop', player), + set_rule(multiworld.get_location('Hyrule Castle - Big Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2)) - set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), + set_rule(multiworld.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2) and state.has('Big Key (Hyrule Castle)', player) - and (world.worlds[player].options.enemy_health in ("easy", "default") + and (multiworld.worlds[player].options.enemy_health in ("easy", "default") or can_kill_standard_start(state, player, 1))) - set_rule(world.get_location('Sewers - Key Rat Key Drop', player), + set_rule(multiworld.get_location('Sewers - Key Rat Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 3) and can_kill_standard_start(state, player, 1)) else: - set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), + set_rule(multiworld.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.has('Big Key (Hyrule Castle)', player)) -def toss_junk_item(world, player): +def toss_junk_item(multiworld: MultiWorld, player: int): items = ['Rupees (20)', 'Bombs (3)', 'Arrows (10)', 'Rupees (5)', 'Rupee (1)', 'Bombs (10)', 'Single Arrow', 'Rupees (50)', 'Rupees (100)', 'Single Bomb', 'Bee', 'Bee Trap', 'Rupees (300)', 'Nothing'] for item in items: - big20 = next((i for i in world.itempool if i.name == item and i.player == player), None) + big20 = next((i for i in multiworld.itempool if i.name == item and i.player == player), None) if big20: - world.itempool.remove(big20) + multiworld.itempool.remove(big20) return raise Exception("Unable to find a junk item to toss to make room for a TR small key") -def set_trock_key_rules(multiworld, player): +def set_trock_key_rules(multiworld: MultiWorld, player: int): # First set all relevant locked doors to impassible. for entrance in ['Turtle Rock Dark Room Staircase', 'Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)', 'Turtle Rock Entrance to Pokey Room', 'Turtle Rock (Pokey Room) (South)', 'Turtle Rock (Pokey Room) (North)', 'Turtle Rock Big Key Door']: set_rule(multiworld.get_entrance(entrance, player), lambda state: False) @@ -1228,9 +1234,9 @@ def set_trock_key_rules(multiworld, player): and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) -def set_big_bomb_rules(world, player): +def set_big_bomb_rules(multiworld: MultiWorld, player: int): # this is a mess - bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0] + bombshop_entrance = multiworld.get_region('Big Bomb Shop', player).entrances[0] Normal_LW_entrances = ['Blinds Hideout', 'Bonk Fairy (Light)', 'Lake Hylia Fairy', @@ -1345,7 +1351,7 @@ def set_big_bomb_rules(world, player): 'Desert Palace Entrance (South)', 'Checkerboard Cave'] - set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player)) + set_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player)) #crossing peg bridge starting from the southern dark world def cross_peg_bridge(state): @@ -1372,96 +1378,96 @@ def set_big_bomb_rules(world, player): #1. basic routes #2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror # -> M or BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: basic_routes(state) or state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: basic_routes(state) or state.has('Magic Mirror', player)) elif bombshop_entrance.name in LW_walkable_entrances: #1. Mirror then basic routes # -> M and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and basic_routes(state)) elif bombshop_entrance.name in Northern_DW_entrances: #1. Mirror and basic routes #2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl # -> (Mitts and CPB) or (M and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and cross_peg_bridge(state)) or (state.has('Magic Mirror', player) and basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and cross_peg_bridge(state)) or (state.has('Magic Mirror', player) and basic_routes(state))) elif bombshop_entrance.name == 'Bumper Cave (Bottom)': #1. Mirror and Lift rock and basic_routes #2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case) #3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl # -> (Mitts and CPB) or (((G or Flute) and M) and BR)) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and cross_peg_bridge(state)) or (((can_lift_rocks(state, player) or state.has('Flute', player)) and state.has('Magic Mirror', player)) and basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and cross_peg_bridge(state)) or (((can_lift_rocks(state, player) or state.has('Flute', player)) and state.has('Magic Mirror', player)) and basic_routes(state))) elif bombshop_entrance.name in Southern_DW_entrances: #1. Mirror and enter via gate: Need mirror and Aga1 #2. cross peg bridge: Need hammer and moon pearl # -> CPB or (M and A) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or (state.has('Magic Mirror', player) and state.has('Beat Agahnim 1', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or (state.has('Magic Mirror', player) and state.has('Beat Agahnim 1', player))) elif bombshop_entrance.name in Isolated_DW_entrances: # 1. mirror then flute then basic routes # -> M and Flute and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and state.has('Activated Flute', player) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and state.has('Activated Flute', player) and basic_routes(state)) elif bombshop_entrance.name in Isolated_LW_entrances: # 1. flute then basic routes # Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations. # -> Flute and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and basic_routes(state)) elif bombshop_entrance.name in West_LW_DM_entrances: # 1. flute then basic routes or mirror # Prexisting mirror spot is permitted, because flute can be used to reach west DM directly. # -> Flute and (M or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and (state.has('Magic Mirror', player) or basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and (state.has('Magic Mirror', player) or basic_routes(state))) elif bombshop_entrance.name in East_LW_DM_entrances: # 1. flute then basic routes or mirror and hookshot # Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot # -> Flute and ((M and Hookshot) or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has('Magic Mirror', player) and state.has('Hookshot', player)) or basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has('Magic Mirror', player) and state.has('Hookshot', player)) or basic_routes(state))) elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)': # Same as East_LW_DM_entrances except navigation without BR requires Mitts # -> Flute and ((M and Hookshot and Mitts) or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has('Magic Mirror', player) and state.has('Hookshot', player) and can_lift_heavy_rocks(state, player)) or basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has('Magic Mirror', player) and state.has('Hookshot', player) and can_lift_heavy_rocks(state, player)) or basic_routes(state))) elif bombshop_entrance.name in Castle_ledge_entrances: # 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror # 2. flute then basic routes # -> M or (Flute and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) or (state.has('Activated Flute', player) and basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) or (state.has('Activated Flute', player) and basic_routes(state))) elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances: # Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and: # 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes # 2. flute then basic routes # -> (Mire access and M) or Flute) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has('Magic Mirror', player)) or state.has('Activated Flute', player)) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has('Magic Mirror', player)) or state.has('Activated Flute', player)) and basic_routes(state)) elif bombshop_entrance.name == 'Old Man Cave (West)': # 1. Lift rock then basic_routes # 2. flute then basic_routes # -> (Flute or G) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or can_lift_rocks(state, player)) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or can_lift_rocks(state, player)) and basic_routes(state)) elif bombshop_entrance.name == 'Graveyard Cave': # 1. flute then basic routes # 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge # -> (Flute or (M and P and West Dark World access) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player))) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player))) and basic_routes(state)) elif bombshop_entrance.name in Mirror_from_SDW_entrances: # 1. flute then basic routes # 2. (has South dark world access) use existing mirror spot, mirror again off ledge # -> (Flute or (M and South Dark World access) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('South Dark World', 'Region', player) and state.has('Magic Mirror', player))) and basic_routes(state)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('South Dark World', 'Region', player) and state.has('Magic Mirror', player))) and basic_routes(state)) elif bombshop_entrance.name == 'Dark World Potion Shop': # 1. walk down by lifting rock: needs gloves and pearl` # 2. walk down by hammering peg: needs hammer and pearl # 3. mirror and basic routes # -> (P and (H or Gloves)) or (M and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Moon Pearl', player) and (state.has('Hammer', player) or can_lift_rocks(state, player))) or (state.has('Magic Mirror', player) and basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Moon Pearl', player) and (state.has('Hammer', player) or can_lift_rocks(state, player))) or (state.has('Magic Mirror', player) and basic_routes(state))) elif bombshop_entrance.name == 'Kings Grave': # same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts # (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot) # to account for insanity, must consider a way to escape without a cave for basic_routes # -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and state.has('Magic Mirror', player)) or ((can_lift_heavy_rocks(state, player) or state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player))) and basic_routes(state))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (can_lift_heavy_rocks(state, player) and state.has('Magic Mirror', player)) or ((can_lift_heavy_rocks(state, player) or state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player))) and basic_routes(state))) elif bombshop_entrance.name == 'Waterfall of Wishing': # same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which # means you need an escape route of either Flippers or Flute - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and (basic_routes(state) or state.has('Magic Mirror', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and (basic_routes(state) or state.has('Magic Mirror', player))) -def set_inverted_big_bomb_rules(world, player): - bombshop_entrance = world.get_region('Inverted Big Bomb Shop', player).entrances[0] +def set_inverted_big_bomb_rules(multiworld: MultiWorld, player: int): + bombshop_entrance = multiworld.get_region('Inverted Big Bomb Shop', player).entrances[0] Normal_LW_entrances = ['Blinds Hideout', 'Bonk Fairy (Light)', 'Lake Hylia Fairy', @@ -1579,7 +1585,7 @@ def set_inverted_big_bomb_rules(world, player): 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)'] - set_rule(world.get_entrance('Pyramid Fairy', player), + set_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Inverted Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player)) # Key for below abbreviations: @@ -1593,64 +1599,64 @@ def set_inverted_big_bomb_rules(world, player): pass elif bombshop_entrance.name in Normal_LW_entrances: # Just walk to the castle and mirror. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player)) elif bombshop_entrance.name in Isolated_LW_entrances: # For these entrances, you cannot walk to the castle/pyramid and thus must use Mirror and then Flute. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and state.has('Magic Mirror', player)) elif bombshop_entrance.name in Northern_DW_entrances: # You can just fly with the Flute, you can take a long walk with Mitts and Hammer, # or you can leave a Mirror portal nearby and then walk to the castle to Mirror again. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) elif bombshop_entrance.name in Southern_DW_entrances: # This is the same as north DW without the Mitts rock present. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.has('Activated Flute', player) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.has('Activated Flute', player) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) elif bombshop_entrance.name in Isolated_DW_entrances: # There's just no way to escape these places with the bomb and no Flute. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player)) elif bombshop_entrance.name in LW_walkable_entrances: # You can fly with the flute, or leave a mirror portal and walk through the light world - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player))) elif bombshop_entrance.name in LW_bush_entrances: # These entrances are behind bushes in LW so you need either Pearl or the tools to solve NDW bomb shop locations. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and (state.has('Activated Flute', player) or state.has('Moon Pearl', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and (state.has('Activated Flute', player) or state.has('Moon Pearl', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)))) elif bombshop_entrance.name == 'Village of Outcasts Shop': # This is mostly the same as NDW but the Mirror path requires the Pearl, or using the Hammer - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player) and (state.has('Moon Pearl', player) or state.has('Hammer', player)))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and state.can_reach('Light World', 'Region', player) and (state.has('Moon Pearl', player) or state.has('Hammer', player)))) elif bombshop_entrance.name == 'Bumper Cave (Bottom)': # This is mostly the same as NDW but the Mirror path requires being able to lift a rock. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and can_lift_rocks(state, player) and state.can_reach('Light World', 'Region', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (state.has('Magic Mirror', player) and can_lift_rocks(state, player) and state.can_reach('Light World', 'Region', player))) elif bombshop_entrance.name == 'Old Man Cave (West)': # The three paths back are Mirror and DW walk, Mirror and Flute, or LW walk and then Mirror. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and ((can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (can_lift_rocks(state, player) and state.has('Moon Pearl', player)) or state.has('Activated Flute', player))) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Magic Mirror', player) and ((can_lift_heavy_rocks(state, player) and state.has('Hammer', player)) or (can_lift_rocks(state, player) and state.has('Moon Pearl', player)) or state.has('Activated Flute', player))) elif bombshop_entrance.name == 'Dark World Potion Shop': # You either need to Flute to 5 or cross the rock/hammer choice pass to the south. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or state.has('Hammer', player) or can_lift_rocks(state, player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or state.has('Hammer', player) or can_lift_rocks(state, player)) elif bombshop_entrance.name == 'Kings Grave': # Either lift the rock and walk to the castle to Mirror or Mirror immediately and Flute. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or can_lift_heavy_rocks(state, player)) and state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or can_lift_heavy_rocks(state, player)) and state.has('Magic Mirror', player)) elif bombshop_entrance.name == 'Waterfall of Wishing': # You absolutely must be able to swim to return it from here. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has('Moon Pearl', player) and state.has('Magic Mirror', player)) elif bombshop_entrance.name == 'Ice Palace': # You can swim to the dock or use the Flute to get off the island. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.has('Activated Flute', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.has('Activated Flute', player)) elif bombshop_entrance.name == 'Capacity Upgrade': # You must Mirror but then can use either Ice Palace return path. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and state.has('Magic Mirror', player)) elif bombshop_entrance.name == 'Two Brothers House (West)': # First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again. - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has('Magic Mirror', player)) elif bombshop_entrance.name in LW_inaccessible_entrances: # You can't get to the pyramid from these entrances without bomb duping. raise Exception('No valid path to open Pyramid Fairy. (Could not route from %s)' % bombshop_entrance.name) elif bombshop_entrance.name == 'Pyramid Fairy': # Self locking. The shuffles don't put the bomb shop here, but doesn't lock anything important. - set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) + set_rule(multiworld.get_entrance('Pyramid Fairy', player), lambda state: False) else: raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name) -def set_bunny_rules(world: MultiWorld, player: int, inverted: bool): +def set_bunny_rules(multiworld: MultiWorld, player: int, inverted: bool): # regions for the exits of multi-entrance caves/drops that bunny cannot pass # Note spiral cave and two brothers house are passable in superbunny state for glitch logic with extra requirements. @@ -1690,7 +1696,7 @@ def set_bunny_rules(world: MultiWorld, player: int, inverted: bool): def get_rule_to_add(region, location = None, connecting_entrance = None): # In OWG, a location can potentially be superbunny-mirror accessible or # bunny revival accessible. - if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if multiworld.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic']: if region.name == 'Swamp Palace (Entrance)': # Need to 0hp revive - not in logic return lambda state: state.has('Moon Pearl', player) if region.name == 'Tower of Hera (Bottom)': # Need to hit the crystal switch @@ -1730,7 +1736,7 @@ def set_bunny_rules(world: MultiWorld, player: int, inverted: bool): seen.add(new_region) if not is_link(new_region): # For glitch rulesets, establish superbunny and revival rules. - if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name not in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): + if multiworld.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name not in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions(): possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has('Magic Mirror', player) and has_sword(state, player)) elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions() @@ -1753,29 +1759,29 @@ def set_bunny_rules(world: MultiWorld, player: int, inverted: bool): return options_to_access_rule(possible_options) # Add requirements for bunny-impassible caves if link is a bunny in them - for region in (world.get_region(name, player) for name in bunny_impassable_caves): + for region in (multiworld.get_region(name, player) for name in bunny_impassable_caves): if not is_bunny(region): continue rule = get_rule_to_add(region) for region_exit in region.exits: add_rule(region_exit, rule) - paradox_shop = world.get_region('Light World Death Mountain Shop', player) + paradox_shop = multiworld.get_region('Light World Death Mountain Shop', player) if is_bunny(paradox_shop): add_rule(paradox_shop.entrances[0], get_rule_to_add(paradox_shop)) # Add requirements for all locations that are actually in the dark world, except those available to the bunny, including dungeon revival - for entrance in world.get_entrances(player): + for entrance in multiworld.get_entrances(player): if is_bunny(entrance.connected_region): - if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] : + if multiworld.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] : if entrance.connected_region.type == LTTPRegionType.Dungeon: if entrance.parent_region.type != LTTPRegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance)) continue if entrance.connected_region.name == 'Turtle Rock (Entrance)': - add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) + add_rule(multiworld.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) for location in entrance.connected_region.locations: - if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances(): + if multiworld.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances(): continue if location.name in bunny_accessible_locations: continue diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index 89e43a1a04..182f25ddc2 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -7,7 +7,7 @@ from Utils import int16_as_bytes from worlds.generic.Rules import add_rule -from BaseClasses import CollectionState +from BaseClasses import CollectionState, Item, MultiWorld from .SubClasses import ALttPLocation from .Items import item_name_groups @@ -159,7 +159,7 @@ shop_class_mapping = {ShopType.UpgradeShop: UpgradeShop, ShopType.TakeAny: TakeAny} -def push_shop_inventories(multiworld): +def push_shop_inventories(multiworld: MultiWorld): all_shops = [] for world in multiworld.get_game_worlds(ALttPLocation.game): all_shops.extend(world.shops) @@ -183,7 +183,7 @@ def push_shop_inventories(multiworld): world.pushed_shop_inventories.set() -def create_shops(multiworld, player: int): +def create_shops(multiworld: MultiWorld, player: int): from .Options import RandomizeShopInventories player_shop_table = shop_table.copy() if multiworld.worlds[player].options.include_witch_hut: @@ -306,7 +306,7 @@ shop_generation_types = { } -def set_up_shops(multiworld, player: int): +def set_up_shops(multiworld: MultiWorld, player: int): from .Options import small_key_shuffle # TODO: move hard+ mode changes for shields here, utilizing the new shops @@ -408,7 +408,7 @@ price_rate_display = { } -def get_price_modifier(item) -> float: +def get_price_modifier(item: Item) -> float: if item.game == "A Link to the Past": if any(x in item.name for x in ['Compass', 'Map', 'Single Bomb', 'Single Arrow', 'Piece of Heart']): @@ -428,7 +428,7 @@ def get_price_modifier(item) -> float: return 0.25 -def get_price(multiworld, item, player: int, price_type=None): +def get_price(multiworld: MultiWorld, item: Item, player: int, price_type=None): """Converts a raw Rupee price into a special price type""" from .Options import small_key_shuffle if price_type: diff --git a/worlds/alttp/UnderworldGlitchRules.py b/worlds/alttp/UnderworldGlitchRules.py index 25511f320d..1b606a23af 100644 --- a/worlds/alttp/UnderworldGlitchRules.py +++ b/worlds/alttp/UnderworldGlitchRules.py @@ -1,3 +1,4 @@ +from BaseClasses import MultiWorld, CollectionState from worlds.generic.Rules import set_rule, add_rule from .StateHelpers import can_bomb_clip, has_sword, has_beam_sword, has_fire_source, can_melt_things, has_misery_mire_medallion from .SubClasses import LTTPEntrance @@ -5,27 +6,27 @@ from .SubClasses import LTTPEntrance # We actually need the logic to properly "mark" these regions as Light or Dark world. # Therefore we need to make these connections during the normal link_entrances stage, rather than during set_rules. -def underworld_glitch_connections(world, player): - specrock = world.get_region('Spectacle Rock Cave (Bottom)', player) - mire = world.get_region('Misery Mire (West)', player) +def underworld_glitch_connections(multiworld: MultiWorld, player: int): + specrock = multiworld.get_region('Spectacle Rock Cave (Bottom)', player) + mire = multiworld.get_region('Misery Mire (West)', player) kikiskip = specrock.create_exit('Kiki Skip') mire_to_hera = mire.create_exit('Mire to Hera Clip') mire_to_swamp = mire.create_exit('Hera to Swamp Clip') - if world.worlds[player].fix_fake_world: - kikiskip.connect(world.get_entrance('Palace of Darkness Exit', player).connected_region) - mire_to_hera.connect(world.get_entrance('Tower of Hera Exit', player).connected_region) - mire_to_swamp.connect(world.get_entrance('Swamp Palace Exit', player).connected_region) + if multiworld.worlds[player].fix_fake_world: + kikiskip.connect(multiworld.get_entrance('Palace of Darkness Exit', player).connected_region) + mire_to_hera.connect(multiworld.get_entrance('Tower of Hera Exit', player).connected_region) + mire_to_swamp.connect(multiworld.get_entrance('Swamp Palace Exit', player).connected_region) else: - kikiskip.connect(world.get_region('Palace of Darkness (Entrance)', player)) - mire_to_hera.connect(world.get_region('Tower of Hera (Bottom)', player)) - mire_to_swamp.connect(world.get_region('Swamp Palace (Entrance)', player)) + kikiskip.connect(multiworld.get_region('Palace of Darkness (Entrance)', player)) + mire_to_hera.connect(multiworld.get_region('Tower of Hera (Bottom)', player)) + mire_to_swamp.connect(multiworld.get_region('Swamp Palace (Entrance)', player)) # For some entrances, we need to fake having pearl, because we're in fake DW/LW. # This creates a copy of the input state that has Moon Pearl. -def fake_pearl_state(state, player): +def fake_pearl_state(state: CollectionState, player: int): if state.has('Moon Pearl', player): return state fake_state = state.copy() @@ -35,11 +36,11 @@ def fake_pearl_state(state, player): # Sets the rules on where we can actually go using this clip. # Behavior differs based on what type of ER shuffle we're playing. -def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str, dungeon_exit: str): - fix_dungeon_exits = world.worlds[player].fix_palaceofdarkness_exit - fix_fake_worlds = world.worlds[player].fix_fake_world +def dungeon_reentry_rules(multiworld: MultiWorld, player: int, clip: LTTPEntrance, dungeon_region: str, dungeon_exit: str): + fix_dungeon_exits = multiworld.worlds[player].fix_palaceofdarkness_exit + fix_fake_worlds = multiworld.worlds[player].fix_fake_world - dungeon_entrance = [r for r in world.get_region(dungeon_region, player).entrances if r.name != clip.name][0] + dungeon_entrance = [r for r in multiworld.get_region(dungeon_region, player).entrances if r.name != clip.name][0] if not fix_dungeon_exits: # vanilla, simple, restricted, dungeons_simple; should never have fake worlds fix # Dungeons are only shuffled among themselves. We need to check SW, MM, and AT because they can't be reentered trivially. if dungeon_entrance.name == 'Skull Woods Final Section': @@ -49,64 +50,64 @@ def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str elif dungeon_entrance.name == 'Agahnims Tower': add_rule(clip, lambda state: state.has('Cape', player) or has_beam_sword(state, player) or state.has('Beat Agahnim 1', player)) # kill/bypass barrier # Then we set a restriction on exiting the dungeon, so you can't leave unless you got in normally. - add_rule(world.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state)) + add_rule(multiworld.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state)) elif not fix_fake_worlds: # full, dungeons_full; fixed dungeon exits, but no fake worlds fix # Entry requires the entrance's requirements plus a fake pearl, but you don't gain logical access to the surrounding region. add_rule(clip, lambda state: dungeon_entrance.access_rule(fake_pearl_state(state, player))) # exiting restriction - add_rule(world.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state)) + add_rule(multiworld.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state)) # Otherwise, the shuffle type is crossed, dungeons_crossed, or insanity; all of these do not need additional rules on where we can go, # since the clip links directly to the exterior region. -def underworld_glitches_rules(world, player): +def underworld_glitches_rules(multiworld: MultiWorld, player: int): # Ice Palace Entrance Clip # This is the easiest one since it's a simple internal clip. # Need to also add melting to freezor chest since it's otherwise assumed. # Also can pick up the first jelly key from behind. - add_rule(world.get_entrance('Ice Palace (Main)', player), lambda state: can_bomb_clip(state, world.get_region('Ice Palace (Entrance)', player), player), combine='or') - add_rule(world.get_location('Ice Palace - Freezor Chest', player), lambda state: can_melt_things(state, player)) - add_rule(world.get_location('Ice Palace - Jelly Key Drop', player), lambda state: can_bomb_clip(state, world.get_region('Ice Palace (Entrance)', player), player), combine='or') + add_rule(multiworld.get_entrance('Ice Palace (Main)', player), lambda state: can_bomb_clip(state, multiworld.get_region('Ice Palace (Entrance)', player), player), combine='or') + add_rule(multiworld.get_location('Ice Palace - Freezor Chest', player), lambda state: can_melt_things(state, player)) + add_rule(multiworld.get_location('Ice Palace - Jelly Key Drop', player), lambda state: can_bomb_clip(state, multiworld.get_region('Ice Palace (Entrance)', player), player), combine='or') # Kiki Skip - kikiskip = world.get_entrance('Kiki Skip', player) + kikiskip = multiworld.get_entrance('Kiki Skip', player) set_rule(kikiskip, lambda state: can_bomb_clip(state, kikiskip.parent_region, player)) - dungeon_reentry_rules(world, player, kikiskip, 'Palace of Darkness (Entrance)', 'Palace of Darkness Exit') + dungeon_reentry_rules(multiworld, player, kikiskip, 'Palace of Darkness (Entrance)', 'Palace of Darkness Exit') # Mire -> Hera -> Swamp # Using mire keys on other dungeon doors - mire = world.get_region('Misery Mire (West)', player) + mire = multiworld.get_region('Misery Mire (West)', player) mire_clip = lambda state: state.can_reach('Misery Mire (West)', 'Region', player) and can_bomb_clip(state, mire, player) and has_fire_source(state, player) - hera_clip = lambda state: state.can_reach('Tower of Hera (Top)', 'Region', player) and can_bomb_clip(state, world.get_region('Tower of Hera (Top)', player), player) - add_rule(world.get_entrance('Tower of Hera Big Key Door', player), lambda state: mire_clip(state) and state.has('Big Key (Misery Mire)', player), combine='or') - add_rule(world.get_entrance('Swamp Palace Small Key Door', player), lambda state: mire_clip(state), combine='or') - add_rule(world.get_entrance('Swamp Palace (Center)', player), lambda state: mire_clip(state) or hera_clip(state), combine='or') + hera_clip = lambda state: state.can_reach('Tower of Hera (Top)', 'Region', player) and can_bomb_clip(state, multiworld.get_region('Tower of Hera (Top)', player), player) + add_rule(multiworld.get_entrance('Tower of Hera Big Key Door', player), lambda state: mire_clip(state) and state.has('Big Key (Misery Mire)', player), combine='or') + add_rule(multiworld.get_entrance('Swamp Palace Small Key Door', player), lambda state: mire_clip(state), combine='or') + add_rule(multiworld.get_entrance('Swamp Palace (Center)', player), lambda state: mire_clip(state) or hera_clip(state), combine='or') # Build the rule for SP moat. # We need to be able to s+q to old man, then go to either Mire or Hera at either Hera or GT. # First we require a certain type of entrance shuffle, then build the rule from its pieces. - if not world.worlds[player].swamp_patch_required: - if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if not multiworld.worlds[player].swamp_patch_required: + if multiworld.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rule_map = { 'Misery Mire (Entrance)': (lambda state: True), 'Tower of Hera (Bottom)': (lambda state: state.can_reach('Tower of Hera Big Key Door', 'Entrance', player)) } - inverted = world.worlds[player].options.mode == 'inverted' + inverted = multiworld.worlds[player].options.mode == 'inverted' hera_rule = lambda state: (state.has('Moon Pearl', player) or not inverted) and \ - rule_map.get(world.get_entrance('Tower of Hera', player).connected_region.name, lambda state: False)(state) + rule_map.get(multiworld.get_entrance('Tower of Hera', player).connected_region.name, lambda state: False)(state) gt_rule = lambda state: (state.has('Moon Pearl', player) or inverted) and \ - rule_map.get(world.get_entrance(('Ganons Tower' if not inverted else 'Inverted Ganons Tower'), player).connected_region.name, lambda state: False)(state) + rule_map.get(multiworld.get_entrance(('Ganons Tower' if not inverted else 'Inverted Ganons Tower'), player).connected_region.name, lambda state: False)(state) mirrorless_moat_rule = lambda state: state.can_reach('Old Man S&Q', 'Entrance', player) and mire_clip(state) and (hera_rule(state) or gt_rule(state)) - add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player) or mirrorless_moat_rule(state)) + add_rule(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player) or mirrorless_moat_rule(state)) else: - add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player)) + add_rule(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player)) # Using the entrances for various ER types. Hera -> Swamp never matters because you can only logically traverse with the mire keys - mire_to_hera = world.get_entrance('Mire to Hera Clip', player) - mire_to_swamp = world.get_entrance('Hera to Swamp Clip', player) + mire_to_hera = multiworld.get_entrance('Mire to Hera Clip', player) + mire_to_swamp = multiworld.get_entrance('Hera to Swamp Clip', player) set_rule(mire_to_hera, mire_clip) set_rule(mire_to_swamp, lambda state: mire_clip(state) and state.has('Flippers', player)) - dungeon_reentry_rules(world, player, mire_to_hera, 'Tower of Hera (Bottom)', 'Tower of Hera Exit') - dungeon_reentry_rules(world, player, mire_to_swamp, 'Swamp Palace (Entrance)', 'Swamp Palace Exit') + dungeon_reentry_rules(multiworld, player, mire_to_hera, 'Tower of Hera (Bottom)', 'Tower of Hera Exit') + dungeon_reentry_rules(multiworld, player, mire_to_swamp, 'Swamp Palace (Entrance)', 'Swamp Palace Exit')