Make keys, pendants, crystals and agahnim fights "events", which we sweep for everytime we have new unlock potential. Simplifies searching for items significantly.
This commit is contained in:
parent
1fe6774ba0
commit
a73dba985f
112
BaseClasses.py
112
BaseClasses.py
|
@ -76,6 +76,39 @@ class World(object):
|
|||
return r_location
|
||||
raise RuntimeError('No such location %s' % location)
|
||||
|
||||
def get_all_state(self):
|
||||
ret = CollectionState(self)
|
||||
|
||||
def soft_collect(item):
|
||||
if item.name.startswith('Progressive '):
|
||||
if 'Sword' in item.name:
|
||||
if ret.has('Golden Sword'):
|
||||
pass
|
||||
elif ret.has('Tempered Sword'):
|
||||
ret.prog_items.append('Golden Sword')
|
||||
elif ret.has('Master Sword'):
|
||||
ret.prog_items.append('Tempered Sword')
|
||||
elif ret.has('Fighter Sword'):
|
||||
ret.prog_items.append('Master Sword')
|
||||
else:
|
||||
ret.prog_items.append('Fighter Sword')
|
||||
elif 'Glove' in item.name:
|
||||
if ret.has('Titans Mitts'):
|
||||
pass
|
||||
elif ret.has('Power Glove'):
|
||||
ret.prog_items.append('Titans Mitts')
|
||||
else:
|
||||
ret.prog_items.append('Power Glove')
|
||||
|
||||
elif item.advancement:
|
||||
ret.prog_items.append(item.name)
|
||||
|
||||
for location in self.get_filled_locations():
|
||||
soft_collect(location.item)
|
||||
for item in self.itempool:
|
||||
soft_collect(item)
|
||||
return ret
|
||||
|
||||
def find_items(self, item):
|
||||
return [location for location in self.get_locations() if location.item is not None and location.item.name == item]
|
||||
|
||||
|
@ -87,7 +120,7 @@ class World(object):
|
|||
location.item = item
|
||||
item.location = location
|
||||
if collect:
|
||||
self.state.collect(item)
|
||||
self.state.collect(item, location.event)
|
||||
|
||||
logging.getLogger('').debug('Placed %s at %s' % (item, location))
|
||||
else:
|
||||
|
@ -103,6 +136,9 @@ class World(object):
|
|||
def get_unfilled_locations(self):
|
||||
return [location for location in self.get_locations() if location.item is None]
|
||||
|
||||
def get_filled_locations(self):
|
||||
return [location for location in self.get_locations() if location.item is not None]
|
||||
|
||||
def get_reachable_locations(self, state=None):
|
||||
if state is None:
|
||||
state = self.state
|
||||
|
@ -116,7 +152,7 @@ class World(object):
|
|||
def unlocks_new_location(self, item):
|
||||
temp_state = self.state.copy()
|
||||
temp_state._clear_cache()
|
||||
temp_state.collect(item)
|
||||
temp_state.collect(item, True)
|
||||
|
||||
for location in self.get_unfilled_locations():
|
||||
if temp_state.can_reach(location) and not self.state.can_reach(location):
|
||||
|
@ -125,7 +161,7 @@ class World(object):
|
|||
return False
|
||||
|
||||
def can_beat_game(self):
|
||||
prog_locations = [location for location in self.get_locations() if location.item is not None and location.item.advancement]
|
||||
prog_locations = [location for location in self.get_locations() if location.item is not None and (location.item.advancement or location.event)]
|
||||
|
||||
state = CollectionState(self)
|
||||
treasure_pieces_collected = 0
|
||||
|
@ -148,7 +184,7 @@ class World(object):
|
|||
|
||||
for location in sphere:
|
||||
prog_locations.remove(location)
|
||||
state.collect(location.item)
|
||||
state.collect(location.item, True)
|
||||
|
||||
return False
|
||||
|
||||
|
@ -166,14 +202,14 @@ class World(object):
|
|||
|
||||
class CollectionState(object):
|
||||
|
||||
def __init__(self, parent, has_everything=False):
|
||||
def __init__(self, parent):
|
||||
self.prog_items = []
|
||||
self.world = parent
|
||||
self.has_everything = has_everything
|
||||
self.region_cache = {}
|
||||
self.location_cache = {}
|
||||
self.entrance_cache = {}
|
||||
self.recursion_count = 0
|
||||
self.events = []
|
||||
|
||||
def _clear_cache(self):
|
||||
# we only need to invalidate results which were False, places we could reach before we can still reach after adding more items
|
||||
|
@ -182,11 +218,12 @@ class CollectionState(object):
|
|||
self.entrance_cache = {k: v for k, v in self.entrance_cache.items() if v}
|
||||
|
||||
def copy(self):
|
||||
ret = CollectionState(self.world, self.has_everything)
|
||||
ret = CollectionState(self.world)
|
||||
ret.prog_items = copy.copy(self.prog_items)
|
||||
ret.region_cache = copy.copy(self.region_cache)
|
||||
ret.location_cache = copy.copy(self.location_cache)
|
||||
ret.entrance_cache = copy.copy(self.entrance_cache)
|
||||
ret.events = copy.copy(self.events)
|
||||
return ret
|
||||
|
||||
def can_reach(self, spot, resolution_hint=None):
|
||||
|
@ -233,45 +270,24 @@ class CollectionState(object):
|
|||
return can_reach
|
||||
return correct_cache[spot]
|
||||
|
||||
def can_collect(self, item, count=None):
|
||||
if isinstance(item, Item):
|
||||
item = item.name
|
||||
if count is None:
|
||||
cached = self.world._item_cache.get(item, None)
|
||||
if cached is None:
|
||||
candidates = self.world.find_items(item)
|
||||
if not candidates:
|
||||
return False
|
||||
elif len(candidates) == 1:
|
||||
cached = candidates[0]
|
||||
self.world._item_cache[item] = cached
|
||||
else:
|
||||
# this should probably not happen, wonky item distribution?
|
||||
return self._can_reach_n(self.world.find_items(item), 1)
|
||||
return self.can_reach(cached)
|
||||
def sweep_for_events(self, key_only=False):
|
||||
# this may need improvement
|
||||
new_locations = True
|
||||
checked_locations = 0
|
||||
while new_locations:
|
||||
reachable_events = [location for location in self.world.get_filled_locations() if location.event and (not key_only or location.item.key) and self.can_reach(location)]
|
||||
for event in reachable_events:
|
||||
if event.name not in self.events:
|
||||
self.events.append(event.name)
|
||||
self.collect(event.item, True)
|
||||
new_locations = len(reachable_events) > checked_locations
|
||||
checked_locations = len(reachable_events)
|
||||
|
||||
return self._can_reach_n(self.world.find_items(item), count)
|
||||
|
||||
def _can_reach_n(self, candidates, count):
|
||||
maxfail = len(candidates) - count
|
||||
fail = 0
|
||||
success = 0
|
||||
for candidate in candidates:
|
||||
if self.can_reach(candidate):
|
||||
success += 1
|
||||
else:
|
||||
fail += 1
|
||||
if fail > maxfail:
|
||||
return False
|
||||
if success >= count:
|
||||
return True
|
||||
return False
|
||||
|
||||
def has(self, item):
|
||||
if self.has_everything:
|
||||
return True
|
||||
else:
|
||||
def has(self, item, count=1):
|
||||
if count == 1:
|
||||
return item in self.prog_items
|
||||
else:
|
||||
return len([pritem for pritem in self.prog_items if pritem == item]) >= count
|
||||
|
||||
def can_lift_rocks(self):
|
||||
return self.has('Power Glove') or self.has('Titans Mitts')
|
||||
|
@ -306,7 +322,7 @@ class CollectionState(object):
|
|||
def has_turtle_rock_medallion(self):
|
||||
return self.has(self.world.required_medallions[1])
|
||||
|
||||
def collect(self, item):
|
||||
def collect(self, item, event=False):
|
||||
changed = False
|
||||
if item.name.startswith('Progressive '):
|
||||
if 'Sword' in item.name:
|
||||
|
@ -334,12 +350,15 @@ class CollectionState(object):
|
|||
self.prog_items.append('Power Glove')
|
||||
changed = True
|
||||
|
||||
elif item.advancement:
|
||||
elif event or item.advancement:
|
||||
self.prog_items.append(item.name)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self._clear_cache()
|
||||
if not event:
|
||||
self.sweep_for_events()
|
||||
self._clear_cache()
|
||||
|
||||
def remove(self, item):
|
||||
if item.advancement:
|
||||
|
@ -456,6 +475,7 @@ class Location(object):
|
|||
self.hint_text = hint_text if hint_text is not None else 'Hyrule'
|
||||
self.recursion_count = 0
|
||||
self.staleness_count = 0
|
||||
self.event = False
|
||||
|
||||
def access_rule(self, state):
|
||||
return True
|
||||
|
|
|
@ -20,15 +20,18 @@ def fill_dungeons(world):
|
|||
|
||||
freebes = ['[dungeon-A2-1F] Ganons Tower - Map Room', '[dungeon-D1-1F] Dark Palace - Spike Statue Room', '[dungeon-D1-1F] Dark Palace - Big Key Room']
|
||||
|
||||
all_state_base = world.get_all_state()
|
||||
|
||||
# this key is in a fixed location (for now)
|
||||
world.push_item(world.get_location('[dungeon-D3-B1] Skull Woods - South of Big Chest'), ItemFactory('Small Key (Skull Woods)'), False)
|
||||
world.get_location('[dungeon-D3-B1] Skull Woods - South of Big Chest').event = True
|
||||
|
||||
for dungeon_regions, big_key, small_keys, dungeon_items in [TR, ES, EP, DP, ToH, AT, PoD, TT, SW, SP, IP, MM, GT]:
|
||||
# this is what we need to fill
|
||||
dungeon_locations = [location for location in world.get_unfilled_locations() if location.parent_region.name in dungeon_regions]
|
||||
random.shuffle(dungeon_locations)
|
||||
|
||||
all_state = CollectionState(world, True)
|
||||
all_state = all_state_base.copy()
|
||||
|
||||
# first place big key
|
||||
if big_key is not None:
|
||||
|
@ -42,11 +45,13 @@ def fill_dungeons(world):
|
|||
raise RuntimeError('No suitable location for %s' % big_key)
|
||||
|
||||
world.push_item(bk_location, big_key, False)
|
||||
bk_location.event = True
|
||||
dungeon_locations.remove(bk_location)
|
||||
all_state._clear_cache()
|
||||
|
||||
# next place small keys
|
||||
for small_key in small_keys:
|
||||
all_state.sweep_for_events()
|
||||
sk_location = None
|
||||
for location in dungeon_locations:
|
||||
if location.name in freebes or location.can_reach(all_state):
|
||||
|
@ -57,6 +62,7 @@ def fill_dungeons(world):
|
|||
raise RuntimeError('No suitable location for %s' % small_key)
|
||||
|
||||
world.push_item(sk_location, small_key, False)
|
||||
sk_location.event = True
|
||||
dungeon_locations.remove(sk_location)
|
||||
all_state._clear_cache()
|
||||
|
||||
|
|
4
Items.py
4
Items.py
|
@ -155,4 +155,6 @@ item_table = {'Bow': (True, False, False, False, 0x0B, 'You have\nchosen the\nar
|
|||
'Big Key (Ganons Tower)': (False, False, True, False, 0x32, None, None, None, None, None, None),
|
||||
'Compass (Ganons Tower)': (False, True, False, False, 0x25, None, None, None, None, None, None),
|
||||
'Map (Ganons Tower)': (False, True, False, False, 0x33, None, None, None, None, None, None),
|
||||
'Nothing': (False, False, False, False, 0x5A, 'Some Hot Air', None, None, None, None, None)}
|
||||
'Nothing': (False, False, False, False, 0x5A, 'Some Hot Air', None, None, None, None, None),
|
||||
'Beat Agahnim 1': (True, False, False, False, None, None, None, None, None, None, None),
|
||||
'Beat Agahnim 2': (True, False, False, False, None, None, None, None, None, None, None)}
|
||||
|
|
11
Main.py
11
Main.py
|
@ -309,6 +309,10 @@ def generate_itempool(world):
|
|||
raise NotImplementedError('Not supported yet')
|
||||
|
||||
world.push_item('Ganon', ItemFactory('Triforce'), False)
|
||||
world.push_item('Agahnim 1', ItemFactory('Beat Agahnim 1'), False)
|
||||
world.get_location('Agahnim 1').event = True
|
||||
world.push_item('Agahnim 2', ItemFactory('Beat Agahnim 2'), False)
|
||||
world.get_location('Agahnim 2').event = True
|
||||
|
||||
# set up item pool
|
||||
if world.difficulty in ['timed', 'timed-countdown']:
|
||||
|
@ -380,6 +384,7 @@ def generate_itempool(world):
|
|||
random.shuffle(crystals)
|
||||
for location, crystal in zip(crystal_locations, crystals):
|
||||
world.push_item(location, crystal, False)
|
||||
location.event = True
|
||||
|
||||
# shuffle medallions
|
||||
mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
|
||||
|
@ -418,6 +423,8 @@ def copy_world(world):
|
|||
item = Item(location.item.name, location.item.advancement, location.item.priority, location.item.key)
|
||||
ret.get_location(location.name).item = item
|
||||
item.location = ret.get_location(location.name)
|
||||
if location.event:
|
||||
ret.get_location(location.name).event = True
|
||||
|
||||
# copy remaining itempool. No item in itempool should have an assigned location
|
||||
for item in world.itempool:
|
||||
|
@ -454,7 +461,9 @@ def create_playthrough(world):
|
|||
|
||||
for location in sphere:
|
||||
sphere_candidates.remove(location)
|
||||
state.collect(location.item)
|
||||
state.collect(location.item, True)
|
||||
|
||||
state.sweep_for_events(key_only=True)
|
||||
|
||||
collection_spheres.append(sphere)
|
||||
|
||||
|
|
10
Regions.py
10
Regions.py
|
@ -13,7 +13,7 @@ def create_regions(world):
|
|||
'Sanctuary', 'Sanctuary Grave', 'Old Man Cave (West)', 'Flute Spot 1', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter',
|
||||
'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
|
||||
'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing',
|
||||
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game']),
|
||||
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']),
|
||||
create_region('Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']),
|
||||
create_region('Thiefs Hut', ["[cave-022-B1] Thiefs hut [top chest]",
|
||||
"[cave-022-B1] Thiefs hut [top left chest]",
|
||||
|
@ -96,7 +96,7 @@ def create_regions(world):
|
|||
'[dungeon-C-B1] Escape - Final Basement Room [right chest]'], ['Sanctuary Push Door', 'Sewers Back Door']),
|
||||
create_region('Sanctuary', ['[dungeon-C-1F] Sanctuary'], ['Sanctuary Exit']),
|
||||
create_region('Agahnims Tower', ['[dungeon-A1-2F] Hyrule Castle Tower - 2 Knife Guys Room', '[dungeon-A1-3F] Hyrule Castle Tower - Maze Room'], ['Agahnim 1', 'Agahnims Tower Exit']),
|
||||
create_region('Agahnim 1', None, ['Top of Pyramid']),
|
||||
create_region('Agahnim 1', ['Agahnim 1'], None),
|
||||
create_region('Old Man Cave', ['Old Mountain Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']),
|
||||
create_region('Old Man House', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']),
|
||||
create_region('Old Man House Back', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']),
|
||||
|
@ -132,7 +132,7 @@ def create_regions(world):
|
|||
create_region('Tower of Hera (Top)', ['[dungeon-L3-1F] Tower of Hera - 4F [small chest]', '[dungeon-L3-1F] Tower of Hera - Big Chest', 'Moldorm - Heart Container', 'Moldorm - Pendant']),
|
||||
|
||||
create_region('East Dark World', ['Piece of Heart (Pyramid)', 'Catfish'], ['Pyramid Fairy', 'South Dark World Bridge', 'West Dark World Gap', 'Palace of Darkness Pay Kiki', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Teleporter',
|
||||
'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Dark World Potion Shop']),
|
||||
'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Dark World Potion Shop', 'Pyramid Hole']),
|
||||
create_region('Palace of Darkness Kiki Door', None, ['Palace of Darkness', 'Palace of Darkness Kiki Door Reverse']),
|
||||
create_region('Palace of Darkness Hint'),
|
||||
create_region('East Dark World Hint'),
|
||||
|
@ -262,7 +262,7 @@ def create_regions(world):
|
|||
create_region('Ganons Tower (Before Moldorm)', ['[dungeon-A2-6F] Ganons Tower - Mini Helmasaur Room [left chest]', '[dungeon-A2-6F] Ganons Tower - Mini Helmasaur Room [right chest]',
|
||||
'[dungeon-A2-6F] Ganons Tower - Room before Moldorm'], ['Ganons Tower Moldorm Door']),
|
||||
create_region('Ganons Tower (Moldorm)', None, ['Ganons Tower Moldorm Gap']),
|
||||
create_region('Agahnim 2', ['[dungeon-A2-6F] Ganons Tower - Moldorm Room'], ['Pyramid Hole']),
|
||||
create_region('Agahnim 2', ['[dungeon-A2-6F] Ganons Tower - Moldorm Room', 'Agahnim 2'], None),
|
||||
create_region('Pyramid', ['Ganon'], ['Ganon Drop']),
|
||||
create_region('Bottom of Pyramid', None, ['Pyramid Exit']),
|
||||
create_region('Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop'])
|
||||
|
@ -499,6 +499,8 @@ location_table = {'Mushroom': (0x180013, False, 'in the woods'),
|
|||
'[dungeon-A2-6F] Ganons Tower - Room before Moldorm': (0xEB03, False, 'atop My Tower'),
|
||||
'[dungeon-A2-6F] Ganons Tower - Moldorm Room': (0xEB06, False, 'atop My Tower'),
|
||||
'Ganon': (None, False, 'from me'),
|
||||
'Agahnim 1': (None, False, 'from my wizardry from'),
|
||||
'Agahnim 2': (None, False, 'from my wizardry from'),
|
||||
'Armos - Pendant': ([0x1209D, 0x53EF8, 0x53EF9, 0x180052, 0x18007C, 0xC6FE], True, 'Eastern Palace'),
|
||||
'Lanmolas - Pendant': ([0x1209E, 0x53F1C, 0x53F1D, 0x180053, 0x180078, 0xC6FF], True, 'Desert Palace'),
|
||||
'Moldorm - Pendant': ([0x120A5, 0x53F0A, 0x53F0B, 0x18005A, 0x18007A, 0xC706], True, 'Tower of Hera'),
|
||||
|
|
7
Rom.py
7
Rom.py
|
@ -14,12 +14,11 @@ RANDOMIZERBASEHASH = 'd5b61947feef1972e0f546ba43180e62'
|
|||
def patch_rom(world, rom, hashtable, quickswap=False, beep='normal', sprite=None):
|
||||
# patch items
|
||||
for location in world.get_locations():
|
||||
if location.name == 'Ganon':
|
||||
# cannot shuffle this yet
|
||||
continue
|
||||
|
||||
itemid = location.item.code if location.item is not None else 0x5A
|
||||
|
||||
if itemid is None or location.address is None:
|
||||
continue
|
||||
|
||||
locationaddress = location.address
|
||||
if not location.crystal:
|
||||
# regular items
|
||||
|
|
112
Rules.py
112
Rules.py
|
@ -69,7 +69,7 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_location('Piece of Heart (Dam)'), lambda state: state.can_reach('Dam'))
|
||||
set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Lumberjack Tree Tree'), lambda state: state.has_Boots() and state.can_reach('Top of Pyramid', 'Entrance'))
|
||||
set_rule(world.get_entrance('Lumberjack Tree Tree'), lambda state: state.has_Boots() and state.has('Beat Agahnim 1'))
|
||||
set_rule(world.get_entrance('Bonk Rock Cave'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_entrance('Desert Palace Stairs'), lambda state: state.has('Book of Mudora'))
|
||||
set_rule(world.get_entrance('Sanctuary Grave'), lambda state: state.can_lift_rocks())
|
||||
|
@ -95,10 +95,11 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Desert Palace Entrance (North) Rocks'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Desert Ledge Return Rocks'), lambda state: state.can_lift_rocks()) # should we decide to place something that is not a dungeon end up there at some point
|
||||
set_rule(world.get_entrance('Checkerboard Cave'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_location('Altar'), lambda state: state.can_collect('Red Pendant') and state.can_collect('Blue Pendant') and state.can_collect('Green Pendant'))
|
||||
set_rule(world.get_location('Sahasrahla'), lambda state: state.can_collect('Green Pendant'))
|
||||
set_rule(world.get_location('Altar'), lambda state: state.has('Red Pendant') and state.has('Blue Pendant') and state.has('Green Pendant'))
|
||||
set_rule(world.get_location('Sahasrahla'), lambda state: state.has('Green Pendant'))
|
||||
set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has_beam_sword() or state.can_reach('Agahnim 1')) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||
set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has_sword())
|
||||
set_rule(world.get_entrance('Top of Pyramid'), lambda state: state.has('Beat Agahnim 1'))
|
||||
set_rule(world.get_entrance('Old Man Cave Exit (West)'), lambda state: False) # drop cannott be climbed up
|
||||
set_rule(world.get_entrance('Broken Bridge (West)'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Broken Bridge (East)'), lambda state: state.has('Hookshot'))
|
||||
|
@ -160,7 +161,7 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Spike Cave'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Dark Death Mountain Fairy'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Spectacle Rock Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Ganons Tower'), lambda state: state.can_collect('Crystal 1') and state.can_collect('Crystal 2') and state.can_collect('Crystal 3') and state.can_collect('Crystal 4') and state.can_collect('Crystal 5') and state.can_collect('Crystal 6') and state.can_collect('Crystal 7'))
|
||||
set_rule(world.get_entrance('Ganons Tower'), lambda state: state.has('Crystal 1') and state.has('Crystal 2') and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7'))
|
||||
set_rule(world.get_entrance('Hookshot Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl())
|
||||
set_rule(world.get_entrance('East Death Mountain (Top) Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Mimic Cave Mirror Spot'), lambda state: state.has_Mirror())
|
||||
|
@ -180,28 +181,28 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_sword() and state.has_turtle_rock_medallion()) # sword required to cast magic (!)
|
||||
set_rule(world.get_location('[cave-013] Mimic Cave'), lambda state: state.has('Hammer'))
|
||||
|
||||
set_rule(world.get_entrance('Sewers Door'), lambda state: state.can_collect('Small Key (Escape)'))
|
||||
set_rule(world.get_entrance('Sewers Back Door'), lambda state: state.can_collect('Small Key (Escape)'))
|
||||
set_rule(world.get_entrance('Sewers Door'), lambda state: state.has('Small Key (Escape)'))
|
||||
set_rule(world.get_entrance('Sewers Back Door'), lambda state: state.has('Small Key (Escape)'))
|
||||
|
||||
set_rule(world.get_location('[dungeon-L1-1F] Eastern Palace - Big Chest'), lambda state: state.can_collect('Big Key (Eastern Palace)'))
|
||||
set_rule(world.get_location('Armos - Heart Container'), lambda state: state.has('Bow') and state.can_collect('Big Key (Eastern Palace)'))
|
||||
set_rule(world.get_location('Armos - Pendant'), lambda state: state.has('Bow') and state.can_collect('Big Key (Eastern Palace)'))
|
||||
set_rule(world.get_location('[dungeon-L1-1F] Eastern Palace - Big Chest'), lambda state: state.has('Big Key (Eastern Palace)'))
|
||||
set_rule(world.get_location('Armos - Heart Container'), lambda state: state.has('Bow') and state.has('Big Key (Eastern Palace)'))
|
||||
set_rule(world.get_location('Armos - Pendant'), lambda state: state.has('Bow') and state.has('Big Key (Eastern Palace)'))
|
||||
for location in ['Armos - Heart Container', '[dungeon-L1-1F] Eastern Palace - Big Chest']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Eastern Palace)')
|
||||
|
||||
set_rule(world.get_location('[dungeon-L2-B1] Desert Palace - Big Chest'), lambda state: state.can_collect('Big Key (Desert Palace)'))
|
||||
set_rule(world.get_location('[dungeon-L2-B1] Desert Palace - Big Chest'), lambda state: state.has('Big Key (Desert Palace)'))
|
||||
set_rule(world.get_location('[dungeon-L2-B1] Desert Palace - Torch'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_entrance('Desert Palace East Wing'), lambda state: state.can_collect('Small Key (Desert Palace)'))
|
||||
set_rule(world.get_location('Lanmolas - Pendant'), lambda state: state.can_collect('Small Key (Desert Palace)') and state.can_collect('Big Key (Desert Palace)') and state.has_fire_source() and
|
||||
set_rule(world.get_entrance('Desert Palace East Wing'), lambda state: state.has('Small Key (Desert Palace)'))
|
||||
set_rule(world.get_location('Lanmolas - Pendant'), lambda state: state.has('Small Key (Desert Palace)') and state.has('Big Key (Desert Palace)') and state.has_fire_source() and
|
||||
(state.has_blunt_weapon() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Bow')))
|
||||
set_rule(world.get_location('Lanmolas - Heart Container'), lambda state: state.can_collect('Small Key (Desert Palace)') and state.can_collect('Big Key (Desert Palace)') and state.has_fire_source() and
|
||||
set_rule(world.get_location('Lanmolas - Heart Container'), lambda state: state.has('Small Key (Desert Palace)') and state.has('Big Key (Desert Palace)') and state.has_fire_source() and
|
||||
(state.has_blunt_weapon() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Bow')))
|
||||
for location in ['Lanmolas - Heart Container', '[dungeon-L2-B1] Desert Palace - Big Chest']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Desert Palace)')
|
||||
|
||||
set_rule(world.get_entrance('Tower of Hera Small Key Door'), lambda state: state.can_collect('Small Key (Tower of Hera)'))
|
||||
set_rule(world.get_entrance('Tower of Hera Big Key Door'), lambda state: state.can_collect('Big Key (Tower of Hera)'))
|
||||
set_rule(world.get_location('[dungeon-L3-1F] Tower of Hera - Big Chest'), lambda state: state.can_collect('Big Key (Tower of Hera)'))
|
||||
set_rule(world.get_entrance('Tower of Hera Small Key Door'), lambda state: state.has('Small Key (Tower of Hera)'))
|
||||
set_rule(world.get_entrance('Tower of Hera Big Key Door'), lambda state: state.has('Big Key (Tower of Hera)'))
|
||||
set_rule(world.get_location('[dungeon-L3-1F] Tower of Hera - Big Chest'), lambda state: state.has('Big Key (Tower of Hera)'))
|
||||
set_rule(world.get_location('[dungeon-L3-1F] Tower of Hera - Basement'), lambda state: state.has_fire_source())
|
||||
set_rule(world.get_location('Moldorm - Heart Container'), lambda state: state.has_blunt_weapon())
|
||||
set_rule(world.get_location('Moldorm - Pendant'), lambda state: state.has_blunt_weapon())
|
||||
|
@ -209,31 +210,31 @@ def global_rules(world):
|
|||
forbid_item(world.get_location(location), 'Big Key (Tower of Hera)')
|
||||
|
||||
set_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has('Flippers') and state.can_reach('Dam'))
|
||||
set_rule(world.get_entrance('Swamp Palace Small Key Door'), lambda state: state.can_collect('Small Key (Swamp Palace)'))
|
||||
set_rule(world.get_entrance('Swamp Palace Small Key Door'), lambda state: state.has('Small Key (Swamp Palace)'))
|
||||
set_rule(world.get_entrance('Swamp Palace (Center)'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_location('[dungeon-D2-B1] Swamp Palace - Big Chest'), lambda state: state.can_collect('Big Key (Swamp Palace)'))
|
||||
set_rule(world.get_location('[dungeon-D2-B1] Swamp Palace - Big Chest'), lambda state: state.has('Big Key (Swamp Palace)'))
|
||||
set_rule(world.get_entrance('Swamp Palace (North)'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_location('Arrghus - Heart Container'), lambda state: state.has_blunt_weapon())
|
||||
set_rule(world.get_location('Arrghus - Crystal'), lambda state: state.has_blunt_weapon())
|
||||
for location in ['[dungeon-D2-B1] Swamp Palace - Big Chest', '[dungeon-D2-1F] Swamp Palace - First Room']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Swamp Palace)')
|
||||
|
||||
set_rule(world.get_entrance('Thieves Town Big Key Door'), lambda state: state.can_collect('Big Key (Thieves Town)'))
|
||||
set_rule(world.get_entrance('Blind Fight'), lambda state: state.can_collect('Small Key (Thieves Town)') and (state.has_blunt_weapon() or state.has('Cane of Somaria')))
|
||||
set_rule(world.get_location('[dungeon-D4-B2] Thieves Town - Big Chest'), lambda state: state.can_collect('Small Key (Thieves Town)') and state.has('Hammer'))
|
||||
set_rule(world.get_location('[dungeon-D4-1F] Thieves Town - Room above Boss'), lambda state: state.can_collect('Small Key (Thieves Town)'))
|
||||
set_rule(world.get_entrance('Thieves Town Big Key Door'), lambda state: state.has('Big Key (Thieves Town)'))
|
||||
set_rule(world.get_entrance('Blind Fight'), lambda state: state.has('Small Key (Thieves Town)') and (state.has_blunt_weapon() or state.has('Cane of Somaria')))
|
||||
set_rule(world.get_location('[dungeon-D4-B2] Thieves Town - Big Chest'), lambda state: state.has('Small Key (Thieves Town)') and state.has('Hammer'))
|
||||
set_rule(world.get_location('[dungeon-D4-1F] Thieves Town - Room above Boss'), lambda state: state.has('Small Key (Thieves Town)'))
|
||||
for location in ['[dungeon-D4-1F] Thieves Town - Room above Boss', '[dungeon-D4-B2] Thieves Town - Big Chest', '[dungeon-D4-B2] Thieves Town - Chest next to Blind', 'Blind - Heart Container']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Thieves Town)')
|
||||
|
||||
set_rule(world.get_location('[dungeon-D3-B1] Skull Woods - Big Chest'), lambda state: state.can_collect('Big Key (Skull Woods)'))
|
||||
set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.can_collect('Small Key (Skull Woods)', 3) and state.has('Fire Rod') and state.has_sword()) # sword required for curtain
|
||||
set_rule(world.get_location('[dungeon-D3-B1] Skull Woods - Big Chest'), lambda state: state.has('Big Key (Skull Woods)'))
|
||||
set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.has('Small Key (Skull Woods)', 3) and state.has('Fire Rod') and state.has_sword()) # sword required for curtain
|
||||
for location in ['[dungeon-D3-B1] Skull Woods - Big Chest']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Skull Woods)')
|
||||
|
||||
set_rule(world.get_entrance('Ice Palace Entrance Room'), lambda state: state.has('Fire Rod') or (state.has('Bombos') and state.has_sword()))
|
||||
set_rule(world.get_location('[dungeon-D5-B5] Ice Palace - Big Chest'), lambda state: state.can_collect('Big Key (Ice Palace)'))
|
||||
set_rule(world.get_entrance('Ice Palace (Kholdstare)'), lambda state: state.can_lift_rocks() and state.has('Hammer') and state.can_collect('Big Key (Ice Palace)') and (state.can_collect('Small Key (Ice Palace)', 2) or (state.has('Cane of Somaria') and state.can_collect('Small Key (Ice Palace)', 1))))
|
||||
set_rule(world.get_entrance('Ice Palace (East)'), lambda state: state.has('Hookshot') or (state.can_collect('Small Key (Ice Palace)', 1) and ((state.world.get_location('[dungeon-D5-B3] Ice Palace - Spike Room').item is not None and state.world.get_location('[dungeon-D5-B3] Ice Palace - Spike Room').item.name in ['Big Key (Ice Palace)']) or
|
||||
set_rule(world.get_location('[dungeon-D5-B5] Ice Palace - Big Chest'), lambda state: state.has('Big Key (Ice Palace)'))
|
||||
set_rule(world.get_entrance('Ice Palace (Kholdstare)'), lambda state: state.can_lift_rocks() and state.has('Hammer') and state.has('Big Key (Ice Palace)') and (state.has('Small Key (Ice Palace)', 2) or (state.has('Cane of Somaria') and state.has('Small Key (Ice Palace)', 1))))
|
||||
set_rule(world.get_entrance('Ice Palace (East)'), lambda state: state.has('Hookshot') or (state.has('Small Key (Ice Palace)', 1) and ((state.world.get_location('[dungeon-D5-B3] Ice Palace - Spike Room').item is not None and state.world.get_location('[dungeon-D5-B3] Ice Palace - Spike Room').item.name in ['Big Key (Ice Palace)']) or
|
||||
(state.world.get_location('[dungeon-D5-B1] Ice Palace - Big Key Room').item is not None and state.world.get_location('[dungeon-D5-B1] Ice Palace - Big Key Room').item.name in ['Big Key (Ice Palace)']) or
|
||||
(state.world.get_location('[dungeon-D5-B2] Ice Palace - Map Room').item is not None and state.world.get_location('[dungeon-D5-B2] Ice Palace - Map Room').item.name in ['Big Key (Ice Palace)'])))) # if you do ipbj and waste SKs in the basement, you have to BJ over the hookshot room to fix your mess potentially. This seems fair
|
||||
set_rule(world.get_entrance('Ice Palace (East Top)'), lambda state: state.can_lift_rocks() and state.has('Hammer'))
|
||||
|
@ -241,13 +242,13 @@ def global_rules(world):
|
|||
forbid_item(world.get_location(location), 'Big Key (Ice Palace)')
|
||||
|
||||
set_rule(world.get_entrance('Misery Mire Entrance Gap'), lambda state: (state.has_Boots() or state.has('Hookshot')) and (state.has_sword() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Hammer') or state.has('Cane of Somaria') or state.has('Bow'))) # need to defeat wizzrobes, bombs don't work ...
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Big Chest'), lambda state: state.can_collect('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_entrance('Misery Mire Big Key Door'), lambda state: state.can_collect('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Big Chest'), lambda state: state.has('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_entrance('Misery Mire Big Key Door'), lambda state: state.has('Big Key (Misery Mire)'))
|
||||
# you can squander the free small key from the pot by opening the south door to the north west switch room, locking you out of accessing a color switch ...
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Hub Room'), lambda state: state.can_collect('Small Key (Misery Mire)', 1) or state.can_collect('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Map Room'), lambda state: state.can_collect('Small Key (Misery Mire)', 1) or state.can_collect('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Hub Room'), lambda state: state.has('Small Key (Misery Mire)', 1) or state.has('Big Key (Misery Mire)'))
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Map Room'), lambda state: state.has('Small Key (Misery Mire)', 1) or state.has('Big Key (Misery Mire)'))
|
||||
# we can place a small key in the West wing iff it also contains/blocks the Big Key, as we cannot reach and softlock with the basement key door yet
|
||||
set_rule(world.get_entrance('Misery Mire (West)'), lambda state: state.can_collect('Small Key (Misery Mire)', 3) if state.can_reach('Misery Mire (Final Area)') else state.can_collect('Small Key (Misery Mire)', 2))
|
||||
set_rule(world.get_entrance('Misery Mire (West)'), lambda state: state.has('Small Key (Misery Mire)', 3) if state.can_reach('Misery Mire (Final Area)') else state.has('Small Key (Misery Mire)', 2))
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Compass Room'), lambda state: state.has_fire_source())
|
||||
set_rule(world.get_location('[dungeon-D6-B1] Misery Mire - Big Key Room'), lambda state: state.has_fire_source())
|
||||
set_rule(world.get_entrance('Misery Mire (Vitreous)'), lambda state: state.has('Cane of Somaria') and (state.has('Bow') or state.has_blunt_weapon()))
|
||||
|
@ -260,16 +261,16 @@ def global_rules(world):
|
|||
set_rule(world.get_location('[dungeon-D7-1F] Turtle Rock - Compass Room'), lambda state: state.has('Cane of Somaria')) # We could get here from the middle section without Cane as we don't cross the entrance gap!
|
||||
set_rule(world.get_location('[dungeon-D7-1F] Turtle Rock - Map Room [left chest]'), lambda state: state.has('Cane of Somaria') and state.has('Fire Rod'))
|
||||
set_rule(world.get_location('[dungeon-D7-1F] Turtle Rock - Map Room [right chest]'), lambda state: state.has('Cane of Somaria') and state.has('Fire Rod'))
|
||||
set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.can_collect('Small Key (Turtle Rock)', 3) if state.can_reach('Turtle Rock (Dark Room) (North)', 'Entrance') else state.can_collect('Small Key (Turtle Rock)', 2) if state.can_reach('Turtle Rock (Eye Bridge)') else state.can_collect('Small Key (Turtle Rock)', 1)) # May waste keys from back entrance if accessible
|
||||
set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)'), lambda state: state.can_collect('Small Key (Turtle Rock)', 4)) # Just to be save
|
||||
set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (North)'), lambda state: state.can_collect('Small Key (Turtle Rock)', 4) if state.can_reach('Turtle Rock (Dark Room) (North)', 'Entrance') else state.can_collect('Small Key (Turtle Rock)', 3) if state.can_reach('Turtle Rock (Eye Bridge)') else state.can_collect('Small Key (Turtle Rock)', 2)) # May waste keys from back entrance if accessible
|
||||
set_rule(world.get_location('[dungeon-D7-B1] Turtle Rock - Big Chest'), lambda state: state.can_collect('Big Key (Turtle Rock)') and (state.has('Cane of Somaria') or state.has('Hookshot')))
|
||||
set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.has('Small Key (Turtle Rock)', 3) if state.can_reach('Turtle Rock (Dark Room) (North)', 'Entrance') else state.has('Small Key (Turtle Rock)', 2) if state.can_reach('Turtle Rock (Eye Bridge)') else state.has('Small Key (Turtle Rock)', 1)) # May waste keys from back entrance if accessible
|
||||
set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)'), lambda state: state.has('Small Key (Turtle Rock)', 4)) # Just to be save
|
||||
set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (North)'), lambda state: state.has('Small Key (Turtle Rock)', 4) if state.can_reach('Turtle Rock (Dark Room) (North)', 'Entrance') else state.has('Small Key (Turtle Rock)', 3) if state.can_reach('Turtle Rock (Eye Bridge)') else state.has('Small Key (Turtle Rock)', 2)) # May waste keys from back entrance if accessible
|
||||
set_rule(world.get_location('[dungeon-D7-B1] Turtle Rock - Big Chest'), lambda state: state.has('Big Key (Turtle Rock)') and (state.has('Cane of Somaria') or state.has('Hookshot')))
|
||||
set_rule(world.get_entrance('Turtle Rock (Big Chest) (North)'), lambda state: state.has('Cane of Somaria') or state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Turtle Rock Big Key Door'), lambda state: state.can_collect('Big Key (Turtle Rock)'))
|
||||
set_rule(world.get_entrance('Turtle Rock Dark Room Staircase'), lambda state: state.can_collect('Small Key (Turtle Rock)', 3))
|
||||
set_rule(world.get_entrance('Turtle Rock Big Key Door'), lambda state: state.has('Big Key (Turtle Rock)'))
|
||||
set_rule(world.get_entrance('Turtle Rock Dark Room Staircase'), lambda state: state.has('Small Key (Turtle Rock)', 3))
|
||||
set_rule(world.get_entrance('Turtle Rock (Dark Room) (North)'), lambda state: state.has('Cane of Somaria'))
|
||||
set_rule(world.get_entrance('Turtle Rock (Dark Room) (South)'), lambda state: state.has('Cane of Somaria'))
|
||||
set_rule(world.get_entrance('Turtle Rock (Trinexx)'), lambda state: state.can_collect('Small Key (Turtle Rock)', 4) and state.can_collect('Big Key (Turtle Rock)') and
|
||||
set_rule(world.get_entrance('Turtle Rock (Trinexx)'), lambda state: state.has('Small Key (Turtle Rock)', 4) and state.has('Big Key (Turtle Rock)') and
|
||||
state.has('Cane of Somaria') and state.has('Fire Rod') and state.has('Ice Rod') and
|
||||
(state.has('Hammer') or state.has_beam_sword() or state.has('Bottle') or state.has('Half Magic') or state.has('Quarter Magic')))
|
||||
for location in ['[dungeon-D7-B1] Turtle Rock - Big Chest', 'Trinexx - Heart Container', '[dungeon-D7-B1] Turtle Rock - Roller Switch Room', '[dungeon-D7-B2] Turtle Rock - Eye Bridge Room [bottom left chest]',
|
||||
|
@ -278,13 +279,13 @@ def global_rules(world):
|
|||
|
||||
set_rule(world.get_entrance('Dark Palace Bonk Wall'), lambda state: state.has('Bow'))
|
||||
set_rule(world.get_entrance('Dark Palace Hammer Peg Drop'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Dark Palace Bridge Room'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 1)) # If we can reach any other small key door, we already have back door access to this area
|
||||
set_rule(world.get_entrance('Dark Palace Big Key Door'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 6) and state.can_collect('Big Key (Palace of Darkness)') and state.has('Bow') and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Dark Palace Big Key Chest Staircase'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 6) or (state.world.get_location('[dungeon-D1-1F] Dark Palace - Big Key Room').item is not None and (state.world.get_location('[dungeon-D1-1F] Dark Palace - Big Key Room').item.name in ['Small Key (Palace of Darkness)'])))
|
||||
set_rule(world.get_entrance('Dark Palace Spike Statue Room Door'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 6) or (state.world.get_location('[dungeon-D1-1F] Dark Palace - Spike Statue Room').item is not None and (state.world.get_location('[dungeon-D1-1F] Dark Palace - Spike Statue Room').item.name in ['Small Key (Palace of Darkness)'])))
|
||||
set_rule(world.get_entrance('Dark Palace (North)'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 4))
|
||||
set_rule(world.get_entrance('Dark Palace Maze Door'), lambda state: state.can_collect('Small Key (Palace of Darkness)', 6))
|
||||
set_rule(world.get_location('[dungeon-D1-1F] Dark Palace - Big Chest'), lambda state: state.can_collect('Big Key (Palace of Darkness)'))
|
||||
set_rule(world.get_entrance('Dark Palace Bridge Room'), lambda state: state.has('Small Key (Palace of Darkness)', 1)) # If we can reach any other small key door, we already have back door access to this area
|
||||
set_rule(world.get_entrance('Dark Palace Big Key Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) and state.has('Big Key (Palace of Darkness)') and state.has('Bow') and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Dark Palace Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (state.world.get_location('[dungeon-D1-1F] Dark Palace - Big Key Room').item is not None and (state.world.get_location('[dungeon-D1-1F] Dark Palace - Big Key Room').item.name in ['Small Key (Palace of Darkness)'])))
|
||||
set_rule(world.get_entrance('Dark Palace Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (state.world.get_location('[dungeon-D1-1F] Dark Palace - Spike Statue Room').item is not None and (state.world.get_location('[dungeon-D1-1F] Dark Palace - Spike Statue Room').item.name in ['Small Key (Palace of Darkness)'])))
|
||||
set_rule(world.get_entrance('Dark Palace (North)'), lambda state: state.has('Small Key (Palace of Darkness)', 4))
|
||||
set_rule(world.get_entrance('Dark Palace Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6))
|
||||
set_rule(world.get_location('[dungeon-D1-1F] Dark Palace - Big Chest'), lambda state: state.has('Big Key (Palace of Darkness)'))
|
||||
for location in ['[dungeon-D1-1F] Dark Palace - Big Chest', 'Helmasaur - Heart Container']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Palace of Darkness)')
|
||||
|
||||
|
@ -292,19 +293,20 @@ def global_rules(world):
|
|||
set_rule(world.get_location('[dungeon-A2-1F] Ganons Tower - Torch'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_entrance('Ganons Tower (Tile Room)'), lambda state: state.has('Cane of Somaria'))
|
||||
set_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.can_collect('Small Key (Ganons Tower)', 3) or (state.world.get_location('[dungeon-A2-1F] Ganons Tower - Map Room').item is not None and state.world.get_location('[dungeon-A2-1F] Ganons Tower - Map Room').item.name == 'Small Key (Ganons Tower)'))
|
||||
set_rule(world.get_entrance('Ganons Tower (Double Switch Room)'), lambda state: state.can_collect('Small Key (Ganons Tower)', 2))
|
||||
set_rule(world.get_entrance('Ganons Tower (Firesnake Room)'), lambda state: state.can_collect('Small Key (Ganons Tower)', 3))
|
||||
set_rule(world.get_entrance('Ganons Tower (Tile Room) Key Door'), lambda state: state.can_collect('Small Key (Ganons Tower)', 3)) # possibly too pessimistic
|
||||
set_rule(world.get_location('[dungeon-A2-1F] Ganons Tower - Big Chest'), lambda state: state.can_collect('Big Key (Ganons Tower)'))
|
||||
set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3) or (state.world.get_location('[dungeon-A2-1F] Ganons Tower - Map Room').item is not None and state.world.get_location('[dungeon-A2-1F] Ganons Tower - Map Room').item.name == 'Small Key (Ganons Tower)'))
|
||||
set_rule(world.get_entrance('Ganons Tower (Double Switch Room)'), lambda state: state.has('Small Key (Ganons Tower)', 2))
|
||||
set_rule(world.get_entrance('Ganons Tower (Firesnake Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3))
|
||||
set_rule(world.get_entrance('Ganons Tower (Tile Room) Key Door'), lambda state: state.has('Small Key (Ganons Tower)', 3)) # possibly too pessimistic
|
||||
set_rule(world.get_location('[dungeon-A2-1F] Ganons Tower - Big Chest'), lambda state: state.has('Big Key (Ganons Tower)'))
|
||||
set_rule(world.get_location('[dungeon-A2-B1] Ganons Tower - Armos Room [left chest]'), lambda state: state.has('Bow') or state.has_blunt_weapon())
|
||||
set_rule(world.get_location('[dungeon-A2-B1] Ganons Tower - Armos Room [bottom chest]'), lambda state: state.has('Bow') or state.has_blunt_weapon())
|
||||
set_rule(world.get_location('[dungeon-A2-B1] Ganons Tower - Armos Room [right chest]'), lambda state: state.has('Bow') or state.has_blunt_weapon())
|
||||
set_rule(world.get_entrance('Ganons Tower Big Key Door'), lambda state: state.can_collect('Big Key (Ganons Tower)') and state.has('Bow'))
|
||||
set_rule(world.get_entrance('Ganons Tower Big Key Door'), lambda state: state.has('Big Key (Ganons Tower)') and state.has('Bow'))
|
||||
set_rule(world.get_entrance('Ganons Tower Torch Rooms'), lambda state: state.has_fire_source())
|
||||
set_rule(world.get_entrance('Ganons Tower Moldorm Door'), lambda state: state.can_collect('Small Key (Ganons Tower)', 4))
|
||||
set_rule(world.get_entrance('Ganons Tower Moldorm Door'), lambda state: state.has('Small Key (Ganons Tower)', 4))
|
||||
set_rule(world.get_entrance('Ganons Tower Moldorm Gap'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.can_reach('East Dark World') and (state.has_sword() or state.has('Bottle') or state.has('Bug Catching Net'))) # some obscure hammer on pyramid soft lock potential scenarios
|
||||
set_rule(world.get_location('Agahnim 2'), lambda state: state.has_sword() or state.has('Hammer') or state.has('Bug Catching Net'))
|
||||
set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.has('Beat Agahnim 2'))
|
||||
for location in ['[dungeon-A2-1F] Ganons Tower - Big Chest', '[dungeon-A2-6F] Ganons Tower - Mini Helmasaur Room [left chest]', '[dungeon-A2-6F] Ganons Tower - Mini Helmasaur Room [right chest]',
|
||||
'[dungeon-A2-6F] Ganons Tower - Room before Moldorm', '[dungeon-A2-6F] Ganons Tower - Moldorm Room']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Ganons Tower)')
|
||||
|
@ -453,7 +455,7 @@ def set_big_bomb_rules(world):
|
|||
'Mimic Cave Mirror Spot']
|
||||
Isolated_LW_entrances =['Capacity Upgrade',
|
||||
'Hookshot Fairy']
|
||||
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.can_collect('Crystal 5') and state.can_collect('Crystal 6'))
|
||||
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
|
||||
if bombshop_entrance.name in Normal_LW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()) or state.has_Mirror())
|
||||
elif bombshop_entrance.name in LW_walkable_entrances:
|
||||
|
|
Loading…
Reference in New Issue