Ban big keys from locations that will block required freestanding keys
TBD how to handle regular rules
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from collections import defaultdict, deque
|
||||
|
||||
from Regions import dungeon_events
|
||||
@@ -46,8 +47,9 @@ class KeyLogic(object):
|
||||
|
||||
class DoorRules(object):
|
||||
|
||||
def __init__(self, number):
|
||||
def __init__(self, number, is_valid):
|
||||
self.small_key_num = number
|
||||
self.is_valid = is_valid
|
||||
# allowing a different number if bk is behind this door in a set of locations
|
||||
self.alternate_small_key = None
|
||||
self.alternate_big_key_loc = set()
|
||||
@@ -144,6 +146,8 @@ def analyze_dungeon(key_layout, world, player):
|
||||
if not child.bigKey and child not in doors_completed:
|
||||
best_counter = find_best_counter(child, odd_counter, key_counter, key_layout, world, player, False, empty_flag)
|
||||
rule = create_rule(best_counter, key_counter, key_layout, world, player)
|
||||
if not rule.is_valid:
|
||||
logging.getLogger('').warning('Key logic for door %s requires too many chests. Seed may be beatable anyway.', child.name)
|
||||
if smallest_rule is None or rule.small_key_num < smallest_rule:
|
||||
smallest_rule = rule.small_key_num
|
||||
check_for_self_lock_key(rule, child, best_counter, key_layout, world, player)
|
||||
@@ -343,9 +347,10 @@ def create_rule(key_counter, prev_counter, key_layout, world, player):
|
||||
required_keys = key_counter.used_keys + 1 # this makes more sense, if key_counter has wasted all keys
|
||||
adj_chest_keys = min(chest_keys, required_keys)
|
||||
needed_chests = required_keys - len(key_counter.key_only_locations)
|
||||
is_valid = needed_chests <= chest_keys
|
||||
unneeded_chests = min(key_gain, adj_chest_keys - needed_chests)
|
||||
rule_num = required_keys - unneeded_chests
|
||||
return DoorRules(rule_num)
|
||||
return DoorRules(rule_num, is_valid)
|
||||
|
||||
|
||||
def check_for_self_lock_key(rule, door, parent_counter, key_layout, world, player):
|
||||
@@ -451,8 +456,8 @@ def bk_restricted_rules(rule, door, odd_counter, empty_flag, key_counter, key_la
|
||||
if key_counter.big_key_opened:
|
||||
return
|
||||
best_counter = find_best_counter(door, odd_counter, key_counter, key_layout, world, player, True, empty_flag)
|
||||
bk_number = create_rule(best_counter, key_counter, key_layout, world, player).small_key_num
|
||||
if bk_number == rule.small_key_num:
|
||||
bk_rule = create_rule(best_counter, key_counter, key_layout, world, player)
|
||||
if bk_rule.is_valid and bk_rule.small_key_num == rule.small_key_num:
|
||||
return
|
||||
door_open = find_next_counter(door, best_counter, key_layout)
|
||||
ignored_doors = dict_intersection(best_counter.child_doors, door_open.child_doors)
|
||||
@@ -463,10 +468,11 @@ def bk_restricted_rules(rule, door, odd_counter, empty_flag, key_counter, key_la
|
||||
ignored_doors = {**ignored_doors, **dict.fromkeys(dest_ignored)}
|
||||
post_counter = open_some_counter(door_open, key_layout, ignored_doors.keys())
|
||||
unique_loc = dict_difference(post_counter.free_locations, best_counter.free_locations)
|
||||
if len(unique_loc) > 0:
|
||||
rule.alternate_small_key = bk_number
|
||||
if bk_rule.is_valid and len(unique_loc) > 0:
|
||||
rule.alternate_small_key = bk_rule.small_key_num
|
||||
rule.alternate_big_key_loc.update(unique_loc)
|
||||
|
||||
elif not bk_rule.is_valid:
|
||||
key_layout.key_logic.bk_restricted.update(unique_loc)
|
||||
|
||||
def open_a_door(door, child_state, flat_proposal):
|
||||
if door.bigKey:
|
||||
@@ -604,7 +610,7 @@ def check_rules(original_counter, key_layout, world, player):
|
||||
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 not access_door.bigKey:
|
||||
access_rules.append(DoorRules(0))
|
||||
access_rules.append(DoorRules(0, True))
|
||||
else:
|
||||
rule = key_layout.key_logic.door_rules[access_door.name]
|
||||
if rule not in access_rules:
|
||||
|
||||
Reference in New Issue
Block a user