Large refactor underway.
Wrote new main method Implemented trap door shuffle to some degree Still needs the other types
This commit is contained in:
@@ -68,16 +68,11 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon
|
||||
entrance_regions = [x for x in entrance_regions if x not in excluded.keys()]
|
||||
doors_to_connect, idx = {}, 0
|
||||
all_regions = set()
|
||||
bk_special = False
|
||||
for sector in builder.sectors:
|
||||
for door in sector.outstanding_doors:
|
||||
doors_to_connect[door.name] = door, idx
|
||||
idx += 1
|
||||
all_regions.update(sector.regions)
|
||||
bk_special |= check_for_special(sector.regions)
|
||||
bk_needed = False
|
||||
for sector in builder.sectors:
|
||||
bk_needed |= determine_if_bk_needed(sector, split_dungeon, bk_special, world, player)
|
||||
finished = False
|
||||
# flag if standard and this is hyrule castle
|
||||
paths = determine_paths_for_dungeon(world, player, all_regions, name)
|
||||
@@ -96,9 +91,9 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon
|
||||
if hash_code not in hash_code_set:
|
||||
hash_code_set.add(hash_code)
|
||||
explored_state = explore_proposal(name, entrance_regions, all_regions, proposed_map, doors_to_connect,
|
||||
bk_needed, bk_special, world, player)
|
||||
world, player)
|
||||
if check_valid(name, explored_state, proposed_map, doors_to_connect, all_regions,
|
||||
bk_needed, bk_special, paths, entrance_regions, world, player):
|
||||
paths, entrance_regions, world, player):
|
||||
finished = True
|
||||
else:
|
||||
proposed_map, hash_code = modify_proposal(proposed_map, explored_state, doors_to_connect,
|
||||
@@ -217,29 +212,21 @@ def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_se
|
||||
return proposed_map, hash_code
|
||||
|
||||
|
||||
def explore_proposal(name, entrance_regions, all_regions, proposed_map, valid_doors,
|
||||
bk_needed, bk_special, world, player):
|
||||
def explore_proposal(name, entrance_regions, all_regions, proposed_map, valid_doors, world, player):
|
||||
start = ExplorationState(dungeon=name)
|
||||
start.big_key_special = bk_special
|
||||
|
||||
bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed
|
||||
|
||||
def exception(d):
|
||||
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
||||
original_state = extend_reachable_state_improved(entrance_regions, start, proposed_map, all_regions,
|
||||
valid_doors, bk_flag, world, player, exception)
|
||||
original_state = extend_reachable_state_lenient(entrance_regions, start, proposed_map,
|
||||
all_regions, valid_doors, world, player)
|
||||
return original_state
|
||||
|
||||
|
||||
def check_valid(name, exploration_state, proposed_map, doors_to_connect, all_regions,
|
||||
bk_needed, bk_special, paths, entrance_regions, world, player):
|
||||
paths, entrance_regions, world, player):
|
||||
all_visited = set()
|
||||
all_visited.update(exploration_state.visited_blue)
|
||||
all_visited.update(exploration_state.visited_orange)
|
||||
if len(all_regions.difference(all_visited)) > 0:
|
||||
return False
|
||||
if not valid_paths(name, paths, entrance_regions, doors_to_connect, all_regions, proposed_map,
|
||||
bk_needed, bk_special, world, player):
|
||||
if not valid_paths(name, paths, entrance_regions, doors_to_connect, all_regions, proposed_map, world, player):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -262,8 +249,7 @@ def check_for_special(regions):
|
||||
return False
|
||||
|
||||
|
||||
def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, proposed_map,
|
||||
bk_needed, bk_special, world, player):
|
||||
def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, proposed_map, world, player):
|
||||
for path in paths:
|
||||
if type(path) is tuple:
|
||||
target = path[1]
|
||||
@@ -275,14 +261,12 @@ def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, propose
|
||||
else:
|
||||
target = path
|
||||
start_regions = entrance_regions
|
||||
if not valid_path(name, start_regions, target, valid_doors, proposed_map, all_regions,
|
||||
bk_needed, bk_special, world, player):
|
||||
if not valid_path(name, start_regions, target, valid_doors, proposed_map, all_regions, world, player):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_regions,
|
||||
bk_needed, bk_special, world, player):
|
||||
def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_regions, world, player):
|
||||
target_regions = set()
|
||||
if type(target) is not list:
|
||||
for region in all_regions:
|
||||
@@ -295,16 +279,11 @@ def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_re
|
||||
target_regions.add(region)
|
||||
|
||||
start = ExplorationState(dungeon=name)
|
||||
start.big_key_special = bk_special
|
||||
bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed
|
||||
|
||||
def exception(d):
|
||||
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
||||
original_state = extend_reachable_state_improved(starting_regions, start, proposed_map, all_regions,
|
||||
valid_doors, bk_flag, world, player, exception)
|
||||
original_state = extend_reachable_state_lenient(starting_regions, start, proposed_map, all_regions,
|
||||
valid_doors, world, player)
|
||||
|
||||
for exp_door in original_state.unattached_doors:
|
||||
if not exp_door.door.blocked:
|
||||
if not exp_door.door.blocked or exp_door.door.trapFlag != 0:
|
||||
return True # outstanding connection possible
|
||||
for target in target_regions:
|
||||
if original_state.visited_at_all(target):
|
||||
@@ -637,6 +616,37 @@ class ExplorationState(object):
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors, flag)
|
||||
|
||||
def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, flag, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if door in proposed_map and door.name in valid_doors:
|
||||
self.visited_doors.add(door)
|
||||
if self.can_traverse_ignore_traps(door):
|
||||
if door.controller is not None:
|
||||
door = door.controller
|
||||
if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors:
|
||||
if not self.in_door_list_ic(door, self.unattached_doors):
|
||||
self.append_door_to_list(door, self.unattached_doors, flag)
|
||||
else:
|
||||
other = self.find_door_in_list(door, self.unattached_doors)
|
||||
if self.crystal != other.crystal:
|
||||
other.crystal = CrystalBarrier.Either
|
||||
elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door,
|
||||
self.event_doors):
|
||||
self.append_door_to_list(door, self.event_doors, flag)
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors, flag)
|
||||
|
||||
def add_all_doors_check_proposed_traps(self, region, proposed_traps, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if self.can_traverse_ignore_traps(door) and door not in proposed_traps:
|
||||
if door.controller is not None:
|
||||
door = door.controller
|
||||
if door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door,
|
||||
self.event_doors):
|
||||
self.append_door_to_list(door, self.event_doors, False)
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors, False)
|
||||
|
||||
def add_all_doors_check_key_region(self, region, key_region, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if self.can_traverse(door):
|
||||
@@ -693,6 +703,13 @@ class ExplorationState(object):
|
||||
return self.crystal == CrystalBarrier.Either or door.crystal == self.crystal
|
||||
return True
|
||||
|
||||
def can_traverse_ignore_traps(self, door):
|
||||
if door.blocked and door.trapFlag == 0:
|
||||
return False
|
||||
if door.crystal not in [CrystalBarrier.Null, CrystalBarrier.Either]:
|
||||
return self.crystal == CrystalBarrier.Either or door.crystal == self.crystal
|
||||
return True
|
||||
|
||||
def count_locations_exclude_specials(self, world, player):
|
||||
return count_locations_exclude_big_chest(self.found_locations, world, player)
|
||||
|
||||
@@ -801,6 +818,25 @@ def extend_reachable_state_improved(search_regions, state, proposed_map, all_reg
|
||||
return local_state
|
||||
|
||||
|
||||
def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regions, valid_doors, world, player):
|
||||
local_state = state.copy()
|
||||
for region in search_regions:
|
||||
local_state.visit_region(region)
|
||||
local_state.add_all_doors_check_proposed_2(region, proposed_map, valid_doors, world, player)
|
||||
while len(local_state.avail_doors) > 0:
|
||||
explorable_door = local_state.next_avail_door()
|
||||
if explorable_door.door in proposed_map:
|
||||
connect_region = world.get_entrance(proposed_map[explorable_door.door].name, player).parent_region
|
||||
else:
|
||||
connect_region = world.get_entrance(explorable_door.door.name, player).connected_region
|
||||
if connect_region is not None:
|
||||
if (valid_region_to_explore_in_regions(connect_region, all_regions, world, player)
|
||||
and not local_state.visited(connect_region)):
|
||||
local_state.visit_region(connect_region)
|
||||
local_state.add_all_doors_check_proposed_2(connect_region, proposed_map, valid_doors, world, player)
|
||||
return local_state
|
||||
|
||||
|
||||
def special_big_key_found(state):
|
||||
for location in state.found_locations:
|
||||
if location.forced_item and location.forced_item.bigkey:
|
||||
|
||||
Reference in New Issue
Block a user