Combine bunny rules calculation for inverted and normal.

This commit is contained in:
compiling 2020-05-07 20:00:29 +10:00
parent a526d71fe0
commit 5b268ef8ae
2 changed files with 47 additions and 156 deletions

View File

@ -27,26 +27,19 @@ def get_boots_required_superbunny_mirror_locations():
yield 'Sahasrahla\'s Hut - Right' yield 'Sahasrahla\'s Hut - Right'
def get_invalid_mirror_bunny_entrances_dw(): def get_invalid_mirror_bunny_entrances():
""" """
Dark World entrances that can't be superbunny-mirrored into. Entrances that can't be superbunny-mirrored into.
""" """
yield 'Skull Woods Final Section (Entrance)' yield 'Skull Woods Final Section'
yield 'Hype Cave' yield 'Hype Cave'
yield 'Bonk Fairy (Dark)' yield 'Bonk Fairy (Dark)'
yield 'Thieves Town' yield 'Thieves Town'
yield 'Dark World Hammer Peg Cave' yield 'Dark World Hammer Peg Cave'
yield 'Brewery' yield 'Brewery'
yield 'Hookshot Cave' yield 'Hookshot Cave'
yield 'Hookshot Cave Exit (South)'
yield 'Dark Lake Hylia Ledge Fairy' yield 'Dark Lake Hylia Ledge Fairy'
yield 'Dark Lake Hylia Ledge Spike Cave' yield 'Dark Lake Hylia Ledge Spike Cave'
def get_invalid_mirror_bunny_entrances_lw():
"""
Light World entrances that can't be superbunny-mirrored into.
"""
yield 'Bonk Rock Cave' yield 'Bonk Rock Cave'
yield 'Bonk Fairy (Light)' yield 'Bonk Fairy (Light)'
yield '50 Rupee Cave' yield '50 Rupee Cave'
@ -59,9 +52,6 @@ def get_invalid_mirror_bunny_entrances_lw():
yield 'Ice Rod Cave' yield 'Ice Rod Cave'
yield 'Sanctuary Grave' yield 'Sanctuary Grave'
yield 'Kings Grave' yield 'Kings Grave'
#todo: you can for insanity shuffle
yield 'Hyrule Castle Secret Entrance Stairs'
yield 'Tower of Hera'
def get_superbunny_accessible_locations(): def get_superbunny_accessible_locations():

171
Rules.py
View File

@ -1,7 +1,7 @@
import collections import collections
import logging import logging
import OverworldGlitchRules import OverworldGlitchRules
from BaseClasses import RegionType from BaseClasses import RegionType, World
from Items import ItemFactory from Items import ItemFactory
from OverworldGlitchRules import overworld_glitches_rules from OverworldGlitchRules import overworld_glitches_rules
@ -81,10 +81,8 @@ def set_rules(world, player):
if world.mode[player] != 'inverted' and world.logic[player] == 'owglitches': if world.mode[player] != 'inverted' and world.logic[player] == 'owglitches':
add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.world.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or') add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.world.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or')
if world.mode[player] != 'inverted': set_bunny_rules(world, player, world.mode[player] == 'inverted')
set_bunny_rules(world, player)
else:
set_inverted_bunny_rules(world, player)
def set_rule(spot, rule): def set_rule(spot, rule):
spot.access_rule = rule spot.access_rule = rule
@ -499,6 +497,7 @@ def inverted_rules(world, player):
# overworld requirements # overworld requirements
set_rule(world.get_location('Maze Race', 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('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('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('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('Light World Pier', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player))
@ -513,7 +512,6 @@ def inverted_rules(world, player):
set_rule(world.get_entrance('Graveyard Cave Outer 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 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('Secret Passage Outer Bushes', player), lambda state: state.has_Pearl(player))
# Caution: If king's grave is releaxed at all to account for reaching it via a two way cave's exit in insanity mode, then the bomb shop logic will need to be updated (that would involve create a small ledge-like Region for it)
set_rule(world.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has_Boots(player) and 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('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('Lumberjack Tree Tree', player), lambda state: state.has_Boots(player) and state.has_Pearl(player) and state.has('Beat Agahnim 1', player))
@ -546,6 +544,7 @@ def inverted_rules(world, player):
set_rule(world.get_entrance('Bush Covered Lawn Outer 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 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('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('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_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_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
@ -1306,13 +1305,15 @@ def set_inverted_big_bomb_rules(world, player):
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name) raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
def set_bunny_rules(world, player): def set_bunny_rules(world: World, player: int, inverted: bool):
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing. # regions for the exits of multi-entrance caves/drops that bunny cannot pass
# Note spiral cave and two brothers house are passable in superbunny state for glitch logic with extra requirements.
bunny_impassable_caves = ['Bumper Cave', 'Two Brothers House', 'Hookshot Cave', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)', 'Turtle Rock (Entrance)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Skull Woods Second Section (Drop)', bunny_impassable_caves = ['Bumper Cave', 'Two Brothers House', 'Hookshot Cave', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)', 'Turtle Rock (Entrance)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Skull Woods Second Section (Drop)',
'Turtle Rock (Eye Bridge)', 'Sewers', 'Pyramid', 'Spiral Cave (Top)', 'Desert Palace Main (Inner)', 'Fairy Ascension Cave (Drop)'] 'Turtle Rock (Eye Bridge)', 'Sewers', 'Pyramid', 'Spiral Cave (Top)', 'Desert Palace Main (Inner)', 'Fairy Ascension Cave (Drop)']
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins'] bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins', 'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Purple Chest', 'Blacksmith', 'Missing Smith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge']
def path_to_access_rule(path, entrance): def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path) return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path)
@ -1320,6 +1321,19 @@ def set_bunny_rules(world, player):
def options_to_access_rule(options): def options_to_access_rule(options):
return lambda state: any(rule(state) for rule in options) return lambda state: any(rule(state) for rule in options)
# Helper functions to determine if the moon pearl is required
def is_bunny(region):
if inverted:
return region.is_light_world
else:
return region.is_dark_world
def is_link(region):
if inverted:
return region.is_dark_world
else:
return region.is_light_world
def get_rule_to_add(region, location = None, connecting_entrance = None): def get_rule_to_add(region, location = None, connecting_entrance = None):
# In OWG, a location can potentially be superbunny-mirror accessible or # In OWG, a location can potentially be superbunny-mirror accessible or
# bunny revival accessible. # bunny revival accessible.
@ -1330,17 +1344,12 @@ def set_bunny_rules(world, player):
return lambda state: state.has_Mirror(player) or state.has_Pearl(player) return lambda state: state.has_Mirror(player) or state.has_Pearl(player)
if region.type == RegionType.Dungeon: if region.type == RegionType.Dungeon:
return lambda state: True return lambda state: True
if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
return lambda state: state.has_Mirror(player) and state.has_sword(player) or state.has_Pearl(player)
if (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
or location is not None and location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations()):
return lambda state: state.has_Mirror(player) and state.has_Boots(player) or state.has_Pearl(player)
if (((location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations()) if (((location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations())
or (connecting_entrance is not None and connecting_entrance.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons())) or (connecting_entrance is not None and connecting_entrance.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons()))
and not region.is_light_world): and not is_link(region)):
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
else: else:
if not region.is_light_world: if not is_link(region):
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
# in this case we are mixed region. # in this case we are mixed region.
@ -1350,7 +1359,7 @@ def set_bunny_rules(world, player):
possible_options = [lambda state: state.has_Pearl(player)] possible_options = [lambda state: state.has_Pearl(player)]
# We will search entrances recursively until we find # We will search entrances recursively until we find
# one that leads to an exclusively light world region # one that leads to an exclusively link state region
# for each such entrance a new option is added that consist of: # for each such entrance a new option is added that consist of:
# a) being able to reach it, and # a) being able to reach it, and
# b) being able to access all entrances from there to `region` # b) being able to access all entrances from there to `region`
@ -1364,9 +1373,9 @@ def set_bunny_rules(world, player):
continue continue
new_path = path + [entrance.access_rule] new_path = path + [entrance.access_rule]
seen.add(new_region) seen.add(new_region)
if not new_region.is_light_world: if not is_link(new_region):
# For OWG, establish superbunny and revival rules. # For OWG, establish superbunny and revival rules.
if world.logic[player] == 'owglitches' and entrance.name not in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_dw(): if world.logic[player] == 'owglitches' and entrance.name not in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions(): if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_sword(player)) possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_sword(player))
elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions() elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
@ -1381,29 +1390,29 @@ def set_bunny_rules(world, player):
continue continue
else: else:
continue continue
if new_region.is_dark_world: if is_bunny(new_region):
queue.append((new_region, new_path)) queue.append((new_region, new_path))
else: else:
# we have reached pure light world or a dungeon, so we have a new possible option # we have reached pure link state, so we have a new possible option
possible_options.append(path_to_access_rule(new_path, entrance)) possible_options.append(path_to_access_rule(new_path, entrance))
return options_to_access_rule(possible_options) return options_to_access_rule(possible_options)
# Add requirements for bunny-impassible caves if they occur in the dark world # Add requirements for bunny-impassible caves if link is a bunny in them
for region in [world.get_region(name, player) for name in bunny_impassable_caves]: for region in [world.get_region(name, player) for name in bunny_impassable_caves]:
if not region.is_dark_world: if not is_bunny(region):
continue continue
rule = get_rule_to_add(region) rule = get_rule_to_add(region)
for exit in region.exits: for exit in region.exits:
add_rule(exit, rule) add_rule(exit, rule)
paradox_shop = world.get_region('Light World Death Mountain Shop', player) paradox_shop = world.get_region('Light World Death Mountain Shop', player)
if paradox_shop.is_dark_world: if is_bunny(paradox_shop):
add_rule(paradox_shop.entrances[0], get_rule_to_add(paradox_shop)) add_rule(paradox_shop.entrances[0], get_rule_to_add(paradox_shop))
# Add requirements for all locations that are actually in the dark world, except those available to the bunny, including dungeon revival # Add requirements for all locations that are actually in the dark world, except those available to the bunny, including dungeon revival
for entrance in world.get_entrances(): for entrance in world.get_entrances():
if entrance.player == player and entrance.connected_region.is_dark_world: if entrance.player == player and is_bunny(entrance.connected_region):
if world.logic[player] == 'owglitches': if world.logic[player] == 'owglitches':
if entrance.connected_region.type == RegionType.Dungeon: if entrance.connected_region.type == RegionType.Dungeon:
if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
@ -1412,115 +1421,7 @@ def set_bunny_rules(world, player):
if entrance.connected_region.name == 'Turtle Rock (Entrance)': if entrance.connected_region.name == 'Turtle Rock (Entrance)':
add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance))
for location in entrance.connected_region.locations: for location in entrance.connected_region.locations:
if world.logic[player] == 'owglitches' and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_dw(): if world.logic[player] == 'owglitches' and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances():
add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance))
continue
if location.name in bunny_accessible_locations:
continue
add_rule(location, get_rule_to_add(entrance.connected_region, location))
#todo: combine this with set_bunny_rules
def set_inverted_bunny_rules(world, player):
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
bunny_impassable_caves = ['Bumper Cave', 'Two Brothers House', 'Hookshot Cave', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)', 'Turtle Rock (Entrance)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Skull Woods Second Section (Drop)',
'Turtle Rock (Eye Bridge)', 'Sewers', 'Pyramid', 'Spiral Cave (Top)', 'Desert Palace Main (Inner)', 'Fairy Ascension Cave (Drop)', 'The Sky']
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins', 'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Purple Chest', 'Blacksmith', 'Missing Smith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge']
def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path)
def options_to_access_rule(options):
return lambda state: any(rule(state) for rule in options)
def get_rule_to_add(region, location = None, connecting_entrance = None):
# In OWG, a location can potentially be superbunny-mirror accessible or
# bunny revival accessible.
if world.logic[player] == 'owglitches':
if region.name == 'Swamp Palace (Entrance)':
return lambda state: state.has_Pearl(player)
if region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
return lambda state: state.has_Mirror(player) or state.has_Pearl(player)
if region.type == RegionType.Dungeon:
return lambda state: True
if (((location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations())
or (connecting_entrance is not None and connecting_entrance.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons()))
and not region.is_dark_world):
return lambda state: state.has_Pearl(player)
else:
if not region.is_dark_world:
return lambda state: state.has_Pearl(player)
# in this case we are mixed region.
# we collect possible options.
# The base option is having the moon pearl
possible_options = [lambda state: state.has_Pearl(player)]
# We will search entrances recursively until we find
# one that leads to an exclusively dark world region
# for each such entrance a new option is added that consist of:
# a) being able to reach it, and
# b) being able to access all entrances from there to `region`
seen = set([region])
queue = collections.deque([(region, [])])
while queue:
(current, path) = queue.popleft()
for entrance in current.entrances:
new_region = entrance.parent_region
if new_region in seen:
continue
new_path = path + [entrance.access_rule]
seen.add(new_region)
if not new_region.is_dark_world:
# For OWG, establish superbunny and revival rules.
if world.logic[player] == 'owglitches' and entrance.name not in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_lw():
if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_sword(player))
elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
or location is not None and location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations()):
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_Boots(player))
elif location is not None and location.name in OverworldGlitchRules.get_superbunny_accessible_locations():
if new_region.name == 'Superbunny Cave (Bottom)' or region.name == 'Kakariko Well (top)':
possible_options.append(lambda state: path_to_access_rule(new_path, entrance))
else:
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player))
if new_region.type != RegionType.Cave:
continue
else:
continue
if new_region.is_light_world:
queue.append((new_region, new_path))
else:
# we have reached pure dark world, so we have a new possible option
possible_options.append(path_to_access_rule(new_path, entrance))
return options_to_access_rule(possible_options)
# Add requirements for bunny-impassible caves if they occur in the light world
for region in [world.get_region(name, player) for name in bunny_impassable_caves]:
if not region.is_light_world:
continue
rule = get_rule_to_add(region)
for exit in region.exits:
add_rule(exit, rule)
paradox_shop = world.get_region('Light World Death Mountain Shop', player)
if paradox_shop.is_light_world:
add_rule(paradox_shop.entrances[0], get_rule_to_add(paradox_shop))
# Add requirements for all locations that are actually in the light world, except those available to the bunny, including dungeon revival
for entrance in world.get_entrances():
if entrance.player == player and entrance.connected_region.is_light_world:
if world.logic[player] == 'owglitches':
if entrance.connected_region.type == RegionType.Dungeon:
if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance))
continue
if entrance.connected_region.name == 'Turtle Rock (Entrance)':
add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance))
for location in entrance.connected_region.locations:
if world.logic[player] == 'owglitches' and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_lw():
add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance))
continue continue
if location.name in bunny_accessible_locations: if location.name in bunny_accessible_locations:
continue continue