Preliminary bunny logic

This commit is contained in:
Kevin Cathcart 2017-12-13 09:51:53 -05:00
parent 1cfbe2e9ef
commit 6bd0664b7f
6 changed files with 137 additions and 55 deletions

View File

@ -473,6 +473,7 @@ class Region(object):
self.locations = [] self.locations = []
self.dungeon = None self.dungeon = None
self.world = None self.world = None
self.is_light_world = False # will be set aftermaking connections.
self.spot_type = 'Region' self.spot_type = 'Region'
self.hint_text = 'Hyrule' self.hint_text = 'Hyrule'
self.recursion_count = 0 self.recursion_count = 0

View File

@ -18,7 +18,7 @@ def create_dungeons(world):
AT = make_dungeon('Agahnims Tower', ['Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2), []) AT = make_dungeon('Agahnims Tower', ['Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2), [])
PoD = make_dungeon('Palace of Darkness', ['Palace of Darkness (Entrance)', 'Palace of Darkness (Center)', 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness (Bonk Section)', 'Palace of Darkness (North)', 'Palace of Darkness (Maze)', 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness (Final Section)'], ItemFactory('Big Key (Palace of Darkness)'), ItemFactory(['Small Key (Palace of Darkness)'] * 6), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)'])) PoD = make_dungeon('Palace of Darkness', ['Palace of Darkness (Entrance)', 'Palace of Darkness (Center)', 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness (Bonk Section)', 'Palace of Darkness (North)', 'Palace of Darkness (Maze)', 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness (Final Section)'], ItemFactory('Big Key (Palace of Darkness)'), ItemFactory(['Small Key (Palace of Darkness)'] * 6), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)']))
TT = make_dungeon('Thieves Town', ['Thieves Town (Entrance)', 'Thieves Town (Deep)', 'Blind Fight'], ItemFactory('Big Key (Thieves Town)'), [ItemFactory('Small Key (Thieves Town)')], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)'])) TT = make_dungeon('Thieves Town', ['Thieves Town (Entrance)', 'Thieves Town (Deep)', 'Blind Fight'], ItemFactory('Big Key (Thieves Town)'), [ItemFactory('Small Key (Thieves Town)')], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)']))
SW = make_dungeon('Skull Woods', ['Skull Woods Final Section (Entrance)', 'Skull Woods First Section', 'Skull Woods Second Section', 'Skull Woods Final Section (Mothula)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)'], ItemFactory('Big Key (Skull Woods)'), ItemFactory(['Small Key (Skull Woods)'] * 2), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)'])) SW = make_dungeon('Skull Woods', ['Skull Woods Final Section (Entrance)', 'Skull Woods First Section', 'Skull Woods Second Section', 'Skull Woods Second Section (Drop)', 'Skull Woods Final Section (Mothula)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)'], ItemFactory('Big Key (Skull Woods)'), ItemFactory(['Small Key (Skull Woods)'] * 2), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)']))
SP = make_dungeon('Swamp Palace', ['Swamp Palace (Entrance)', 'Swamp Palace (First Room)', 'Swamp Palace (Starting Area)', 'Swamp Palace (Center)', 'Swamp Palace (North)'], ItemFactory('Big Key (Swamp Palace)'), [ItemFactory('Small Key (Swamp Palace)')], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)'])) SP = make_dungeon('Swamp Palace', ['Swamp Palace (Entrance)', 'Swamp Palace (First Room)', 'Swamp Palace (Starting Area)', 'Swamp Palace (Center)', 'Swamp Palace (North)'], ItemFactory('Big Key (Swamp Palace)'), [ItemFactory('Small Key (Swamp Palace)')], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)']))
IP = make_dungeon('Ice Palace', ['Ice Palace (Entrance)', 'Ice Palace (Main)', 'Ice Palace (East)', 'Ice Palace (East Top)', 'Ice Palace (Kholdstare)'], ItemFactory('Big Key (Ice Palace)'), ItemFactory(['Small Key (Ice Palace)'] * 2), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)'])) IP = make_dungeon('Ice Palace', ['Ice Palace (Entrance)', 'Ice Palace (Main)', 'Ice Palace (East)', 'Ice Palace (East Top)', 'Ice Palace (Kholdstare)'], ItemFactory('Big Key (Ice Palace)'), ItemFactory(['Small Key (Ice Palace)'] * 2), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)']))
MM = make_dungeon('Misery Mire', ['Misery Mire (Entrance)', 'Misery Mire (Main)', 'Misery Mire (West)', 'Misery Mire (Final Area)', 'Misery Mire (Vitreous)'], ItemFactory('Big Key (Misery Mire)'), ItemFactory(['Small Key (Misery Mire)'] * 3), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)'])) MM = make_dungeon('Misery Mire', ['Misery Mire (Entrance)', 'Misery Mire (Main)', 'Misery Mire (West)', 'Misery Mire (Final Area)', 'Misery Mire (Vitreous)'], ItemFactory('Big Key (Misery Mire)'), ItemFactory(['Small Key (Misery Mire)'] * 3), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)']))

View File

@ -293,7 +293,7 @@ def link_entrances(world):
('North Fairy Cave Exit', 'North Fairy Cave'), ('North Fairy Cave Exit', 'North Fairy Cave'),
('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'), ('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'),
('Lumberjack Tree Exit', 'Lumberjack Tree (top)'), ('Lumberjack Tree Exit', 'Lumberjack Tree (top)'),
(('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section')] (('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section (Drop)')]
if world.mode == 'standard': if world.mode == 'standard':
# cannot move uncle cave # cannot move uncle cave
@ -519,7 +519,7 @@ def link_entrances(world):
hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave',
'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole']
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section', hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)',
'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)']
if world.mode == 'standard': if world.mode == 'standard':
@ -834,7 +834,7 @@ def connect_doors(world, doors, targets):
def skull_woods_shuffle(world): def skull_woods_shuffle(world):
connect_random(world, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'], connect_random(world, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'],
['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)', 'Skull Woods Second Section']) ['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)', 'Skull Woods Second Section (Drop)'])
connect_random(world, ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'], connect_random(world, ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'],
['Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'], True) ['Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'], True)
@ -1173,6 +1173,8 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'),
('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'),
('Death Mountain Return Ledge Drop', 'Light World'), ('Death Mountain Return Ledge Drop', 'Light World'),
('Old Man House Front to Back', 'Old Man House Back'),
('Old Man House Back to Front', 'Old Man House'),
('Broken Bridge (West)', 'East Death Mountain (Bottom)'), ('Broken Bridge (West)', 'East Death Mountain (Bottom)'),
('Broken Bridge (East)', 'Death Mountain'), ('Broken Bridge (East)', 'Death Mountain'),
('East Death Mountain Drop', 'East Death Mountain (Bottom)'), ('East Death Mountain Drop', 'East Death Mountain (Bottom)'),
@ -1232,6 +1234,7 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
('Turtle Rock Teleporter', 'Turtle Rock (Top)'), ('Turtle Rock Teleporter', 'Turtle Rock (Top)'),
('Turtle Rock Drop', 'Dark Death Mountain (Top)'), ('Turtle Rock Drop', 'Dark Death Mountain (Top)'),
('Floating Island Drop', 'Dark Death Mountain (Top)'), ('Floating Island Drop', 'Dark Death Mountain (Top)'),
('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'),
('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'),
('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'),
('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'),
@ -1249,6 +1252,7 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
('Skull Woods First Section (Left) Door to Right', 'Skull Woods First Section (Right)'), ('Skull Woods First Section (Left) Door to Right', 'Skull Woods First Section (Right)'),
('Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section'), ('Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section'),
('Skull Woods First Section (Top) One-Way Path', 'Skull Woods First Section'), ('Skull Woods First Section (Top) One-Way Path', 'Skull Woods First Section'),
('Skull Woods Second Section (Drop)', 'Skull Woods Second Section'),
('Blind Fight', 'Blind Fight'), ('Blind Fight', 'Blind Fight'),
('Ice Palace Entrance Room', 'Ice Palace (Main)'), ('Ice Palace Entrance Room', 'Ice Palace (Main)'),
('Ice Palace (East)', 'Ice Palace (East)'), ('Ice Palace (East)', 'Ice Palace (East)'),
@ -1439,7 +1443,7 @@ default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'),
('Superbunny Cave Exit (Top)', 'Dark Death Mountain (Top)'), ('Superbunny Cave Exit (Top)', 'Dark Death Mountain (Top)'),
('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'), ('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'),
('Hookshot Cave Exit (South)', 'Dark Death Mountain (Top)'), ('Hookshot Cave Exit (South)', 'Dark Death Mountain (Top)'),
('Hookshot Cave Exit (North)', 'Death Mountain Floating Island'), ('Hookshot Cave Exit (North)', 'Death Mountain Floating Island (Dark World)'),
('Hookshot Cave Back Entrance', 'Hookshot Cave'), ('Hookshot Cave Back Entrance', 'Hookshot Cave'),
('Mimic Cave Mirror Spot', 'Mimic Cave'), ('Mimic Cave Mirror Spot', 'Mimic Cave'),
@ -1479,7 +1483,7 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace
('Skull Woods First Section Hole (North)', 'Skull Woods First Section (Top)'), ('Skull Woods First Section Hole (North)', 'Skull Woods First Section (Top)'),
('Skull Woods First Section Door', 'Skull Woods First Section'), ('Skull Woods First Section Door', 'Skull Woods First Section'),
('Skull Woods First Section Exit', 'Skull Woods Forest'), ('Skull Woods First Section Exit', 'Skull Woods Forest'),
('Skull Woods Second Section Hole', 'Skull Woods Second Section'), ('Skull Woods Second Section Hole', 'Skull Woods Second Section (Drop)'),
('Skull Woods Second Section Door (East)', 'Skull Woods Second Section'), ('Skull Woods Second Section Door (East)', 'Skull Woods Second Section'),
('Skull Woods Second Section Door (West)', 'Skull Woods Second Section'), ('Skull Woods Second Section Door (West)', 'Skull Woods Second Section'),
('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'),
@ -1772,7 +1776,7 @@ exit_ids = {'Desert Palace Exit (South)': (0x09, 0x84),
'Lost Woods Hideout (top)': 0x7A, 'Lost Woods Hideout (top)': 0x7A,
'Lumberjack Tree (top)': 0x7F, 'Lumberjack Tree (top)': 0x7F,
'Sewer Drop': 0x81, 'Sewer Drop': 0x81,
'Skull Woods Second Section': 0x79, 'Skull Woods Second Section (Drop)': 0x79,
'Skull Woods First Section (Left)': 0x77, 'Skull Woods First Section (Left)': 0x77,
'Skull Woods First Section (Right)': 0x78, 'Skull Woods First Section (Right)': 0x78,
'Skull Woods First Section (Top)': 0x76, 'Skull Woods First Section (Top)': 0x76,

View File

@ -1,5 +1,5 @@
from BaseClasses import World, CollectionState, Item from BaseClasses import World, CollectionState, Item
from Regions import create_regions from Regions import create_regions, mark_light_world_regions
from EntranceShuffle import link_entrances from EntranceShuffle import link_entrances
from Rom import patch_rom, LocalRom, JsonRom from Rom import patch_rom, LocalRom, JsonRom
from Rules import set_rules from Rules import set_rules
@ -48,6 +48,7 @@ def main(args, seed=None):
logger.info('Shuffling the World about.') logger.info('Shuffling the World about.')
link_entrances(world) link_entrances(world)
mark_light_world_regions(world)
logger.info('Calculating Access Rules.') logger.info('Calculating Access Rules.')
@ -134,8 +135,10 @@ def copy_world(world):
# connect copied world # connect copied world
for region in world.regions: for region in world.regions:
copied_region = ret.get_region(region.name)
copied_region.is_light_world = region.is_light_world
for entrance in region.entrances: for entrance in region.entrances:
ret.get_entrance(entrance.name).connect(ret.get_region(region.name)) ret.get_entrance(entrance.name).connect(copied_region)
# fill locations # fill locations
for location in world.get_locations(): for location in world.get_locations():

View File

@ -1,3 +1,4 @@
import collections
from BaseClasses import Region, Location, Entrance from BaseClasses import Region, Location, Entrance
@ -178,7 +179,8 @@ def create_regions(world):
create_region('Spike Cave', ['Spike Cave']), create_region('Spike Cave', ['Spike Cave']),
create_region('Hookshot Cave', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], create_region('Hookshot Cave', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'],
['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']), ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']),
create_region('Death Mountain Floating Island', ['Floating Island'], ['Floating Island Drop', 'Hookshot Cave Back Entrance']), create_region('Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']),
create_region('Death Mountain Floating Island (Light World)', ['Floating Island'] ),
create_region('Turtle Rock (Top)', None, ['Turtle Rock Drop']), create_region('Turtle Rock (Top)', None, ['Turtle Rock Drop']),
create_region('Mimic Cave', ['Mimic Cave']), create_region('Mimic Cave', ['Mimic Cave']),
@ -201,6 +203,7 @@ def create_regions(world):
create_region('Skull Woods First Section (Right)', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']), create_region('Skull Woods First Section (Right)', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']),
create_region('Skull Woods First Section (Left)', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']), create_region('Skull Woods First Section (Left)', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']),
create_region('Skull Woods First Section (Top)', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']), create_region('Skull Woods First Section (Top)', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']),
create_region('Skull Woods Second Section (Drop)', None, ['Skull Woods Second Section (Drop)']),
create_region('Skull Woods Second Section', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']), create_region('Skull Woods Second Section', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']),
create_region('Skull Woods Final Section (Entrance)', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']), create_region('Skull Woods Final Section (Entrance)', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']),
create_region('Skull Woods Final Section (Mothula)', ['Skull Woods - Mothula', 'Skull Woods - Prize']), create_region('Skull Woods Final Section (Mothula)', ['Skull Woods - Mothula', 'Skull Woods - Prize']),
@ -282,6 +285,27 @@ def create_region(name, locations=None, exits=None):
return ret return ret
def mark_light_world_regions(world):
# Note that in "inanity" shuffle this code may mark some dark world locations as being in light world. That is fine because this flag
# is only used for bunny logic, and you start with a Moon pearl immediately availible in Insanity shuffle.
# Exclude entrances that represent connections from the light world to the dark world
excluded_entrances = set(['Top of Pyramid', 'Lake Hylia Central Island Teleporter', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter', 'Death Mountain Teleporter', 'East Death Mountain Teleporter', 'Turtle Rock Teleporter'])
starting_regions = ['Links House', 'Cave 45', 'Graveyard Cave','Mimic Cave', 'Death Mountain Floating Island (Light World)','Desert Ledge (West)', 'Lake Hylia Island', 'Spectacle Rock']
queue = collections.deque([world.get_region(region) for region in starting_regions])
seen = set(queue)
while queue:
current = queue.popleft()
current.is_light_world = True
for exit in current.exits:
if exit.name in excluded_entrances:
continue
if exit.connected_region not in seen:
seen.add(exit.connected_region)
queue.append(exit.connected_region)
location_table = {'Mushroom': (0x180013, False, 'in the woods'), location_table = {'Mushroom': (0x180013, False, 'in the woods'),
'Bottle Merchant': (0x2EB18, False, 'with a merchant'), 'Bottle Merchant': (0x2EB18, False, 'with a merchant'),
'Flute Spot': (0x18014A, False, 'underground'), 'Flute Spot': (0x18014A, False, 'underground'),

140
Rules.py
View File

@ -33,6 +33,8 @@ def set_rules(world):
if not world.swamp_patch_required: if not world.swamp_patch_required:
add_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has_Mirror()) add_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has_Mirror())
set_bunny_rules(world)
def set_rule(spot, rule): def set_rule(spot, rule):
spot.access_rule = rule spot.access_rule = rule
@ -76,7 +78,7 @@ def global_rules(world):
world.get_region('Old Man House').can_reach = lambda state: state.can_reach('Old Man', 'Location') or old_rule(state) world.get_region('Old Man House').can_reach = lambda state: state.can_reach('Old Man', 'Location') or old_rule(state)
# overworld requirements # overworld requirements
set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Mirror() and state.can_reach('West Dark World')))) set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Pearl() and state.has_Mirror() and state.can_reach('West Dark World'))))
set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots()) set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots())
set_rule(world.get_location('Sunken Treasure'), lambda state: state.can_reach('Dam')) set_rule(world.get_location('Sunken Treasure'), lambda state: state.can_reach('Dam'))
set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer')) set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer'))
@ -90,9 +92,9 @@ def global_rules(world):
set_rule(world.get_entrance('Flute Spot 1'), lambda state: state.has('Ocarina')) set_rule(world.get_entrance('Flute Spot 1'), lambda state: state.has('Ocarina'))
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter'), lambda state: state.can_lift_heavy_rocks()) set_rule(world.get_entrance('Lake Hylia Central Island Teleporter'), lambda state: state.can_lift_heavy_rocks())
set_rule(world.get_entrance('Dark Desert Teleporter'), lambda state: state.has('Ocarina') and state.can_lift_heavy_rocks()) set_rule(world.get_entrance('Dark Desert Teleporter'), lambda state: state.has('Ocarina') and state.can_lift_heavy_rocks())
set_rule(world.get_entrance('East Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) set_rule(world.get_entrance('East Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) # bunny cannot use hammer
set_rule(world.get_entrance('South Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) set_rule(world.get_entrance('South Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) # bunny cannot use hammer
set_rule(world.get_entrance('Kakariko Teleporter'), lambda state: ((state.has('Hammer') and state.can_lift_rocks()) or state.can_lift_heavy_rocks()) and state.has_Pearl()) set_rule(world.get_entrance('Kakariko Teleporter'), lambda state: ((state.has('Hammer') and state.can_lift_rocks()) or state.can_lift_heavy_rocks()) and state.has_Pearl()) # bunny cannot lift bushes
set_rule(world.get_location('Flute Spot'), lambda state: state.has('Shovel')) set_rule(world.get_location('Flute Spot'), lambda state: state.has('Shovel'))
set_rule(world.get_location('Purple Chest'), lambda state: state.can_reach('Blacksmith', 'Location')) # Can S&Q with chest set_rule(world.get_location('Purple Chest'), lambda state: state.can_reach('Blacksmith', 'Location')) # Can S&Q with chest
@ -123,67 +125,62 @@ def global_rules(world):
set_rule(world.get_location('Ether Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword()) set_rule(world.get_location('Ether Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword())
set_rule(world.get_entrance('East Death Mountain (Top)'), lambda state: state.has('Hammer')) set_rule(world.get_entrance('East Death Mountain (Top)'), lambda state: state.has('Hammer'))
set_rule(world.get_location('Catfish'), lambda state: state.has_Pearl() and state.can_lift_rocks()) set_rule(world.get_location('Catfish'), lambda state: state.can_lift_rocks())
set_rule(world.get_entrance('Dark Lake Hylia Fairy'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Palace of Darkness Hint'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('East Dark World Hint'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Dark World Potion Shop'), lambda state: state.has_Pearl() and (state.can_lift_rocks() or state.has('Hammer') or state.has('Flippers'))) set_rule(world.get_entrance('Dark World Potion Shop'), lambda state: state.has_Pearl() and (state.can_lift_rocks() or state.has('Hammer') or state.has('Flippers')))
set_rule(world.get_entrance('South Dark World Bridge'), lambda state: state.has('Hammer') and state.has_Pearl()) set_rule(world.get_entrance('South Dark World Bridge'), lambda state: state.has('Hammer') and state.has_Pearl())
set_rule(world.get_entrance('Bonk Fairy (Dark)'), lambda state: state.has_Boots()) set_rule(world.get_entrance('Bonk Fairy (Dark)'), lambda state: state.has_Pearl() and state.has_Boots())
set_rule(world.get_entrance('West Dark World Gap'), lambda state: state.has_Pearl() and state.has('Hookshot') and (state.has('Flippers') or state.has('Hammer') or state.can_lift_rocks())) set_rule(world.get_entrance('West Dark World Gap'), lambda state: state.has_Pearl() and state.has('Hookshot') and (state.has('Flippers') or state.has('Hammer') or state.can_lift_rocks()))
set_rule(world.get_entrance('Palace of Darkness'), lambda state: state.has_Pearl()) set_rule(world.get_entrance('Palace of Darkness'), lambda state: state.has_Pearl()) # kiki needs pearl
set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Hyrule Castle Main Gate'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Hyrule Castle Main Gate'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: (state.has_Pearl() and state.has('Flippers') or state.has_Mirror())) # Overworld Bunny Revival set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: (state.has_Pearl() and state.has('Flippers') or state.has_Mirror())) # Overworld Bunny Revival
set_rule(world.get_location('Bombos Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword() and state.has_Mirror()) set_rule(world.get_location('Bombos Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword() and state.has_Mirror())
set_rule(world.get_entrance('Dark Lake Hylia Drop (South)'), lambda state: state.has('Flippers')) # ToDo any fake flipper set up? set_rule(world.get_entrance('Dark Lake Hylia Drop (South)'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up?
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy'), lambda state: state.has_Pearl()) # bomb required
set_rule(world.get_entrance('Dark Lake Hylia Ledge'), lambda state: state.has_Pearl()) # To avoid Bunny nonsense for now set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl())
set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) # Fake Flippers set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) # Fake Flippers
set_rule(world.get_entrance('Village of Outcasts Heavy Rock'), lambda state: state.can_lift_heavy_rocks()) set_rule(world.get_entrance('Village of Outcasts Heavy Rock'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks())
set_rule(world.get_entrance('Hype Cave'), lambda state: state.has_Pearl()) # bomb required
set_rule(world.get_entrance('Brewery'), lambda state: state.has_Pearl()) # bomb required
set_rule(world.get_entrance('Thieves Town'), lambda state: state.has_Pearl()) # bunny cannot pull
set_rule(world.get_entrance('Skull Woods First Section Hole (North)'), lambda state: state.has_Pearl()) # bunny cannot lift bush
set_rule(world.get_entrance('Maze Race Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Maze Race Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Cave 45'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Cave 45'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('East Dark World Bridge'), lambda state: state.has('Hammer')) set_rule(world.get_entrance('East Dark World Bridge'), lambda state: state.has_Pearl() and state.has('Hammer'))
set_rule(world.get_entrance('Lake Hylia Island Mirror Spot'), lambda state: state.has_Mirror() and state.has('Flippers')) set_rule(world.get_entrance('Lake Hylia Island Mirror Spot'), lambda state: state.has_Pearl() and state.has_Mirror() and state.has('Flippers'))
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has('Flippers')) # ToDo any fake flipper set up? set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up?
set_rule(world.get_entrance('Graveyard Cave'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Graveyard Cave'), lambda state: state.has_Pearl() and state.has_Mirror())
set_rule(world.get_entrance('Bumper Cave (Bottom)'), lambda state: state.can_lift_rocks()) set_rule(world.get_entrance('Bumper Cave (Bottom)'), lambda state: state.has_Pearl() and state.can_lift_rocks())
set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.can_lift_heavy_rocks() and state.has_Mirror()) set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has_Mirror())
set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.can_lift_heavy_rocks() and state.has('Hammer')) set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has('Hammer'))
set_rule(world.get_entrance('Dark World Shop'), lambda state: state.has('Hammer')) set_rule(world.get_entrance('Dark World Shop'), lambda state: state.has_Pearl() and state.has('Hammer'))
set_rule(world.get_entrance('Bumper Cave Exit (Top)'), lambda state: state.has('Cape')) set_rule(world.get_entrance('Bumper Cave Exit (Top)'), lambda state: state.has('Cape'))
set_rule(world.get_entrance('Bumper Cave Exit (Bottom)'), lambda state: state.has('Cape') or state.has('Hookshot')) set_rule(world.get_entrance('Bumper Cave Exit (Bottom)'), lambda state: state.has('Cape') or state.has('Hookshot'))
set_rule(world.get_entrance('Skull Woods Final Section'), lambda state: state.has('Fire Rod'))
set_rule(world.get_entrance('Skull Woods Final Section'), lambda state: state.has('Fire Rod') and state.has_Pearl()) # bunny cannot use fire rod
set_rule(world.get_entrance('Misery Mire'), lambda state: state.has_Pearl() and state.has_sword() and state.has_misery_mire_medallion()) # sword required to cast magic (!) set_rule(world.get_entrance('Misery Mire'), lambda state: state.has_Pearl() and state.has_sword() and state.has_misery_mire_medallion()) # sword required to cast magic (!)
set_rule(world.get_entrance('Desert Ledge (West) Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Desert Ledge (West) Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Desert Ledge Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Desert Ledge Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Desert Palace Entrance (North) Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Desert Palace Entrance (North) Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Mire Shed'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
set_rule(world.get_entrance('Dark Desert Hint'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
set_rule(world.get_entrance('Dark Desert Fairy'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
set_rule(world.get_entrance('Spike Cave'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Dark Death Mountain Fairy'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Spectacle Rock Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Spectacle Rock Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Ganons Tower'), lambda state: state.has('Crystal 1') and state.has('Crystal 2') and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7')) set_rule(world.get_entrance('Ganons Tower'), lambda state: state.has('Crystal 1') and state.has('Crystal 2') and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7'))
set_rule(world.get_entrance('Hookshot Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl()) set_rule(world.get_entrance('Hookshot Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl())
set_rule(world.get_entrance('East Death Mountain (Top) Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('East Death Mountain (Top) Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Mimic Cave Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Mimic Cave Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Spiral Cave Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Spiral Cave Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Fairy Ascension Mirror Spot'), lambda state: state.has_Mirror() and state.has_Pearl()) # need to lift flowers set_rule(world.get_entrance('Fairy Ascension Mirror Spot'), lambda state: state.has_Mirror() and state.has_Pearl()) # need to lift flowers
set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Superbunny Cave (Top)'), lambda state: state.has_Pearl()) # Chests inside could be collected with super bunny, but may be shuffled. rather limit access for now ToDo
set_rule(world.get_entrance('Superbunny Cave (Bottom)'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Cave Shop (Dark Death Mountain)'), lambda state: state.has_Pearl()) # just for save bunny algo for now
set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling
set_rule(world.get_location('Spike Cave'), lambda state: state.has('Hammer') and state.can_lift_rocks() and (state.has('Cane of Byrna') or state.has('Cape')) and (state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic'))) set_rule(world.get_location('Spike Cave'), lambda state: state.has('Hammer') and state.can_lift_rocks() and (state.has('Cane of Byrna') or state.has('Cape')) and (state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic')))
set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot')) set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot'))
set_rule(world.get_location('Hookshot Cave - Top Left'), lambda state: state.has('Hookshot')) set_rule(world.get_location('Hookshot Cave - Top Left'), lambda state: state.has('Hookshot'))
set_rule(world.get_location('Hookshot Cave - Bottom Right'), lambda state: state.has('Hookshot') or state.has('Pegasus Boots')) set_rule(world.get_location('Hookshot Cave - Bottom Right'), lambda state: state.has('Hookshot') or state.has('Pegasus Boots'))
set_rule(world.get_location('Hookshot Cave - Bottom Left'), lambda state: state.has('Hookshot')) set_rule(world.get_location('Hookshot Cave - Bottom Left'), lambda state: state.has('Hookshot'))
set_rule(world.get_location('Floating Island'), lambda state: state.has_Mirror()) set_rule(world.get_entrance('Floating Island Mirror Spot'), lambda state: state.has_Mirror())
set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_sword() and state.has_turtle_rock_medallion() and state.can_reach('Turtle Rock (Top)', 'Region')) # sword required to cast magic (!) set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_sword() and state.has_turtle_rock_medallion() and state.can_reach('Turtle Rock (Top)', 'Region')) # sword required to cast magic (!)
set_rule(world.get_location('Mimic Cave'), lambda state: state.has('Hammer')) set_rule(world.get_location('Mimic Cave'), lambda state: state.has('Hammer'))
@ -357,8 +354,7 @@ def global_rules(world):
set_rule(world.get_entrance('Ganons Tower Moldorm Door'), lambda state: state.has('Small Key (Ganons Tower)', 4)) set_rule(world.get_entrance('Ganons Tower Moldorm Door'), lambda state: state.has('Small Key (Ganons Tower)', 4))
set_rule(world.get_entrance('Ganons Tower Moldorm Gap'), lambda state: state.has('Hookshot')) set_rule(world.get_entrance('Ganons Tower Moldorm Gap'), lambda state: state.has('Hookshot'))
set_rule(world.get_location('Agahnim 2'), lambda state: state.has_sword() or state.has('Hammer') or state.has('Bug Catching Net')) set_rule(world.get_location('Agahnim 2'), lambda state: state.has_sword() or state.has('Hammer') or state.has('Bug Catching Net'))
set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.has('Beat Agahnim 2') and state.has_Pearl()) set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.has('Beat Agahnim 2'))
set_rule(world.get_entrance('Pyramid Entrance'), lambda state: state.has_Pearl())
for location in ['Ganons Tower - Big Chest', 'Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', for location in ['Ganons Tower - Big Chest', 'Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Validation Chest']: 'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Validation Chest']:
forbid_item(world.get_location(location), 'Big Key (Ganons Tower)') forbid_item(world.get_location(location), 'Big Key (Ganons Tower)')
@ -373,10 +369,9 @@ def no_glitches_rules(world):
set_rule(world.get_entrance('Zoras River'), lambda state: state.has('Flippers') or state.can_lift_rocks()) set_rule(world.get_entrance('Zoras River'), lambda state: state.has('Flippers') or state.can_lift_rocks())
set_rule(world.get_entrance('Lake Hylia Central Island Pier'), lambda state: state.has('Flippers')) # can be fake flippered to set_rule(world.get_entrance('Lake Hylia Central Island Pier'), lambda state: state.has('Flippers')) # can be fake flippered to
set_rule(world.get_entrance('Hobo Bridge'), lambda state: state.has('Flippers')) set_rule(world.get_entrance('Hobo Bridge'), lambda state: state.has('Flippers'))
add_rule(world.get_entrance('Ice Palace'), lambda state: state.has_Pearl())
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: state.has_Pearl() and state.has('Flippers')) set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: state.has_Pearl() and state.has('Flippers'))
set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and state.has('Flippers') and (state.has('Hammer') or state.can_lift_rocks())) set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and state.has('Flippers') and (state.has('Hammer') or state.can_lift_rocks()))
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop'), lambda state: state.has('Flippers')) set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop'), lambda state: state.has_Pearl() and state.has('Flippers'))
add_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hookshot')) add_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hookshot'))
set_rule(world.get_entrance('Paradox Cave Push Block Reverse'), lambda state: False) # no glitches does not require block override set_rule(world.get_entrance('Paradox Cave Push Block Reverse'), lambda state: False) # no glitches does not require block override
set_rule(world.get_entrance('Paradox Cave Bomb Jump'), lambda state: False) set_rule(world.get_entrance('Paradox Cave Bomb Jump'), lambda state: False)
@ -583,20 +578,75 @@ def set_big_bomb_rules(world):
'Mimic Cave Mirror Spot'] 'Mimic Cave Mirror Spot']
Isolated_LW_entrances = ['Capacity Upgrade', Isolated_LW_entrances = ['Capacity Upgrade',
'Hookshot Fairy'] 'Hookshot Fairy']
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6')) set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('East Dark World', 'Region') and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
if bombshop_entrance.name in Normal_LW_entrances: if bombshop_entrance.name in Normal_LW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()) or state.has_Mirror()) #1. Enter via gate: Needs Aga1
#2. south hyrule teleporter and cross peg bridge: Hammer and moon pearl
#3. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
# -> A or (H and P)) or (M)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or state.has_Mirror())
elif bombshop_entrance.name in LW_walkable_entrances: elif bombshop_entrance.name in LW_walkable_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()))) #1. Mirror then gate: Needs mirror and Aga1
#2. Mirror then go to south hyrule teleporter and cross peg bridge: Needs Mirror and Hammer and moon pearl
# -> M and (A or (H and P))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
elif bombshop_entrance.name in Northern_DW_entrances: elif bombshop_entrance.name in Northern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has('Hammer')) or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks())))) #1. Mirror and enter via gate: Need mirror and Aga1
#2. Mirror and enter via south hyrule teleporter: Need mirror and hammer and moon pearl
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
# -> (Mitts and P and H) or (M and (A or (H and P)))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has_Pearl() and state.has('Hammer')) or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()))))
elif bombshop_entrance.name in Southern_DW_entrances: elif bombshop_entrance.name in Southern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Hammer') or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks())))) #1. Mirror and enter via gate: Need mirror and Aga1
#2. cross peg bridge: Need hammer and moon pearl
# -> (H and P) or (M and A)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Hammer') and state.has_Pearl()) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
elif bombshop_entrance.name in Isolated_DW_entrances: elif bombshop_entrance.name in Isolated_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()))) # 1. mirror then flute then enter via gate: Needs mirror and flute and Aga 1
# 2. mirror then flute then enter via south hyrule teleporter: Needs mirror and Flute and hammer and moon pearl
# -> M and Flute and (A or (H and P))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
elif bombshop_entrance.name in Isolated_LW_entrances: elif bombshop_entrance.name in Isolated_LW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()))) # 1. flute then enter via gate: Needs flute and Aga 1
# 2. flute then enter via south hyrule teleporter: Needs Flute and hammer and moon pearl
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
# -> Flute and (A or (H and P))
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
elif bombshop_entrance.name == 'Dark World Potion Shop': elif bombshop_entrance.name == 'Dark World Potion Shop':
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Hammer') or state.can_lift_rocks() or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance'))) # 1. walk down by lifting rock: needs gloves and pearl`
# 2. walk down by hammering peg: needs hammer and pearl
# 3. mirror and eneter via gate: needs Mirror and Aga1
# (south hyrule teleporter would be redundant with #2)
# -> P and (H or H) or (M and A)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
elif bombshop_entrance.name == 'Kings Grave': elif bombshop_entrance.name == 'Kings Grave':
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.can_lift_rocks() and state.has('Hammer')) or (state.can_lift_heavy_rocks() and state.has_Mirror())) # same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
# -> A or (H and P) or (M and Mitts)
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or (state.can_lift_heavy_rocks() and state.has_Mirror()))
def set_bunny_rules(world):
# regions for the extis 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)']
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']
# Add pearl requirements for bunny-impassible caves if they occur in the dark world
for region in [world.get_region(name) for name in bunny_impassable_caves]:
if region.is_light_world:
continue
for exit in region.exits:
add_rule(exit, lambda state: state.has_Pearl)
# Add a moon pearl requirement for all locations that are actually in the dark world, except those available to the bunny
for location in world.get_locations():
if not location.parent_region.is_light_world:
if location.name in bunny_accessible_locations:
continue
add_rule(location, lambda state: state.has_Pearl())