Initial approach to eliminating inaccessible regions resulting from OW Layout Shuffle

This commit is contained in:
codemann8
2021-11-30 11:37:20 -06:00
parent b4173044d7
commit 4e4b08da4f

View File

@@ -280,48 +280,58 @@ def link_overworld(world, player):
trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player) trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player)
groups = reorganize_groups(world, trimmed_groups, player) groups = reorganize_groups(world, trimmed_groups, player)
if world.mode[player] == 'standard': tries = 10
random.shuffle(groups[2:]) # keep first 2 groups (Standard) first valid_layout = False
else: connected_edge_cache = connected_edges.copy()
random.shuffle(groups) while not valid_layout and tries > 0:
connected_edges = connected_edge_cache.copy()
for (forward_edge_sets, back_edge_sets) in groups: if world.mode[player] == 'standard':
assert len(forward_edge_sets) == len(back_edge_sets) random.shuffle(groups[2:]) # keep first 2 groups (Standard) first
random.shuffle(forward_edge_sets) else:
random.shuffle(back_edge_sets) random.shuffle(groups)
if len(forward_edge_sets) > 0:
f = 0 for (forward_edge_sets, back_edge_sets) in groups:
b = 0 assert len(forward_edge_sets) == len(back_edge_sets)
while f < len(forward_edge_sets) and b < len(back_edge_sets): random.shuffle(forward_edge_sets)
forward_set = forward_edge_sets[f] random.shuffle(back_edge_sets)
back_set = back_edge_sets[b] if len(forward_edge_sets) > 0:
while forward_set[0] in connected_edges: f = 0
b = 0
while f < len(forward_edge_sets) and b < len(back_edge_sets):
forward_set = forward_edge_sets[f]
back_set = back_edge_sets[b]
while forward_set[0] in connected_edges:
f += 1
if f < len(forward_edge_sets):
forward_set = forward_edge_sets[f]
else:
forward_set = None
break
f += 1 f += 1
if f < len(forward_edge_sets): while back_set[0] in connected_edges:
forward_set = forward_edge_sets[f] b += 1
else: if b < len(back_edge_sets):
forward_set = None back_set = back_edge_sets[b]
break else:
f += 1 back_set = None
while back_set[0] in connected_edges: break
b += 1 b += 1
if b < len(back_edge_sets): if forward_set is not None and back_set is not None:
back_set = back_edge_sets[b] assert len(forward_set) == len(back_set)
else: for (forward_edge, back_edge) in zip(forward_set, back_set):
back_set = None connect_two_way(world, forward_edge, back_edge, player, connected_edges)
break elif forward_set is not None:
b += 1 logging.getLogger('').warning("Edge '%s' could not find a valid connection" % forward_set[0])
if forward_set is not None and back_set is not None: elif back_set is not None:
assert len(forward_set) == len(back_set) logging.getLogger('').warning("Edge '%s' could not find a valid connection" % back_set[0])
for (forward_edge, back_edge) in zip(forward_set, back_set): assert len(connected_edges) == len(default_connections) * 2, connected_edges
connect_two_way(world, forward_edge, back_edge, player, connected_edges)
elif forward_set is not None: world.owsectors[player] = build_sectors(world, player)
logging.getLogger('').warning("Edge '%s' could not find a valid connection" % forward_set[0]) valid_layout = validate_layout(world, player)
elif back_set is not None:
logging.getLogger('').warning("Edge '%s' could not find a valid connection" % back_set[0])
assert len(connected_edges) == len(default_connections) * 2, connected_edges
# TODO: Reshuffle some areas if impossible to reach, exception if non-dungeon ER enabled or if area is LW with no portal and flute shuffle is enabled tries -= 1
assert valid_layout, 'Could not find a valid OW layout'
# flute shuffle # flute shuffle
def connect_flutes(flute_destinations): def connect_flutes(flute_destinations):
@@ -913,6 +923,20 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
explore_region(start_region) explore_region(start_region)
return explored_regions return explored_regions
def validate_layout(world, player):
sectors = [[r for l in s for r in l] for s in world.owsectors[player]]
for sector in sectors:
entrances_present = False
for region_name in sector:
region = world.get_region(region_name, player)
if any(x.spot_type == 'Entrance' for x in region.exits):
entrances_present = True
break
if not entrances_present and not all(r in isolated_regions for r in sector):
return False
return True
test_connections = [ test_connections = [
#('Links House ES', 'Octoballoon WS'), #('Links House ES', 'Octoballoon WS'),
@@ -1670,6 +1694,11 @@ default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'),
('East Dark Death Mountain EN', 'Turtle Rock WN') ('East Dark Death Mountain EN', 'Turtle Rock WN')
] ]
isolated_regions = [
'Death Mountain Floating Island',
'Mimic Cave Ledge'
]
flute_data = { flute_data = {
#Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX #Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX
0x09: (['Lost Woods East Area', 'Skull Woods Forest'], 0x00, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290), 0x09: (['Lost Woods East Area', 'Skull Woods Forest'], 0x00, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290),