This commit is contained in:
qadan 2020-01-15 19:25:36 -04:00
commit 277d3ed713
2 changed files with 169 additions and 14 deletions

View File

@ -37,7 +37,8 @@ def parse_arguments(argv, no_defaults=False):
Overworld Glitches: May require overworld glitches. Starts with
boots.
No Logic: Distribute items without regard for
item requirements.
item requirements. Starts with
boots
''')
parser.add_argument('--mode', default=defval('open'), const='open', nargs='?', choices=['standard', 'open', 'inverted'],
help='''\

180
Rules.py
View File

@ -647,17 +647,33 @@ def no_glitches_rules(world, player):
add_conditional_lamps(world, player)
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)',
'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)']
def check_is_dark_world(region):
for entrance in region.entrances:
if entrance.name in DW_Entrances:
return True
return False
def add_conditional_lamps(world, player):
# 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
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)',
'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)']
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':
@ -749,6 +765,113 @@ def overworld_glitches_rules(world, player):
for spot in dw_boots_accessible_regions:
for location in world.get_region(spot, player).locations:
add_rule(world.get_location(location, player), needs_boots if world.mode[player] == 'inverted' else needs_boots_and_pearl, 'or')
# spots that are immediately accessible due to fake flippering
set_rule(world.get_entrance('Hobo Bridge', player), lambda state: True)
set_rule(world.get_region('Lake Hylia Central Island', player), lambda state: True)
set_rule(world.get_entrance('Zoras River', player), lambda state: True)
# boots-accessible stuff
lw_boots_accessible_entrances = [
'Bat Cave Drop Ledge',
'Bat Cave Drop Ledge Mirror Spot',
'Lake Hylia Island Mirror Spot',
'Desert Ledge Return Rocks',
'Desert Ledge Mirror Spot',
'Checkerboard Cave',
'Old Man House Exit (Bottom)',
'Desert Ledge (Northeast) Mirror Spot',
'Death Mountain Return Cave Exit (East)',
'Desert Palace Entrance (North) Rocks',
'Desert Palace Entrance (North) Mirror Spot',
'Flute Spot 1',
'Broken Bridge (East)',
'Death Mountain Drop',
'Death Mountain Return Cave Exit (West)',
'Old Man Cave Exit (East)',
'Bumper Cave Ledge Mirror Spot',
'Broken Bridge (West)',
'East Death Mountain Drop',
'Spiral Cave Ledge Drop',
'Fairy Ascension Drop',
'East Death Mountain (Top)',
'East Death Mountain (Top) Mirror Spot',
'Death Mountain (Top)',
'Spectacle Rock Drop',
'Spectacle Rock Mirror Spot',
'Floating Island Mirror Spot',
'Fairy Ascension Cave Exit (Top)',
'Fairy Ascension Cave Exit (Bottom)',
'Death Mountain Return Cave Exit (East)',
'Spiral Cave Exit',
]
lw_boots_accessible_locations = [
'Lake Hylia Island',
'Desert Ledge',
'Ether Tablet',
'Spectacle Rock',
'Floating Island',
]
dw_boots_accessible_entrances = [
'Northeast Dark World Broken Bridge Pass',
'Death Mountain Return Cave Exit (West)',
'Peg Area Rocks',
'Grassy Lawn Pegs',
'West Dark World Gap',
'Bumper Cave Ledge Drop',
'Turtle Rock Ledge Exit (West)',
'Turtle Rock Isolated Ledge Exit',
'Dark Desert Teleporter',
'Turtle Rock Exit (Front)',
'Turtle Rock Drop',
'Floating Island Drop',
'Turtle Rock Ledge Exit (East)',
'Dark Death Mountain Drop (East)',
'Village of Outcasts Drop',
'Dark Lake Hylia Ledge',
'Hype Cave',
'Dark World Potion Shop',
'Big Bomb Shop',
'Archery Game',
'Brewery',
'C-Shaped House',
'Chest Game',
'Thieves Town',
'Graveyard Ledge Mirror Spot',
'Kings Grave Mirror Spot',
'Bumper Cave Entrance Rock',
'Red Shield Shop',
'Dark Sanctuary Hint',
'Fortune Teller (Dark)',
'Dark World Lumberjack Shop',
]
dw_boots_accessible_locations = [
'Catfish',
'Frog',
'Dark Blacksmith Ruins',
'Bumper Cave Ledge',
]
# set up boots-accessible regions
if world.mode[player] != 'inverted':
lw_boots_accessible_entrances.append('Cave 45 Mirror Spot')
lw_boots_accessible_entrances.append('Graveyard Ledge Mirror Spot')
# couple other random spots
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player) and (state.has_Mirror(player) or state.has_Boots(player)))
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Ocarina', player) or (state.has_Boots(player) and state.can_lift_heavy_rocks(player)))
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player))
add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.has_Boots(player) and state.has_Pearl(player), 'or')
add_rule(world.get_entrance('East Death Mountain Teleporter', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Boots(player), 'or')
add_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has_Boots(player) and state.has('Hammer', player))
needs_boots = lambda state: state.has_Boots(player)
needs_boots_and_pearl = lambda state: state.has_Boots(player) and state.has_Pearl(player)
for entrance in lw_boots_accessible_entrances:
add_rule(world.get_entrance(entrance, player), needs_boots_and_pearl if world.mode[player] == 'inverted' else needs_boots, 'or')
for location in lw_boots_accessible_locations:
add_rule(world.get_location(location, player), needs_boots_and_pearl if world.mode[player] == 'inverted' else needs_boots, 'or')
# no inverted rules here; no DMD bunny known so far
for entrance in dw_boots_accessible_entrances:
add_rule(world.get_entrance(entrance, player), needs_boots_and_pearl, 'or')
for location in dw_boots_accessible_locations:
add_rule(world.get_location(location, player), needs_boots_and_pearl, 'or')
# bunny DMD rules
if world.mode[player] != 'inverted':
# set up some mirror-accessible dw entrances.
@ -769,6 +892,33 @@ def overworld_glitches_rules(world, player):
boots_mirror_titans = lambda state: state.has_Boots(player) and state.has_Mirror(player) and state.can_lift_heavy_rocks(player)
add_rule(world.get_entrance('Mire Shed', player), boots_mirror_titans, 'or')
add_rule(world.get_location('Frog', player), boots_mirror_titans, 'or')
# all entrances you can't mirror bunny into. @todo: use for inverted
invalid_mirror_bunny_entrances_lw = [
'Bonk Rock Cave',
'Bonk Fairy (Light)',
'Blinds Hideout',
'50 Rupee Cave',
'20 Rupee Cave',
'Checkerboard Cave',
'Light Hype Fairy',
'Waterfall of Wishing',
'Light World Bomb Hut',
'Mini Moldorm Cave',
'Ice Rod Cave',
'Hyrule Castle Secret Entrance Stairs',
'Sanctuary Grave',
'Kings Grave',
'Tower of Hera',
]
# also, you can do mini moldorm cave and spiral cave - but you need a sword
superbunny_mirror_sword = lambda state: state.has_Boots(player) and state.has_Mirror(player) and state.has_sword(player)
mini_moldorm_cave = world.get_region('Mini Moldorm Cave', player)
if check_is_dark_world(mini_moldorm_cave):
for spot in mini_moldorm_cave.locations:
add_rule(world.get_location(spot, player), superbunny_mirror_sword, 'or')
add_rule(world.get_location('Spiral Cave', player), superbunny_mirror_sword, 'or')
>>>>>>> c677a875f2a124bd0930467b2952e0587d24839b
add_conditional_lamps(world, player)
@ -1249,6 +1399,7 @@ def set_inverted_big_bomb_rules(world, player):
'Dark Desert Hint',
'Dark Desert Fairy',
'Misery Mire']
LW_bush_entrances = ['Bush Covered House',
'Light World Bomb Hut',
'Graveyard Cave']
@ -1318,7 +1469,9 @@ def set_bunny_rules(world, player):
'Turtle Rock (Eye Bridge)', 'Sewers', 'Pyramid', 'Spiral Cave (Top)', 'Desert Palace Main (Inner)', 'Fairy Ascension Cave (Drop)']
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins']
# interiors that are accessible if you're in bunny state but have the mirror; OWG-only.
superbunny_accessible_locations = ['Waterfall of Wishing - Left', 'Waterfall of Wishing - Right', 'King\'s Tomb', 'Floodgate', 'Floodgate Chest', 'Cave 45', 'Bonk Rock Cave', 'Brewery', 'C-Shaped House', 'Chest Game', 'Mire Shed - Left', 'Mire Shed - Right', 'Secret Passage', 'Ice Rod Cave', 'Pyramid Fairy - Left', 'Pyramid Fairy - Right']
invalid_mirror_bunny_entrances_dw = ['Skull Woods Final Section (Entrance)', 'Hype Cave', 'Bonk Fairy (Dark)', 'Thieves Town', 'Dark World Hammer Peg Cave', 'Brewery', 'Hookshot Cave', 'Hookshot Cave Exit (South)', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave']
def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path)
@ -1326,8 +1479,10 @@ def set_bunny_rules(world, player):
def options_to_access_rule(options):
return lambda state: any(rule(state) for rule in options)
def get_rule_to_add(region):
def get_rule_to_add(region, location = None):
if not region.is_light_world:
if world.logic[player] == 'owglitches' and location in superbunny_accessible_locations and region.name not in invalid_mirror_bunny_entrances_dw:
return lambda state: (state.can_reach(region) and state.has_Mirror(player)) or state.has_Pearl(player)
return lambda state: state.has_Pearl(player)
# in this case we are mixed region.
# we collect possible options.
@ -1351,7 +1506,7 @@ def set_bunny_rules(world, player):
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
continue # we don't care about pure dark world entrances in non-owg
if new_region.is_dark_world:
queue.append((new_region, new_path))
else:
@ -1379,7 +1534,7 @@ def set_bunny_rules(world, player):
if location.name in bunny_accessible_locations:
continue
add_rule(location, get_rule_to_add(location.parent_region))
add_rule(location, get_rule_to_add(location.parent_region, location.name))
def set_inverted_bunny_rules(world, player):
@ -1390,7 +1545,6 @@ def set_inverted_bunny_rules(world, player):
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', 'Bombos Tablet', 'Ether Tablet', 'Purple Chest']
def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule(state) for rule in path)