Simple key logic for Escape
Adds ability to make a location for required keys (enemy drops and pots), so the filler knows about them. Uses the most pessimistic possible rule to make sure you can't keylock yourself in Escape.
This commit is contained in:
@@ -898,17 +898,24 @@ class Boss(object):
|
|||||||
return self.defeat_rule(state, self.player)
|
return self.defeat_rule(state, self.player)
|
||||||
|
|
||||||
class Location(object):
|
class Location(object):
|
||||||
def __init__(self, player, name='', address=None, crystal=False, hint_text=None, parent=None):
|
def __init__(self, player, name='', address=None, crystal=False, hint_text=None, parent=None, forced_item=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.parent_region = parent
|
self.parent_region = parent
|
||||||
self.item = None
|
if forced_item is not None:
|
||||||
|
from Items import ItemFactory
|
||||||
|
self.forced_item = ItemFactory([forced_item], player)[0]
|
||||||
|
self.item = self.forced_item
|
||||||
|
self.event = True
|
||||||
|
else:
|
||||||
|
self.forced_item = None
|
||||||
|
self.item = None
|
||||||
|
self.event = False
|
||||||
self.crystal = crystal
|
self.crystal = crystal
|
||||||
self.address = address
|
self.address = address
|
||||||
self.spot_type = 'Location'
|
self.spot_type = 'Location'
|
||||||
self.hint_text = hint_text if hint_text is not None else 'Hyrule'
|
self.hint_text = hint_text if hint_text is not None else 'Hyrule'
|
||||||
self.recursion_count = 0
|
self.recursion_count = 0
|
||||||
self.staleness_count = 0
|
self.staleness_count = 0
|
||||||
self.event = False
|
|
||||||
self.locked = True
|
self.locked = True
|
||||||
self.always_allow = lambda item, state: False
|
self.always_allow = lambda item, state: False
|
||||||
self.access_rule = lambda state: True
|
self.access_rule = lambda state: True
|
||||||
|
|||||||
16
Regions.py
16
Regions.py
@@ -296,13 +296,13 @@ def create_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Hyrule Castle Back Hall', 'A dungeon', None, ['Hyrule Castle Back Hall E', 'Hyrule Castle Back Hall W', 'Hyrule Castle Back Hall Down Stairs']),
|
create_dungeon_region(player, 'Hyrule Castle Back Hall', 'A dungeon', None, ['Hyrule Castle Back Hall E', 'Hyrule Castle Back Hall W', 'Hyrule Castle Back Hall Down Stairs']),
|
||||||
create_dungeon_region(player, 'Hyrule Castle Throne Room', 'A dungeon', None, ['Hyrule Castle Throne Room N', 'Hyrule Castle Throne Room South Stairs']),
|
create_dungeon_region(player, 'Hyrule Castle Throne Room', 'A dungeon', None, ['Hyrule Castle Throne Room N', 'Hyrule Castle Throne Room South Stairs']),
|
||||||
|
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Map Room', 'A dungeon', ['Hyrule Castle - Map Chest'], ['Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon Map Room Up Stairs']),
|
create_dungeon_region(player, 'Hyrule Dungeon Map Room', 'A dungeon', ['Hyrule Castle - Map Chest', 'Hyrule Castle - Map Guard Key Drop'], ['Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon Map Room Up Stairs']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon North Abyss', 'A dungeon', None, ['Hyrule Dungeon North Abyss South Edge', 'Hyrule Dungeon North Abyss Key Door N']),
|
create_dungeon_region(player, 'Hyrule Dungeon North Abyss', 'A dungeon', None, ['Hyrule Dungeon North Abyss South Edge', 'Hyrule Dungeon North Abyss Key Door N']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon North Abyss Catwalk', 'A dungeon', None, ['Hyrule Dungeon North Abyss Catwalk Edge', 'Hyrule Dungeon North Abyss Catwalk Dropdown']),
|
create_dungeon_region(player, 'Hyrule Dungeon North Abyss Catwalk', 'A dungeon', None, ['Hyrule Dungeon North Abyss Catwalk Edge', 'Hyrule Dungeon North Abyss Catwalk Dropdown']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon South Abyss', 'A dungeon', None, ['Hyrule Dungeon South Abyss North Edge', 'Hyrule Dungeon South Abyss West Edge']),
|
create_dungeon_region(player, 'Hyrule Dungeon South Abyss', 'A dungeon', None, ['Hyrule Dungeon South Abyss North Edge', 'Hyrule Dungeon South Abyss West Edge']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon South Abyss Catwalk', 'A dungeon', None, ['Hyrule Dungeon South Abyss Catwalk North Edge', 'Hyrule Dungeon South Abyss Catwalk West Edge']),
|
create_dungeon_region(player, 'Hyrule Dungeon South Abyss Catwalk', 'A dungeon', None, ['Hyrule Dungeon South Abyss Catwalk North Edge', 'Hyrule Dungeon South Abyss Catwalk West Edge']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Guardroom', 'A dungeon', None, ['Hyrule Dungeon Guardroom Catwalk Edge', 'Hyrule Dungeon Guardroom Abyss Edge', 'Hyrule Dungeon Guardroom N']),
|
create_dungeon_region(player, 'Hyrule Dungeon Guardroom', 'A dungeon', None, ['Hyrule Dungeon Guardroom Catwalk Edge', 'Hyrule Dungeon Guardroom Abyss Edge', 'Hyrule Dungeon Guardroom N']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Armory Main', 'A dungeon', ['Hyrule Castle - Boomerang Chest'], ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory Interior Key Door N']),
|
create_dungeon_region(player, 'Hyrule Dungeon Armory Main', 'A dungeon', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Boomerang Guard Key Drop'], ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory Interior Key Door N']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Armory North Branch', 'A dungeon', None, ['Hyrule Dungeon Armory Interior Key Door S', 'Hyrule Dungeon Armory Down Stairs']),
|
create_dungeon_region(player, 'Hyrule Dungeon Armory North Branch', 'A dungeon', None, ['Hyrule Dungeon Armory Interior Key Door S', 'Hyrule Dungeon Armory Down Stairs']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Staircase', 'A dungeon', None, ['Hyrule Dungeon Staircase Up Stairs', 'Hyrule Dungeon Staircase Down Stairs']),
|
create_dungeon_region(player, 'Hyrule Dungeon Staircase', 'A dungeon', None, ['Hyrule Dungeon Staircase Up Stairs', 'Hyrule Dungeon Staircase Down Stairs']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Cellblock', 'A dungeon', ['Hyrule Castle - Zelda\'s Chest'], ['Hyrule Dungeon Cellblock Up Stairs']),
|
create_dungeon_region(player, 'Hyrule Dungeon Cellblock', 'A dungeon', ['Hyrule Castle - Zelda\'s Chest'], ['Hyrule Dungeon Cellblock Up Stairs']),
|
||||||
@@ -389,8 +389,11 @@ def _create_region(player, name, type, hint='Hyrule', locations=None, exits=None
|
|||||||
for exit in exits:
|
for exit in exits:
|
||||||
ret.exits.append(Entrance(player, exit, ret))
|
ret.exits.append(Entrance(player, exit, ret))
|
||||||
for location in locations:
|
for location in locations:
|
||||||
address, crystal, hint_text = location_table[location]
|
if location in key_only_locations:
|
||||||
ret.locations.append(Location(player, location, address, crystal, hint_text, ret))
|
ret.locations.append(Location(player, location, None, False, None, ret, key_only_locations[location]))
|
||||||
|
else:
|
||||||
|
address, crystal, hint_text = location_table[location]
|
||||||
|
ret.locations.append(Location(player, location, address, crystal, hint_text, ret))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def mark_light_world_regions(world):
|
def mark_light_world_regions(world):
|
||||||
@@ -456,6 +459,11 @@ default_shop_contents = {
|
|||||||
'Potion Shop': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
|
'Potion Shop': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key_only_locations = {
|
||||||
|
'Hyrule Castle - Map Guard Key Drop': 'Small Key (Escape)',
|
||||||
|
'Hyrule Castle - Boomerang Guard Key Drop': 'Small Key (Escape)'
|
||||||
|
}
|
||||||
|
|
||||||
location_table = {'Mushroom': (0x180013, False, 'in the woods'),
|
location_table = {'Mushroom': (0x180013, False, 'in the woods'),
|
||||||
'Bottle Merchant': (0x2eb18, False, 'with a merchant'),
|
'Bottle Merchant': (0x2eb18, False, 'with a merchant'),
|
||||||
'Flute Spot': (0x18014a, False, 'underground'),
|
'Flute Spot': (0x18014a, False, 'underground'),
|
||||||
|
|||||||
11
Rules.py
11
Rules.py
@@ -262,6 +262,17 @@ def global_rules(world, player):
|
|||||||
# TODO: Do these need to flag off when door rando is off?
|
# TODO: Do these need to flag off when door rando is off?
|
||||||
# TODO: Can these replace other rules?
|
# TODO: Can these replace other rules?
|
||||||
|
|
||||||
|
# Hyrule Castle: Can't get keys from guards unless you can kill said guards.
|
||||||
|
add_rule(world.get_location('Hyrule Castle - Map Guard Key Drop', player), lambda state: state.can_kill_most_things(player))
|
||||||
|
add_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), lambda state: state.can_kill_most_things(player))
|
||||||
|
|
||||||
|
# Hyrule Castle: There are three keys and we don't know how we shuffled, so we
|
||||||
|
# need three keys to be accessible before you use any of these doors.
|
||||||
|
# TODO: Generate key rules in the shuffler. (But make sure this way works first.)
|
||||||
|
for door in ['Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S',
|
||||||
|
'Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S', 'Hyrule Dungeon Armory Interior Key Door N', 'Hyrule Dungeon Armory Interior Key Door S', 'Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon North Abyss Key Door N']:
|
||||||
|
set_rule(world.get_entrance(door, player), lambda state: state.has_key('Small Key (Escape)', player, 3))
|
||||||
|
|
||||||
# Sewers: All sorts of things need lamps
|
# Sewers: All sorts of things need lamps
|
||||||
# TODO: Need to play nice with other complicated lamp rules
|
# TODO: Need to play nice with other complicated lamp rules
|
||||||
set_rule(world.get_entrance('Sewers Behind Tapestry S', player), lambda state: state.has('Lamp', player))
|
set_rule(world.get_entrance('Sewers Behind Tapestry S', player), lambda state: state.has('Lamp', player))
|
||||||
|
|||||||
Reference in New Issue
Block a user