2018-01-27 22:17:03 +00:00
import collections
2017-05-20 12:04:02 +00:00
import logging
2017-05-16 19:23:47 +00:00
def set_rules ( world ) :
2018-03-25 22:21:36 +00:00
if world . logic == ' nologic ' :
logging . getLogger ( ' ' ) . info ( ' WARNING! Seeds generated under this logic often require major glitches and may be impossible! ' )
world . get_region ( ' Links House ' ) . can_reach = lambda state : True
world . get_region ( ' Sanctuary ' ) . can_reach = lambda state : True
old_rule = world . get_region ( ' Old Man House ' ) . can_reach
world . get_region ( ' Old Man House ' ) . can_reach = lambda state : state . can_reach ( ' Old Man ' , ' Location ' ) or old_rule ( state )
return
2017-05-15 18:28:04 +00:00
global_rules ( world )
2017-11-04 18:23:57 +00:00
2017-05-16 19:23:47 +00:00
if world . mode == ' open ' :
open_rules ( world )
elif world . mode == ' standard ' :
standard_rules ( world )
2017-06-24 16:48:03 +00:00
elif world . mode == ' swordless ' :
swordless_rules ( world )
2017-05-16 19:23:47 +00:00
else :
raise NotImplementedError ( ' Not implemented yet ' )
2017-10-19 02:46:47 +00:00
if world . logic == ' noglitches ' :
no_glitches_rules ( world )
elif world . logic == ' minorglitches ' :
logging . getLogger ( ' ' ) . info ( ' Minor Glitches may be buggy still. No guarantee for proper logic checks. ' )
else :
raise NotImplementedError ( ' Not implemented yet ' )
2017-05-20 12:04:02 +00:00
if world . goal == ' dungeons ' :
2017-07-14 14:28:14 +00:00
# require all dungeons to beat ganon
2017-10-29 03:42:35 +00:00
add_rule ( world . get_location ( ' Ganon ' ) , lambda state : state . can_reach ( ' Master Sword Pedestal ' , ' Location ' ) and state . has ( ' Beat Agahnim 1 ' ) and state . has ( ' Beat Agahnim 2 ' ) )
2017-08-01 17:07:44 +00:00
elif world . goal == ' ganon ' :
# require aga2 to beat ganon
add_rule ( world . get_location ( ' Ganon ' ) , lambda state : state . has ( ' Beat Agahnim 2 ' ) )
2017-05-16 19:23:47 +00:00
2017-05-20 12:04:02 +00:00
set_big_bomb_rules ( world )
# if swamp and dam have not been moved we require mirror for swamp palace
if not world . swamp_patch_required :
add_rule ( world . get_entrance ( ' Swamp Palace Moat ' ) , lambda state : state . has_Mirror ( ) )
2017-12-13 14:51:53 +00:00
set_bunny_rules ( world )
2017-05-15 18:28:04 +00:00
def set_rule ( spot , rule ) :
spot . access_rule = rule
2018-09-26 17:12:20 +00:00
def set_defeat_dungeon_boss_rule ( location ) :
# Lambda required to defer evaluation of dungeon.boss since it will change later if boos shuffle is used
set_rule ( location , lambda state : location . parent_region . dungeon . boss . can_defeat ( state ) )
2018-01-02 05:39:53 +00:00
def set_always_allow ( spot , rule ) :
spot . always_allow = rule
2017-05-15 18:28:04 +00:00
def add_rule ( spot , rule , combine = ' and ' ) :
old_rule = spot . access_rule
if combine == ' or ' :
spot . access_rule = lambda state : rule ( state ) or old_rule ( state )
else :
spot . access_rule = lambda state : rule ( state ) and old_rule ( state )
2017-05-20 13:47:28 +00:00
def add_lamp_requirement ( spot ) :
2018-02-24 21:16:50 +00:00
add_rule ( spot , lambda state : state . has ( ' Lamp ' , state . world . lamps_needed_for_dark_rooms ) )
2017-05-20 13:47:28 +00:00
2017-05-15 18:28:04 +00:00
def forbid_item ( location , item ) :
old_rule = location . item_rule
location . item_rule = lambda i : i . name != item and old_rule ( i )
2017-11-04 18:23:57 +00:00
2017-10-14 18:45:59 +00:00
def item_in_locations ( state , item , locations ) :
for location in locations :
2018-01-06 03:46:00 +00:00
if item_name ( state , location ) == item :
2017-10-14 18:45:59 +00:00
return True
return False
2017-05-15 18:28:04 +00:00
2018-01-06 03:46:00 +00:00
def item_name ( state , location ) :
location = state . world . get_location ( location )
2018-01-02 05:39:53 +00:00
if location . item is None :
return None
return location . item . name
2017-05-15 18:28:04 +00:00
def global_rules ( world ) :
# ganon can only carry triforce
world . get_location ( ' Ganon ' ) . item_rule = lambda item : item . name == ' Triforce '
2017-05-20 12:04:02 +00:00
# these are default save&quit points and always accessible
world . get_region ( ' Links House ' ) . can_reach = lambda state : True
world . get_region ( ' Sanctuary ' ) . can_reach = lambda state : True
2017-05-20 13:47:28 +00:00
# we can s&q to the old man house after we rescue him. This may be somewhere completely different if caves are shuffled!
old_rule = world . get_region ( ' Old Man House ' ) . can_reach
2017-10-29 03:42:35 +00:00
world . get_region ( ' Old Man House ' ) . can_reach = lambda state : state . can_reach ( ' Old Man ' , ' Location ' ) or old_rule ( state )
2017-05-20 13:47:28 +00:00
2017-05-15 18:28:04 +00:00
# overworld requirements
2018-02-20 02:30:56 +00:00
set_rule ( world . get_entrance ( ' Kings Grave ' ) , lambda state : state . has_Boots ( ) )
set_rule ( world . get_entrance ( ' Kings Grave Outer Rocks ' ) , lambda state : state . can_lift_heavy_rocks ( ) )
set_rule ( world . get_entrance ( ' Kings Grave Inner Rocks ' ) , lambda state : state . can_lift_heavy_rocks ( ) )
set_rule ( world . get_entrance ( ' Kings Grave Mirror Spot ' ) , lambda state : state . has_Pearl ( ) and state . has_Mirror ( ) )
2018-01-20 21:36:03 +00:00
# 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)
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' Bonk Fairy (Light) ' ) , lambda state : state . has_Boots ( ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Sunken Treasure ' ) , lambda state : state . can_reach ( ' Dam ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Bat Cave Drop Ledge ' ) , lambda state : state . has ( ' Hammer ' ) )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Lumberjack Tree Tree ' ) , lambda state : state . has_Boots ( ) and state . has ( ' Beat Agahnim 1 ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Bonk Rock Cave ' ) , lambda state : state . has_Boots ( ) )
set_rule ( world . get_entrance ( ' Desert Palace Stairs ' ) , lambda state : state . has ( ' Book of Mudora ' ) )
set_rule ( world . get_entrance ( ' Sanctuary Grave ' ) , lambda state : state . can_lift_rocks ( ) )
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' 20 Rupee Cave ' ) , lambda state : state . can_lift_rocks ( ) )
set_rule ( world . get_entrance ( ' 50 Rupee Cave ' ) , lambda state : state . can_lift_rocks ( ) )
2018-02-07 04:07:13 +00:00
set_rule ( world . get_entrance ( ' Death Mountain Entrance Rock ' ) , lambda state : state . can_lift_rocks ( ) )
set_rule ( world . get_entrance ( ' Bumper Cave Entrance Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Flute Spot 1 ' ) , lambda state : state . has ( ' Ocarina ' ) )
2017-05-27 08:02:54 +00:00
set_rule ( world . get_entrance ( ' Lake Hylia Central Island Teleporter ' ) , lambda state : state . can_lift_heavy_rocks ( ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Dark Desert Teleporter ' ) , lambda state : state . has ( ' Ocarina ' ) and state . can_lift_heavy_rocks ( ) )
2017-12-13 14:51:53 +00:00
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 ( ) ) # 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 ( ) ) # bunny cannot lift bushes
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Flute Spot ' ) , lambda state : state . has ( ' Shovel ' ) )
2018-03-18 05:36:45 +00:00
set_rule ( world . get_location ( ' Dark Blacksmith Ruins ' ) , lambda state : state . has ( ' Return Smith ' ) )
set_rule ( world . get_location ( ' Purple Chest ' ) , lambda state : state . has ( ' Pick Up Purple Chest ' ) ) # Can S&Q with chest
2017-05-15 18:28:04 +00:00
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Zora \' s Ledge ' ) , lambda state : state . has ( ' Flippers ' ) )
2017-05-20 18:03:13 +00:00
set_rule ( world . get_entrance ( ' Waterfall of Wishing ' ) , lambda state : state . has ( ' Flippers ' ) ) # can be fake flippered into, but is in weird state inside that might prevent you from doing things. Can be improved in future Todo
2018-03-18 05:36:45 +00:00
set_rule ( world . get_location ( ' Frog ' ) , lambda state : state . can_lift_heavy_rocks ( ) ) # will get automatic moon pearl requirement
set_rule ( world . get_location ( ' Missing Smith ' ) , lambda state : state . has ( ' Get Frog ' ) ) # Can S&Q with smith
set_rule ( world . get_location ( ' Blacksmith ' ) , lambda state : state . has ( ' Return Smith ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_location ( ' Magic Bat ' ) , lambda state : state . has ( ' Magic Powder ' ) )
2017-11-12 02:22:44 +00:00
set_rule ( world . get_location ( ' Sick Kid ' ) , lambda state : state . has_bottle ( ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_location ( ' Library ' ) , lambda state : state . has_Boots ( ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Potion Shop ' ) , lambda state : state . has ( ' Mushroom ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Desert Palace Entrance (North) Rocks ' ) , lambda state : state . can_lift_rocks ( ) )
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' Desert Ledge Return Rocks ' ) , lambda state : state . can_lift_rocks ( ) ) # should we decide to place something that is not a dungeon end up there at some point
2017-06-03 12:19:49 +00:00
set_rule ( world . get_entrance ( ' Checkerboard Cave ' ) , lambda state : state . can_lift_rocks ( ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Master Sword Pedestal ' ) , lambda state : state . has ( ' Red Pendant ' ) and state . has ( ' Blue Pendant ' ) and state . has ( ' Green Pendant ' ) )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_location ( ' Sahasrahla ' ) , lambda state : state . has ( ' Green Pendant ' ) )
2017-06-24 16:48:03 +00:00
set_rule ( world . get_entrance ( ' Agahnims Tower ' ) , lambda state : state . has ( ' Cape ' ) or state . has_beam_sword ( ) or state . has ( ' Beat Agahnim 1 ' ) ) # barrier gets removed after killing agahnim, relevant for entrance shuffle
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Agahnim 1 ' ) , lambda state : state . has_sword ( ) and state . has_key ( ' Small Key (Agahnims Tower) ' , 2 ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Agahnim 1 ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Castle Tower - Dark Maze ' ) , lambda state : state . has_key ( ' Small Key (Agahnims Tower) ' ) )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Top of Pyramid ' ) , lambda state : state . has ( ' Beat Agahnim 1 ' ) )
2017-06-24 16:48:03 +00:00
set_rule ( world . get_entrance ( ' Old Man Cave Exit (West) ' ) , lambda state : False ) # drop cannot be climbed up
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Broken Bridge (West) ' ) , lambda state : state . has ( ' Hookshot ' ) )
set_rule ( world . get_entrance ( ' Broken Bridge (East) ' ) , lambda state : state . has ( ' Hookshot ' ) )
set_rule ( world . get_entrance ( ' East Death Mountain Teleporter ' ) , lambda state : state . can_lift_heavy_rocks ( ) )
2017-06-03 12:19:49 +00:00
set_rule ( world . get_entrance ( ' Fairy Ascension Rocks ' ) , lambda state : state . can_lift_heavy_rocks ( ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_entrance ( ' Paradox Cave Push Block Reverse ' ) , lambda state : state . has ( ' Mirror ' ) ) # can erase block
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Death Mountain (Top) ' ) , lambda state : state . has ( ' Hammer ' ) )
set_rule ( world . get_entrance ( ' Turtle Rock Teleporter ' ) , lambda state : state . can_lift_heavy_rocks ( ) and state . has ( ' Hammer ' ) )
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 ' ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_location ( ' Catfish ' ) , lambda state : state . can_lift_rocks ( ) )
2018-02-09 02:56:57 +00:00
set_rule ( world . get_entrance ( ' Northeast Dark World Broken Bridge Pass ' ) , lambda state : state . has_Pearl ( ) and ( state . can_lift_rocks ( ) or state . has ( ' Hammer ' ) or state . has ( ' Flippers ' ) ) )
set_rule ( world . get_entrance ( ' East Dark World Broken Bridge Pass ' ) , lambda state : state . has_Pearl ( ) and ( state . can_lift_rocks ( ) or state . has ( ' Hammer ' ) ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' South Dark World Bridge ' ) , lambda state : state . has ( ' Hammer ' ) and state . has_Pearl ( ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Bonk Fairy (Dark) ' ) , lambda state : state . has_Pearl ( ) and state . has_Boots ( ) )
2018-02-09 02:56:57 +00:00
set_rule ( world . get_entrance ( ' West Dark World Gap ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Hookshot ' ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness ' ) , lambda state : state . has_Pearl ( ) ) # kiki needs pearl
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Hyrule Castle Ledge Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-12-12 14:20:42 +00:00
set_rule ( world . get_entrance ( ' Hyrule Castle Main Gate ' ) , lambda state : state . has_Mirror ( ) )
2017-05-15 18:28:04 +00:00
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 ( ) )
2017-12-13 14:51:53 +00:00
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 Fairy ' ) , lambda state : state . has_Pearl ( ) ) # bomb required
set_rule ( world . get_entrance ( ' Dark Lake Hylia Ledge Spike Cave ' ) , lambda state : state . can_lift_rocks ( ) and state . has_Pearl ( ) )
2017-05-20 12:04:02 +00:00
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
2017-12-13 14:51:53 +00:00
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
2018-02-20 04:20:01 +00:00
set_rule ( world . get_entrance ( ' Skull Woods Second Section Hole ' ) , lambda state : state . has_Pearl ( ) ) # bunny cannot lift bush
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Maze Race Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2018-01-18 06:38:28 +00:00
set_rule ( world . get_entrance ( ' Cave 45 Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-12-13 14:51:53 +00:00
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_Pearl ( ) and state . has_Mirror ( ) and state . has ( ' Flippers ' ) )
2017-05-27 08:02:54 +00:00
set_rule ( world . get_entrance ( ' Lake Hylia Central Island Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-12-13 14:51:53 +00:00
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?
2018-01-18 06:38:28 +00:00
set_rule ( world . get_entrance ( ' Graveyard Ledge Mirror Spot ' ) , lambda state : state . has_Pearl ( ) and state . has_Mirror ( ) )
2018-02-07 04:07:13 +00:00
set_rule ( world . get_entrance ( ' Bumper Cave Entrance Rock ' ) , lambda state : state . has_Pearl ( ) and state . can_lift_rocks ( ) )
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' Bumper Cave Ledge Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2018-02-12 04:04:58 +00:00
set_rule ( world . get_entrance ( ' Bat Cave Drop Ledge Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
set_rule ( world . get_entrance ( ' Dark World Hammer Peg Cave ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Hammer ' ) )
set_rule ( world . get_entrance ( ' Village of Outcasts Eastern Rocks ' ) , lambda state : state . has_Pearl ( ) and state . can_lift_heavy_rocks ( ) )
set_rule ( world . get_entrance ( ' Peg Area Rocks ' ) , lambda state : state . has_Pearl ( ) and state . can_lift_heavy_rocks ( ) )
set_rule ( world . get_entrance ( ' Village of Outcasts Pegs ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Hammer ' ) )
set_rule ( world . get_entrance ( ' Grassy Lawn Pegs ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Hammer ' ) )
2017-05-20 12:04:02 +00:00
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 ' ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Skull Woods Final Section ' ) , lambda state : state . has ( ' Fire Rod ' ) and state . has_Pearl ( ) ) # bunny cannot use fire rod
2017-05-15 18:28:04 +00:00
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 (!)
2018-01-18 06:38:28 +00:00
set_rule ( world . get_entrance ( ' Desert Ledge (Northeast) Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2018-01-03 02:17:07 +00:00
2017-05-15 18:28:04 +00:00
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 Entrance (North) 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 ( ' Hookshot Cave ' ) , lambda state : state . can_lift_rocks ( ) and state . has_Pearl ( ) )
2017-12-13 14:51:53 +00:00
2017-05-15 18:28:04 +00:00
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 ( ) )
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' Spiral Cave Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-06-03 12:19:49 +00:00
set_rule ( world . get_entrance ( ' Fairy Ascension Mirror Spot ' ) , lambda state : state . has_Mirror ( ) and state . has_Pearl ( ) ) # need to lift flowers
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Isolated Ledge Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-11-12 00:03:42 +00:00
set_rule ( world . get_entrance ( ' Superbunny Cave Exit (Bottom) ' ) , lambda state : False ) # Cannot get to bottom exit from top. Just exists for shuffling
2018-01-25 01:03:34 +00:00
2018-01-06 18:39:22 +00:00
set_rule ( world . get_location ( ' Spike Cave ' ) , lambda state :
2018-01-07 04:08:20 +00:00
state . has ( ' Hammer ' ) and state . can_lift_rocks ( ) and
2018-01-30 00:56:15 +00:00
( ( state . has ( ' Cape ' ) and state . can_extend_magic ( 16 , True ) ) or
( state . has ( ' Cane of Byrna ' ) and
( state . can_extend_magic ( 12 , True ) or
( state . world . can_take_damage and ( state . has_Boots ( ) or state . has_hearts ( 4 ) ) ) ) ) )
2018-01-06 18:39:22 +00:00
)
2017-10-29 03:42:35 +00:00
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 - 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 ' ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Floating Island Mirror Spot ' ) , lambda state : state . has_Mirror ( ) )
2017-06-24 17:11:00 +00:00
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 (!)
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Mimic Cave ' ) , lambda state : state . has ( ' Hammer ' ) )
2017-05-15 18:28:04 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Sewers Door ' ) , lambda state : state . has_key ( ' Small Key (Escape) ' ) )
set_rule ( world . get_entrance ( ' Sewers Back Door ' ) , lambda state : state . has_key ( ' Small Key (Escape) ' ) )
2017-05-15 18:28:04 +00:00
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Eastern Palace - Big Chest ' ) , lambda state : state . has ( ' Big Key (Eastern Palace) ' ) )
2018-09-26 21:34:15 +00:00
set_rule ( world . get_location ( ' Eastern Palace - Boss ' ) , lambda state : state . can_shoot_arrows ( ) and state . has ( ' Big Key (Eastern Palace) ' ) and world . get_location ( ' Eastern Palace - Boss ' ) . parent_region . dungeon . boss . can_defeat ( state ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_location ( ' Eastern Palace - Prize ' ) , lambda state : state . can_shoot_arrows ( ) and state . has ( ' Big Key (Eastern Palace) ' ) and world . get_location ( ' Eastern Palace - Prize ' ) . parent_region . dungeon . boss . can_defeat ( state ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Eastern Palace - Boss ' , ' Eastern Palace - Big Chest ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Eastern Palace) ' )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Desert Palace - Big Chest ' ) , lambda state : state . has ( ' Big Key (Desert Palace) ' ) )
set_rule ( world . get_location ( ' Desert Palace - Torch ' ) , lambda state : state . has_Boots ( ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Desert Palace East Wing ' ) , lambda state : state . has_key ( ' Small Key (Desert Palace) ' ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_location ( ' Desert Palace - Prize ' ) , lambda state : state . has_key ( ' Small Key (Desert Palace) ' ) and state . has ( ' Big Key (Desert Palace) ' ) and state . has_fire_source ( ) and world . get_location ( ' Desert Palace - Prize ' ) . parent_region . dungeon . boss . can_defeat ( state ) )
2018-09-26 21:34:15 +00:00
set_rule ( world . get_location ( ' Desert Palace - Boss ' ) , lambda state : state . has_key ( ' Small Key (Desert Palace) ' ) and state . has ( ' Big Key (Desert Palace) ' ) and state . has_fire_source ( ) and world . get_location ( ' Desert Palace - Boss ' ) . parent_region . dungeon . boss . can_defeat ( state ) )
for location in [ ' Desert Palace - Boss ' , ' Desert Palace - Big Chest ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Desert Palace) ' )
2017-11-04 18:23:57 +00:00
2018-09-26 21:34:15 +00:00
for location in [ ' Desert Palace - Boss ' , ' Desert Palace - Big Key Chest ' , ' Desert Palace - Compass Chest ' ] :
2017-10-14 18:45:59 +00:00
forbid_item ( world . get_location ( location ) , ' Small Key (Desert Palace) ' )
2017-05-15 18:28:04 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Tower of Hera Small Key Door ' ) , lambda state : state . has_key ( ' Small Key (Tower of Hera) ' ) or item_name ( state , ' Tower of Hera - Big Key Chest ' ) == ' Small Key (Tower of Hera) ' )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Tower of Hera Big Key Door ' ) , lambda state : state . has ( ' Big Key (Tower of Hera) ' ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Tower of Hera - Big Chest ' ) , lambda state : state . has ( ' Big Key (Tower of Hera) ' ) )
set_rule ( world . get_location ( ' Tower of Hera - Big Key Chest ' ) , lambda state : state . has_fire_source ( ) )
2018-01-03 02:17:07 +00:00
set_always_allow ( world . get_location ( ' Tower of Hera - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Tower of Hera) ' )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Tower of Hera - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Tower of Hera - Prize ' ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Tower of Hera - Boss ' , ' Tower of Hera - Big Chest ' , ' Tower of Hera - Compass Chest ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Tower of Hera) ' )
2018-03-15 21:23:02 +00:00
# for location in ['Tower of Hera - Big Key Chest']:
# forbid_item(world.get_location(location), 'Small Key (Tower of Hera)')
2017-05-15 18:28:04 +00:00
2018-03-18 05:36:45 +00:00
set_rule ( world . get_entrance ( ' Swamp Palace Moat ' ) , lambda state : state . has ( ' Flippers ' ) and state . has ( ' Open Floodgate ' ) )
add_rule ( world . get_location ( ' Sunken Treasure ' ) , lambda state : state . has ( ' Open Floodgate ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Swamp Palace Small Key Door ' ) , lambda state : state . has_key ( ' Small Key (Swamp Palace) ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Swamp Palace (Center) ' ) , lambda state : state . has ( ' Hammer ' ) )
2018-01-06 03:46:00 +00:00
set_rule ( world . get_location ( ' Swamp Palace - Big Chest ' ) , lambda state : state . has ( ' Big Key (Swamp Palace) ' ) or item_name ( state , ' Swamp Palace - Big Chest ' ) == ' Big Key (Swamp Palace) ' )
2018-01-03 02:17:07 +00:00
set_always_allow ( world . get_location ( ' Swamp Palace - Big Chest ' ) , lambda state , item : item . name == ' Big Key (Swamp Palace) ' )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Swamp Palace (North) ' ) , lambda state : state . has ( ' Hookshot ' ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Swamp Palace - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Swamp Palace - Prize ' ) )
2018-01-03 02:17:07 +00:00
for location in [ ' Swamp Palace - Entrance ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Swamp Palace) ' )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Thieves Town Big Key Door ' ) , lambda state : state . has ( ' Big Key (Thieves Town) ' ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Blind Fight ' ) , lambda state : state . has_key ( ' Small Key (Thieves Town) ' ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Thieves \' Town - Boss ' ) )
set_defeat_dungeon_boss_rule ( world . get_location ( ' Thieves \' Town - Prize ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Thieves \' Town - Big Chest ' ) , lambda state : ( state . has_key ( ' Small Key (Thieves Town) ' ) or item_name ( state , ' Thieves \' Town - Big Chest ' ) == ' Small Key (Thieves Town) ' ) and state . has ( ' Hammer ' ) )
2018-01-27 19:16:47 +00:00
set_always_allow ( world . get_location ( ' Thieves \' Town - Big Chest ' ) , lambda state , item : item . name == ' Small Key (Thieves Town) ' and state . has ( ' Hammer ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Thieves \' Town - Attic ' ) , lambda state : state . has_key ( ' Small Key (Thieves Town) ' ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Thieves \' Town - Attic ' , ' Thieves \' Town - Big Chest ' , ' Thieves \' Town - Blind \' s Cell ' , ' Thieves \' Town - Boss ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Thieves Town) ' )
2018-09-26 21:34:15 +00:00
for location in [ ' Thieves \' Town - Attic ' , ' Thieves \' Town - Boss ' ] :
2017-10-14 18:45:59 +00:00
forbid_item ( world . get_location ( location ) , ' Small Key (Thieves Town) ' )
2017-05-15 18:28:04 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Skull Woods First Section South Door ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' ) )
set_rule ( world . get_entrance ( ' Skull Woods First Section (Right) North Door ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' ) )
set_rule ( world . get_entrance ( ' Skull Woods First Section West Door ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' , 2 ) ) # ideally would only be one key, but we may have spent thst key already on escaping the right section
set_rule ( world . get_entrance ( ' Skull Woods First Section (Left) Door to Exit ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' , 2 ) )
2018-01-06 03:46:00 +00:00
set_rule ( world . get_location ( ' Skull Woods - Big Chest ' ) , lambda state : state . has ( ' Big Key (Skull Woods) ' ) or item_name ( state , ' Skull Woods - Big Chest ' ) == ' Big Key (Skull Woods) ' )
2018-01-03 02:17:07 +00:00
set_always_allow ( world . get_location ( ' Skull Woods - Big Chest ' ) , lambda state , item : item . name == ' Big Key (Skull Woods) ' )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Skull Woods Torch Room ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' , 3 ) and state . has ( ' Fire Rod ' ) and state . has_sword ( ) ) # sword required for curtain
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Skull Woods - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Skull Woods - Prize ' ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Skull Woods - Boss ' ] :
2017-10-14 18:45:59 +00:00
forbid_item ( world . get_location ( location ) , ' Small Key (Skull Woods) ' )
2017-05-15 18:28:04 +00:00
2017-05-25 10:09:50 +00:00
set_rule ( world . get_entrance ( ' Ice Palace Entrance Room ' ) , lambda state : state . has ( ' Fire Rod ' ) or ( state . has ( ' Bombos ' ) and state . has_sword ( ) ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Ice Palace - Big Chest ' ) , lambda state : state . has ( ' Big Key (Ice Palace) ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ice Palace (Kholdstare) ' ) , lambda state : state . can_lift_rocks ( ) and state . has ( ' Hammer ' ) and state . has ( ' Big Key (Ice Palace) ' ) and ( state . has_key ( ' Small Key (Ice Palace) ' , 2 ) or ( state . has ( ' Cane of Somaria ' ) and state . has_key ( ' Small Key (Ice Palace) ' , 1 ) ) ) )
2018-09-23 02:51:54 +00:00
# TODO: investigate change from VT. Changed to hookshot or 2 keys (no checking for big key in specific chests)
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ice Palace (East) ' ) , lambda state : ( state . has ( ' Hookshot ' ) or ( item_in_locations ( state , ' Big Key (Ice Palace) ' , [ ' Ice Palace - Spike Room ' , ' Ice Palace - Big Key Chest ' , ' Ice Palace - Map Chest ' ] ) and state . has_key ( ' Small Key (Ice Palace) ' ) ) ) and ( state . world . can_take_damage or state . has ( ' Hookshot ' ) or state . has ( ' Cape ' ) or state . has ( ' Cane of Byrna ' ) ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Ice Palace (East Top) ' ) , lambda state : state . can_lift_rocks ( ) and state . has ( ' Hammer ' ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Ice Palace - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Ice Palace - Prize ' ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Ice Palace - Big Chest ' , ' Ice Palace - Boss ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Ice Palace) ' )
2018-02-17 23:38:54 +00:00
set_rule ( world . get_entrance ( ' Misery Mire Entrance Gap ' ) , lambda state : ( state . has_Boots ( ) or state . has ( ' Hookshot ' ) ) and ( state . has_sword ( ) or state . has ( ' Fire Rod ' ) or state . has ( ' Ice Rod ' ) or state . has ( ' Hammer ' ) or state . has ( ' Cane of Somaria ' ) or state . can_shoot_arrows ( ) ) ) # need to defeat wizzrobes, bombs don't work ...
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Misery Mire - Big Chest ' ) , lambda state : state . has ( ' Big Key (Misery Mire) ' ) )
2018-01-06 18:39:22 +00:00
set_rule ( world . get_location ( ' Misery Mire - Spike Chest ' ) , lambda state : ( state . world . can_take_damage and state . has_hearts ( 4 ) ) or state . has ( ' Cane of Byrna ' ) or state . has ( ' Cape ' ) )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Misery Mire Big Key Door ' ) , lambda state : state . has ( ' Big Key (Misery Mire) ' ) )
2017-06-17 11:15:37 +00:00
# you can squander the free small key from the pot by opening the south door to the north west switch room, locking you out of accessing a color switch ...
2017-06-24 16:49:50 +00:00
# big key gives backdoor access to that from the teleporter in the north west
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Misery Mire - Map Chest ' ) , lambda state : state . has_key ( ' Small Key (Misery Mire) ' , 1 ) or state . has ( ' Big Key (Misery Mire) ' ) )
2017-06-24 16:49:50 +00:00
# in addition, you can open the door to the map room before getting access to a color switch, so this is locked behing 2 small keys or the big key...
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Misery Mire - Main Lobby ' ) , lambda state : state . has_key ( ' Small Key (Misery Mire) ' , 2 ) or state . has_key ( ' Big Key (Misery Mire) ' ) )
2017-05-15 18:28:04 +00:00
# we can place a small key in the West wing iff it also contains/blocks the Big Key, as we cannot reach and softlock with the basement key door yet
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Misery Mire (West) ' ) , lambda state : state . has_key ( ' Small Key (Misery Mire) ' , 2 ) if ( ( item_name ( state , ' Misery Mire - Compass Chest ' ) in [ ' Big Key (Misery Mire) ' ] ) or
( item_name ( state , ' Misery Mire - Big Key Chest ' ) in [ ' Big Key (Misery Mire) ' ] ) ) else state . has_key ( ' Small Key (Misery Mire) ' , 3 ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Misery Mire - Compass Chest ' ) , lambda state : state . has_fire_source ( ) )
set_rule ( world . get_location ( ' Misery Mire - Big Key Chest ' ) , lambda state : state . has_fire_source ( ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Misery Mire (Vitreous) ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Misery Mire - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Misery Mire - Prize ' ) )
2018-09-26 21:34:15 +00:00
for location in [ ' Misery Mire - Big Chest ' , ' Misery Mire - Boss ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Misery Mire) ' )
set_rule ( world . get_entrance ( ' Turtle Rock Entrance Gap ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
2017-05-20 12:04:02 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock Entrance Gap Reverse ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Turtle Rock - Compass Chest ' ) , lambda state : state . has ( ' Cane of Somaria ' ) ) # We could get here from the middle section without Cane as we don't cross the entrance gap!
set_rule ( world . get_location ( ' Turtle Rock - Roller Room - Left ' ) , lambda state : state . has ( ' Cane of Somaria ' ) and state . has ( ' Fire Rod ' ) )
set_rule ( world . get_location ( ' Turtle Rock - Roller Room - Right ' ) , lambda state : state . has ( ' Cane of Somaria ' ) and state . has ( ' Fire Rod ' ) )
set_rule ( world . get_location ( ' Turtle Rock - Big Chest ' ) , lambda state : state . has ( ' Big Key (Turtle Rock) ' ) and ( state . has ( ' Cane of Somaria ' ) or state . has ( ' Hookshot ' ) ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock (Big Chest) (North) ' ) , lambda state : state . has ( ' Cane of Somaria ' ) or state . has ( ' Hookshot ' ) )
2017-06-17 12:40:37 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock Big Key Door ' ) , lambda state : state . has ( ' Big Key (Turtle Rock) ' ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock (Dark Room) (North) ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
set_rule ( world . get_entrance ( ' Turtle Rock (Dark Room) (South) ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Turtle Rock - Eye Bridge - Bottom Left ' ) , lambda state : state . has ( ' Cane of Byrna ' ) or state . has ( ' Cape ' ) or state . has ( ' Mirror Shield ' ) )
set_rule ( world . get_location ( ' Turtle Rock - Eye Bridge - Bottom Right ' ) , lambda state : state . has ( ' Cane of Byrna ' ) or state . has ( ' Cape ' ) or state . has ( ' Mirror Shield ' ) )
set_rule ( world . get_location ( ' Turtle Rock - Eye Bridge - Top Left ' ) , lambda state : state . has ( ' Cane of Byrna ' ) or state . has ( ' Cape ' ) or state . has ( ' Mirror Shield ' ) )
set_rule ( world . get_location ( ' Turtle Rock - Eye Bridge - Top Right ' ) , lambda state : state . has ( ' Cane of Byrna ' ) or state . has ( ' Cape ' ) or state . has ( ' Mirror Shield ' ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock (Trinexx) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) and state . has ( ' Big Key (Turtle Rock) ' ) and state . has ( ' Cane of Somaria ' ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Turtle Rock - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Turtle Rock - Prize ' ) )
2018-01-25 01:03:34 +00:00
2018-02-17 23:38:54 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Bonk Wall ' ) , lambda state : state . can_shoot_arrows ( ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Hammer Peg Drop ' ) , lambda state : state . has ( ' Hammer ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Bridge Room ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 1 ) ) # If we can reach any other small key door, we already have back door access to this area
2018-02-17 23:38:54 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Big Key Door ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 6 ) and state . has ( ' Big Key (Palace of Darkness) ' ) and state . can_shoot_arrows ( ) and state . has ( ' Hammer ' ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness (North) ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 4 ) )
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Palace of Darkness - Big Chest ' ) , lambda state : state . has ( ' Big Key (Palace of Darkness) ' ) )
2017-11-19 01:43:37 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Big Key Chest Staircase ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 6 ) or ( item_name ( state , ' Palace of Darkness - Big Key Chest ' ) in [ ' Small Key (Palace of Darkness) ' ] and state . has_key ( ' Small Key (Palace of Darkness) ' , 3 ) ) )
set_always_allow ( world . get_location ( ' Palace of Darkness - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Palace of Darkness) ' and state . has_key ( ' Small Key (Palace of Darkness) ' , 5 ) )
2017-11-04 18:23:57 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Palace of Darkness Spike Statue Room Door ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 6 ) or ( item_name ( state , ' Palace of Darkness - Harmless Hellway ' ) in [ ' Small Key (Palace of Darkness) ' ] and state . has_key ( ' Small Key (Palace of Darkness) ' , 4 ) ) )
set_always_allow ( world . get_location ( ' Palace of Darkness - Harmless Hellway ' ) , lambda state , item : item . name == ' Small Key (Palace of Darkness) ' and state . has_key ( ' Small Key (Palace of Darkness) ' , 5 ) )
set_rule ( world . get_entrance ( ' Palace of Darkness Maze Door ' ) , lambda state : state . has_key ( ' Small Key (Palace of Darkness) ' , 6 ) )
2018-09-26 21:34:15 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Palace of Darkness - Boss ' ) )
2018-09-26 17:12:20 +00:00
set_defeat_dungeon_boss_rule ( world . get_location ( ' Palace of Darkness - Prize ' ) )
2017-05-15 18:28:04 +00:00
# these key rules are conservative, you might be able to get away with more lenient rules
2017-11-09 03:13:36 +00:00
randomizer_room_chests = [ ' Ganons Tower - Randomizer Room - Top Left ' , ' Ganons Tower - Randomizer Room - Top Right ' , ' Ganons Tower - Randomizer Room - Bottom Left ' , ' Ganons Tower - Randomizer Room - Bottom Right ' ]
compass_room_chests = [ ' Ganons Tower - Compass Room - Top Left ' , ' Ganons Tower - Compass Room - Top Right ' , ' Ganons Tower - Compass Room - Bottom Left ' , ' Ganons Tower - Compass Room - Bottom Right ' ]
2017-11-19 01:43:37 +00:00
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Ganons Tower - Bob \' s Torch ' ) , lambda state : state . has_Boots ( ) )
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower (Tile Room) ' ) , lambda state : state . has ( ' Cane of Somaria ' ) )
set_rule ( world . get_entrance ( ' Ganons Tower (Hookshot Room) ' ) , lambda state : state . has ( ' Hammer ' ) )
2017-11-19 01:43:37 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower (Map Room) ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 4 ) or ( item_name ( state , ' Ganons Tower - Map Chest ' ) in [ ' Big Key (Ganons Tower) ' , ' Small Key (Ganons Tower) ' ] and state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) ) )
set_always_allow ( world . get_location ( ' Ganons Tower - Map Chest ' ) , lambda state , item : item . name == ' Small Key (Ganons Tower) ' and state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) )
2018-01-02 05:39:53 +00:00
# It is possible to need more than 2 keys to get through this entance if you spend keys elsewhere. We reflect this in the chest requirements.
# However we need to leave these at the lower values to derive that with 3 keys it is always possible to reach Bob and Ice Armos.
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower (Double Switch Room) ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 2 ) )
2017-11-09 03:13:36 +00:00
# It is possible to need more than 3 keys ....
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower (Firesnake Room) ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) )
2017-11-19 01:43:37 +00:00
2017-11-09 03:13:36 +00:00
#The actual requirements for these rooms to avoid key-lock
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Ganons Tower - Firesnake Room ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) or ( item_in_locations ( state , ' Big Key (Ganons Tower) ' , randomizer_room_chests ) and state . has_key ( ' Small Key (Ganons Tower) ' , 2 ) ) )
2017-11-09 03:13:36 +00:00
for location in randomizer_room_chests :
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( location ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 4 ) or ( item_in_locations ( state , ' Big Key (Ganons Tower) ' , randomizer_room_chests ) and state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) ) )
2017-11-19 01:43:37 +00:00
2017-11-09 03:13:36 +00:00
# Once again it is possible to need more than 3 keys...
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower (Tile Room) Key Door ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) and state . has ( ' Fire Rod ' ) )
2017-11-09 03:13:36 +00:00
# Actual requirements
for location in compass_room_chests :
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( location ) , lambda state : state . has ( ' Fire Rod ' ) and ( state . has_key ( ' Small Key (Ganons Tower) ' , 4 ) or ( item_in_locations ( state , ' Big Key (Ganons Tower) ' , compass_room_chests ) and state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) ) ) )
2017-11-19 01:43:37 +00:00
2017-10-29 03:42:35 +00:00
set_rule ( world . get_location ( ' Ganons Tower - Big Chest ' ) , lambda state : state . has ( ' Big Key (Ganons Tower) ' ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_location ( ' Ganons Tower - Big Key Room - Left ' ) , lambda state : world . get_location ( ' Ganons Tower - Big Key Room - Left ' ) . parent_region . dungeon . bosses [ ' bottom ' ] . can_defeat ( state ) )
set_rule ( world . get_location ( ' Ganons Tower - Big Key Chest ' ) , lambda state : world . get_location ( ' Ganons Tower - Big Key Chest ' ) . parent_region . dungeon . bosses [ ' bottom ' ] . can_defeat ( state ) )
set_rule ( world . get_location ( ' Ganons Tower - Big Key Room - Right ' ) , lambda state : world . get_location ( ' Ganons Tower - Big Key Room - Right ' ) . parent_region . dungeon . bosses [ ' bottom ' ] . can_defeat ( state ) )
2018-02-17 23:38:54 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower Big Key Door ' ) , lambda state : state . has ( ' Big Key (Ganons Tower) ' ) and state . can_shoot_arrows ( ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower Torch Rooms ' ) , lambda state : state . has_fire_source ( ) and world . get_entrance ( ' Ganons Tower Torch Rooms ' ) . parent_region . dungeon . bosses [ ' middle ' ] . can_defeat ( state ) )
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Ganons Tower - Pre-Moldorm Chest ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 3 ) )
set_rule ( world . get_entrance ( ' Ganons Tower Moldorm Door ' ) , lambda state : state . has_key ( ' Small Key (Ganons Tower) ' , 4 ) )
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower Moldorm Gap ' ) , lambda state : state . has ( ' Hookshot ' ) and world . get_entrance ( ' Ganons Tower Moldorm Gap ' ) . parent_region . dungeon . bosses [ ' top ' ] . can_defeat ( state ) )
set_defeat_dungeon_boss_rule ( world . get_location ( ' Agahnim 2 ' ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Pyramid Hole ' ) , lambda state : state . has ( ' Beat Agahnim 2 ' ) )
2017-10-29 03:42:35 +00:00
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 ' ] :
2017-05-15 18:28:04 +00:00
forbid_item ( world . get_location ( location ) , ' Big Key (Ganons Tower) ' )
2017-08-01 17:07:44 +00:00
set_rule ( world . get_location ( ' Ganon ' ) , lambda state : state . has_beam_sword ( ) and state . has_fire_source ( ) and state . has ( ' Crystal 1 ' ) and state . has ( ' Crystal 2 ' )
2017-07-17 22:10:00 +00:00
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 ' )
2018-02-17 23:38:54 +00:00
and ( state . has ( ' Tempered Sword ' ) or state . has ( ' Golden Sword ' ) or ( state . has ( ' Silver Arrows ' ) and state . can_shoot_arrows ( ) ) or state . has ( ' Lamp ' ) or state . can_extend_magic ( 12 ) ) ) # need to light torch a sufficient amount of times
2017-07-17 20:20:03 +00:00
set_rule ( world . get_entrance ( ' Ganon Drop ' ) , lambda state : state . has_beam_sword ( ) ) # need to damage ganon to get tiles to drop
2017-05-15 18:28:04 +00:00
2019-04-16 00:17:44 +00:00
set_rule ( world . get_entrance ( ' Ganons Tower ' ) , lambda state : False ) # This is a safety for the TR function below to not require GT entrance in its key logic.
set_trock_key_rules ( world )
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 ' ) )
2017-05-15 18:28:04 +00:00
2017-05-16 19:23:47 +00:00
def no_glitches_rules ( world ) :
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Zoras River ' ) , lambda state : state . has ( ' Flippers ' ) or state . can_lift_rocks ( ) )
2017-05-27 08:02:54 +00:00
set_rule ( world . get_entrance ( ' Lake Hylia Central Island Pier ' ) , lambda state : state . has ( ' Flippers ' ) ) # can be fake flippered to
2017-05-15 18:28:04 +00:00
set_rule ( world . get_entrance ( ' Hobo Bridge ' ) , lambda state : state . has ( ' Flippers ' ) )
set_rule ( world . get_entrance ( ' Dark Lake Hylia Drop (East) ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Flippers ' ) )
2017-05-20 12:04:02 +00:00
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 ( ) ) )
2017-12-13 14:51:53 +00:00
set_rule ( world . get_entrance ( ' Dark Lake Hylia Ledge Drop ' ) , lambda state : state . has_Pearl ( ) and state . has ( ' Flippers ' ) )
2017-05-15 18:28:04 +00:00
add_rule ( world . get_entrance ( ' Ganons Tower (Hookshot Room) ' ) , lambda state : state . has ( ' Hookshot ' ) )
2017-10-29 03:42:35 +00:00
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 )
2017-11-04 18:23:57 +00:00
set_rule ( world . get_entrance ( ' Skull Woods First Section Bomb Jump ' ) , lambda state : False )
2017-07-17 20:20:03 +00:00
2017-05-20 13:47:28 +00:00
# Light cones in standard depend on which world we actually are in, not which one the location would normally be
# We add Lamp requirements only to those locations which lie in the dark world (or everything if open
2017-11-12 00:03:42 +00:00
DW_Entrances = [ ' Bumper Cave (Bottom) ' , ' Superbunny Cave (Top) ' , ' Superbunny Cave (Bottom) ' , ' Hookshot Cave ' , ' Bumper Cave (Top) ' , ' Hookshot Cave Back Entrance ' , ' Dark Death Mountain Ledge (East) ' ,
2017-05-20 18:03:13 +00:00
' Turtle Rock Isolated Ledge Entrance ' , ' Thieves Town ' , ' Skull Woods Final Section ' , ' Ice Palace ' , ' Misery Mire ' , ' Palace of Darkness ' , ' Swamp Palace ' , ' Turtle Rock ' , ' Dark Death Mountain Ledge (West) ' ]
2017-05-20 13:47:28 +00:00
def check_is_dark_world ( region ) :
for entrance in region . entrances :
if entrance . name in DW_Entrances :
return True
return False
def add_conditional_lamp ( spot , region , spottype = ' Location ' ) :
if spottype == ' Location ' :
spot = world . get_location ( spot )
else :
spot = world . get_entrance ( spot )
2017-06-03 13:46:05 +00:00
if ( not world . dark_world_light_cone and check_is_dark_world ( world . get_region ( region ) ) ) or ( not world . light_world_light_cone and not check_is_dark_world ( world . get_region ( region ) ) ) :
2017-05-20 13:47:28 +00:00
add_lamp_requirement ( spot )
add_conditional_lamp ( ' Misery Mire (Vitreous) ' , ' Misery Mire (Entrance) ' , ' Entrance ' )
add_conditional_lamp ( ' Turtle Rock (Dark Room) (North) ' , ' Turtle Rock (Entrance) ' , ' Entrance ' )
add_conditional_lamp ( ' Turtle Rock (Dark Room) (South) ' , ' Turtle Rock (Entrance) ' , ' Entrance ' )
2017-10-29 03:42:35 +00:00
add_conditional_lamp ( ' Palace of Darkness Big Key Door ' , ' Palace of Darkness (Entrance) ' , ' Entrance ' )
add_conditional_lamp ( ' Palace of Darkness Maze Door ' , ' Palace of Darkness (Entrance) ' , ' Entrance ' )
add_conditional_lamp ( ' Palace of Darkness - Dark Basement - Left ' , ' Palace of Darkness (Entrance) ' , ' Location ' )
add_conditional_lamp ( ' Palace of Darkness - Dark Basement - Right ' , ' Palace of Darkness (Entrance) ' , ' Location ' )
2017-05-21 14:32:34 +00:00
add_conditional_lamp ( ' Agahnim 1 ' , ' Agahnims Tower ' , ' Entrance ' )
2017-10-29 03:42:35 +00:00
add_conditional_lamp ( ' Castle Tower - Dark Maze ' , ' Agahnims Tower ' , ' Location ' )
add_conditional_lamp ( ' Old Man ' , ' Old Man Cave ' , ' Location ' )
2017-05-20 13:47:28 +00:00
add_conditional_lamp ( ' Old Man Cave Exit (East) ' , ' Old Man Cave ' , ' Entrance ' )
add_conditional_lamp ( ' Death Mountain Return Cave Exit (East) ' , ' Death Mountain Return Cave ' , ' Entrance ' )
add_conditional_lamp ( ' Death Mountain Return Cave Exit (West) ' , ' Death Mountain Return Cave ' , ' Entrance ' )
add_conditional_lamp ( ' Old Man House Front to Back ' , ' Old Man House ' , ' Entrance ' )
add_conditional_lamp ( ' Old Man House Back to Front ' , ' Old Man House ' , ' Entrance ' )
2017-10-29 03:42:35 +00:00
add_conditional_lamp ( ' Eastern Palace - Big Key Chest ' , ' Eastern Palace ' , ' Location ' )
2018-09-26 21:34:15 +00:00
add_conditional_lamp ( ' Eastern Palace - Boss ' , ' Eastern Palace ' , ' Location ' )
2017-10-29 03:42:35 +00:00
add_conditional_lamp ( ' Eastern Palace - Prize ' , ' Eastern Palace ' , ' Location ' )
2017-05-20 13:47:28 +00:00
2017-06-03 13:46:05 +00:00
if not world . sewer_light_cone :
2018-02-24 21:16:50 +00:00
add_lamp_requirement ( world . get_location ( ' Sewers - Dark Cross ' ) )
add_lamp_requirement ( world . get_entrance ( ' Sewers Back Door ' ) )
add_lamp_requirement ( world . get_entrance ( ' Throne Room ' ) )
2017-05-16 19:23:47 +00:00
def open_rules ( world ) :
2017-08-05 15:50:47 +00:00
# softlock protection as you can reach the sewers small key door with a guard drop key
2017-10-29 03:42:35 +00:00
forbid_item ( world . get_location ( ' Hyrule Castle - Boomerang Chest ' ) , ' Small Key (Escape) ' )
forbid_item ( world . get_location ( ' Hyrule Castle - Zelda \' s Chest ' ) , ' Small Key (Escape) ' )
2017-11-19 01:43:37 +00:00
2018-03-15 21:23:02 +00:00
set_rule ( world . get_location ( ' Hyrule Castle - Boomerang Chest ' ) , lambda state : state . has_key ( ' Small Key (Escape) ' ) )
set_rule ( world . get_location ( ' Hyrule Castle - Zelda \' s Chest ' ) , lambda state : state . has_key ( ' Small Key (Escape) ' ) )
2017-05-16 19:23:47 +00:00
2017-06-24 16:48:03 +00:00
def swordless_rules ( world ) :
2017-12-17 05:25:46 +00:00
2018-02-08 10:40:16 +00:00
# for the time being swordless mode just inherits all fixes from open mode.
2017-12-17 05:25:46 +00:00
# should there ever be fixes that apply to open mode but not swordless, this
# can be revisited.
open_rules ( world )
2017-11-19 01:43:37 +00:00
2017-06-24 16:48:03 +00:00
set_rule ( world . get_entrance ( ' Agahnims Tower ' ) , lambda state : state . has ( ' Cape ' ) or state . has ( ' Hammer ' ) or state . has ( ' Beat Agahnim 1 ' ) ) # barrier gets removed after killing agahnim, relevant for entrance shuffle
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Agahnim 1 ' ) , lambda state : ( state . has ( ' Hammer ' ) or state . has ( ' Fire Rod ' ) or state . can_shoot_arrows ( ) or state . has ( ' Cane of Somaria ' ) ) and state . has_key ( ' Small Key (Agahnims Tower) ' , 2 ) )
2017-10-14 18:45:59 +00:00
set_rule ( world . get_location ( ' Ether Tablet ' ) , lambda state : state . has ( ' Book of Mudora ' ) and state . has ( ' Hammer ' ) )
set_rule ( world . get_location ( ' Bombos Tablet ' ) , lambda state : state . has ( ' Book of Mudora ' ) and state . has ( ' Hammer ' ) and state . has_Mirror ( ) )
2017-06-24 16:48:03 +00:00
set_rule ( world . get_entrance ( ' Misery Mire ' ) , lambda state : state . has_Pearl ( ) and state . has_misery_mire_medallion ( ) ) # sword not required to use medallion for opening in swordless (!)
set_rule ( world . get_entrance ( ' Turtle Rock ' ) , lambda state : state . has_Pearl ( ) and state . has_turtle_rock_medallion ( ) and state . can_reach ( ' Turtle Rock (Top) ' , ' Region ' ) ) # sword not required to use medallion for opening in swordless (!)
2018-09-26 17:12:20 +00:00
set_rule ( world . get_entrance ( ' Skull Woods Torch Room ' ) , lambda state : state . has_key ( ' Small Key (Skull Woods) ' , 3 ) and state . has ( ' Fire Rod ' ) ) # no curtain
2018-01-07 03:20:08 +00:00
set_rule ( world . get_entrance ( ' Ice Palace Entrance Room ' ) , lambda state : state . has ( ' Fire Rod ' ) or state . has ( ' Bombos ' ) ) #in swordless mode bombos pads are present in the relevant parts of ice palace
2018-02-17 23:38:54 +00:00
set_rule ( world . get_location ( ' Ganon ' ) , lambda state : state . has ( ' Hammer ' ) and state . has_fire_source ( ) and state . has ( ' Silver Arrows ' ) and state . can_shoot_arrows ( ) and state . has ( ' Crystal 1 ' ) and state . has ( ' Crystal 2 ' )
2017-07-17 22:10:00 +00:00
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 ' ) )
2017-06-24 16:48:03 +00:00
set_rule ( world . get_entrance ( ' Ganon Drop ' ) , lambda state : state . has ( ' Hammer ' ) ) # need to damage ganon to get tiles to drop
2017-05-16 19:23:47 +00:00
def standard_rules ( world ) :
2018-02-18 17:22:50 +00:00
for loc in [ ' Sanctuary ' , ' Sewers - Secret Room - Left ' , ' Sewers - Secret Room - Middle ' ,
' Sewers - Secret Room - Right ' ] :
2018-03-15 21:23:02 +00:00
add_rule ( world . get_location ( loc ) , lambda state : state . can_kill_most_things ( ) and state . has_key ( ' Small Key (Escape) ' ) )
2018-02-18 17:22:50 +00:00
2017-05-16 19:23:47 +00:00
# easiest way to enforce key placement not relevant for open
2018-01-02 05:39:53 +00:00
set_rule ( world . get_location ( ' Sewers - Dark Cross ' ) , lambda state : state . can_kill_most_things ( ) )
set_rule ( world . get_location ( ' Hyrule Castle - Boomerang Chest ' ) , lambda state : state . can_kill_most_things ( ) )
set_rule ( world . get_location ( ' Hyrule Castle - Zelda \' s Chest ' ) , lambda state : state . can_kill_most_things ( ) )
2017-06-03 15:09:26 +00:00
2017-05-16 19:23:47 +00:00
2017-06-23 19:32:31 +00:00
def set_trock_key_rules ( world ) :
2017-08-05 15:50:47 +00:00
2019-04-16 00:17:44 +00:00
all_state = world . get_all_state ( True )
2017-06-23 19:32:31 +00:00
2019-04-16 00:17:44 +00:00
# First set all relevant locked doors to impassible.
for entrance in [ ' Turtle Rock Dark Room Staircase ' , ' Turtle Rock (Chain Chomp Room) (North) ' , ' Turtle Rock (Chain Chomp Room) (South) ' , ' Turtle Rock Pokey Room ' ] :
set_rule ( world . get_entrance ( entrance ) , lambda state : False )
2017-06-23 19:32:31 +00:00
2019-04-16 00:17:44 +00:00
# Check if each of the four main regions of the dungoen can be reached. The previous code section prevents key-costing moves within the dungeon.
2017-07-17 21:13:39 +00:00
can_reach_back = all_state . can_reach ( world . get_region ( ' Turtle Rock (Eye Bridge) ' ) ) if world . can_access_trock_eyebridge is None else world . can_access_trock_eyebridge
world . can_access_trock_eyebridge = can_reach_back
2019-04-16 00:17:44 +00:00
can_reach_front = all_state . can_reach ( world . get_region ( ' Turtle Rock (Entrance) ' ) ) if world . can_access_trock_front is None else world . can_access_trock_front
world . can_access_trock_front = can_reach_front
can_reach_big_chest = all_state . can_reach ( world . get_region ( ' Turtle Rock (Big Chest) ' ) ) if world . can_access_trock_big_chest is None else world . can_access_trock_big_chest
world . can_access_trock_big_chest = can_reach_big_chest
can_reach_middle = all_state . can_reach ( world . get_region ( ' Turtle Rock (Second Section) ' ) ) if world . can_access_trock_middle is None else world . can_access_trock_middle
world . can_access_trock_middle = can_reach_middle
# No matter what, the key requirement for going from the middle to the bottom should be three keys.
set_rule ( world . get_entrance ( ' Turtle Rock Dark Room Staircase ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 3 ) )
2017-06-23 19:32:31 +00:00
2019-04-16 00:17:44 +00:00
# The following represent the most common and most restrictive key rules. These are overwritten later as needed.
2018-03-15 21:23:02 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock (Chain Chomp Room) (South) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) )
2019-04-16 00:17:44 +00:00
set_rule ( world . get_entrance ( ' Turtle Rock (Chain Chomp Room) (North) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) )
set_rule ( world . get_entrance ( ' Turtle Rock Pokey Room ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) )
2017-06-23 19:32:31 +00:00
2019-04-16 00:17:44 +00:00
# No matter what, the Big Key cannot be in the Big Chest or held by Trinexx.
non_big_key_locations = [ ' Turtle Rock - Big Chest ' , ' Turtle Rock - Boss ' ]
2017-06-23 19:32:31 +00:00
2018-01-05 07:02:58 +00:00
def tr_big_key_chest_keys_needed ( state ) :
2019-04-16 00:17:44 +00:00
# This function handles the key requirements for the TR Big Chest in the situations it having the Big Key should logically require 2 keys, small key
# should logically require no keys, and anything else should logically require 4 keys.
2018-01-06 03:46:00 +00:00
item = item_name ( state , ' Turtle Rock - Big Key Chest ' )
2018-01-05 07:02:58 +00:00
if item in [ ' Small Key (Turtle Rock) ' ] :
2019-04-16 00:17:44 +00:00
return 0
if item in [ ' Big Key (Turtle Rock) ' ] :
2018-01-05 07:02:58 +00:00
return 2
return 4
2019-04-16 00:17:44 +00:00
# Now we need to set rules based on which entrances we have access to. The most important point is whether we have back access. If we have back access, we
# might open all the locked doors in any order so we need maximally restrictive rules.
if can_reach_back :
set_rule ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state : ( state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) or item_name ( state , ' Turtle Rock - Big Key Chest ' ) == ' Small Key (Turtle Rock) ' ) )
set_always_allow ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Turtle Rock) ' )
elif can_reach_front and can_reach_middle :
set_rule ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , tr_big_key_chest_keys_needed ( state ) ) )
set_always_allow ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Turtle Rock) ' )
non_big_key_locations + = [ ' Turtle Rock - Crystaroller Room ' , ' Turtle Rock - Eye Bridge - Bottom Left ' ,
' Turtle Rock - Eye Bridge - Bottom Right ' , ' Turtle Rock - Eye Bridge - Top Left ' ,
' Turtle Rock - Eye Bridge - Top Right ' ]
elif can_reach_front :
set_rule ( world . get_entrance ( ' Turtle Rock (Chain Chomp Room) (North) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 2 ) )
set_rule ( world . get_entrance ( ' Turtle Rock Pokey Room ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 1 ) )
set_rule ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , tr_big_key_chest_keys_needed ( state ) ) )
2019-04-18 21:11:11 +00:00
set_always_allow ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Turtle Rock) ' and state . has_key ( ' Small Key (Turtle Rock) ' , 2 ) )
2019-04-16 00:17:44 +00:00
non_big_key_locations + = [ ' Turtle Rock - Crystaroller Room ' , ' Turtle Rock - Eye Bridge - Bottom Left ' ,
' Turtle Rock - Eye Bridge - Bottom Right ' , ' Turtle Rock - Eye Bridge - Top Left ' ,
' Turtle Rock - Eye Bridge - Top Right ' ]
elif can_reach_big_chest :
set_rule ( world . get_entrance ( ' Turtle Rock (Chain Chomp Room) (South) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 2 ) if item_in_locations ( state , ' Big Key (Turtle Rock) ' , [ ' Turtle Rock - Compass Chest ' , ' Turtle Rock - Roller Room - Left ' , ' Turtle Rock - Roller Room - Right ' ] ) else state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) )
set_rule ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state : ( state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) or item_name ( state , ' Turtle Rock - Big Key Chest ' ) == ' Small Key (Turtle Rock) ' ) )
set_always_allow ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Turtle Rock) ' )
non_big_key_locations + = [ ' Turtle Rock - Crystaroller Room ' , ' Turtle Rock - Eye Bridge - Bottom Left ' ,
' Turtle Rock - Eye Bridge - Bottom Right ' , ' Turtle Rock - Eye Bridge - Top Left ' ,
' Turtle Rock - Eye Bridge - Top Right ' ]
if not world . keysanity :
non_big_key_locations + = [ ' Turtle Rock - Big Key Chest ' ]
else :
set_rule ( world . get_entrance ( ' Turtle Rock (Chain Chomp Room) (South) ' ) , lambda state : state . has_key ( ' Small Key (Turtle Rock) ' , 2 ) if item_in_locations ( state , ' Big Key (Turtle Rock) ' , [ ' Turtle Rock - Compass Chest ' , ' Turtle Rock - Roller Room - Left ' , ' Turtle Rock - Roller Room - Right ' ] ) else state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) )
set_rule ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state : ( state . has_key ( ' Small Key (Turtle Rock) ' , 4 ) or item_name ( state , ' Turtle Rock - Big Key Chest ' ) == ' Small Key (Turtle Rock) ' ) )
set_always_allow ( world . get_location ( ' Turtle Rock - Big Key Chest ' ) , lambda state , item : item . name == ' Small Key (Turtle Rock) ' )
2017-11-12 00:03:42 +00:00
non_big_key_locations + = [ ' Turtle Rock - Crystaroller Room ' , ' Turtle Rock - Eye Bridge - Bottom Left ' ,
2017-10-29 03:42:35 +00:00
' Turtle Rock - Eye Bridge - Bottom Right ' , ' Turtle Rock - Eye Bridge - Top Left ' ,
' Turtle Rock - Eye Bridge - Top Right ' ]
2019-04-16 00:17:44 +00:00
if not world . keysanity :
non_big_key_locations + = [ ' Turtle Rock - Big Key Chest ' , ' Turtle Rock - Chain Chomps ' ]
2017-06-23 19:32:31 +00:00
2019-04-16 00:17:44 +00:00
# set big key restrictions
2017-06-23 19:32:31 +00:00
for location in non_big_key_locations :
forbid_item ( world . get_location ( location ) , ' Big Key (Turtle Rock) ' )
2017-11-04 18:23:57 +00:00
2017-10-14 18:45:59 +00:00
# small key restriction
2018-09-26 21:34:15 +00:00
for location in [ ' Turtle Rock - Boss ' ] :
2017-10-14 18:45:59 +00:00
forbid_item ( world . get_location ( location ) , ' Small Key (Turtle Rock) ' )
2017-06-23 19:32:31 +00:00
2017-05-20 12:04:02 +00:00
def set_big_bomb_rules ( world ) :
2017-06-02 19:56:39 +00:00
# this is a mess
bombshop_entrance = world . get_region ( ' Big Bomb Shop ' ) . entrances [ 0 ]
2017-10-29 03:42:35 +00:00
Normal_LW_entrances = [ ' Blinds Hideout ' ,
2017-06-02 19:56:39 +00:00
' Bonk Fairy (Light) ' ,
' Lake Hylia Fairy ' ,
2018-03-03 00:05:26 +00:00
' Light Hype Fairy ' ,
2017-06-02 19:56:39 +00:00
' Desert Fairy ' ,
' Chicken House ' ,
' Aginahs Cave ' ,
' Sahasrahlas Hut ' ,
' Cave Shop (Lake Hylia) ' ,
' Blacksmiths Hut ' ,
' Sick Kids House ' ,
' Lost Woods Gamble ' ,
' Fortune Teller (Light) ' ,
' Snitch Lady (East) ' ,
' Snitch Lady (West) ' ,
' Bush Covered House ' ,
' Tavern (Front) ' ,
' Light World Bomb Hut ' ,
' Kakariko Shop ' ,
2017-06-03 12:19:49 +00:00
' Mini Moldorm Cave ' ,
2017-06-02 19:56:39 +00:00
' Long Fairy Cave ' ,
' Good Bee Cave ' ,
' 20 Rupee Cave ' ,
' 50 Rupee Cave ' ,
2017-10-29 03:42:35 +00:00
' Ice Rod Cave ' ,
2017-06-02 19:56:39 +00:00
' Bonk Rock Cave ' ,
' Library ' ,
2017-10-29 03:42:35 +00:00
' Potion Shop ' ,
2017-06-02 19:56:39 +00:00
' Waterfall of Wishing ' ,
' Dam ' ,
' Lumberjack House ' ,
' Lake Hylia Fortune Teller ' ,
2018-02-18 19:53:39 +00:00
' Eastern Palace ' ,
2018-01-20 21:36:03 +00:00
' Kakariko Gamble Game ' ,
' Kakariko Well Cave ' ,
' Bat Cave Cave ' ,
' Elder House (East) ' ,
' Elder House (West) ' ,
' North Fairy Cave ' ,
' Lost Woods Hideout Stump ' ,
' Lumberjack Tree Cave ' ,
' Two Brothers House (East) ' ,
' Sanctuary ' ,
' Hyrule Castle Entrance (South) ' ,
' Hyrule Castle Secret Entrance Stairs ' ]
2017-06-02 19:56:39 +00:00
LW_walkable_entrances = [ ' Dark Lake Hylia Ledge Fairy ' ,
' Dark Lake Hylia Ledge Spike Cave ' ,
' Dark Lake Hylia Ledge Hint ' ,
2017-10-29 03:42:35 +00:00
' Mire Shed ' ,
2017-06-02 19:56:39 +00:00
' Dark Desert Hint ' ,
' Dark Desert Fairy ' ,
2018-01-20 21:36:03 +00:00
' Misery Mire ' ]
2017-10-29 03:42:35 +00:00
Northern_DW_entrances = [ ' Brewery ' ,
2017-06-02 19:56:39 +00:00
' C-Shaped House ' ,
' Chest Game ' ,
' Dark World Hammer Peg Cave ' ,
' Red Shield Shop ' ,
' Dark Sanctuary Hint ' ,
' Fortune Teller (Dark) ' ,
' Dark World Shop ' ,
' Dark World Lumberjack Shop ' ,
2018-01-20 21:36:03 +00:00
' Thieves Town ' ,
' Skull Woods First Section Door ' ,
2018-02-07 04:07:13 +00:00
' Skull Woods Second Section Door (East) ' ]
2017-11-12 00:03:42 +00:00
Southern_DW_entrances = [ ' Hype Cave ' ,
2017-06-02 19:56:39 +00:00
' Bonk Fairy (Dark) ' ,
' Archery Game ' ,
' Big Bomb Shop ' ,
' Dark Lake Hylia Shop ' ,
2018-01-20 21:36:03 +00:00
' Swamp Palace ' ]
2017-06-02 19:56:39 +00:00
Isolated_DW_entrances = [ ' Spike Cave ' ,
' Cave Shop (Dark Death Mountain) ' ,
' Dark Death Mountain Fairy ' ,
2018-01-20 21:36:03 +00:00
' Mimic Cave ' ,
2018-02-18 19:53:39 +00:00
' Skull Woods Second Section Door (West) ' ,
2018-01-20 21:36:03 +00:00
' Skull Woods Final Section ' ,
' Ice Palace ' ,
' Turtle Rock ' ,
' Dark Death Mountain Ledge (West) ' ,
' Dark Death Mountain Ledge (East) ' ,
' Bumper Cave (Top) ' ,
' Superbunny Cave (Top) ' ,
' Superbunny Cave (Bottom) ' ,
' Hookshot Cave ' ,
2018-02-08 10:40:16 +00:00
' Ganons Tower ' ,
' Turtle Rock Isolated Ledge Entrance ' ,
' Hookshot Cave Back Entrance ' ]
2017-11-04 18:23:57 +00:00
Isolated_LW_entrances = [ ' Capacity Upgrade ' ,
2018-01-20 21:36:03 +00:00
' Tower of Hera ' ,
' Death Mountain Return Cave (West) ' ,
' Paradox Cave (Top) ' ,
' Fairy Ascension Cave (Top) ' ,
' Spiral Cave ' ,
2018-02-08 10:40:16 +00:00
' Desert Palace Entrance (East) ' ]
West_LW_DM_entrances = [ ' Old Man Cave (East) ' ,
' Old Man House (Bottom) ' ,
' Old Man House (Top) ' ,
' Death Mountain Return Cave (East) ' ,
' Spectacle Rock Cave Peak ' ,
' Spectacle Rock Cave ' ,
' Spectacle Rock Cave (Bottom) ' ]
East_LW_DM_entrances = [ ' Paradox Cave (Bottom) ' ,
' Paradox Cave (Middle) ' ,
' Hookshot Fairy ' ,
' Spiral Cave (Bottom) ' ]
2018-01-20 21:36:03 +00:00
Mirror_from_SDW_entrances = [ ' Two Brothers House (West) ' ,
' Cave 45 ' ]
Castle_ledge_entrances = [ ' Hyrule Castle Entrance (West) ' ,
' Hyrule Castle Entrance (East) ' ,
' Agahnims Tower ' ]
Desert_mirrorable_ledge_entrances = [ ' Desert Palace Entrance (West) ' ,
' Desert Palace Entrance (North) ' ,
' Desert Palace Entrance (South) ' ,
' Checkerboard Cave ' , ]
2017-12-13 14:51:53 +00:00
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 ' ) )
2018-01-28 21:56:55 +00:00
#crossing peg bridge starting from the southern dark world
def cross_peg_bridge ( state ) :
return state . has ( ' Hammer ' ) and state . has_Pearl ( )
# returning via the eastern and southern teleporters needs the same items, so we use the southern teleporter for out routing.
# crossing preg bridge already requires hammer so we just add the gloves to the requirement
def southern_teleporter ( state ) :
return state . can_lift_rocks ( ) and cross_peg_bridge ( state )
# the basic routes assume you can reach eastern light world with the bomb.
# you can then use the southern teleporter, or (if you have beaten Aga1) the hyrule castle gate warp
def basic_routes ( state ) :
return southern_teleporter ( state ) or state . can_reach ( ' Top of Pyramid ' , ' Entrance ' )
2018-01-20 21:36:03 +00:00
# Key for below abbreviations:
# P = pearl
# A = Aga1
# H = hammer
# M = Mirror
# G = Glove
2017-06-02 19:56:39 +00:00
if bombshop_entrance . name in Normal_LW_entrances :
2018-01-28 21:56:55 +00:00
#1. basic routes
#2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
# -> M or BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : basic_routes ( state ) or state . has_Mirror ( ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name in LW_walkable_entrances :
2018-01-28 21:56:55 +00:00
#1. Mirror then basic routes
# -> M and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has_Mirror ( ) and basic_routes ( state ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name in Northern_DW_entrances :
2018-01-28 21:56:55 +00:00
#1. Mirror and basic routes
#2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
2018-02-07 04:07:13 +00:00
# -> (Mitts and CPB) or (M and BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . can_lift_heavy_rocks ( ) and cross_peg_bridge ( state ) ) or ( state . has_Mirror ( ) and basic_routes ( state ) ) )
elif bombshop_entrance . name == ' Bumper Cave (Bottom) ' :
#1. Mirror and Lift rock and basic_routes
#2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case)
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
# -> (Mitts and CPB) or (((G or Flute) and M) and BR))
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . can_lift_heavy_rocks ( ) and cross_peg_bridge ( state ) ) or ( ( ( state . can_lift_rocks ( ) or state . has ( ' Ocarina ' ) ) and state . has_Mirror ( ) ) and basic_routes ( state ) ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name in Southern_DW_entrances :
2017-12-13 14:51:53 +00:00
#1. Mirror and enter via gate: Need mirror and Aga1
#2. cross peg bridge: Need hammer and moon pearl
2018-01-28 21:56:55 +00:00
# -> CPB or (M and A)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : cross_peg_bridge ( state ) or ( state . has_Mirror ( ) and state . can_reach ( ' Top of Pyramid ' , ' Entrance ' ) ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name in Isolated_DW_entrances :
2018-01-28 21:56:55 +00:00
# 1. mirror then flute then basic routes
# -> M and Flute and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has_Mirror ( ) and state . has ( ' Ocarina ' ) and basic_routes ( state ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name in Isolated_LW_entrances :
2018-01-20 21:36:03 +00:00
# 1. flute then basic routes
2017-12-13 14:51:53 +00:00
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
2018-01-28 21:56:55 +00:00
# -> Flute and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has ( ' Ocarina ' ) and basic_routes ( state ) )
2018-02-08 10:40:16 +00:00
elif bombshop_entrance . name in West_LW_DM_entrances :
# 1. flute then basic routes or mirror
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
# -> Flute and (M or BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has ( ' Ocarina ' ) and ( state . has_Mirror ( ) or basic_routes ( state ) ) )
elif bombshop_entrance . name in East_LW_DM_entrances :
# 1. flute then basic routes or mirror and hookshot
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot
# -> Flute and ((M and Hookshot) or BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has ( ' Ocarina ' ) and ( ( state . has_Mirror ( ) and state . has ( ' Hookshot ' ) ) or basic_routes ( state ) ) )
elif bombshop_entrance . name == ' Fairy Ascension Cave (Bottom) ' :
# Same as East_LW_DM_entrances except navigation without BR requires Mitts
# -> Flute and ((M and Hookshot and Mitts) or BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has ( ' Ocarina ' ) and ( ( state . has_Mirror ( ) and state . has ( ' Hookshot ' ) and state . can_lift_heavy_rocks ( ) ) or basic_routes ( state ) ) )
2018-01-20 21:36:03 +00:00
elif bombshop_entrance . name in Castle_ledge_entrances :
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
# 2. flute then basic routes
# -> M or (Flute and BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : state . has_Mirror ( ) or ( state . has ( ' Ocarina ' ) and basic_routes ( state ) ) )
elif bombshop_entrance . name in Desert_mirrorable_ledge_entrances :
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
# 2. flute then basic routes
# -> (Mire access and M) or Flute) and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( ( state . can_reach ( ' Dark Desert ' , ' Region ' ) and state . has_Mirror ( ) ) or state . has ( ' Ocarina ' ) ) and basic_routes ( state ) )
elif bombshop_entrance . name == ' Old Man Cave (West) ' :
# 1. Lift rock then basic_routes
2018-02-07 04:07:13 +00:00
# 2. flute then basic_routes
# -> (Flute or G) and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . has ( ' Ocarina ' ) or state . can_lift_rocks ( ) ) and basic_routes ( state ) )
2018-01-20 21:36:03 +00:00
elif bombshop_entrance . name == ' Graveyard Cave ' :
# 1. flute then basic routes
2018-02-07 04:07:13 +00:00
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
# -> (Flute or (M and P and West Dark World access) and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . has ( ' Ocarina ' ) or ( state . can_reach ( ' West Dark World ' , ' Region ' ) and state . has_Pearl ( ) and state . has_Mirror ( ) ) ) and basic_routes ( state ) )
2018-01-20 21:36:03 +00:00
elif bombshop_entrance . name in Mirror_from_SDW_entrances :
# 1. flute then basic routes
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
# -> (Flute or (M and South Dark World access) and BR
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . has ( ' Ocarina ' ) or ( state . can_reach ( ' South Dark World ' , ' Region ' ) and state . has_Mirror ( ) ) ) and basic_routes ( state ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name == ' Dark World Potion Shop ' :
2017-12-13 14:51:53 +00:00
# 1. walk down by lifting rock: needs gloves and pearl`
# 2. walk down by hammering peg: needs hammer and pearl
2018-01-28 21:56:55 +00:00
# 3. mirror and basic routes
# -> (P and (H or Gloves)) or (M and BR)
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 basic_routes ( state ) ) )
2017-06-02 19:56:39 +00:00
elif bombshop_entrance . name == ' Kings Grave ' :
2017-12-13 14:51:53 +00:00
# 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)
2018-02-20 02:30:56 +00:00
# to account for insanity, must consider a way to escape without a cave for basic_routes
# -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR)
add_rule ( world . get_entrance ( ' Pyramid Fairy ' ) , lambda state : ( state . can_lift_heavy_rocks ( ) and state . has_Mirror ( ) ) or ( ( state . can_lift_heavy_rocks ( ) or state . has ( ' Ocarina ' ) or ( state . can_reach ( ' West Dark World ' , ' Region ' ) and state . has_Pearl ( ) and state . has_Mirror ( ) ) ) and basic_routes ( state ) ) )
2017-12-13 14:51:53 +00:00
def set_bunny_rules ( world ) :
2018-02-08 10:40:16 +00:00
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
2017-12-13 14:51:53 +00:00
# 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) ' ,
2018-02-08 10:40:16 +00:00
' Turtle Rock (Eye Bridge) ' , ' Sewers ' , ' Pyramid ' , ' Spiral Cave (Top) ' , ' Desert Palace Main (Inner) ' ]
2017-12-13 14:51:53 +00:00
2018-03-18 05:36:45 +00:00
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 ' ]
2017-12-13 14:51:53 +00:00
2018-01-25 01:03:34 +00:00
2018-01-27 22:17:03 +00:00
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 ) :
if not region . is_light_world :
return lambda state : state . has_Pearl ( )
# 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 ( ) ]
# We will search entrances recursively until we find
# one that leads to an exclusively light world region
2018-02-17 23:38:54 +00:00
# for each such entrance a new option is added that consist of:
2018-01-27 22:17:03 +00:00
# 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_light_world :
continue # we don't care about pure dark world entrances
if new_region . is_dark_world :
queue . append ( ( new_region , new_path ) )
else :
# we have reached pure light 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 dark world
2017-12-13 14:51:53 +00:00
for region in [ world . get_region ( name ) for name in bunny_impassable_caves ] :
2018-01-27 22:17:03 +00:00
if not region . is_dark_world :
2017-12-13 14:51:53 +00:00
continue
2018-01-27 22:17:03 +00:00
rule = get_rule_to_add ( region )
2017-12-13 14:51:53 +00:00
for exit in region . exits :
2018-01-27 22:17:03 +00:00
add_rule ( exit , rule )
2017-12-13 14:51:53 +00:00
2018-02-17 23:38:54 +00:00
paradox_shop = world . get_region ( ' Light World Death Mountain Shop ' )
if paradox_shop . is_dark_world :
add_rule ( paradox_shop . entrances [ 0 ] , get_rule_to_add ( paradox_shop ) )
2018-01-27 22:17:03 +00:00
# Add requirements for all locations that are actually in the dark world, except those available to the bunny
2017-12-13 14:51:53 +00:00
for location in world . get_locations ( ) :
2018-01-27 22:17:03 +00:00
if location . parent_region . is_dark_world :
2017-12-13 14:51:53 +00:00
if location . name in bunny_accessible_locations :
continue
2018-01-27 22:17:03 +00:00
add_rule ( location , get_rule_to_add ( location . parent_region ) )