Add ow_layout and ow_parallel settings
This commit is contained in:
@@ -20,11 +20,12 @@ from source.overworld.EntranceData import door_addresses
|
|||||||
|
|
||||||
class World(object):
|
class World(object):
|
||||||
|
|
||||||
def __init__(self, players, owShuffle, owCrossed, owMixed, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments,
|
def __init__(self, players, owLayout, owParallel, owCrossed, owMixed, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments,
|
||||||
timer, progressive, goal, algorithm, accessibility, shuffle_ganon, custom, customitemarray, hints, spoiler_mode):
|
timer, progressive, goal, algorithm, accessibility, shuffle_ganon, custom, customitemarray, hints, spoiler_mode):
|
||||||
self.players = players
|
self.players = players
|
||||||
self.teams = 1
|
self.teams = 1
|
||||||
self.owShuffle = owShuffle.copy()
|
self.owLayout = owLayout.copy()
|
||||||
|
self.owParallel = owParallel.copy()
|
||||||
self.owTerrain = {}
|
self.owTerrain = {}
|
||||||
self.owKeepSimilar = {}
|
self.owKeepSimilar = {}
|
||||||
self.owMixed = owMixed.copy()
|
self.owMixed = owMixed.copy()
|
||||||
@@ -3041,7 +3042,8 @@ class Spoiler(object):
|
|||||||
'bow_mode': self.world.bow_mode,
|
'bow_mode': self.world.bow_mode,
|
||||||
'goal': self.world.goal,
|
'goal': self.world.goal,
|
||||||
'custom_goals': self.world.custom_goals,
|
'custom_goals': self.world.custom_goals,
|
||||||
'ow_shuffle': self.world.owShuffle,
|
'ow_layout': self.world.owLayout,
|
||||||
|
'ow_parallel': self.world.owParallel,
|
||||||
'ow_terrain': self.world.owTerrain,
|
'ow_terrain': self.world.owTerrain,
|
||||||
'ow_crossed': self.world.owCrossed,
|
'ow_crossed': self.world.owCrossed,
|
||||||
'ow_keepsimilar': self.world.owKeepSimilar,
|
'ow_keepsimilar': self.world.owKeepSimilar,
|
||||||
@@ -3312,11 +3314,12 @@ class Spoiler(object):
|
|||||||
outfile.write('Enemy Drop Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['dropshuffle'][player])
|
outfile.write('Enemy Drop Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['dropshuffle'][player])
|
||||||
outfile.write('Take Any Caves:'.ljust(line_width) + '%s\n' % self.metadata['take_any'][player])
|
outfile.write('Take Any Caves:'.ljust(line_width) + '%s\n' % self.metadata['take_any'][player])
|
||||||
outfile.write('\n')
|
outfile.write('\n')
|
||||||
outfile.write('Overworld Layout Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_shuffle'][player])
|
outfile.write('Overworld Layout Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_layout'][player])
|
||||||
if self.metadata['ow_shuffle'][player] != 'vanilla':
|
if self.metadata['ow_layout'][player] != 'vanilla':
|
||||||
|
outfile.write('Parallel OW:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_parallel'][player]))
|
||||||
outfile.write('Free Terrain:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_terrain'][player]))
|
outfile.write('Free Terrain:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_terrain'][player]))
|
||||||
outfile.write('Crossed OW:'.ljust(line_width) + '%s\n' % self.metadata['ow_crossed'][player])
|
outfile.write('Crossed OW:'.ljust(line_width) + '%s\n' % self.metadata['ow_crossed'][player])
|
||||||
if self.metadata['ow_shuffle'][player] != 'vanilla' or self.metadata['ow_crossed'][player] != 'none':
|
if self.metadata['ow_layout'][player] != 'vanilla' or self.metadata['ow_crossed'][player] != 'none':
|
||||||
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_keepsimilar'][player]))
|
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_keepsimilar'][player]))
|
||||||
outfile.write('OW Tile Flip (Mixed):'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_mixed'][player]))
|
outfile.write('OW Tile Flip (Mixed):'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_mixed'][player]))
|
||||||
outfile.write('Whirlpool Shuffle:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_whirlpool'][player]))
|
outfile.write('Whirlpool Shuffle:'.ljust(line_width) + '%s\n' % yn(self.metadata['ow_whirlpool'][player]))
|
||||||
@@ -3728,8 +3731,8 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique
|
|||||||
|
|
||||||
# byte 10: settings_version
|
# byte 10: settings_version
|
||||||
|
|
||||||
# byte 11: OOOT WCCC (OWR layout, free terrain, whirlpools, OWR crossed)
|
# byte 11: POOT WCCC (parallel, OWR layout, free terrain, whirlpools, OWR crossed)
|
||||||
or_mode = {"vanilla": 0, "parallel": 1, "full": 2}
|
orlayout_mode = {"vanilla": 0, "grid": 1, "wild": 2}
|
||||||
orcrossed_mode = {"none": 0, "polar": 1, "grouped": 2, "unrestricted": 4}
|
orcrossed_mode = {"none": 0, "polar": 1, "grouped": 2, "unrestricted": 4}
|
||||||
|
|
||||||
# byte 12: KMBQ FF?? (keep similar, mixed/tile flip, bonk drops, follower quests, flute spots)
|
# byte 12: KMBQ FF?? (keep similar, mixed/tile flip, bonk drops, follower quests, flute spots)
|
||||||
@@ -3795,7 +3798,7 @@ class Settings(object):
|
|||||||
|
|
||||||
settings_version,
|
settings_version,
|
||||||
|
|
||||||
(or_mode[w.owShuffle[p]] << 5) | (0x10 if w.owTerrain[p] else 0)
|
(0x80 if w.owParallel[p] else 0) | (orlayout_mode[w.owLayout[p]] << 5) | (0x10 if w.owTerrain[p] else 0)
|
||||||
| (0x08 if w.owWhirlpoolShuffle[p] else 0) | orcrossed_mode[w.owCrossed[p]],
|
| (0x08 if w.owWhirlpoolShuffle[p] else 0) | orcrossed_mode[w.owCrossed[p]],
|
||||||
|
|
||||||
(0x80 if w.owKeepSimilar[p] else 0) | (0x40 if w.owMixed[p] else 0)
|
(0x80 if w.owKeepSimilar[p] else 0) | (0x40 if w.owMixed[p] else 0)
|
||||||
@@ -3877,7 +3880,8 @@ class Settings(object):
|
|||||||
args.algorithm = r(algo_mode)[(settings[9] & 0x38) >> 3]
|
args.algorithm = r(algo_mode)[(settings[9] & 0x38) >> 3]
|
||||||
args.shufflebosses[p] = r(boss_mode)[(settings[9] & 0x07)]
|
args.shufflebosses[p] = r(boss_mode)[(settings[9] & 0x07)]
|
||||||
|
|
||||||
args.ow_shuffle[p] = r(or_mode)[(settings[11] & 0xE0) >> 5]
|
args.ow_parallel[p] = True if settings[11] & 0x80 else False
|
||||||
|
args.ow_layout[p] = r(orlayout_mode)[(settings[11] & 0x60) >> 5]
|
||||||
args.ow_terrain[p] = True if settings[11] & 0x10 else False
|
args.ow_terrain[p] = True if settings[11] & 0x10 else False
|
||||||
args.ow_whirlpool[p] = True if settings[11] & 0x08 else False
|
args.ow_whirlpool[p] = True if settings[11] & 0x08 else False
|
||||||
args.ow_crossed[p] = r(orcrossed_mode)[(settings[11] & 0x07)]
|
args.ow_crossed[p] = r(orcrossed_mode)[(settings[11] & 0x07)]
|
||||||
|
|||||||
19
CLI.py
19
CLI.py
@@ -120,6 +120,16 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
ret.take_any = 'random' if ret.take_any == 'none' else ret.take_any
|
ret.take_any = 'random' if ret.take_any == 'none' else ret.take_any
|
||||||
ret.keyshuffle = 'universal'
|
ret.keyshuffle = 'universal'
|
||||||
|
|
||||||
|
if ret.ow_unparallel:
|
||||||
|
ret.ow_parallel = False
|
||||||
|
|
||||||
|
if ret.ow_shuffle == 'parallel':
|
||||||
|
ret.ow_layout = 'wild'
|
||||||
|
ret.ow_parallel = True
|
||||||
|
elif ret.ow_shuffle == 'full':
|
||||||
|
ret.ow_layout = 'wild'
|
||||||
|
ret.ow_parallel = False
|
||||||
|
|
||||||
if player_num:
|
if player_num:
|
||||||
defaults = copy.deepcopy(ret)
|
defaults = copy.deepcopy(ret)
|
||||||
for player in range(1, player_num + 1):
|
for player in range(1, player_num + 1):
|
||||||
@@ -130,8 +140,8 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
for k, v in playersettings.items():
|
for k, v in playersettings.items():
|
||||||
setattr(playerargs, k, v)
|
setattr(playerargs, k, v)
|
||||||
|
|
||||||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'ow_shuffle',
|
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'ow_shuffle', 'ow_layout',
|
||||||
'ow_terrain', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool', 'ow_fluteshuffle',
|
'ow_parallel', 'ow_terrain', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool', 'ow_fluteshuffle',
|
||||||
'flute_mode', 'bow_mode', 'take_any', 'boots_hint', 'shuffle_followers',
|
'flute_mode', 'bow_mode', 'take_any', 'boots_hint', 'shuffle_followers',
|
||||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'prizeshuffle', 'startinventory',
|
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'prizeshuffle', 'startinventory',
|
||||||
@@ -193,7 +203,10 @@ def parse_settings():
|
|||||||
# Shuffle Ganon defaults to TRUE
|
# Shuffle Ganon defaults to TRUE
|
||||||
"openpyramid": "auto",
|
"openpyramid": "auto",
|
||||||
"shuffleganon": True,
|
"shuffleganon": True,
|
||||||
"ow_shuffle": "vanilla",
|
"ow_shuffle": "vanilla", # for backwards compatibility
|
||||||
|
"ow_layout": "vanilla",
|
||||||
|
"ow_parallel": True,
|
||||||
|
"ow_unparallel": False,
|
||||||
"ow_terrain": False,
|
"ow_terrain": False,
|
||||||
"ow_crossed": "none",
|
"ow_crossed": "none",
|
||||||
"ow_keepsimilar": False,
|
"ow_keepsimilar": False,
|
||||||
|
|||||||
6
Main.py
6
Main.py
@@ -432,7 +432,7 @@ def init_world(args, fish):
|
|||||||
customized.load_yaml(args.customizer)
|
customized.load_yaml(args.customizer)
|
||||||
customized.adjust_args(args, False)
|
customized.adjust_args(args, False)
|
||||||
|
|
||||||
world = World(args.multi, args.ow_shuffle, args.ow_crossed, args.ow_mixed, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords,
|
world = World(args.multi, args.ow_layout, args.ow_parallel, args.ow_crossed, args.ow_mixed, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords,
|
||||||
args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm,
|
args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm,
|
||||||
args.accessibility, args.shuffleganon, args.custom, args.customitemarray, args.hints, args.spoiler)
|
args.accessibility, args.shuffleganon, args.custom, args.customitemarray, args.hints, args.spoiler)
|
||||||
|
|
||||||
@@ -725,7 +725,7 @@ def set_starting_inventory(world, args):
|
|||||||
|
|
||||||
def copy_world(world):
|
def copy_world(world):
|
||||||
# ToDo: Not good yet
|
# ToDo: Not good yet
|
||||||
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
ret = World(world.players, world.owLayout, world.owParallel, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
||||||
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
||||||
world.accessibility, world.shuffle_ganon, world.custom, world.customitemarray, world.hints, world.spoiler_mode)
|
world.accessibility, world.shuffle_ganon, world.custom, world.customitemarray, world.hints, world.spoiler_mode)
|
||||||
ret.teams = world.teams
|
ret.teams = world.teams
|
||||||
@@ -946,7 +946,7 @@ def copy_world(world):
|
|||||||
|
|
||||||
def copy_world_premature(world, player, create_flute_exits=True):
|
def copy_world_premature(world, player, create_flute_exits=True):
|
||||||
# ToDo: Not good yet
|
# ToDo: Not good yet
|
||||||
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
ret = World(world.players, world.owLayout, world.owParallel, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
||||||
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
||||||
world.accessibility, world.shuffle_ganon, world.custom, world.customitemarray, world.hints, world.spoiler_mode)
|
world.accessibility, world.shuffle_ganon, world.custom, world.customitemarray, world.hints, world.spoiler_mode)
|
||||||
ret.teams = world.teams
|
ret.teams = world.teams
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ def link_overworld(world, player):
|
|||||||
parallel_links_new = {**dict(parallel_links_new), **dict({e:p[0] for e, p in parallel_links_new.inverse.items()})}
|
parallel_links_new = {**dict(parallel_links_new), **dict({e:p[0] for e, p in parallel_links_new.inverse.items()})}
|
||||||
|
|
||||||
connected_edges = []
|
connected_edges = []
|
||||||
if world.owShuffle[player] != 'vanilla':
|
if world.owLayout[player] != 'vanilla':
|
||||||
trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player)
|
trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player)
|
||||||
trimmed_groups = reorganize_groups(world, trimmed_groups, player)
|
trimmed_groups = reorganize_groups(world, trimmed_groups, player)
|
||||||
|
|
||||||
@@ -264,10 +264,10 @@ def link_overworld(world, player):
|
|||||||
s[0x30], s[0x35],
|
s[0x30], s[0x35],
|
||||||
s[0x41], s[0x3a],s[0x3b],s[0x3c], s[0x3f])
|
s[0x41], s[0x3a],s[0x3b],s[0x3c], s[0x3f])
|
||||||
world.spoiler.set_map('groups', text_output, ow_crossed_tiles, player)
|
world.spoiler.set_map('groups', text_output, ow_crossed_tiles, player)
|
||||||
elif limited_crossed > -1 or (world.owShuffle[player] == 'vanilla' and world.owCrossed[player] == 'unrestricted'):
|
elif limited_crossed > -1 or (world.owLayout[player] == 'vanilla' and world.owCrossed[player] == 'unrestricted'):
|
||||||
crossed_candidates = list()
|
crossed_candidates = list()
|
||||||
for group in trimmed_groups.keys():
|
for group in trimmed_groups.keys():
|
||||||
(mode, wrld, dir, terrain, parallel, count, _) = group
|
(mode, wrld, _, terrain, parallel, _, _) = group
|
||||||
if wrld == WorldType.Light and mode != OpenStd.Standard:
|
if wrld == WorldType.Light and mode != OpenStd.Standard:
|
||||||
for (forward_set, back_set) in zip(trimmed_groups[group][0], trimmed_groups[group][1]):
|
for (forward_set, back_set) in zip(trimmed_groups[group][0], trimmed_groups[group][1]):
|
||||||
if forward_set[0] in parallel_links_new:
|
if forward_set[0] in parallel_links_new:
|
||||||
@@ -278,7 +278,7 @@ def link_overworld(world, player):
|
|||||||
combine_set = forward_combine+back_combine
|
combine_set = forward_combine+back_combine
|
||||||
|
|
||||||
skip_forward = False
|
skip_forward = False
|
||||||
if world.owShuffle[player] == 'vanilla':
|
if world.owLayout[player] == 'vanilla':
|
||||||
if any(edge in force_crossed for edge in combine_set):
|
if any(edge in force_crossed for edge in combine_set):
|
||||||
if not any(edge in force_noncrossed for edge in combine_set):
|
if not any(edge in force_noncrossed for edge in combine_set):
|
||||||
if any(edge in force_crossed for edge in forward_combine):
|
if any(edge in force_crossed for edge in forward_combine):
|
||||||
@@ -412,7 +412,7 @@ def link_overworld(world, player):
|
|||||||
# layout shuffle
|
# layout shuffle
|
||||||
logging.getLogger('').debug('Shuffling overworld layout')
|
logging.getLogger('').debug('Shuffling overworld layout')
|
||||||
|
|
||||||
if world.owShuffle[player] == 'vanilla':
|
if world.owLayout[player] == 'vanilla':
|
||||||
# apply outstanding flips
|
# apply outstanding flips
|
||||||
trimmed_groups = performSwap(trimmed_groups, edges_to_swap)
|
trimmed_groups = performSwap(trimmed_groups, edges_to_swap)
|
||||||
assert len(edges_to_swap) == 0, 'Not all edges were flipped successfully: ' + ', '.join(edges_to_swap)
|
assert len(edges_to_swap) == 0, 'Not all edges were flipped successfully: ' + ', '.join(edges_to_swap)
|
||||||
@@ -425,8 +425,10 @@ def link_overworld(world, player):
|
|||||||
assert len(forward_set) == len(back_set)
|
assert len(forward_set) == len(back_set)
|
||||||
for (forward_edge, back_edge) in zip(forward_set, back_set):
|
for (forward_edge, back_edge) in zip(forward_set, back_set):
|
||||||
connect_two_way(world, forward_edge, back_edge, player, connected_edges)
|
connect_two_way(world, forward_edge, back_edge, player, connected_edges)
|
||||||
|
elif world.owLayout[player] == 'grid':
|
||||||
|
raise NotImplementedError()
|
||||||
else:
|
else:
|
||||||
if world.owKeepSimilar[player] and world.owShuffle[player] == 'parallel':
|
if world.owKeepSimilar[player] and world.owParallel[player]:
|
||||||
for exitname, destname in parallelsimilar_connections:
|
for exitname, destname in parallelsimilar_connections:
|
||||||
connect_two_way(world, exitname, destname, player, connected_edges)
|
connect_two_way(world, exitname, destname, player, connected_edges)
|
||||||
|
|
||||||
@@ -822,7 +824,7 @@ def connect_custom(world, connected_edges, groups, forced, player):
|
|||||||
remove_pair_from_pool(edge1.name, edge2.name, is_crossed)
|
remove_pair_from_pool(edge1.name, edge2.name, is_crossed)
|
||||||
connect_two_way(world, edge1.name, edge2.name, player, connected_edges)
|
connect_two_way(world, edge1.name, edge2.name, player, connected_edges)
|
||||||
# resolve parallel
|
# resolve parallel
|
||||||
if world.owShuffle[player] == 'parallel' and edge1.name in parallel_links_new:
|
if world.owParallel[player] and edge1.name in parallel_links_new:
|
||||||
parallel_forward_edge = parallel_links_new[edge1.name]
|
parallel_forward_edge = parallel_links_new[edge1.name]
|
||||||
parallel_back_edge = parallel_links_new[edge2.name]
|
parallel_back_edge = parallel_links_new[edge2.name]
|
||||||
if validate_crossed_allowed(parallel_forward_edge, parallel_back_edge, is_crossed):
|
if validate_crossed_allowed(parallel_forward_edge, parallel_back_edge, is_crossed):
|
||||||
@@ -838,7 +840,7 @@ def connect_custom(world, connected_edges, groups, forced, player):
|
|||||||
connect_two_way(world, forward_edge, back_edge, player, connected_edges)
|
connect_two_way(world, forward_edge, back_edge, player, connected_edges)
|
||||||
else:
|
else:
|
||||||
raise GenerationException('Violation of force crossed rules on unresolved similars: \'%s\' <-> \'%s\'', forward_edge, back_edge)
|
raise GenerationException('Violation of force crossed rules on unresolved similars: \'%s\' <-> \'%s\'', forward_edge, back_edge)
|
||||||
if world.owShuffle[player] == 'parallel' and forward_edge in parallel_links_new:
|
if world.owParallel[player] and forward_edge in parallel_links_new:
|
||||||
parallel_forward_edge = parallel_links_new[forward_edge]
|
parallel_forward_edge = parallel_links_new[forward_edge]
|
||||||
parallel_back_edge = parallel_links_new[back_edge]
|
parallel_back_edge = parallel_links_new[back_edge]
|
||||||
if not validate_crossed_allowed(parallel_forward_edge, parallel_back_edge, is_crossed):
|
if not validate_crossed_allowed(parallel_forward_edge, parallel_back_edge, is_crossed):
|
||||||
@@ -868,7 +870,7 @@ def connect_two_way(world, edgename1, edgename2, player, connected_edges=None):
|
|||||||
x.dest = y
|
x.dest = y
|
||||||
y.dest = x
|
y.dest = x
|
||||||
|
|
||||||
if world.owShuffle[player] != 'vanilla' or world.owMixed[player] or world.owCrossed[player] != 'none':
|
if world.owLayout[player] != 'vanilla' or world.owMixed[player] or world.owCrossed[player] != 'none':
|
||||||
world.spoiler.set_overworld(edgename2, edgename1, 'both', player)
|
world.spoiler.set_overworld(edgename2, edgename1, 'both', player)
|
||||||
|
|
||||||
if connected_edges is not None:
|
if connected_edges is not None:
|
||||||
@@ -876,7 +878,7 @@ def connect_two_way(world, edgename1, edgename2, player, connected_edges=None):
|
|||||||
connected_edges.append(edgename2)
|
connected_edges.append(edgename2)
|
||||||
|
|
||||||
# connecting parallel connections
|
# connecting parallel connections
|
||||||
if world.owShuffle[player] in ['vanilla', 'parallel']:
|
if world.owLayout[player] == 'vanilla' or world.owParallel[player]:
|
||||||
if edgename1 in parallel_links_new:
|
if edgename1 in parallel_links_new:
|
||||||
try:
|
try:
|
||||||
parallel_forward_edge = parallel_links_new[edgename1]
|
parallel_forward_edge = parallel_links_new[edgename1]
|
||||||
@@ -965,7 +967,7 @@ def determine_forced_flips(world, tile_ow_groups, do_grouped, player):
|
|||||||
for whirl1, whirl2 in custom_whirlpools.items():
|
for whirl1, whirl2 in custom_whirlpools.items():
|
||||||
if [whirlpool_map[whirl1], whirlpool_map[whirl2]] not in merged_owids and should_merge_group(whirlpool_map[whirl1], whirlpool_map[whirl2]):
|
if [whirlpool_map[whirl1], whirlpool_map[whirl2]] not in merged_owids and should_merge_group(whirlpool_map[whirl1], whirlpool_map[whirl2]):
|
||||||
merged_owids.append([whirlpool_map[whirl1], whirlpool_map[whirl2]])
|
merged_owids.append([whirlpool_map[whirl1], whirlpool_map[whirl2]])
|
||||||
if world.owShuffle[player] != 'vanilla':
|
if world.owLayout[player] != 'vanilla':
|
||||||
custom_edges = world.customizer.get_owedges()
|
custom_edges = world.customizer.get_owedges()
|
||||||
if custom_edges and player in custom_edges:
|
if custom_edges and player in custom_edges:
|
||||||
custom_edges = custom_edges[player]
|
custom_edges = custom_edges[player]
|
||||||
@@ -1071,6 +1073,9 @@ def shuffle_tiles(world, groups, result_list, do_grouped, forced_flips, player):
|
|||||||
exist_dw_regions.extend(dw_regions)
|
exist_dw_regions.extend(dw_regions)
|
||||||
|
|
||||||
parity = [sum(group_parity[group[0][0]][i] for group in groups if group not in removed) for i in range(6)]
|
parity = [sum(group_parity[group[0][0]][i] for group in groups if group not in removed) for i in range(6)]
|
||||||
|
if world.owLayout[player] == 'grid':
|
||||||
|
parity[1] = 0
|
||||||
|
parity[2] = 0
|
||||||
if not world.owKeepSimilar[player]:
|
if not world.owKeepSimilar[player]:
|
||||||
parity[1] += 2*parity[2]
|
parity[1] += 2*parity[2]
|
||||||
parity[2] = 0
|
parity[2] = 0
|
||||||
@@ -1164,12 +1169,16 @@ def define_tile_groups(world, do_grouped, player):
|
|||||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'simple', 'restricted', 'district']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'simple', 'restricted', 'district']:
|
||||||
merge_groups([[0x05, 0x07]])
|
merge_groups([[0x05, 0x07]])
|
||||||
|
|
||||||
# all non-parallel screens
|
# special screens
|
||||||
if world.owShuffle[player] == 'vanilla' and (world.owCrossed[player] == 'none' or do_grouped):
|
if world.owLayout[player] != 'wild' and (world.owCrossed[player] == 'none' or do_grouped):
|
||||||
merge_groups([[0x00, 0x2d, 0x80], [0x0f, 0x81], [0x1a, 0x1b], [0x28, 0x29], [0x30, 0x3a]])
|
merge_groups([[0x00, 0x2d, 0x80], [0x0f, 0x81]])
|
||||||
|
|
||||||
|
# remaining non-parallel edges
|
||||||
|
if world.owLayout[player] == 'vanilla' and (world.owCrossed[player] == 'none' or do_grouped):
|
||||||
|
merge_groups([[0x1a, 0x1b], [0x28, 0x29], [0x30, 0x3a]])
|
||||||
|
|
||||||
# special case: non-parallel keep similar
|
# special case: non-parallel keep similar
|
||||||
if world.owShuffle[player] == 'parallel' and world.owKeepSimilar[player] and (world.owCrossed[player] == 'none' or do_grouped):
|
if world.owLayout[player] == 'wild' and world.owParallel[player] and world.owKeepSimilar[player] and (world.owCrossed[player] == 'none' or do_grouped):
|
||||||
merge_groups([[0x28, 0x29]])
|
merge_groups([[0x28, 0x29]])
|
||||||
|
|
||||||
# whirlpool screens
|
# whirlpool screens
|
||||||
@@ -1225,7 +1234,7 @@ def reorganize_groups(world, groups, player):
|
|||||||
new_group[0] = None
|
new_group[0] = None
|
||||||
if world.owTerrain[player]:
|
if world.owTerrain[player]:
|
||||||
new_group[3] = None
|
new_group[3] = None
|
||||||
if world.owShuffle[player] != 'parallel':
|
if not world.owParallel[player]:
|
||||||
new_group[4] = None
|
new_group[4] = None
|
||||||
if not world.owKeepSimilar[player]:
|
if not world.owKeepSimilar[player]:
|
||||||
new_group[5] = None
|
new_group[5] = None
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ def main(args):
|
|||||||
start_time = time.process_time()
|
start_time = time.process_time()
|
||||||
|
|
||||||
# initialize the world
|
# initialize the world
|
||||||
world = World(1, 'vanilla', 'vanilla', 'vanilla', 'vanilla', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, False, False, False, None, False)
|
world = World(1, 'vanilla', True, 'vanilla', 'vanilla', 'vanilla', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, False, False, False, None, False)
|
||||||
world.player_names[1].append("Player 1")
|
world.player_names[1].append("Player 1")
|
||||||
logger = logging.getLogger('')
|
logger = logging.getLogger('')
|
||||||
|
|
||||||
@@ -157,9 +157,9 @@ def prefill_world(world, plando, text_patches):
|
|||||||
elif line.startswith('!goal'):
|
elif line.startswith('!goal'):
|
||||||
_, goalstr = line.split(':', 1)
|
_, goalstr = line.split(':', 1)
|
||||||
world.goal = {1: goalstr.strip()}
|
world.goal = {1: goalstr.strip()}
|
||||||
elif line.startswith('!owShuffle'):
|
elif line.startswith('!owLayout'):
|
||||||
_, modestr = line.split(':', 1)
|
_, modestr = line.split(':', 1)
|
||||||
world.owShuffle = {1: modestr.strip()}
|
world.owLayout = {1: modestr.strip()}
|
||||||
elif line.startswith('!owCrossed'):
|
elif line.startswith('!owCrossed'):
|
||||||
_, modestr = line.split(':', 1)
|
_, modestr = line.split(':', 1)
|
||||||
world.owCrossed = {1: modestr.strip()}
|
world.owCrossed = {1: modestr.strip()}
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ Ganons Tower - Validation Chest: Nothing
|
|||||||
Ganon: Triforce
|
Ganon: Triforce
|
||||||
|
|
||||||
# set Overworld connections (lines starting with $, separate edges with =)
|
# set Overworld connections (lines starting with $, separate edges with =)
|
||||||
!owShuffle: parallel
|
!owLayout: wild
|
||||||
#!owMixed: true # Mixed OW not supported yet
|
#!owMixed: true # Mixed OW not supported yet
|
||||||
!owCrossed: none
|
!owCrossed: none
|
||||||
!owKeepSimilar: true
|
!owKeepSimilar: true
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -132,20 +132,24 @@ Note: These changes do impact the logic. If you use `CodeTracker`, these Inverte
|
|||||||
|
|
||||||
Only settings specifically added by this Overworld Shuffle fork are found here. All door and entrance randomizer settings are supported. See their [readme](https://github.com/Aerinon/ALttPDoorRandomizer/blob/master/README.md)
|
Only settings specifically added by this Overworld Shuffle fork are found here. All door and entrance randomizer settings are supported. See their [readme](https://github.com/Aerinon/ALttPDoorRandomizer/blob/master/README.md)
|
||||||
|
|
||||||
## Overworld Layout Shuffle (--ow_shuffle)
|
## Overworld Layout Shuffle (--ow_layout)
|
||||||
OW Edge Transitions are shuffled to create new world layouts. A brief visual representation of this can be viewed [here](https://zelda.codemann8.com/images/shared/ow-modes.gif). (This graphic also includes combinations of Crossed and Tile Flip)
|
OW Edge Transitions are shuffled to create new world layouts. A brief visual representation of this can be viewed [here](https://zelda.codemann8.com/images/shared/ow-modes.gif). (This graphic also includes combinations of Crossed and Tile Flip)
|
||||||
|
|
||||||
### Vanilla
|
### Vanilla
|
||||||
|
|
||||||
OW Transitions are not shuffled.
|
OW Transitions are not shuffled.
|
||||||
|
|
||||||
### Parallel
|
### Grid
|
||||||
|
|
||||||
OW Transitions are shuffled, but both worlds will have a matching layout, similar to that of vanilla.
|
OW Screens are shuffled in such a way that they are still arranged on an 8x8 grid for each world like vanilla, and the OW Transitions are based on that arrangement.
|
||||||
|
|
||||||
### Full
|
### Wild
|
||||||
|
|
||||||
OW Transitions are shuffled within each world separately.
|
OW Transitions are shuffled with no respect to geometric coherence.
|
||||||
|
|
||||||
|
## Parallel (--ow_unparallel to disable)
|
||||||
|
|
||||||
|
With OW Layout Shuffle, this forces both worlds to have a matching layout.
|
||||||
|
|
||||||
## Free Terrain (--ow_terrain)
|
## Free Terrain (--ow_terrain)
|
||||||
|
|
||||||
@@ -389,11 +393,17 @@ Districts are a concept originally conceived by Aerinon in the Door Randomizer,
|
|||||||
Show the help message and exit.
|
Show the help message and exit.
|
||||||
|
|
||||||
```
|
```
|
||||||
--ow_shuffle <mode>
|
--ow_layout <mode>
|
||||||
```
|
```
|
||||||
|
|
||||||
For specifying the overworld layout shuffle you want as above. (default: vanilla)
|
For specifying the overworld layout shuffle you want as above. (default: vanilla)
|
||||||
|
|
||||||
|
```
|
||||||
|
--ow_unparallel
|
||||||
|
```
|
||||||
|
|
||||||
|
With OW Layout Shuffle, this no longer forces both worlds to have a matching layout.
|
||||||
|
|
||||||
```
|
```
|
||||||
--ow_terrain
|
--ow_terrain
|
||||||
```
|
```
|
||||||
|
|||||||
15
Rom.py
15
Rom.py
@@ -557,13 +557,10 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
|
|||||||
# patch overworld edges
|
# patch overworld edges
|
||||||
inverted_buffer = [0] * 0x82
|
inverted_buffer = [0] * 0x82
|
||||||
owMode = 0
|
owMode = 0
|
||||||
if world.owShuffle[player] != 'vanilla' or world.owCrossed[player] not in ['none', 'polar'] or world.owMixed[player]:
|
if world.owLayout[player] != 'vanilla' or world.owCrossed[player] not in ['none', 'polar'] or world.owMixed[player]:
|
||||||
if world.owShuffle[player] == 'parallel':
|
if world.owLayout[player] != 'vanilla':
|
||||||
owMode = 1
|
owMode = 1 if world.owParallel[player] else 2
|
||||||
elif world.owShuffle[player] == 'full':
|
if world.owKeepSimilar[player] and (world.owLayout[player] != 'vanilla' or world.owCrossed[player] == 'unrestricted'):
|
||||||
owMode = 2
|
|
||||||
|
|
||||||
if world.owKeepSimilar[player] and (world.owShuffle[player] != 'vanilla' or world.owCrossed[player] == 'unrestricted'):
|
|
||||||
owMode |= 0x0100
|
owMode |= 0x0100
|
||||||
if world.owCrossed[player] != 'none' and (world.owCrossed[player] != 'polar' or world.owMixed[player]):
|
if world.owCrossed[player] != 'none' and (world.owCrossed[player] != 'polar' or world.owMixed[player]):
|
||||||
owMode |= 0x0200
|
owMode |= 0x0200
|
||||||
@@ -2393,7 +2390,7 @@ def write_strings(rom, world, player, team):
|
|||||||
if world.is_tile_swapped(0x18, player) or world.flute_mode[player] == 'active':
|
if world.is_tile_swapped(0x18, player) or world.flute_mode[player] == 'active':
|
||||||
items_to_hint.remove(flute_item)
|
items_to_hint.remove(flute_item)
|
||||||
flute_item = 'Ocarina (Activated)'
|
flute_item = 'Ocarina (Activated)'
|
||||||
if world.owShuffle[player] != 'vanilla' or world.owMixed[player]:
|
if world.owLayout[player] != 'vanilla' or world.owMixed[player]:
|
||||||
# Adding a guaranteed hint for the Flute in overworld shuffle.
|
# Adding a guaranteed hint for the Flute in overworld shuffle.
|
||||||
this_location = world.find_items_not_key_only(flute_item, player)
|
this_location = world.find_items_not_key_only(flute_item, player)
|
||||||
if this_location and this_location not in hinted_locations:
|
if this_location and this_location not in hinted_locations:
|
||||||
@@ -2411,7 +2408,7 @@ def write_strings(rom, world, player, team):
|
|||||||
random.shuffle(items_to_hint)
|
random.shuffle(items_to_hint)
|
||||||
hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'district', 'swapped'] else 8
|
hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'district', 'swapped'] else 8
|
||||||
hint_count += 2 if world.doorShuffle[player] not in ['vanilla', 'basic'] else 0
|
hint_count += 2 if world.doorShuffle[player] not in ['vanilla', 'basic'] else 0
|
||||||
hint_count += 1 if world.owShuffle[player] != 'vanilla' or world.owCrossed[player] != 'none' or world.owMixed[player] else 0
|
hint_count += 1 if world.owLayout[player] != 'vanilla' or world.owCrossed[player] != 'none' or world.owMixed[player] else 0
|
||||||
while hint_count > 0 and len(items_to_hint) > 0:
|
while hint_count > 0 and len(items_to_hint) > 0:
|
||||||
this_item = items_to_hint.pop(0)
|
this_item = items_to_hint.pop(0)
|
||||||
this_location = world.find_items_not_key_only(this_item, player)
|
this_location = world.find_items_not_key_only(this_item, player)
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ You may define a list of items and a list of locations. Those items will be cons
|
|||||||
|
|
||||||
### ow-edges
|
### ow-edges
|
||||||
|
|
||||||
This must be defined by player. Each player number should be listed with the appropriate sections and each of these players MUST have either `ow_shuffle` or `ow_crossed` enabled in the `settings` section in order for any values here to take effect. This section has two primary subsections: `two-way` and `groups`.
|
This must be defined by player. Each player number should be listed with the appropriate sections and each of these players MUST have either `ow_layout` or `ow_crossed` enabled in the `settings` section in order for any values here to take effect. This section has two primary subsections: `two-way` and `groups`.
|
||||||
|
|
||||||
#### two-way
|
#### two-way
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ settings:
|
|||||||
shuffle_followers: true
|
shuffle_followers: true
|
||||||
shuffle: crossed
|
shuffle: crossed
|
||||||
shufflelinks: true
|
shufflelinks: true
|
||||||
ow_shuffle: parallel
|
ow_layout: wild
|
||||||
|
ow_parallel: true
|
||||||
ow_terrain: true
|
ow_terrain: true
|
||||||
ow_crossed: grouped
|
ow_crossed: grouped
|
||||||
ow_keepsimilar: true
|
ow_keepsimilar: true
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
ow_shuffle: full
|
ow_layout: wild
|
||||||
|
ow_parallel: false
|
||||||
ow_keepsimilar: false
|
ow_keepsimilar: false
|
||||||
ow-edges:
|
ow-edges:
|
||||||
1:
|
1:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
ow_shuffle: full
|
ow_layout: wild
|
||||||
|
ow_parallel: false
|
||||||
ow_keepsimilar: false
|
ow_keepsimilar: false
|
||||||
ow-edges:
|
ow-edges:
|
||||||
1:
|
1:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
ow_shuffle: full
|
ow_layout: wild
|
||||||
|
ow_parallel: false
|
||||||
ow_keepsimilar: false
|
ow_keepsimilar: false
|
||||||
ow-edges:
|
ow-edges:
|
||||||
1:
|
1:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
ow_shuffle: full
|
ow_layout: wild
|
||||||
|
ow_parallel: false
|
||||||
ow_terrain: true
|
ow_terrain: true
|
||||||
ow-edges:
|
ow-edges:
|
||||||
1:
|
1:
|
||||||
|
|||||||
@@ -173,6 +173,22 @@
|
|||||||
"full"
|
"full"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ow_layout": {
|
||||||
|
"choices": [
|
||||||
|
"vanilla",
|
||||||
|
"grid",
|
||||||
|
"wild"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ow_parallel": {
|
||||||
|
"action": "store_true",
|
||||||
|
"help": "suppress",
|
||||||
|
"type": "bool"
|
||||||
|
},
|
||||||
|
"ow_unparallel": {
|
||||||
|
"action": "store_true",
|
||||||
|
"type": "bool"
|
||||||
|
},
|
||||||
"ow_terrain": {
|
"ow_terrain": {
|
||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
|
|||||||
@@ -234,14 +234,18 @@
|
|||||||
"the entrances vanilla."
|
"the entrances vanilla."
|
||||||
],
|
],
|
||||||
"ow_shuffle": [
|
"ow_shuffle": [
|
||||||
|
"Deprecated, use ow_layout and ow_unparallel instead."
|
||||||
|
],
|
||||||
|
"ow_layout": [
|
||||||
"This shuffles the layout of the overworld.",
|
"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.",
|
||||||
"Parallel: Overworld transitions are shuffled, but both worlds",
|
"Grid: OW Screens are arranged on 8x8 grids and OW Transitions",
|
||||||
" will have the same pattern/shape.",
|
" work according to this arrangement.",
|
||||||
"Full: Overworld transitions are shuffled, but both worlds",
|
"Wild: OW Transitions are shuffled with no respect to geometric coherence."
|
||||||
" will have an independent map shape."
|
|
||||||
],
|
],
|
||||||
|
"ow_unparallel": [
|
||||||
|
"With OW Layout Shuffle, this no longer forces both worlds to have a matching layout." ],
|
||||||
"ow_terrain": [
|
"ow_terrain": [
|
||||||
"With OW Layout Shuffle, this allows land and water edges to be connected." ],
|
"With OW Layout Shuffle, this allows land and water edges to be connected." ],
|
||||||
"ow_crossed": [
|
"ow_crossed": [
|
||||||
|
|||||||
@@ -157,10 +157,12 @@
|
|||||||
"randomizer.enemizer.enemylogic.allow_all": "Allow special enemies anywhere",
|
"randomizer.enemizer.enemylogic.allow_all": "Allow special enemies anywhere",
|
||||||
|
|
||||||
|
|
||||||
"randomizer.overworld.overworldshuffle": "Layout Shuffle",
|
"randomizer.overworld.layout": "Layout Shuffle",
|
||||||
"randomizer.overworld.overworldshuffle.vanilla": "Vanilla",
|
"randomizer.overworld.layout.vanilla": "Vanilla",
|
||||||
"randomizer.overworld.overworldshuffle.parallel": "Parallel",
|
"randomizer.overworld.layout.grid": "Grid",
|
||||||
"randomizer.overworld.overworldshuffle.full": "Full",
|
"randomizer.overworld.layout.wild": "Wild",
|
||||||
|
|
||||||
|
"randomizer.overworld.parallel": "Keep Worlds Parallel",
|
||||||
|
|
||||||
"randomizer.overworld.terrain": "Free Terrain",
|
"randomizer.overworld.terrain": "Free Terrain",
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"topOverworldFrame": {},
|
"topOverworldFrame": {},
|
||||||
"leftOverworldFrame": {
|
"leftOverworldFrame": {
|
||||||
"overworldshuffle": {
|
"layout": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"default": "vanilla",
|
"default": "vanilla",
|
||||||
"options": [
|
"options": [
|
||||||
"vanilla",
|
"vanilla",
|
||||||
"parallel",
|
"grid",
|
||||||
"full"
|
"wild"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"crossed": {
|
"crossed": {
|
||||||
@@ -18,7 +18,10 @@
|
|||||||
"grouped",
|
"grouped",
|
||||||
"polar",
|
"polar",
|
||||||
"unrestricted"
|
"unrestricted"
|
||||||
]
|
],
|
||||||
|
"config": {
|
||||||
|
"pady": [16,0]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mixed": {
|
"mixed": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
@@ -48,19 +51,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rightOverworldFrame": {
|
"rightOverworldFrame": {
|
||||||
|
"parallel": {
|
||||||
|
"type": "checkbox",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
"terrain": {
|
"terrain": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"default": false,
|
"default": false
|
||||||
"config": {
|
|
||||||
"pady": [3,0]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"keepsimilar": {
|
"keepsimilar": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"default": false,
|
"default": false
|
||||||
"config": {
|
|
||||||
"pady": [6,0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,8 @@ class CustomSettings(object):
|
|||||||
args.mystery = True
|
args.mystery = True
|
||||||
else:
|
else:
|
||||||
settings = defaultdict(lambda: None, player_setting)
|
settings = defaultdict(lambda: None, player_setting)
|
||||||
args.ow_shuffle[p] = get_setting(settings['ow_shuffle'], args.ow_shuffle[p])
|
args.ow_layout[p] = get_setting(settings['ow_layout'], args.ow_layout[p])
|
||||||
|
args.ow_parallel[p] = get_setting(settings['ow_parallel'], args.ow_parallel[p])
|
||||||
args.ow_terrain[p] = get_setting(settings['ow_terrain'], args.ow_terrain[p])
|
args.ow_terrain[p] = get_setting(settings['ow_terrain'], args.ow_terrain[p])
|
||||||
args.ow_crossed[p] = get_setting(settings['ow_crossed'], args.ow_crossed[p])
|
args.ow_crossed[p] = get_setting(settings['ow_crossed'], args.ow_crossed[p])
|
||||||
if args.ow_crossed[p] == 'chaos':
|
if args.ow_crossed[p] == 'chaos':
|
||||||
@@ -135,6 +136,14 @@ class CustomSettings(object):
|
|||||||
args.take_any[p] = 'random' if args.take_any[p] == 'none' else args.take_any[p]
|
args.take_any[p] = 'random' if args.take_any[p] == 'none' else args.take_any[p]
|
||||||
args.keyshuffle[p] = 'universal'
|
args.keyshuffle[p] = 'universal'
|
||||||
|
|
||||||
|
ow_shuffle = get_setting(settings['ow_shuffle'], args.ow_shuffle[p])
|
||||||
|
if ow_shuffle == 'parallel':
|
||||||
|
args.ow_layout = 'wild'
|
||||||
|
args.ow_parallel = True
|
||||||
|
elif ow_shuffle == 'full':
|
||||||
|
args.ow_layout = 'wild'
|
||||||
|
args.ow_parallel = False
|
||||||
|
|
||||||
args.mixed_travel[p] = get_setting(settings['mixed_travel'], args.mixed_travel[p])
|
args.mixed_travel[p] = get_setting(settings['mixed_travel'], args.mixed_travel[p])
|
||||||
args.standardize_palettes[p] = get_setting(settings['standardize_palettes'],
|
args.standardize_palettes[p] = get_setting(settings['standardize_palettes'],
|
||||||
args.standardize_palettes[p])
|
args.standardize_palettes[p])
|
||||||
@@ -356,7 +365,8 @@ class CustomSettings(object):
|
|||||||
self.world_rep['start_inventory'] = start_inv = {}
|
self.world_rep['start_inventory'] = start_inv = {}
|
||||||
for p in self.player_range:
|
for p in self.player_range:
|
||||||
settings_dict[p] = {}
|
settings_dict[p] = {}
|
||||||
settings_dict[p]['ow_shuffle'] = world.owShuffle[p]
|
settings_dict[p]['ow_layout'] = world.owLayout[p]
|
||||||
|
settings_dict[p]['ow_parallel'] = world.owParallel[p]
|
||||||
settings_dict[p]['ow_terrain'] = world.owTerrain[p]
|
settings_dict[p]['ow_terrain'] = world.owTerrain[p]
|
||||||
settings_dict[p]['ow_crossed'] = world.owCrossed[p]
|
settings_dict[p]['ow_crossed'] = world.owCrossed[p]
|
||||||
settings_dict[p]['ow_keepsimilar'] = world.owKeepSimilar[p]
|
settings_dict[p]['ow_keepsimilar'] = world.owKeepSimilar[p]
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ SETTINGSTOPROCESS = {
|
|||||||
"bombbag": "bombbag"
|
"bombbag": "bombbag"
|
||||||
},
|
},
|
||||||
"overworld": {
|
"overworld": {
|
||||||
"overworldshuffle": "ow_shuffle",
|
"layout": "ow_layout",
|
||||||
|
"parallel": "ow_parallel",
|
||||||
"terrain": "ow_terrain",
|
"terrain": "ow_terrain",
|
||||||
"crossed": "ow_crossed",
|
"crossed": "ow_crossed",
|
||||||
"keepsimilar": "ow_keepsimilar",
|
"keepsimilar": "ow_keepsimilar",
|
||||||
|
|||||||
@@ -635,7 +635,7 @@ def do_dark_sanc(entrances, exits, avail):
|
|||||||
forbidden.append('Links House')
|
forbidden.append('Links House')
|
||||||
else:
|
else:
|
||||||
forbidden.append('Big Bomb Shop')
|
forbidden.append('Big Bomb Shop')
|
||||||
if avail.world.owShuffle[avail.player] == 'vanilla':
|
if avail.world.owLayout[avail.player] == 'vanilla':
|
||||||
choices = [e for e in avail.world.districts[avail.player]['Northwest Dark World'].entrances if e not in forbidden and e in entrances]
|
choices = [e for e in avail.world.districts[avail.player]['Northwest Dark World'].entrances if e not in forbidden and e in entrances]
|
||||||
else:
|
else:
|
||||||
choices = [e for e in get_starting_entrances(avail) if e not in forbidden and e in entrances]
|
choices = [e for e in get_starting_entrances(avail) if e not in forbidden and e in entrances]
|
||||||
@@ -679,7 +679,7 @@ def do_links_house(entrances, exits, avail, cross_world):
|
|||||||
forbidden.append(links_house_vanilla)
|
forbidden.append(links_house_vanilla)
|
||||||
forbidden.extend(Forbidden_Swap_Entrances)
|
forbidden.extend(Forbidden_Swap_Entrances)
|
||||||
shuffle_mode = avail.world.shuffle[avail.player]
|
shuffle_mode = avail.world.shuffle[avail.player]
|
||||||
if avail.world.owShuffle[avail.player] == 'vanilla':
|
if avail.world.owLayout[avail.player] == 'vanilla':
|
||||||
# simple shuffle -
|
# simple shuffle -
|
||||||
if shuffle_mode == 'simple':
|
if shuffle_mode == 'simple':
|
||||||
avail.links_on_mountain = True # taken care of by the logic below
|
avail.links_on_mountain = True # taken care of by the logic below
|
||||||
@@ -733,7 +733,7 @@ def do_links_house(entrances, exits, avail, cross_world):
|
|||||||
|
|
||||||
# links on dm
|
# links on dm
|
||||||
dm_spots = LH_DM_Connector_List.union(LH_DM_Exit_Forbidden)
|
dm_spots = LH_DM_Connector_List.union(LH_DM_Exit_Forbidden)
|
||||||
if links_house in dm_spots and avail.world.owShuffle[avail.player] == 'vanilla':
|
if links_house in dm_spots and avail.world.owLayout[avail.player] == 'vanilla':
|
||||||
if avail.links_on_mountain:
|
if avail.links_on_mountain:
|
||||||
return # connector is fine
|
return # connector is fine
|
||||||
logging.getLogger('').warning(f'Links House is placed in tight area and is now unhandled. Report any errors that occur from here.')
|
logging.getLogger('').warning(f'Links House is placed in tight area and is now unhandled. Report any errors that occur from here.')
|
||||||
|
|||||||
@@ -120,8 +120,16 @@ def roll_settings(weights):
|
|||||||
ret.accessibility = get_choice('accessibility')
|
ret.accessibility = get_choice('accessibility')
|
||||||
ret.restrict_boss_items = get_choice('restrict_boss_items')
|
ret.restrict_boss_items = get_choice('restrict_boss_items')
|
||||||
|
|
||||||
|
overworld_layout = get_choice('overworld_layout')
|
||||||
|
ret.ow_layout = overworld_layout if overworld_layout != 'none' else 'vanilla'
|
||||||
|
ret.ow_parallel = get_choice_bool('overworld_parallel')
|
||||||
overworld_shuffle = get_choice('overworld_shuffle')
|
overworld_shuffle = get_choice('overworld_shuffle')
|
||||||
ret.ow_shuffle = overworld_shuffle if overworld_shuffle != 'none' else 'vanilla'
|
if overworld_shuffle == 'parallel':
|
||||||
|
ret.ow_layout = 'wild'
|
||||||
|
ret.ow_parallel = True
|
||||||
|
elif overworld_shuffle == 'full':
|
||||||
|
ret.ow_layout = 'wild'
|
||||||
|
ret.ow_parallel = False
|
||||||
ret.ow_terrain = get_choice_bool('overworld_terrain')
|
ret.ow_terrain = get_choice_bool('overworld_terrain')
|
||||||
valid_options = {'none': 'none', 'polar': 'polar', 'grouped': 'polar', 'chaos': 'unrestricted', 'unrestricted': 'unrestricted'}
|
valid_options = {'none': 'none', 'polar': 'polar', 'grouped': 'polar', 'chaos': 'unrestricted', 'unrestricted': 'unrestricted'}
|
||||||
ret.ow_crossed = get_choice('overworld_crossed')
|
ret.ow_crossed = get_choice('overworld_crossed')
|
||||||
|
|||||||
Reference in New Issue
Block a user