From 6cd6dca6a34c031f262c328e09a26a7c9be0b522 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 23 Jun 2021 03:09:27 -0500 Subject: [PATCH] Initial Tile Shuffle Implementation --- BaseClasses.py | 6 +- DoorShuffle.py | 2 +- Main.py | 2 +- OWEdges.py | 488 ++++++++++++++++++++ OverworldShuffle.py | 1010 +++++++++++++++++++++++++---------------- Regions.py | 4 +- Rom.py | 495 +++++++++++--------- Rules.py | 732 ++++++++++++++--------------- asm/owrando.asm | 29 +- data/base2current.bps | Bin 137725 -> 27 bytes 10 files changed, 1781 insertions(+), 987 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 4721ef85..1ed73865 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3,7 +3,7 @@ import copy import json import logging from collections import OrderedDict, Counter, deque, defaultdict -from enum import Enum, unique +from enum import Enum, IntEnum, unique try: from fast_enum import FastEnum @@ -73,6 +73,7 @@ class World(object): self.dynamic_locations = [] self.spoiler = Spoiler(self) self.lamps_needed_for_dark_rooms = 1 + self.owswaps = {} self.owedges = [] self._owedge_cache = {} self.doors = [] @@ -142,6 +143,7 @@ class World(object): set_player_attr('mixed_travel', 'prevent') set_player_attr('standardize_palettes', 'standardize') set_player_attr('force_fix', {'gt': False, 'sw': False, 'pod': False, 'tr': False}) + set_player_attr('owswaps', [[],[],[]]) def get_name_string_for_object(self, obj): return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})' @@ -1503,7 +1505,7 @@ class Door(object): @unique -class WorldType(Enum): +class WorldType(IntEnum): Light = 0 Dark = 1 Special = 2 diff --git a/DoorShuffle.py b/DoorShuffle.py index 55e481b4..3478d027 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -211,7 +211,7 @@ def vanilla_key_logic(world, player): analyze_dungeon(key_layout, world, player) world.key_logic[player][builder.name] = key_layout.key_logic log_key_logic(builder.name, key_layout.key_logic) - if world.shuffle[player] == 'vanilla' and world.owShuffle[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player] and not world.keydropshuffle[player]: + if world.shuffle[player] == 'vanilla' and world.owShuffle[player] == 'vanilla' and world.owSwap[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player] and not world.keydropshuffle[player]: validate_vanilla_key_logic(world, player) diff --git a/Main.py b/Main.py index f4f9c371..96fbe6c2 100644 --- a/Main.py +++ b/Main.py @@ -245,7 +245,7 @@ def main(args, seed=None, fish=None): customize_shops(world, player) balance_money_progression(world) - if world.owShuffle[1] != 'vanilla': + if world.owShuffle[1] != 'vanilla' or world.owSwap[1] != 'vanilla': outfilebase = f'OR_{args.outputname if args.outputname else world.seed}' else: outfilebase = f'DR_{args.outputname if args.outputname else world.seed}' diff --git a/OWEdges.py b/OWEdges.py index 2a912280..671f3609 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -583,6 +583,10 @@ OWEdgeGroups = { ['Bomber Corner NE'] ] ), + (Op, DW, Hz, Ld, NP, 1): ( + [ ], + [ ] + ), (Op, DW, Hz, Ld, PL, 2): ( [ ['Dark Fortune EN', 'Dark Fortune ES'], @@ -657,6 +661,490 @@ OWEdgeGroups = { ) } +OWTileGroups = { + ("Woods", "Regular"): ( + [ + 0x00, 0x40, 0x80 + ], + [ + 'Master Sword Meadow', + 'Lost Woods West Area', + 'Lost Woods East Area' + ], + [ + 'Skull Woods Forest', + 'Skull Woods Portal Entry', + 'Skull Woods Forest (West)', + 'Skull Woods Forgotten Path (Southwest)', + 'Skull Woods Forgotten Path (Northeast)' + ] + ), + ("Lumberjack", "Regular"): ( + [ + 0x02, 0x42 + ], + [ + 'Lumberjack Area' + ], + [ + 'Dark Lumberjack Area' + ] + ), + ("West Mountain", "Regular"): ( + [ + 0x03, 0x43 + ], + [ + 'West Death Mountain (Top)', + 'Spectacle Rock Ledge', + 'West Death Mountain (Bottom)' + ], + [ + 'West Dark Death Mountain (Top)', + 'GT Approach', + 'West Dark Death Mountain (Bottom)' + ] + ), + ("East Mountain", "Regular"): ( + [ + 0x05, 0x45 + ], + [ + 'Death Mountain Floating Island', + 'East Death Mountain (Top West)', + 'East Death Mountain (Top East)', + 'Spiral Cave Ledge', + 'Mimic Cave Ledge', + 'Fairy Ascension Ledge', + 'Fairy Ascension Plateau', + 'East Death Mountain (Bottom Left)', + 'East Death Mountain (Bottom)' + ], + [ + 'East Dark Death Mountain (Top)', + 'East Dark Death Mountain (Bottom)', + 'East Dark Death Mountain (Bottom Left)' + ] + ), + ("East Mountain", "Entrance"): ( + [ + 0x07, 0x47 + ], + [ + 'Death Mountain TR Pegs', + 'Death Mountain TR Pegs Ledge' + ], + [ + 'Turtle Rock Area', + 'Turtle Rock Ledge' + ] + ), + ("Lake", "Regular"): ( + [ + 0x0f, 0x35, 0x4f, 0x75, 0x81 + ], + [ + 'Zora Waterfall Area', + 'Zora Waterfall Water', + 'Waterfall of Wishing Cave', + 'Zoras Domain', + 'Lake Hylia Area', + 'Lake Hylia South Shore', + 'Lake Hylia Northeast Bank', + 'Lake Hylia Central Island', + 'Lake Hylia Island', + 'Lake Hylia Water' + ], + [ + 'Catfish Area', + 'Ice Lake Area', + 'Ice Lake Northeast Bank', + 'Ice Lake Ledge (West)', + 'Ice Lake Ledge (East)', + 'Ice Lake Water', + 'Ice Lake Moat', + 'Ice Palace Area' + ] + ), + ("West Mountain", "Entrance"): ( + [ + 0x0a, 0x4a + ], + [ + 'Mountain Entry Area', + 'Mountain Entry Entrance', + 'Mountain Entry Ledge' + ], + [ + 'Bumper Cave Area', + 'Bumper Cave Entrance', + 'Bumper Cave Ledge' + ] + ), + ("Woods Pass", "Regular"): ( + [ + 0x10, 0x50 + ], + [ + 'Lost Woods Pass West Area', + 'Lost Woods Pass East Top Area', + 'Lost Woods Pass East Bottom Area' + ], + [ + 'Skull Woods Pass West Area', + 'Skull Woods Pass East Top Area', + 'Skull Woods Pass East Bottom Area' + ] + ), + ("Fortune", "Regular"): ( + [ + 0x11, 0x51 + ], + [ + 'Kakariko Fortune Area' + ], + [ + 'Dark Fortune Area' + ] + ), + ("Whirlpools", "Regular"): ( + [ + 0x12, 0x15, 0x33, 0x3f, 0x52, 0x55, 0x73, 0x7f + ], + [ + 'Kakariko Pond Area', + 'River Bend Area', + 'River Bend East Bank', + 'River Bend Water', + 'C Whirlpool Area', + 'C Whirlpool Water', + 'C Whirlpool Outer Area', + 'Octoballoon Area', + 'Octoballoon Water', + 'Octoballoon Water Ledge' + ], + [ + 'Outcast Pond Area', + 'Qirn Jump Area', + 'Qirn Jump East Bank', + 'Qirn Jump Water', + 'Dark C Whirlpool Area', + 'Dark C Whirlpool Water', + 'Dark C Whirlpool Outer Area', + 'Bomber Corner Area', + 'Bomber Corner Water', + 'Bomber Corner Water Ledge' + ] + ), + ("Castle", "Entrance"): ( + [ + 0x13, 0x14, 0x53, 0x54 + ], + [ + 'Sanctuary Area', + 'Bonk Rock Ledge', + 'Graveyard Area', + 'Graveyard Ledge', + 'Kings Grave Area' + ], + [ + 'Dark Chapel Area', + 'Dark Graveyard Area' + ] + ), + ("Castle", "Regular"): ( + [ + 0x1a, 0x1b, 0x5a, 0x5b + ], + [ + 'Forgotten Forest Area', + 'Hyrule Castle Area', + 'Hyrule Castle Southwest', + 'Hyrule Castle Courtyard', + 'Hyrule Castle Courtyard Northeast', + 'Hyrule Castle Ledge', + 'Hyrule Castle East Entry' + ], + [ + 'Shield Shop Area', + 'Shield Shop Fence', + 'Pyramid Area', + 'Pyramid Exit Ledge', + 'Pyramid Pass' + ] + ), + ("Witch", "Regular"): ( + [ + 0x16, 0x56 + ], + [ + 'Potion Shop Area', + 'Potion Shop Northeast', + 'Potion Shop Water' + ], + [ + 'Dark Witch Area', + 'Dark Witch Northeast', + 'Dark Witch Water' + ] + ), + ("Water Approach", "Regular"): ( + [ + 0x17, 0x57 + ], + [ + 'Zora Approach Area', + 'Zora Approach Ledge', + 'Zora Approach Water' + ], + [ + 'Catfish Approach Area', + 'Catfish Approach Ledge', + 'Catfish Approach Water' + ] + ), + ("Village", "Regular"): ( + [ + 0x18, 0x58 + ], + [ + 'Kakariko Area', + 'Kakariko Southwest', + 'Kakariko Grass Yard' + ], + [ + 'Village of Outcasts Area', + 'Dark Grassy Lawn' + ] + ), + ("Wooden Bridge", "Regular"): ( + [ + 0x1d, 0x5d + ], + [ + 'Wooden Bridge Area', + 'Wooden Bridge Northeast', + 'Wooden Bridge Water' + ], + [ + 'Broken Bridge Area', + 'Broken Bridge Northeast', + 'Broken Bridge West', + 'Broken Bridge Water' + ] + ), + ("Eastern", "Regular"): ( + [ + 0x1e, 0x5e + ], + [ + 'Eastern Palace Area' + ], + [ + 'Palace of Darkness Area' + ] + ), + # ("Blacksmith", "Regular"): ( + # [ + # 0x22, 0x62 + # ], + # [ + # 'Blacksmith Area', + # 'Bat Cave Ledge' + # ], + # [ + # 'Hammer Pegs Area', + # 'Hammer Pegs Entry' + # ] + # ), + ("Dunes", "Regular"): ( + [ + 0x25, 0x65 + ], + [ + 'Sand Dunes Area' + ], + [ + 'Dark Dunes Area' + ] + ), + ("Game", "Regular"): ( + [ + 0x28, 0x29, 0x68, 0x69 + ], + [ + 'Maze Race Area', + 'Maze Race Ledge', + 'Maze Race Prize', + 'Kakariko Suburb Area' + ], + [ + 'Dig Game Area', + 'Dig Game Ledge', + 'Frog Area', + 'Frog Prison', + 'Archery Game Area' + ] + ), + ("Grove", "Regular"): ( + [ + 0x2a, 0x6a + ], + [ + 'Flute Boy Area', + 'Flute Boy Pass' + ], + [ + 'Stumpy Area', + 'Stumpy Pass' + ] + ), + ("Central Bonk Rocks", "Regular"): ( + [ + 0x2b, 0x6b + ], + [ + 'Central Bonk Rocks Area' + ], + [ + 'Dark Bonk Rocks Area' + ] + ), + # ("Links", "Regular"): ( + # [ + # 0x2c, 0x6c + # ], + # [ + # 'Links House Area' + # ], + # [ + # 'Big Bomb Shop Area' + # ] + # ), + ("Bridge", "Regular"): ( + [ + 0x2d, 0x6d, 0x80 + ], + [ + 'Stone Bridge Area', + 'Stone Bridge Water', + 'Hobo Bridge' + ], + [ + 'Hammer Bridge North Area', + 'Hammer Bridge South Area', + 'Hammer Bridge Water' + ] + ), + ("Tree Line", "Regular"): ( + [ + 0x2e, 0x6e + ], + [ + 'Tree Line Area', + 'Tree Line Water' + ], + [ + 'Dark Tree Line Area', + 'Dark Tree Line Water' + ] + ), + ("Nook", "Regular"): ( + [ + 0x2f, 0x6f + ], + [ + 'Eastern Nook Area' + ], + [ + 'Palace of Darkness Nook Area' + ] + ), + ("Desert", "Regular"): ( + [ + 0x30, 0x3a, 0x70, 0x7a + ], + [ + 'Desert Area', + 'Desert Ledge', + 'Desert Palace Entrance (North) Spot', + 'Desert Checkerboard Ledge', + 'Desert Palace Stairs', + 'Desert Palace Mouth', + 'Desert Palace Teleporter Ledge', + 'Bombos Tablet Ledge', + 'Desert Pass Area', + 'Desert Pass Southeast', + 'Desert Pass Ledge' + ], + [ + 'Misery Mire Area', + 'Misery Mire Teleporter Ledge', + 'Swamp Nook Area' + ] + ), + ("Grove Approach", "Regular"): ( + [ + 0x32, 0x72 + ], + [ + 'Flute Boy Approach Area', + 'Flute Boy Bush Entry', + 'Cave 45 Ledge' + ], + [ + 'Stumpy Approach Area', + 'Stumpy Approach Bush Entry' + ] + ), + ("Hype", "Regular"): ( + [ + 0x34, 0x74 + ], + [ + 'Statues Area', + 'Statues Water' + ], + [ + 'Hype Cave Area', + 'Hype Cave Water' + ] + ), + ("Shopping Mall", "Regular"): ( + [ + 0x37, 0x77 + ], + [ + 'Ice Cave Area' + ], + [ + 'Shopping Mall Area' + ] + ), + ("Swamp", "Regular"): ( + [ + 0x3b, 0x7b + ], + [ + 'Dam Area' + ], + [ + 'Swamp Area' + ] + ), + ("South Pass", "Regular"): ( + [ + 0x3c, 0x7c + ], + [ + 'South Pass Area' + ], + [ + 'Dark South Pass Area' + ] + ) +} + parallel_links = bidict({'Lost Woods SW': 'Skull Woods SW', 'Lost Woods SC': 'Skull Woods SC', 'Lost Woods SE': 'Skull Woods SE', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index c6ad8310..f8467346 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1,6 +1,6 @@ -import random, logging -from BaseClasses import OWEdge, WorldType, Direction, Terrain -from OWEdges import OWEdgeGroups, parallel_links, IsParallel +import random, logging, copy +from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain +from OWEdges import OWTileGroups, OWEdgeGroups, parallel_links, IsParallel __version__ = '0.1.4.3-u' @@ -10,22 +10,155 @@ def link_overworld(world, player): connect_simple(world, exitname, regionname, player) for exitname, destname in temporary_mandatory_connections: connect_two_way(world, exitname, destname, player) + + # tile shuffle + trimmed_groups = copy.deepcopy(OWEdgeGroups) + if world.owSwap[player] != 'vanilla': + tile_groups = {} + for (name, groupType) in OWTileGroups.keys(): + if world.mode[player] != 'standard' or name not in ['Castle', 'Links']: + if world.shuffle[player] in ['vanilla', 'simple', 'dungeonssimple']: + tile_groups[(name,)] = ([], [], []) + else: + tile_groups[(name, groupType)] = ([], [], []) + + for (name, groupType) in OWTileGroups.keys(): + if world.mode[player] != 'standard' or name not in ['Castle', 'Links']: + (owids, lw_regions, dw_regions) = OWTileGroups[(name, groupType,)] + if world.shuffle[player] in ['vanilla', 'simple', 'dungeonssimple']: + (exist_owids, exist_lw_regions, exist_dw_regions) = tile_groups[(name,)] + exist_owids.extend(owids) + exist_lw_regions.extend(lw_regions) + exist_dw_regions.extend(dw_regions) + tile_groups[(name,)] = (exist_owids, exist_lw_regions, exist_dw_regions) + else: + (exist_owids, exist_lw_regions, exist_dw_regions) = tile_groups[(name, groupType)] + exist_owids.extend(owids) + exist_lw_regions.extend(lw_regions) + exist_dw_regions.extend(dw_regions) + tile_groups[(name, groupType)] = (exist_owids, exist_lw_regions, exist_dw_regions) + + #tile shuffle happens here, the groups that remain in the list are the tiles that get swapped + removed = list() + for group in tile_groups.keys(): + if random.randint(0, 1): + removed.append(group) + for group in removed: + tile_groups.pop(group, None) + + #save shuffled tiles to world object + for group in tile_groups.keys(): + (owids, lw_regions, dw_regions) = tile_groups[group] + (exist_owids, exist_lw_regions, exist_dw_regions) = world.owswaps[player] + exist_owids.extend(owids) + exist_lw_regions.extend(lw_regions) + exist_dw_regions.extend(dw_regions) + world.owswaps[player] = [exist_owids, exist_lw_regions, exist_dw_regions] + + #dont perform moon pearl check unless both hobo and ped are swapped + if 0x80 in world.owswaps[player][0]: + world.owswaps[player][0].remove(0x80) + + #replace LW edges with DW + ignore_list = list() #TODO: Remove ignore_list when special OW areas are included in pool + for edgeset in temporary_mandatory_connections: + for edge in edgeset: + ignore_list.append(edge) + + swapped_edges = list() + def getSwappedEdges(world, lst, player): + for regionname in lst: + region = world.get_region(regionname, player) + for exit in region.exits: + if exit.spot_type == 'OWEdge' and exit.name not in ignore_list: + swapped_edges.append(exit.name) + + getSwappedEdges(world, world.owswaps[player][1], player) + getSwappedEdges(world, world.owswaps[player][2], player) + + def performSwap(groups, swaps): + try: + for group in groups.keys(): + (mode, wrld, dir, terrain, parallel, count) = group + for p in range(0, len(groups[group])): + edgepool = groups[group][p] + for s in range(0, len(edgepool)): + if s <= len(edgepool): + for e in range(0, len(edgepool[s])): + if len(edgepool) > 0 and edgepool[s][e] in swaps: + if parallel == IsParallel.Yes: + if wrld == WorldType.Light and edgepool[s][e] in parallel_links: + logging.getLogger('').debug('%s was moved', edgepool[s][e]) + swaps.remove(edgepool[s][e]) + groups[group][p][s][e] = parallel_links[edgepool[s][e]] + elif wrld == WorldType.Dark and edgepool[s][e] in parallel_links.inverse: + logging.getLogger('').debug('%s was moved', edgepool[s][e]) + swaps.remove(edgepool[s][e]) + groups[group][p][s][e] = parallel_links.inverse[edgepool[s][e]][0] + else: + for edge in edgepool[s]: + logging.getLogger('').debug('%s was moved', edge) + swaps.remove(edge) + groups[(mode, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][p].append(edgepool[s]) + groups[group][p].remove(edgepool[s]) + except IndexError: + #TODO: Figure out a way to handle index changes on the fly when removing items + logging.getLogger('').warning('OW Tile Swap encountered minor IndexError... retrying') + + tries = 5 + while tries > 0: + performSwap(trimmed_groups, swapped_edges) + if len(swapped_edges) == 0: + tries = 0 + continue + tries -= 1 + assert len(swapped_edges) == 0 + + #move swapped regions to other world + if world.owSwap[player] == 'mixed': + for name in world.owswaps[player][1]: + region = world.get_region(name, player) + region.type = RegionType.DarkWorld + for name in world.owswaps[player][2]: + region = world.get_region(name, player) + region.type = RegionType.LightWorld - if world.mode[player] != 'inverted': - for exitname, regionname in open_connections: - connect_simple(world, exitname, regionname, player) - else: - for exitname, regionname in inverted_connections: - connect_simple(world, exitname, regionname, player) + #make new connections + for owid in flute_connections.keys(): + (spot, dest) = flute_connections[owid] + if (world.mode[player] == 'inverted') == (owid in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + connect_simple(world, spot, dest[0], player) + else: + connect_simple(world, spot, dest[1], player) + + for owid in ow_connections.keys(): + if (world.mode[player] == 'inverted') == (owid in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + for (exitname, regionname) in ow_connections[owid][0]: + connect_simple(world, exitname, regionname, player) + else: + for (exitname, regionname) in ow_connections[owid][1]: + connect_simple(world, exitname, regionname, player) connected_edges = [] connect_custom(world, connected_edges, player) - # if we do not shuffle, set default connections + # layout shuffle if world.owShuffle[player] == 'vanilla': - for exitname, destname in default_connections: - connect_two_way(world, exitname, destname, player) + #for exitname, destname in default_connections: + # connect_two_way(world, exitname, destname, player) + for grouping in (trimmed_groups,): + groups = list(trimmed_groups.values()) + for (forward_edge_sets, back_edge_sets) in groups: + assert len(forward_edge_sets) == len(back_edge_sets) + for (forward_set, back_set) in zip(forward_edge_sets, back_edge_sets): + assert len(forward_set) == len(back_set) + for (forward_edge, back_edge) in zip(forward_set, back_set): + connect_two_way(world, forward_edge, back_edge, player) + connected_edges.append(forward_edge) + connected_edges.append(back_edge) + + assert len(connected_edges) == len(default_connections) * 2, connected_edges else: if world.owKeepSimilar[player] and world.owShuffle[player] == 'parallel': for exitname, destname in parallelsimilar_connections: @@ -39,7 +172,7 @@ def link_overworld(world, player): connected_edges.append(exitname) connected_edges.append(destname) - trimmed_groups = remove_reserved(world, OWEdgeGroups, connected_edges, player) + trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player) groups = reorganize_groups(world, trimmed_groups, player) @@ -54,11 +187,14 @@ def link_overworld(world, player): connect_two_way(world, forward_edge, back_edge, player) connected_edges.append(forward_edge) connected_edges.append(back_edge) - if world.owShuffle[player] == 'parallel' and forward_edge in parallel_links.keys(): - connect_two_way(world, parallel_links[forward_edge], parallel_links[back_edge], player) - connected_edges.append(parallel_links[forward_edge]) - connected_edges.append(parallel_links[back_edge]) - + if world.owShuffle[player] == 'parallel': + if forward_edge in parallel_links.keys() or forward_edge in parallel_links.inverse.keys(): + parallel_forward_edge = parallel_links[forward_edge] if forward_edge in parallel_links.keys() else parallel_links.inverse[forward_edge][0] + parallel_back_edge = parallel_links[back_edge] if back_edge in parallel_links.keys() else parallel_links.inverse[back_edge][0] + connect_two_way(world, parallel_forward_edge, parallel_back_edge, player) + connected_edges.append(parallel_forward_edge) + connected_edges.append(parallel_back_edge) + assert len(connected_edges) == len(default_connections) * 2, connected_edges def connect_custom(world, connected_edges, player): @@ -93,7 +229,7 @@ def connect_two_way(world, edgename1, edgename2, player): x.dest = y y.dest = x - if world.owShuffle[player] != 'vanilla': + if world.owShuffle[player] != 'vanilla' or world.owSwap[player] != 'vanilla': world.spoiler.set_overworld(edgename2, edgename1, 'both', player) def remove_reserved(world, groupedlist, connected_edges, player): @@ -113,6 +249,9 @@ def remove_reserved(world, groupedlist, connected_edges, player): for edge in parallel_links: forward_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in forward_edges) back_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in back_edges) + for edge in parallel_links.inverse: + forward_edges = list(list(filter((parallel_links.inverse[edge][0]).__ne__, i)) for i in forward_edges) + back_edges = list(list(filter((parallel_links.inverse[edge][0]).__ne__, i)) for i in back_edges) forward_edges = list(filter(([]).__ne__, forward_edges)) back_edges = list(filter(([]).__ne__, back_edges)) @@ -133,159 +272,151 @@ def reorganize_groups(world, groups, player): if world.owKeepSimilar[player]: if world.mode[player] == 'standard': #tuple stays (A,B,C,D,_,F) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (std, region, axis, terrain, _, count) = group - new_grouping[(std, region, axis, terrain, count)] = ([], []) - - for group in grouping.keys(): - (std, region, axis, terrain, _, count) = group - (forward_edges, back_edges) = grouping[group] - (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, count)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(std, region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges) + for group in grouping.keys(): + (std, region, axis, terrain, _, count) = group + new_grouping[(std, region, axis, terrain, count)] = ([], []) + + for group in grouping.keys(): + (std, region, axis, terrain, _, count) = group + (forward_edges, back_edges) = grouping[group] + (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, count)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(std, region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: #tuple goes to (_,B,C,D,_,F) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (_, region, axis, terrain, _, count) = group - new_grouping[(region, axis, terrain, count)] = ([], []) - - for group in grouping.keys(): - (_, region, axis, terrain, _, count) = group - (forward_edges, back_edges) = grouping[group] - (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, count)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges) + for group in grouping.keys(): + (_, region, axis, terrain, _, count) = group + new_grouping[(region, axis, terrain, count)] = ([], []) + + for group in grouping.keys(): + (_, region, axis, terrain, _, count) = group + (forward_edges, back_edges) = grouping[group] + (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, count)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: if world.mode[player] == 'standard': #tuple stays (A,B,C,D,_,_) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (std, region, axis, terrain, _, _) = group - new_grouping[(std, region, axis, terrain)] = ([], []) + for group in grouping.keys(): + (std, region, axis, terrain, _, _) = group + new_grouping[(std, region, axis, terrain)] = ([], []) + + for group in grouping.keys(): + (std, region, axis, terrain, _, _) = group + (forward_edges, back_edges) = grouping[group] + forward_edges = [[i] for l in forward_edges for i in l] + back_edges = [[i] for l in back_edges for i in l] - for group in grouping.keys(): - (std, region, axis, terrain, _, _) = group - (forward_edges, back_edges) = grouping[group] - forward_edges = [[i] for l in forward_edges for i in l] - back_edges = [[i] for l in back_edges for i in l] - - (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(std, region, axis, terrain)] = (exist_forward_edges, exist_back_edges) + (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(std, region, axis, terrain)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: #tuple goes to (_,B,C,D,_,_) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (_, region, axis, terrain, _, _) = group - new_grouping[(region, axis, terrain)] = ([], []) + for group in grouping.keys(): + (_, region, axis, terrain, _, _) = group + new_grouping[(region, axis, terrain)] = ([], []) + + for group in grouping.keys(): + (_, region, axis, terrain, _, _) = group + (forward_edges, back_edges) = grouping[group] + forward_edges = [[i] for l in forward_edges for i in l] + back_edges = [[i] for l in back_edges for i in l] - for group in grouping.keys(): - (_, region, axis, terrain, _, _) = group - (forward_edges, back_edges) = grouping[group] - forward_edges = [[i] for l in forward_edges for i in l] - back_edges = [[i] for l in back_edges for i in l] - - (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(region, axis, terrain)] = (exist_forward_edges, exist_back_edges) + (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(region, axis, terrain)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) elif world.owShuffle[player] == 'parallel': #predefined shuffle groups get reorganized here if world.owKeepSimilar[player]: if world.mode[player] == 'standard': #tuple stays (A,B,C,D,E,F) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - return list(grouping.values()) + for grouping in (groups,): + return list(grouping.values()) else: #tuple goes to (_,B,C,D,E,F) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (_, region, axis, terrain, parallel, count) = group - new_grouping[(region, axis, terrain, parallel, count)] = ([], []) - - for group in grouping.keys(): - (_, region, axis, terrain, parallel, count) = group - (forward_edges, back_edges) = grouping[group] - (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel, count)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(region, axis, terrain, parallel, count)] = (exist_forward_edges, exist_back_edges) + for group in grouping.keys(): + (_, region, axis, terrain, parallel, count) = group + new_grouping[(region, axis, terrain, parallel, count)] = ([], []) + + for group in grouping.keys(): + (_, region, axis, terrain, parallel, count) = group + (forward_edges, back_edges) = grouping[group] + (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel, count)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(region, axis, terrain, parallel, count)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: if world.mode[player] == 'standard': #tuple stays (A,B,C,D,E,_) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (std, region, axis, terrain, parallel, _) = group - new_grouping[(std, region, axis, terrain, parallel)] = ([], []) + for group in grouping.keys(): + (std, region, axis, terrain, parallel, _) = group + new_grouping[(std, region, axis, terrain, parallel)] = ([], []) + + for group in grouping.keys(): + (std, region, axis, terrain, parallel, _) = group + (forward_edges, back_edges) = grouping[group] + forward_edges = [[i] for l in forward_edges for i in l] + back_edges = [[i] for l in back_edges for i in l] - for group in grouping.keys(): - (std, region, axis, terrain, parallel, _) = group - (forward_edges, back_edges) = grouping[group] - forward_edges = [[i] for l in forward_edges for i in l] - back_edges = [[i] for l in back_edges for i in l] - - (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, parallel)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(std, region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges) + (exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, parallel)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(std, region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: #tuple goes to (_,B,C,D,E,_) - for grouping in (groups, None): - if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work - new_grouping = {} + for grouping in (groups,): + new_grouping = {} - for group in grouping.keys(): - (_, region, axis, terrain, parallel, _) = group - new_grouping[(region, axis, terrain, parallel)] = ([], []) + for group in grouping.keys(): + (_, region, axis, terrain, parallel, _) = group + new_grouping[(region, axis, terrain, parallel)] = ([], []) + + for group in grouping.keys(): + (_, region, axis, terrain, parallel, _) = group + (forward_edges, back_edges) = grouping[group] + forward_edges = [[i] for l in forward_edges for i in l] + back_edges = [[i] for l in back_edges for i in l] - for group in grouping.keys(): - (_, region, axis, terrain, parallel, _) = group - (forward_edges, back_edges) = grouping[group] - forward_edges = [[i] for l in forward_edges for i in l] - back_edges = [[i] for l in back_edges for i in l] - - (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel)] - exist_forward_edges.extend(forward_edges) - exist_back_edges.extend(back_edges) - new_grouping[(region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges) + (exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel)] + exist_forward_edges.extend(forward_edges) + exist_back_edges.extend(back_edges) + new_grouping[(region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges) - return list(new_grouping.values()) + return list(new_grouping.values()) else: raise NotImplementedError('Shuffling not supported yet') @@ -535,259 +666,364 @@ mandatory_connections = [('Flute Away', 'Flute Sky'), ('Dark Tree Line WC Cliff Water Drop', 'Dark Tree Line Water') #fake flipper ] -open_connections = [('Flute Spot 1', 'West Death Mountain (Bottom)'), - ('Flute Spot 2', 'Potion Shop Area'), - ('Flute Spot 3', 'Kakariko Area'), - ('Flute Spot 4', 'Links House Area'), - ('Flute Spot 5', 'Eastern Nook Area'), - ('Flute Spot 6', 'Desert Palace Teleporter Ledge'), - ('Flute Spot 7', 'Dam Area'), - ('Flute Spot 8', 'Octoballoon Area'), - - # Mirror Connections - ('Lost Woods East Mirror Spot', 'Lost Woods East Area'), - ('Lost Woods Entry Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods Pedestal Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods Southwest Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods East Area'), - ('Lost Woods West (Forgotten) Mirror Spot', 'Lost Woods West Area'), - ('Lumberjack Mirror Spot', 'Lumberjack Area'), - ('Spectacle Rock Mirror Spot', 'Spectacle Rock Ledge'), - ('West Death Mountain (Top) Mirror Spot', 'West Death Mountain (Top)'), - ('East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top West)'), - ('East Death Mountain (Top East) Mirror Spot', 'East Death Mountain (Top East)'), - ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), - ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), - ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), - ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), - ('Death Mountain Bridge Mirror Spot', 'East Death Mountain (Bottom Left)'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island'), - ('TR Pegs Area Mirror Spot', 'Death Mountain TR Pegs'), - ('Mountain Entry Mirror Spot', 'Mountain Entry Area'), - ('Mountain Entry Entrance Mirror Spot', 'Mountain Entry Entrance'), - ('Mountain Entry Ledge Mirror Spot', 'Mountain Entry Ledge'), - ('Zora Waterfall Mirror Spot', 'Zora Waterfall Area'), - ('Lost Woods Pass West Mirror Spot', 'Lost Woods Pass West Area'), - ('Lost Woods Pass East Top Mirror Spot', 'Lost Woods Pass East Top Area'), - ('Lost Woods Pass East Bottom Mirror Spot', 'Lost Woods Pass East Bottom Area'), - ('Kakariko Fortune Mirror Spot', 'Kakariko Fortune Area'), - ('Kakariko Pond Mirror Spot', 'Kakariko Pond Area'), - ('Forgotton Forest Mirror Spot', 'Forgotten Forest Area'), - ('Forgotton Forest Fence Mirror Spot', 'Forgotten Forest Area'), - ('Bonk Rock Ledge Mirror Spot', 'Bonk Rock Ledge'), - ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), - ('Kings Grave Mirror Spot', 'Kings Grave Area'), - ('River Bend Mirror Spot', 'River Bend Area'), - ('River Bend East Mirror Spot', 'River Bend East Bank'), - ('Potion Shop Mirror Spot', 'Potion Shop Area'), - ('Potion Shop Northeast Mirror Spot', 'Potion Shop Northeast'), - ('Zora Approach Mirror Spot', 'Zora Approach Area'), - ('Zora Approach Ledge Mirror Spot', 'Zora Approach Ledge'), - ('Kakariko Mirror Spot', 'Kakariko Area'), - ('Kakariko Grass Mirror Spot', 'Kakariko Area'), - ('HC Ledge Mirror Spot', 'Hyrule Castle Ledge'), - ('HC Courtyard Mirror Spot', 'Hyrule Castle Courtyard'), - ('HC Area Mirror Spot', 'Hyrule Castle Area'), - ('HC Area South Mirror Spot', 'Hyrule Castle Area'), - ('HC East Entry Mirror Spot', 'Hyrule Castle East Entry'), - ('Wooden Bridge Mirror Spot', 'Wooden Bridge Area'), - ('Wooden Bridge Northeast Mirror Spot', 'Wooden Bridge Area'), - ('Wooden Bridge West Mirror Spot', 'Wooden Bridge Area'), - ('Eastern Palace Mirror Spot', 'Eastern Palace Area'), - ('Blacksmith Mirror Spot', 'Blacksmith Area'), - ('Blacksmith Entry Mirror Spot', 'Blacksmith Area'), - ('Bat Cave Ledge Mirror Spot', 'Bat Cave Ledge'), - ('Sand Dunes Mirror Spot', 'Sand Dunes Area'), - ('Maze Race Mirror Spot', 'Maze Race Ledge'), - ('Maze Race Ledge Mirror Spot', 'Maze Race Ledge'), - ('Kakariko Suburb Mirror Spot', 'Kakariko Suburb Area'), - ('Kakariko Suburb South Mirror Spot', 'Kakariko Suburb Area'), - ('Flute Boy Mirror Spot', 'Flute Boy Area'), - ('Flute Boy Pass Mirror Spot', 'Flute Boy Pass'), - ('Central Bonk Rocks Mirror Spot', 'Central Bonk Rocks Area'), - ('Links House Mirror Spot', 'Links House Area'), - ('Stone Bridge Mirror Spot', 'Stone Bridge Area'), - ('Stone Bridge South Mirror Spot', 'Stone Bridge Area'), - ('Hobo Mirror Spot', 'Stone Bridge Water'), - ('Tree Line Mirror Spot', 'Tree Line Area'), - ('Eastern Nook Mirror Spot', 'Eastern Nook Area'), - ('Desert Mirror Spot', 'Desert Area'), - ('Desert Ledge Mirror Spot', 'Desert Ledge'), - ('Checkerboard Mirror Spot', 'Desert Checkerboard Ledge'), - ('DP Stairs Mirror Spot', 'Desert Palace Stairs'), - ('DP Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), - ('Bombos Tablet Ledge Mirror Spot', 'Bombos Tablet Ledge'), - ('Flute Boy Entry Mirror Spot', 'Flute Boy Bush Entry'), - ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), - ('C Whirlpool Mirror Spot', 'C Whirlpool Area'), - ('C Whirlpool Outer Mirror Spot', 'C Whirlpool Outer Area'), - ('Desert Pass Ledge Mirror Spot', 'Desert Pass Ledge'), - ('Desert Pass Mirror Spot', 'Desert Pass Area'), - ('Dam Mirror Spot', 'Dam Area'), - ('Statues Mirror Spot', 'Statues Area'), - ('South Pass Mirror Spot', 'South Pass Area'), - ('Lake Hylia Mirror Spot', 'Lake Hylia Area'), - ('Lake Hylia Northeast Mirror Spot', 'Lake Hylia Northeast Bank'), - ('South Shore Mirror Spot', 'Lake Hylia South Shore'), - ('South Shore East Mirror Spot', 'Lake Hylia South Shore'), - ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), - ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), - ('Lake Hylia Water Mirror Spot', 'Lake Hylia Water'), - ('Octoballoon Mirror Spot', 'Octoballoon Area'), - ('Ice Cave Mirror Spot', 'Ice Cave Area'), +flute_connections = {0x03: ('Flute Spot 1', ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)']), + 0x16: ('Flute Spot 2', ['Potion Shop Area', 'Dark Witch Area']), + 0x18: ('Flute Spot 3', ['Kakariko Area', 'Village of Outcasts Area']), + 0x2c: ('Flute Spot 4', ['Links House Area', 'Big Bomb Shop Area']), + 0x2f: ('Flute Spot 5', ['Eastern Nook Area', 'Palace of Darkness Nook Area']), + 0x30: ('Flute Spot 6', ['Desert Palace Teleporter Ledge', 'Misery Mire Teleporter Ledge']), + 0x33: ('Flute Spot 7', ['Dam Area', 'Swamp Area']), + 0x3f: ('Flute Spot 8', ['Octoballoon Area', 'Bomber Corner Area']) + } - # Portal Connections - ('Kakariko Teleporter (Hammer)', 'Skull Woods Pass East Top Area'), - ('Kakariko Teleporter (Rock)', 'Skull Woods Pass East Top Area'), - ('Top of Pyramid', 'Pyramid Area'), - ('Top of Pyramid (Inner)', 'Pyramid Area'), - ('East Hyrule Teleporter', 'Palace of Darkness Nook Area'), - ('South Hyrule Teleporter', 'Dark C Whirlpool Area'), - ('Desert Teleporter', 'Misery Mire Teleporter Ledge'), - ('Lake Hylia Teleporter', 'Ice Palace Area'), - ('West Death Mountain Teleporter', 'West Dark Death Mountain (Bottom)'), - ('East Death Mountain Teleporter', 'East Dark Death Mountain (Bottom)'), - ('TR Pegs Teleporter', 'Turtle Rock Ledge') - ] - -inverted_connections = [('Flute Spot 1', 'West Dark Death Mountain (Bottom)'), - ('Flute Spot 2', 'Dark Witch Area'), - ('Flute Spot 3', 'Village of Outcasts Area'), - ('Flute Spot 4', 'Big Bomb Shop Area'), - ('Flute Spot 5', 'Palace of Darkness Nook Area'), - ('Flute Spot 6', 'Misery Mire Teleporter Ledge'), - ('Flute Spot 7', 'Swamp Area'), - ('Flute Spot 8', 'Bomber Corner Area'), - - ('Spectacle Rock Leave', 'West Death Mountain (Top)'), - ('Spectacle Rock Approach', 'Spectacle Rock Ledge'), - ('Floating Island Bridge (West)', 'East Death Mountain (Top East)'), - ('Floating Island Bridge (East)', 'Death Mountain Floating Island'), - ('East Death Mountain Mimic Ledge Drop', 'Mimic Cave Ledge'), - ('Mimic Ledge Drop', 'East Death Mountain (Bottom)'), - ('Graveyard Ladder (Top)', 'Graveyard Area'), - ('Graveyard Ladder (Bottom)', 'Graveyard Ledge'), - ('Checkerboard Ledge Approach', 'Desert Checkerboard Ledge'), - ('Checkerboard Ledge Leave', 'Desert Area'), - ('Cave 45 Inverted Leave', 'Flute Boy Approach Area'), - ('Cave 45 Inverted Approach', 'Cave 45 Ledge'), - ('Lake Hylia Island Pier', 'Lake Hylia Island'), - ('Desert Pass Ladder (North)', 'Desert Pass Area'), - ('Desert Pass Ladder (South)', 'Desert Pass Ledge'), - ('Dark Death Mountain Ladder (North)', 'West Dark Death Mountain (Bottom)'), - ('Dark Death Mountain Ladder (South)', 'West Dark Death Mountain (Top)'), - ('Dark South Teleporter Cliff Ledge Drop', 'Central Cliffs'), #OWG only, needs glove - ('Turtle Rock Tail Ledge Drop', 'Turtle Rock Ledge'), - ('Ice Palace Approach', 'Ice Palace Area'), - ('Ice Palace Leave', 'Ice Lake Moat'), - - # Mirror Connections - ('Skull Woods Back Mirror Spot', 'Skull Woods Forest (West)'), - ('Skull Woods Forgotten (West) Mirror Spot', 'Skull Woods Forgotten Path (Southwest)'), - ('Skull Woods Forgotten (East) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), - ('Skull Woods Portal Entry Mirror Spot', 'Skull Woods Portal Entry'), - ('Skull Woods Forgotten (Middle) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), - ('Skull Woods Front Mirror Spot', 'Skull Woods Forest'), - ('Dark Lumberjack Mirror Spot', 'Dark Lumberjack Area'), - ('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'), - ('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'), - ('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'), - ('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'), - ('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'), - ('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'), - ('TR Ledge (East) Mirror Spot', 'Dark Death Mountain Ledge'), - ('TR Isolated Mirror Spot', 'Dark Death Mountain Isolated Ledge'), - ('East Dark Death Mountain (Bottom Plateau) Mirror Spot', 'East Dark Death Mountain (Bottom)'), - ('East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Dark Death Mountain (Bottom Left)'), - ('East Dark Death Mountain (Bottom) Mirror Spot', 'East Dark Death Mountain (Bottom)'), - ('Dark Floating Island Mirror Spot', 'Dark Death Mountain Floating Island'), - ('Turtle Rock Mirror Spot', 'Turtle Rock Area'), - ('Turtle Rock Ledge Mirror Spot', 'Turtle Rock Ledge'), - ('Bumper Cave Area Mirror Spot', 'Bumper Cave Area'), - ('Bumper Cave Entry Mirror Spot', 'Bumper Cave Entrance'), - ('Bumper Cave Ledge Mirror Spot', 'Bumper Cave Ledge'), - ('Catfish Mirror Spot', 'Catfish Area'), - ('Skull Woods Pass West Mirror Spot', 'Skull Woods Pass West Area'), - ('Skull Woods Pass East Top Mirror Spot', 'Skull Woods Pass East Top Area'), - ('Skull Woods Pass East Bottom Mirror Spot', 'Skull Woods Pass East Bottom Area'), - ('Outcast Fortune Mirror Spot', 'Dark Fortune Area'), - ('Outcast Pond Mirror Spot', 'Outcast Pond Area'), - ('Dark Chapel Mirror Spot', 'Dark Chapel Area'), - ('Dark Chapel Ledge Mirror Spot', 'Dark Chapel Area'), - ('Dark Graveyard Mirror Spot', 'Dark Graveyard Area'), - ('Dark Graveyard Ledge Mirror Spot', 'Dark Graveyard Area'), - ('Dark Graveyard Grave Mirror Spot', 'Dark Graveyard Area'), - ('Qirn Jump Mirror Spot', 'Qirn Jump Area'), - ('Qirn Jump East Mirror Spot', 'Qirn Jump East Bank'), - ('Dark Witch Mirror Spot', 'Dark Witch Area'), - ('Dark Witch Northeast Mirror Spot', 'Dark Witch Northeast'), - ('Catfish Approach Mirror Spot', 'Catfish Approach Area'), - ('Catfish Approach Ledge Mirror Spot', 'Catfish Approach Ledge'), - ('Village of Outcasts Mirror Spot', 'Village of Outcasts Area'), - ('Village of Outcasts Southwest Mirror Spot', 'Village of Outcasts Area'), - ('Hammer House Mirror Spot', 'Dark Grassy Lawn'), - ('Shield Shop Mirror Spot', 'Shield Shop Area'), - ('Pyramid Mirror Spot', 'Pyramid Area'), - ('Pyramid Pass Mirror Spot', 'Pyramid Pass'), - ('Pyramid Courtyard Mirror Spot', 'Pyramid Area'), - ('Pyramid Uncle Mirror Spot', 'Pyramid Area'), - ('Pyramid From Ledge Mirror Spot', 'Pyramid Area'), - ('Pyramid Entry Mirror Spot', 'Pyramid Area'), - ('Broken Bridge West Mirror Spot', 'Broken Bridge West'), - ('Broken Bridge East Mirror Spot', 'Broken Bridge Area'), - ('Broken Bridge Northeast Mirror Spot', 'Broken Bridge Northeast'), - ('Palace of Darkness Mirror Spot', 'Palace of Darkness Area'), - ('Hammer Pegs Mirror Spot', 'Hammer Peg Area'), - ('Hammer Pegs Entry Mirror Spot', 'Hammer Peg Entry'), - ('Dark Dunes Mirror Spot', 'Dark Dunes Area'), - ('Dig Game Mirror Spot', 'Dig Game Area'), - ('Dig Game Ledge Mirror Spot', 'Dig Game Ledge'), - ('Frog Mirror Spot', 'Frog Area'), - ('Frog Prison Mirror Spot', 'Frog Prison'), - ('Archery Game Mirror Spot', 'Archery Game Area'), - ('Stumpy Mirror Spot', 'Stumpy Area'), - ('Stumpy Pass Mirror Spot', 'Stumpy Pass'), - ('Dark Bonk Rocks Mirror Spot', 'Dark Bonk Rocks Area'), - ('Big Bomb Shop Mirror Spot', 'Big Bomb Shop Area'), - ('Hammer Bridge North Mirror Spot', 'Hammer Bridge North Area'), - ('Hammer Bridge South Mirror Spot', 'Hammer Bridge South Area'), - ('Dark Hobo Mirror Spot', 'Hammer Bridge Water'), - ('Dark Tree Line Mirror Spot', 'Dark Tree Line Area'), - ('Darkness Nook Mirror Spot', 'Palace of Darkness Nook Area'), - ('Misery Mire Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Ledge Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Blocked Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Main Mirror Spot', 'Misery Mire Area'), - ('Stumpy Approach Mirror Spot', 'Stumpy Approach Area'), - ('Stumpy Bush Entry Mirror Spot', 'Stumpy Approach Bush Entry'), - ('Dark C Whirlpool Mirror Spot', 'Dark C Whirlpool Area'), - ('Dark C Whirlpool Outer Mirror Spot', 'Dark C Whirlpool Outer Area'), - ('Hype Cave Mirror Spot', 'Hype Cave Area'), - ('Ice Lake Mirror Spot', 'Ice Lake Area'), - ('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'), - ('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'), - ('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'), - ('Ice Palace Mirror Spot', 'Ice Palace Area'), - ('Shopping Mall Mirror Spot', 'Shopping Mall Area'), - ('Swmap Nook Mirror Spot', 'Swamp Nook Area'), - ('Swamp Nook Southeast Mirror Spot', 'Swamp Nook Area'), - ('Swamp Nook Pegs Mirror Spot', 'Swamp Nook Area'), - ('Swamp Mirror Spot', 'Swamp Area'), - ('Dark South Pass Mirror Spot', 'Dark South Pass Area'), - ('Bomber Corner Mirror Spot', 'Bomber Corner Area'), - - # Portal Connections - ('Post Aga Inverted Teleporter', 'Hyrule Castle Area'), - ('Ice Palace Teleporter', 'Lake Hylia Central Island'), - ('Misery Mire Teleporter', 'Desert Palace Teleporter Ledge'), - ('East Dark World Teleporter', 'Eastern Nook Area'), - ('South Dark World Teleporter', 'C Whirlpool Area'), - ('West Dark World Teleporter (Hammer)', 'Lost Woods Pass East Top Area'), - ('West Dark World Teleporter (Rock)', 'Lost Woods Pass East Bottom Area'), - ('Dark Death Mountain Teleporter (West)', 'West Death Mountain (Bottom)'), - ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Bottom)'), - ('Turtle Rock Teleporter', 'Death Mountain TR Pegs Ledge') - ] +ow_connections = { + 0x00: ([ + ('Lost Woods East Mirror Spot', 'Lost Woods East Area'), + ('Lost Woods Entry Mirror Spot', 'Lost Woods West Area'), + ('Lost Woods Pedestal Mirror Spot', 'Lost Woods West Area'), + ('Lost Woods Southwest Mirror Spot', 'Lost Woods West Area'), + ('Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods East Area'), + ('Lost Woods West (Forgotten) Mirror Spot', 'Lost Woods West Area') + ], [ + ('Skull Woods Back Mirror Spot', 'Skull Woods Forest (West)'), + ('Skull Woods Forgotten (West) Mirror Spot', 'Skull Woods Forgotten Path (Southwest)'), + ('Skull Woods Forgotten (East) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), + ('Skull Woods Portal Entry Mirror Spot', 'Skull Woods Portal Entry'), + ('Skull Woods Forgotten (Middle) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), + ('Skull Woods Front Mirror Spot', 'Skull Woods Forest') + ]), + 0x02: ([ + ('Lumberjack Mirror Spot', 'Lumberjack Area') + ], [ + ('Dark Lumberjack Mirror Spot', 'Dark Lumberjack Area') + ]), + 0x03: ([ + ('Spectacle Rock Mirror Spot', 'Spectacle Rock Ledge'), + ('West Death Mountain (Top) Mirror Spot', 'West Death Mountain (Top)'), + ('West Death Mountain Teleporter', 'West Dark Death Mountain (Bottom)') + ], [ + ('Spectacle Rock Leave', 'West Death Mountain (Top)'), + ('Spectacle Rock Approach', 'Spectacle Rock Ledge'), + ('Dark Death Mountain Ladder (North)', 'West Dark Death Mountain (Bottom)'), + ('Dark Death Mountain Ladder (South)', 'West Dark Death Mountain (Top)'), + ('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'), + ('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'), + ('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'), + ('Dark Death Mountain Teleporter (West)', 'West Death Mountain (Bottom)') + ]), + 0x05: ([ + ('East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top West)'), + ('East Death Mountain (Top East) Mirror Spot', 'East Death Mountain (Top East)'), + ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), + ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), + ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), + ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), + ('Death Mountain Bridge Mirror Spot', 'East Death Mountain (Bottom Left)'), + ('Floating Island Mirror Spot', 'Death Mountain Floating Island'), + ('East Death Mountain Teleporter', 'East Dark Death Mountain (Bottom)') + ], [ + ('Floating Island Bridge (West)', 'East Death Mountain (Top East)'), + ('Floating Island Bridge (East)', 'Death Mountain Floating Island'), + ('East Death Mountain Mimic Ledge Drop', 'Mimic Cave Ledge'), + ('Mimic Ledge Drop', 'East Death Mountain (Bottom)'), + ('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'), + ('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'), + ('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'), + ('TR Ledge (East) Mirror Spot', 'Dark Death Mountain Ledge'), + ('TR Isolated Mirror Spot', 'Dark Death Mountain Isolated Ledge'), + ('East Dark Death Mountain (Bottom Plateau) Mirror Spot', 'East Dark Death Mountain (Bottom)'), + ('East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Dark Death Mountain (Bottom Left)'), + ('East Dark Death Mountain (Bottom) Mirror Spot', 'East Dark Death Mountain (Bottom)'), + ('Dark Floating Island Mirror Spot', 'Dark Death Mountain Floating Island'), + ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Bottom)') + ]), + 0x07: ([ + ('TR Pegs Area Mirror Spot', 'Death Mountain TR Pegs'), + ('TR Pegs Teleporter', 'Turtle Rock Ledge') + ], [ + ('Turtle Rock Tail Ledge Drop', 'Turtle Rock Ledge'), + ('Turtle Rock Mirror Spot', 'Turtle Rock Area'), + ('Turtle Rock Ledge Mirror Spot', 'Turtle Rock Ledge'), + ('Turtle Rock Teleporter', 'Death Mountain TR Pegs Ledge') + ]), + 0x0a: ([ + ('Mountain Entry Mirror Spot', 'Mountain Entry Area'), + ('Mountain Entry Entrance Mirror Spot', 'Mountain Entry Entrance'), + ('Mountain Entry Ledge Mirror Spot', 'Mountain Entry Ledge') + ], [ + ('Bumper Cave Area Mirror Spot', 'Bumper Cave Area'), + ('Bumper Cave Entry Mirror Spot', 'Bumper Cave Entrance'), + ('Bumper Cave Ledge Mirror Spot', 'Bumper Cave Ledge') + ]), + 0x0f: ([ + ('Zora Waterfall Mirror Spot', 'Zora Waterfall Area') + ], [ + ('Catfish Mirror Spot', 'Catfish Area') + ]), + 0x10: ([ + ('Lost Woods Pass West Mirror Spot', 'Lost Woods Pass West Area'), + ('Lost Woods Pass East Top Mirror Spot', 'Lost Woods Pass East Top Area'), + ('Lost Woods Pass East Bottom Mirror Spot', 'Lost Woods Pass East Bottom Area'), + ('Kakariko Teleporter (Hammer)', 'Skull Woods Pass East Top Area'), + ('Kakariko Teleporter (Rock)', 'Skull Woods Pass East Top Area') + ], [ + ('Skull Woods Pass West Mirror Spot', 'Skull Woods Pass West Area'), + ('Skull Woods Pass East Top Mirror Spot', 'Skull Woods Pass East Top Area'), + ('Skull Woods Pass East Bottom Mirror Spot', 'Skull Woods Pass East Bottom Area'), + ('West Dark World Teleporter (Hammer)', 'Lost Woods Pass East Top Area'), + ('West Dark World Teleporter (Rock)', 'Lost Woods Pass East Bottom Area') + ]), + 0x11: ([ + ('Kakariko Fortune Mirror Spot', 'Kakariko Fortune Area') + ], [ + ('Outcast Fortune Mirror Spot', 'Dark Fortune Area') + ]), + 0x12: ([ + ('Kakariko Pond Mirror Spot', 'Kakariko Pond Area') + ], [ + ('Outcast Pond Mirror Spot', 'Outcast Pond Area') + ]), + 0x13: ([ + ('Sanctuary Mirror Spot', 'Sanctuary Area'), + ('Bonk Rock Ledge Mirror Spot', 'Bonk Rock Ledge') + ], [ + ('Dark Chapel Mirror Spot', 'Dark Chapel Area'), + ('Dark Chapel Ledge Mirror Spot', 'Dark Chapel Area') + ]), + 0x14: ([ + ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), + ('Kings Grave Mirror Spot', 'Kings Grave Area') + ], [ + ('Graveyard Ladder (Top)', 'Graveyard Area'), + ('Graveyard Ladder (Bottom)', 'Graveyard Ledge'), + ('Dark Graveyard Mirror Spot', 'Dark Graveyard Area'), + ('Dark Graveyard Ledge Mirror Spot', 'Dark Graveyard Area'), + ('Dark Graveyard Grave Mirror Spot', 'Dark Graveyard Area') + ]), + 0x15: ([ + ('River Bend Mirror Spot', 'River Bend Area'), + ('River Bend East Mirror Spot', 'River Bend East Bank') + ], [ + ('Qirn Jump Mirror Spot', 'Qirn Jump Area'), + ('Qirn Jump East Mirror Spot', 'Qirn Jump East Bank') + ]), + 0x16: ([ + ('Potion Shop Mirror Spot', 'Potion Shop Area'), + ('Potion Shop Northeast Mirror Spot', 'Potion Shop Northeast') + ], [ + ('Dark Witch Mirror Spot', 'Dark Witch Area'), + ('Dark Witch Northeast Mirror Spot', 'Dark Witch Northeast') + ]), + 0x17: ([ + ('Zora Approach Mirror Spot', 'Zora Approach Area'), + ('Zora Approach Ledge Mirror Spot', 'Zora Approach Ledge') + ], [ + ('Catfish Approach Mirror Spot', 'Catfish Approach Area'), + ('Catfish Approach Ledge Mirror Spot', 'Catfish Approach Ledge') + ]), + 0x18: ([ + ('Kakariko Mirror Spot', 'Kakariko Area'), + ('Kakariko Grass Mirror Spot', 'Kakariko Area') + ], [ + ('Village of Outcasts Mirror Spot', 'Village of Outcasts Area'), + ('Village of Outcasts Southwest Mirror Spot', 'Village of Outcasts Area'), + ('Hammer House Mirror Spot', 'Dark Grassy Lawn') + ]), + 0x1a: ([ + ('Forgotton Forest Mirror Spot', 'Forgotten Forest Area'), + ('Forgotton Forest Fence Mirror Spot', 'Forgotten Forest Area') + ], [ + ('Shield Shop Mirror Spot', 'Shield Shop Area') + ]), + 0x1b: ([ + ('HC Ledge Mirror Spot', 'Hyrule Castle Ledge'), + ('HC Courtyard Mirror Spot', 'Hyrule Castle Courtyard'), + ('HC Area Mirror Spot', 'Hyrule Castle Area'), + ('HC Area South Mirror Spot', 'Hyrule Castle Area'), + ('HC East Entry Mirror Spot', 'Hyrule Castle East Entry'), + ('Top of Pyramid', 'Pyramid Area'), + ('Top of Pyramid (Inner)', 'Pyramid Area') + ], [ + ('Pyramid Mirror Spot', 'Pyramid Area'), + ('Pyramid Pass Mirror Spot', 'Pyramid Pass'), + ('Pyramid Courtyard Mirror Spot', 'Pyramid Area'), + ('Pyramid Uncle Mirror Spot', 'Pyramid Area'), + ('Pyramid From Ledge Mirror Spot', 'Pyramid Area'), + ('Pyramid Entry Mirror Spot', 'Pyramid Area'), + ('Post Aga Inverted Teleporter', 'Hyrule Castle Area') + ]), + 0x1d: ([ + ('Wooden Bridge Mirror Spot', 'Wooden Bridge Area'), + ('Wooden Bridge Northeast Mirror Spot', 'Wooden Bridge Area'), + ('Wooden Bridge West Mirror Spot', 'Wooden Bridge Area') + ], [ + ('Broken Bridge West Mirror Spot', 'Broken Bridge West'), + ('Broken Bridge East Mirror Spot', 'Broken Bridge Area'), + ('Broken Bridge Northeast Mirror Spot', 'Broken Bridge Northeast') + ]), + 0x1e: ([ + ('Eastern Palace Mirror Spot', 'Eastern Palace Area') + ], [ + ('Palace of Darkness Mirror Spot', 'Palace of Darkness Area') + ]), + 0x22: ([ + ('Blacksmith Mirror Spot', 'Blacksmith Area'), + ('Blacksmith Entry Mirror Spot', 'Blacksmith Area'), + ('Bat Cave Ledge Mirror Spot', 'Bat Cave Ledge') + ], [ + ('Hammer Pegs Mirror Spot', 'Hammer Peg Area'), + ('Hammer Pegs Entry Mirror Spot', 'Hammer Peg Entry') + ]), + 0x25: ([ + ('Sand Dunes Mirror Spot', 'Sand Dunes Area') + ], [ + ('Dark Dunes Mirror Spot', 'Dark Dunes Area') + ]), + 0x28: ([ + ('Maze Race Mirror Spot', 'Maze Race Ledge'), + ('Maze Race Ledge Mirror Spot', 'Maze Race Ledge') + ], [ + ('Dig Game Mirror Spot', 'Dig Game Area'), + ('Dig Game Ledge Mirror Spot', 'Dig Game Ledge') + ]), + 0x29: ([ + ('Kakariko Suburb Mirror Spot', 'Kakariko Suburb Area'), + ('Kakariko Suburb South Mirror Spot', 'Kakariko Suburb Area') + ], [ + ('Frog Mirror Spot', 'Frog Area'), + ('Frog Prison Mirror Spot', 'Frog Prison'), + ('Archery Game Mirror Spot', 'Archery Game Area') + ]), + 0x2a: ([ + ('Flute Boy Mirror Spot', 'Flute Boy Area'), + ('Flute Boy Pass Mirror Spot', 'Flute Boy Pass') + ], [ + ('Stumpy Mirror Spot', 'Stumpy Area'), + ('Stumpy Pass Mirror Spot', 'Stumpy Pass') + ]), + 0x2b: ([ + ('Central Bonk Rocks Mirror Spot', 'Central Bonk Rocks Area') + ], [ + ('Dark Bonk Rocks Mirror Spot', 'Dark Bonk Rocks Area') + ]), + 0x2c: ([ + ('Links House Mirror Spot', 'Links House Area') + ], [ + ('Big Bomb Shop Mirror Spot', 'Big Bomb Shop Area') + ]), + 0x2d: ([ + ('Stone Bridge Mirror Spot', 'Stone Bridge Area'), + ('Stone Bridge South Mirror Spot', 'Stone Bridge Area'), + ('Hobo Mirror Spot', 'Stone Bridge Water') + ], [ + ('Hammer Bridge North Mirror Spot', 'Hammer Bridge North Area'), + ('Hammer Bridge South Mirror Spot', 'Hammer Bridge South Area'), + ('Dark Hobo Mirror Spot', 'Hammer Bridge Water') + ]), + 0x2e: ([ + ('Tree Line Mirror Spot', 'Tree Line Area') + ], [ + ('Dark Tree Line Mirror Spot', 'Dark Tree Line Area') + ]), + 0x2f: ([ + ('Eastern Nook Mirror Spot', 'Eastern Nook Area'), + ('East Hyrule Teleporter', 'Palace of Darkness Nook Area') + ], [ + ('Darkness Nook Mirror Spot', 'Palace of Darkness Nook Area'), + ('East Dark World Teleporter', 'Eastern Nook Area') + ]), + 0x30: ([ + ('Desert Mirror Spot', 'Desert Area'), + ('Desert Ledge Mirror Spot', 'Desert Ledge'), + ('Checkerboard Mirror Spot', 'Desert Checkerboard Ledge'), + ('DP Stairs Mirror Spot', 'Desert Palace Stairs'), + ('DP Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), + ('Bombos Tablet Ledge Mirror Spot', 'Bombos Tablet Ledge'), + ('Desert Teleporter', 'Misery Mire Teleporter Ledge') + ], [ + ('Checkerboard Ledge Approach', 'Desert Checkerboard Ledge'), + ('Checkerboard Ledge Leave', 'Desert Area'), + ('Misery Mire Mirror Spot', 'Misery Mire Area'), + ('Misery Mire Ledge Mirror Spot', 'Misery Mire Area'), + ('Misery Mire Blocked Mirror Spot', 'Misery Mire Area'), + ('Misery Mire Main Mirror Spot', 'Misery Mire Area'), + ('Misery Mire Teleporter', 'Desert Palace Teleporter Ledge') + ]), + 0x32: ([ + ('Flute Boy Entry Mirror Spot', 'Flute Boy Bush Entry'), + ('Cave 45 Mirror Spot', 'Cave 45 Ledge') + ], [ + ('Cave 45 Inverted Leave', 'Flute Boy Approach Area'), + ('Cave 45 Inverted Approach', 'Cave 45 Ledge'), + ('Stumpy Approach Mirror Spot', 'Stumpy Approach Area'), + ('Stumpy Bush Entry Mirror Spot', 'Stumpy Approach Bush Entry') + ]), + 0x33: ([ + ('C Whirlpool Mirror Spot', 'C Whirlpool Area'), + ('C Whirlpool Outer Mirror Spot', 'C Whirlpool Outer Area'), + ('South Hyrule Teleporter', 'Dark C Whirlpool Area') + ], [ + ('Dark C Whirlpool Mirror Spot', 'Dark C Whirlpool Area'), + ('Dark C Whirlpool Outer Mirror Spot', 'Dark C Whirlpool Outer Area'), + ('South Dark World Teleporter', 'C Whirlpool Area'), + ('Dark South Teleporter Cliff Ledge Drop', 'Central Cliffs') #OWG only, needs glove + ]), + 0x34: ([ + ('Statues Mirror Spot', 'Statues Area') + ], [ + ('Hype Cave Mirror Spot', 'Hype Cave Area') + ]), + 0x35: ([ + ('Lake Hylia Mirror Spot', 'Lake Hylia Area'), + ('Lake Hylia Northeast Mirror Spot', 'Lake Hylia Northeast Bank'), + ('South Shore Mirror Spot', 'Lake Hylia South Shore'), + ('South Shore East Mirror Spot', 'Lake Hylia South Shore'), + ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), + ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), + ('Lake Hylia Water Mirror Spot', 'Lake Hylia Water'), + ('Lake Hylia Teleporter', 'Ice Palace Area') + ], [ + ('Lake Hylia Island Pier', 'Lake Hylia Island'), + ('Ice Palace Approach', 'Ice Palace Area'), + ('Ice Palace Leave', 'Ice Lake Moat'), + ('Ice Lake Mirror Spot', 'Ice Lake Area'), + ('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'), + ('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'), + ('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'), + ('Ice Palace Mirror Spot', 'Ice Palace Area'), + ('Ice Palace Teleporter', 'Lake Hylia Central Island') + ]), + 0x37: ([ + ('Ice Cave Mirror Spot', 'Ice Cave Area') + ], [ + ('Shopping Mall Mirror Spot', 'Shopping Mall Area') + ]), + 0x3a: ([ + ('Desert Pass Ledge Mirror Spot', 'Desert Pass Ledge'), + ('Desert Pass Mirror Spot', 'Desert Pass Area') + ], [ + ('Desert Pass Ladder (North)', 'Desert Pass Area'), + ('Desert Pass Ladder (South)', 'Desert Pass Ledge'), + ('Swamp Nook Mirror Spot', 'Swamp Nook Area'), + ('Swamp Nook Southeast Mirror Spot', 'Swamp Nook Area'), + ('Swamp Nook Pegs Mirror Spot', 'Swamp Nook Area') + ]), + 0x3b: ([ + ('Dam Mirror Spot', 'Dam Area') + ], [ + ('Swamp Mirror Spot', 'Swamp Area') + ]), + 0x3c: ([ + ('South Pass Mirror Spot', 'South Pass Area') + ], [ + ('Dark South Pass Mirror Spot', 'Dark South Pass Area') + ]), + 0x3f: ([ + ('Octoballoon Mirror Spot', 'Octoballoon Area') + ], [ + ('Bomber Corner Mirror Spot', 'Bomber Corner Area') + ]) +} parallelsimilar_connections = [('Maze Race ES', 'Kakariko Suburb WS'), ('Dig Game EC', 'Frog WC'), diff --git a/Regions.py b/Regions.py index f0315796..bbec1ca0 100644 --- a/Regions.py +++ b/Regions.py @@ -111,7 +111,7 @@ def create_regions(world, player): create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']), create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool']), create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']), - create_lw_region(player, 'Desert Pass Area', ['Purple Chest'], ['Desert Pass Ladder (South)', 'Desert Fairy', '50 Rupee Cave', 'Swmap Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), + create_lw_region(player, 'Desert Pass Area', ['Purple Chest'], ['Desert Pass Ladder (South)', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Swamp Nook Southeast Mirror Spot', 'Desert Pass ES']), create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Swamp Nook Pegs Mirror Spot', 'Desert Pass WC']), create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Swamp Mirror Spot', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']), @@ -147,7 +147,7 @@ def create_regions(world, player): create_dw_region(player, 'Skull Woods Pass East Bottom Area', None, ['Skull Woods Pass Rock (Bottom)', 'Lost Woods Pass East Bottom Mirror Spot', 'Skull Woods Pass SE']), create_dw_region(player, 'Dark Fortune Area', None, ['Fortune Teller (Dark)', 'Kakariko Fortune Mirror Spot', 'Dark Fortune NE', 'Dark Fortune EN', 'Dark Fortune ES', 'Dark Fortune SC']), create_dw_region(player, 'Outcast Pond Area', None, ['Kakariko Pond Mirror Spot', 'Outcast Pond NE', 'Outcast Pond WN', 'Outcast Pond WS', 'Outcast Pond SW', 'Outcast Pond SE', 'Outcast Pond EN', 'Outcast Pond ES']), - create_dw_region(player, 'Dark Chapel Area', None, ['Dark Sanctuary Hint', 'Bonk Rock Ledge Mirror Spot', 'Dark Chapel WN', 'Dark Chapel WS', 'Dark Chapel EC']), + create_dw_region(player, 'Dark Chapel Area', None, ['Dark Sanctuary Hint', 'Sanctuary Mirror Spot', 'Bonk Rock Ledge Mirror Spot', 'Dark Chapel WN', 'Dark Chapel WS', 'Dark Chapel EC']), create_dw_region(player, 'Dark Graveyard Area', None, ['Graveyard Ledge Mirror Spot', 'Kings Grave Mirror Spot', 'Dark Graveyard WC', 'Dark Graveyard EC']), create_dw_region(player, 'Qirn Jump Area', None, ['Qirn Jump Water Drop', 'River Bend Mirror Spot', 'Qirn Jump WC', 'Qirn Jump SW']), create_dw_region(player, 'Qirn Jump East Bank', None, ['Qirn Jump East Water Drop', 'River Bend East Mirror Spot', 'Qirn Jump SE', 'Qirn Jump EC', 'Qirn Jump ES']), diff --git a/Rom.py b/Rom.py index 9f5ba574..fdc5a39a 100644 --- a/Rom.py +++ b/Rom.py @@ -27,7 +27,7 @@ from EntranceShuffle import door_addresses, exit_ids JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '2f83a44f0ac2720b489d50bfa8e56837' +RANDOMIZERBASEHASH = '03a63945398191337e896e5771f77173' class JsonRom(object): @@ -592,7 +592,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): write_pots_to_rom(rom, world.pot_contents[player]) # patch overworld edges - if world.owShuffle[player] != 'vanilla': + if world.owShuffle[player] != 'vanilla' or world.owSwap[player] != 'vanilla': rom.write_byte(0x18004C, 0x01) #patch for allowing Frogsmith to enter multi-entrance caves #patches map data specific for OW Shuffle rom.buffer[0x153B03] = rom.buffer[0x153B03] | 0x2 #convenient portal on WDM @@ -606,18 +606,39 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.buffer[0x153B62] = rom.buffer[0x153B62] | 0x2 #rocks added to prevent OWG hardlock rom.buffer[0x153B7F] = rom.buffer[0x153B7F] | 0x2 #added C to terrain + + owMode = 0 if world.owShuffle[player] == 'parallel': owMode = 1 elif world.owShuffle[player] == 'full': owMode = 2 - rom.write_byte(0x150002, owMode) + if world.owSwap[player] == 'mixed': + owMode |= 0x100 + world.fix_fake_world[player] = True + elif world.owSwap[player] == 'crossed': + owMode |= 0x200 + world.fix_fake_world[player] = True + + write_int16(rom, 0x150002, owMode) owFlags = 0 if world.owKeepSimilar[player]: - owFlags += 0x1 + owFlags |= 0x1 - write_int16(rom, 0x150003, owFlags) + write_int16(rom, 0x150004, owFlags) + + if world.owSwap[player] == 'mixed': + for b in world.owswaps[player][0]: + # load inverted maps + v = rom.buffer[0x153B00 + b] + v = (v & 0xFE) | ((v + 1) % 2) + rom.buffer[0x153B00 + b] = v + + # set world flag + v = rom.buffer[0x153A00 + b] + v = (v & 0xBF) | ((((v >> 6) + 1) % 2) << 6) + rom.buffer[0x153A00 + b] = v for edge in world.owedges: if edge.dest is not None and isinstance(edge.dest, OWEdge) and edge.player == player: @@ -895,11 +916,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # set open mode: if world.mode[player] in ['open', 'inverted']: rom.write_byte(0x180032, 0x01) # open mode - if world.mode[player] == 'inverted': - set_inverted_mode(world, player, rom) elif world.mode[player] == 'standard': rom.write_byte(0x180032, 0x00) # standard mode + set_inverted_mode(world, player, rom) + uncle_location = world.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']: # disable sword sprite from uncle @@ -2221,211 +2242,265 @@ def write_strings(rom, world, player, team): rom.write_bytes(0x76CC0, [byte for p in pointers for byte in [p & 0xFF, p >> 8 & 0xFF]]) def set_inverted_mode(world, player, rom): - # flip inverted map flags - for b in range(0x00, 0x80): - v = rom.buffer[0x153B00 + b] - rom.buffer[0x153B00 + b] = (v & 0xFE) | ((v + 1) % 2) + if world.mode[player] == 'inverted': + # load inverted maps + for b in range(0x00, 0x82): + v = rom.buffer[0x153B00 + b] + rom.buffer[0x153B00 + b] = (v & 0xFE) | ((v + 1) % 2) - 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) - rom.write_byte(snes_to_pc(0x05AF79), 0xF0) - rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6) - rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck - write_int16s(rom, snes_to_pc(0x02E849), [0x0043, 0x0056, 0x0058, 0x006C, 0x006F, 0x0070, 0x007B, 0x007F, 0x001B]) # dw flute - write_int16(rom, snes_to_pc(0x02E8D5), 0x07C8) - write_int16(rom, snes_to_pc(0x02E8F7), 0x01F8) - 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.shuffle[player] == 'vanilla': - rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT - rom.write_byte(0xDBB73 + 0x36, 0x24) - if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: - write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) - write_int16(rom, 0x15AEE + 2*0x25, 0x000C) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0x15B8C, 0x6C) - rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house - rom.write_byte(0xDBB73 + 0x52, 0x01) - rom.write_byte(0xDBB73 + 0x15, 0x06) # bumper and old man cave - write_int16(rom, 0x15AEE + 2*0x17, 0x00F0) - rom.write_byte(0xDBB73 + 0x05, 0x16) - write_int16(rom, 0x15AEE + 2*0x07, 0x00FB) - rom.write_byte(0xDBB73 + 0x2D, 0x17) - write_int16(rom, 0x15AEE + 2*0x2F, 0x00EB) - rom.write_byte(0xDBB73 + 0x06, 0x2E) - write_int16(rom, 0x15AEE + 2*0x08, 0x00E6) - rom.write_byte(0xDBB73 + 0x16, 0x5E) - rom.write_byte(0xDBB73 + 0x6F, 0x07) # DDM fairy to old man cave - write_int16(rom, 0x15AEE + 2*0x18, 0x00F1) - rom.write_byte(0x15B8C + 0x18, 0x43) - write_int16(rom, 0x15BDB + 2 * 0x18, 0x1400) - write_int16(rom, 0x15C79 + 2 * 0x18, 0x0294) - write_int16(rom, 0x15D17 + 2 * 0x18, 0x0600) - write_int16(rom, 0x15DB5 + 2 * 0x18, 0x02E8) - write_int16(rom, 0x15E53 + 2 * 0x18, 0x0678) - write_int16(rom, 0x15EF1 + 2 * 0x18, 0x0303) - write_int16(rom, 0x15F8F + 2 * 0x18, 0x0685) - rom.write_byte(0x1602D + 0x18, 0x0A) - rom.write_byte(0x1607C + 0x18, 0xF6) - write_int16(rom, 0x160CB + 2 * 0x18, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x18, 0x0000) - write_int16(rom, 0x15AEE + 2 * 0x3D, 0x0003) # pyramid exit and houlihan - rom.write_byte(0x15B8C + 0x3D, 0x5B) - write_int16(rom, 0x15BDB + 2 * 0x3D, 0x0B0E) - write_int16(rom, 0x15C79 + 2 * 0x3D, 0x075A) - write_int16(rom, 0x15D17 + 2 * 0x3D, 0x0674) - write_int16(rom, 0x15DB5 + 2 * 0x3D, 0x07A8) - write_int16(rom, 0x15E53 + 2 * 0x3D, 0x06E8) - write_int16(rom, 0x15EF1 + 2 * 0x3D, 0x07C7) - write_int16(rom, 0x15F8F + 2 * 0x3D, 0x06F3) - rom.write_byte(0x1602D + 0x3D, 0x06) - rom.write_byte(0x1607C + 0x3D, 0xFA) - write_int16(rom, 0x160CB + 2 * 0x3D, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x3D, 0x0000) - write_int16(rom, snes_to_pc(0x02D8D4), 0x112) # change sactuary spawn point to dark sanc - rom.write_bytes(snes_to_pc(0x02D8E8), [0x22, 0x22, 0x22, 0x23, 0x04, 0x04, 0x04, 0x05]) - write_int16(rom, snes_to_pc(0x02D91A), 0x0400) - write_int16(rom, snes_to_pc(0x02D928), 0x222E) - write_int16(rom, snes_to_pc(0x02D936), 0x229A) - write_int16(rom, snes_to_pc(0x02D944), 0x0480) - write_int16(rom, snes_to_pc(0x02D952), 0x00A5) - write_int16(rom, snes_to_pc(0x02D960), 0x007F) - rom.write_byte(snes_to_pc(0x02D96D), 0x14) - rom.write_byte(snes_to_pc(0x02D974), 0x00) - rom.write_byte(snes_to_pc(0x02D97B), 0xFF) - rom.write_byte(snes_to_pc(0x02D982), 0x00) - rom.write_byte(snes_to_pc(0x02D989), 0x02) - rom.write_byte(snes_to_pc(0x02D990), 0x00) - write_int16(rom, snes_to_pc(0x02D998), 0x0000) - write_int16(rom, 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.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']: - rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) - write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) - rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) - write_int16(rom, snes_to_pc(0x02D924), 0x0300) - write_int16(rom, snes_to_pc(0x02D932), 0x1F10) - write_int16(rom, snes_to_pc(0x02D940), 0x1FC0) - write_int16(rom, snes_to_pc(0x02D94E), 0x0378) - write_int16(rom, snes_to_pc(0x02D95C), 0x0187) - write_int16(rom, snes_to_pc(0x02D96A), 0x017F) - rom.write_byte(snes_to_pc(0x02D972), 0x06) - rom.write_byte(snes_to_pc(0x02D979), 0x00) - rom.write_byte(snes_to_pc(0x02D980), 0xFF) - rom.write_byte(snes_to_pc(0x02D987), 0x00) - rom.write_byte(snes_to_pc(0x02D98E), 0x22) - rom.write_byte(snes_to_pc(0x02D995), 0x12) - write_int16(rom, snes_to_pc(0x02D9A2), 0x0000) - write_int16(rom, snes_to_pc(0x02D9B0), 0x0007) - rom.write_byte(snes_to_pc(0x02D9B8), 0x12) - rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) - write_int16(rom, 0x15AEE + 2 * 0x06, 0x0020) # post aga hyrule castle spawn - rom.write_byte(0x15B8C + 0x06, 0x1B) - write_int16(rom, 0x15BDB + 2 * 0x06, 0x00AE) - write_int16(rom, 0x15C79 + 2 * 0x06, 0x0610) - write_int16(rom, 0x15D17 + 2 * 0x06, 0x077E) - write_int16(rom, 0x15DB5 + 2 * 0x06, 0x0672) - write_int16(rom, 0x15E53 + 2 * 0x06, 0x07F8) - write_int16(rom, 0x15EF1 + 2 * 0x06, 0x067D) - write_int16(rom, 0x15F8F + 2 * 0x06, 0x0803) - rom.write_byte(0x1602D + 0x06, 0x00) - rom.write_byte(0x1607C + 0x06, 0xF2) - write_int16(rom, 0x160CB + 2 * 0x06, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x06, 0x0000) - write_int16(rom, snes_to_pc(0x02E87B), 0x00AE) # move flute splot 9 - write_int16(rom, snes_to_pc(0x02E89D), 0x0610) - write_int16(rom, snes_to_pc(0x02E8BF), 0x077E) - write_int16(rom, snes_to_pc(0x02E8E1), 0x0672) - write_int16(rom, snes_to_pc(0x02E903), 0x07F8) - write_int16(rom, snes_to_pc(0x02E925), 0x067D) - write_int16(rom, snes_to_pc(0x02E947), 0x0803) - write_int16(rom, snes_to_pc(0x02E969), 0x0000) - write_int16(rom, snes_to_pc(0x02E98B), 0xFFF2) - rom.write_byte(snes_to_pc(0x1AF696), 0xF0) # bat sprite retreat - rom.write_byte(snes_to_pc(0x1AF6B2), 0x33) - rom.write_bytes(snes_to_pc(0x1AF730), [0x6A, 0x9E, 0x0C, 0x00, 0x7A, 0x9E, 0x0C, - 0x00, 0x8A, 0x9E, 0x0C, 0x00, 0x6A, 0xAE, - 0x0C, 0x00, 0x7A, 0xAE, 0x0C, 0x00, 0x8A, - 0xAE, 0x0C, 0x00, 0x67, 0x97, 0x0C, 0x00, - 0x8D, 0x97, 0x0C, 0x00]) - write_int16s(rom, snes_to_pc(0x0FF1C8), [0x190F, 0x190F, 0x190F, 0x194C, 0x190F, - 0x194B, 0x190F, 0x195C, 0x594B, 0x194C, - 0x19EE, 0x19EE, 0x194B, 0x19EE, 0x19EE, - 0x19EE, 0x594B, 0x190F, 0x595C, 0x190F, - 0x190F, 0x195B, 0x190F, 0x190F, 0x19EE, - 0x19EE, 0x195C, 0x19EE, 0x19EE, 0x19EE, - 0x19EE, 0x595C, 0x595B, 0x190F, 0x190F, - 0x190F]) - write_int16s(rom, snes_to_pc(0x0FA480), [0x190F, 0x196B, 0x9D04, 0x9D04, 0x196B, - 0x190F, 0x9D04, 0x9D04]) - write_int16s(rom, snes_to_pc(0x1bb810), [0x00BE, 0x00C0, 0x013E]) - write_int16s(rom, snes_to_pc(0x1bb836), [0x001B, 0x001B, 0x001B]) - write_int16(rom, snes_to_pc(0x308300), 0x0140) # new pyramid hole entrance - write_int16(rom, snes_to_pc(0x308320), 0x001B) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(snes_to_pc(0x308340), 0x7B) - write_int16(rom, snes_to_pc(0x1af504), 0x148B) - write_int16(rom, snes_to_pc(0x1af50c), 0x149B) - write_int16(rom, snes_to_pc(0x1af514), 0x14A4) - write_int16(rom, snes_to_pc(0x1af51c), 0x1489) - write_int16(rom, snes_to_pc(0x1af524), 0x14AC) - write_int16(rom, snes_to_pc(0x1af52c), 0x54AC) - write_int16(rom, snes_to_pc(0x1af534), 0x148C) - write_int16(rom, snes_to_pc(0x1af53c), 0x548C) - write_int16(rom, snes_to_pc(0x1af544), 0x1484) - write_int16(rom, snes_to_pc(0x1af54c), 0x5484) - write_int16(rom, snes_to_pc(0x1af554), 0x14A2) - write_int16(rom, snes_to_pc(0x1af55c), 0x54A2) - write_int16(rom, snes_to_pc(0x1af564), 0x14A0) - write_int16(rom, snes_to_pc(0x1af56c), 0x54A0) - write_int16(rom, snes_to_pc(0x1af574), 0x148E) - write_int16(rom, snes_to_pc(0x1af57c), 0x548E) - write_int16(rom, snes_to_pc(0x1af584), 0x14AE) - write_int16(rom, snes_to_pc(0x1af58c), 0x54AE) - rom.write_byte(snes_to_pc(0x00DB9D), 0x1A) # castle hole graphics - rom.write_byte(snes_to_pc(0x00DC09), 0x1A) - rom.write_byte(snes_to_pc(0x00D009), 0x31) - rom.write_byte(snes_to_pc(0x00D0e8), 0xE0) - rom.write_byte(snes_to_pc(0x00D1c7), 0x00) - write_int16(rom, snes_to_pc(0x1BE8DA), 0x39AD) - rom.write_byte(0xF6E58, 0x80) # no whirlpool under castle gate - rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail - rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warps under rocks - rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) - rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) - rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) - rom.write_bytes(snes_to_pc(0x1BC3DF), [0xD8, 0xD1]) - rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) - rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) - write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door - write_int16(rom, 0xDBA71 + 2 * 0x35, 0x011C) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0xDBB73 + 0x35, 0x36) - rom.write_byte(snes_to_pc(0x09D436), 0xF3) # remove castle gate warp - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area - rom.write_byte(0x15B8C + 0x37, 0x1B) - write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E) - write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600) - write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676) - write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604) - write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8) - write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D) - write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3) - rom.write_byte(0x1602D + 0x37, 0x00) - rom.write_byte(0x1607C + 0x37, 0x0A) - write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x37, 0x811c) - rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) - rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) - rom.write_byte(0x180089, 0x01) # open TR after exit - rom.write_byte(snes_to_pc(0x0ABFBB), 0x90) - rom.write_byte(snes_to_pc(0x0280A6), 0xD0) - rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) + 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) # dark-style portal + rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6) #vortex + + rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck + rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph poof + rom.write_byte(snes_to_pc(0x0ABFBB), 0x90) # move mirror portal indicator to correct map (0xB0 normally) + rom.write_byte(snes_to_pc(0x0280A6), 0xD0) # use starting point prompt instead of start at pyramid + + write_int16(rom, snes_to_pc(0x02D8D4), 0x112) # change sanctuary spawn point to dark sanc + rom.write_bytes(snes_to_pc(0x02D8E8), [0x22, 0x22, 0x22, 0x23, 0x04, 0x04, 0x04, 0x05]) + write_int16(rom, snes_to_pc(0x02D91A), 0x0400) + write_int16(rom, snes_to_pc(0x02D928), 0x222E) + write_int16(rom, snes_to_pc(0x02D936), 0x229A) + write_int16(rom, snes_to_pc(0x02D944), 0x0480) + write_int16(rom, snes_to_pc(0x02D952), 0x00A5) + write_int16(rom, snes_to_pc(0x02D960), 0x007F) + rom.write_byte(snes_to_pc(0x02D96D), 0x14) + rom.write_byte(snes_to_pc(0x02D974), 0x00) + rom.write_byte(snes_to_pc(0x02D97B), 0xFF) + rom.write_byte(snes_to_pc(0x02D982), 0x00) + rom.write_byte(snes_to_pc(0x02D989), 0x02) + rom.write_byte(snes_to_pc(0x02D990), 0x00) + write_int16(rom, snes_to_pc(0x02D998), 0x0000) + write_int16(rom, snes_to_pc(0x02D9A6), 0x005A) + rom.write_byte(snes_to_pc(0x02D9B3), 0x12) + + if world.shuffle[player] == 'vanilla': + rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT + rom.write_byte(0xDBB73 + 0x36, 0x24) + if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: + write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) + write_int16(rom, 0x15AEE + 2*0x25, 0x000C) + + if (world.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E849), 0x0043) #flute spot + if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']: + rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW + + write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave + rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) + write_int16(rom, snes_to_pc(0x02D924), 0x0300) + write_int16(rom, snes_to_pc(0x02D932), 0x1F10) + write_int16(rom, snes_to_pc(0x02D940), 0x1FC0) + write_int16(rom, snes_to_pc(0x02D94E), 0x0378) + write_int16(rom, snes_to_pc(0x02D95C), 0x0187) + write_int16(rom, snes_to_pc(0x02D96A), 0x017F) + rom.write_byte(snes_to_pc(0x02D972), 0x06) + rom.write_byte(snes_to_pc(0x02D979), 0x00) + rom.write_byte(snes_to_pc(0x02D980), 0xFF) + rom.write_byte(snes_to_pc(0x02D987), 0x00) + rom.write_byte(snes_to_pc(0x02D98E), 0x22) + rom.write_byte(snes_to_pc(0x02D995), 0x12) + write_int16(rom, snes_to_pc(0x02D9A2), 0x0000) + write_int16(rom, snes_to_pc(0x02D9B0), 0x0007) + rom.write_byte(snes_to_pc(0x02D9B8), 0x12) + + rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) #indicates the overworld door being used for the single entrance spawn point + + rom.write_byte(0xDBB73 + 0x6F, 0x07) # DDM fairy entrance to old man fetch east UW + write_int16(rom, 0x15AEE + 2*0x18, 0x00F1) # old man fetch UW to DDM fairy entrance + rom.write_byte(0x15B8C + 0x18, 0x43) + write_int16(rom, 0x15BDB + 2 * 0x18, 0x1400) + write_int16(rom, 0x15C79 + 2 * 0x18, 0x0294) + write_int16(rom, 0x15D17 + 2 * 0x18, 0x0600) + write_int16(rom, 0x15DB5 + 2 * 0x18, 0x02E8) + write_int16(rom, 0x15E53 + 2 * 0x18, 0x0678) + write_int16(rom, 0x15EF1 + 2 * 0x18, 0x0303) + write_int16(rom, 0x15F8F + 2 * 0x18, 0x0685) + rom.write_byte(0x1602D + 0x18, 0x0A) + rom.write_byte(0x1607C + 0x18, 0xF6) + write_int16(rom, 0x160CB + 2 * 0x18, 0x0000) + write_int16(rom, 0x16169 + 2 * 0x18, 0x0000) + + rom.write_byte(0xDBB73 + 0x06, 0x2E) # old man fetch east entrance to DMD west UW + write_int16(rom, 0x15AEE + 2*0x08, 0x00E6) # DMD west UW to old man fetch east entrance + if (world.mode[player] == 'inverted') != (0x0A in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_byte(0xDBB73 + 0x16, 0x5E) # bumper cave top entrance to DDM Fairy UW + else: + rom.write_byte(0xDBB73 + 0x2D, 0x5E) # DMD west entrance to DDM Fairy + if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) # add warps under rocks + rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks + rom.write_byte(0x180089, 0x01) # open TR after exit + rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail + if world.shuffle[player] in ['vanilla']: + world.fix_trock_doors[player] = True + if (world.mode[player] == 'inverted') != (0x0A in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + rom.write_byte(0xDBB73 + 0x15, 0x06) # bumper cave bottom entrance to old man fetch west UW + write_int16(rom, 0x15AEE + 2*0x17, 0x00F0) # old man fetch west UW to bumper cave bottom entrance + rom.write_byte(0xDBB73 + 0x05, 0x16) # old man fetch west entrance to bumper cave bottom UW + write_int16(rom, 0x15AEE + 2*0x07, 0x00FB) # bumper cave bottom UW to old man fetch west entrance + rom.write_byte(0xDBB73 + 0x2D, 0x17) # DMD west entrance to bumper cave top UW + write_int16(rom, 0x15AEE + 2*0x2F, 0x00EB) # bumper cave top UW to DMD west entrance + if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_byte(0xDBB73 + 0x16, 0x2E) # bumper cave top entrance to DMD west UW + write_int16(rom, 0x15AEE + 2*0x18, 0x00E6) # DMD west UW to bumper cave top entrance + if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x16 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E84B), 0x0056) #flute spot + if (world.mode[player] == 'inverted') != (0x18 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E84D), 0x0058) #flute spot + write_int16(rom, snes_to_pc(0x02E8D5), 0x07C8) #flute spot + write_int16(rom, snes_to_pc(0x02E8F7), 0x01F8) #flute spot + if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, 0x15AEE + 2 * 0x06, 0x0020) # post aga hyrule castle spawn + rom.write_byte(0x15B8C + 0x06, 0x1B) + write_int16(rom, 0x15BDB + 2 * 0x06, 0x00AE) + write_int16(rom, 0x15C79 + 2 * 0x06, 0x0610) + write_int16(rom, 0x15D17 + 2 * 0x06, 0x077E) + write_int16(rom, 0x15DB5 + 2 * 0x06, 0x0672) + write_int16(rom, 0x15E53 + 2 * 0x06, 0x07F8) + write_int16(rom, 0x15EF1 + 2 * 0x06, 0x067D) + write_int16(rom, 0x15F8F + 2 * 0x06, 0x0803) + rom.write_byte(0x1602D + 0x06, 0x00) + rom.write_byte(0x1607C + 0x06, 0xF2) + write_int16(rom, 0x160CB + 2 * 0x06, 0x0000) + write_int16(rom, 0x16169 + 2 * 0x06, 0x0000) + + write_int16(rom, snes_to_pc(0x02E859), 0x001B) # move flute spot 9 + write_int16(rom, snes_to_pc(0x02E87B), 0x00AE) + write_int16(rom, snes_to_pc(0x02E89D), 0x0610) + write_int16(rom, snes_to_pc(0x02E8BF), 0x077E) + write_int16(rom, snes_to_pc(0x02E8E1), 0x0672) + write_int16(rom, snes_to_pc(0x02E903), 0x07F8) + write_int16(rom, snes_to_pc(0x02E925), 0x067D) + write_int16(rom, snes_to_pc(0x02E947), 0x0803) + write_int16(rom, snes_to_pc(0x02E969), 0x0000) + write_int16(rom, snes_to_pc(0x02E98B), 0xFFF2) + + #new pyramid hole mask position + rom.write_bytes(snes_to_pc(0x1AF730), [0x6A, 0x9E, 0x0C, 0x00, 0x7A, 0x9E, 0x0C, + 0x00, 0x8A, 0x9E, 0x0C, 0x00, 0x6A, 0xAE, + 0x0C, 0x00, 0x7A, 0xAE, 0x0C, 0x00, 0x8A, + 0xAE, 0x0C, 0x00, 0x67, 0x97, 0x0C, 0x00, + 0x8D, 0x97, 0x0C, 0x00]) + + rom.write_byte(snes_to_pc(0x00D009), 0x31) # castle hole graphics + rom.write_byte(snes_to_pc(0x00D0E8), 0xE0) + rom.write_byte(snes_to_pc(0x00D1C7), 0x00) + write_int16(rom, snes_to_pc(0x1BE8DA), 0x39AD) # add color for shading for castle hole + + #castle hole map16 data + write_int16s(rom, snes_to_pc(0x0FF1C8), [0x190F, 0x190F, 0x190F, 0x194C, 0x190F, + 0x194B, 0x190F, 0x195C, 0x594B, 0x194C, + 0x19EE, 0x19EE, 0x194B, 0x19EE, 0x19EE, + 0x19EE, 0x594B, 0x190F, 0x595C, 0x190F, + 0x190F, 0x195B, 0x190F, 0x190F, 0x19EE, + 0x19EE, 0x195C, 0x19EE, 0x19EE, 0x19EE, + 0x19EE, 0x595C, 0x595B, 0x190F, 0x190F, + 0x190F]) + write_int16s(rom, snes_to_pc(0x0FA480), [0x190F, 0x196B, 0x9D04, 0x9D04, 0x196B, + 0x190F, 0x9D04, 0x9D04]) + + write_int16s(rom, snes_to_pc(0x1BB810), [0x00BE, 0x00C0, 0x013E]) # update pyramid hole entrance + write_int16s(rom, snes_to_pc(0x1BB836), [0x001B, 0x001B, 0x001B]) + + write_int16(rom, snes_to_pc(0x308300), 0x0140) #add extra pyramid hole + write_int16(rom, snes_to_pc(0x308320), 0x001B) + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + rom.write_byte(snes_to_pc(0x308340), 0x7B) + + rom.write_byte(snes_to_pc(0x00DB9D), 0x1A) # make retreat bat gfx available in HC area + rom.write_byte(snes_to_pc(0x00DC09), 0x1A) + + rom.write_byte(snes_to_pc(0x1AF696), 0xF0) # bat sprite retreat : bat X position + rom.write_byte(snes_to_pc(0x1AF6B2), 0x33) # bat sprite retreat : bat delay + + write_int16(rom, snes_to_pc(0x1af504), 0x148B) # prioritize retreat Bat and use 3rd sprite group + write_int16(rom, snes_to_pc(0x1af50c), 0x149B) + write_int16(rom, snes_to_pc(0x1af514), 0x14A4) + write_int16(rom, snes_to_pc(0x1af51c), 0x1489) + write_int16(rom, snes_to_pc(0x1af524), 0x14AC) + write_int16(rom, snes_to_pc(0x1af52c), 0x54AC) + write_int16(rom, snes_to_pc(0x1af534), 0x148C) + write_int16(rom, snes_to_pc(0x1af53c), 0x548C) + write_int16(rom, snes_to_pc(0x1af544), 0x1484) + write_int16(rom, snes_to_pc(0x1af54c), 0x5484) + write_int16(rom, snes_to_pc(0x1af554), 0x14A2) + write_int16(rom, snes_to_pc(0x1af55c), 0x54A2) + write_int16(rom, snes_to_pc(0x1af564), 0x14A0) + write_int16(rom, snes_to_pc(0x1af56c), 0x54A0) + write_int16(rom, snes_to_pc(0x1af574), 0x148E) + write_int16(rom, snes_to_pc(0x1af57c), 0x548E) + write_int16(rom, snes_to_pc(0x1af584), 0x14AE) + write_int16(rom, snes_to_pc(0x1af58c), 0x54AE) + + rom.write_byte(0xF6E58, 0x80) # no whirlpool under castle gate + rom.write_byte(snes_to_pc(0x09D436), 0xF3) # replace whirlpool with harmless sprite + + write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door + write_int16(rom, 0xDBA71 + 2 * 0x35, 0x011C) + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + rom.write_byte(0xDBB73 + 0x35, 0x36) + + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area + rom.write_byte(0x15B8C + 0x37, 0x1B) + write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E) + write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600) + write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676) + write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604) + write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8) + write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D) + write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3) + rom.write_byte(0x1602D + 0x37, 0x00) + rom.write_byte(0x1607C + 0x37, 0x0A) + write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) + write_int16(rom, 0x16169 + 2 * 0x37, 0x811c) + if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) #frog pickup on contact + if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E84F), 0x006C) #flute spot + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + rom.write_byte(0x15B8C, 0x6C) #exit links at bomb shop area + rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house + rom.write_byte(0xDBB73 + 0x52, 0x01) + if (world.mode[player] == 'inverted') != (0x2F in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E851), 0x006F) #flute spot + rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x30 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E853), 0x0070) #flute spot + rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x33 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x1BC3DF), [0xD8, 0xD1]) # add warp under rock + rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x35 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock + if (world.mode[player] == 'inverted') != (0x3B in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E855), 0x007B) #flute spot + if (world.mode[player] == 'inverted') != (0x3F in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + write_int16(rom, snes_to_pc(0x02E857), 0x007F) #flute spot + + if world.mode[player] == 'inverted': + rom.write_byte(0x15B8C + 0x3D, rom.buffer[0x15B8C]) # houlihan exit + write_int16(rom, 0x15BDB + 2 * 0x3D, rom.buffer[0x15BDB] + (rom.buffer[0x15BDC] << 8)) + write_int16(rom, 0x15C79 + 2 * 0x3D, rom.buffer[0x15C79] + (rom.buffer[0x15C7A] << 8)) + write_int16(rom, 0x15D17 + 2 * 0x3D, rom.buffer[0x15D17] + (rom.buffer[0x15D18] << 8)) + write_int16(rom, 0x15DB5 + 2 * 0x3D, rom.buffer[0x15DB5] + (rom.buffer[0x15DB6] << 8)) + write_int16(rom, 0x15E53 + 2 * 0x3D, rom.buffer[0x15E53] + (rom.buffer[0x15E54] << 8)) + write_int16(rom, 0x15EF1 + 2 * 0x3D, rom.buffer[0x15EF1] + (rom.buffer[0x15EF2] << 8)) + write_int16(rom, 0x15F8F + 2 * 0x3D, rom.buffer[0x15F8F] + (rom.buffer[0x15F90] << 8)) + rom.write_byte(0x1602D + 0x3D, rom.buffer[0x1602D]) + rom.write_byte(0x1607C + 0x3D, rom.buffer[0x1607C]) + write_int16(rom, 0x160CB + 2 * 0x3D, rom.buffer[0x160CB] + (rom.buffer[0x160CC] << 8)) + write_int16(rom, 0x16169 + 2 * 0x3D, rom.buffer[0x16169] + (rom.buffer[0x1616A] << 8)) + def patch_shuffled_dark_sanc(world, rom, player): dark_sanc = world.get_region('Dark Sanctuary Hint', player) dark_sanc_entrance = str([i for i in dark_sanc.entrances if i.parent_region.name != 'Menu'][0].name) diff --git a/Rules.py b/Rules.py index 3c03f045..a87a2493 100644 --- a/Rules.py +++ b/Rules.py @@ -19,11 +19,7 @@ def set_rules(world, player): global_rules(world, player) default_rules(world, player) - - if world.mode[player] != 'inverted': - ow_open_rules(world, player) - else: - ow_inverted_rules(world, player) + ow_rules(world, player) ow_bunny_rules(world, player) @@ -76,6 +72,13 @@ def set_rules(world, player): set_bunny_rules(world, player, world.mode[player] == 'inverted') + # TODO: Remove these rules when these scenarios aren't a problem + if world.owSwap[player] == 'mixed': + if 'Frog Area' in world.owswaps[player][2]: + set_rule(world.get_location('Frog', player), lambda state: False) + if 'Stumpy Area' in world.owswaps[player][2]: + set_rule(world.get_location('Stumpy', player), lambda state: False) + def mirrorless_path_to_location(world, startName, targetName, player): # If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch. @@ -839,382 +842,348 @@ def default_rules(world, player): swordless_rules(world, player) -def ow_open_rules(world, player): - set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pedestal Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods East (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods West (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('West Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Spiral Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Fairy Ascension Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player)) # need to lift flowers - set_rule(world.get_entrance('Isolated Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Death Mountain Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Pegs Area Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mountain Entry Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mountain Entry Entrance Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Zora Waterfall Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bonk Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) - set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) - set_rule(world.get_entrance('River Bend Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('River Bend East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Potion Shop Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Zora Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Zora Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Grass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Forgotton Forest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Forgotton Forest Fence Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC East Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Area South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Wooden Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Wooden Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Wooden Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Eastern Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Blacksmith Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Blacksmith Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bat Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Sand Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Maze Race Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Suburb Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Suburb South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Boy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Central Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Links House Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stone Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stone Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Eastern Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Checkerboard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('DP Stairs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('DP Entrance (North) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bombos Tablet Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Boy Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Statues Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Water Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Shore Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Shore East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Pass Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Octoballoon Mirror Spot', player), lambda state: state.has_Mirror(player)) +def ow_rules(world, player): + if (world.mode[player] == 'inverted') == (0x00 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods Pedestal Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods East (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods West (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Skull Woods Back Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Forgotten (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Forgotten (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Portal Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Forgotten (Middle) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Front Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x02 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) + set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'crossed', 'insanity')) + + set_rule(world.get_entrance('West Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x05 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Spiral Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Fairy Ascension Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player)) # need to lift flowers + set_rule(world.get_entrance('Isolated Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Death Mountain Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Death Mountain Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + else: + set_rule(world.get_entrance('East Dark Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Dark Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('TR Ledge (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('TR Ledge (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('TR Isolated Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Dark Death Mountain (Bottom Plateau) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Dark Death Mountain (Bottom Left) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: state.can_lift_heavy_rocks(player)) + + if (world.mode[player] == 'inverted') == (0x07 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('TR Pegs Area Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('TR Pegs Teleporter', player), lambda state: state.has('Hammer', player)) + else: + set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player)) + + if (world.mode[player] == 'inverted') == (0x0a in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Mountain Entry Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Mountain Entry Entrance Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Bumper Cave Area Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bumper Cave Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x0f in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Zora Waterfall Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x10 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Lost Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lost Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Kakariko Teleporter (Hammer)', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes + set_rule(world.get_entrance('Kakariko Teleporter (Rock)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes + else: + set_rule(world.get_entrance('Skull Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Skull Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('West Dark World Teleporter (Hammer)', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player)) + set_rule(world.get_entrance('West Dark World Teleporter (Rock)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes + + if (world.mode[player] == 'inverted') == (0x11 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Kakariko Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Outcast Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x12 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Kakariko Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Outcast Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x13 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Sanctuary Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bonk Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Chapel Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Chapel Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x14 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) + set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: state.has_Pearl(player)) + set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: state.has_Pearl(player)) + set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x15 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('River Bend Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('River Bend East Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Qirn Jump Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Qirn Jump East Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x16 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Potion Shop Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Witch Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Witch Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x17 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Zora Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Zora Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Catfish Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Catfish Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x18 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Kakariko Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Kakariko Grass Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Village of Outcasts Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Village of Outcasts Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Hammer House Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x1a in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Forgotton Forest Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Forgotton Forest Fence Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Shield Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x1b in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False) + set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False) + set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) + set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle + + set_rule(world.get_entrance('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('HC Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('HC East Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('HC Area South Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player)) + set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player)) + else: + set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) + add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False) + set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False) + set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) + + set_rule(world.get_entrance('Pyramid Exit Ledge Drop', player), lambda state: state.has('Hammer', player)) + set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Pyramid Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Pyramid Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Pyramid Uncle Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Pyramid From Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Pyramid Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Post Aga Inverted Teleporter', player), lambda state: state.has('Beat Agahnim 1', player)) + + if (world.mode[player] == 'inverted') == (0x1d in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Wooden Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Wooden Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Wooden Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Broken Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Broken Bridge East Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Broken Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x1e in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Eastern Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Palace of Darkness Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x22 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Blacksmith Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Blacksmith Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bat Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Hammer Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Hammer Pegs Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x25 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Sand Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x28 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Maze Race Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dig Game Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dig Game Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x29 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Kakariko Suburb Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Kakariko Suburb South Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Frog Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Frog Prison Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Archery Game Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x2a in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Flute Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Flute Boy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Stumpy Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Stumpy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x2b in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Central Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x2c in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Links House Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Big Bomb Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x2d in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Stone Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Stone Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) + else: + set_rule(world.get_entrance('Hammer Bridge North Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Hammer Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) + + if (world.mode[player] == 'inverted') == (0x2e in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x2f in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Eastern Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer + else: + set_rule(world.get_entrance('Darkness Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) + + if (world.mode[player] == 'inverted') == (0x30 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Checkerboard Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Desert Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('DP Stairs Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('DP Entrance (North) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Bombos Tablet Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Desert Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + else: + set_rule(world.get_entrance('Misery Mire Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Misery Mire Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + + if (world.mode[player] == 'inverted') == (0x32 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Flute Boy Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x33 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer + set_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) # OWG only, can bomb clip out + else: + set_rule(world.get_entrance('Dark C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Dark C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) + set_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) + + if (world.mode[player] == 'inverted') == (0x34 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Statues Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Hype Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x35 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Lake Hylia Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lake Hylia Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) + set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lake Hylia Water Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('South Shore Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('South Shore East Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Lake Hylia Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + else: + set_rule(world.get_entrance('Ice Lake Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Ice Lake Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Ice Lake Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + + if (world.mode[player] == 'inverted') == (0x37 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x3a in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Desert Pass Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Desert Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Swamp Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x3b in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Swamp Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x3c in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Dark South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) + + if (world.mode[player] == 'inverted') == (0x3f in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + set_rule(world.get_entrance('Octoballoon Mirror Spot', player), lambda state: state.has_Mirror(player)) + else: + set_rule(world.get_entrance('Bomber Corner Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Teleporter (Hammer)', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes - set_rule(world.get_entrance('Kakariko Teleporter (Rock)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes - set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer - set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer - set_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) # OWG only, can bomb clip out - set_rule(world.get_entrance('Desert Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Lake Hylia Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('East Death Mountain Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('TR Pegs Teleporter', player), lambda state: state.has('Hammer', player)) - - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False) - set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False) - set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle - set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) - set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'crossed', 'insanity')) - - -def ow_inverted_rules(world, player): - set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Pyramid Exit Ledge Drop', player), lambda state: state.has('Hammer', player)) - - set_rule(world.get_entrance('Skull Woods Back Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Portal Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (Middle) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Front Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Ledge (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Ledge (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Isolated Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom Plateau) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom Left) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Area Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Outcast Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Outcast Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Chapel Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Chapel Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Qirn Jump Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Qirn Jump East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Witch Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Witch Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Catfish Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Catfish Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Village of Outcasts Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Village of Outcasts Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer House Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Shield Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Uncle Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid From Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Broken Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Broken Bridge East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Broken Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Palace of Darkness Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Pegs Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dig Game Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dig Game Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Frog Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Frog Prison Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Archery Game Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Big Bomb Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Bridge North Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Dark Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Darkness Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hype Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swmap Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swamp Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bomber Corner Mirror Spot', player), lambda state: state.has_Mirror(player)) - - set_rule(world.get_entrance('West Dark World Teleporter (Hammer)', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('West Dark World Teleporter (Rock)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) # bunny cannot lift bushes - set_rule(world.get_entrance('Post Aga Inverted Teleporter', player), lambda state: state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player)) - - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) - add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False) - set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False) - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) - - -def old_inverted_rules(world, player): - # s&q regions. link's house entrance is set to true so the filler knows the chest inside can always be reached - - # overworld requirements - set_rule(world.get_location('Ice Rod Cave', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_location('Maze Race', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Mini Moldorm Cave', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Ice Rod Cave', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Light Hype Fairy', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Potion Shop Pier', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Light World Pier', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Kings Grave', player), lambda state: state.has_Boots(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Kings Grave Outer Rocks', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Kings Grave Inner Rocks', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Potion Shop Inner Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Potion Shop Outer Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Potion Shop Outer Rock', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Potion Shop Inner Rock', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Graveyard Cave Inner Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Graveyard Cave Outer Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Secret Passage Inner Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Secret Passage Outer Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has_Boots(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has_Boots(player) and state.has_Pearl(player) and state.has('Beat Agahnim 1', player)) - set_rule(world.get_entrance('Bonk Rock Cave', player), lambda state: state.has_Boots(player) and state.has_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: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('20 Rupee Cave', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer - set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer - set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) - set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player) and state.has_Pearl(player)) - - set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Waterfall of Wishing Cave', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Northeast Light World Return', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) - set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and - (state.has_Pearl(player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player) - and state.has_Mirror(player))) # Need LW access using Mirror or Portal - set_rule(world.get_location('Mushroom', player), lambda state: state.has_Pearl(player)) # need pearl to pick up bushes - set_rule(world.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Bush Covered Lawn Outer Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Bomb Hut Inner Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Bomb Hut Outer Bushes', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Light World Bomb Hut', player), lambda state: state.has_Pearl(player)) # need bomb - set_rule(world.get_entrance('North Fairy Cave Drop', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Lost Woods Hideout Drop', player), lambda state: state.has_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: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Desert Ledge Return Rocks', player), lambda state: state.can_lift_rocks(player) and state.has_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: state.can_lift_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Hyrule Castle Secret Entrance Drop', player), lambda state: state.has_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_Pearl(player)) - set_rule(world.get_entrance('Broken Bridge (East)', player), lambda state: state.has('Hookshot', player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Dark Death Mountain Teleporter (East Bottom)', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Fairy Ascension Rocks', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_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_Pearl(player)) - set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has('Hammer', player) and state.has_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_Pearl(player)) # bunny can not use hammer - - set_rule(world.get_entrance('Catfish Entrance Rock', player), lambda state: state.can_lift_rocks(player)) - set_rule(world.get_entrance('Northeast Dark World Broken Bridge Pass', player), lambda state: ((state.can_lift_rocks(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.can_lift_rocks(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_Boots(player)) - set_rule(world.get_entrance('West Dark World Gap', player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('Ice Lake Drop (East)', player), lambda state: state.has('Flippers', player)) - set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(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: state.can_lift_rocks(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: state.can_lift_heavy_rocks(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_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Entrance Rock', player), lambda state: state.can_lift_rocks(player)) - set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Peg Area Mirror Spot', player), lambda state: state.has_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: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Peg Area Rocks', player), lambda state: state.can_lift_heavy_rocks(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(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: state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!) - - set_rule(world.get_entrance('Hookshot Cave', player), lambda state: state.can_lift_rocks(player)) - - set_rule(world.get_entrance('East Death Mountain Mirror Spot (Top)', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - - set_rule(world.get_entrance('East Death Mountain Mirror Spot (Bottom)', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (East)', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (West)', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Laser Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_sword(player) and state.has_turtle_rock_medallion(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_Mirror(player)) - set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Death Mountain Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark World Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('West Dark World Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Dark World Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Palace North Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Graveyard Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bomb Hut Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Mirror Spot', player), lambda state: state.has_Mirror(player)) - - # inverted flute spots - - set_rule(world.get_entrance('DDM Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('NEDW Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('WDW Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('SDW Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('EDW Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('DLHL Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('DD Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('EDDM Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.can_flute(player)) - - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) - if world.swords[player] == 'swordless': - swordless_rules(world, player) - - set_rule(world.get_entrance('Ganons Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) def ow_bunny_rules(world, player): add_bunny_rule(world.get_location('Mushroom', player), player) @@ -1625,6 +1594,7 @@ def standard_rules(world, player): add_rule(world.get_entrance('Hyrule Castle ES', player), lambda state: state.has('Zelda Delivered', player)) add_rule(world.get_entrance('Hyrule Castle Main Gate (South)', player), lambda state: state.has('Zelda Delivered', player)) add_rule(world.get_entrance('Hyrule Castle Main Gate (North)', player), lambda state: state.has('Zelda Delivered', player)) + add_rule(world.get_entrance('Hyrule Castle Ledge Drop', player), lambda state: state.has('Zelda Delivered', player)) def find_rules_for_zelda_delivery(world, player): @@ -2082,7 +2052,7 @@ def set_inverted_big_bomb_rules(world, player): else: raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name) - if world.owShuffle[player] != 'vanilla': + if world.owShuffle[player] != 'vanilla' or world.owSwap[player] != 'vanilla': add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) #temp disable progression until routing to Pyramid get be guaranteed diff --git a/asm/owrando.asm b/asm/owrando.asm index 962ed005..2147a544 100644 --- a/asm/owrando.asm +++ b/asm/owrando.asm @@ -27,7 +27,7 @@ org $02c40a ; < ? - Bank02.asm 10547 () jsl.l OWWorldCheck org $05afd9 ; < ? - sprite_warp_vortex.asm 60 () jsl.l OWWorldCheck -org $07a3f0 ; < ? - Bank07.asm 5772 () +org $07a3f0 ; < ? - Bank07.asm 5772 () ; flute activation/use jsl.l OWWorldCheck org $07a967 ; < ? - Bank07.asm 6578 () jsl.l OWWorldCheck @@ -54,6 +54,9 @@ jsl.l OWWorldCheck16 : nop org $1bed95 ; < ? - palettes.asm 748 () jsl.l OWWorldCheck16 : nop +org $02b16e ; AND #$3F : ORA 7EF3CA +and #$7f : eor #$40 : nop #2 ; something to do with mirroring and simply toggling world to opposite one: TODO: better comment + ;Code org $aa8800 OWCoordIndex: ; Horizontal 1st @@ -94,7 +97,7 @@ org $aa9000 OWEdgeTransition: { php : phy - lda.l OWMode : beq + + lda.l OWMode : ora.l OWMode+1 : beq + jsl OWShuffle : bra .return + jsl OWVanilla .return @@ -270,7 +273,27 @@ OWNewDestination: lda $418 : asl : tax : lda $610,x : !add 1,s : sta $610,x : pla sep #$30 : lda OWOppSlotOffset,y : !add $04 : asl : and #$7f : sta $700 - sep #$20 : lda $05 : sta $8a ;: and #$40 : sta.l $7ef3ca ;removed setting DW flag + + lda.l OWMode+1 : and #$ff : cmp #$02 : bne .return + ldx $05 : lda.l OWTileWorldAssoc,x : sta.l $7ef3ca ; change world + + ; toggle bunny mode + lda $7ef357 : bne .nobunny + lda.l InvertedMode : bne .inverted + lda $7ef3ca : and.b #$40 : bra + + .inverted lda $7ef3ca : and.b #$40 : eor #$40 + ++ cmp #$40 : bne .nobunny + ; turn into bunny + lda $5d : cmp #$17 : beq .return + lda #$17 : sta $5d + lda #$01 : sta $02e0 + bra .return + .nobunny + lda $5d : cmp #$17 : bne .return + stz $5d : stz $2e0 + + .return + lda $05 : sta $8a rep #$30 : rts } diff --git a/data/base2current.bps b/data/base2current.bps index 923e89609d5fc3a69c6d0beae638b56a51a7308e..eacabeae42efe76ce27222c229278924263435b8 100644 GIT binary patch literal 27 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%0D1;Ql+vOI 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 D_944y