Merged in DR v1.2.0.20

This commit is contained in:
codemann8
2023-08-07 15:30:50 -05:00
21 changed files with 376 additions and 76 deletions

View File

@@ -1677,10 +1677,24 @@ def assign_location_sectors_minimal(dungeon_map, free_location_sectors, global_p
random.shuffle(sector_list)
orig_location_set = build_orig_location_set(dungeon_map)
num_dungeon_items = requested_dungeon_items(world, player)
locations_to_distribute = sum(sector.chest_locations for sector in free_location_sectors.keys())
reserved_per_dungeon = {d_name: count_reserved_locations(world, player, orig_location_set[d_name])
for d_name in dungeon_map.keys()}
base_free, found_enough = 2, False
while not found_enough:
needed = sum(max(0, max(base_free, reserved_per_dungeon[d]) + num_dungeon_items - len(orig_location_set[d]))
for d in dungeon_map.keys())
if needed > locations_to_distribute:
if base_free == 0:
raise Exception('Unable to meet minimum requirements, check for customizer problems')
base_free -= 1
else:
found_enough = True
d_idx = {builder.name: i for i, builder in enumerate(dungeon_map.values())}
next_sector = sector_list.pop()
while not valid:
choice, totals, location_set = weighted_random_location(dungeon_map, choices, orig_location_set, world, player)
choice, totals, location_set = weighted_random_location(dungeon_map, choices, orig_location_set,
base_free, world, player)
if not choice:
break
choices[choice].append(next_sector)
@@ -1691,7 +1705,7 @@ def assign_location_sectors_minimal(dungeon_map, free_location_sectors, global_p
valid = True
for d_name, idx in d_idx.items():
free_items = count_reserved_locations(world, player, location_set[d_name])
target = max(free_items, 2) + num_dungeon_items
target = max(free_items, base_free) + num_dungeon_items
if totals[idx] < target:
valid = False
break
@@ -1699,8 +1713,7 @@ def assign_location_sectors_minimal(dungeon_map, free_location_sectors, global_p
if len(sector_list) == 0:
choices = defaultdict(list)
sector_list = list(free_location_sectors)
else:
next_sector = sector_list.pop()
next_sector = sector_list.pop()
else:
choices[choice].remove(next_sector)
for builder, choice_list in choices.items():
@@ -1709,7 +1722,7 @@ def assign_location_sectors_minimal(dungeon_map, free_location_sectors, global_p
return free_location_sectors
def weighted_random_location(dungeon_map, choices, orig_location_set, world, player):
def weighted_random_location(dungeon_map, choices, orig_location_set, base_free, world, player):
population = []
totals = []
location_set = {x: set(y) for x, y in orig_location_set.items()}
@@ -1720,7 +1733,7 @@ def weighted_random_location(dungeon_map, choices, orig_location_set, world, pla
builder_set = location_set[dungeon_builder.name]
builder_set.update(set().union(*(s.chest_location_set for s in choices[dungeon_builder])))
free_items = count_reserved_locations(world, player, builder_set)
target = max(free_items, 2) + num_dungeon_items
target = max(free_items, base_free) + num_dungeon_items
if ttl < target:
population.append(dungeon_builder)
choice = random.choice(population) if len(population) > 0 else None
@@ -1775,7 +1788,7 @@ def count_reserved_locations(world, player, proposed_set):
return 2
def assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers, global_pole, assign_one=False):
def assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers, global_pole):
population = []
some_c_switches_present = False
for name, builder in dungeon_map.items():
@@ -1784,7 +1797,7 @@ def assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barrier
if builder.c_switch_present and not builder.c_locked:
some_c_switches_present = True
if len(population) == 0: # nothing needs a switch
if assign_one and not some_c_switches_present: # something should have one
if len(crystal_barriers) > 0 and not some_c_switches_present: # something should have one
if len(crystal_switches) == 0:
raise GenerationException('No crystal switches to assign. Ref %s' % next(iter(dungeon_map.keys())))
valid, builder_choice, switch_choice = False, None, None
@@ -3139,8 +3152,7 @@ def balance_split(candidate_sectors, dungeon_map, global_pole, builder_info):
check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole)
check_for_forced_crystal(dungeon_map, candidate_sectors, global_pole)
crystal_switches, crystal_barriers, neutral_sectors, polarized_sectors = categorize_sectors(candidate_sectors)
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers,
global_pole, len(crystal_barriers) > 0)
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers, global_pole)
ensure_crystal_switches_reachable(dungeon_map, leftover, polarized_sectors, crystal_barriers, global_pole)
for sector in leftover:
if sector.polarity().is_neutral():