diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 2ea496d7..932034c8 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -219,6 +219,7 @@ def add_alternate_rule(entrance, rule): old_rule = entrance.access_rule entrance.access_rule = lambda state: old_rule(state) or rule(state) + def create_owg_connections(player, world, connections, rule): for entrance, parent_region, target_region in connections: parent = world.get_region(parent_region, player) diff --git a/Rules.py b/Rules.py index b4ea377d..f3c38419 100644 --- a/Rules.py +++ b/Rules.py @@ -58,8 +58,9 @@ def set_rules(world, player): if world.mode != 'inverted': set_big_bomb_rules(world, player) - if world.logic == 'owglitches': - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Dark Death Mountain (West Bottom)', 'Region', player) and state.has_Mirror(player), 'or') + if world.logic == 'owglitches' and world.shuffle not in ('insanity', 'insanity_legacy'): + path_to_courtyard = mirrorless_path_to_castle_courtyard(world, player) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.world.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard), 'or') else: set_inverted_big_bomb_rules(world, player) @@ -79,6 +80,23 @@ def set_rules(world, player): set_bunny_rules(world, player, world.mode == 'inverted') +def mirrorless_path_to_castle_courtyard(world, player): + # If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch. + # Only considering the secret passage for now (in non-insanity shuffle). Basically, if it's Ganon you need the master sword. + start = world.get_entrance('Hyrule Castle Secret Entrance Drop', player) + target = world.get_region('Hyrule Castle Courtyard', player) + seen = {start.parent_region, start.connected_region} + queue = collections.deque([(start.connected_region, [])]) + while queue: + (current, path) = queue.popleft() + for entrance in current.exits: + if entrance.connected_region not in seen: + new_path = path + [entrance.access_rule] + if entrance.connected_region == target: + return new_path + else: + queue.append((entrance.connected_region, new_path)) + def set_rule(spot, rule): spot.access_rule = rule