Minor tweaks in prep for ER rewrite

This commit is contained in:
codemann8
2021-10-02 13:45:14 -05:00
parent c54bd67ddc
commit c99805f47d
3 changed files with 243 additions and 252 deletions

View File

@@ -12,7 +12,6 @@ except ImportError:
from source.classes.BabelFish import BabelFish from source.classes.BabelFish import BabelFish
from EntranceShuffle import door_addresses, indirect_connections
from Utils import int16_as_bytes from Utils import int16_as_bytes
from Tables import normal_offset_table, spiral_offset_table, multiply_lookup, divisor_lookup from Tables import normal_offset_table, spiral_offset_table, multiply_lookup, divisor_lookup
from RoomData import Room from RoomData import Room
@@ -598,6 +597,7 @@ class CollectionState(object):
self.path[new_region] = (new_region.name, self.path.get(connection, None)) self.path[new_region] = (new_region.name, self.path.get(connection, None))
# Retry connections if the new region can unblock them # Retry connections if the new region can unblock them
from EntranceShuffle import indirect_connections
if new_region.name in indirect_connections: if new_region.name in indirect_connections:
new_entrance = self.world.get_entrance(indirect_connections[new_region.name], player) new_entrance = self.world.get_entrance(indirect_connections[new_region.name], player)
if new_entrance in bc and new_entrance.parent_region in rrp: if new_entrance in bc and new_entrance.parent_region in rrp:
@@ -2501,6 +2501,7 @@ class Shop(object):
# [id][roomID-low][roomID-high][doorID][zero][shop_config][shopkeeper_config][sram_index] # [id][roomID-low][roomID-high][doorID][zero][shop_config][shopkeeper_config][sram_index]
entrances = self.region.entrances entrances = self.region.entrances
config = self.item_count config = self.item_count
from EntranceShuffle import door_addresses
if len(entrances) == 1 and entrances[0].name in door_addresses: if len(entrances) == 1 and entrances[0].name in door_addresses:
door_id = door_addresses[entrances[0].name][0]+1 door_id = door_addresses[entrances[0].name][0]+1
else: else:

View File

@@ -53,6 +53,9 @@ def link_entrances(world, player):
connect_custom(world, player) connect_custom(world, player)
if invFlag == (0x05 in world.owswaps[player][0] and world.owMixed[player]):
isolated_entrances.append('Mimic Cave')
# if we do not shuffle, set default connections # if we do not shuffle, set default connections
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections: for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections:
@@ -141,10 +144,7 @@ def link_entrances(world, player):
if world.mode[player] == 'standard' or not world.shufflelinks[player]: if world.mode[player] == 'standard' or not world.shufflelinks[player]:
links_house = 'Links House' links_house = 'Links House'
else: else:
if not invFlag: links_house_doors = [i for i in LW_Single_Cave_Doors if i not in isolated_entrances + ([] if not invFlag else Inverted_Dark_Sanctuary_Doors)]
links_house_doors = [i for i in LW_Single_Cave_Doors if i not in Isolated_LH_Doors_Open]
else:
links_house_doors = [i for i in LW_Single_Cave_Doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
links_house = random.choice(links_house_doors) links_house = random.choice(links_house_doors)
connect_two_way(world, links_house, 'Links House Exit', player) connect_two_way(world, links_house, 'Links House Exit', player)
connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should always match link's house, except for plandos connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should always match link's house, except for plandos
@@ -1666,16 +1666,15 @@ LW_Single_Cave_Doors = ['Blinds Hideout',
'Mimic Cave', 'Mimic Cave',
'Links House'] 'Links House']
Isolated_LH_Doors_Open = ['Mimic Cave', Isolated_LH_Doors = ['Kings Grave',
'Kings Grave', 'Waterfall of Wishing',
'Waterfall of Wishing', 'Desert Palace Entrance (South)',
'Desert Palace Entrance (South)', 'Desert Palace Entrance (North)',
'Desert Palace Entrance (North)', 'Capacity Upgrade',
'Capacity Upgrade', 'Ice Palace',
'Ice Palace', 'Skull Woods Final Section',
'Skull Woods Final Section', 'Dark World Hammer Peg Cave',
'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance']
'Turtle Rock Isolated Ledge Entrance']
DW_Single_Cave_Doors = ['Bonk Fairy (Dark)', DW_Single_Cave_Doors = ['Bonk Fairy (Dark)',
'Dark Sanctuary Hint', 'Dark Sanctuary Hint',
@@ -2125,16 +2124,6 @@ Inverted_Dark_Sanctuary_Doors = ['Dark Sanctuary Hint',
'Bumper Cave (Top)', 'Bumper Cave (Top)',
'Thieves Town'] 'Thieves Town']
Isolated_LH_Doors = ['Kings Grave',
'Waterfall of Wishing',
'Desert Palace Entrance (South)',
'Desert Palace Entrance (North)',
'Capacity Upgrade',
'Ice Palace',
'Skull Woods Final Section',
'Dark World Hammer Peg Cave',
'Turtle Rock Isolated Ledge Entrance']
# Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups # Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups
Must_Exit_Invalid_Connections = defaultdict(set, { Must_Exit_Invalid_Connections = defaultdict(set, {
'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'}, 'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'},

453
Rules.py
View File

@@ -1629,239 +1629,240 @@ def find_rules_for_zelda_delivery(world, player):
def set_big_bomb_rules(world, player): def set_big_bomb_rules(world, player):
# this is a mess # this is a mess
bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0] if len(world.get_region('Big Bomb Shop', player).entrances) > 0:
Normal_LW_entrances = ['Blinds Hideout', bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0]
'Bonk Fairy (Light)', Normal_LW_entrances = ['Blinds Hideout',
'Lake Hylia Fairy', 'Bonk Fairy (Light)',
'Light Hype Fairy', 'Lake Hylia Fairy',
'Desert Fairy', 'Light Hype Fairy',
'Chicken House', 'Desert Fairy',
'Aginahs Cave', 'Chicken House',
'Sahasrahlas Hut', 'Aginahs Cave',
'Cave Shop (Lake Hylia)', 'Sahasrahlas Hut',
'Blacksmiths Hut', 'Cave Shop (Lake Hylia)',
'Sick Kids House', 'Blacksmiths Hut',
'Lost Woods Gamble', 'Sick Kids House',
'Fortune Teller (Light)', 'Lost Woods Gamble',
'Snitch Lady (East)', 'Fortune Teller (Light)',
'Snitch Lady (West)', 'Snitch Lady (East)',
'Bush Covered House', 'Snitch Lady (West)',
'Tavern (Front)', 'Bush Covered House',
'Light World Bomb Hut', 'Tavern (Front)',
'Kakariko Shop', 'Light World Bomb Hut',
'Mini Moldorm Cave', 'Kakariko Shop',
'Long Fairy Cave', 'Mini Moldorm Cave',
'Good Bee Cave', 'Long Fairy Cave',
'20 Rupee Cave', 'Good Bee Cave',
'50 Rupee Cave', '20 Rupee Cave',
'Ice Rod Cave', '50 Rupee Cave',
'Bonk Rock Cave', 'Ice Rod Cave',
'Library', 'Bonk Rock Cave',
'Potion Shop', 'Library',
'Dam', 'Potion Shop',
'Lumberjack House', 'Dam',
'Lake Hylia Fortune Teller', 'Lumberjack House',
'Eastern Palace', 'Lake Hylia Fortune Teller',
'Kakariko Gamble Game', 'Eastern Palace',
'Kakariko Well Cave', 'Kakariko Gamble Game',
'Bat Cave Cave', 'Kakariko Well Cave',
'Elder House (East)', 'Bat Cave Cave',
'Elder House (West)', 'Elder House (East)',
'North Fairy Cave', 'Elder House (West)',
'Lost Woods Hideout Stump', 'North Fairy Cave',
'Lumberjack Tree Cave', 'Lost Woods Hideout Stump',
'Two Brothers House (East)', 'Lumberjack Tree Cave',
'Sanctuary', 'Two Brothers House (East)',
'Hyrule Castle Entrance (South)', 'Sanctuary',
'Hyrule Castle Secret Entrance Stairs'] 'Hyrule Castle Entrance (South)',
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy', 'Hyrule Castle Secret Entrance Stairs']
'Dark Lake Hylia Ledge Spike Cave', LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave',
'Mire Shed', 'Dark Lake Hylia Ledge Hint',
'Dark Desert Hint', 'Mire Shed',
'Dark Desert Fairy', 'Dark Desert Hint',
'Misery Mire'] 'Dark Desert Fairy',
Northern_DW_entrances = ['Brewery', 'Misery Mire']
'C-Shaped House', Northern_DW_entrances = ['Brewery',
'Chest Game', 'C-Shaped House',
'Dark World Hammer Peg Cave', 'Chest Game',
'Red Shield Shop', 'Dark World Hammer Peg Cave',
'Dark Sanctuary Hint', 'Red Shield Shop',
'Fortune Teller (Dark)', 'Dark Sanctuary Hint',
'Dark World Shop', 'Fortune Teller (Dark)',
'Dark World Lumberjack Shop', 'Dark World Shop',
'Thieves Town', 'Dark World Lumberjack Shop',
'Skull Woods First Section Door', 'Thieves Town',
'Skull Woods Second Section Door (East)'] 'Skull Woods First Section Door',
Southern_DW_entrances = ['Hype Cave', 'Skull Woods Second Section Door (East)']
'Bonk Fairy (Dark)', Southern_DW_entrances = ['Hype Cave',
'Archery Game', 'Bonk Fairy (Dark)',
'Big Bomb Shop', 'Archery Game',
'Dark Lake Hylia Shop', 'Big Bomb Shop',
'Swamp Palace'] 'Dark Lake Hylia Shop',
Isolated_DW_entrances = ['Spike Cave', 'Swamp Palace']
'Cave Shop (Dark Death Mountain)', Isolated_DW_entrances = ['Spike Cave',
'Dark Death Mountain Fairy', 'Cave Shop (Dark Death Mountain)',
'Mimic Cave', 'Dark Death Mountain Fairy',
'Skull Woods Second Section Door (West)', 'Mimic Cave',
'Skull Woods Final Section', 'Skull Woods Second Section Door (West)',
'Ice Palace', 'Skull Woods Final Section',
'Turtle Rock', 'Ice Palace',
'Dark Death Mountain Ledge (West)', 'Turtle Rock',
'Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)',
'Bumper Cave (Top)', 'Dark Death Mountain Ledge (East)',
'Superbunny Cave (Top)', 'Bumper Cave (Top)',
'Superbunny Cave (Bottom)', 'Superbunny Cave (Top)',
'Hookshot Cave', 'Superbunny Cave (Bottom)',
'Ganons Tower', 'Hookshot Cave',
'Turtle Rock Isolated Ledge Entrance', 'Ganons Tower',
'Hookshot Cave Back Entrance'] 'Turtle Rock Isolated Ledge Entrance',
Isolated_LW_entrances = ['Capacity Upgrade', 'Hookshot Cave Back Entrance']
'Tower of Hera', Isolated_LW_entrances = ['Capacity Upgrade',
'Death Mountain Return Cave (West)', 'Tower of Hera',
'Paradox Cave (Top)', 'Death Mountain Return Cave (West)',
'Fairy Ascension Cave (Top)', 'Paradox Cave (Top)',
'Spiral Cave', 'Fairy Ascension Cave (Top)',
'Desert Palace Entrance (East)'] 'Spiral Cave',
West_LW_DM_entrances = ['Old Man Cave (East)', 'Desert Palace Entrance (East)']
'Old Man House (Bottom)', West_LW_DM_entrances = ['Old Man Cave (East)',
'Old Man House (Top)', 'Old Man House (Bottom)',
'Death Mountain Return Cave (East)', 'Old Man House (Top)',
'Spectacle Rock Cave Peak', 'Death Mountain Return Cave (East)',
'Spectacle Rock Cave', 'Spectacle Rock Cave Peak',
'Spectacle Rock Cave (Bottom)'] 'Spectacle Rock Cave',
East_LW_DM_entrances = ['Paradox Cave (Bottom)', 'Spectacle Rock Cave (Bottom)']
'Paradox Cave (Middle)', East_LW_DM_entrances = ['Paradox Cave (Bottom)',
'Hookshot Fairy', 'Paradox Cave (Middle)',
'Spiral Cave (Bottom)'] 'Hookshot Fairy',
Mirror_from_SDW_entrances = ['Two Brothers House (West)', 'Spiral Cave (Bottom)']
'Cave 45'] Mirror_from_SDW_entrances = ['Two Brothers House (West)',
Castle_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Cave 45']
'Hyrule Castle Entrance (East)', Castle_ledge_entrances = ['Hyrule Castle Entrance (West)',
'Agahnims Tower'] 'Hyrule Castle Entrance (East)',
Desert_mirrorable_ledge_entrances = ['Desert Palace Entrance (West)', 'Agahnims Tower']
'Desert Palace Entrance (North)', Desert_mirrorable_ledge_entrances = ['Desert Palace Entrance (West)',
'Desert Palace Entrance (South)', 'Desert Palace Entrance (North)',
'Checkerboard Cave'] 'Desert Palace Entrance (South)',
'Checkerboard Cave']
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_reach('Pyramid Area', 'Region', player) or state.can_reach('East Dark World', 'Region', player)) and state.can_reach('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('Pyramid Area', 'Region', player) or state.can_reach('East Dark World', 'Region', player)) and state.can_reach('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 #crossing peg bridge starting from the southern dark world
def cross_peg_bridge(state): def cross_peg_bridge(state):
return state.has('Hammer', player) and state.has_Pearl(player) return state.has('Hammer', player) and state.has_Pearl(player)
# returning via the eastern and southern teleporters needs the same items, so we use the southern teleporter for out routing. # 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 # crossing preg bridge already requires hammer so we just add the gloves to the requirement
def southern_teleporter(state): def southern_teleporter(state):
return state.can_lift_rocks(player) and cross_peg_bridge(state) return state.can_lift_rocks(player) and cross_peg_bridge(state)
# the basic routes assume you can reach eastern light world with the bomb. # 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 # you can then use the southern teleporter, or (if you have beaten Aga1) the hyrule castle gate warp
def basic_routes(state): def basic_routes(state):
return southern_teleporter(state) or state.has('Beat Agahnim 1', player) return southern_teleporter(state) or state.has('Beat Agahnim 1', player)
# Key for below abbreviations: # Key for below abbreviations:
# P = pearl # P = pearl
# A = Aga1 # A = Aga1
# 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 Normal_LW_entrances:
#1. basic routes #1. basic routes
#2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror #2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
# -> M or BR # -> M or BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: basic_routes(state) or state.has_Mirror(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: basic_routes(state) or state.has_Mirror(player))
elif bombshop_entrance.name in LW_walkable_entrances: elif bombshop_entrance.name in LW_walkable_entrances:
#1. Mirror then basic routes #1. Mirror then basic routes
# -> M and BR # -> M and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and basic_routes(state)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and basic_routes(state))
elif bombshop_entrance.name in Northern_DW_entrances: elif bombshop_entrance.name in Northern_DW_entrances:
#1. Mirror and basic routes #1. Mirror and basic routes
#2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl #2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
# -> (Mitts and CPB) or (M and BR) # -> (Mitts and CPB) or (M and BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (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 cross_peg_bridge(state)) or (state.has_Mirror(player) and basic_routes(state)))
elif bombshop_entrance.name == 'Bumper Cave (Bottom)': elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
#1. Mirror and Lift rock and basic_routes #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) #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 #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)) # -> (Mitts and CPB) or (((G or Flute) and M) and BR))
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.can_flute(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 cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.can_flute(player)) and state.has_Mirror(player)) and basic_routes(state)))
elif bombshop_entrance.name in Southern_DW_entrances: elif bombshop_entrance.name in Southern_DW_entrances:
#1. Mirror and enter via gate: Need mirror and Aga1 #1. Mirror and enter via gate: Need mirror and Aga1
#2. cross peg bridge: Need hammer and moon pearl #2. cross peg bridge: Need hammer and moon pearl
# -> CPB or (M and A) # -> CPB or (M and A)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or (state.has_Mirror(player) and state.has('Beat Agahnim 1', player))) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or (state.has_Mirror(player) and state.has('Beat Agahnim 1', player)))
elif bombshop_entrance.name in Isolated_DW_entrances: elif bombshop_entrance.name in Isolated_DW_entrances:
# 1. mirror then flute then basic routes # 1. mirror then flute then basic routes
# -> M and Flute and BR # -> M and Flute and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player) and basic_routes(state)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player) and basic_routes(state))
elif bombshop_entrance.name in Isolated_LW_entrances: elif bombshop_entrance.name in Isolated_LW_entrances:
# 1. flute then basic routes # 1. flute then basic routes
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations. # Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
# -> Flute and BR # -> Flute and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and basic_routes(state)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and basic_routes(state))
elif bombshop_entrance.name in West_LW_DM_entrances: elif bombshop_entrance.name in West_LW_DM_entrances:
# 1. flute then basic routes or mirror # 1. flute then basic routes or mirror
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly. # Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
# -> Flute and (M or BR) # -> Flute and (M or BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('West Death Mountain (Bottom)', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('West Death Mountain (Bottom)', 'Region', player))
elif bombshop_entrance.name in East_LW_DM_entrances: elif bombshop_entrance.name in East_LW_DM_entrances:
# 1. flute then basic routes or mirror and hookshot # 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 # 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) # -> Flute and ((M and Hookshot) or BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Death Mountain (Bottom)', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Death Mountain (Bottom)', 'Region', player))
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)': elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)':
# Same as East_LW_DM_entrances except navigation without BR requires Mitts # Same as East_LW_DM_entrances except navigation without BR requires Mitts
# -> Flute and ((M and Hookshot and Mitts) or BR) # -> Flute and ((M and Hookshot and Mitts) or BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Death Mountain (Bottom)', 'Region', player) and state.can_lift_heavy_rocks(player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Death Mountain (Bottom)', 'Region', player) and state.can_lift_heavy_rocks(player))
elif bombshop_entrance.name in Castle_ledge_entrances: elif bombshop_entrance.name in Castle_ledge_entrances:
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror # 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
# 2. flute then basic routes # 2. flute then basic routes
# -> M or (Flute and BR) # -> M or (Flute and BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Hyrule Castle Ledge', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Hyrule Castle Ledge', 'Region', player))
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances: 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: # 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 # 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 # 2. flute then basic routes
# -> (Mire access and M) or Flute) and BR # -> (Mire access and M) or Flute) and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Desert Ledge', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Desert Ledge', 'Region', player))
elif bombshop_entrance.name == 'Old Man Cave (West)': elif bombshop_entrance.name == 'Old Man Cave (West)':
# 1. Lift rock then basic_routes # 1. Lift rock then basic_routes
# 2. flute then basic_routes # 2. flute then basic_routes
# -> (Flute or G) and BR # -> (Flute or G) and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Death Mountain Entrance', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Death Mountain Entrance', 'Region', player))
elif bombshop_entrance.name == 'Graveyard Cave': elif bombshop_entrance.name == 'Graveyard Cave':
# 1. flute then basic routes # 1. flute then basic routes
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge # 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 # -> (Flute or (M and P and West Dark World access) and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('Dark Graveyard Area', '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_flute(player) or (state.can_reach('Dark Graveyard Area', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))
elif bombshop_entrance.name in Mirror_from_SDW_entrances: elif bombshop_entrance.name in Mirror_from_SDW_entrances:
# 1. flute then basic routes # 1. flute then basic routes
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge # 2. (has South dark world access) use existing mirror spot, mirror again off ledge
# -> (Flute or (M and South Dark World access) and BR # -> (Flute or (M and South Dark World access) and BR
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('Pyramid Area', 'Region', player) and state.has_Mirror(player))) and basic_routes(state)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('Pyramid Area', 'Region', player) and state.has_Mirror(player))) and basic_routes(state))
elif bombshop_entrance.name == 'Dark World Potion Shop': elif bombshop_entrance.name == 'Dark World Potion Shop':
# 1. walk down by lifting rock: needs gloves and pearl` # 1. walk down by lifting rock: needs gloves and pearl`
# 2. walk down by hammering peg: needs hammer and pearl # 2. walk down by hammering peg: needs hammer and pearl
# 3. mirror and basic routes # 3. mirror and basic routes
# -> (P and (H or Gloves)) or (M and BR) # -> (P and (H or Gloves)) or (M and BR)
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Dark Witch Area', 'Region', player)) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Dark Witch Area', 'Region', player))
elif bombshop_entrance.name == 'Kings Grave': elif bombshop_entrance.name == 'Kings Grave':
# same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts # 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) # (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
# to account for insanity, must consider a way to escape without a cave for basic_routes # 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) # -> (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) or state.can_flute(player) or (state.can_reach('Dark Graveyard Area', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player)))) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) or state.can_flute(player) or (state.can_reach('Dark Graveyard Area', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))))
elif bombshop_entrance.name == 'Waterfall of Wishing': elif bombshop_entrance.name == 'Waterfall of Wishing':
# same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which # same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which
# means you need an escape route of either Flippers or Flute # means you need an escape route of either Flippers or Flute
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player))) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)))
#TODO: Fix red bomb rules, artifically adding a bunch of rules to help reduce unbeatable seeds in OW shuffle #TODO: Fix red bomb rules, artifically adding a bunch of rules to help reduce unbeatable seeds in OW shuffle
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Pyramid Area', 'Region', player)) #add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Pyramid Area', 'Region', player))
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has('Flippers', player) and state.can_flute(player) and state.has('Hammer', player) and state.has('Hookshot', player) and state.has_Pearl(player) and state.has_Mirror(player))) #add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has('Flippers', player) and state.can_flute(player) and state.has('Hammer', player) and state.has('Hookshot', player) and state.has_Pearl(player) and state.has_Mirror(player)))
def set_inverted_big_bomb_rules(world, player): def set_inverted_big_bomb_rules(world, player):
bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0] bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0]