fix(key logic): typo
fix(bunny logic): multiple paths considered
This commit is contained in:
@@ -1729,7 +1729,7 @@ def imp_locations_factory(world, player):
|
|||||||
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
imp_locations.append('Zelda Pickup')
|
imp_locations.append('Zelda Pickup')
|
||||||
imp_locations.append('Zelda Dropoff')
|
imp_locations.append('Zelda Drop Off')
|
||||||
return imp_locations
|
return imp_locations
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names
|
|||||||
from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config
|
from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config
|
||||||
from source.tools.BPS import create_bps_from_data
|
from source.tools.BPS import create_bps_from_data
|
||||||
|
|
||||||
__version__ = '1.1.6-dev'
|
__version__ = '1.1.7-dev'
|
||||||
|
|
||||||
from source.classes.BabelFish import BabelFish
|
from source.classes.BabelFish import BabelFish
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,10 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o
|
|||||||
|
|
||||||
# Bug Fixes and Notes
|
# Bug Fixes and Notes
|
||||||
|
|
||||||
|
* 1.1.7
|
||||||
|
* Fixed logic issues:
|
||||||
|
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
|
||||||
|
* More advanced bunny-walking logic in dungeons (multiple paths considred)
|
||||||
* 1.1.6
|
* 1.1.6
|
||||||
* Minor issue with dungeon counter hud interfering with timer
|
* Minor issue with dungeon counter hud interfering with timer
|
||||||
* 1.1.5
|
* 1.1.5
|
||||||
|
|||||||
215
Rules.py
215
Rules.py
@@ -98,16 +98,20 @@ def mirrorless_path_to_castle_courtyard(world, player):
|
|||||||
else:
|
else:
|
||||||
queue.append((entrance.connected_region, new_path))
|
queue.append((entrance.connected_region, new_path))
|
||||||
|
|
||||||
|
|
||||||
def set_rule(spot, rule):
|
def set_rule(spot, rule):
|
||||||
spot.access_rule = rule
|
spot.access_rule = rule
|
||||||
|
|
||||||
|
|
||||||
def set_defeat_dungeon_boss_rule(location):
|
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
|
# 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))
|
set_rule(location, lambda state: location.parent_region.dungeon.boss.can_defeat(state))
|
||||||
|
|
||||||
|
|
||||||
def set_always_allow(spot, rule):
|
def set_always_allow(spot, rule):
|
||||||
spot.always_allow = rule
|
spot.always_allow = rule
|
||||||
|
|
||||||
|
|
||||||
def add_rule(spot, rule, combine='and'):
|
def add_rule(spot, rule, combine='and'):
|
||||||
old_rule = spot.access_rule
|
old_rule = spot.access_rule
|
||||||
if combine == 'or':
|
if combine == 'or':
|
||||||
@@ -128,22 +132,26 @@ def forbid_item(location, item, player):
|
|||||||
old_rule = location.item_rule
|
old_rule = location.item_rule
|
||||||
location.item_rule = lambda i: (i.name != item or i.player != player) and old_rule(i)
|
location.item_rule = lambda i: (i.name != item or i.player != player) and old_rule(i)
|
||||||
|
|
||||||
|
|
||||||
def add_item_rule(location, rule):
|
def add_item_rule(location, rule):
|
||||||
old_rule = location.item_rule
|
old_rule = location.item_rule
|
||||||
location.item_rule = lambda item: rule(item) and old_rule(item)
|
location.item_rule = lambda item: rule(item) and old_rule(item)
|
||||||
|
|
||||||
|
|
||||||
def item_in_locations(state, item, player, locations):
|
def item_in_locations(state, item, player, locations):
|
||||||
for location in locations:
|
for location in locations:
|
||||||
if item_name(state, location[0], location[1]) == (item, player):
|
if item_name(state, location[0], location[1]) == (item, player):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def item_name(state, location, player):
|
def item_name(state, location, player):
|
||||||
location = state.world.get_location(location, player)
|
location = state.world.get_location(location, player)
|
||||||
if location.item is None:
|
if location.item is None:
|
||||||
return None
|
return None
|
||||||
return (location.item.name, location.item.player)
|
return (location.item.name, location.item.player)
|
||||||
|
|
||||||
|
|
||||||
def global_rules(world, player):
|
def global_rules(world, player):
|
||||||
# ganon can only carry triforce
|
# ganon can only carry triforce
|
||||||
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
|
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
|
||||||
@@ -161,7 +169,7 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
||||||
set_rule(world.get_location('Master Sword Pedestal', player), lambda state: state.has('Red Pendant', player) and state.has('Blue Pendant', player) and state.has('Green Pendant', player))
|
set_rule(world.get_location('Master Sword Pedestal', player), lambda state: state.has('Red Pendant', player) and state.has('Blue Pendant', player) and state.has('Green Pendant', player))
|
||||||
|
|
||||||
set_rule(world.get_location('Missing Smith', player), lambda state: state.has('Get Frog', player) and state.can_reach('Blacksmiths Hut', 'Region', player)) # Can't S&Q with smith
|
set_rule(world.get_location('Missing Smith', player), lambda state: state.has('Get Frog', player) and state.can_reach('Blacksmiths Hut', 'Region', player)) # Can't S&Q with smith
|
||||||
set_rule(world.get_location('Blacksmith', player), lambda state: state.has('Return Smith', player))
|
set_rule(world.get_location('Blacksmith', player), lambda state: state.has('Return Smith', player))
|
||||||
set_rule(world.get_location('Magic Bat', player), lambda state: state.has('Magic Powder', player))
|
set_rule(world.get_location('Magic Bat', player), lambda state: state.has('Magic Powder', player))
|
||||||
set_rule(world.get_location('Sick Kid', player), lambda state: state.has_bottle(player))
|
set_rule(world.get_location('Sick Kid', player), lambda state: state.has_bottle(player))
|
||||||
@@ -220,7 +228,6 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: state.has_sword(player))
|
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: state.has_sword(player))
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 1', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 1', player))
|
||||||
|
|
||||||
|
|
||||||
set_rule(world.get_entrance('PoD Arena Landing Bonk Path', player), lambda state: state.has_Boots(player))
|
set_rule(world.get_entrance('PoD Arena Landing Bonk Path', player), lambda state: state.has_Boots(player))
|
||||||
set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||||
@@ -478,7 +485,7 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Swamp Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Swamp Barrier', player), player))
|
set_rule(world.get_entrance('Swamp Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Swamp Barrier', player), player))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Crystal', player), lambda state: state.can_hit_crystal(player))
|
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||||
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Swamp Crystal Switch Outer', player), player))) # It is the length of the sword, not the beam itself that allows this
|
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Swamp Crystal Switch Outer', player), player))) # It is the length of the sword, not the beam itself that allows this
|
||||||
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Inner Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Inner Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
||||||
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Outer Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Outer Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
||||||
|
|
||||||
@@ -521,8 +528,8 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Mire Crystal Left Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Left', player), player))
|
set_rule(world.get_entrance('Mire Crystal Left Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Left', player), player))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Mire Conveyor to Crystal', player), lambda state: state.can_hit_crystal(player))
|
set_rule(world.get_entrance('Mire Conveyor to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||||
set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: True) # Can always throw pots
|
set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: True) # Can always throw pots
|
||||||
set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic?
|
set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic?
|
||||||
|
|
||||||
set_rule(world.get_location('Turtle Rock - Chain Chomps', player), lambda state: state.can_reach('TR Chain Chomps Top', 'Region', player) and state.can_hit_crystal_through_barrier(player))
|
set_rule(world.get_location('Turtle Rock - Chain Chomps', player), lambda state: state.can_reach('TR Chain Chomps Top', 'Region', player) and state.can_hit_crystal_through_barrier(player))
|
||||||
set_rule(world.get_entrance('TR Chain Chomps Top to Bottom Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('TR Chain Chomps Top', player), player))
|
set_rule(world.get_entrance('TR Chain Chomps Top to Bottom Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('TR Chain Chomps Top', player), player))
|
||||||
@@ -544,14 +551,14 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('TR Pokey 2 Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
set_rule(world.get_entrance('TR Pokey 2 Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||||
set_rule(world.get_entrance('TR Crystaroller Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
set_rule(world.get_entrance('TR Crystaroller Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||||
set_rule(world.get_entrance('TR Crystal Maze Start to Crystal', player), lambda state: state.can_hit_crystal(player))
|
set_rule(world.get_entrance('TR Crystal Maze Start to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||||
set_rule(world.get_entrance('TR Chain Chomps Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Chain Chomps Bottom', player), player))) # or state.has_beam_sword(player)
|
set_rule(world.get_entrance('TR Chain Chomps Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Chain Chomps Bottom', player), player))) # or state.has_beam_sword(player)
|
||||||
set_rule(world.get_entrance('TR Pokey 2 Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('TR Pokey 2 Bottom', player), player))) # or state.has_beam_sword(player)
|
set_rule(world.get_entrance('TR Pokey 2 Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('TR Pokey 2 Bottom', player), player))) # or state.has_beam_sword(player)
|
||||||
set_rule(world.get_entrance('TR Crystaroller Bottom to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Bottom', player), player))) # or state.has_beam_sword(player)
|
set_rule(world.get_entrance('TR Crystaroller Bottom to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Bottom', player), player))) # or state.has_beam_sword(player)
|
||||||
set_rule(world.get_entrance('TR Crystaroller Middle to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Middle', player), player))) # or state.has_beam_sword(player)
|
set_rule(world.get_entrance('TR Crystaroller Middle to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Middle', player), player))) # or state.has_beam_sword(player)
|
||||||
set_rule(world.get_entrance('TR Crystaroller Middle to Bottom Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player))
|
set_rule(world.get_entrance('TR Crystaroller Middle to Bottom Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player))
|
||||||
set_rule(world.get_entrance('TR Crystal Maze End to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) # or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) // These work by clipping the rang through the two stone blocks, which works sometimes.
|
set_rule(world.get_entrance('TR Crystal Maze End to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) # or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) // These work by clipping the rang through the two stone blocks, which works sometimes.
|
||||||
set_rule(world.get_entrance('TR Crystal Maze Interior to End Bypass', player), lambda state: state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # Beam sword does NOT work
|
set_rule(world.get_entrance('TR Crystal Maze Interior to End Bypass', player), lambda state: state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # Beam sword does NOT work
|
||||||
set_rule(world.get_entrance('TR Crystal Maze Interior to Start Bypass', player), lambda state: True) # Can always grab a pot from the interior and walk it to the start region and throw it there
|
set_rule(world.get_entrance('TR Crystal Maze Interior to Start Bypass', player), lambda state: True) # Can always grab a pot from the interior and walk it to the start region and throw it there
|
||||||
|
|
||||||
set_rule(world.get_entrance('GT Hookshot Platform Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Platform', player), player))
|
set_rule(world.get_entrance('GT Hookshot Platform Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Platform', player), player))
|
||||||
set_rule(world.get_entrance('GT Hookshot Entry Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Entry', player), player))
|
set_rule(world.get_entrance('GT Hookshot Entry Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Entry', player), player))
|
||||||
@@ -655,7 +662,7 @@ def bomb_rules(world, player):
|
|||||||
('GT Petting Zoo SE', False), # Dont make anyone do this room with bombs and/or pots.
|
('GT Petting Zoo SE', False), # Dont make anyone do this room with bombs and/or pots.
|
||||||
('GT DMs Room SW', False) # Four red stalfos
|
('GT DMs Room SW', False) # Four red stalfos
|
||||||
]
|
]
|
||||||
for killdoor,bombable in easy_kill_rooms:
|
for killdoor, bombable in easy_kill_rooms:
|
||||||
if bombable:
|
if bombable:
|
||||||
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||||
else:
|
else:
|
||||||
@@ -663,47 +670,47 @@ def bomb_rules(world, player):
|
|||||||
add_rule(world.get_entrance('Ice Stalfos Hint SE', player), lambda state: state.can_use_bombs(player)) # Need bombs for big stalfos knights
|
add_rule(world.get_entrance('Ice Stalfos Hint SE', player), lambda state: state.can_use_bombs(player)) # Need bombs for big stalfos knights
|
||||||
add_rule(world.get_entrance('Mire Cross ES', player), lambda state: state.can_kill_most_things(player)) # 4 Sluggulas. Bombs don't work // or (state.can_use_bombs(player) and state.has('Magic Powder'), player)
|
add_rule(world.get_entrance('Mire Cross ES', player), lambda state: state.can_kill_most_things(player)) # 4 Sluggulas. Bombs don't work // or (state.can_use_bombs(player) and state.has('Magic Powder'), player)
|
||||||
|
|
||||||
enemy_kill_drops = [ # Location, bool-bombable
|
enemy_kill_drops = [ # Location, bool-bombable
|
||||||
('Hyrule Castle - Map Guard Key Drop', True),
|
('Hyrule Castle - Map Guard Key Drop', True),
|
||||||
('Hyrule Castle - Boomerang Guard Key Drop', True),
|
('Hyrule Castle - Boomerang Guard Key Drop', True),
|
||||||
('Hyrule Castle - Key Rat Key Drop', True),
|
('Hyrule Castle - Key Rat Key Drop', True),
|
||||||
# ('Hyrule Castle - Big Key Drop', True), # Pots are available
|
# ('Hyrule Castle - Big Key Drop', True), # Pots are available
|
||||||
# ('Eastern Palace - Dark Eyegore Key Drop', True), # Pots are available
|
# ('Eastern Palace - Dark Eyegore Key Drop', True), # Pots are available
|
||||||
('Castle Tower - Dark Archer Key Drop', True),
|
('Castle Tower - Dark Archer Key Drop', True),
|
||||||
# ('Castle Tower - Circle of Pots Key Drop', True), # Pots are available
|
# ('Castle Tower - Circle of Pots Key Drop', True), # Pots are available
|
||||||
# ('Skull Woods - Spike Corner Key Drop', True), # Pots are available
|
# ('Skull Woods - Spike Corner Key Drop', True), # Pots are available
|
||||||
('Ice Palace - Jelly Key Drop', True),
|
('Ice Palace - Jelly Key Drop', True),
|
||||||
('Ice Palace - Conveyor Key Drop', True),
|
('Ice Palace - Conveyor Key Drop', True),
|
||||||
('Misery Mire - Conveyor Crystal Key Drop', True),
|
('Misery Mire - Conveyor Crystal Key Drop', True),
|
||||||
('Turtle Rock - Pokey 1 Key Drop', True),
|
('Turtle Rock - Pokey 1 Key Drop', True),
|
||||||
('Turtle Rock - Pokey 2 Key Drop', True),
|
('Turtle Rock - Pokey 2 Key Drop', True),
|
||||||
# ('Ganons Tower - Mini Helmasaur Key Drop', True) # Pots are available
|
# ('Ganons Tower - Mini Helmasaur Key Drop', True) # Pots are available
|
||||||
('Castle Tower - Room 03', True), # Two spring soliders
|
('Castle Tower - Room 03', True), # Two spring soliders
|
||||||
('Ice Palace - Compass Chest', True) # Pengators
|
('Ice Palace - Compass Chest', True) # Pengators
|
||||||
]
|
]
|
||||||
for location,bombable in enemy_kill_drops:
|
for location, bombable in enemy_kill_drops:
|
||||||
if bombable:
|
if bombable:
|
||||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.can_kill_most_things(player))
|
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.can_kill_most_things(player))
|
||||||
else:
|
else:
|
||||||
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player))
|
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player))
|
||||||
|
|
||||||
add_rule(world.get_location('Attic Cracked Floor', player), lambda state: state.can_use_bombs(player))
|
add_rule(world.get_location('Attic Cracked Floor', player), lambda state: state.can_use_bombs(player))
|
||||||
bombable_floors = ['PoD Pit Room Bomb Hole', 'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole', 'GT Bob\'s Room Hole']
|
bombable_floors = ['PoD Pit Room Bomb Hole', 'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole', 'GT Bob\'s Room Hole']
|
||||||
for entrance in bombable_floors:
|
for entrance in bombable_floors:
|
||||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||||
|
|
||||||
if world.doorShuffle[player] == 'vanilla':
|
if world.doorShuffle[player] == 'vanilla':
|
||||||
add_rule(world.get_entrance('TR Lazy Eyes SE', player), lambda state: state.can_use_bombs(player)) # ToDo: Add always true for inverted, cross-entrance, and door-variants and so on.
|
add_rule(world.get_entrance('TR Lazy Eyes SE', player), lambda state: state.can_use_bombs(player)) # ToDo: Add always true for inverted, cross-entrance, and door-variants and so on.
|
||||||
add_rule(world.get_entrance('Turtle Rock Ledge Exit (West)', player), lambda state: state.can_use_bombs(player)) # Is this the same as above?
|
add_rule(world.get_entrance('Turtle Rock Ledge Exit (West)', player), lambda state: state.can_use_bombs(player)) # Is this the same as above?
|
||||||
|
|
||||||
dungeon_bonkable = ['Sewers Rat Path WS', 'Sewers Rat Path WN',
|
dungeon_bonkable = ['Sewers Rat Path WS', 'Sewers Rat Path WN',
|
||||||
'PoD Warp Hint SE', 'PoD Jelly Hall NW', 'PoD Jelly Hall NE', 'PoD Mimics 1 SW',
|
'PoD Warp Hint SE', 'PoD Jelly Hall NW', 'PoD Jelly Hall NE', 'PoD Mimics 1 SW',
|
||||||
'Thieves Ambush E', 'Thieves Rail Ledge W',
|
'Thieves Ambush E', 'Thieves Rail Ledge W',
|
||||||
'TR Dash Room NW', 'TR Crystaroller SW', 'TR Dash Room ES',
|
'TR Dash Room NW', 'TR Crystaroller SW', 'TR Dash Room ES',
|
||||||
'GT Four Torches NW','GT Fairy Abyss SW'
|
'GT Four Torches NW', 'GT Fairy Abyss SW'
|
||||||
]
|
]
|
||||||
dungeon_bombable = ['PoD Map Balcony WS', 'PoD Arena Ledge ES', 'PoD Dark Maze E', 'PoD Big Chest Balcony W',
|
dungeon_bombable = ['PoD Map Balcony WS', 'PoD Arena Ledge ES', 'PoD Dark Maze E', 'PoD Big Chest Balcony W',
|
||||||
'Swamp Pot Row WN','Swamp Map Ledge EN', 'Swamp Hammer Switch WN', 'Swamp Hub Dead Ledge EN', 'Swamp Waterway N', 'Swamp I S',
|
'Swamp Pot Row WN', 'Swamp Map Ledge EN', 'Swamp Hammer Switch WN', 'Swamp Hub Dead Ledge EN', 'Swamp Waterway N', 'Swamp I S',
|
||||||
'Skull Pot Circle WN', 'Skull Pull Switch EN', 'Skull Big Key EN', 'Skull Lone Pot WN',
|
'Skull Pot Circle WN', 'Skull Pull Switch EN', 'Skull Big Key EN', 'Skull Lone Pot WN',
|
||||||
'Thieves Rail Ledge NW', 'Thieves Pot Alcove Bottom SW',
|
'Thieves Rail Ledge NW', 'Thieves Pot Alcove Bottom SW',
|
||||||
'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole',
|
'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole',
|
||||||
@@ -711,9 +718,9 @@ def bomb_rules(world, player):
|
|||||||
'GT Warp Maze (Rails) WS', 'GT Bob\'s Room Hole', 'GT Randomizer Room ES', 'GT Bomb Conveyor SW', 'GT Crystal Circles NW', 'GT Cannonball Bridge SE', 'GT Refill NE'
|
'GT Warp Maze (Rails) WS', 'GT Bob\'s Room Hole', 'GT Randomizer Room ES', 'GT Bomb Conveyor SW', 'GT Crystal Circles NW', 'GT Cannonball Bridge SE', 'GT Refill NE'
|
||||||
]
|
]
|
||||||
for entrance in dungeon_bonkable:
|
for entrance in dungeon_bonkable:
|
||||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||||
for entrance in dungeon_bombable:
|
for entrance in dungeon_bombable:
|
||||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||||
else:
|
else:
|
||||||
doors_to_bomb_check = [x for x in world.doors if x.player == player and x.type in [DoorType.Normal, DoorType.Interior]]
|
doors_to_bomb_check = [x for x in world.doors if x.player == player and x.type in [DoorType.Normal, DoorType.Interior]]
|
||||||
for door in doors_to_bomb_check:
|
for door in doors_to_bomb_check:
|
||||||
@@ -768,7 +775,6 @@ def pot_rules(world, player):
|
|||||||
add_rule(l, lambda state: state.can_hit_crystal(player))
|
add_rule(l, lambda state: state.can_hit_crystal(player))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def default_rules(world, player):
|
def default_rules(world, player):
|
||||||
# overworld requirements
|
# overworld requirements
|
||||||
set_rule(world.get_entrance('Kings Grave', player), lambda state: state.has_Boots(player))
|
set_rule(world.get_entrance('Kings Grave', player), lambda state: state.has_Boots(player))
|
||||||
@@ -789,9 +795,9 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Ocarina', player))
|
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Ocarina', player))
|
||||||
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Ocarina', player) and state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Ocarina', player) and state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes
|
set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes
|
||||||
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player))
|
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player))
|
||||||
|
|
||||||
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player))
|
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player))
|
||||||
@@ -799,7 +805,7 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player))
|
set_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player))
|
||||||
# to leave via fake flippers, you'd need pearl and have waterwalk or swimming state, so just require flippers
|
# to leave via fake flippers, you'd need pearl and have waterwalk or swimming state, so just require flippers
|
||||||
set_rule(world.get_entrance('Zora Waterfall Water Drop', player), lambda state: state.has('Flippers', player))
|
set_rule(world.get_entrance('Zora Waterfall Water Drop', player), lambda state: state.has('Flippers', player))
|
||||||
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player)) # will get automatic moon pearl requirement
|
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player)) # will get automatic moon pearl requirement
|
||||||
set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player))
|
set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player))
|
||||||
set_rule(world.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Desert Palace Entrance (North) Rocks', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Desert Ledge Return Rocks', player), lambda state: state.can_lift_rocks(player)) # should we decide to place something that is not a dungeon end up there at some point
|
set_rule(world.get_entrance('Desert Ledge Return Rocks', player), lambda state: state.can_lift_rocks(player)) # should we decide to place something that is not a dungeon end up there at some point
|
||||||
@@ -824,22 +830,22 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player))
|
set_rule(world.get_entrance('South Dark World Bridge', player), lambda state: state.has('Hammer', player) and state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has_Pearl(player) and state.has_Boots(player))
|
set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has_Pearl(player) and state.has_Boots(player))
|
||||||
set_rule(world.get_entrance('West Dark World Gap', player), lambda state: state.has_Pearl(player) and state.has('Hookshot', player))
|
set_rule(world.get_entrance('West Dark World Gap', player), lambda state: state.has_Pearl(player) and state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Palace of Darkness', player), lambda state: state.has_Pearl(player)) # kiki needs pearl
|
set_rule(world.get_entrance('Palace of Darkness', player), lambda state: state.has_Pearl(player)) # kiki needs pearl
|
||||||
set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Hyrule Castle Main Gate', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Hyrule Castle Main Gate', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Hyrule Castle Main Gate (North)', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Hyrule Castle Main Gate (North)', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: (state.has_Pearl(player) and state.has('Flippers', player) or state.has_Mirror(player))) # Overworld Bunny Revival
|
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: (state.has_Pearl(player) and state.has('Flippers', player) or state.has_Mirror(player))) # Overworld Bunny Revival
|
||||||
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # ToDo any fake flipper set up?
|
set_rule(world.get_entrance('Dark Lake Hylia Drop (South)', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # ToDo any fake flipper set up?
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: state.has_Pearl(player)) # bomb required
|
set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy', player), lambda state: state.has_Pearl(player)) # bomb required
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player))
|
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has_Pearl(player) and (state.has('Hammer', player) or state.can_lift_rocks(player))) # Fake Flippers
|
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has_Pearl(player) and (state.has('Hammer', player) or state.can_lift_rocks(player))) # Fake Flippers
|
||||||
set_rule(world.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: state.has_Pearl(player) and state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: state.has_Pearl(player) and state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('Hype Cave', player), lambda state: state.has_Pearl(player)) # bomb required
|
set_rule(world.get_entrance('Hype Cave', player), lambda state: state.has_Pearl(player)) # bomb required
|
||||||
set_rule(world.get_entrance('Brewery', player), lambda state: state.has_Pearl(player)) # bomb required
|
set_rule(world.get_entrance('Brewery', player), lambda state: state.has_Pearl(player)) # bomb required
|
||||||
set_rule(world.get_entrance('Thieves Town', player), lambda state: state.has_Pearl(player)) # bunny cannot pull
|
set_rule(world.get_entrance('Thieves Town', player), lambda state: state.has_Pearl(player)) # bunny cannot pull
|
||||||
set_rule(world.get_entrance('Skull Woods First Section Hole (North)', player), lambda state: state.has_Pearl(player)) # bunny cannot lift bush
|
set_rule(world.get_entrance('Skull Woods First Section Hole (North)', player), lambda state: state.has_Pearl(player)) # bunny cannot lift bush
|
||||||
set_rule(world.get_entrance('Skull Woods Second Section Hole', player), lambda state: state.has_Pearl(player)) # bunny cannot lift bush
|
set_rule(world.get_entrance('Skull Woods Second Section Hole', player), lambda state: state.has_Pearl(player)) # bunny cannot lift bush
|
||||||
set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Bombos Tablet Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Bombos Tablet Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
@@ -859,7 +865,7 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Bumper Cave Bottom to Top', player), lambda state: state.has('Cape', player))
|
set_rule(world.get_entrance('Bumper Cave Bottom to Top', player), lambda state: state.has('Cape', player))
|
||||||
set_rule(world.get_entrance('Bumper Cave Top To Bottom', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player))
|
set_rule(world.get_entrance('Bumper Cave Top To Bottom', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player) and state.has_Pearl(player)) # bunny cannot use fire rod
|
set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player) and state.has_Pearl(player)) # bunny cannot use fire rod
|
||||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!)
|
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!)
|
||||||
set_rule(world.get_entrance('Desert Ledge (Northeast) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Desert Ledge (Northeast) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
|
|
||||||
@@ -920,8 +926,8 @@ def inverted_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player))
|
set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player))
|
||||||
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player) and state.has_Pearl(player))
|
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player) and state.has_Pearl(player))
|
||||||
|
|
||||||
@@ -931,13 +937,13 @@ def inverted_rules(world, player):
|
|||||||
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and
|
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and
|
||||||
(state.has_Pearl(player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player)
|
(state.has_Pearl(player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player)
|
||||||
and state.has_Mirror(player))) # Need LW access using Mirror or Portal
|
and state.has_Mirror(player))) # Need LW access using Mirror or Portal
|
||||||
set_rule(world.get_location('Mushroom', player), lambda state: state.has_Pearl(player)) # need pearl to pick up bushes
|
set_rule(world.get_location('Mushroom', player), lambda state: state.has_Pearl(player)) # need pearl to pick up bushes
|
||||||
set_rule(world.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Bush Covered Lawn Outer Bushes', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('Bush Covered Lawn Outer Bushes', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Bomb Hut Inner Bushes', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('Bomb Hut Inner Bushes', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Bomb Hut Outer Bushes', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('Bomb Hut Outer Bushes', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Light World Bomb Hut', player), lambda state: state.has_Pearl(player)) # need bomb
|
set_rule(world.get_entrance('Light World Bomb Hut', player), lambda state: state.has_Pearl(player)) # need bomb
|
||||||
set_rule(world.get_entrance('North Fairy Cave Drop', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('North Fairy Cave Drop', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_entrance('Lost Woods Hideout Drop', player), lambda state: state.has_Pearl(player))
|
set_rule(world.get_entrance('Lost Woods Hideout Drop', player), lambda state: state.has_Pearl(player))
|
||||||
set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player) and (state.can_reach('Potion Shop Area', 'Region', player))) # new inverted region, need pearl for bushes or access to potion shop door/waterfall fairy
|
set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player) and (state.can_reach('Potion Shop Area', 'Region', player))) # new inverted region, need pearl for bushes or access to potion shop door/waterfall fairy
|
||||||
@@ -996,7 +1002,7 @@ def inverted_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (West)', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Dark Death Mountain Ledge Mirror Spot (West)', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Laser Bridge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Laser Bridge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_sword(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!)
|
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_sword(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!)
|
||||||
|
|
||||||
# new inverted spots
|
# new inverted spots
|
||||||
set_rule(world.get_entrance('Post Aga Teleporter', player), lambda state: state.has('Beat Agahnim 1', player))
|
set_rule(world.get_entrance('Post Aga Teleporter', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||||
@@ -1098,17 +1104,20 @@ def forbid_bomb_jump_requirements(world, player):
|
|||||||
add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
|
add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)
|
set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)
|
||||||
|
|
||||||
|
|
||||||
# Light cones in standard depend on which world we actually are in, not which one the location would normally be
|
# 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
|
# 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)',
|
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)']
|
'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):
|
def check_is_dark_world(region):
|
||||||
for entrance in region.entrances:
|
for entrance in region.entrances:
|
||||||
if entrance.name in DW_Entrances:
|
if entrance.name in DW_Entrances:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def add_conditional_lamps(world, player):
|
def add_conditional_lamps(world, player):
|
||||||
def add_conditional_lamp(spot, region, spottype='Location'):
|
def add_conditional_lamp(spot, region, spottype='Location'):
|
||||||
if spottype == 'Location':
|
if spottype == 'Location':
|
||||||
@@ -1180,6 +1189,7 @@ def add_conditional_lamps(world, player):
|
|||||||
|
|
||||||
add_conditional_lamp('Old Man House Front to Back', 'Old Man House', 'Entrance')
|
add_conditional_lamp('Old Man House Front to Back', 'Old Man House', 'Entrance')
|
||||||
|
|
||||||
|
|
||||||
def open_rules(world, player):
|
def open_rules(world, player):
|
||||||
# softlock protection as you can reach the sewers small key door with a guard drop key
|
# softlock protection as you can reach the sewers small key door with a guard drop key
|
||||||
set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state.has_sm_key('Small Key (Escape)', player))
|
set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state.has_sm_key('Small Key (Escape)', player))
|
||||||
@@ -1187,7 +1197,6 @@ def open_rules(world, player):
|
|||||||
|
|
||||||
|
|
||||||
def swordless_rules(world, player):
|
def swordless_rules(world, player):
|
||||||
|
|
||||||
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: True)
|
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: True)
|
||||||
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: True)
|
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: True)
|
||||||
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
||||||
@@ -1199,46 +1208,47 @@ def swordless_rules(world, player):
|
|||||||
|
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!)
|
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!)
|
||||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
||||||
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player) and state.has_Mirror(player))
|
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player) and state.has_Mirror(player))
|
||||||
else:
|
else:
|
||||||
# only need ddm access for aga tower in inverted
|
# only need ddm access for aga tower in inverted
|
||||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!)
|
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!)
|
||||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
||||||
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
||||||
|
|
||||||
|
|
||||||
std_kill_rooms = {
|
std_kill_rooms = {
|
||||||
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
||||||
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
||||||
'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots
|
'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots
|
||||||
'Desert Compass Room': ['Desert Compass NW'], # Three popos
|
'Desert Compass Room': ['Desert Compass NW'], # Three popos
|
||||||
'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos
|
'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos
|
||||||
'Hera Beetles': ['Hera Beetles WS'], # Three blue beetles and only two pots, and bombs don't work.
|
'Hera Beetles': ['Hera Beetles WS'], # Three blue beetles and only two pots, and bombs don't work.
|
||||||
'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain
|
'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain
|
||||||
'Tower Dark Archers': ['Tower Dark Archers WN'], # Not a kill room
|
'Tower Dark Archers': ['Tower Dark Archers WN'], # Not a kill room
|
||||||
'Tower Red Spears': ['Tower Red Spears WN'], # Two spear soldiers
|
'Tower Red Spears': ['Tower Red Spears WN'], # Two spear soldiers
|
||||||
'Tower Red Guards': ['Tower Red Guards EN', 'Tower Red Guards SW'], # Two usain bolts
|
'Tower Red Guards': ['Tower Red Guards EN', 'Tower Red Guards SW'], # Two usain bolts
|
||||||
'Tower Circle of Pots': ['Tower Circle of Pots NW'], # Two spear soldiers. Plenty of pots.
|
'Tower Circle of Pots': ['Tower Circle of Pots NW'], # Two spear soldiers. Plenty of pots.
|
||||||
'PoD Turtle Party': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], # Lots of turtles.
|
'PoD Turtle Party': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], # Lots of turtles.
|
||||||
'Thieves Basement Block': ['Thieves Basement Block WN'], # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
'Thieves Basement Block': ['Thieves Basement Block WN'], # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
||||||
'Ice Stalfos Hint': ['Ice Stalfos Hint SE'], # Need bombs for big stalfos knights
|
'Ice Stalfos Hint': ['Ice Stalfos Hint SE'], # Need bombs for big stalfos knights
|
||||||
'Ice Pengator Trap': ['Ice Pengator Trap NE'], # Five pengators. Bomb-doable?
|
'Ice Pengator Trap': ['Ice Pengator Trap NE'], # Five pengators. Bomb-doable?
|
||||||
'Mire 2': ['Mire 2 NE'], # Wizzrobes. Bombs dont work.
|
'Mire 2': ['Mire 2 NE'], # Wizzrobes. Bombs dont work.
|
||||||
'Mire Cross': ['Mire Cross ES'], # 4 Sluggulas. Bombs don't work
|
'Mire Cross': ['Mire Cross ES'], # 4 Sluggulas. Bombs don't work
|
||||||
'TR Twin Pokeys': ['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], # Two pokeys
|
'TR Twin Pokeys': ['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], # Two pokeys
|
||||||
'GT Petting Zoo': ['GT Petting Zoo SE'], # Dont make anyone do this room with bombs.
|
'GT Petting Zoo': ['GT Petting Zoo SE'], # Dont make anyone do this room with bombs.
|
||||||
'GT DMs Room': ['GT DMs Room SW'], # Four red stalfos
|
'GT DMs Room': ['GT DMs Room SW'], # Four red stalfos
|
||||||
'GT Gauntlet 1': ['GT Gauntlet 1 WN'], # Stalfos/zazaks
|
'GT Gauntlet 1': ['GT Gauntlet 1 WN'], # Stalfos/zazaks
|
||||||
'GT Gauntlet 2': ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], # Red stalfos
|
'GT Gauntlet 2': ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], # Red stalfos
|
||||||
'GT Gauntlet 3': ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], # Blue zazaks
|
'GT Gauntlet 3': ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], # Blue zazaks
|
||||||
'GT Gauntlet 4': ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], # Red zazaks
|
'GT Gauntlet 4': ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], # Red zazaks
|
||||||
'GT Gauntlet 5': ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], # Stalfos and zazak
|
'GT Gauntlet 5': ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], # Stalfos and zazak
|
||||||
'GT Wizzrobes 1': ['GT Wizzrobes 1 SW'], # Wizzrobes. Bombs don't work
|
'GT Wizzrobes 1': ['GT Wizzrobes 1 SW'], # Wizzrobes. Bombs don't work
|
||||||
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
||||||
} # all trap rooms?
|
} # all trap rooms?
|
||||||
|
|
||||||
|
|
||||||
def add_connection(parent_name, target_name, entrance_name, world, player):
|
def add_connection(parent_name, target_name, entrance_name, world, player):
|
||||||
parent = world.get_region(parent_name, player)
|
parent = world.get_region(parent_name, player)
|
||||||
target = world.get_region(target_name, player)
|
target = world.get_region(target_name, player)
|
||||||
@@ -1276,7 +1286,7 @@ def standard_rules(world, player):
|
|||||||
return loc.item and loc.item.name in ['Bomb Upgrade (+10)' if world.bombbag[player] else 'Bombs (10)']
|
return loc.item and loc.item.name in ['Bomb Upgrade (+10)' if world.bombbag[player] else 'Bombs (10)']
|
||||||
|
|
||||||
def standard_escape_rule(state):
|
def standard_escape_rule(state):
|
||||||
return state.can_kill_most_things(player) or bomb_escape_rule()
|
return state.can_kill_most_things(player) or bomb_escape_rule()
|
||||||
|
|
||||||
add_item_rule(world.get_location('Link\'s Uncle', player), uncle_item_rule)
|
add_item_rule(world.get_location('Link\'s Uncle', player), uncle_item_rule)
|
||||||
|
|
||||||
@@ -1300,6 +1310,7 @@ def standard_rules(world, player):
|
|||||||
|
|
||||||
def check_rule_list(state, r_list):
|
def check_rule_list(state, r_list):
|
||||||
return True if len(r_list) <= 0 else r_list[0](state) and check_rule_list(state, r_list[1:])
|
return True if len(r_list) <= 0 else r_list[0](state) and check_rule_list(state, r_list[1:])
|
||||||
|
|
||||||
rule_list, debug_path = find_rules_for_zelda_delivery(world, player)
|
rule_list, debug_path = find_rules_for_zelda_delivery(world, player)
|
||||||
set_rule(world.get_location('Zelda Drop Off', player), lambda state: state.has('Zelda Herself', player) and check_rule_list(state, rule_list))
|
set_rule(world.get_location('Zelda Drop Off', player), lambda state: state.has('Zelda Herself', player) and check_rule_list(state, rule_list))
|
||||||
|
|
||||||
@@ -1473,7 +1484,7 @@ def set_big_bomb_rules(world, player):
|
|||||||
|
|
||||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: 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('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)
|
||||||
|
|
||||||
@@ -1495,28 +1506,28 @@ def set_big_bomb_rules(world, player):
|
|||||||
# 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.has('Ocarina', 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.has('Ocarina', 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:
|
||||||
@@ -1780,7 +1791,6 @@ def set_inverted_big_bomb_rules(world, player):
|
|||||||
|
|
||||||
|
|
||||||
def set_bunny_rules(world, player, inverted):
|
def set_bunny_rules(world, player, inverted):
|
||||||
|
|
||||||
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
|
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
|
||||||
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
|
# 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 (top)', 'Bumper Cave (bottom)', 'Two Brothers House',
|
bunny_impassable_caves = ['Bumper Cave (top)', 'Bumper Cave (bottom)', 'Two Brothers House',
|
||||||
@@ -1819,13 +1829,14 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
return region.is_light_world
|
return region.is_light_world
|
||||||
else:
|
else:
|
||||||
return region.is_dark_world
|
return region.is_dark_world
|
||||||
|
|
||||||
def is_link(region):
|
def is_link(region):
|
||||||
if inverted:
|
if inverted:
|
||||||
return region.is_dark_world
|
return region.is_dark_world
|
||||||
else:
|
else:
|
||||||
return region.is_light_world
|
return region.is_light_world
|
||||||
|
|
||||||
def get_rule_to_add(region, location = None, connecting_entrance = None):
|
def get_rule_to_add(region, location=None, connecting_entrance=None):
|
||||||
# In OWG, a location can potentially be superbunny-mirror accessible or
|
# In OWG, a location can potentially be superbunny-mirror accessible or
|
||||||
# bunny revival accessible.
|
# bunny revival accessible.
|
||||||
if world.logic[player] == 'owglitches':
|
if world.logic[player] == 'owglitches':
|
||||||
@@ -1848,16 +1859,15 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
# for each such entrance a new option is added that consist of:
|
# for each such entrance a new option is added that consist of:
|
||||||
# a) being able to reach it, and
|
# a) being able to reach it, and
|
||||||
# b) being able to access all entrances from there to `region`
|
# b) being able to access all entrances from there to `region`
|
||||||
seen = {region}
|
queue = deque([(region, [], {region})])
|
||||||
queue = deque([(region, [])])
|
|
||||||
while queue:
|
while queue:
|
||||||
(current, path) = queue.popleft()
|
(current, path, seen) = queue.popleft()
|
||||||
for entrance in current.entrances:
|
for entrance in current.entrances:
|
||||||
new_region = entrance.parent_region
|
new_region = entrance.parent_region
|
||||||
if new_region.type in (RegionType.Cave, RegionType.Dungeon) and new_region in seen:
|
if new_region.type in (RegionType.Cave, RegionType.Dungeon) and new_region in seen:
|
||||||
continue
|
continue
|
||||||
new_path = path + [entrance.access_rule]
|
new_path = path + [entrance.access_rule]
|
||||||
seen.add(new_region)
|
new_seen = seen.union({new_region})
|
||||||
if not is_link(new_region):
|
if not is_link(new_region):
|
||||||
if world.logic[player] == 'owglitches':
|
if world.logic[player] == 'owglitches':
|
||||||
if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon:
|
if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon:
|
||||||
@@ -1894,7 +1904,7 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
if is_bunny(new_region):
|
if is_bunny(new_region):
|
||||||
queue.append((new_region, new_path))
|
queue.append((new_region, new_path, new_seen))
|
||||||
else:
|
else:
|
||||||
# we have reached pure light world, so we have a new possible option
|
# we have reached pure light world, so we have a new possible option
|
||||||
possible_options.append(path_to_access_rule(new_path, entrance))
|
possible_options.append(path_to_access_rule(new_path, entrance))
|
||||||
@@ -1941,7 +1951,6 @@ drop_dungeon_entrances = {
|
|||||||
"Skull Back Drop"
|
"Skull Back Drop"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bunny_revivable_entrances = {
|
bunny_revivable_entrances = {
|
||||||
"Sewers Pull Switch", "TR Dash Room", "Swamp Boss", "Hera Boss",
|
"Sewers Pull Switch", "TR Dash Room", "Swamp Boss", "Hera Boss",
|
||||||
"Tower Agahnim 1", "Ice Lobby", "Sewers Rat Path", "PoD Falling Bridge",
|
"Tower Agahnim 1", "Ice Lobby", "Sewers Rat Path", "PoD Falling Bridge",
|
||||||
@@ -1989,7 +1998,7 @@ bunny_impassible_doors = {
|
|||||||
'Eastern Darkness S', 'Eastern Darkness NE', 'Eastern Darkness Up Stairs',
|
'Eastern Darkness S', 'Eastern Darkness NE', 'Eastern Darkness Up Stairs',
|
||||||
'Eastern Attic Start WS', 'Eastern Single Eyegore NE', 'Eastern Duo Eyegores NE', 'Desert Main Lobby Left Path',
|
'Eastern Attic Start WS', 'Eastern Single Eyegore NE', 'Eastern Duo Eyegores NE', 'Desert Main Lobby Left Path',
|
||||||
'Desert Main Lobby Right Path', 'Desert Left Alcove Path', 'Desert Right Alcove Path', 'Desert Compass NW',
|
'Desert Main Lobby Right Path', 'Desert Left Alcove Path', 'Desert Right Alcove Path', 'Desert Compass NW',
|
||||||
'Desert West Lobby NW', 'Desert Back Lobby NW', 'Desert Four Statues NW', 'Desert Four Statues ES',
|
'Desert West Lobby NW', 'Desert Back Lobby NW', 'Desert Four Statues NW', 'Desert Four Statues ES',
|
||||||
'Desert Beamos Hall WS', 'Desert Beamos Hall NE', 'Desert Wall Slide NW',
|
'Desert Beamos Hall WS', 'Desert Beamos Hall NE', 'Desert Wall Slide NW',
|
||||||
'Hera Lobby to Front Barrier - Blue', 'Hera Front to Lobby Barrier - Blue', 'Hera Front to Down Stairs Barrier - Blue',
|
'Hera Lobby to Front Barrier - Blue', 'Hera Front to Lobby Barrier - Blue', 'Hera Front to Down Stairs Barrier - Blue',
|
||||||
'Hera Down Stairs to Front Barrier - Blue', 'Hera Tile Room EN', 'Hera Tridorm SE', 'Hera Beetles WS',
|
'Hera Down Stairs to Front Barrier - Blue', 'Hera Tile Room EN', 'Hera Tridorm SE', 'Hera Beetles WS',
|
||||||
@@ -2001,14 +2010,14 @@ bunny_impassible_doors = {
|
|||||||
'PoD Arena Landing Bonk Path', 'PoD Sexy Statue NW', 'PoD Map Balcony Drop Down',
|
'PoD Arena Landing Bonk Path', 'PoD Sexy Statue NW', 'PoD Map Balcony Drop Down',
|
||||||
'PoD Mimics 1 NW', 'PoD Falling Bridge Path N', 'PoD Falling Bridge Path S',
|
'PoD Mimics 1 NW', 'PoD Falling Bridge Path N', 'PoD Falling Bridge Path S',
|
||||||
'PoD Mimics 2 NW', 'PoD Bow Statue Down Ladder', 'PoD Dark Pegs Landing to Right',
|
'PoD Mimics 2 NW', 'PoD Bow Statue Down Ladder', 'PoD Dark Pegs Landing to Right',
|
||||||
'PoD Dark Pegs Left to Middle Barrier - Blue', 'PoD Dark Pegs Left to Ranged Crystal',
|
'PoD Dark Pegs Left to Middle Barrier - Blue', 'PoD Dark Pegs Left to Ranged Crystal',
|
||||||
'PoD Turtle Party ES', 'PoD Turtle Party NW', 'PoD Callback Warp', 'Swamp Lobby Moat', 'Swamp Entrance Moat',
|
'PoD Turtle Party ES', 'PoD Turtle Party NW', 'PoD Callback Warp', 'Swamp Lobby Moat', 'Swamp Entrance Moat',
|
||||||
'Swamp Trench 1 Approach Swim Depart', 'Swamp Trench 1 Approach Key', 'Swamp Trench 1 Key Approach',
|
'Swamp Trench 1 Approach Swim Depart', 'Swamp Trench 1 Approach Key', 'Swamp Trench 1 Key Approach',
|
||||||
'Swamp Trench 1 Key Ledge Depart', 'Swamp Trench 1 Departure Approach', 'Swamp Trench 1 Departure Key',
|
'Swamp Trench 1 Key Ledge Depart', 'Swamp Trench 1 Departure Approach', 'Swamp Trench 1 Departure Key',
|
||||||
'Swamp Hub Hook Path', 'Swamp Shortcut Blue Barrier', 'Swamp Trench 2 Pots Blue Barrier',
|
'Swamp Hub Hook Path', 'Swamp Shortcut Blue Barrier', 'Swamp Trench 2 Pots Blue Barrier',
|
||||||
'Swamp Trench 2 Pots Wet', 'Swamp Trench 2 Departure Wet', 'Swamp West Ledge Hook Path', 'Swamp Barrier Ledge Hook Path',
|
'Swamp Trench 2 Pots Wet', 'Swamp Trench 2 Departure Wet', 'Swamp West Ledge Hook Path', 'Swamp Barrier Ledge Hook Path',
|
||||||
'Swamp Attic Left Pit', 'Swamp Attic Right Pit', 'Swamp Push Statue NW', 'Swamp Push Statue NE',
|
'Swamp Attic Left Pit', 'Swamp Attic Right Pit', 'Swamp Push Statue NW', 'Swamp Push Statue NE',
|
||||||
'Swamp Drain Right Switch', 'Swamp Waterway NE', 'Swamp Waterway N', 'Swamp Waterway NW',
|
'Swamp Drain Right Switch', 'Swamp Waterway NE', 'Swamp Waterway N', 'Swamp Waterway NW',
|
||||||
'Skull Pot Circle WN', 'Skull Pot Circle Star Path', 'Skull Pull Switch S', 'Skull Big Chest N',
|
'Skull Pot Circle WN', 'Skull Pot Circle Star Path', 'Skull Pull Switch S', 'Skull Big Chest N',
|
||||||
'Skull Big Chest Hookpath', 'Skull 2 East Lobby NW', 'Skull Back Drop Star Path', 'Skull 2 West Lobby NW',
|
'Skull Big Chest Hookpath', 'Skull 2 East Lobby NW', 'Skull Back Drop Star Path', 'Skull 2 West Lobby NW',
|
||||||
'Skull 3 Lobby EN', 'Skull Star Pits SW', 'Skull Star Pits ES', 'Skull Torch Room WN', 'Skull Vines NW',
|
'Skull 3 Lobby EN', 'Skull Star Pits SW', 'Skull Star Pits ES', 'Skull Torch Room WN', 'Skull Vines NW',
|
||||||
@@ -2043,7 +2052,7 @@ bunny_impassible_doors = {
|
|||||||
'GT Double Switch Exit to Blue Barrier', 'GT Firesnake Room Hook Path', 'GT Falling Bridge WN', 'GT Falling Bridge WS',
|
'GT Double Switch Exit to Blue Barrier', 'GT Firesnake Room Hook Path', 'GT Falling Bridge WN', 'GT Falling Bridge WS',
|
||||||
'GT Ice Armos NE', 'GT Ice Armos WS', 'GT Crystal Paths SW', 'GT Mimics 1 NW', 'GT Mimics 1 ES', 'GT Mimics 2 WS',
|
'GT Ice Armos NE', 'GT Ice Armos WS', 'GT Crystal Paths SW', 'GT Mimics 1 NW', 'GT Mimics 1 ES', 'GT Mimics 2 WS',
|
||||||
'GT Mimics 2 NE', 'GT Hidden Spikes EN', 'GT Cannonball Bridge SE', 'GT Gauntlet 1 WN', 'GT Gauntlet 2 EN',
|
'GT Mimics 2 NE', 'GT Hidden Spikes EN', 'GT Cannonball Bridge SE', 'GT Gauntlet 1 WN', 'GT Gauntlet 2 EN',
|
||||||
'GT Gauntlet 2 SW', 'GT Gauntlet 3 NW', 'GT Gauntlet 3 SW', 'GT Gauntlet 4 NW', 'GT Gauntlet 4 SW',
|
'GT Gauntlet 2 SW', 'GT Gauntlet 3 NW', 'GT Gauntlet 3 SW', 'GT Gauntlet 4 NW', 'GT Gauntlet 4 SW',
|
||||||
'GT Gauntlet 5 NW', 'GT Gauntlet 5 WS', 'GT Lanmolas 2 ES', 'GT Lanmolas 2 NW', 'GT Wizzrobes 1 SW',
|
'GT Gauntlet 5 NW', 'GT Gauntlet 5 WS', 'GT Lanmolas 2 ES', 'GT Lanmolas 2 NW', 'GT Wizzrobes 1 SW',
|
||||||
'GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE', 'GT Torch Cross ES', 'GT Falling Torches NE', 'GT Moldorm Gap',
|
'GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE', 'GT Torch Cross ES', 'GT Falling Torches NE', 'GT Moldorm Gap',
|
||||||
'GT Validation Block Path'
|
'GT Validation Block Path'
|
||||||
@@ -2091,7 +2100,7 @@ def eval_small_key_door_main(state, door_name, dungeon, player):
|
|||||||
door_openable |= state.has_sm_key(key_logic.small_key_name, player, number)
|
door_openable |= state.has_sm_key(key_logic.small_key_name, player, number)
|
||||||
elif ruleType == KeyRuleType.AllowSmall:
|
elif ruleType == KeyRuleType.AllowSmall:
|
||||||
if (door_rule.small_location.item and door_rule.small_location.item.name == key_logic.small_key_name
|
if (door_rule.small_location.item and door_rule.small_location.item.name == key_logic.small_key_name
|
||||||
and door_rule.small_location.item.player == player):
|
and door_rule.small_location.item.player == player):
|
||||||
return True # always okay if allow small is on
|
return True # always okay if allow small is on
|
||||||
elif isinstance(ruleType, tuple):
|
elif isinstance(ruleType, tuple):
|
||||||
lock, lock_item = ruleType
|
lock, lock_item = ruleType
|
||||||
@@ -2126,7 +2135,7 @@ def create_key_rule(small_key_name, player, keys):
|
|||||||
|
|
||||||
def create_key_rule_allow_small(small_key_name, player, keys, location):
|
def create_key_rule_allow_small(small_key_name, player, keys, location):
|
||||||
loc = location.name
|
loc = location.name
|
||||||
return lambda state: state.has_sm_key(small_key_name, player, keys) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys-1))
|
return lambda state: state.has_sm_key(small_key_name, player, keys) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys - 1))
|
||||||
|
|
||||||
|
|
||||||
def create_key_rule_bk_exception(small_key_name, big_key_name, player, keys, bk_keys, bk_locs):
|
def create_key_rule_bk_exception(small_key_name, big_key_name, player, keys, bk_keys, bk_locs):
|
||||||
@@ -2137,7 +2146,7 @@ def create_key_rule_bk_exception(small_key_name, big_key_name, player, keys, bk_
|
|||||||
def create_key_rule_bk_exception_or_allow(small_key_name, big_key_name, player, keys, location, bk_keys, bk_locs):
|
def create_key_rule_bk_exception_or_allow(small_key_name, big_key_name, player, keys, location, bk_keys, bk_locs):
|
||||||
loc = location.name
|
loc = location.name
|
||||||
chest_names = [x.name for x in bk_locs]
|
chest_names = [x.name for x in bk_locs]
|
||||||
return lambda state: (state.has_sm_key(small_key_name, player, keys) and not item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names)))) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys-1)) or (item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names))) and state.has_sm_key(small_key_name, player, bk_keys))
|
return lambda state: (state.has_sm_key(small_key_name, player, keys) and not item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names)))) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys - 1)) or (item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names))) and state.has_sm_key(small_key_name, player, bk_keys))
|
||||||
|
|
||||||
|
|
||||||
def create_advanced_key_rule(key_logic, player, rule):
|
def create_advanced_key_rule(key_logic, player, rule):
|
||||||
|
|||||||
Reference in New Issue
Block a user