Implemented Whirlpool Shuffle
This commit is contained in:
@@ -26,6 +26,7 @@ class World(object):
|
|||||||
self.owCrossed = owCrossed.copy()
|
self.owCrossed = owCrossed.copy()
|
||||||
self.owKeepSimilar = {}
|
self.owKeepSimilar = {}
|
||||||
self.owMixed = owMixed.copy()
|
self.owMixed = owMixed.copy()
|
||||||
|
self.owWhirlpoolShuffle = {}
|
||||||
self.owFluteShuffle = {}
|
self.owFluteShuffle = {}
|
||||||
self.shuffle = shuffle.copy()
|
self.shuffle = shuffle.copy()
|
||||||
self.doorShuffle = doorShuffle.copy()
|
self.doorShuffle = doorShuffle.copy()
|
||||||
@@ -76,6 +77,7 @@ class World(object):
|
|||||||
self.spoiler = Spoiler(self)
|
self.spoiler = Spoiler(self)
|
||||||
self.lamps_needed_for_dark_rooms = 1
|
self.lamps_needed_for_dark_rooms = 1
|
||||||
self.owswaps = {}
|
self.owswaps = {}
|
||||||
|
self.owwhirlpools = {}
|
||||||
self.owedges = []
|
self.owedges = []
|
||||||
self._owedge_cache = {}
|
self._owedge_cache = {}
|
||||||
self.owflutespots = {}
|
self.owflutespots = {}
|
||||||
@@ -105,6 +107,7 @@ class World(object):
|
|||||||
set_player_attr('_region_cache', {})
|
set_player_attr('_region_cache', {})
|
||||||
set_player_attr('player_names', [])
|
set_player_attr('player_names', [])
|
||||||
set_player_attr('owswaps', [[],[],[]])
|
set_player_attr('owswaps', [[],[],[]])
|
||||||
|
set_player_attr('owwhirlpools', [])
|
||||||
set_player_attr('remote_items', False)
|
set_player_attr('remote_items', False)
|
||||||
set_player_attr('required_medallions', ['Ether', 'Quake'])
|
set_player_attr('required_medallions', ['Ether', 'Quake'])
|
||||||
set_player_attr('swamp_patch_required', False)
|
set_player_attr('swamp_patch_required', False)
|
||||||
@@ -2693,6 +2696,7 @@ class Spoiler(object):
|
|||||||
'ow_crossed': self.world.owCrossed,
|
'ow_crossed': self.world.owCrossed,
|
||||||
'ow_keepsimilar': self.world.owKeepSimilar,
|
'ow_keepsimilar': self.world.owKeepSimilar,
|
||||||
'ow_mixed': self.world.owMixed,
|
'ow_mixed': self.world.owMixed,
|
||||||
|
'ow_whirlpool': self.world.owWhirlpoolShuffle,
|
||||||
'ow_fluteshuffle': self.world.owFluteShuffle,
|
'ow_fluteshuffle': self.world.owFluteShuffle,
|
||||||
'shuffle': self.world.shuffle,
|
'shuffle': self.world.shuffle,
|
||||||
'shuffleganon': self.world.shuffle_ganon,
|
'shuffleganon': self.world.shuffle_ganon,
|
||||||
@@ -2784,6 +2788,7 @@ class Spoiler(object):
|
|||||||
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
||||||
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])
|
||||||
outfile.write('Swapped OW (Mixed):'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_mixed'][player] else 'No'))
|
outfile.write('Swapped OW (Mixed):'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_mixed'][player] else 'No'))
|
||||||
|
outfile.write('Whirlpool Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_whirlpool'][player] else 'No'))
|
||||||
outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_fluteshuffle'][player])
|
outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_fluteshuffle'][player])
|
||||||
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('Shuffle GT/Ganon:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shuffleganon'][player] else 'No'))
|
outfile.write('Shuffle GT/Ganon:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shuffleganon'][player] else 'No'))
|
||||||
@@ -2807,6 +2812,7 @@ class Spoiler(object):
|
|||||||
if self.startinventory:
|
if self.startinventory:
|
||||||
outfile.write('Starting Inventory:'.ljust(line_width))
|
outfile.write('Starting Inventory:'.ljust(line_width))
|
||||||
outfile.write('\n'.ljust(line_width+1).join(self.startinventory))
|
outfile.write('\n'.ljust(line_width+1).join(self.startinventory))
|
||||||
|
|
||||||
outfile.write('\n\nRequirements:\n\n')
|
outfile.write('\n\nRequirements:\n\n')
|
||||||
for dungeon, medallion in self.medallions.items():
|
for dungeon, medallion in self.medallions.items():
|
||||||
outfile.write(f'{dungeon}:'.ljust(line_width) + '%s Medallion\n' % medallion)
|
outfile.write(f'{dungeon}:'.ljust(line_width) + '%s Medallion\n' % medallion)
|
||||||
|
|||||||
3
CLI.py
3
CLI.py
@@ -94,7 +94,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
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',
|
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
|
||||||
'ow_shuffle', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_fluteshuffle',
|
'ow_shuffle', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool', 'ow_fluteshuffle',
|
||||||
'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',
|
||||||
'bombbag', 'shuffleganon',
|
'bombbag', 'shuffleganon',
|
||||||
@@ -149,6 +149,7 @@ def parse_settings():
|
|||||||
"ow_crossed": "none",
|
"ow_crossed": "none",
|
||||||
"ow_keepsimilar": False,
|
"ow_keepsimilar": False,
|
||||||
"ow_mixed": False,
|
"ow_mixed": False,
|
||||||
|
"ow_whirlpool": False,
|
||||||
"ow_fluteshuffle": "vanilla",
|
"ow_fluteshuffle": "vanilla",
|
||||||
"shuffle": "vanilla",
|
"shuffle": "vanilla",
|
||||||
"shufflelinks": False,
|
"shufflelinks": False,
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -87,6 +87,7 @@ 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.owWhirlpoolShuffle = args.ow_whirlpool.copy()
|
||||||
world.owFluteShuffle = args.ow_fluteshuffle.copy()
|
world.owFluteShuffle = args.ow_fluteshuffle.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()
|
||||||
@@ -406,6 +407,7 @@ def copy_world(world):
|
|||||||
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
||||||
ret.crystals_gt_orig = world.crystals_gt_orig.copy()
|
ret.crystals_gt_orig = world.crystals_gt_orig.copy()
|
||||||
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
||||||
|
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
||||||
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
||||||
ret.open_pyramid = world.open_pyramid.copy()
|
ret.open_pyramid = world.open_pyramid.copy()
|
||||||
ret.boss_shuffle = world.boss_shuffle.copy()
|
ret.boss_shuffle = world.boss_shuffle.copy()
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ def roll_settings(weights):
|
|||||||
ret.ow_crossed = get_choice('overworld_crossed')
|
ret.ow_crossed = get_choice('overworld_crossed')
|
||||||
ret.ow_keepsimilar = get_choice('overworld_keepsimilar') == 'on'
|
ret.ow_keepsimilar = get_choice('overworld_keepsimilar') == 'on'
|
||||||
ret.ow_mixed = get_choice('overworld_swap') == 'on'
|
ret.ow_mixed = get_choice('overworld_swap') == 'on'
|
||||||
|
ret.ow_whirlpool = get_choice('whirlpool_shuffle') == 'on'
|
||||||
overworld_flute = get_choice('flute_shuffle')
|
overworld_flute = get_choice('flute_shuffle')
|
||||||
ret.ow_fluteshuffle = overworld_flute if overworld_flute != 'none' else 'vanilla'
|
ret.ow_fluteshuffle = overworld_flute if overworld_flute != 'none' else 'vanilla'
|
||||||
entrance_shuffle = get_choice('entrance_shuffle')
|
entrance_shuffle = get_choice('entrance_shuffle')
|
||||||
|
|||||||
104
OWEdges.py
104
OWEdges.py
@@ -969,7 +969,7 @@ OWTileRegions = bidict({
|
|||||||
})
|
})
|
||||||
|
|
||||||
OWTileGroups = {
|
OWTileGroups = {
|
||||||
("Woods", "Regular"): (
|
("Woods", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x00, 0x2d, 0x80
|
0x00, 0x2d, 0x80
|
||||||
],
|
],
|
||||||
@@ -977,7 +977,7 @@ OWTileGroups = {
|
|||||||
0x40, 0x6d
|
0x40, 0x6d
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Lumberjack", "Regular"): (
|
("Lumberjack", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x02
|
0x02
|
||||||
],
|
],
|
||||||
@@ -985,7 +985,7 @@ OWTileGroups = {
|
|||||||
0x42
|
0x42
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("West Mountain", "Regular"): (
|
("West Mountain", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x03
|
0x03
|
||||||
],
|
],
|
||||||
@@ -993,7 +993,7 @@ OWTileGroups = {
|
|||||||
0x43
|
0x43
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("East Mountain", "Regular"): (
|
("East Mountain", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x05
|
0x05
|
||||||
],
|
],
|
||||||
@@ -1001,23 +1001,31 @@ OWTileGroups = {
|
|||||||
0x45
|
0x45
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("East Mountain", "Entrance"): (
|
("East Mountain", "Entrance", "None"): (
|
||||||
[
|
[
|
||||||
0x07,
|
0x07
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0x47
|
0x47
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Lake", "Regular"): (
|
("Lake", "Regular", "Zora"): (
|
||||||
[
|
[
|
||||||
0x0f, 0x35, 0x81
|
0x0f, 0x81
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0x4f, 0x75
|
0x4f
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Mountain Entry", "Regular"): (
|
("Lake", "Regular", "Lake"): (
|
||||||
|
[
|
||||||
|
0x35
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0x75
|
||||||
|
]
|
||||||
|
),
|
||||||
|
("Mountain Entry", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x0a
|
0x0a
|
||||||
],
|
],
|
||||||
@@ -1025,7 +1033,7 @@ OWTileGroups = {
|
|||||||
0x4a
|
0x4a
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Woods Pass", "Regular"): (
|
("Woods Pass", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x10
|
0x10
|
||||||
],
|
],
|
||||||
@@ -1033,7 +1041,7 @@ OWTileGroups = {
|
|||||||
0x50
|
0x50
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Fortune", "Regular"): (
|
("Fortune", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x11
|
0x11
|
||||||
],
|
],
|
||||||
@@ -1041,15 +1049,39 @@ OWTileGroups = {
|
|||||||
0x51
|
0x51
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Whirlpools", "Regular"): (
|
("Whirlpools", "Regular", "Pond"): (
|
||||||
[
|
[
|
||||||
0x12, 0x15, 0x33, 0x3f
|
0x12
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0x52, 0x55, 0x73, 0x7f
|
0x52
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Castle", "Entrance"): (
|
("Whirlpools", "Regular", "Witch"): (
|
||||||
|
[
|
||||||
|
0x15
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0x55
|
||||||
|
]
|
||||||
|
),
|
||||||
|
("Whirlpools", "Regular", "CWhirlpool"): (
|
||||||
|
[
|
||||||
|
0x33
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0x73
|
||||||
|
]
|
||||||
|
),
|
||||||
|
("Whirlpools", "Regular", "Southeast"): (
|
||||||
|
[
|
||||||
|
0x3f
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0x7f
|
||||||
|
]
|
||||||
|
),
|
||||||
|
("Castle", "Entrance", "None"): (
|
||||||
[
|
[
|
||||||
0x13, 0x14
|
0x13, 0x14
|
||||||
],
|
],
|
||||||
@@ -1057,7 +1089,7 @@ OWTileGroups = {
|
|||||||
0x53, 0x54
|
0x53, 0x54
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Castle", "Regular"): (
|
("Castle", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x1a, 0x1b
|
0x1a, 0x1b
|
||||||
],
|
],
|
||||||
@@ -1065,7 +1097,7 @@ OWTileGroups = {
|
|||||||
0x5a, 0x5b
|
0x5a, 0x5b
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Witch", "Regular"): (
|
("Witch", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x16
|
0x16
|
||||||
],
|
],
|
||||||
@@ -1073,7 +1105,7 @@ OWTileGroups = {
|
|||||||
0x56
|
0x56
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Water Approach", "Regular"): (
|
("Water Approach", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x17
|
0x17
|
||||||
],
|
],
|
||||||
@@ -1081,7 +1113,7 @@ OWTileGroups = {
|
|||||||
0x57
|
0x57
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Village", "Regular"): (
|
("Village", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x18
|
0x18
|
||||||
],
|
],
|
||||||
@@ -1089,7 +1121,7 @@ OWTileGroups = {
|
|||||||
0x58
|
0x58
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Wooden Bridge", "Regular"): (
|
("Wooden Bridge", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x1d
|
0x1d
|
||||||
],
|
],
|
||||||
@@ -1097,7 +1129,7 @@ OWTileGroups = {
|
|||||||
0x5d
|
0x5d
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Eastern", "Regular"): (
|
("Eastern", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x1e
|
0x1e
|
||||||
],
|
],
|
||||||
@@ -1105,7 +1137,7 @@ OWTileGroups = {
|
|||||||
0x5e
|
0x5e
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Blacksmith", "Regular"): (
|
("Blacksmith", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x22
|
0x22
|
||||||
],
|
],
|
||||||
@@ -1113,7 +1145,7 @@ OWTileGroups = {
|
|||||||
0x62
|
0x62
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Dunes", "Regular"): (
|
("Dunes", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x25
|
0x25
|
||||||
],
|
],
|
||||||
@@ -1121,7 +1153,7 @@ OWTileGroups = {
|
|||||||
0x65
|
0x65
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Game", "Regular"): (
|
("Game", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x28, 0x29
|
0x28, 0x29
|
||||||
],
|
],
|
||||||
@@ -1129,7 +1161,7 @@ OWTileGroups = {
|
|||||||
0x68, 0x69
|
0x68, 0x69
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Grove", "Regular"): (
|
("Grove", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x2a
|
0x2a
|
||||||
],
|
],
|
||||||
@@ -1137,7 +1169,7 @@ OWTileGroups = {
|
|||||||
0x6a
|
0x6a
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Central Bonk Rocks", "Regular"): (
|
("Central Bonk Rocks", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x2b
|
0x2b
|
||||||
],
|
],
|
||||||
@@ -1145,7 +1177,7 @@ OWTileGroups = {
|
|||||||
0x6b
|
0x6b
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
# ("Links", "Regular"): (
|
# ("Links", "Regular", "None"): (
|
||||||
# [
|
# [
|
||||||
# 0x2c
|
# 0x2c
|
||||||
# ],
|
# ],
|
||||||
@@ -1153,7 +1185,7 @@ OWTileGroups = {
|
|||||||
# 0x6c
|
# 0x6c
|
||||||
# ]
|
# ]
|
||||||
# ),
|
# ),
|
||||||
("Tree Line", "Regular"): (
|
("Tree Line", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x2e
|
0x2e
|
||||||
],
|
],
|
||||||
@@ -1161,7 +1193,7 @@ OWTileGroups = {
|
|||||||
0x6e
|
0x6e
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Nook", "Regular"): (
|
("Nook", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x2f
|
0x2f
|
||||||
],
|
],
|
||||||
@@ -1169,7 +1201,7 @@ OWTileGroups = {
|
|||||||
0x6f
|
0x6f
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Desert", "Regular"): (
|
("Desert", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x30, 0x3a
|
0x30, 0x3a
|
||||||
],
|
],
|
||||||
@@ -1177,7 +1209,7 @@ OWTileGroups = {
|
|||||||
0x70, 0x7a
|
0x70, 0x7a
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Grove Approach", "Regular"): (
|
("Grove Approach", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x32
|
0x32
|
||||||
],
|
],
|
||||||
@@ -1185,7 +1217,7 @@ OWTileGroups = {
|
|||||||
0x72
|
0x72
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Hype", "Regular"): (
|
("Hype", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x34
|
0x34
|
||||||
],
|
],
|
||||||
@@ -1193,7 +1225,7 @@ OWTileGroups = {
|
|||||||
0x74
|
0x74
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Shopping Mall", "Regular"): (
|
("Shopping Mall", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x37
|
0x37
|
||||||
],
|
],
|
||||||
@@ -1201,7 +1233,7 @@ OWTileGroups = {
|
|||||||
0x77
|
0x77
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("Swamp", "Regular"): (
|
("Swamp", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x3b
|
0x3b
|
||||||
],
|
],
|
||||||
@@ -1209,7 +1241,7 @@ OWTileGroups = {
|
|||||||
0x7b
|
0x7b
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("South Pass", "Regular"): (
|
("South Pass", "Regular", "None"): (
|
||||||
[
|
[
|
||||||
0x3c
|
0x3c
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -187,6 +187,44 @@ def link_overworld(world, player):
|
|||||||
trimmed_groups = performSwap(trimmed_groups, crossed_edges)
|
trimmed_groups = performSwap(trimmed_groups, crossed_edges)
|
||||||
assert len(crossed_edges) == 0, 'Not all edges were crossed successfully: ' + ', '.join(crossed_edges)
|
assert len(crossed_edges) == 0, 'Not all edges were crossed successfully: ' + ', '.join(crossed_edges)
|
||||||
|
|
||||||
|
# whirlpool shuffle
|
||||||
|
logging.getLogger('').debug('Shuffling whirlpools')
|
||||||
|
|
||||||
|
if not world.owWhirlpoolShuffle[player]:
|
||||||
|
for (_, from_whirlpool, from_region), (_, to_whirlpool, to_region) in default_whirlpool_connections:
|
||||||
|
connect_simple(world, from_whirlpool, to_region, player)
|
||||||
|
connect_simple(world, to_whirlpool, from_region, player)
|
||||||
|
else:
|
||||||
|
whirlpool_candidates = [[],[]]
|
||||||
|
for (from_owid, from_whirlpool, from_region), (to_owid, to_whirlpool, to_region) in default_whirlpool_connections:
|
||||||
|
if world.owCrossed[player] != 'none':
|
||||||
|
whirlpool_candidates[0].append(tuple((from_owid, from_whirlpool, from_region)))
|
||||||
|
whirlpool_candidates[0].append(tuple((to_owid, to_whirlpool, to_region)))
|
||||||
|
else:
|
||||||
|
if world.get_region(from_region, player).type == RegionType.LightWorld:
|
||||||
|
whirlpool_candidates[0].append(tuple((from_owid, from_whirlpool, from_region)))
|
||||||
|
else:
|
||||||
|
whirlpool_candidates[1].append(tuple((from_owid, from_whirlpool, from_region)))
|
||||||
|
|
||||||
|
if world.get_region(to_region, player).type == RegionType.LightWorld:
|
||||||
|
whirlpool_candidates[0].append(tuple((to_owid, to_whirlpool, to_region)))
|
||||||
|
else:
|
||||||
|
whirlpool_candidates[1].append(tuple((to_owid, to_whirlpool, to_region)))
|
||||||
|
|
||||||
|
# shuffle happens here
|
||||||
|
world.owwhirlpools[player] = [None] * 8
|
||||||
|
whirlpool_map = [ 0x35, 0x0f, 0x15, 0x33, 0x12, 0x3f, 0x55, 0x7f ]
|
||||||
|
for whirlpools in whirlpool_candidates:
|
||||||
|
random.shuffle(whirlpools)
|
||||||
|
while len(whirlpools):
|
||||||
|
from_owid, from_whirlpool, from_region = whirlpools.pop()
|
||||||
|
to_owid, to_whirlpool, to_region = whirlpools.pop()
|
||||||
|
connect_simple(world, from_whirlpool, to_region, player)
|
||||||
|
connect_simple(world, to_whirlpool, from_region, player)
|
||||||
|
world.owwhirlpools[player][next(i for i, v in enumerate(whirlpool_map) if v == to_owid)] = from_owid
|
||||||
|
world.owwhirlpools[player][next(i for i, v in enumerate(whirlpool_map) if v == from_owid)] = to_owid
|
||||||
|
world.spoiler.set_overworld(from_whirlpool, to_whirlpool, 'both', player)
|
||||||
|
|
||||||
# layout shuffle
|
# layout shuffle
|
||||||
logging.getLogger('').debug('Shuffling overworld layout')
|
logging.getLogger('').debug('Shuffling overworld layout')
|
||||||
connected_edges = []
|
connected_edges = []
|
||||||
@@ -387,22 +425,33 @@ def connect_two_way(world, edgename1, edgename2, player, connected_edges=None):
|
|||||||
|
|
||||||
def shuffle_tiles(world, groups, result_list, player):
|
def shuffle_tiles(world, groups, result_list, player):
|
||||||
swapped_edges = list()
|
swapped_edges = list()
|
||||||
|
valid_whirlpool_parity = False
|
||||||
|
|
||||||
# tile shuffle happens here
|
while not valid_whirlpool_parity:
|
||||||
removed = list()
|
# tile shuffle happens here
|
||||||
for group in groups.keys():
|
removed = list()
|
||||||
if random.randint(0, 1):
|
for group in groups.keys():
|
||||||
removed.append(group)
|
# if group[0] in ['Links', 'Central Bonk Rocks', 'Castle']: # TODO: Standard + Inverted
|
||||||
|
if random.randint(0, 1):
|
||||||
# save shuffled tiles to list
|
removed.append(group)
|
||||||
for group in groups.keys():
|
|
||||||
if group not in removed:
|
# save shuffled tiles to list
|
||||||
(owids, lw_regions, dw_regions) = groups[group]
|
new_results = [[],[],[]]
|
||||||
(exist_owids, exist_lw_regions, exist_dw_regions) = result_list
|
for group in groups.keys():
|
||||||
exist_owids.extend(owids)
|
if group not in removed:
|
||||||
exist_lw_regions.extend(lw_regions)
|
(owids, lw_regions, dw_regions) = groups[group]
|
||||||
exist_dw_regions.extend(dw_regions)
|
(exist_owids, exist_lw_regions, exist_dw_regions) = new_results
|
||||||
result_list = [exist_owids, exist_lw_regions, exist_dw_regions]
|
exist_owids.extend(owids)
|
||||||
|
exist_lw_regions.extend(lw_regions)
|
||||||
|
exist_dw_regions.extend(dw_regions)
|
||||||
|
|
||||||
|
# check whirlpool parity
|
||||||
|
valid_whirlpool_parity = world.owCrossed[player] != 'none' or len(set(new_results[0]) & set({0x0f, 0x12, 0x15, 0x33, 0x35, 0x3f, 0x55, 0x7f})) % 2 == 0
|
||||||
|
|
||||||
|
(exist_owids, exist_lw_regions, exist_dw_regions) = result_list
|
||||||
|
exist_owids.extend(new_results[0])
|
||||||
|
exist_lw_regions.extend(new_results[1])
|
||||||
|
exist_dw_regions.extend(new_results[2])
|
||||||
|
|
||||||
# replace LW edges with DW
|
# replace LW edges with DW
|
||||||
ignore_list = list() #TODO: Remove ignore_list when special OW areas are included in pool
|
ignore_list = list() #TODO: Remove ignore_list when special OW areas are included in pool
|
||||||
@@ -426,36 +475,62 @@ def shuffle_tiles(world, groups, result_list, player):
|
|||||||
|
|
||||||
def reorganize_tile_groups(world, player):
|
def reorganize_tile_groups(world, player):
|
||||||
groups = {}
|
groups = {}
|
||||||
for (name, groupType) in OWTileGroups.keys():
|
for (name, groupType, whirlpoolGroup) in OWTileGroups.keys():
|
||||||
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
||||||
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
||||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||||
groups[(name,)] = ([], [], [])
|
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||||
|
groups[(name, whirlpoolGroup)] = ([], [], [])
|
||||||
|
else:
|
||||||
|
groups[(name,)] = ([], [], [])
|
||||||
else:
|
else:
|
||||||
groups[(name, groupType)] = ([], [], [])
|
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||||
|
groups[(name, groupType, whirlpoolGroup)] = ([], [], [])
|
||||||
|
else:
|
||||||
|
groups[(name, groupType)] = ([], [], [])
|
||||||
|
|
||||||
for (name, groupType) in OWTileGroups.keys():
|
for (name, groupType, whirlpoolGroup) in OWTileGroups.keys():
|
||||||
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
||||||
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
||||||
(lw_owids, dw_owids) = OWTileGroups[(name, groupType,)]
|
(lw_owids, dw_owids) = OWTileGroups[(name, groupType, whirlpoolGroup)]
|
||||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name,)]
|
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||||
exist_owids.extend(lw_owids)
|
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, whirlpoolGroup)]
|
||||||
exist_owids.extend(dw_owids)
|
exist_owids.extend(lw_owids)
|
||||||
for owid in lw_owids:
|
exist_owids.extend(dw_owids)
|
||||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
for owid in lw_owids:
|
||||||
for owid in dw_owids:
|
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
for owid in dw_owids:
|
||||||
groups[(name,)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
groups[(name, whirlpoolGroup)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||||
|
else:
|
||||||
|
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name,)]
|
||||||
|
exist_owids.extend(lw_owids)
|
||||||
|
exist_owids.extend(dw_owids)
|
||||||
|
for owid in lw_owids:
|
||||||
|
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
for owid in dw_owids:
|
||||||
|
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
groups[(name,)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||||
else:
|
else:
|
||||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, groupType)]
|
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||||
exist_owids.extend(lw_owids)
|
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, groupType, whirlpoolGroup)]
|
||||||
exist_owids.extend(dw_owids)
|
exist_owids.extend(lw_owids)
|
||||||
for owid in lw_owids:
|
exist_owids.extend(dw_owids)
|
||||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
for owid in lw_owids:
|
||||||
for owid in dw_owids:
|
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
for owid in dw_owids:
|
||||||
groups[(name, groupType)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
groups[(name, groupType, whirlpoolGroup)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||||
|
else:
|
||||||
|
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, groupType)]
|
||||||
|
exist_owids.extend(lw_owids)
|
||||||
|
exist_owids.extend(dw_owids)
|
||||||
|
for owid in lw_owids:
|
||||||
|
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
for owid in dw_owids:
|
||||||
|
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||||
|
groups[(name, groupType)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||||
return groups
|
return groups
|
||||||
|
|
||||||
def remove_reserved(world, groupedlist, connected_edges, player):
|
def remove_reserved(world, groupedlist, connected_edges, player):
|
||||||
@@ -733,17 +808,7 @@ temporary_mandatory_connections = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions
|
# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions
|
||||||
mandatory_connections = [# Whirlpool Connections
|
mandatory_connections = [# Intra-tile OW Connections
|
||||||
('C Whirlpool', 'River Bend Water'),
|
|
||||||
('River Bend Whirlpool', 'C Whirlpool Water'),
|
|
||||||
('Lake Hylia Whirlpool', 'Zora Waterfall Water'),
|
|
||||||
('Zora Whirlpool', 'Lake Hylia Water'),
|
|
||||||
('Kakariko Pond Whirlpool', 'Octoballoon Water'),
|
|
||||||
('Octoballoon Whirlpool', 'Kakariko Pond Area'),
|
|
||||||
('Qirn Jump Whirlpool', 'Bomber Corner Water'),
|
|
||||||
('Bomber Corner Whirlpool', 'Qirn Jump Water'),
|
|
||||||
|
|
||||||
# Intra-tile OW Connections
|
|
||||||
('Lost Woods Bush (West)', 'Lost Woods East Area'), #pearl
|
('Lost Woods Bush (West)', 'Lost Woods East Area'), #pearl
|
||||||
('Lost Woods Bush (East)', 'Lost Woods West Area'), #pearl
|
('Lost Woods Bush (East)', 'Lost Woods West Area'), #pearl
|
||||||
('West Death Mountain Drop', 'West Death Mountain (Bottom)'),
|
('West Death Mountain Drop', 'West Death Mountain (Bottom)'),
|
||||||
@@ -967,6 +1032,13 @@ mandatory_connections = [# Whirlpool Connections
|
|||||||
('Dark Tree Line WC Cliff Water Drop', 'Dark Tree Line Water') #fake flipper
|
('Dark Tree Line WC Cliff Water Drop', 'Dark Tree Line Water') #fake flipper
|
||||||
]
|
]
|
||||||
|
|
||||||
|
default_whirlpool_connections = [
|
||||||
|
((0x33, 'C Whirlpool', 'C Whirlpool Water'), (0x15, 'River Bend Whirlpool', 'River Bend Water')),
|
||||||
|
((0x35, 'Lake Hylia Whirlpool', 'Lake Hylia Water'), (0x0f, 'Zora Whirlpool', 'Zora Waterfall Water')),
|
||||||
|
((0x12, 'Kakariko Pond Whirlpool', 'Kakariko Pond Area'), (0x3f, 'Octoballoon Whirlpool', 'Octoballoon Water')),
|
||||||
|
((0x55, 'Qirn Jump Whirlpool', 'Qirn Jump Water'), (0x7f, 'Bomber Corner Whirlpool', 'Bomber Corner Water'))
|
||||||
|
]
|
||||||
|
|
||||||
default_flute_connections = [
|
default_flute_connections = [
|
||||||
0x0b, 0x16, 0x18, 0x2c, 0x2f, 0x38, 0x3b, 0x3f
|
0x0b, 0x16, 0x18, 0x2c, 0x2f, 0x38, 0x3b, 0x3f
|
||||||
]
|
]
|
||||||
|
|||||||
7
Rom.py
7
Rom.py
@@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'c6c2a2d5d89a3c84871f58806bbb3acf'
|
RANDOMIZERBASEHASH = 'e9dea70e0a0b15bfa0ff7ecd63228a0c'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -644,6 +644,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # Y low byte
|
rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # Y low byte
|
||||||
rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # Y high byte
|
rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # Y high byte
|
||||||
|
|
||||||
|
# patch whirlpools
|
||||||
|
if world.owWhirlpoolShuffle[player]:
|
||||||
|
owFlags |= 0x01
|
||||||
|
write_int16s(rom, snes_to_pc(0x02EA5C), world.owwhirlpools[player])
|
||||||
|
|
||||||
# patch overworld edges
|
# patch overworld edges
|
||||||
inverted_buffer = [0] * 0x82
|
inverted_buffer = [0] * 0x82
|
||||||
owMode = 0
|
owMode = 0
|
||||||
|
|||||||
Binary file not shown.
@@ -15,6 +15,9 @@
|
|||||||
overworld_swap:
|
overworld_swap:
|
||||||
on: 1
|
on: 1
|
||||||
off: 1
|
off: 1
|
||||||
|
whirlpool_shuffle:
|
||||||
|
on: 1
|
||||||
|
off: 1
|
||||||
flute_shuffle:
|
flute_shuffle:
|
||||||
vanilla: 0
|
vanilla: 0
|
||||||
balanced: 1
|
balanced: 1
|
||||||
|
|||||||
@@ -133,6 +133,10 @@
|
|||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
},
|
},
|
||||||
|
"ow_whirlpool": {
|
||||||
|
"action": "store_true",
|
||||||
|
"type": "bool"
|
||||||
|
},
|
||||||
"ow_fluteshuffle": {
|
"ow_fluteshuffle": {
|
||||||
"choices": [
|
"choices": [
|
||||||
"vanilla",
|
"vanilla",
|
||||||
|
|||||||
@@ -221,6 +221,9 @@
|
|||||||
"ow_mixed": [
|
"ow_mixed": [
|
||||||
"Overworld tiles are randomly chosen to become part of the opposite world."
|
"Overworld tiles are randomly chosen to become part of the opposite world."
|
||||||
],
|
],
|
||||||
|
"ow_whirlpool": [
|
||||||
|
"Whirlpools will be shuffled and paired together."
|
||||||
|
],
|
||||||
"ow_fluteshuffle": [
|
"ow_fluteshuffle": [
|
||||||
"This randomizes the flute spot destinations.",
|
"This randomizes the flute spot destinations.",
|
||||||
"Vanilla: All flute spots remain unchanged.",
|
"Vanilla: All flute spots remain unchanged.",
|
||||||
|
|||||||
@@ -123,13 +123,18 @@
|
|||||||
"randomizer.overworld.crossed.grouped": "Grouped",
|
"randomizer.overworld.crossed.grouped": "Grouped",
|
||||||
"randomizer.overworld.crossed.limited": "Limited",
|
"randomizer.overworld.crossed.limited": "Limited",
|
||||||
"randomizer.overworld.crossed.chaos": "Chaos",
|
"randomizer.overworld.crossed.chaos": "Chaos",
|
||||||
|
|
||||||
"randomizer.overworld.keepsimilar": "Keep Similar Edges Together",
|
"randomizer.overworld.keepsimilar": "Keep Similar Edges Together",
|
||||||
|
|
||||||
"randomizer.overworld.mixed": "Tile Swap (Mixed)",
|
"randomizer.overworld.mixed": "Tile Swap (Mixed)",
|
||||||
|
|
||||||
|
"randomizer.overworld.whirlpool": "Whirlpool Shuffle",
|
||||||
|
|
||||||
"randomizer.overworld.overworldflute": "Flute Shuffle",
|
"randomizer.overworld.overworldflute": "Flute Shuffle",
|
||||||
"randomizer.overworld.overworldflute.vanilla": "Vanilla",
|
"randomizer.overworld.overworldflute.vanilla": "Vanilla",
|
||||||
"randomizer.overworld.overworldflute.balanced": "Balanced",
|
"randomizer.overworld.overworldflute.balanced": "Balanced",
|
||||||
"randomizer.overworld.overworldflute.random": "Random",
|
"randomizer.overworld.overworldflute.random": "Random",
|
||||||
|
|
||||||
|
|
||||||
"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",
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"whirlpool": {
|
||||||
|
"type": "checkbox",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"overworldflute": {
|
"overworldflute": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"default": "vanilla",
|
"default": "vanilla",
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ SETTINGSTOPROCESS = {
|
|||||||
"crossed": "ow_crossed",
|
"crossed": "ow_crossed",
|
||||||
"keepsimilar": "ow_keepsimilar",
|
"keepsimilar": "ow_keepsimilar",
|
||||||
"mixed": "ow_mixed",
|
"mixed": "ow_mixed",
|
||||||
|
"whirlpool": "ow_whirlpool",
|
||||||
"overworldflute": "ow_fluteshuffle"
|
"overworldflute": "ow_fluteshuffle"
|
||||||
},
|
},
|
||||||
"entrance": {
|
"entrance": {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ def overworld_page(parent):
|
|||||||
packAttrs = {"side":LEFT, "pady":(18,0)}
|
packAttrs = {"side":LEFT, "pady":(18,0)}
|
||||||
elif key == "overworldflute":
|
elif key == "overworldflute":
|
||||||
packAttrs["pady"] = (20,0)
|
packAttrs["pady"] = (20,0)
|
||||||
elif key == "mixed":
|
elif key in ["whirlpool", "mixed"]:
|
||||||
packAttrs = {"anchor":W, "padx":(79,0)}
|
packAttrs = {"anchor":W, "padx":(79,0)}
|
||||||
|
|
||||||
self.widgets[key].pack(packAttrs)
|
self.widgets[key].pack(packAttrs)
|
||||||
|
|||||||
Reference in New Issue
Block a user