Merged Parallel Worlds into OW Layout Shuffle setting
This commit is contained in:
@@ -25,7 +25,6 @@ class World(object):
|
|||||||
self.teams = 1
|
self.teams = 1
|
||||||
self.owShuffle = owShuffle.copy()
|
self.owShuffle = owShuffle.copy()
|
||||||
self.owKeepSimilar = {}
|
self.owKeepSimilar = {}
|
||||||
self.owParallelWorlds = {}
|
|
||||||
self.shuffle = shuffle.copy()
|
self.shuffle = shuffle.copy()
|
||||||
self.doorShuffle = doorShuffle.copy()
|
self.doorShuffle = doorShuffle.copy()
|
||||||
self.intensity = {}
|
self.intensity = {}
|
||||||
@@ -2096,7 +2095,6 @@ class Spoiler(object):
|
|||||||
'goal': self.world.goal,
|
'goal': self.world.goal,
|
||||||
'ow_shuffle': self.world.owShuffle,
|
'ow_shuffle': self.world.owShuffle,
|
||||||
'ow_keepsimilar': self.world.owKeepSimilar,
|
'ow_keepsimilar': self.world.owKeepSimilar,
|
||||||
'ow_parallel': self.world.owParallelWorlds,
|
|
||||||
'shuffle': self.world.shuffle,
|
'shuffle': self.world.shuffle,
|
||||||
'door_shuffle': self.world.doorShuffle,
|
'door_shuffle': self.world.doorShuffle,
|
||||||
'intensity': self.world.intensity,
|
'intensity': self.world.intensity,
|
||||||
@@ -2174,9 +2172,8 @@ class Spoiler(object):
|
|||||||
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
||||||
outfile.write('Difficulty:'.ljust(line_width) + '%s\n' % self.metadata['item_pool'][player])
|
outfile.write('Difficulty:'.ljust(line_width) + '%s\n' % self.metadata['item_pool'][player])
|
||||||
outfile.write('Item Functionality:'.ljust(line_width) + '%s\n' % self.metadata['item_functionality'][player])
|
outfile.write('Item Functionality:'.ljust(line_width) + '%s\n' % self.metadata['item_functionality'][player])
|
||||||
outfile.write('Overworld Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_shuffle'][player])
|
outfile.write('Overworld Layout Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_shuffle'][player])
|
||||||
outfile.write('Keep OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
outfile.write('Keep OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
||||||
outfile.write('Parallel Worlds:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_parallel'][player] else 'No'))
|
|
||||||
outfile.write('Entrance Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['shuffle'][player])
|
outfile.write('Entrance Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['shuffle'][player])
|
||||||
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
||||||
outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player])
|
outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player])
|
||||||
|
|||||||
3
CLI.py
3
CLI.py
@@ -94,7 +94,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
for player in range(1, multiargs.multi + 1):
|
for player in range(1, multiargs.multi + 1):
|
||||||
playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True)
|
playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True)
|
||||||
|
|
||||||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'ow_shuffle', 'ow_keepsimilar', 'ow_parallel',
|
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'ow_shuffle', 'ow_keepsimilar',
|
||||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||||
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
||||||
@@ -144,7 +144,6 @@ def parse_settings():
|
|||||||
"shuffleganon": True,
|
"shuffleganon": True,
|
||||||
"ow_shuffle": "vanilla",
|
"ow_shuffle": "vanilla",
|
||||||
"ow_keepsimilar": False,
|
"ow_keepsimilar": False,
|
||||||
"ow_parallel": False,
|
|
||||||
"shuffle": "vanilla",
|
"shuffle": "vanilla",
|
||||||
|
|
||||||
"shufflepots": False,
|
"shufflepots": False,
|
||||||
|
|||||||
1
Main.py
1
Main.py
@@ -74,7 +74,6 @@ def main(args, seed=None, fish=None):
|
|||||||
world.crystals_ganon_orig = args.crystals_ganon.copy()
|
world.crystals_ganon_orig = args.crystals_ganon.copy()
|
||||||
world.crystals_gt_orig = args.crystals_gt.copy()
|
world.crystals_gt_orig = args.crystals_gt.copy()
|
||||||
world.owKeepSimilar = args.ow_keepsimilar.copy()
|
world.owKeepSimilar = args.ow_keepsimilar.copy()
|
||||||
world.owParallelWorlds = args.ow_parallel.copy()
|
|
||||||
world.open_pyramid = args.openpyramid.copy()
|
world.open_pyramid = args.openpyramid.copy()
|
||||||
world.boss_shuffle = args.shufflebosses.copy()
|
world.boss_shuffle = args.shufflebosses.copy()
|
||||||
world.enemy_shuffle = args.shuffleenemies.copy()
|
world.enemy_shuffle = args.shuffleenemies.copy()
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ def roll_settings(weights):
|
|||||||
overworld_shuffle = get_choice('overworld_shuffle')
|
overworld_shuffle = get_choice('overworld_shuffle')
|
||||||
ret.ow_shuffle = overworld_shuffle if overworld_shuffle != 'none' else 'vanilla'
|
ret.ow_shuffle = overworld_shuffle if overworld_shuffle != 'none' else 'vanilla'
|
||||||
ret.ow_keepsimilar = get_choice('ow_keepsimilar')
|
ret.ow_keepsimilar = get_choice('ow_keepsimilar')
|
||||||
ret.ow_parallel = get_choice('ow_parallel')
|
|
||||||
entrance_shuffle = get_choice('entrance_shuffle')
|
entrance_shuffle = get_choice('entrance_shuffle')
|
||||||
ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla'
|
ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla'
|
||||||
door_shuffle = get_choice('door_shuffle')
|
door_shuffle = get_choice('door_shuffle')
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ def link_overworld(world, player):
|
|||||||
for exitname, destname in default_connections:
|
for exitname, destname in default_connections:
|
||||||
connect_two_way(world, exitname, destname, player)
|
connect_two_way(world, exitname, destname, player)
|
||||||
else:
|
else:
|
||||||
if world.owKeepSimilar[player] and world.owParallelWorlds[player]:
|
if world.owKeepSimilar[player] and world.owShuffle[player] == 'parallel':
|
||||||
for exitname, destname in parallelsimilar_connections:
|
for exitname, destname in parallelsimilar_connections:
|
||||||
connect_two_way(world, exitname, destname, player)
|
connect_two_way(world, exitname, destname, player)
|
||||||
connected_edges.append(exitname)
|
connected_edges.append(exitname)
|
||||||
@@ -38,182 +38,182 @@ def link_overworld(world, player):
|
|||||||
if world.owShuffle[player] == 'full':
|
if world.owShuffle[player] == 'full':
|
||||||
#predefined shuffle groups get reorganized here
|
#predefined shuffle groups get reorganized here
|
||||||
if world.owKeepSimilar[player]:
|
if world.owKeepSimilar[player]:
|
||||||
if world.owParallelWorlds[player]:
|
if world.mode[player] == 'standard':
|
||||||
if world.mode[player] == 'standard':
|
#tuple stays (A,B,C,D,_,F)
|
||||||
#tuple stays (A,B,C,D,E,F)
|
for grouping in (trimmed_groups, None):
|
||||||
for grouping in (trimmed_groups, None):
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
new_grouping = {}
|
||||||
groups = list(grouping.values())
|
|
||||||
else:
|
|
||||||
#tuple goes to (_,B,C,D,E,F)
|
|
||||||
for grouping in (trimmed_groups, None):
|
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(_, region, axis, terrain, parallel, count) = group
|
(std, region, axis, terrain, _, count) = group
|
||||||
new_grouping[(region, axis, terrain, parallel, count)] = ([], [])
|
new_grouping[(std, region, axis, terrain, count)] = ([], [])
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(_, region, axis, terrain, parallel, count) = group
|
(std, region, axis, terrain, _, count) = group
|
||||||
(forward_edges, back_edges) = grouping[group]
|
(forward_edges, back_edges) = grouping[group]
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel, count)]
|
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, count)]
|
||||||
exist_forward_edges.extend(forward_edges)
|
exist_forward_edges.extend(forward_edges)
|
||||||
exist_back_edges.extend(back_edges)
|
exist_back_edges.extend(back_edges)
|
||||||
new_grouping[(region, axis, terrain, parallel, count)] = (exist_forward_edges, exist_back_edges)
|
new_grouping[(std, region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
groups = list(new_grouping.values())
|
||||||
else:
|
else:
|
||||||
if world.mode[player] == 'standard':
|
#tuple goes to (_,B,C,D,_,F)
|
||||||
#tuple stays (A,B,C,D,_,F)
|
for grouping in (trimmed_groups, None):
|
||||||
for grouping in (trimmed_groups, None):
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
new_grouping = {}
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, _, count) = group
|
(_, region, axis, terrain, _, count) = group
|
||||||
new_grouping[(std, region, axis, terrain, count)] = ([], [])
|
new_grouping[(region, axis, terrain, count)] = ([], [])
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, _, count) = group
|
(_, region, axis, terrain, _, count) = group
|
||||||
(forward_edges, back_edges) = grouping[group]
|
(forward_edges, back_edges) = grouping[group]
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, count)]
|
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, count)]
|
||||||
exist_forward_edges.extend(forward_edges)
|
exist_forward_edges.extend(forward_edges)
|
||||||
exist_back_edges.extend(back_edges)
|
exist_back_edges.extend(back_edges)
|
||||||
new_grouping[(std, region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
new_grouping[(region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
groups = list(new_grouping.values())
|
||||||
else:
|
|
||||||
#tuple goes to (_,B,C,D,_,F)
|
|
||||||
for grouping in (trimmed_groups, None):
|
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
|
||||||
(_, region, axis, terrain, _, count) = group
|
|
||||||
new_grouping[(region, axis, terrain, count)] = ([], [])
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
|
||||||
(_, region, axis, terrain, _, count) = group
|
|
||||||
(forward_edges, back_edges) = grouping[group]
|
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, count)]
|
|
||||||
exist_forward_edges.extend(forward_edges)
|
|
||||||
exist_back_edges.extend(back_edges)
|
|
||||||
new_grouping[(region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
|
||||||
else:
|
else:
|
||||||
if world.owParallelWorlds[player]:
|
if world.mode[player] == 'standard':
|
||||||
if world.mode[player] == 'standard':
|
#tuple stays (A,B,C,D,_,_)
|
||||||
#tuple stays (A,B,C,D,E,_)
|
for grouping in (trimmed_groups, None):
|
||||||
for grouping in (trimmed_groups, None):
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
new_grouping = {}
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, parallel, _) = group
|
(std, region, axis, terrain, _, _) = group
|
||||||
new_grouping[(std, region, axis, terrain, parallel)] = ([], [])
|
new_grouping[(std, region, axis, terrain)] = ([], [])
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, parallel, _) = group
|
(std, region, axis, terrain, _, _) = group
|
||||||
(forward_edges, back_edges) = grouping[group]
|
(forward_edges, back_edges) = grouping[group]
|
||||||
forward_edges = [[i] for l in forward_edges for i in l]
|
forward_edges = [[i] for l in forward_edges for i in l]
|
||||||
back_edges = [[i] for l in back_edges for i in l]
|
back_edges = [[i] for l in back_edges for i in l]
|
||||||
|
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, parallel)]
|
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain)]
|
||||||
exist_forward_edges.extend(forward_edges)
|
exist_forward_edges.extend(forward_edges)
|
||||||
exist_back_edges.extend(back_edges)
|
exist_back_edges.extend(back_edges)
|
||||||
new_grouping[(std, region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
new_grouping[(std, region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
groups = list(new_grouping.values())
|
||||||
else:
|
|
||||||
#tuple goes to (_,B,C,D,E,_)
|
|
||||||
for grouping in (trimmed_groups, None):
|
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
|
||||||
(_, region, axis, terrain, parallel, _) = group
|
|
||||||
new_grouping[(region, axis, terrain, parallel)] = ([], [])
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
|
||||||
(_, region, axis, terrain, parallel, _) = group
|
|
||||||
(forward_edges, back_edges) = grouping[group]
|
|
||||||
forward_edges = [[i] for l in forward_edges for i in l]
|
|
||||||
back_edges = [[i] for l in back_edges for i in l]
|
|
||||||
|
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel)]
|
|
||||||
exist_forward_edges.extend(forward_edges)
|
|
||||||
exist_back_edges.extend(back_edges)
|
|
||||||
new_grouping[(region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
|
||||||
else:
|
else:
|
||||||
if world.mode[player] == 'standard':
|
#tuple goes to (_,B,C,D,_,_)
|
||||||
#tuple stays (A,B,C,D,_,_)
|
for grouping in (trimmed_groups, None):
|
||||||
for grouping in (trimmed_groups, None):
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
new_grouping = {}
|
||||||
new_grouping = {}
|
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, _, _) = group
|
(_, region, axis, terrain, _, _) = group
|
||||||
new_grouping[(std, region, axis, terrain)] = ([], [])
|
new_grouping[(region, axis, terrain)] = ([], [])
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(std, region, axis, terrain, _, _) = group
|
(_, region, axis, terrain, _, _) = group
|
||||||
(forward_edges, back_edges) = grouping[group]
|
(forward_edges, back_edges) = grouping[group]
|
||||||
forward_edges = [[i] for l in forward_edges for i in l]
|
forward_edges = [[i] for l in forward_edges for i in l]
|
||||||
back_edges = [[i] for l in back_edges for i in l]
|
back_edges = [[i] for l in back_edges for i in l]
|
||||||
|
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain)]
|
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain)]
|
||||||
exist_forward_edges.extend(forward_edges)
|
exist_forward_edges.extend(forward_edges)
|
||||||
exist_back_edges.extend(back_edges)
|
exist_back_edges.extend(back_edges)
|
||||||
new_grouping[(std, region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
new_grouping[(region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
groups = list(new_grouping.values())
|
||||||
else:
|
elif world.owShuffle[player] == 'parallel':
|
||||||
#tuple goes to (_,B,C,D,_,_)
|
#predefined shuffle groups get reorganized here
|
||||||
for grouping in (trimmed_groups, None):
|
if world.owKeepSimilar[player]:
|
||||||
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
if world.mode[player] == 'standard':
|
||||||
new_grouping = {}
|
#tuple stays (A,B,C,D,E,F)
|
||||||
|
for grouping in (trimmed_groups, None):
|
||||||
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
|
groups = list(grouping.values())
|
||||||
|
else:
|
||||||
|
#tuple goes to (_,B,C,D,E,F)
|
||||||
|
for grouping in (trimmed_groups, None):
|
||||||
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
|
new_grouping = {}
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(_, region, axis, terrain, _, _) = group
|
(_, region, axis, terrain, parallel, count) = group
|
||||||
new_grouping[(region, axis, terrain)] = ([], [])
|
new_grouping[(region, axis, terrain, parallel, count)] = ([], [])
|
||||||
|
|
||||||
for group in grouping.keys():
|
for group in grouping.keys():
|
||||||
(_, region, axis, terrain, _, _) = group
|
(_, region, axis, terrain, parallel, count) = group
|
||||||
(forward_edges, back_edges) = grouping[group]
|
(forward_edges, back_edges) = grouping[group]
|
||||||
forward_edges = [[i] for l in forward_edges for i in l]
|
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel, count)]
|
||||||
back_edges = [[i] for l in back_edges for i in l]
|
exist_forward_edges.extend(forward_edges)
|
||||||
|
exist_back_edges.extend(back_edges)
|
||||||
|
new_grouping[(region, axis, terrain, parallel, count)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain)]
|
groups = list(new_grouping.values())
|
||||||
exist_forward_edges.extend(forward_edges)
|
else:
|
||||||
exist_back_edges.extend(back_edges)
|
if world.mode[player] == 'standard':
|
||||||
new_grouping[(region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
#tuple stays (A,B,C,D,E,_)
|
||||||
|
for grouping in (trimmed_groups, None):
|
||||||
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
|
new_grouping = {}
|
||||||
|
|
||||||
groups = list(new_grouping.values())
|
for group in grouping.keys():
|
||||||
|
(std, region, axis, terrain, parallel, _) = group
|
||||||
|
new_grouping[(std, region, axis, terrain, parallel)] = ([], [])
|
||||||
|
|
||||||
#all shuffling occurs here
|
for group in grouping.keys():
|
||||||
random.shuffle(groups)
|
(std, region, axis, terrain, parallel, _) = group
|
||||||
for (forward_edge_sets, back_edge_sets) in groups:
|
(forward_edges, back_edges) = grouping[group]
|
||||||
assert len(forward_edge_sets) == len(back_edge_sets)
|
forward_edges = [[i] for l in forward_edges for i in l]
|
||||||
random.shuffle(back_edge_sets)
|
back_edges = [[i] for l in back_edges for i in l]
|
||||||
for (forward_set, back_set) in zip(forward_edge_sets, back_edge_sets):
|
|
||||||
assert len(forward_set) == len(back_set)
|
|
||||||
for (forward_edge, back_edge) in zip(forward_set, back_set):
|
|
||||||
connect_two_way(world, forward_edge, back_edge, player)
|
|
||||||
connected_edges.append(forward_edge)
|
|
||||||
connected_edges.append(back_edge)
|
|
||||||
if world.owParallelWorlds[player] and forward_edge in parallel_links.keys():
|
|
||||||
connect_two_way(world, parallel_links[forward_edge], parallel_links[back_edge], player)
|
|
||||||
connected_edges.append(parallel_links[forward_edge])
|
|
||||||
connected_edges.append(parallel_links[back_edge])
|
|
||||||
|
|
||||||
assert len(connected_edges) == len(default_connections) * 2, connected_edges
|
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, parallel)]
|
||||||
|
exist_forward_edges.extend(forward_edges)
|
||||||
|
exist_back_edges.extend(back_edges)
|
||||||
|
new_grouping[(std, region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
|
groups = list(new_grouping.values())
|
||||||
|
else:
|
||||||
|
#tuple goes to (_,B,C,D,E,_)
|
||||||
|
for grouping in (trimmed_groups, None):
|
||||||
|
if grouping is not None: #TODO: Figure out why ^ has to be a tuple for this to work
|
||||||
|
new_grouping = {}
|
||||||
|
|
||||||
|
for group in grouping.keys():
|
||||||
|
(_, region, axis, terrain, parallel, _) = group
|
||||||
|
new_grouping[(region, axis, terrain, parallel)] = ([], [])
|
||||||
|
|
||||||
|
for group in grouping.keys():
|
||||||
|
(_, region, axis, terrain, parallel, _) = group
|
||||||
|
(forward_edges, back_edges) = grouping[group]
|
||||||
|
forward_edges = [[i] for l in forward_edges for i in l]
|
||||||
|
back_edges = [[i] for l in back_edges for i in l]
|
||||||
|
|
||||||
|
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel)]
|
||||||
|
exist_forward_edges.extend(forward_edges)
|
||||||
|
exist_back_edges.extend(back_edges)
|
||||||
|
new_grouping[(region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
||||||
|
|
||||||
|
groups = list(new_grouping.values())
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError('Shuffling not supported yet')
|
raise NotImplementedError('Shuffling not supported yet')
|
||||||
|
|
||||||
|
#all shuffling occurs here
|
||||||
|
random.shuffle(groups)
|
||||||
|
for (forward_edge_sets, back_edge_sets) in groups:
|
||||||
|
assert len(forward_edge_sets) == len(back_edge_sets)
|
||||||
|
random.shuffle(back_edge_sets)
|
||||||
|
for (forward_set, back_set) in zip(forward_edge_sets, back_edge_sets):
|
||||||
|
assert len(forward_set) == len(back_set)
|
||||||
|
for (forward_edge, back_edge) in zip(forward_set, back_set):
|
||||||
|
connect_two_way(world, forward_edge, back_edge, player)
|
||||||
|
connected_edges.append(forward_edge)
|
||||||
|
connected_edges.append(back_edge)
|
||||||
|
if world.owShuffle[player] == 'parallel' and forward_edge in parallel_links.keys():
|
||||||
|
connect_two_way(world, parallel_links[forward_edge], parallel_links[back_edge], player)
|
||||||
|
connected_edges.append(parallel_links[forward_edge])
|
||||||
|
connected_edges.append(parallel_links[back_edge])
|
||||||
|
|
||||||
|
assert len(connected_edges) == len(default_connections) * 2, connected_edges
|
||||||
|
|
||||||
def connect_custom(world, connected_edges, player):
|
def connect_custom(world, connected_edges, player):
|
||||||
if hasattr(world, 'custom_overworld') and world.custom_overworld[player]:
|
if hasattr(world, 'custom_overworld') and world.custom_overworld[player]:
|
||||||
for edgename1, edgename2 in world.custom_overworld[player]:
|
for edgename1, edgename2 in world.custom_overworld[player]:
|
||||||
@@ -262,7 +262,7 @@ def remove_reserved(world, groupedlist, connected_edges, player):
|
|||||||
forward_edges = list(list(filter((edge).__ne__, i)) for i in forward_edges)
|
forward_edges = list(list(filter((edge).__ne__, i)) for i in forward_edges)
|
||||||
back_edges = list(list(filter((edge).__ne__, i)) for i in back_edges)
|
back_edges = list(list(filter((edge).__ne__, i)) for i in back_edges)
|
||||||
|
|
||||||
if world.owParallelWorlds[player] and region == WorldType.Dark:
|
if world.owShuffle[player] == 'parallel' and region == WorldType.Dark:
|
||||||
for edge in parallel_links:
|
for edge in parallel_links:
|
||||||
forward_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in forward_edges)
|
forward_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in forward_edges)
|
||||||
back_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in back_edges)
|
back_edges = list(list(filter((parallel_links[edge]).__ne__, i)) for i in back_edges)
|
||||||
|
|||||||
28
README.md
28
README.md
@@ -9,7 +9,7 @@ See https://alttpr.com/ for more details on the normal randomizer.
|
|||||||
This is a very new mode of LTTPR so the tools and info is very limited. There is a [OW Rando Cheat Sheet](https://zelda.codemann8.com/images/shared/ow-rando-reference-sheet.png) that shows all the transitions that exist and are candidates for shuffle. There is a rumor that some OW tracking capability will be coming to CodeTracker, an EmoTracker package for LTTPR.
|
This is a very new mode of LTTPR so the tools and info is very limited. There is a [OW Rando Cheat Sheet](https://zelda.codemann8.com/images/shared/ow-rando-reference-sheet.png) that shows all the transitions that exist and are candidates for shuffle. There is a rumor that some OW tracking capability will be coming to CodeTracker, an EmoTracker package for LTTPR.
|
||||||
|
|
||||||
# Known Issues
|
# Known Issues
|
||||||
(Updated 2021-05-04)
|
(Updated 2021-05-09)
|
||||||
|
|
||||||
### If you want to playtest this, know these things:
|
### If you want to playtest this, know these things:
|
||||||
- Big Red Bomb may require bomb duping as ledge drops may be in the way of your path to the Pyramid Fairy crack
|
- Big Red Bomb may require bomb duping as ledge drops may be in the way of your path to the Pyramid Fairy crack
|
||||||
@@ -40,24 +40,24 @@ Alternatively, run ```Gui.py``` for a simple graphical user interface. (WIP)
|
|||||||
|
|
||||||
Only extra settings are found here. All door and entrance randomizer settings are supported. See their [readme](https://github.com/Aerinon/ALttPDoorRandomizer/blob/master/README.md)
|
Only extra settings are found here. All door and entrance randomizer settings are supported. See their [readme](https://github.com/Aerinon/ALttPDoorRandomizer/blob/master/README.md)
|
||||||
|
|
||||||
## Overworld Shuffle (--ow_shuffle)
|
## Overworld Layout Shuffle (--ow_shuffle)
|
||||||
|
|
||||||
### Full
|
|
||||||
|
|
||||||
OW Transitions are shuffled within each world separately.
|
|
||||||
|
|
||||||
### Vanilla
|
### Vanilla
|
||||||
|
|
||||||
OW is not shuffled.
|
OW is not shuffled.
|
||||||
|
|
||||||
|
### Parallel
|
||||||
|
|
||||||
|
OW Transitions are shuffled, but both worlds will have a matching layout.
|
||||||
|
|
||||||
|
### Full
|
||||||
|
|
||||||
|
OW Transitions are shuffled within each world separately.
|
||||||
|
|
||||||
## Keep Similar Edges Together (--ow_keepsimilar)
|
## Keep Similar Edges Together (--ow_keepsimilar)
|
||||||
|
|
||||||
This keeps similar edge transitions together. ie. The 2 west edges of Potion Shop will be paired to another set of two similar edges
|
This keeps similar edge transitions together. ie. The 2 west edges of Potion Shop will be paired to another set of two similar edges
|
||||||
|
|
||||||
## Parallel Worlds (--ow_parallel)
|
|
||||||
|
|
||||||
This ensures matching layouts of Light and Dark worlds. Any remaining edge transitions that don't have a matching counterpart will be shuffled amongst themselves. ie. If going right from Link's House leads to Blacksmith, then going right from Big Bomb Shop will lead to Hammer Pegs
|
|
||||||
|
|
||||||
|
|
||||||
# Command Line Options
|
# Command Line Options
|
||||||
|
|
||||||
@@ -71,16 +71,10 @@ Show the help message and exit.
|
|||||||
--ow_shuffle <mode>
|
--ow_shuffle <mode>
|
||||||
```
|
```
|
||||||
|
|
||||||
For specifying the overworld shuffle you want as above. (default: vanilla)
|
For specifying the overworld layout shuffle you want as above. (default: vanilla)
|
||||||
|
|
||||||
```
|
```
|
||||||
--ow_keepsimilar
|
--ow_keepsimilar
|
||||||
```
|
```
|
||||||
|
|
||||||
This keeps similar edge transitions paired together with other pairs of transitions
|
This keeps similar edge transitions paired together with other pairs of transitions
|
||||||
|
|
||||||
```
|
|
||||||
--ow_parallel
|
|
||||||
```
|
|
||||||
|
|
||||||
This ensures the layout of both worlds have the same shape
|
|
||||||
|
|||||||
@@ -111,19 +111,14 @@
|
|||||||
"ow_shuffle": {
|
"ow_shuffle": {
|
||||||
"choices": [
|
"choices": [
|
||||||
"vanilla",
|
"vanilla",
|
||||||
"simple",
|
"parallel",
|
||||||
"full",
|
"full"
|
||||||
"crossed"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ow_keepsimilar": {
|
"ow_keepsimilar": {
|
||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
},
|
},
|
||||||
"ow_parallel": {
|
|
||||||
"action": "store_true",
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
"shuffle": {
|
"shuffle": {
|
||||||
"choices": [
|
"choices": [
|
||||||
"vanilla",
|
"vanilla",
|
||||||
|
|||||||
@@ -194,19 +194,17 @@
|
|||||||
"the overworld vanilla."
|
"the overworld vanilla."
|
||||||
],
|
],
|
||||||
"ow_shuffle": [
|
"ow_shuffle": [
|
||||||
"Select Overworld Shuffling Algorithm. (default: %(default)s)",
|
"This shuffles the layout of the overworld.",
|
||||||
"Vanilla: All overworld transitions are connected the same",
|
"Vanilla: All overworld transitions are connected the same",
|
||||||
" way they were in the base game.",
|
" way they were in the base game.",
|
||||||
"Simple: Overworld retains the same vanilla shape, but some overworld",
|
"Parallel: Overworld transitions are shuffled, but both worlds",
|
||||||
" screens will be swapped with their opposite world version.",
|
" will have the same pattern/shape.",
|
||||||
"Full: Overworld screen transitions will lead to other",
|
"Full: Overworld transitions are shuffled, but both worlds",
|
||||||
" overworld screens from the same world.",
|
" will have an independent map shape."
|
||||||
"Crossed: Overworld screen transitions can lead to any other overworld screen."
|
|
||||||
],
|
],
|
||||||
"ow_keepsimilar": [
|
"ow_keepsimilar": [
|
||||||
"This keeps similar edge transitions together. ie. the two west edges on",
|
"This keeps similar edge transitions together. ie. the two west edges on",
|
||||||
"Potion Shop will be paired with another similar pair." ],
|
"Potion Shop will be paired with another similar pair." ],
|
||||||
"ow_parallel": [ "This ensures the layouts of both worlds are the same shape." ],
|
|
||||||
"door_shuffle": [
|
"door_shuffle": [
|
||||||
"Select Door Shuffling Algorithm. (default: %(default)s)",
|
"Select Door Shuffling Algorithm. (default: %(default)s)",
|
||||||
"Basic: Doors are mixed within a single dungeon.",
|
"Basic: Doors are mixed within a single dungeon.",
|
||||||
|
|||||||
@@ -109,14 +109,12 @@
|
|||||||
"randomizer.enemizer.enemizercli.online": "(get online)",
|
"randomizer.enemizer.enemizercli.online": "(get online)",
|
||||||
|
|
||||||
|
|
||||||
"randomizer.overworld.overworldshuffle": "Overworld Shuffle",
|
"randomizer.overworld.overworldshuffle": "Layout Shuffle",
|
||||||
"randomizer.overworld.overworldshuffle.vanilla": "Vanilla",
|
"randomizer.overworld.overworldshuffle.vanilla": "Vanilla",
|
||||||
"randomizer.overworld.overworldshuffle.simple": "Simple",
|
"randomizer.overworld.overworldshuffle.parallel": "Parallel",
|
||||||
"randomizer.overworld.overworldshuffle.full": "Full",
|
"randomizer.overworld.overworldshuffle.full": "Full",
|
||||||
"randomizer.overworld.overworldshuffle.crossed": "Crossed",
|
|
||||||
|
|
||||||
"randomizer.overworld.keepsimilar": "Keep Similar Edges Together",
|
"randomizer.overworld.keepsimilar": "Keep Similar Edges Together",
|
||||||
"randomizer.overworld.parallelworlds": "Parallel Worlds",
|
|
||||||
|
|
||||||
"randomizer.entrance.openpyramid": "Pre-open Pyramid Hole",
|
"randomizer.entrance.openpyramid": "Pre-open Pyramid Hole",
|
||||||
"randomizer.entrance.shuffleganon": "Include Ganon's Tower and Pyramid Hole in shuffle pool",
|
"randomizer.entrance.shuffleganon": "Include Ganon's Tower and Pyramid Hole in shuffle pool",
|
||||||
|
|||||||
@@ -2,19 +2,16 @@
|
|||||||
"widgets": {
|
"widgets": {
|
||||||
"overworldshuffle": {
|
"overworldshuffle": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"default": "full",
|
"default": "parallel",
|
||||||
"options": [
|
"options": [
|
||||||
"vanilla",
|
"vanilla",
|
||||||
|
"parallel",
|
||||||
"full"
|
"full"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"keepsimilar": {
|
"keepsimilar": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
|
||||||
"parallelworlds": {
|
|
||||||
"type": "checkbox",
|
|
||||||
"default": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,8 +72,7 @@ SETTINGSTOPROCESS = {
|
|||||||
},
|
},
|
||||||
"overworld": {
|
"overworld": {
|
||||||
"overworldshuffle": "ow_shuffle",
|
"overworldshuffle": "ow_shuffle",
|
||||||
"keepsimilar": "ow_keepsimilar",
|
"keepsimilar": "ow_keepsimilar"
|
||||||
"parallelworlds": "ow_parallel"
|
|
||||||
},
|
},
|
||||||
"entrance": {
|
"entrance": {
|
||||||
"openpyramid": "openpyramid",
|
"openpyramid": "openpyramid",
|
||||||
|
|||||||
Reference in New Issue
Block a user