Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -1581,15 +1581,71 @@ class Entrance(object):
|
||||
self.player = player
|
||||
self.door = None
|
||||
self.hide_path = False
|
||||
self.temp_path = []
|
||||
|
||||
def can_reach(self, state):
|
||||
if self.parent_region.can_reach(state) and self.access_rule(state):
|
||||
if not self.hide_path and not self in state.path:
|
||||
state.path[self] = (self.name, state.path.get(self.parent_region, (self.parent_region.name, None)))
|
||||
return True
|
||||
# Destination Pickup OW Only No Ledges Can S&Q
|
||||
multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False),
|
||||
'Missing Smith': ('Frog', True, False, True),
|
||||
'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True) }
|
||||
|
||||
if self.name in multi_step_locations:
|
||||
if self not in state.path:
|
||||
world = self.parent_region.world if self.parent_region else None
|
||||
step_location = world.get_location(multi_step_locations[self.name][0], self.player)
|
||||
if step_location.can_reach(state) and self.can_reach_thru(state, step_location.parent_region, multi_step_locations[self.name][1], multi_step_locations[self.name][2], multi_step_locations[self.name][3]) and self.access_rule(state):
|
||||
if not self in state.path:
|
||||
path = state.path.get(step_location.parent_region, (step_location.parent_region.name, None))
|
||||
item_name = step_location.item.name if step_location.item else 'Pick Up Item'
|
||||
path = (f'{step_location.parent_region.name} Exit', (item_name, path))
|
||||
while len(self.temp_path):
|
||||
exit = self.temp_path.pop(0)
|
||||
path = (exit.name, (exit.parent_region.name, path))
|
||||
item_name = self.connected_region.locations[0].item.name if self.connected_region.locations[0].item else 'Deliver Item'
|
||||
path = (item_name, (self.parent_region.name, path))
|
||||
state.path[self] = (self.name, path)
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
if self.parent_region.can_reach(state) and self.access_rule(state):
|
||||
if not self.hide_path and not self in state.path:
|
||||
state.path[self] = (self.name, state.path.get(self.parent_region, (self.parent_region.name, None)))
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def can_reach_thru(self, state, start_region, ignore_underworld=False, ignore_ledges=False, allow_save_quit=False):
|
||||
def explore_region(region, path = []):
|
||||
nonlocal found
|
||||
if region not in explored_regions or len(explored_regions[region]) > len(path):
|
||||
explored_regions[region] = path
|
||||
for exit in region.exits:
|
||||
if exit.connected_region and (not ignore_ledges or exit.spot_type != 'Ledge') \
|
||||
and exit.connected_region.name not in ['Dig Game Area'] \
|
||||
and exit.access_rule(state):
|
||||
if exit.connected_region == self.parent_region:
|
||||
found = True
|
||||
explored_regions[self.parent_region] = path + [exit]
|
||||
elif not ignore_underworld or region.type == exit.connected_region.type or exit.connected_region.type not in [RegionType.Cave, RegionType.Dungeon]:
|
||||
explore_region(exit.connected_region, path + [exit])
|
||||
|
||||
found = False
|
||||
explored_regions = {}
|
||||
explore_region(start_region.entrances[0].parent_region)
|
||||
if found:
|
||||
self.temp_path = explored_regions[self.parent_region]
|
||||
elif allow_save_quit:
|
||||
world = self.parent_region.world if self.parent_region else None
|
||||
exit = world.get_entrance('Links House S&Q', self.player)
|
||||
explore_region(exit.connected_region, [exit])
|
||||
if found:
|
||||
self.temp_path = explored_regions[self.parent_region]
|
||||
|
||||
#TODO: Implement residual mirror portal placing for the previous leg, to be used for the final destination
|
||||
|
||||
return found
|
||||
|
||||
def connect(self, region, addresses=None, target=None, vanilla=None):
|
||||
self.connected_region = region
|
||||
self.target = target
|
||||
@@ -2851,7 +2907,7 @@ class Spoiler(object):
|
||||
|
||||
outfile.write('\n\nBottle Refills:\n\n')
|
||||
for fairy, bottle in self.bottles.items():
|
||||
outfile.write(f'\n{fairy}: {bottle}')
|
||||
outfile.write(f'{fairy}: {bottle}\n')
|
||||
|
||||
if self.overworlds:
|
||||
# overworlds: overworld transitions;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
### 0.2.2.0
|
||||
- Delivering Big Red Bomb is now in logic
|
||||
- Smith/Purple Chest have proper dynamic pathing to fix logical issues
|
||||
- Fixed issue with bomb walls in OW not requiring moon pearl in DW
|
||||
|
||||
### 0.2.1.3
|
||||
- New fake flipper handling to allow S+Q rather than insta-kill
|
||||
- Fixed whirlpools in Crossed OW
|
||||
|
||||
@@ -557,10 +557,10 @@ def link_entrances(world, player):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
pool.remove(bomb_shop)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
|
||||
# shuffle connectors
|
||||
pool = [e for e in pool if e in entrance_pool]
|
||||
connect_caves(world, pool, [], caves, player)
|
||||
|
||||
# place remaining doors
|
||||
@@ -2184,6 +2184,7 @@ mandatory_connections = [('Links House S&Q', 'Links House'),
|
||||
('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'),
|
||||
('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'),
|
||||
('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'),
|
||||
('Missing Smith', 'Missing Smith'),
|
||||
('Superbunny Cave Climb', 'Superbunny Cave (Top)'),
|
||||
('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'),
|
||||
('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'),
|
||||
|
||||
@@ -214,6 +214,9 @@ def generate_itempool(world, player):
|
||||
world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False)
|
||||
world.get_location('Dark Blacksmith Ruins', player).event = True
|
||||
world.get_location('Dark Blacksmith Ruins', player).locked = True
|
||||
world.push_item(world.get_location('Middle Aged Man', player), ItemFactory('Deliver Purple Chest', player), False)
|
||||
world.get_location('Middle Aged Man', player).event = True
|
||||
world.get_location('Middle Aged Man', player).locked = True
|
||||
world.push_item(world.get_location('Frog', player), ItemFactory('Get Frog', player), False)
|
||||
world.get_location('Frog', player).event = True
|
||||
world.get_location('Frog', player).locked = True
|
||||
@@ -223,6 +226,12 @@ def generate_itempool(world, player):
|
||||
world.push_item(world.get_location('Floodgate', player), ItemFactory('Open Floodgate', player), False)
|
||||
world.get_location('Floodgate', player).event = True
|
||||
world.get_location('Floodgate', player).locked = True
|
||||
world.push_item(world.get_location('Big Bomb', player), ItemFactory('Pick Up Big Bomb', player), False)
|
||||
world.get_location('Big Bomb', player).event = True
|
||||
world.get_location('Big Bomb', player).locked = True
|
||||
world.push_item(world.get_location('Pyramid Crack', player), ItemFactory('Detonate Big Bomb', player), False)
|
||||
world.get_location('Pyramid Crack', player).event = True
|
||||
world.get_location('Pyramid Crack', player).locked = True
|
||||
world.push_item(world.get_location('Trench 1 Switch', player), ItemFactory('Trench 1 Filled', player), False)
|
||||
world.get_location('Trench 1 Switch', player).event = True
|
||||
world.get_location('Trench 1 Switch', player).locked = True
|
||||
|
||||
3
Items.py
3
Items.py
@@ -176,7 +176,10 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Get Frog': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Return Smith': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Pick Up Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Deliver Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Open Floodgate': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Pick Up Big Bomb': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Detonate Big Bomb': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Trench 1 Filled': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Trench 2 Filled': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
'Drained Swamp': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||
|
||||
2
Main.py
2
Main.py
@@ -567,7 +567,7 @@ def create_playthrough(world):
|
||||
|
||||
# get locations containing progress items
|
||||
prog_locations = [location for location in world.get_filled_locations() if location.item.advancement]
|
||||
optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop']
|
||||
optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop', 'Big Bomb']
|
||||
state_cache = [None]
|
||||
collection_spheres = []
|
||||
state = CollectionState(world)
|
||||
|
||||
25
OWEdges.py
25
OWEdges.py
@@ -820,6 +820,7 @@ OWTileRegions = bidict({
|
||||
'Ice Cave Area': 0x37,
|
||||
|
||||
'Desert Pass Area': 0x3a,
|
||||
'Middle Aged Man': 0x3a,
|
||||
'Desert Pass Southeast': 0x3a,
|
||||
'Desert Pass Ledge': 0x3a,
|
||||
|
||||
@@ -891,6 +892,7 @@ OWTileRegions = bidict({
|
||||
'Shield Shop Fence': 0x5a,
|
||||
|
||||
'Pyramid Area': 0x5b,
|
||||
'Pyramid Crack': 0x5b,
|
||||
'Pyramid Exit Ledge': 0x5b,
|
||||
'Pyramid Pass': 0x5b,
|
||||
|
||||
@@ -1403,8 +1405,6 @@ OWExitTypes = {
|
||||
'Zora Waterfall Water Drop',
|
||||
'Bonk Rock Ledge Drop',
|
||||
'Graveyard Ledge Drop',
|
||||
'River Bend Water Drop',
|
||||
'River Bend East Water Drop',
|
||||
'Potion Shop Water Drop',
|
||||
'Potion Shop Northeast Water Drop',
|
||||
'Zora Approach Bottom Ledge Drop',
|
||||
@@ -1444,13 +1444,9 @@ OWExitTypes = {
|
||||
'Dam Cliff Ledge Drop',
|
||||
'Bombos Tablet Drop',
|
||||
'Cave 45 Ledge Drop',
|
||||
'Lake Hylia Water Drop',
|
||||
'Lake Hylia South Water Drop',
|
||||
'Lake Hylia Northeast Water Drop',
|
||||
'Lake Hylia Central Water Drop',
|
||||
'Lake Hylia Island Water Drop',
|
||||
'Desert Pass Ledge Drop',
|
||||
'Octoballoon Water Drop',
|
||||
'Octoballoon Waterfall Water Drop',
|
||||
'Dark Death Mountain Drop (West)',
|
||||
'Dark Death Mountain Drop (East)',
|
||||
@@ -1460,7 +1456,6 @@ OWExitTypes = {
|
||||
'Bumper Cave Ledge Drop',
|
||||
'Bumper Cave Entrance Drop',
|
||||
'Qirn Jump Water Drop',
|
||||
'Qirn Jump East Water Drop',
|
||||
'Dark Witch Water Drop',
|
||||
'Dark Witch Northeast Water Drop',
|
||||
'Catfish Approach Bottom Ledge Drop',
|
||||
@@ -1483,6 +1478,8 @@ OWExitTypes = {
|
||||
'Dark Bonk Rocks Cliff Ledge Drop',
|
||||
'Bomb Shop Cliff Ledge Drop',
|
||||
'Hammer Bridge South Cliff Ledge Drop',
|
||||
'Ice Lake Northeast Pier Hop',
|
||||
'Ice Lake Moat Bomb Jump',
|
||||
'Ice Lake Area Cliff Ledge Drop',
|
||||
'Ice Palace Island FAWT Ledge Drop',
|
||||
'Hammer Bridge EC Cliff Water Drop',
|
||||
@@ -1499,10 +1496,8 @@ OWExitTypes = {
|
||||
'Swamp Nook Cliff Ledge Drop',
|
||||
'Swamp Cliff Ledge Drop',
|
||||
'Ice Lake Water Drop',
|
||||
'Ice Lake Northeast Water Drop',
|
||||
'Ice Lake Southwest Water Drop',
|
||||
'Ice Lake Southeast Water Drop',
|
||||
'Bomber Corner Water Drop',
|
||||
'Bomber Corner Waterfall Water Drop'
|
||||
],
|
||||
'OWTerrain': ['Lost Woods Bush (West)',
|
||||
@@ -1528,7 +1523,9 @@ OWExitTypes = {
|
||||
'Graveyard Ladder (Bottom)',
|
||||
'Graveyard Ladder (Top)',
|
||||
'Kings Grave Inner Rocks',
|
||||
'River Bend Water Drop',
|
||||
'River Bend West Pier',
|
||||
'River Bend East Water Drop',
|
||||
'River Bend East Pier',
|
||||
'Potion Shop Rock (South)',
|
||||
'Potion Shop Rock (North)',
|
||||
@@ -1566,14 +1563,19 @@ OWExitTypes = {
|
||||
'C Whirlpool Rock (Top)',
|
||||
'Statues Water Entry',
|
||||
'Statues Landing',
|
||||
'Lake Hylia Central Water Drop',
|
||||
'Lake Hylia Central Island Pier',
|
||||
'Lake Hylia Island Pier',
|
||||
'Lake Hylia Water Drop',
|
||||
'Lake Hylia West Pier',
|
||||
'Lake Hylia Northeast Water Drop',
|
||||
'Lake Hylia East Pier',
|
||||
'Desert Pass Ladder (South)',
|
||||
'Desert Pass Rocks (North)',
|
||||
'Desert Pass Rocks (South)',
|
||||
'Desert Pass Ladder (North)',
|
||||
'Middle Aged Man',
|
||||
'Octoballoon Water Drop',
|
||||
'Octoballoon Pier',
|
||||
'Skull Woods Bush Rock (East)',
|
||||
'Skull Woods Bush Rock (West)',
|
||||
@@ -1590,6 +1592,7 @@ OWExitTypes = {
|
||||
'Skull Woods Pass Rock (Bottom)',
|
||||
'Dark Graveyard Bush (South)',
|
||||
'Dark Graveyard Bush (North)',
|
||||
'Qirn Jump East Water Drop',
|
||||
'Qirn Jump Pier',
|
||||
'Dark Witch Rock (South)',
|
||||
'Dark Witch Rock (North)',
|
||||
@@ -1597,6 +1600,7 @@ OWExitTypes = {
|
||||
'Catfish Approach Rocks (East)',
|
||||
'Village of Outcasts Pegs',
|
||||
'Grassy Lawn Pegs',
|
||||
'Pyramid Crack',
|
||||
'Broken Bridge Hammer Rock (South)',
|
||||
'Broken Bridge Hammer Rock (North)',
|
||||
'Broken Bridge Hookshot Gap',
|
||||
@@ -1617,11 +1621,12 @@ OWExitTypes = {
|
||||
'Dark C Whirlpool Rock (Top)',
|
||||
'Hype Cave Water Entry',
|
||||
'Hype Cave Landing',
|
||||
'Ice Lake Northeast Water Drop',
|
||||
'Ice Lake Northeast Pier',
|
||||
'Ice Lake Moat Water Entry',
|
||||
'Ice Lake Northeast Pier Bomb Jump',
|
||||
'Ice Palace Approach',
|
||||
'Ice Palace Leave',
|
||||
'Bomber Corner Water Drop',
|
||||
'Bomber Corner Pier'
|
||||
],
|
||||
'Portal': ['West Death Mountain Teleporter',
|
||||
|
||||
@@ -3,7 +3,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl
|
||||
from Regions import mark_dark_world_regions, mark_light_world_regions
|
||||
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
|
||||
|
||||
__version__ = '0.2.1.3-u'
|
||||
__version__ = '0.2.2.0-u'
|
||||
|
||||
def link_overworld(world, player):
|
||||
# setup mandatory connections
|
||||
@@ -902,6 +902,7 @@ mandatory_connections = [# Intra-tile OW Connections
|
||||
('Desert Pass Ledge Drop', 'Desert Pass Area'),
|
||||
('Desert Pass Rocks (North)', 'Desert Pass Southeast'), #glove
|
||||
('Desert Pass Rocks (South)', 'Desert Pass Area'), #glove
|
||||
('Middle Aged Man', 'Middle Aged Man'),
|
||||
('Octoballoon Water Drop', 'Octoballoon Water'), #flippers
|
||||
('Octoballoon Waterfall Water Drop', 'Octoballoon Water'), #flippers
|
||||
('Octoballoon Pier', 'Octoballoon Area'),
|
||||
@@ -942,6 +943,7 @@ mandatory_connections = [# Intra-tile OW Connections
|
||||
('Shield Shop Fence (Outer) Ledge Drop', 'Shield Shop Fence'),
|
||||
('Shield Shop Fence (Inner) Ledge Drop', 'Shield Shop Area'),
|
||||
('Pyramid Exit Ledge Drop', 'Pyramid Area'),
|
||||
('Pyramid Crack', 'Pyramid Crack'),
|
||||
('Broken Bridge Hammer Rock (South)', 'Broken Bridge Northeast'), #hammer/glove
|
||||
('Broken Bridge Hammer Rock (North)', 'Broken Bridge Area'), #hammer/glove
|
||||
('Broken Bridge Hookshot Gap', 'Broken Bridge West'), #hookshot
|
||||
@@ -1023,7 +1025,8 @@ mandatory_connections = [# Intra-tile OW Connections
|
||||
('Dark Bonk Rocks Cliff Ledge Drop', 'Dark Bonk Rocks Area'),
|
||||
('Hammer Bridge South Cliff Ledge Drop', 'Hammer Bridge South Area'),
|
||||
('Ice Lake Area Cliff Ledge Drop', 'Ice Lake Area'),
|
||||
('Ice Lake Northeast Pier Bomb Jump', 'Ice Lake Northeast Bank'),
|
||||
('Ice Lake Northeast Pier Hop', 'Ice Lake Northeast Bank'),
|
||||
('Ice Lake Moat Bomb Jump', 'Ice Lake Moat'),
|
||||
('Dark C Whirlpool Cliff Ledge Drop', 'Dark C Whirlpool Area'),
|
||||
('Dark C Whirlpool Outer Cliff Ledge Drop', 'Dark C Whirlpool Outer Area'),
|
||||
('Hype Cliff Ledge Drop', 'Hype Cave Area'),
|
||||
|
||||
18
Regions.py
18
Regions.py
@@ -111,7 +111,8 @@ def create_regions(world, player):
|
||||
create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']),
|
||||
create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], Terrain.Water),
|
||||
create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']),
|
||||
create_lw_region(player, 'Desert Pass Area', ['Purple Chest'], ['Desert Pass Ladder (South)', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']),
|
||||
create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']),
|
||||
create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None),
|
||||
create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Swamp Nook Southeast Mirror Spot', 'Desert Pass ES']),
|
||||
create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Swamp Nook Pegs Mirror Spot', 'Desert Pass WC']),
|
||||
create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Swamp Mirror Spot', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']),
|
||||
@@ -163,7 +164,8 @@ def create_regions(world, player):
|
||||
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Kakariko Grass Mirror Spot']),
|
||||
create_dw_region(player, 'Shield Shop Area', None, ['Shield Shop Fence (Outer) Ledge Drop', 'Forgotton Forest Mirror Spot', 'Shield Shop NW', 'Shield Shop NE']),
|
||||
create_dw_region(player, 'Shield Shop Fence', None, ['Shield Shop Fence (Inner) Ledge Drop', 'Red Shield Shop', 'Forgotton Forest Fence Mirror Spot']),
|
||||
create_dw_region(player, 'Pyramid Area', ['Pyramid'], ['Pyramid Fairy', 'Pyramid Hole', 'HC Ledge Mirror Spot', 'HC Courtyard Mirror Spot', 'HC Area Mirror Spot', 'HC East Entry Mirror Spot', 'Pyramid ES']),
|
||||
create_dw_region(player, 'Pyramid Area', ['Pyramid'], ['Pyramid Fairy', 'Pyramid Crack', 'Pyramid Hole', 'HC Ledge Mirror Spot', 'HC Courtyard Mirror Spot', 'HC Area Mirror Spot', 'HC East Entry Mirror Spot', 'Pyramid ES']),
|
||||
create_dw_region(player, 'Pyramid Crack', ['Pyramid Crack'], None),
|
||||
create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'HC Courtyard Left Mirror Spot', 'Pyramid Entrance']),
|
||||
create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'HC Area South Mirror Spot', 'Pyramid SW', 'Pyramid SE']),
|
||||
create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Wooden Bridge Mirror Spot', 'Broken Bridge SW']),
|
||||
@@ -206,8 +208,8 @@ def create_regions(world, player):
|
||||
create_dw_region(player, 'Ice Lake Northeast Bank', None, ['Ice Lake Northeast Water Drop', 'Lake Hylia Northeast Mirror Spot', 'Ice Lake NE']),
|
||||
create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']),
|
||||
create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']),
|
||||
create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], Terrain.Water),
|
||||
create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Bomb Jump', 'Ice Palace Approach', 'Lake Hylia Water Mirror Spot']),
|
||||
create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], Terrain.Water),
|
||||
create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Ice Palace Approach', 'Lake Hylia Water Mirror Spot']),
|
||||
create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace Leave', 'Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']),
|
||||
create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']),
|
||||
create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']),
|
||||
@@ -268,7 +270,8 @@ def create_regions(world, player):
|
||||
create_cave_region(player, 'Tavern (Front)', 'the tavern'),
|
||||
create_cave_region(player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']),
|
||||
create_cave_region(player, 'Sahasrahlas Hut', 'Sahasrahla', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']),
|
||||
create_cave_region(player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']),
|
||||
create_cave_region(player, 'Blacksmiths Hut', 'the smith', ['Blacksmith'], ['Missing Smith']),
|
||||
create_cave_region(player, 'Missing Smith', None, ['Missing Smith']),
|
||||
create_cave_region(player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']),
|
||||
create_cave_region(player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']),
|
||||
create_cave_region(player, 'Two Brothers House', 'a connector', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']),
|
||||
@@ -321,7 +324,7 @@ def create_regions(world, player):
|
||||
create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']),
|
||||
create_cave_region(player, 'Archery Game', 'a game of skill'),
|
||||
create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'),
|
||||
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop'),
|
||||
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb']),
|
||||
create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'),
|
||||
create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
|
||||
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
|
||||
@@ -1488,6 +1491,9 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'),
|
||||
'Frog': (None, None, False, None),
|
||||
'Missing Smith': (None, None, False, None),
|
||||
'Dark Blacksmith Ruins': (None, None, False, None),
|
||||
'Big Bomb': (None, None, False, None),
|
||||
'Pyramid Crack': (None, None, False, None),
|
||||
'Middle Aged Man': (None, None, False, None),
|
||||
'Trench 1 Switch': (None, None, False, None),
|
||||
'Trench 2 Switch': (None, None, False, None),
|
||||
'Swamp Drain': (None, None, False, None),
|
||||
|
||||
472
Rules.py
472
Rules.py
@@ -58,15 +58,6 @@ def set_rules(world, player):
|
||||
elif world.goal[player] == 'triforcehunt':
|
||||
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||
|
||||
if world.mode[player] != 'inverted':
|
||||
set_big_bomb_rules(world, player)
|
||||
if world.logic[player] == 'owglitches' and world.shuffle[player] not in ('insanity', 'insanity_legacy'):
|
||||
path_to_hc = mirrorless_path_to_location(world, 'West Death Mountain (Bottom)', 'Hyrule Castle Area', player)
|
||||
path_to_courtyard = mirrorless_path_to_castle_courtyard(world, player)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.world.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard) and all(rule(state) for rule in path_to_hc), 'or')
|
||||
else:
|
||||
set_inverted_big_bomb_rules(world, player)
|
||||
|
||||
# if swamp and dam have not been moved we require mirror for swamp palace
|
||||
if not world.swamp_patch_required[player]:
|
||||
add_rule(world.get_entrance('Swamp Lobby Moat', player), lambda state: state.has_Mirror(player))
|
||||
@@ -192,11 +183,14 @@ def global_rules(world, player):
|
||||
|
||||
set_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player))
|
||||
set_rule(world.get_location('Dark Blacksmith Ruins', player), lambda state: state.has('Return Smith', player))
|
||||
set_rule(world.get_location('Purple Chest', player), lambda state: state.has('Pick Up Purple Chest', player)) # Can S&Q with chest
|
||||
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('Middle Aged Man', player), lambda state: state.has('Pick Up Purple Chest', player)) # Can S&Q with chest
|
||||
set_rule(world.get_location('Purple Chest', player), lambda state: state.has('Deliver Purple Chest', player)) # Can S&Q with chest
|
||||
set_rule(world.get_location('Big Bomb', player), lambda state: state.has('Crystal 5', player) and state.has('Crystal 6', player))
|
||||
set_rule(world.get_location('Pyramid Crack', player), lambda state: state.has('Pick Up Big Bomb', player))
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Detonate Big Bomb', 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))
|
||||
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('Sick Kid', player), lambda state: state.has_bottle(player))
|
||||
@@ -605,9 +599,11 @@ def bomb_rules(world, player):
|
||||
'Hookshot Cave Back to Middle', 'Hookshot Cave Front to Middle', 'Hookshot Cave Middle to Front','Hookshot Cave Middle to Back',
|
||||
'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery']
|
||||
for entrance in bonkable_doors:
|
||||
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))
|
||||
add_bunny_rule(world.get_entrance(entrance, player), player)
|
||||
for entrance in bombable_doors:
|
||||
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))
|
||||
add_bunny_rule(world.get_entrance(entrance, player), player)
|
||||
|
||||
bonkable_items = ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right']
|
||||
bombable_items = ['Blind\'s Hideout - Top', 'Kakariko Well - Top', 'Chicken House', 'Aginah\'s Cave', 'Graveyard Cave',
|
||||
@@ -615,18 +611,23 @@ def bomb_rules(world, player):
|
||||
'Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', 'Hype Cave - Bottom']
|
||||
for location in bonkable_items:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
for location in bombable_items:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
|
||||
cave_kill_locations = ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', 'Mini Moldorm Cave - Generous Guy', 'Spiral Cave']
|
||||
for location in cave_kill_locations:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player) or state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
add_rule(world.get_entrance('Spiral Cave (top to bottom)', player), lambda state: state.can_kill_most_things(player) or state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_entrance('Spiral Cave (top to bottom)', player), player)
|
||||
|
||||
paradox_switch_chests = ['Paradox Cave Lower - Far Left', 'Paradox Cave Lower - Left', 'Paradox Cave Lower - Right', 'Paradox Cave Lower - Far Right', 'Paradox Cave Lower - Middle']
|
||||
for location in paradox_switch_chests:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_hit_crystal_through_barrier(player))
|
||||
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
|
||||
# Dungeon bomb logic
|
||||
easy_kill_rooms = [ # Door, bool-bombable
|
||||
('Hyrule Dungeon Armory S', True), # One green guard
|
||||
@@ -683,7 +684,7 @@ def bomb_rules(world, player):
|
||||
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('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',
|
||||
'PoD Warp Hint SE', 'PoD Jelly Hall NW', 'PoD Jelly Hall NE', 'PoD Mimics 1 SW',
|
||||
'Thieves Ambush E', 'Thieves Rail Ledge W',
|
||||
@@ -724,6 +725,7 @@ def default_rules(world, player):
|
||||
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_location('Potion Shop', player), lambda state: state.has('Mushroom', player))
|
||||
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', 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('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
||||
|
||||
# Entrance Access
|
||||
@@ -1352,7 +1354,7 @@ def no_glitches_rules(world, player):
|
||||
|
||||
|
||||
def fake_flipper_rules(world, player):
|
||||
set_rule(world.get_entrance('Waterfall of Wishing Cave Entry', player), lambda state: state.has('Flippers', player) or (state.has_Pearl(player) and state.can_reach('Lake Hylia Water', player)))
|
||||
set_rule(world.get_entrance('Waterfall of Wishing Cave Entry', player), lambda state: True) # warning, assumes FF possible on other end of whirlpool or local ancilla splash delete
|
||||
set_rule(world.get_entrance('River Bend Water Drop', player), lambda state: True)
|
||||
set_rule(world.get_entrance('River Bend East Water Drop', player), lambda state: True)
|
||||
set_rule(world.get_entrance('Potion Shop Water Drop', player), lambda state: True)
|
||||
@@ -1637,440 +1639,6 @@ def find_rules_for_zelda_delivery(world, player):
|
||||
raise Exception('No path to Sanctuary found')
|
||||
|
||||
|
||||
def set_big_bomb_rules(world, player):
|
||||
# this is a mess
|
||||
if len(world.get_region('Big Bomb Shop', player).entrances) > 0:
|
||||
bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0]
|
||||
Normal_LW_entrances = ['Blinds Hideout',
|
||||
'Bonk Fairy (Light)',
|
||||
'Lake Hylia Fairy',
|
||||
'Light Hype Fairy',
|
||||
'Desert Fairy',
|
||||
'Chicken House',
|
||||
'Aginahs Cave',
|
||||
'Sahasrahlas Hut',
|
||||
'Cave Shop (Lake Hylia)',
|
||||
'Blacksmiths Hut',
|
||||
'Sick Kids House',
|
||||
'Lost Woods Gamble',
|
||||
'Fortune Teller (Light)',
|
||||
'Snitch Lady (East)',
|
||||
'Snitch Lady (West)',
|
||||
'Bush Covered House',
|
||||
'Tavern (Front)',
|
||||
'Light World Bomb Hut',
|
||||
'Kakariko Shop',
|
||||
'Mini Moldorm Cave',
|
||||
'Long Fairy Cave',
|
||||
'Good Bee Cave',
|
||||
'20 Rupee Cave',
|
||||
'50 Rupee Cave',
|
||||
'Ice Rod Cave',
|
||||
'Bonk Rock Cave',
|
||||
'Library',
|
||||
'Potion Shop',
|
||||
'Dam',
|
||||
'Lumberjack House',
|
||||
'Lake Hylia Fortune Teller',
|
||||
'Eastern Palace',
|
||||
'Kakariko Gamble Game',
|
||||
'Kakariko Well Cave',
|
||||
'Bat Cave Cave',
|
||||
'Elder House (East)',
|
||||
'Elder House (West)',
|
||||
'North Fairy Cave',
|
||||
'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Cave',
|
||||
'Two Brothers House (East)',
|
||||
'Sanctuary',
|
||||
'Hyrule Castle Entrance (South)',
|
||||
'Hyrule Castle Secret Entrance Stairs']
|
||||
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
|
||||
'Dark Lake Hylia Ledge Spike Cave',
|
||||
'Dark Lake Hylia Ledge Hint',
|
||||
'Mire Shed',
|
||||
'Dark Desert Hint',
|
||||
'Dark Desert Fairy',
|
||||
'Misery Mire']
|
||||
Northern_DW_entrances = ['Brewery',
|
||||
'C-Shaped House',
|
||||
'Chest Game',
|
||||
'Dark World Hammer Peg Cave',
|
||||
'Red Shield Shop',
|
||||
'Dark Sanctuary Hint',
|
||||
'Fortune Teller (Dark)',
|
||||
'Dark World Shop',
|
||||
'Dark World Lumberjack Shop',
|
||||
'Thieves Town',
|
||||
'Skull Woods First Section Door',
|
||||
'Skull Woods Second Section Door (East)']
|
||||
Southern_DW_entrances = ['Hype Cave',
|
||||
'Bonk Fairy (Dark)',
|
||||
'Archery Game',
|
||||
'Big Bomb Shop',
|
||||
'Dark Lake Hylia Shop',
|
||||
'Swamp Palace']
|
||||
Isolated_DW_entrances = ['Spike Cave',
|
||||
'Cave Shop (Dark Death Mountain)',
|
||||
'Dark Death Mountain Fairy',
|
||||
'Mimic Cave',
|
||||
'Skull Woods Second Section Door (West)',
|
||||
'Skull Woods Final Section',
|
||||
'Ice Palace',
|
||||
'Turtle Rock',
|
||||
'Dark Death Mountain Ledge (West)',
|
||||
'Dark Death Mountain Ledge (East)',
|
||||
'Bumper Cave (Top)',
|
||||
'Superbunny Cave (Top)',
|
||||
'Superbunny Cave (Bottom)',
|
||||
'Hookshot Cave',
|
||||
'Ganons Tower',
|
||||
'Turtle Rock Isolated Ledge Entrance',
|
||||
'Hookshot Cave Back Entrance']
|
||||
Isolated_LW_entrances = ['Capacity Upgrade',
|
||||
'Tower of Hera',
|
||||
'Death Mountain Return Cave (West)',
|
||||
'Paradox Cave (Top)',
|
||||
'Fairy Ascension Cave (Top)',
|
||||
'Spiral Cave',
|
||||
'Desert Palace Entrance (East)']
|
||||
West_LW_DM_entrances = ['Old Man Cave (East)',
|
||||
'Old Man House (Bottom)',
|
||||
'Old Man House (Top)',
|
||||
'Death Mountain Return Cave (East)',
|
||||
'Spectacle Rock Cave Peak',
|
||||
'Spectacle Rock Cave',
|
||||
'Spectacle Rock Cave (Bottom)']
|
||||
East_LW_DM_entrances = ['Paradox Cave (Bottom)',
|
||||
'Paradox Cave (Middle)',
|
||||
'Hookshot Fairy',
|
||||
'Spiral Cave (Bottom)']
|
||||
Mirror_from_SDW_entrances = ['Two Brothers House (West)',
|
||||
'Cave 45']
|
||||
Castle_ledge_entrances = ['Hyrule Castle Entrance (West)',
|
||||
'Hyrule Castle Entrance (East)',
|
||||
'Agahnims Tower']
|
||||
Desert_mirrorable_ledge_entrances = ['Desert Palace Entrance (West)',
|
||||
'Desert Palace Entrance (North)',
|
||||
'Desert Palace Entrance (South)',
|
||||
'Checkerboard Cave']
|
||||
|
||||
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
|
||||
def cross_peg_bridge(state):
|
||||
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.
|
||||
# crossing preg bridge already requires hammer so we just add the gloves to the requirement
|
||||
def southern_teleporter(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.
|
||||
# you can then use the southern teleporter, or (if you have beaten Aga1) the hyrule castle gate warp
|
||||
def basic_routes(state):
|
||||
return southern_teleporter(state) or state.has('Beat Agahnim 1', player)
|
||||
|
||||
# Key for below abbreviations:
|
||||
# P = pearl
|
||||
# A = Aga1
|
||||
# H = hammer
|
||||
# M = Mirror
|
||||
# G = Glove
|
||||
|
||||
if bombshop_entrance.name in Normal_LW_entrances:
|
||||
#1. basic routes
|
||||
#2. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
|
||||
# -> M or BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: basic_routes(state) or state.has_Mirror(player))
|
||||
elif bombshop_entrance.name in LW_walkable_entrances:
|
||||
#1. Mirror then basic routes
|
||||
# -> M and BR
|
||||
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:
|
||||
#1. Mirror and basic routes
|
||||
#2. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
|
||||
# -> (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)))
|
||||
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
|
||||
#1. Mirror and Lift rock and basic_routes
|
||||
#2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case)
|
||||
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
|
||||
# -> (Mitts and CPB) or (((G or Flute) and M) and BR))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', 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:
|
||||
#1. Mirror and enter via gate: Need mirror and Aga1
|
||||
#2. cross peg bridge: Need hammer and moon pearl
|
||||
# -> 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)))
|
||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||
# 1. mirror then flute then basic routes
|
||||
# -> 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))
|
||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||
# 1. flute then basic routes
|
||||
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
|
||||
# -> Flute and BR
|
||||
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:
|
||||
# 1. flute then basic routes or mirror
|
||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
|
||||
# -> Flute and (M or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('West Death Mountain (Bottom)', 'Region', player))
|
||||
elif bombshop_entrance.name in East_LW_DM_entrances:
|
||||
# 1. flute then basic routes or mirror and hookshot
|
||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot
|
||||
# -> Flute and ((M and Hookshot) or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Death Mountain (Bottom)', 'Region', player))
|
||||
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)':
|
||||
# Same as East_LW_DM_entrances except navigation without BR requires Mitts
|
||||
# -> Flute and ((M and Hookshot and Mitts) or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', 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:
|
||||
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
|
||||
# 2. flute then basic routes
|
||||
# -> M or (Flute and BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Hyrule Castle Ledge', 'Region', player))
|
||||
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances:
|
||||
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
|
||||
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
|
||||
# 2. flute then basic routes
|
||||
# -> (Mire access and M) or Flute) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Desert Ledge', 'Region', player))
|
||||
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
||||
# 1. Lift rock then basic_routes
|
||||
# 2. flute then basic_routes
|
||||
# -> (Flute or G) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Death Mountain Entrance', 'Region', player))
|
||||
elif bombshop_entrance.name == 'Graveyard Cave':
|
||||
# 1. flute then basic routes
|
||||
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
|
||||
# -> (Flute or (M and P and West Dark World access) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', 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:
|
||||
# 1. flute then basic routes
|
||||
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
|
||||
# -> (Flute or (M and South Dark World access) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', 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':
|
||||
# 1. walk down by lifting rock: needs gloves and pearl`
|
||||
# 2. walk down by hammering peg: needs hammer and pearl
|
||||
# 3. mirror and basic routes
|
||||
# -> (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))
|
||||
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
|
||||
# (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
|
||||
# -> (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))))
|
||||
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
|
||||
# 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)))
|
||||
|
||||
#TODO: Fix red bomb rules, artifically adding a bunch of rules to help reduce unbeatable seeds in OW shuffle
|
||||
set_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_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):
|
||||
if len(world.get_region('Big Bomb Shop', player).entrances) > 0:
|
||||
bombshop_entrance = world.get_region('Big Bomb Shop', player).entrances[0]
|
||||
Normal_LW_entrances = ['Blinds Hideout',
|
||||
'Bonk Fairy (Light)',
|
||||
'Lake Hylia Fairy',
|
||||
'Light Hype Fairy',
|
||||
'Desert Fairy',
|
||||
'Chicken House',
|
||||
'Aginahs Cave',
|
||||
'Sahasrahlas Hut',
|
||||
'Cave Shop (Lake Hylia)',
|
||||
'Blacksmiths Hut',
|
||||
'Sick Kids House',
|
||||
'Lost Woods Gamble',
|
||||
'Fortune Teller (Light)',
|
||||
'Snitch Lady (East)',
|
||||
'Snitch Lady (West)',
|
||||
'Tavern (Front)',
|
||||
'Kakariko Shop',
|
||||
'Mini Moldorm Cave',
|
||||
'Long Fairy Cave',
|
||||
'Good Bee Cave',
|
||||
'20 Rupee Cave',
|
||||
'50 Rupee Cave',
|
||||
'Ice Rod Cave',
|
||||
'Bonk Rock Cave',
|
||||
'Library',
|
||||
'Potion Shop',
|
||||
'Dam',
|
||||
'Lumberjack House',
|
||||
'Lake Hylia Fortune Teller',
|
||||
'Eastern Palace',
|
||||
'Kakariko Gamble Game',
|
||||
'Kakariko Well Cave',
|
||||
'Bat Cave Cave',
|
||||
'Elder House (East)',
|
||||
'Elder House (West)',
|
||||
'North Fairy Cave',
|
||||
'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Cave',
|
||||
'Two Brothers House (East)',
|
||||
'Sanctuary',
|
||||
'Hyrule Castle Entrance (South)',
|
||||
'Hyrule Castle Secret Entrance Stairs',
|
||||
'Hyrule Castle Entrance (West)',
|
||||
'Hyrule Castle Entrance (East)',
|
||||
'Ganons Tower',
|
||||
'Cave 45',
|
||||
'Checkerboard Cave',
|
||||
'Links House']
|
||||
Isolated_LW_entrances = ['Old Man Cave (East)',
|
||||
'Old Man House (Bottom)',
|
||||
'Old Man House (Top)',
|
||||
'Death Mountain Return Cave (East)',
|
||||
'Spectacle Rock Cave Peak',
|
||||
'Tower of Hera',
|
||||
'Death Mountain Return Cave (West)',
|
||||
'Paradox Cave (Top)',
|
||||
'Fairy Ascension Cave (Top)',
|
||||
'Spiral Cave',
|
||||
'Paradox Cave (Bottom)',
|
||||
'Paradox Cave (Middle)',
|
||||
'Hookshot Fairy',
|
||||
'Spiral Cave (Bottom)',
|
||||
'Mimic Cave',
|
||||
'Fairy Ascension Cave (Bottom)',
|
||||
'Desert Palace Entrance (West)',
|
||||
'Desert Palace Entrance (North)',
|
||||
'Desert Palace Entrance (South)']
|
||||
Eastern_DW_entrances = ['Palace of Darkness',
|
||||
'Palace of Darkness Hint',
|
||||
'Dark Lake Hylia Fairy',
|
||||
'East Dark World Hint']
|
||||
Northern_DW_entrances = ['Brewery',
|
||||
'C-Shaped House',
|
||||
'Chest Game',
|
||||
'Dark World Hammer Peg Cave',
|
||||
'Dark Sanctuary Hint',
|
||||
'Fortune Teller (Dark)',
|
||||
'Dark World Lumberjack Shop',
|
||||
'Thieves Town',
|
||||
'Skull Woods First Section Door',
|
||||
'Skull Woods Second Section Door (East)']
|
||||
Southern_DW_entrances = ['Hype Cave',
|
||||
'Bonk Fairy (Dark)',
|
||||
'Archery Game',
|
||||
'Big Bomb Shop',
|
||||
'Dark Lake Hylia Shop',
|
||||
'Swamp Palace']
|
||||
Isolated_DW_entrances = ['Spike Cave',
|
||||
'Cave Shop (Dark Death Mountain)',
|
||||
'Dark Death Mountain Fairy',
|
||||
'Skull Woods Second Section Door (West)',
|
||||
'Skull Woods Final Section',
|
||||
'Turtle Rock',
|
||||
'Dark Death Mountain Ledge (West)',
|
||||
'Dark Death Mountain Ledge (East)',
|
||||
'Bumper Cave (Top)',
|
||||
'Superbunny Cave (Top)',
|
||||
'Superbunny Cave (Bottom)',
|
||||
'Hookshot Cave',
|
||||
'Turtle Rock Isolated Ledge Entrance',
|
||||
'Hookshot Cave Back Entrance',
|
||||
'Agahnims Tower']
|
||||
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
|
||||
'Dark Lake Hylia Ledge Spike Cave',
|
||||
'Dark Lake Hylia Ledge Hint',
|
||||
'Mire Shed',
|
||||
'Dark Desert Hint',
|
||||
'Dark Desert Fairy',
|
||||
'Misery Mire',
|
||||
'Red Shield Shop']
|
||||
LW_bush_entrances = ['Bush Covered House',
|
||||
'Light World Bomb Hut',
|
||||
'Graveyard Cave']
|
||||
LW_inaccessible_entrances = ['Desert Palace Entrance (East)',
|
||||
'Spectacle Rock Cave',
|
||||
'Spectacle Rock Cave (Bottom)']
|
||||
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player),
|
||||
lambda state: state.can_reach('Pyramid Area', 'Region', player) and state.can_reach('Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player))
|
||||
|
||||
# Key for below abbreviations:
|
||||
# P = pearl
|
||||
# A = Aga1
|
||||
# H = hammer
|
||||
# M = Mirror
|
||||
# G = Glove
|
||||
if bombshop_entrance.name in Eastern_DW_entrances:
|
||||
# Just walk to the pyramid
|
||||
pass
|
||||
elif bombshop_entrance.name in Normal_LW_entrances:
|
||||
# Just walk to the castle and mirror.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
|
||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||
# For these entrances, you cannot walk to the castle/pyramid and thus must use Mirror and then Flute.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name in Northern_DW_entrances:
|
||||
# You can just fly with the Flute, you can take a long walk with Mitts and Hammer,
|
||||
# or you can leave a Mirror portal nearby and then walk to the castle to Mirror again.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Hyrule Castle Area', 'Region', player)))
|
||||
elif bombshop_entrance.name in Southern_DW_entrances:
|
||||
# This is the same as north DW without the Mitts rock present.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Hyrule Castle Area', 'Region', player)))
|
||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||
# There's just no way to escape these places with the bomb and no Flute.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player))
|
||||
elif bombshop_entrance.name in LW_walkable_entrances:
|
||||
# You can fly with the flute, or leave a mirror portal and walk through the light world
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Hyrule Castle Area', 'Region', player)))
|
||||
elif bombshop_entrance.name in LW_bush_entrances:
|
||||
# These entrances are behind bushes in LW so you need either Pearl or the tools to solve NDW bomb shop locations.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and (state.can_flute(player) or state.has_Pearl(player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player))))
|
||||
elif bombshop_entrance.name == 'Dark World Shop':
|
||||
# This is mostly the same as NDW but the Mirror path requires the Pearl, or using the Hammer
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Hyrule Castle Area', 'Region', player) and (state.has_Pearl(player) or state.has('Hammer', player))))
|
||||
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
|
||||
# This is mostly the same as NDW but the Mirror path requires being able to lift a rock.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_lift_rocks(player) and state.can_reach('Hyrule Castle Area', 'Region', player)))
|
||||
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
||||
# The three paths back are Mirror and DW walk, Mirror and Flute, or LW walk and then Mirror.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and ((state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.can_lift_rocks(player) and state.has_Pearl(player)) or state.can_flute(player)))
|
||||
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
||||
# You either need to Flute to 5 or cross the rock/hammer choice pass to the south.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or state.has('Hammer', player) or state.can_lift_rocks(player))
|
||||
elif bombshop_entrance.name == 'Kings Grave':
|
||||
# Either lift the rock and walk to the castle to Mirror or Mirror immediately and Flute.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.has_Pearl(player) and state.can_lift_heavy_rocks(player))) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name == 'Two Brothers House (West)':
|
||||
# First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
||||
# You absolutely must be able to swim to return it from here.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name == 'Ice Palace':
|
||||
# You can swim to the dock or use the Flute to get off the island.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.can_flute(player))
|
||||
elif bombshop_entrance.name == 'Capacity Upgrade':
|
||||
# You must Mirror but then can use either Ice Palace return path.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name == 'Two Brothers House (West)':
|
||||
# First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has_Mirror(player))
|
||||
elif bombshop_entrance.name in LW_inaccessible_entrances:
|
||||
# You can't get to the pyramid from these entrances without bomb duping.
|
||||
raise Exception('No valid path to open Pyramid Fairy. (Could not route from %s)' % bombshop_entrance.name)
|
||||
elif bombshop_entrance.name == 'Pyramid Fairy':
|
||||
# Self locking. The shuffles don't put the bomb shop here, but doesn't lock anything important.
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
|
||||
else:
|
||||
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
|
||||
|
||||
if world.owShuffle[player] != 'vanilla' or world.owMixed[player] or world.owCrossed[player] not in ['none', 'polar']:
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) #temp disable progression until routing to Pyramid get be guaranteed
|
||||
|
||||
|
||||
def set_bunny_rules(world, player, inverted):
|
||||
|
||||
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
|
||||
@@ -2081,7 +1649,7 @@ def set_bunny_rules(world, player, inverted):
|
||||
'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid',
|
||||
'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins',
|
||||
'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Purple Chest', 'Blacksmith',
|
||||
'Missing Smith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge',
|
||||
'Missing Smith', 'Pyramid Crack', 'Big Bomb', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge',
|
||||
'Kakariko Shop - Left', 'Kakariko Shop - Middle', 'Kakariko Shop - Right',
|
||||
'Lake Hylia Shop - Left', 'Lake Hylia Shop - Middle', 'Lake Hylia Shop - Right',
|
||||
'Potion Shop - Left', 'Potion Shop - Middle', 'Potion Shop - Right',
|
||||
|
||||
Reference in New Issue
Block a user