Initial approach to eliminating inaccessible regions resulting from OW Layout Shuffle
This commit is contained in:
@@ -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:
|
|
||||||
logging.getLogger('').warning("Edge '%s' could not find a valid connection" % forward_set[0])
|
|
||||||
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
|
world.owsectors[player] = build_sectors(world, player)
|
||||||
|
valid_layout = validate_layout(world, player)
|
||||||
|
|
||||||
|
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):
|
||||||
@@ -914,6 +924,20 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
|
|||||||
|
|
||||||
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'),
|
||||||
#('Links House NE', 'Lost Woods Pass SW')
|
#('Links House NE', 'Lost Woods Pass SW')
|
||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user