Re-factoring polarity and branching issues

This commit is contained in:
aerinon
2020-01-24 16:44:20 -07:00
parent bd50ad9d77
commit dc9a4a1303

View File

@@ -1031,7 +1031,7 @@ class DungeonBuilder(object):
self.c_switch_present = False
self.dead_ends = 0
self.branches = 0
self.mag_needed = [False, False, False]
self.mag_needed = {}
self.unfulfilled = defaultdict(int)
self.all_entrances = None # used for sector segration/branching
self.entrance_list = None # used for overworld accessibility
@@ -1294,17 +1294,17 @@ def identify_polarity_issues(dungeon_map):
other_mag = sum_magnitude(others)
sector_mag = sector.magnitude()
check_flags(sector_mag, connection_flags)
for i in range(len(sector_mag)):
if sector_mag[i] > 0 and other_mag[i] == 0:
builder.mag_needed[i] = True
for i in PolSlot:
if sector_mag[i.value] > 0 and other_mag[i.value] == 0:
builder.mag_needed[i] = [x for x in PolSlot if other_mag[x.value] > 0]
if name not in unconnected_builders.keys():
unconnected_builders[name] = builder
ttl_mag = sum_magnitude(builder.sectors)
for slot in PolSlot:
for slot2 in PolSlot:
if ttl_mag[slot.value] > 0 and ttl_mag[slot2.value] > 0 and not connection_flags[slot][slot2]:
builder.mag_needed[slot.value] = True
builder.mag_needed[slot2.value] = True
builder.mag_needed[slot] = [slot2]
builder.mag_needed[slot2] = [slot]
if name not in unconnected_builders.keys():
unconnected_builders[name] = builder
return unconnected_builders
@@ -1333,7 +1333,7 @@ def identify_branching_issues(dungeon_map):
is_entrance = is_entrance_sector(builder, sector)
if is_entrance:
for door in sector.outstanding_doors:
dependent_doors = [x for x in sector.outstanding_doors if x != door]
dependent_doors = find_dependent_doors(door, sector)
if not door.blocked:
entrance_doors[hook_from_door(door)].append((door, dependent_doors))
else:
@@ -1344,7 +1344,7 @@ def identify_branching_issues(dungeon_map):
other_doors = []
one_way_flag = False
for door in sector.outstanding_doors:
dependent_doors = [x for x in sector.outstanding_doors if x != door]
dependent_doors = find_dependent_doors(door, sector)
if door.blocked or door.dead or (outflow <= 1 and len(dependent_doors) == 0):
unsatisfied_doors[hook_from_door(door)].append((door, dependent_doors))
one_way_flag = True
@@ -1373,19 +1373,62 @@ def identify_branching_issues(dungeon_map):
builder.unfulfilled[hook] += len(door_list)
satisfied = True
continue
used_doors.add(candidate)
used_doors.add(match_maker)
if candidate_is_unsated and len(match_deps) == 1:
for door in match_deps:
door_list = multi_purpose[hook_from_door(door)]
pair = find_door_in_list(door, door_list)
if pair[0] is not None:
door_list.remove(pair)
unsatisfied_doors[hook_from_door(door)].append((pair))
used_doors.add((candidate, match_maker))
# used_doors.add(match_maker)
cull_dependents(match_deps, match_list, match_maker, unsatisfied_doors)
if not candidate_is_unsated:
cull_dependents(dep_list, match_list, candidate, unsatisfied_doors)
satisfied = is_satisfied([unsatisfied_doors, entrance_doors, satisfying_doors, multi_purpose])
return unconnected_builders
def find_dependent_doors(door, sector):
dependent_doors = []
start_region = door.entrance.parent_region
visited = {start_region}
queue = deque([start_region])
found_events = set()
event_doors = set()
while len(queue) > 0:
region = queue.popleft()
for loc in region.locations:
if loc.name in dungeon_events:
found_events.add(loc.name)
for d in event_doors:
next = d.entrance.parent_region
if d.req_event in found_events and next not in visited and next.type == RegionType.Dungeon:
visited.add(next)
queue.append(next)
for ext in region.exits:
d = ext.door
if d is not None and d is not door and d in sector.outstanding_doors:
dependent_doors.append(d)
for ent in region.entrances:
next = ent.parent_region
d = ent.door
if d is not None:
if d.req_event is not None and d.req_event not in found_events:
event_doors.add(d)
elif next.type == RegionType.Dungeon and next not in visited:
visited.add(next)
queue.append(next)
return dependent_doors
def cull_dependents(dep_list, lists_to_cull, cullee, unsatisfied_doors):
for door in dep_list:
for list_to_cull in lists_to_cull:
door_list = list_to_cull[hook_from_door(door)]
pair = find_door_in_list(door, door_list)
if pair[0] is not None:
match_dep, rev_deps = pair
if cullee in rev_deps:
rev_deps.remove(cullee)
if len(rev_deps) < 1:
door_list.remove(pair)
unsatisfied_doors[hook_from_door(door)].append(pair)
def is_entrance_sector(builder, sector):
for entrance in builder.all_entrances:
r_set = sector.region_set()
@@ -1425,7 +1468,7 @@ def find_candidate_match(candidate, dep_list, check_deps, door_dict_list):
door_list = door_dict[dir]
pair = None
for match, match_deps in door_list:
if not check_deps or match not in dep_list:
if not check_deps or (match not in dep_list and candidate not in match_deps):
pair = match, match_deps
break
elif len(filter_match_deps(candidate, match_deps)) > 0:
@@ -1481,7 +1524,7 @@ def assign_polarized_sectors(dungeon_map, polarized_sectors, logger):
raise Exception('Cross Dungeon Builder: Cannot find a candidate for connectedness - restart?')
sector = random.choice(candidates)
assign_sector(sector, builder, polarized_sectors)
builder.mag_needed = [False, False, False]
builder.mag_needed = {}
unconnected_builders = identify_polarity_issues(unconnected_builders)
# step 2: fix neutrality issues
@@ -1529,10 +1572,12 @@ def find_connection_candidates(mag_needed, sector_pool):
continue
mag = sector.magnitude()
matches = False
for i, need in enumerate(mag_needed):
if need and mag[i] > 0:
matches = True
break
for slot, match_slot in mag_needed.items():
if mag[slot.value] > 0:
for i in PolSlot:
if i in match_slot and mag[i.value] > 0:
matches = True
break
if matches:
candidates.append(sector)
return candidates