Directional typos on interior doors fixed.

Better batching support for mass testing of seed generation.

Generation issues fixed:
--Filler now tests with the key in the proposed location to enable alternate key rules
--Key rule checker now only considers key locations that the parent sphere did not have - better key rules
This commit is contained in:
aerinon
2020-01-02 11:15:27 -07:00
parent 59f819aebd
commit 438d765627
7 changed files with 68 additions and 38 deletions

View File

@@ -1150,9 +1150,9 @@ def find_inaccessible_regions(world, player):
world.inaccessible_regions[player].append('Hyrule Castle Ledge') world.inaccessible_regions[player].append('Hyrule Castle Ledge')
world.inaccessible_regions[player].append('Sewer Drop') world.inaccessible_regions[player].append('Sewer Drop')
logger = logging.getLogger('') logger = logging.getLogger('')
logger.info('Inaccessible Regions:') logger.debug('Inaccessible Regions:')
for r in world.inaccessible_regions[player]: for r in world.inaccessible_regions[player]:
logger.info('%s', r) logger.debug('%s', r)
def valid_inaccessible_region(r): def valid_inaccessible_region(r):
@@ -1661,10 +1661,10 @@ interior_doors = [
('Skull Big Key WN', 'Skull Lone Pot EN'), ('Skull Big Key WN', 'Skull Lone Pot EN'),
('Skull Small Hall WS', 'Skull 2 West Lobby ES'), ('Skull Small Hall WS', 'Skull 2 West Lobby ES'),
('Skull 2 West Lobby NW', 'Skull X Room SW'), ('Skull 2 West Lobby NW', 'Skull X Room SW'),
('Skull 3 Lobby WN', 'Skull East Bridge EN'), ('Skull 3 Lobby EN', 'Skull East Bridge WN'),
('Skull East Bridge ES', 'Skull West Bridge Nook WS'), ('Skull East Bridge WS', 'Skull West Bridge Nook ES'),
('Skull Star Pits WS', 'Skull Torch Room ES'), ('Skull Star Pits ES', 'Skull Torch Room WS'),
('Skull Torch Room EN', 'Skull Vines WN'), ('Skull Torch Room WN', 'Skull Vines EN'),
('Skull Spike Corner ES', 'Skull Final Drop WS'), ('Skull Spike Corner ES', 'Skull Final Drop WS'),
('Thieves Hallway WS', 'Thieves Pot Alcove Mid ES'), ('Thieves Hallway WS', 'Thieves Pot Alcove Mid ES'),
('Thieves Conveyor Maze SW', 'Thieves Pot Alcove Top NW'), ('Thieves Conveyor Maze SW', 'Thieves Pot Alcove Top NW'),

View File

@@ -307,9 +307,9 @@ def create_doors(world, player):
create_door(player, 'PoD Lobby N', Intr).dir(No, 0x4a, Mid, High).pos(3), create_door(player, 'PoD Lobby N', Intr).dir(No, 0x4a, Mid, High).pos(3),
create_door(player, 'PoD Lobby NW', Intr).dir(No, 0x4a, Left, High).pos(0), create_door(player, 'PoD Lobby NW', Intr).dir(No, 0x4a, Left, High).pos(0),
create_door(player, 'PoD Lobby NE', Intr).dir(No, 0x4a, Right, High).pos(1), create_door(player, 'PoD Lobby NE', Intr).dir(No, 0x4a, Right, High).pos(1),
create_door(player, 'PoD Left Cage SW', Intr).dir(No, 0x4a, Left, High).pos(0), create_door(player, 'PoD Left Cage SW', Intr).dir(So, 0x4a, Left, High).pos(0),
create_door(player, 'PoD Middle Cage S', Intr).dir(No, 0x4a, Mid, High).pos(3), create_door(player, 'PoD Middle Cage S', Intr).dir(So, 0x4a, Mid, High).pos(3),
create_door(player, 'PoD Middle Cage SE', Intr).dir(No, 0x4a, Right, High).pos(1), create_door(player, 'PoD Middle Cage SE', Intr).dir(So, 0x4a, Right, High).pos(1),
create_door(player, 'PoD Left Cage Down Stairs', Sprl).dir(Dn, 0x4a, 1, HTH).ss(A, 0x12, 0x80, False, True), create_door(player, 'PoD Left Cage Down Stairs', Sprl).dir(Dn, 0x4a, 1, HTH).ss(A, 0x12, 0x80, False, True),
create_door(player, 'PoD Middle Cage Down Stairs', Sprl).dir(Dn, 0x4a, 0, HTH).ss(S, 0x12, 0x80, False, True), create_door(player, 'PoD Middle Cage Down Stairs', Sprl).dir(Dn, 0x4a, 0, HTH).ss(S, 0x12, 0x80, False, True),
create_door(player, 'PoD Middle Cage N', Nrml).dir(No, 0x4a, Mid, High).small_key().pos(2), create_door(player, 'PoD Middle Cage N', Nrml).dir(No, 0x4a, Mid, High).small_key().pos(2),
@@ -358,7 +358,7 @@ def create_doors(world, player):
create_door(player, 'PoD Dark Maze EN', Nrml).dir(Ea, 0x19, Top, High).small_key().pos(1), create_door(player, 'PoD Dark Maze EN', Nrml).dir(Ea, 0x19, Top, High).small_key().pos(1),
create_door(player, 'PoD Dark Maze E', Nrml).dir(Ea, 0x19, Mid, High).pos(0), create_door(player, 'PoD Dark Maze E', Nrml).dir(Ea, 0x19, Mid, High).pos(0),
create_door(player, 'PoD Compass Room WN', Intr).dir(We, 0x1a, Top, High).pos(4), create_door(player, 'PoD Compass Room WN', Intr).dir(We, 0x1a, Top, High).pos(4),
create_door(player, 'PoD Compass Room SE', Intr).dir(No, 0x1a, Mid, High).small_key().pos(0), create_door(player, 'PoD Compass Room SE', Intr).dir(So, 0x1a, Mid, High).small_key().pos(0),
create_door(player, 'PoD Harmless Hellway NE', Intr).dir(No, 0x1a, Right, High).small_key().pos(0), create_door(player, 'PoD Harmless Hellway NE', Intr).dir(No, 0x1a, Right, High).small_key().pos(0),
create_door(player, 'PoD Harmless Hellway SE', Nrml).dir(So, 0x1a, Right, High).pos(5), create_door(player, 'PoD Harmless Hellway SE', Nrml).dir(So, 0x1a, Right, High).pos(5),
create_door(player, 'PoD Compass Room W Down Stairs', Sprl).dir(Dn, 0x1a, 0, HTH).ss(S, 0x12, 0x50, True, True), create_door(player, 'PoD Compass Room W Down Stairs', Sprl).dir(Dn, 0x1a, 0, HTH).ss(S, 0x12, 0x50, True, True),
@@ -466,7 +466,7 @@ def create_doors(world, player):
create_door(player, 'Swamp Flooded Spot Ladder', Lgcl), create_door(player, 'Swamp Flooded Spot Ladder', Lgcl),
create_door(player, 'Swamp Flooded Room Ladder', Lgcl), create_door(player, 'Swamp Flooded Room Ladder', Lgcl),
create_door(player, 'Swamp Basement Shallows NW', Nrml).dir(No, 0x76, Left, High).toggler().pos(2), create_door(player, 'Swamp Basement Shallows NW', Nrml).dir(No, 0x76, Left, High).toggler().pos(2),
create_door(player, 'Swamp Basement Shallows EN', Intr).dir(We, 0x76, Top, High).pos(0), create_door(player, 'Swamp Basement Shallows EN', Intr).dir(Ea, 0x76, Top, High).pos(0),
create_door(player, 'Swamp Basement Shallows ES', Intr).dir(Ea, 0x76, Bot, High).pos(1), create_door(player, 'Swamp Basement Shallows ES', Intr).dir(Ea, 0x76, Bot, High).pos(1),
create_door(player, 'Swamp Waterfall Room SW', Nrml).dir(So, 0x66, Left, Low).toggler().pos(1), create_door(player, 'Swamp Waterfall Room SW', Nrml).dir(So, 0x66, Left, Low).toggler().pos(1),
create_door(player, 'Swamp Waterfall Room NW', Intr).dir(No, 0x66, Left, Low).pos(3), create_door(player, 'Swamp Waterfall Room NW', Intr).dir(No, 0x66, Left, Low).pos(3),
@@ -514,15 +514,15 @@ def create_doors(world, player):
create_door(player, 'Skull X Room SW', Intr).dir(So, 0x56, Left, High).small_key().pos(0), create_door(player, 'Skull X Room SW', Intr).dir(So, 0x56, Left, High).small_key().pos(0),
create_door(player, 'Skull Back Drop Star Path', Lgcl), create_door(player, 'Skull Back Drop Star Path', Lgcl),
create_door(player, 'Skull 3 Lobby NW', Nrml).dir(No, 0x59, Left, High).small_key().pos(0), create_door(player, 'Skull 3 Lobby NW', Nrml).dir(No, 0x59, Left, High).small_key().pos(0),
create_door(player, 'Skull 3 Lobby WN', Intr).dir(We, 0x59, Top, High).pos(2), create_door(player, 'Skull 3 Lobby EN', Intr).dir(Ea, 0x59, Top, High).pos(2),
create_door(player, 'Skull East Bridge EN', Intr).dir(Ea, 0x59, Top, High).pos(2), create_door(player, 'Skull East Bridge WN', Intr).dir(We, 0x59, Top, High).pos(2),
create_door(player, 'Skull East Bridge ES', Intr).dir(Ea, 0x59, Bot, High).pos(3), create_door(player, 'Skull East Bridge WS', Intr).dir(We, 0x59, Bot, High).pos(3),
create_door(player, 'Skull West Bridge Nook WS', Intr).dir(We, 0x59, Bot, High).pos(3), create_door(player, 'Skull West Bridge Nook ES', Intr).dir(Ea, 0x59, Bot, High).pos(3),
create_door(player, 'Skull Star Pits SW', Nrml).dir(So, 0x49, Left, High).small_key().pos(2), create_door(player, 'Skull Star Pits SW', Nrml).dir(So, 0x49, Left, High).small_key().pos(2),
create_door(player, 'Skull Star Pits WS', Intr).dir(We, 0x49, Bot, High).pos(3), create_door(player, 'Skull Star Pits ES', Intr).dir(Ea, 0x49, Bot, High).pos(3),
create_door(player, 'Skull Torch Room ES', Intr).dir(Ea, 0x49, Bot, High).pos(3), create_door(player, 'Skull Torch Room WS', Intr).dir(We, 0x49, Bot, High).pos(3),
create_door(player, 'Skull Torch Room EN', Intr).dir(Ea, 0x49, Top, High).pos(1), create_door(player, 'Skull Torch Room WN', Intr).dir(We, 0x49, Top, High).pos(1),
create_door(player, 'Skull Vines WN', Intr).dir(We, 0x49, Top, High).pos(1), create_door(player, 'Skull Vines EN', Intr).dir(Ea, 0x49, Top, High).pos(1),
create_door(player, 'Skull Vines NW', Nrml).dir(No, 0x49, Left, High).pos(0), create_door(player, 'Skull Vines NW', Nrml).dir(No, 0x49, Left, High).pos(0),
create_door(player, 'Skull Spike Corner SW', Nrml).dir(So, 0x39, Left, High).no_exit().trap(0x4).pos(0), create_door(player, 'Skull Spike Corner SW', Nrml).dir(So, 0x39, Left, High).no_exit().trap(0x4).pos(0),
create_door(player, 'Skull Spike Corner ES', Intr).dir(Ea, 0x39, Bot, High).small_key().pos(1), create_door(player, 'Skull Spike Corner ES', Intr).dir(Ea, 0x39, Bot, High).small_key().pos(1),
@@ -701,7 +701,7 @@ def create_doors(world, player):
create_door(player, 'Mire Lobby Gap', Lgcl), create_door(player, 'Mire Lobby Gap', Lgcl),
create_door(player, 'Mire Post-Gap Gap', Lgcl), create_door(player, 'Mire Post-Gap Gap', Lgcl),
create_door(player, 'Mire Post-Gap Down Stairs', Sprl).dir(Up, 0x98, 0, HTH).ss(X, 0x11, 0x90, False, True), create_door(player, 'Mire Post-Gap Down Stairs', Sprl).dir(Dn, 0x98, 0, HTH).ss(X, 0x11, 0x90, False, True),
create_door(player, 'Mire 2 Up Stairs', Sprl).dir(Up, 0xd2, 0, HTH).ss(X, 0x1a, 0x7c, False, True), create_door(player, 'Mire 2 Up Stairs', Sprl).dir(Up, 0xd2, 0, HTH).ss(X, 0x1a, 0x7c, False, True),
create_door(player, 'Mire 2 NE', Nrml).dir(No, 0xd2, Right, High).trap(0x4).pos(0), create_door(player, 'Mire 2 NE', Nrml).dir(No, 0xd2, Right, High).trap(0x4).pos(0),
create_door(player, 'Mire Hub SE', Nrml).dir(So, 0xc2, Right, High).pos(5), create_door(player, 'Mire Hub SE', Nrml).dir(So, 0xc2, Right, High).pos(5),
@@ -900,7 +900,7 @@ def create_doors(world, player):
create_door(player, 'GT Torch EN', Intr).dir(Ea, 0x8c, Top, High).small_key().pos(2), create_door(player, 'GT Torch EN', Intr).dir(Ea, 0x8c, Top, High).small_key().pos(2),
create_door(player, 'GT Hope Room WN', Intr).dir(We, 0x8c, Top, High).small_key().pos(2), create_door(player, 'GT Hope Room WN', Intr).dir(We, 0x8c, Top, High).small_key().pos(2),
create_door(player, 'GT Torch SW', Intr).dir(So, 0x8c, Left, High).no_exit().pos(1), create_door(player, 'GT Torch SW', Intr).dir(So, 0x8c, Left, High).no_exit().pos(1),
create_door(player, 'GT Big Chest NW', Intr).dir(So, 0x8c, Left, High).pos(1), create_door(player, 'GT Big Chest NW', Intr).dir(No, 0x8c, Left, High).pos(1),
create_door(player, 'GT Blocked Stairs Down Stairs', Sprl).dir(Dn, 0x8c, 3, HTH).ss(Z, 0x12, 0x40, True, True).kill(), create_door(player, 'GT Blocked Stairs Down Stairs', Sprl).dir(Dn, 0x8c, 3, HTH).ss(Z, 0x12, 0x40, True, True).kill(),
create_door(player, 'GT Blocked Stairs Block Path', Lgcl), create_door(player, 'GT Blocked Stairs Block Path', Lgcl),
create_door(player, 'GT Big Chest SW', Nrml).dir(So, 0x8c, Left, High).pos(4), create_door(player, 'GT Big Chest SW', Nrml).dir(So, 0x8c, Left, High).pos(4),

View File

@@ -8,6 +8,7 @@ import sys
from Main import main from Main import main
from Utils import is_bundled, close_console, output_path from Utils import is_bundled, close_console, output_path
from Fill import FillError
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
@@ -303,12 +304,22 @@ def start():
guiMain(args) guiMain(args)
elif args.count is not None: elif args.count is not None:
seed = args.seed seed = args.seed
failures = []
logger = logging.getLogger('')
for _ in range(args.count): for _ in range(args.count):
main(seed=seed, args=args) try:
main(seed=seed, args=args)
logger.info('Finished run %s', _+1)
except (FillError, Exception, RuntimeError) as err:
failures.append((err, seed))
logger.warning('Generation failed: %s', err)
seed = random.randint(0, 999999999) seed = random.randint(0, 999999999)
logging.getLogger('').info('Finished run %s', _) for fail in failures:
logger.info('%s seed failed with: %s', fail[1], fail[0])
logger.info('Generation fail rate: %f%%', 100*len(failures)/args.count)
else: else:
main(seed=args.seed, args=args) main(seed=args.seed, args=args)
if __name__ == '__main__': if __name__ == '__main__':
start() start()

10
Fill.py
View File

@@ -190,9 +190,17 @@ def fill_restrictive(world, base_state, locations, itempool):
for item_to_place in items_to_place: for item_to_place in items_to_place:
spot_to_fill = None spot_to_fill = None
for location in locations: for location in locations:
if location.can_fill(maximum_exploration_state, item_to_place, perform_access_check): if item_to_place.key: # a better test to see if a key can go there
location.item = item_to_place
test_state = maximum_exploration_state.copy()
test_state.stale[item_to_place.player] = True
else:
test_state = maximum_exploration_state
if location.can_fill(test_state, item_to_place, perform_access_check):
spot_to_fill = location spot_to_fill = location
break break
elif item_to_place.key:
location.item = None
if spot_to_fill is None: if spot_to_fill is None:
# we filled all reachable spots. Maybe the game can be beaten anyway? # we filled all reachable spots. Maybe the game can be beaten anyway?

View File

@@ -162,6 +162,13 @@ def queue_sorter(queue_item):
return 1 if door.bigKey else 0 return 1 if door.bigKey else 0
def queue_sorter_2(queue_item):
door, counter, key_only = queue_item
if door is None:
return 0
return 1 if door.bigKey else 0
def find_bk_locked_sections(key_layout, world): def find_bk_locked_sections(key_layout, world):
key_counters = key_layout.key_counters key_counters = key_layout.key_counters
key_logic = key_layout.key_logic key_logic = key_layout.key_logic
@@ -547,13 +554,13 @@ def flatten_pair_list(paired_list):
def check_rules(original_counter, key_layout): def check_rules(original_counter, key_layout):
all_key_only = set() all_key_only = set()
key_only_map = {} key_only_map = {}
queue = collections.deque([(None, original_counter)]) queue = collections.deque([(None, original_counter, original_counter.key_only_locations)])
completed = set() completed = set()
completed.add(cid(original_counter, key_layout)) completed.add(cid(original_counter, key_layout))
while len(queue) > 0: while len(queue) > 0:
queue = collections.deque(sorted(queue, key=queue_sorter)) queue = collections.deque(sorted(queue, key=queue_sorter_2))
access_door, counter = queue.popleft() access_door, counter, key_only_loc = queue.popleft()
for loc in counter.key_only_locations: for loc in key_only_loc:
if loc not in all_key_only: if loc not in all_key_only:
all_key_only.add(loc) all_key_only.add(loc)
access_rules = [] access_rules = []
@@ -561,16 +568,20 @@ def check_rules(original_counter, key_layout):
else: else:
access_rules = key_only_map[loc] access_rules = key_only_map[loc]
if access_door is None or access_door.name not in key_layout.key_logic.door_rules.keys(): if access_door is None or access_door.name not in key_layout.key_logic.door_rules.keys():
access_rules.append(DoorRules(0)) if access_door is None or not access_door.bigKey:
access_rules.append(DoorRules(0))
else: else:
access_rules.append(key_layout.key_logic.door_rules[access_door.name]) rule = key_layout.key_logic.door_rules[access_door.name]
if rule not in access_rules:
access_rules.append(rule)
for child in counter.child_doors.keys(): for child in counter.child_doors.keys():
if not child.bigKey or not key_layout.big_key_special or counter.big_key_opened: if not child.bigKey or not key_layout.big_key_special or counter.big_key_opened:
next_counter = find_next_counter(child, counter, key_layout) next_counter = find_next_counter(child, counter, key_layout)
c_id = cid(next_counter, key_layout) c_id = cid(next_counter, key_layout)
if c_id not in completed: if c_id not in completed:
completed.add(c_id) completed.add(c_id)
queue.append((child, next_counter)) new_key_only = dict_difference(next_counter.key_only_locations, counter.key_only_locations)
queue.append((child, next_counter, new_key_only))
min_rule_bk = defaultdict(list) min_rule_bk = defaultdict(list)
min_rule_non_bk = defaultdict(list) min_rule_non_bk = defaultdict(list)
check_non_bk = False check_non_bk = False

View File

@@ -432,12 +432,12 @@ def create_regions(world, player):
create_dungeon_region(player, 'Skull Back Drop', 'Skull Woods', None, ['Skull Back Drop Star Path', ]), create_dungeon_region(player, 'Skull Back Drop', 'Skull Woods', None, ['Skull Back Drop Star Path', ]),
create_dungeon_region(player, 'Skull 2 West Lobby', 'Skull Woods', ['Skull Woods - West Lobby Pot Key'], ['Skull 2 West Lobby ES', 'Skull 2 West Lobby NW', 'Skull Woods Second Section Exit (West)']), create_dungeon_region(player, 'Skull 2 West Lobby', 'Skull Woods', ['Skull Woods - West Lobby Pot Key'], ['Skull 2 West Lobby ES', 'Skull 2 West Lobby NW', 'Skull Woods Second Section Exit (West)']),
create_dungeon_region(player, 'Skull X Room', 'Skull Woods', None, ['Skull X Room SW']), create_dungeon_region(player, 'Skull X Room', 'Skull Woods', None, ['Skull X Room SW']),
create_dungeon_region(player, 'Skull 3 Lobby', 'Skull Woods', None, ['Skull 3 Lobby NW', 'Skull 3 Lobby WN', 'Skull Woods Final Section Exit']), create_dungeon_region(player, 'Skull 3 Lobby', 'Skull Woods', None, ['Skull 3 Lobby NW', 'Skull 3 Lobby EN', 'Skull Woods Final Section Exit']),
create_dungeon_region(player, 'Skull East Bridge', 'Skull Woods', None, ['Skull East Bridge EN', 'Skull East Bridge ES']), create_dungeon_region(player, 'Skull East Bridge', 'Skull Woods', None, ['Skull East Bridge WN', 'Skull East Bridge WS']),
create_dungeon_region(player, 'Skull West Bridge Nook', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull West Bridge Nook WS']), create_dungeon_region(player, 'Skull West Bridge Nook', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull West Bridge Nook ES']),
create_dungeon_region(player, 'Skull Star Pits', 'Skull Woods', None, ['Skull Star Pits SW', 'Skull Star Pits WS']), create_dungeon_region(player, 'Skull Star Pits', 'Skull Woods', None, ['Skull Star Pits SW', 'Skull Star Pits ES']),
create_dungeon_region(player, 'Skull Torch Room', 'Skull Woods', None, ['Skull Torch Room ES', 'Skull Torch Room EN']), create_dungeon_region(player, 'Skull Torch Room', 'Skull Woods', None, ['Skull Torch Room WS', 'Skull Torch Room WN']),
create_dungeon_region(player, 'Skull Vines', 'Skull Woods', None, ['Skull Vines WN', 'Skull Vines NW']), create_dungeon_region(player, 'Skull Vines', 'Skull Woods', None, ['Skull Vines EN', 'Skull Vines NW']),
create_dungeon_region(player, 'Skull Spike Corner', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop'], ['Skull Spike Corner SW', 'Skull Spike Corner ES']), create_dungeon_region(player, 'Skull Spike Corner', 'Skull Woods', ['Skull Woods - Spike Corner Key Drop'], ['Skull Spike Corner SW', 'Skull Spike Corner ES']),
create_dungeon_region(player, 'Skull Final Drop', 'Skull Woods', None, ['Skull Final Drop WS', 'Skull Final Drop Hole']), create_dungeon_region(player, 'Skull Final Drop', 'Skull Woods', None, ['Skull Final Drop WS', 'Skull Final Drop Hole']),
create_dungeon_region(player, 'Skull Boss', 'Skull Woods', ['Skull Woods - Boss', 'Skull Woods - Prize']), create_dungeon_region(player, 'Skull Boss', 'Skull Woods', ['Skull Woods - Boss', 'Skull Woods - Prize']),

View File

@@ -324,7 +324,7 @@ def global_rules(world, player):
set_defeat_dungeon_boss_rule(world.get_location('Swamp Palace - Prize', player)) set_defeat_dungeon_boss_rule(world.get_location('Swamp Palace - Prize', player))
set_rule(world.get_entrance('Skull Big Chest Hookpath', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_entrance('Skull Big Chest Hookpath', player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('Skull Torch Room EN', player), lambda state: state.has('Fire Rod', player)) set_rule(world.get_entrance('Skull Torch Room WN', player), lambda state: state.has('Fire Rod', player))
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: state.has_sword(player)) set_rule(world.get_entrance('Skull Vines NW', player), lambda state: state.has_sword(player))
set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Boss', player)) set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Boss', player))
set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Prize', player)) set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Prize', player))