Update inverted big bomb rules.

Add checks that will not allow unexpected entrances to get east dark world logic.
This commit is contained in:
compiling 2020-03-19 18:49:41 +11:00
parent e01983c494
commit 6003d40ce2
1 changed files with 103 additions and 82 deletions

185
Rules.py
View File

@ -414,7 +414,7 @@ def global_rules(world, player):
else: else:
forbid_item(world.get_location('Ganons Tower - Map Chest', player), 'Small Key (Ganons Tower)', player) forbid_item(world.get_location('Ganons Tower - Map Chest', player), 'Small Key (Ganons Tower)', player)
# 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. # It is possible to need more than 2 keys to get through this entrance 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. # 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.
set_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 2)) set_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 2))
# It is possible to need more than 3 keys .... # It is possible to need more than 3 keys ....
@ -1311,6 +1311,7 @@ def set_big_bomb_rules(world, player):
# -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR) # -> (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', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)))
def set_inverted_big_bomb_rules(world, player): def set_inverted_big_bomb_rules(world, player):
bombshop_entrance = world.get_region('Inverted Big Bomb Shop', player).entrances[0] bombshop_entrance = world.get_region('Inverted Big Bomb Shop', player).entrances[0]
Normal_LW_entrances = ['Blinds Hideout', Normal_LW_entrances = ['Blinds Hideout',
@ -1328,9 +1329,7 @@ def set_inverted_big_bomb_rules(world, player):
'Fortune Teller (Light)', 'Fortune Teller (Light)',
'Snitch Lady (East)', 'Snitch Lady (East)',
'Snitch Lady (West)', 'Snitch Lady (West)',
'Bush Covered House',
'Tavern (Front)', 'Tavern (Front)',
'Light World Bomb Hut',
'Kakariko Shop', 'Kakariko Shop',
'Mini Moldorm Cave', 'Mini Moldorm Cave',
'Long Fairy Cave', 'Long Fairy Cave',
@ -1341,7 +1340,6 @@ def set_inverted_big_bomb_rules(world, player):
'Bonk Rock Cave', 'Bonk Rock Cave',
'Library', 'Library',
'Potion Shop', 'Potion Shop',
'Waterfall of Wishing',
'Dam', 'Dam',
'Lumberjack House', 'Lumberjack House',
'Lake Hylia Fortune Teller', 'Lake Hylia Fortune Teller',
@ -1357,22 +1355,42 @@ def set_inverted_big_bomb_rules(world, player):
'Two Brothers House (East)', 'Two Brothers House (East)',
'Sanctuary', 'Sanctuary',
'Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (South)',
'Hyrule Castle Secret Entrance Stairs'] 'Hyrule Castle Secret Entrance Stairs',
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy', 'Hyrule Castle Entrance (West)',
'Dark Lake Hylia Ledge Spike Cave', 'Hyrule Castle Entrance (East)',
'Dark Lake Hylia Ledge Hint', 'Inverted Ganons Tower',
'Mire Shed', 'Cave 45',
'Dark Desert Hint', 'Checkerboard Cave',
'Dark Desert Fairy', 'Inverted Big Bomb Shop']
'Misery Mire'] Isolated_LW_entrances = ['Old Man Cave (East)',
'Old Man House (Bottom)',
'Old Man House (Top)',
'Death Mountain Return Cave (East)',
'Spectacle Rock Cave Peak',
'Tower of Hera',
'Death Mountain Return Cave (West)',
'Paradox Cave (Top)',
'Fairy Ascension Cave (Top)',
'Spiral Cave',
'Paradox Cave (Bottom)',
'Paradox Cave (Middle)',
'Hookshot Fairy',
'Spiral Cave (Bottom)',
'Mimic Cave',
'Fairy Ascension Cave (Bottom)',
'Desert Palace Entrance (West)',
'Desert Palace Entrance (North)',
'Desert Palace Entrance (South)']
Eastern_DW_entrances = ['Palace of Darkness',
'Palace of Darkness Hint',
'Dark Lake Hylia Fairy',
'East Dark World Hint']
Northern_DW_entrances = ['Brewery', Northern_DW_entrances = ['Brewery',
'C-Shaped House', 'C-Shaped House',
'Chest Game', 'Chest Game',
'Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave',
'Red Shield Shop', 'Inverted Dark Sanctuary',
'Dark Sanctuary Hint',
'Fortune Teller (Dark)', 'Fortune Teller (Dark)',
'Dark World Shop',
'Dark World Lumberjack Shop', 'Dark World Lumberjack Shop',
'Thieves Town', 'Thieves Town',
'Skull Woods First Section Door', 'Skull Woods First Section Door',
@ -1380,16 +1398,14 @@ def set_inverted_big_bomb_rules(world, player):
Southern_DW_entrances = ['Hype Cave', Southern_DW_entrances = ['Hype Cave',
'Bonk Fairy (Dark)', 'Bonk Fairy (Dark)',
'Archery Game', 'Archery Game',
'Inverted Big Bomb Shop', 'Inverted Links House',
'Dark Lake Hylia Shop', 'Dark Lake Hylia Shop',
'Swamp Palace'] 'Swamp Palace']
Isolated_DW_entrances = ['Spike Cave', Isolated_DW_entrances = ['Spike Cave',
'Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)',
'Dark Death Mountain Fairy', 'Dark Death Mountain Fairy',
'Mimic Cave',
'Skull Woods Second Section Door (West)', 'Skull Woods Second Section Door (West)',
'Skull Woods Final Section', 'Skull Woods Final Section',
'Ice Palace',
'Turtle Rock', 'Turtle Rock',
'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (West)',
'Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (East)',
@ -1400,42 +1416,23 @@ def set_inverted_big_bomb_rules(world, player):
'Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Isolated Ledge Entrance',
'Hookshot Cave Back Entrance', 'Hookshot Cave Back Entrance',
'Inverted Agahnims Tower'] 'Inverted Agahnims Tower']
Isolated_LW_entrances = ['Capacity Upgrade', LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
'Tower of Hera', 'Dark Lake Hylia Ledge Spike Cave',
'Death Mountain Return Cave (West)', 'Dark Lake Hylia Ledge Hint',
'Paradox Cave (Top)', 'Mire Shed',
'Fairy Ascension Cave (Top)', 'Dark Desert Hint',
'Spiral Cave', 'Dark Desert Fairy',
'Desert Palace Entrance (East)'] 'Misery Mire',
West_LW_DM_entrances = ['Old Man Cave (East)', 'Red Shield Shop']
'Old Man House (Bottom)', LW_bush_entrances = ['Bush Covered House',
'Old Man House (Top)', 'Light World Bomb Hut',
'Death Mountain Return Cave (East)', 'Graveyard Cave']
'Spectacle Rock Cave Peak', LW_inaccessible_entrances = ['Desert Palace Entrance (East)',
'Spectacle Rock Cave', 'Spectacle Rock Cave',
'Spectacle Rock Cave (Bottom)'] 'Spectacle Rock Cave (Bottom)']
East_LW_DM_entrances = ['Paradox Cave (Bottom)',
'Paradox Cave (Middle)',
'Hookshot Fairy',
'Spiral Cave (Bottom)']
Mirror_from_SDW_entrances = ['Two Brothers House (West)',
'Cave 45']
Castle_ledge_entrances = ['Hyrule Castle Entrance (West)',
'Hyrule Castle Entrance (East)',
'Inverted Ganons Tower']
Desert_mirrorable_ledge_entrances = ['Desert Palace Entrance (West)',
'Desert Palace Entrance (North)',
'Desert Palace Entrance (South)',
'Checkerboard Cave',]
Desert_ledge_entrances = ['Desert Palace Entrance (West)',
'Desert Palace Entrance (North)',
'Desert Palace Entrance (South)']
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Inverted Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player)) set_rule(world.get_entrance('Pyramid Fairy', player),
lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Inverted Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player))
#crossing peg bridge starting from the southern dark world
def cross_peg_bridge(state):
return state.has('Hammer', player)
# Key for below abbreviations: # Key for below abbreviations:
# P = pearl # P = pearl
@ -1443,42 +1440,66 @@ def set_inverted_big_bomb_rules(world, player):
# H = hammer # H = hammer
# M = Mirror # M = Mirror
# G = Glove # G = Glove
if bombshop_entrance.name in Normal_LW_entrances: if bombshop_entrance.name in Eastern_DW_entrances:
# Just walk to the pyramid
pass
elif bombshop_entrance.name in Normal_LW_entrances:
# Just walk to the castle and mirror.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
elif bombshop_entrance.name in LW_walkable_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player))
elif bombshop_entrance.name in Northern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and (cross_peg_bridge(state) or (state.has_Mirror(player) and state.has('Beat Agahnim 1', player)))))
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and (cross_peg_bridge(state) or state.has_Mirror(player) and state.has('Beat Agahnim 1', player))))
elif bombshop_entrance.name in Southern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or state.can_flute(player) or (state.has_Mirror(player) and state.has('Beat Agahnim 1', player)))
elif bombshop_entrance.name in Isolated_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player))
elif bombshop_entrance.name in Isolated_LW_entrances: elif bombshop_entrance.name in Isolated_LW_entrances:
# For these entrances, you cannot walk to the castle/pyramid and thus must use Mirror and then Flute.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player))
elif bombshop_entrance.name in West_LW_DM_entrances: elif bombshop_entrance.name in Northern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player)) # You can just fly with the Flute, you can take a long walk with Mitts and Hammer,
elif bombshop_entrance.name in East_LW_DM_entrances: # or you can leave a Mirror portal nearby and then walk to the castle to Mirror again.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)': elif bombshop_entrance.name in Southern_DW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player)) # This is the same as north DW without the Mitts rock present.
elif bombshop_entrance.name in Castle_ledge_entrances: add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player)) elif bombshop_entrance.name in Isolated_DW_entrances:
elif bombshop_entrance.name in Desert_ledge_entrances: # There's just no way to escape these places with the bomb and no Flute.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player))
elif bombshop_entrance.name == 'Checkerboard Cave': elif bombshop_entrance.name in LW_walkable_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player)) # You can fly with the flute, or leave a mirror portal and walk through the light world
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
elif bombshop_entrance.name in LW_bush_entrances:
# These entrances are behind bushes in LW so you need either Pearl or the tools to solve NDW bomb shop locations.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and (state.can_flute(player) or state.has_Pearl(player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player))))
elif bombshop_entrance.name == 'Dark World Shop':
# This is mostly the same as NDW but the Mirror path requires the Pearl, or using the Hammer
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player) and (state.has_Pearl(player) or state.has('Hammer', player))))
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
# This is mostly the same as NDW but the Mirror path requires being able to lift a rock.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_lift_rocks(player) and state.can_reach('Light World', 'Region', player)))
elif bombshop_entrance.name == 'Old Man Cave (West)': elif bombshop_entrance.name == 'Old Man Cave (West)':
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and ((state.can_lift_rocks(player) and cross_peg_bridge(state)) or state.can_flute(player))) # The three paths back are Mirror and DW walk, Mirror and Flute, or LW walk and then Mirror.
elif bombshop_entrance.name == 'Graveyard Cave': add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and ((state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.can_lift_rocks(player) and state.has_Pearl(player)) or state.can_flute(player)))
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
elif bombshop_entrance.name in Mirror_from_SDW_entrances:
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and (state.can_flute(player) or cross_peg_bridge(state)))
elif bombshop_entrance.name == 'Dark World Potion Shop': elif bombshop_entrance.name == 'Dark World Potion Shop':
# You either need to Flute to 5 or cross the rock/hammer choice pass to the south.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or state.has('Hammer', player) or state.can_lift_rocks(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or state.has('Hammer', player) or state.can_lift_rocks(player))
elif bombshop_entrance.name == 'Kings Grave': elif bombshop_entrance.name == 'Kings Grave':
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) # Either lift the rock and walk to the castle to Mirror or Mirror immediately and Flute.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.has_Pearl(player) and state.can_lift_heavy_rocks(player))) and state.has_Mirror(player))
elif bombshop_entrance.name == 'Two Brothers House (West)':
# First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has_Mirror(player))
elif bombshop_entrance.name == 'Waterfall of Wishing':
# You absolutely must be able to swim to return it from here.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player))
elif bombshop_entrance.name == 'Ice Palace':
# You can swim to the dock or use the Flute to get off the island.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.can_flute(player))
elif bombshop_entrance.name == 'Capacity Upgrade':
# You must Mirror but then can use either Ice Palace return path.
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and state.has_Mirror(player))
elif bombshop_entrance.name in LW_inaccessible_entrances:
# You can't get to the pyramid from these entrances without bomb duping.
raise Exception('No valid path to open Pyramid Fairy. (Could not route from %s)' % bombshop_entrance.name)
elif bombshop_entrance.name == 'Pyramid Fairy':
# Self locking. The shuffles don't put the bomb shop here, but doesn't lock anything important.
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
else:
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
def set_bunny_rules(world, player): def set_bunny_rules(world, player):