Merge remote-tracking branch 'origin/OverworldShuffle' into GwaaKiwi
This commit is contained in:
+16
-9
@@ -1665,18 +1665,21 @@ class Entrance(object):
|
|||||||
self.temp_path = []
|
self.temp_path = []
|
||||||
|
|
||||||
def can_reach(self, state):
|
def can_reach(self, state):
|
||||||
# Destination Pickup OW Only No Ledges Can S&Q Allow Mirror
|
# Destination Pickup OW Only No Ledges Can S&Q Allow Mirror
|
||||||
multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True),
|
multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True),
|
||||||
'Missing Smith': ('Frog', True, False, True, True),
|
'Missing Smith': ('Frog', True, False, True, True),
|
||||||
'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True),
|
'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True),
|
||||||
'Old Man Drop Off': ('Lost Old Man', True, False, False, False),
|
'Dark Palace Button':('Kiki', True, False, False, False),
|
||||||
'Revealing Light': ('Suspicious Maiden', False, False, False, False)
|
'Old Man Drop Off': ('Lost Old Man', True, False, False, False),
|
||||||
|
'Revealing Light': ('Suspicious Maiden', False, False, False, False)
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.name in multi_step_locations:
|
if self.name in multi_step_locations:
|
||||||
if self not in state.path:
|
if self not in state.path:
|
||||||
world = self.parent_region.world
|
world = self.parent_region.world
|
||||||
multi_step_loc = multi_step_locations[self.name]
|
multi_step_loc = multi_step_locations[self.name]
|
||||||
|
if world.shuffle_followers[self.player]:
|
||||||
|
multi_step_loc = (multi_step_loc[0], self.name == 'Pyramid Crack', multi_step_loc[2], True, True)
|
||||||
step_location = world.get_location(multi_step_loc[0], self.player)
|
step_location = world.get_location(multi_step_loc[0], self.player)
|
||||||
if step_location.can_reach(state) and self.can_reach_thru(state, step_location, multi_step_loc[1], multi_step_loc[2], multi_step_loc[3], multi_step_loc[4]) and self.access_rule(state):
|
if step_location.can_reach(state) and self.can_reach_thru(state, step_location, multi_step_loc[1], multi_step_loc[2], multi_step_loc[3], multi_step_loc[4]) and self.access_rule(state):
|
||||||
if not self in state.path:
|
if not self in state.path:
|
||||||
@@ -2955,7 +2958,7 @@ class Spoiler(object):
|
|||||||
self.settings = {}
|
self.settings = {}
|
||||||
|
|
||||||
|
|
||||||
self.suppress_spoiler_locations = ['Big Bomb', 'Frog', 'Dark Blacksmith Ruins', 'Middle Aged Man', 'Lost Old Man', 'Old Man Drop Off']
|
self.suppress_spoiler_locations = ['Lost Old Man', 'Big Bomb', 'Frog', 'Dark Blacksmith Ruins', 'Middle Aged Man', 'Kiki']
|
||||||
|
|
||||||
def set_overworld(self, entrance, exit, direction, player):
|
def set_overworld(self, entrance, exit, direction, player):
|
||||||
if self.world.players == 1:
|
if self.world.players == 1:
|
||||||
@@ -3021,6 +3024,7 @@ class Spoiler(object):
|
|||||||
'ow_whirlpool': self.world.owWhirlpoolShuffle,
|
'ow_whirlpool': self.world.owWhirlpoolShuffle,
|
||||||
'ow_fluteshuffle': self.world.owFluteShuffle,
|
'ow_fluteshuffle': self.world.owFluteShuffle,
|
||||||
'bonk_drops': self.world.shuffle_bonk_drops,
|
'bonk_drops': self.world.shuffle_bonk_drops,
|
||||||
|
'shuffle_followers': self.world.shuffle_followers,
|
||||||
'shuffle': self.world.shuffle,
|
'shuffle': self.world.shuffle,
|
||||||
'shuffleganon': self.world.shuffle_ganon,
|
'shuffleganon': self.world.shuffle_ganon,
|
||||||
'shufflelinks': self.world.shufflelinks,
|
'shufflelinks': self.world.shufflelinks,
|
||||||
@@ -3264,6 +3268,7 @@ class Spoiler(object):
|
|||||||
outfile.write('\n')
|
outfile.write('\n')
|
||||||
outfile.write('Shopsanity:'.ljust(line_width) + '%s\n' % yn(self.metadata['shopsanity'][player]))
|
outfile.write('Shopsanity:'.ljust(line_width) + '%s\n' % yn(self.metadata['shopsanity'][player]))
|
||||||
outfile.write('Bonk Drops:'.ljust(line_width) + '%s\n' % yn(self.metadata['bonk_drops'][player]))
|
outfile.write('Bonk Drops:'.ljust(line_width) + '%s\n' % yn(self.metadata['bonk_drops'][player]))
|
||||||
|
outfile.write('Followers:'.ljust(line_width) + '%s\n' % yn(self.metadata['shuffle_followers'][player]))
|
||||||
outfile.write('Pottery Mode:'.ljust(line_width) + '%s\n' % self.metadata['pottery'][player])
|
outfile.write('Pottery Mode:'.ljust(line_width) + '%s\n' % self.metadata['pottery'][player])
|
||||||
outfile.write('Pot Shuffle (Legacy):'.ljust(line_width) + '%s\n' % yn(self.metadata['potshuffle'][player]))
|
outfile.write('Pot Shuffle (Legacy):'.ljust(line_width) + '%s\n' % yn(self.metadata['potshuffle'][player]))
|
||||||
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])
|
||||||
@@ -3677,7 +3682,7 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique
|
|||||||
or_mode = {"vanilla": 0, "parallel": 1, "full": 2}
|
or_mode = {"vanilla": 0, "parallel": 1, "full": 2}
|
||||||
orcrossed_mode = {"none": 0, "polar": 1, "grouped": 2, "unrestricted": 4}
|
orcrossed_mode = {"none": 0, "polar": 1, "grouped": 2, "unrestricted": 4}
|
||||||
|
|
||||||
# byte 12: KMB? FF?? (keep similar, mixed/tile flip, bonk drops, flute spots)
|
# byte 12: KMBQ FF?? (keep similar, mixed/tile flip, bonk drops, follower quests, flute spots)
|
||||||
flutespot_mode = {"vanilla": 0, "balanced": 1, "random": 2}
|
flutespot_mode = {"vanilla": 0, "balanced": 1, "random": 2}
|
||||||
|
|
||||||
# byte 13: FBBB TTPP (flute_mode, bow_mode, take_any, prize shuffle)
|
# byte 13: FBBB TTPP (flute_mode, bow_mode, take_any, prize shuffle)
|
||||||
@@ -3744,7 +3749,8 @@ class Settings(object):
|
|||||||
| (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)
|
||||||
| (0x20 if w.shuffle_bonk_drops[p] else 0) | (flutespot_mode[w.owFluteShuffle[p]] << 4),
|
| (0x20 if w.shuffle_bonk_drops[p] else 0) | (0x10 if w.shuffle_followers[p] else 0)
|
||||||
|
| (flutespot_mode[w.owFluteShuffle[p]] << 4),
|
||||||
|
|
||||||
(flute_mode[w.flute_mode[p]] << 7 | bow_mode[w.bow_mode[p]] << 4
|
(flute_mode[w.flute_mode[p]] << 7 | bow_mode[w.bow_mode[p]] << 4
|
||||||
| take_any_mode[w.take_any[p]] << 2 | prizeshuffle_mode[w.prizeshuffle[p]]),
|
| take_any_mode[w.take_any[p]] << 2 | prizeshuffle_mode[w.prizeshuffle[p]]),
|
||||||
@@ -3829,6 +3835,7 @@ class Settings(object):
|
|||||||
args.ow_keepsimilar[p] = True if settings[12] & 0x80 else False
|
args.ow_keepsimilar[p] = True if settings[12] & 0x80 else False
|
||||||
args.ow_mixed[p] = True if settings[12] & 0x40 else False
|
args.ow_mixed[p] = True if settings[12] & 0x40 else False
|
||||||
args.bonk_drops[p] = True if settings[12] & 0x20 else False
|
args.bonk_drops[p] = True if settings[12] & 0x20 else False
|
||||||
|
args.shuffle_followers[p] = True if settings[12] & 0x10 else False
|
||||||
args.ow_fluteshuffle[p] = r(flutespot_mode)[(settings[12] & 0x0C) >> 2]
|
args.ow_fluteshuffle[p] = r(flutespot_mode)[(settings[12] & 0x0C) >> 2]
|
||||||
|
|
||||||
if len(settings) > 13:
|
if len(settings) > 13:
|
||||||
|
|||||||
@@ -1,5 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.6.0.2
|
||||||
|
- Fixed issue with item pool placing items on Zelda Drop Off
|
||||||
|
- Fix issue with infinite purple chest item get
|
||||||
|
- Fix issue with Kiki running away on i-frame ledge hops
|
||||||
|
- Fix issue with bad follower gfx on screens with followers
|
||||||
|
- Fix issue with Zelda appearing in conditional follower locations
|
||||||
|
|
||||||
|
## 0.6.0.1
|
||||||
|
- Emergency fix for generation errors
|
||||||
|
|
||||||
|
## 0.6.0.0
|
||||||
|
- New Follower Shuffle option (See Readme)
|
||||||
|
- HMG fixes for key pickup behavior
|
||||||
|
- Fixed some errors with starting equipment
|
||||||
|
- Added documentation for some unknown/obscure starting inventory options
|
||||||
|
- Possible fix for ignorable error message for EXE users
|
||||||
|
- \~Merged in DR v1.4.9~
|
||||||
|
- Fixed Moth conveyor issue
|
||||||
|
|
||||||
## 0.5.1.5
|
## 0.5.1.5
|
||||||
- Fixed rare overworld map check VRAM crash
|
- Fixed rare overworld map check VRAM crash
|
||||||
- Fixed cavestate dark room hidden item issue
|
- Fixed cavestate dark room hidden item issue
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
|
|
||||||
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_terrain', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool', 'ow_fluteshuffle',
|
'ow_terrain', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool', 'ow_fluteshuffle',
|
||||||
'flute_mode', 'bow_mode', 'take_any', 'boots_hint',
|
'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',
|
||||||
'usestartinventory', 'bombbag', 'shuffleganon', 'overworld_map', 'restrict_boss_items',
|
'usestartinventory', 'bombbag', 'shuffleganon', 'overworld_map', 'restrict_boss_items',
|
||||||
@@ -200,6 +200,7 @@ def parse_settings():
|
|||||||
"ow_mixed": False,
|
"ow_mixed": False,
|
||||||
"ow_whirlpool": False,
|
"ow_whirlpool": False,
|
||||||
"ow_fluteshuffle": "vanilla",
|
"ow_fluteshuffle": "vanilla",
|
||||||
|
"shuffle_followers": False,
|
||||||
"bonk_drops": False,
|
"bonk_drops": False,
|
||||||
"shuffle": "vanilla",
|
"shuffle": "vanilla",
|
||||||
"shufflelinks": False,
|
"shufflelinks": False,
|
||||||
|
|||||||
+4
-1
@@ -1063,8 +1063,11 @@ def handle_split_dungeons(dungeon_builders, recombinant_builders, entrances_map,
|
|||||||
|
|
||||||
for name, split_list in split_dungeon_entrances.items():
|
for name, split_list in split_dungeon_entrances.items():
|
||||||
builder = dungeon_builders.pop(name)
|
builder = dungeon_builders.pop(name)
|
||||||
recombinant_builders[name] = builder
|
if all(len(sector.outstanding_doors) <= 0 for sector in builder.sectors):
|
||||||
|
dungeon_builders[name] = builder
|
||||||
|
continue
|
||||||
|
|
||||||
|
recombinant_builders[name] = builder
|
||||||
split_builders = split_dungeon_builder(builder, split_list, builder_info)
|
split_builders = split_dungeon_builder(builder, split_list, builder_info)
|
||||||
dungeon_builders.update(split_builders)
|
dungeon_builders.update(split_builders)
|
||||||
for sub_name, split_entrances in split_list.items():
|
for sub_name, split_entrances in split_list.items():
|
||||||
|
|||||||
@@ -1301,7 +1301,7 @@ def create_doors(world, player):
|
|||||||
world.get_door('Swamp Drain Right Switch', player).event('Swamp Drain')
|
world.get_door('Swamp Drain Right Switch', player).event('Swamp Drain')
|
||||||
world.get_door('Swamp Flooded Room Ladder', player).event('Swamp Drain')
|
world.get_door('Swamp Flooded Room Ladder', player).event('Swamp Drain')
|
||||||
|
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard' and 'Zelda Herself' not in [i.name for i in world.precollected_items if i.player == player]:
|
||||||
world.get_door('Hyrule Castle Throne Room Tapestry', player).event('Zelda Pickup')
|
world.get_door('Hyrule Castle Throne Room Tapestry', player).event('Zelda Pickup')
|
||||||
world.get_door('Hyrule Castle Tapestry Backwards', player).event('Zelda Pickup')
|
world.get_door('Hyrule Castle Tapestry Backwards', player).event('Zelda Pickup')
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -602,7 +602,8 @@ def determine_paths_for_dungeon(world, player, all_regions, name):
|
|||||||
paths.append(boss)
|
paths.append(boss)
|
||||||
if 'Thieves Boss' in all_r_names:
|
if 'Thieves Boss' in all_r_names:
|
||||||
paths.append('Thieves Boss')
|
paths.append('Thieves Boss')
|
||||||
if world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind':
|
if world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind' \
|
||||||
|
and not world.shuffle_followers[player]:
|
||||||
paths.append(('Thieves Blind\'s Cell', 'Thieves Boss'))
|
paths.append(('Thieves Blind\'s Cell', 'Thieves Boss'))
|
||||||
for drop_check in drop_path_checks:
|
for drop_check in drop_path_checks:
|
||||||
if drop_check in all_r_names:
|
if drop_check in all_r_names:
|
||||||
@@ -1324,7 +1325,8 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge
|
|||||||
for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda
|
for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda
|
||||||
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon,
|
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon,
|
||||||
candidate_sectors, global_pole)
|
candidate_sectors, global_pole)
|
||||||
if key == 'Thieves Town' and world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind':
|
if key == 'Thieves Town' and (world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind'
|
||||||
|
and not world.shuffle_followers[player]):
|
||||||
assign_sector(find_sector("Thieves Blind's Cell", candidate_sectors), current_dungeon,
|
assign_sector(find_sector("Thieves Blind's Cell", candidate_sectors), current_dungeon,
|
||||||
candidate_sectors, global_pole)
|
candidate_sectors, global_pole)
|
||||||
entrances_map, potentials, connections = connections_tuple
|
entrances_map, potentials, connections = connections_tuple
|
||||||
@@ -1342,10 +1344,6 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge
|
|||||||
if not sector:
|
if not sector:
|
||||||
sector = find_sector(r_name, all_sectors)
|
sector = find_sector(r_name, all_sectors)
|
||||||
reverse_d_map[sector] = key
|
reverse_d_map[sector] = key
|
||||||
if world.mode[player] == 'standard':
|
|
||||||
if 'Hyrule Castle' in dungeon_map:
|
|
||||||
current_dungeon = dungeon_map['Hyrule Castle']
|
|
||||||
standard_stair_check(dungeon_map, current_dungeon, candidate_sectors, global_pole)
|
|
||||||
|
|
||||||
complete_dungeons = {x: y for x, y in dungeon_map.items() if sum(len(sector.outstanding_doors) for sector in y.sectors) <= 0}
|
complete_dungeons = {x: y for x, y in dungeon_map.items() if sum(len(sector.outstanding_doors) for sector in y.sectors) <= 0}
|
||||||
[dungeon_map.pop(key) for key in complete_dungeons.keys()]
|
[dungeon_map.pop(key) for key in complete_dungeons.keys()]
|
||||||
@@ -1354,6 +1352,11 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge
|
|||||||
dungeon_map.update(complete_dungeons)
|
dungeon_map.update(complete_dungeons)
|
||||||
return dungeon_map
|
return dungeon_map
|
||||||
|
|
||||||
|
if world.mode[player] == 'standard':
|
||||||
|
if 'Hyrule Castle' in dungeon_map:
|
||||||
|
current_dungeon = dungeon_map['Hyrule Castle']
|
||||||
|
standard_stair_check(dungeon_map, current_dungeon, candidate_sectors, global_pole)
|
||||||
|
|
||||||
# categorize sectors
|
# categorize sectors
|
||||||
identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, connections,
|
identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, connections,
|
||||||
dungeon_entrances, split_dungeon_entrances)
|
dungeon_entrances, split_dungeon_entrances)
|
||||||
|
|||||||
@@ -657,6 +657,29 @@ def ensure_good_items(world, write_skips=False):
|
|||||||
if loc.type in [LocationType.Pot, LocationType.Bonk] and loc.item.name in valid_pot_items:
|
if loc.type in [LocationType.Pot, LocationType.Bonk] and loc.item.name in valid_pot_items:
|
||||||
loc.skip = True
|
loc.skip = True
|
||||||
|
|
||||||
|
dungeon_pool = collections.defaultdict(list)
|
||||||
|
prize_pool = collections.defaultdict(list)
|
||||||
|
from Dungeons import dungeon_table
|
||||||
|
from Items import prize_item_table
|
||||||
|
for dungeon in world.dungeons:
|
||||||
|
if dungeon_table[dungeon.name].prize:
|
||||||
|
dungeon_pool[dungeon.player].append(dungeon)
|
||||||
|
prize_set = set(prize_item_table.keys())
|
||||||
|
for p in range(1, world.players + 1):
|
||||||
|
prize_pool[p] = prize_set.copy()
|
||||||
|
|
||||||
|
for player in dungeon_pool:
|
||||||
|
dungeons = list(dungeon_pool[player])
|
||||||
|
random.shuffle(dungeons)
|
||||||
|
dungeon_pool[player] = dungeons
|
||||||
|
for dungeon in world.dungeons:
|
||||||
|
if dungeon.prize:
|
||||||
|
dungeon_pool[dungeon.player].remove(dungeon)
|
||||||
|
prize_pool[dungeon.prize.player].remove(dungeon.prize.name)
|
||||||
|
for p in range(1, world.players + 1):
|
||||||
|
for dungeon in dungeon_pool[p]:
|
||||||
|
dungeon.prize = ItemFactory(prize_pool[p].pop(), p)
|
||||||
|
|
||||||
|
|
||||||
invalid_location_replacement = {'Arrows (5)': 'Arrows (10)', 'Nothing': 'Rupees (5)',
|
invalid_location_replacement = {'Arrows (5)': 'Arrows (10)', 'Nothing': 'Rupees (5)',
|
||||||
'Chicken': 'Rupees (5)', 'Big Magic': 'Small Magic', 'Fairy': 'Small Heart'}
|
'Chicken': 'Rupees (5)', 'Big Magic': 'Small Magic', 'Fairy': 'Small Heart'}
|
||||||
|
|||||||
+24
-3
@@ -124,10 +124,29 @@ class InitialSram:
|
|||||||
if startingstate.has('Beat Agahnim 1', player):
|
if startingstate.has('Beat Agahnim 1', player):
|
||||||
self.pre_open_lumberjack()
|
self.pre_open_lumberjack()
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
self.set_progress_indicator(0x80) # todo: probably missing some code rom side for this
|
self.set_progress_indicator(0x80)
|
||||||
else:
|
else:
|
||||||
self.set_progress_indicator(0x03)
|
self.set_progress_indicator(0x03)
|
||||||
|
|
||||||
|
if startingstate.has('Zelda Herself', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x01
|
||||||
|
elif startingstate.has('Escort Old Man', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x04
|
||||||
|
elif startingstate.has('Maiden Rescued', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x06
|
||||||
|
elif startingstate.has('Get Frog', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x07
|
||||||
|
elif startingstate.has('Sign Vandalized', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x09
|
||||||
|
elif startingstate.has('Pick Up Kiki', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x0A
|
||||||
|
elif startingstate.has('Pick Up Purple Chest', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x0C
|
||||||
|
elif startingstate.has('Pick Up Big Bomb', player):
|
||||||
|
self._initial_sram_bytes[0x3CC] = 0x0D
|
||||||
|
if self._initial_sram_bytes[0x3CC] > 0x01 and world.mode[player] == 'standard':
|
||||||
|
self._initial_sram_bytes[0x3D3] = 0x80
|
||||||
|
|
||||||
for item in world.precollected_items:
|
for item in world.precollected_items:
|
||||||
if item.player != player:
|
if item.player != player:
|
||||||
continue
|
continue
|
||||||
@@ -138,7 +157,9 @@ class InitialSram:
|
|||||||
'Mirror Shield', 'Red Shield', 'Blue Shield', 'Progressive Shield',
|
'Mirror Shield', 'Red Shield', 'Blue Shield', 'Progressive Shield',
|
||||||
'Red Mail', 'Blue Mail', 'Progressive Armor',
|
'Red Mail', 'Blue Mail', 'Progressive Armor',
|
||||||
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)',
|
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)',
|
||||||
'Return Old Man', 'Beat Agahnim 1']:
|
'Return Old Man', 'Beat Agahnim 1', 'Zelda Herself', 'Escort Old Man',
|
||||||
|
'Maiden Rescued', 'Get Frog', 'Sign Vandalized', 'Pick Up Kiki',
|
||||||
|
'Pick Up Purple Chest', 'Pick Up Big Bomb']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
set_table = {'Book of Mudora': (0x34E, 1), 'Hammer': (0x34B, 1), 'Bug Catching Net': (0x34D, 1), 'Hookshot': (0x342, 1), 'Magic Mirror': (0x353, 2),
|
set_table = {'Book of Mudora': (0x34E, 1), 'Hammer': (0x34B, 1), 'Bug Catching Net': (0x34D, 1), 'Hookshot': (0x342, 1), 'Magic Mirror': (0x353, 2),
|
||||||
@@ -229,7 +250,7 @@ class InitialSram:
|
|||||||
equip[0x343] = min(starting_bombs, equip[0x370])
|
equip[0x343] = min(starting_bombs, equip[0x370])
|
||||||
equip[0x377] = min(starting_arrows, equip[0x371])
|
equip[0x377] = min(starting_arrows, equip[0x371])
|
||||||
|
|
||||||
if not startingstate.has('Magic Mirror', player) and world.doorShuffle[player] != 'vanilla':
|
if not startingstate.has('Magic Mirror', player) and (world.doorShuffle[player] != 'vanilla' or world.mirrorscroll[player]):
|
||||||
equip[0x353] = 1
|
equip[0x353] = 1
|
||||||
|
|
||||||
# Assertion and copy equip to initial_sram_bytes
|
# Assertion and copy equip to initial_sram_bytes
|
||||||
|
|||||||
+86
-17
@@ -129,6 +129,40 @@ difficulties = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
follower_quests = {
|
||||||
|
'Zelda Pickup': ['Zelda Herself', 'Zelda Drop Off', 'Zelda Delivered'],
|
||||||
|
'Lost Old Man': ['Escort Old Man', 'Old Man Drop Off', 'Return Old Man'],
|
||||||
|
'Locksmith': ['Sign Vandalized', None, None],
|
||||||
|
'Kiki': ['Pick Up Kiki', 'Kiki Assistance', 'Dark Palace Opened'],
|
||||||
|
'Suspicious Maiden': ['Maiden Rescued', 'Revealing Light', 'Maiden Unmasked'],
|
||||||
|
'Frog': ['Get Frog', 'Missing Smith', 'Return Smith'],
|
||||||
|
'Dark Blacksmith Ruins': ['Pick Up Purple Chest', 'Middle Aged Man', 'Deliver Purple Chest'],
|
||||||
|
'Big Bomb': ['Pick Up Big Bomb', 'Pyramid Crack', 'Detonate Big Bomb'],
|
||||||
|
}
|
||||||
|
|
||||||
|
follower_locations = {
|
||||||
|
'Zelda Pickup': 0x1802C0,
|
||||||
|
'Lost Old Man': 0x1802C3,
|
||||||
|
'Suspicious Maiden': 0x1802C6,
|
||||||
|
'Frog': 0x1802C9,
|
||||||
|
'Locksmith': 0x1802CC,
|
||||||
|
'Kiki': 0x1802CF,
|
||||||
|
'Dark Blacksmith Ruins': 0x1802D2,
|
||||||
|
'Big Bomb': 0x1802D5,
|
||||||
|
}
|
||||||
|
|
||||||
|
follower_pickups = {
|
||||||
|
'Zelda Herself': 0x01,
|
||||||
|
'Escort Old Man': 0x04,
|
||||||
|
'Maiden Rescued': 0x06,
|
||||||
|
'Get Frog': 0x07,
|
||||||
|
'Sign Vandalized': 0x09,
|
||||||
|
'Pick Up Kiki': 0x0A,
|
||||||
|
'Pick Up Purple Chest': 0x0C,
|
||||||
|
'Pick Up Big Bomb': 0x0D,
|
||||||
|
}
|
||||||
|
|
||||||
# Translate between Mike's label array and YAML/JSON keys
|
# Translate between Mike's label array and YAML/JSON keys
|
||||||
def get_custom_array_key(item):
|
def get_custom_array_key(item):
|
||||||
label_switcher = {
|
label_switcher = {
|
||||||
@@ -194,17 +228,10 @@ def generate_itempool(world, player):
|
|||||||
if world.timer in ['ohko', 'timed-ohko']:
|
if world.timer in ['ohko', 'timed-ohko']:
|
||||||
world.can_take_damage = False
|
world.can_take_damage = False
|
||||||
|
|
||||||
def set_event_item(location_name, item_name=None):
|
|
||||||
location = world.get_location(location_name, player)
|
|
||||||
if item_name:
|
|
||||||
world.push_item(location, ItemFactory(item_name, player), False)
|
|
||||||
location.event = True
|
|
||||||
location.locked = True
|
|
||||||
|
|
||||||
if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']:
|
if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']:
|
||||||
set_event_item('Ganon', 'Nothing')
|
set_event_item(world, player, 'Ganon', 'Nothing')
|
||||||
else:
|
else:
|
||||||
set_event_item('Ganon', 'Triforce')
|
set_event_item(world, player, 'Ganon', 'Triforce')
|
||||||
|
|
||||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
region = world.get_region('Hyrule Castle Courtyard', player)
|
region = world.get_region('Hyrule Castle Courtyard', player)
|
||||||
@@ -241,12 +268,9 @@ def generate_itempool(world, player):
|
|||||||
old_man.skip = True
|
old_man.skip = True
|
||||||
|
|
||||||
for loc, item in location_events.items():
|
for loc, item in location_events.items():
|
||||||
if item:
|
if loc in follower_quests and world.shuffle_followers[player]:
|
||||||
set_event_item(loc, item)
|
item = None
|
||||||
|
set_event_item(world, player, loc, item)
|
||||||
if world.mode[player] == 'standard':
|
|
||||||
set_event_item('Zelda Pickup', 'Zelda Herself')
|
|
||||||
set_event_item('Zelda Drop Off', 'Zelda Delivered')
|
|
||||||
|
|
||||||
# set up item pool
|
# set up item pool
|
||||||
skip_pool_adjustments = False
|
skip_pool_adjustments = False
|
||||||
@@ -459,7 +483,8 @@ def generate_itempool(world, player):
|
|||||||
world.itempool = [beemizer(item) for item in world.itempool]
|
world.itempool = [beemizer(item) for item in world.itempool]
|
||||||
|
|
||||||
# increase pool if not enough items
|
# increase pool if not enough items
|
||||||
ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if world.prizeshuffle[player] != 'none' or not x.prize)
|
ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if not x.prize and not x.event)
|
||||||
|
ttl_locations -= 10 if world.prizeshuffle[player] in ['dungeon', 'nearby'] else 0 # TODO: Fix item pool to include prizes for these modes
|
||||||
pool_size = count_player_dungeon_item_pool(world, player)
|
pool_size = count_player_dungeon_item_pool(world, player)
|
||||||
pool_size += sum(1 for x in world.itempool if x.player == player)
|
pool_size += sum(1 for x in world.itempool if x.player == player)
|
||||||
|
|
||||||
@@ -1247,7 +1272,7 @@ def modify_pool_for_start_inventory(start_inventory, world, player):
|
|||||||
world.itempool.remove(alt_item)
|
world.itempool.remove(alt_item)
|
||||||
i = i-1
|
i = i-1
|
||||||
elif 'Bottle' in item.name:
|
elif 'Bottle' in item.name:
|
||||||
bottle_item = next((x for x in world.itempool if 'Bottle' in item.name and x.player == player), None)
|
bottle_item = next((x for x in world.itempool if 'Bottle' in x.name and x.player == player), None)
|
||||||
if bottle_item is not None:
|
if bottle_item is not None:
|
||||||
world.itempool.remove(bottle_item)
|
world.itempool.remove(bottle_item)
|
||||||
if item.dungeon:
|
if item.dungeon:
|
||||||
@@ -1647,6 +1672,50 @@ def fill_specific_items(world):
|
|||||||
world.item_pool_config.verify_target += len(placement['locations'])
|
world.item_pool_config.verify_target += len(placement['locations'])
|
||||||
|
|
||||||
|
|
||||||
|
def set_event_item(world, player, location_name, item_name=None):
|
||||||
|
location = world.get_location(location_name, player)
|
||||||
|
if item_name:
|
||||||
|
world.push_item(location, ItemFactory(item_name, player), False)
|
||||||
|
location.event = True
|
||||||
|
if location_name not in follower_quests or not world.shuffle_followers[player]:
|
||||||
|
location.locked = True
|
||||||
|
|
||||||
|
|
||||||
|
def shuffle_event_items(world, player):
|
||||||
|
if (world.shuffle_followers[player]):
|
||||||
|
available_quests = follower_quests.copy()
|
||||||
|
available_pickups = [quests[0] for quests in available_quests.values()]
|
||||||
|
|
||||||
|
for loc_name in follower_quests.keys():
|
||||||
|
loc = world.get_location(loc_name, player)
|
||||||
|
if loc.item:
|
||||||
|
set_event_item(world, player, loc_name)
|
||||||
|
available_quests.pop(loc_name)
|
||||||
|
available_pickups.remove(loc.item.name)
|
||||||
|
|
||||||
|
|
||||||
|
if world.mode[player] == 'standard':
|
||||||
|
if 'Zelda Herself' in available_pickups:
|
||||||
|
zelda_pickup = available_quests.pop('Zelda Pickup')[0]
|
||||||
|
available_pickups.remove(zelda_pickup)
|
||||||
|
set_event_item(world, player, 'Zelda Pickup', zelda_pickup)
|
||||||
|
|
||||||
|
random.shuffle(available_pickups)
|
||||||
|
|
||||||
|
restricted_pickups = { 'Get Frog': 'Dark Blacksmith Ruins'}
|
||||||
|
for pickup in restricted_pickups:
|
||||||
|
restricted_quests = [q for q in available_quests.keys() if q not in restricted_pickups[pickup]]
|
||||||
|
random.shuffle(restricted_quests)
|
||||||
|
quest = restricted_quests.pop()
|
||||||
|
available_quests.pop(quest)
|
||||||
|
available_pickups.remove(pickup)
|
||||||
|
set_event_item(world, player, quest, pickup)
|
||||||
|
|
||||||
|
for pickup in available_pickups:
|
||||||
|
quest, _ = available_quests.popitem()
|
||||||
|
set_event_item(world, player, quest, pickup)
|
||||||
|
|
||||||
|
|
||||||
def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool):
|
def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool):
|
||||||
item_parts = item.split('#')
|
item_parts = item.split('#')
|
||||||
item_player = player if len(item_parts) < 2 else int(item_parts[1])
|
item_player = player if len(item_parts) < 2 else int(item_parts[1])
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'Bow!\nJoin the archer class
|
|||||||
'Beat Boss': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Beat Boss': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Beat Agahnim 1': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Beat Agahnim 1': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Beat Agahnim 2': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Beat Agahnim 2': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
|
'Pick Up Kiki': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
|
'Dark Palace Opened': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Get Frog': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Get Frog': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Return Smith': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Return Smith': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Pick Up Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Pick Up Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
@@ -198,6 +200,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'Bow!\nJoin the archer class
|
|||||||
'Hidden Pits': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Hidden Pits': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Zelda Herself': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Zelda Herself': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Zelda Delivered': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Zelda Delivered': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
|
'Sign Vandalized': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Escort Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Escort Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Return Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Return Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
'Farmable Bombs': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
'Farmable Bombs': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from Dungeons import create_dungeons
|
|||||||
from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dungeons_restrictive, ensure_good_items
|
from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dungeons_restrictive, ensure_good_items
|
||||||
from Fill import dungeon_tracking
|
from Fill import dungeon_tracking
|
||||||
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations, set_prize_drops
|
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations, set_prize_drops
|
||||||
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items, create_farm_locations
|
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items, create_farm_locations, shuffle_event_items, follower_pickups
|
||||||
from UnderworldGlitchRules import connect_hmg_entrances_regions, create_hmg_entrances_regions
|
from UnderworldGlitchRules import connect_hmg_entrances_regions, create_hmg_entrances_regions
|
||||||
from Utils import output_path, parse_player_names
|
from Utils import output_path, parse_player_names
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ from source.enemizer.DamageTables import DamageTable
|
|||||||
from source.enemizer.Enemizer import randomize_enemies
|
from source.enemizer.Enemizer import randomize_enemies
|
||||||
from source.rom.DataTables import init_data_tables
|
from source.rom.DataTables import init_data_tables
|
||||||
|
|
||||||
version_number = '1.4.8.1'
|
version_number = '1.4.9'
|
||||||
version_branch = '-u'
|
version_branch = '-u'
|
||||||
__version__ = f'{version_number}{version_branch}'
|
__version__ = f'{version_number}{version_branch}'
|
||||||
|
|
||||||
@@ -245,6 +245,7 @@ def main(args, seed=None, fish=None):
|
|||||||
sell_keys(world, player)
|
sell_keys(world, player)
|
||||||
else:
|
else:
|
||||||
lock_shop_locations(world, player)
|
lock_shop_locations(world, player)
|
||||||
|
shuffle_event_items(world, player)
|
||||||
|
|
||||||
massage_item_pool(world)
|
massage_item_pool(world)
|
||||||
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
|
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
|
||||||
@@ -435,6 +436,9 @@ def export_yaml(args, fish):
|
|||||||
for k,v in {"DR":__version__,"OR":ORVersion}.items():
|
for k,v in {"DR":__version__,"OR":ORVersion}.items():
|
||||||
logger.info((k + ' Version:').ljust(16) + '%s' % v)
|
logger.info((k + ' Version:').ljust(16) + '%s' % v)
|
||||||
|
|
||||||
|
for player in range(1, world.players + 1):
|
||||||
|
world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
|
||||||
|
|
||||||
set_starting_inventory(world, args)
|
set_starting_inventory(world, args)
|
||||||
|
|
||||||
world.settings = CustomSettings()
|
world.settings = CustomSettings()
|
||||||
@@ -479,6 +483,7 @@ def init_world(args, fish):
|
|||||||
world.owKeepSimilar = args.ow_keepsimilar.copy()
|
world.owKeepSimilar = args.ow_keepsimilar.copy()
|
||||||
world.owWhirlpoolShuffle = args.ow_whirlpool.copy()
|
world.owWhirlpoolShuffle = args.ow_whirlpool.copy()
|
||||||
world.owFluteShuffle = args.ow_fluteshuffle.copy()
|
world.owFluteShuffle = args.ow_fluteshuffle.copy()
|
||||||
|
world.shuffle_followers = args.shuffle_followers.copy()
|
||||||
world.shuffle_bonk_drops = args.bonk_drops.copy()
|
world.shuffle_bonk_drops = args.bonk_drops.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()
|
||||||
@@ -535,6 +540,7 @@ def set_starting_inventory(world, args):
|
|||||||
if world.customizer and world.customizer.get_start_inventory():
|
if world.customizer and world.customizer.get_start_inventory():
|
||||||
for p, inv_list in world.customizer.get_start_inventory().items():
|
for p, inv_list in world.customizer.get_start_inventory().items():
|
||||||
if inv_list:
|
if inv_list:
|
||||||
|
follower_added = False
|
||||||
for inv_item in inv_list:
|
for inv_item in inv_list:
|
||||||
name = inv_item.strip()
|
name = inv_item.strip()
|
||||||
if inv_item == 'RandomWeapon':
|
if inv_item == 'RandomWeapon':
|
||||||
@@ -548,7 +554,13 @@ def set_starting_inventory(world, args):
|
|||||||
item = ItemFactory(e, p)
|
item = ItemFactory(e, p)
|
||||||
if item:
|
if item:
|
||||||
world.push_precollected(item)
|
world.push_precollected(item)
|
||||||
|
elif inv_item == 'RandomFollower':
|
||||||
|
name = random.choice([f for f in follower_pickups if f != 'Zelda Herself' or world.mode[p] == 'standard'])
|
||||||
name = name if name != 'Ocarina' or world.flute_mode[p] != 'active' else 'Ocarina (Activated)'
|
name = name if name != 'Ocarina' or world.flute_mode[p] != 'active' else 'Ocarina (Activated)'
|
||||||
|
if name in follower_pickups:
|
||||||
|
if not world.shuffle_followers[p] or follower_added:
|
||||||
|
continue
|
||||||
|
follower_added = True
|
||||||
item = ItemFactory(name, p)
|
item = ItemFactory(name, p)
|
||||||
if item:
|
if item:
|
||||||
world.push_precollected(item)
|
world.push_precollected(item)
|
||||||
@@ -596,6 +608,7 @@ def copy_world(world):
|
|||||||
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
||||||
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
||||||
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
||||||
|
ret.shuffle_followers = world.shuffle_followers.copy()
|
||||||
ret.shuffle_bonk_drops = world.shuffle_bonk_drops.copy()
|
ret.shuffle_bonk_drops = world.shuffle_bonk_drops.copy()
|
||||||
ret.open_pyramid = world.open_pyramid.copy()
|
ret.open_pyramid = world.open_pyramid.copy()
|
||||||
ret.shufflelinks = world.shufflelinks.copy()
|
ret.shufflelinks = world.shufflelinks.copy()
|
||||||
@@ -818,6 +831,7 @@ def copy_world_premature(world, player):
|
|||||||
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
||||||
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
||||||
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
||||||
|
ret.shuffle_followers = world.shuffle_followers.copy()
|
||||||
ret.shuffle_bonk_drops = world.shuffle_bonk_drops.copy()
|
ret.shuffle_bonk_drops = world.shuffle_bonk_drops.copy()
|
||||||
ret.open_pyramid = world.open_pyramid.copy()
|
ret.open_pyramid = world.open_pyramid.copy()
|
||||||
ret.shufflelinks = world.shufflelinks.copy()
|
ret.shufflelinks = world.shufflelinks.copy()
|
||||||
|
|||||||
@@ -1241,6 +1241,7 @@ OWTileRegions = bidict({
|
|||||||
'Broken Bridge Water': 0x5d,
|
'Broken Bridge Water': 0x5d,
|
||||||
|
|
||||||
'Palace of Darkness Area': 0x5e,
|
'Palace of Darkness Area': 0x5e,
|
||||||
|
'Dark Palace Button': 0x5e,
|
||||||
|
|
||||||
'Hammer Pegs Area': 0x62,
|
'Hammer Pegs Area': 0x62,
|
||||||
'Hammer Pegs Entry': 0x62,
|
'Hammer Pegs Entry': 0x62,
|
||||||
@@ -1580,6 +1581,7 @@ OWExitTypes = {
|
|||||||
'Middle Aged Man',
|
'Middle Aged Man',
|
||||||
'Desert Pass Ladder (South)',
|
'Desert Pass Ladder (South)',
|
||||||
'Desert Pass Ladder (North)',
|
'Desert Pass Ladder (North)',
|
||||||
|
'Kiki Assistance',
|
||||||
'GT Approach',
|
'GT Approach',
|
||||||
'GT Leave',
|
'GT Leave',
|
||||||
],
|
],
|
||||||
|
|||||||
+3
-2
@@ -8,9 +8,9 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
|
|||||||
from OverworldGlitchRules import create_owg_connections
|
from OverworldGlitchRules import create_owg_connections
|
||||||
from Utils import bidict
|
from Utils import bidict
|
||||||
|
|
||||||
version_number = '0.5.1.5'
|
version_number = '0.6.0.2'
|
||||||
# branch indicator is intentionally different across branches
|
# branch indicator is intentionally different across branches
|
||||||
version_branch = '-u'
|
version_branch = ''
|
||||||
|
|
||||||
__version__ = '%s%s' % (version_number, version_branch)
|
__version__ = '%s%s' % (version_number, version_branch)
|
||||||
|
|
||||||
@@ -1833,6 +1833,7 @@ mandatory_connections = [
|
|||||||
('Broken Bridge Water Drop', 'Broken Bridge Water'), #flippers
|
('Broken Bridge Water Drop', 'Broken Bridge Water'), #flippers
|
||||||
('Broken Bridge Northeast Water Drop', 'Broken Bridge Water'), #flippers
|
('Broken Bridge Northeast Water Drop', 'Broken Bridge Water'), #flippers
|
||||||
('Broken Bridge West Water Drop', 'Broken Bridge Water'), #flippers
|
('Broken Bridge West Water Drop', 'Broken Bridge Water'), #flippers
|
||||||
|
('Kiki Assistance', 'Dark Palace Button'),
|
||||||
('Peg Area Rocks (West)', 'Hammer Pegs Area'), #mitts
|
('Peg Area Rocks (West)', 'Hammer Pegs Area'), #mitts
|
||||||
('Peg Area Rocks (East)', 'Hammer Pegs Entry'), #mitts
|
('Peg Area Rocks (East)', 'Hammer Pegs Entry'), #mitts
|
||||||
('Dig Game To Ledge Drop', 'Dig Game Ledge'), #mitts
|
('Dig Game To Ledge Drop', 'Dig Game Ledge'), #mitts
|
||||||
|
|||||||
@@ -234,6 +234,27 @@ New flute spots are chosen at random, with restrictions that limit the promixity
|
|||||||
|
|
||||||
New flute spots are chosen at random with minimum bias.
|
New flute spots are chosen at random with minimum bias.
|
||||||
|
|
||||||
|
## Follower Shuffle (--shuffle_followers)
|
||||||
|
|
||||||
|
This shuffles the follower companions throughout the world. Here is a full list of followers in the game:
|
||||||
|
|
||||||
|
- Princess Zelda
|
||||||
|
- Old Man
|
||||||
|
- Blind Maiden
|
||||||
|
- Frog/Blacksmith
|
||||||
|
- Locksmith (Guy who unlocks Purple Chest)
|
||||||
|
- Kiki the Monkey
|
||||||
|
- Purple Chest
|
||||||
|
- Super Bomb
|
||||||
|
|
||||||
|
When followers are shuffled, you must still fulfill the original requirements of the follower location. For example, if the Super Bomb Shop now contains the Frog, you must have crystals 5 and 6 and 100 rupees to unlock the Frog. It is also important to note that Purple Chest still needs to be delivered to the usual spot. Also, since it isn't useful normally, many people might not know that the Locksmith (the Purple Chest unlocking guy) can follow you, you must remove his sign to get him to follow.
|
||||||
|
|
||||||
|
Most of the limitations of followers in the vanilla game have been lifted for this shuffle to work. For instance, you are able to mirror, flute, die, collect a crystal, and save/quit in most situations and still retain the follower. You are also able to enter caves/dungeons and complete dig game while you have a follower.
|
||||||
|
|
||||||
|
In the scenario where you are forced down a narrow path and a follower is in your way and you already have a different follower. Running into that follower will switch the followers rather than overwriting, this gives you the opportunity to proceed with either one of the followers. Note that if you leave the screen, you lose this option to switch and you will need to go back to the original place you found the first follower.
|
||||||
|
|
||||||
|
Optionally, thru the customizer, you can add a follower to your starting inventory, and you will be given that follower and it will stay with you until you complete their quest.
|
||||||
|
|
||||||
## Bonk Drop Shuffle (--bonk_drops)
|
## Bonk Drop Shuffle (--bonk_drops)
|
||||||
|
|
||||||
This adds 42 new item locations to the game. These bonk locations are limited to the ones that drop a static item in the vanilla game.
|
This adds 42 new item locations to the game. These bonk locations are limited to the ones that drop a static item in the vanilla game.
|
||||||
@@ -272,7 +293,7 @@ As far as map trackers, Bonk Locations are supported on `CodeTracker` when the B
|
|||||||
|
|
||||||
This is a new option in addition to the traditional wild vs non-wild (keysanity/non-keysanity) options for all the dungeon item types (maps, compasses, small keys, big keys, prizes). This new option shuffles dungeon items into locations somewhere either within the dungeon that it is assigned to or within the surrounding district of that dungeon.
|
This is a new option in addition to the traditional wild vs non-wild (keysanity/non-keysanity) options for all the dungeon item types (maps, compasses, small keys, big keys, prizes). This new option shuffles dungeon items into locations somewhere either within the dungeon that it is assigned to or within the surrounding district of that dungeon.
|
||||||
|
|
||||||
## Prize Shuffle
|
## Prize Shuffle (--prizeshuffle)
|
||||||
|
|
||||||
A new option has been added to shuffle the 10 dungeon prizes in ways that they haven't been shuffled before. This means that dungeon prizes can be found in other item locations, such as chests or free-standing item locations. This also means that bosses are able to drop a 2nd item in place of the shuffled prize.
|
A new option has been added to shuffle the 10 dungeon prizes in ways that they haven't been shuffled before. This means that dungeon prizes can be found in other item locations, such as chests or free-standing item locations. This also means that bosses are able to drop a 2nd item in place of the shuffled prize.
|
||||||
|
|
||||||
@@ -292,7 +313,7 @@ This option shuffles the prize into a location somewhere either within the dunge
|
|||||||
|
|
||||||
This option freely shuffles the prizes throughout the world. While the dungeon prizes can end up anywhere, they still are assigned to a specific dungeon. When you defeat the boss of a certain dungeon, checking the map on the overworld will reveal the location WHERE you can find the prize, an example shown [here](https://zelda.codemann8.com/images/shared/prizemap-all.gif). Finding the map will still reveal WHAT the prize is. If you defeated a boss but haven't collected the map for that dungeon, the prize will be indicated by a red X, example shown [here](https://zelda.codemann8.com/images/shared/prizemap-boss.gif). If you collected a map but haven't defeated the boss yet, the icon indicator on the map will be shown on the top edge (for LW dungeons) or the bottom edge (for DW dungeons), but it will show you WHAT the prize is for that dungeon, an example of that is shown [here](https://zelda.codemann8.com/images/shared/prizemap-map.gif).
|
This option freely shuffles the prizes throughout the world. While the dungeon prizes can end up anywhere, they still are assigned to a specific dungeon. When you defeat the boss of a certain dungeon, checking the map on the overworld will reveal the location WHERE you can find the prize, an example shown [here](https://zelda.codemann8.com/images/shared/prizemap-all.gif). Finding the map will still reveal WHAT the prize is. If you defeated a boss but haven't collected the map for that dungeon, the prize will be indicated by a red X, example shown [here](https://zelda.codemann8.com/images/shared/prizemap-boss.gif). If you collected a map but haven't defeated the boss yet, the icon indicator on the map will be shown on the top edge (for LW dungeons) or the bottom edge (for DW dungeons), but it will show you WHAT the prize is for that dungeon, an example of that is shown [here](https://zelda.codemann8.com/images/shared/prizemap-map.gif).
|
||||||
|
|
||||||
- It is important to note that the overworld map check has changed: the numbered icons that are displayed are NO LONGER indicating the crystal number like they have in the past. They are now indicating the dungeon that it belongs to; a blue 1-3 indicates the 3 LW dungeons (EP, DP, and ToH) and a red 1-7 indicate the 7 DW dungeons
|
- It is important to note that the overworld map check has changed: the numbered icons that are displayed are NO LONGER indicating the crystal number like they have in the past. They are now indicating the dungeon that it belongs to; a blue E/D/T indicates the 3 LW dungeons (EP, DP, and ToH) and a red 1-7 indicate the 7 DW dungeons
|
||||||
|
|
||||||
## New Goal Options (--goal)
|
## New Goal Options (--goal)
|
||||||
|
|
||||||
@@ -403,8 +424,20 @@ This gives each OW tile a random chance to be flipped to the opposite world
|
|||||||
|
|
||||||
For randomizing the flute spots around the overworld
|
For randomizing the flute spots around the overworld
|
||||||
|
|
||||||
|
```
|
||||||
|
--shuffle_followers
|
||||||
|
```
|
||||||
|
|
||||||
|
This shuffles the follower companion locations, ie. Purple Chest, Old Man, etc.
|
||||||
|
|
||||||
```
|
```
|
||||||
--bonk_drops
|
--bonk_drops
|
||||||
```
|
```
|
||||||
|
|
||||||
This extends the item pool to bonk locations and makes them additional item locations
|
This extends the item pool to bonk locations and makes them additional item locations
|
||||||
|
|
||||||
|
```
|
||||||
|
--prizeshuffle <mode>
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows prizes (crystals/pendants) to shuffle outside their usual boss location.
|
||||||
|
|||||||
+8
-15
@@ -141,18 +141,11 @@ These are now independent of retro mode and have three options: None, Random, an
|
|||||||
|
|
||||||
# Patch Notes
|
# Patch Notes
|
||||||
|
|
||||||
* 1.4.8.1
|
* 1.4.9
|
||||||
- Fixed broken doors generation
|
* Attempted fix for Moth conveyor room timing. THank for many people's input. Unsure if Helmacopter is still acceptable.
|
||||||
- Fixed bomb/arrow upgrade ignoring custom pricing
|
* Mirror scroll will show up on file start screen if enabled (thanks Clearmouse!)
|
||||||
- Extended `money_balance` to apply to price balancing for non-custom shops.
|
* Fixes for HMG by Muffins
|
||||||
* 1.4.8
|
* Various fixes for Enemizer by Codemann (gfx fixes, more randomization options)
|
||||||
- New option: Mirror Scroll - to add the item to the starting inventory in non-doors modes (Thanks Telethar!)
|
* Vanilla door shuffle prevents big key doors changes from door_type_mode
|
||||||
- Customizer: Ability to customize shop prices and control money balancing. `money_balance` is a percentage betwen 0 and 100 that attempts to ensure you have that much percentage of money available for purchases. (100 is default, 0 essentially ignores money considerations)
|
* Couple of minor fixes to custom generation. Deals with a complete specification of all dungeons
|
||||||
- Fixed a key logic bug with decoupled doors when a big key door leads to a small key door (the small key door was missing appropriate logic)
|
* Various enemizer bans for blocked paths (thanks to all the reports, Q1 2025)
|
||||||
- Fixed an ER bug where Bonk Fairy could be used for a mandatory connector in standard mode (boots could allow escape to be skipped)
|
|
||||||
- Fixed an issue with flute activation in rain mode. (thanks Codemann!)
|
|
||||||
- Fixed an issue with enemies in TR Dark Ride room not requiring Somaria. (Refactored the room for decoupled logic better)
|
|
||||||
- More HMG fixes by Muffins
|
|
||||||
- Fixed an issue with multi-player HMG
|
|
||||||
- Fixed an issue limiting number of items specified in the item pool on the GUI
|
|
||||||
- Minor documentation fixes (thanks Codemann!)
|
|
||||||
|
|||||||
+17
-8
@@ -133,7 +133,7 @@ def create_regions(world, player):
|
|||||||
create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Ice Cave Water Drop', 'Ice Cave SE']),
|
create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Ice Cave Water Drop', 'Ice Cave SE']),
|
||||||
create_lw_region(player, 'Ice Cave Water', None, ['Ice Cave Pier', 'Ice Cave SW'], 'Light World', Terrain.Water),
|
create_lw_region(player, 'Ice Cave Water', None, ['Ice Cave Pier', 'Ice Cave SW'], 'Light World', Terrain.Water),
|
||||||
create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Fairy', '50 Rupee Cave', 'Middle Aged Man', 'Desert Pass Ladder (South)', 'Desert Pass Rocks (North)', 'Desert Pass WS', 'Desert Pass EC']),
|
create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Fairy', '50 Rupee Cave', 'Middle Aged Man', 'Desert Pass Ladder (South)', 'Desert Pass Rocks (North)', 'Desert Pass WS', 'Desert Pass EC']),
|
||||||
create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None),
|
create_lw_region(player, 'Middle Aged Man', ['Purple Chest', 'Locksmith'], None),
|
||||||
create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Desert Pass ES']),
|
create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Desert Pass ES']),
|
||||||
create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Desert Pass WC']),
|
create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Desert Pass WC']),
|
||||||
create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']),
|
create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']),
|
||||||
@@ -197,7 +197,8 @@ def create_regions(world, player):
|
|||||||
create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Broken Bridge NE']),
|
create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Broken Bridge NE']),
|
||||||
create_dw_region(player, 'Broken Bridge West', None, ['Broken Bridge West Water Drop', 'Broken Bridge NW']),
|
create_dw_region(player, 'Broken Bridge West', None, ['Broken Bridge West Water Drop', 'Broken Bridge NW']),
|
||||||
create_dw_region(player, 'Broken Bridge Water', None, ['Broken Bridge NC'], 'Dark World', Terrain.Water),
|
create_dw_region(player, 'Broken Bridge Water', None, ['Broken Bridge NC'], 'Dark World', Terrain.Water),
|
||||||
create_dw_region(player, 'Palace of Darkness Area', None, ['Palace of Darkness Hint', 'Palace of Darkness', 'Palace of Darkness SW', 'Palace of Darkness SE']),
|
create_dw_region(player, 'Palace of Darkness Area', ['Kiki'], ['Palace of Darkness Hint', 'Palace of Darkness', 'Kiki Assistance', 'Palace of Darkness SW', 'Palace of Darkness SE']),
|
||||||
|
create_dw_region(player, 'Dark Palace Button', ['Kiki Assistance'], None),
|
||||||
create_dw_region(player, 'Darkness Cliff', None, ['Dark Dunes Cliff Ledge Drop', 'Hammer Bridge North Cliff Ledge Drop', 'Dark Tree Line Cliff Ledge Drop', 'Palace of Darkness Cliff Ledge Drop']),
|
create_dw_region(player, 'Darkness Cliff', None, ['Dark Dunes Cliff Ledge Drop', 'Hammer Bridge North Cliff Ledge Drop', 'Dark Tree Line Cliff Ledge Drop', 'Palace of Darkness Cliff Ledge Drop']),
|
||||||
create_dw_region(player, 'Hammer Pegs Area', ['Dark Blacksmith Ruins'], ['Hammer Peg Cave', 'Peg Area Rocks (East)']),
|
create_dw_region(player, 'Hammer Pegs Area', ['Dark Blacksmith Ruins'], ['Hammer Peg Cave', 'Peg Area Rocks (East)']),
|
||||||
create_dw_region(player, 'Hammer Pegs Entry', None, ['Peg Area Rocks (West)', 'Hammer Pegs WS']),
|
create_dw_region(player, 'Hammer Pegs Entry', None, ['Peg Area Rocks (West)', 'Hammer Pegs WS']),
|
||||||
@@ -436,7 +437,6 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Hyrule Dungeon Staircase', 'Hyrule Castle', None, ['Hyrule Dungeon Staircase Up Stairs', 'Hyrule Dungeon Staircase Down Stairs']),
|
create_dungeon_region(player, 'Hyrule Dungeon Staircase', 'Hyrule Castle', None, ['Hyrule Dungeon Staircase Up Stairs', 'Hyrule Dungeon Staircase Down Stairs']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Cellblock', 'Hyrule Castle', ['Hyrule Castle - Big Key Drop'], ['Hyrule Dungeon Cellblock Up Stairs', 'Hyrule Dungeon Cellblock Door']),
|
create_dungeon_region(player, 'Hyrule Dungeon Cellblock', 'Hyrule Castle', ['Hyrule Castle - Big Key Drop'], ['Hyrule Dungeon Cellblock Up Stairs', 'Hyrule Dungeon Cellblock Door']),
|
||||||
create_dungeon_region(player, 'Hyrule Dungeon Cell', 'Hyrule Castle',
|
create_dungeon_region(player, 'Hyrule Dungeon Cell', 'Hyrule Castle',
|
||||||
["Hyrule Castle - Zelda's Chest"] if not std_flag else
|
|
||||||
["Hyrule Castle - Zelda's Chest", 'Zelda Pickup'],
|
["Hyrule Castle - Zelda's Chest", 'Zelda Pickup'],
|
||||||
['Hyrule Dungeon Cell Exit']),
|
['Hyrule Dungeon Cell Exit']),
|
||||||
|
|
||||||
@@ -456,7 +456,8 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Sewers Yet More Rats', 'Hyrule Castle', None, ['Sewers Pull Switch Down Stairs', 'Sewers Yet More Rats S']),
|
create_dungeon_region(player, 'Sewers Yet More Rats', 'Hyrule Castle', None, ['Sewers Pull Switch Down Stairs', 'Sewers Yet More Rats S']),
|
||||||
create_dungeon_region(player, 'Sewers Pull Switch', 'Hyrule Castle', None, ['Sewers Pull Switch N', 'Sewers Pull Switch S']),
|
create_dungeon_region(player, 'Sewers Pull Switch', 'Hyrule Castle', None, ['Sewers Pull Switch N', 'Sewers Pull Switch S']),
|
||||||
create_dungeon_region(player, 'Sanctuary', 'Hyrule Castle',
|
create_dungeon_region(player, 'Sanctuary', 'Hyrule Castle',
|
||||||
['Sanctuary'] if not std_flag else ['Sanctuary', 'Zelda Drop Off'],
|
#['Sanctuary'] if not std_flag else
|
||||||
|
['Sanctuary', 'Zelda Drop Off'],
|
||||||
['Sanctuary S', 'Sanctuary N', 'Sanctuary Mirror Route']),
|
['Sanctuary S', 'Sanctuary N', 'Sanctuary Mirror Route']),
|
||||||
|
|
||||||
# Eastern Palace
|
# Eastern Palace
|
||||||
@@ -1249,13 +1250,15 @@ def adjust_locations(world, player):
|
|||||||
location.prize = prize_on_boss
|
location.prize = prize_on_boss
|
||||||
location.real = not prize_on_boss
|
location.real = not prize_on_boss
|
||||||
# unreal events:
|
# unreal events:
|
||||||
for l in ['Ganon', 'Zelda Pickup', 'Zelda Drop Off'] + list(location_events):
|
for l in ['Ganon'] + list(location_events):
|
||||||
location = world.get_location_unsafe(l, player)
|
location = world.get_location_unsafe(l, player)
|
||||||
if location:
|
if location:
|
||||||
location.type = LocationType.Logical
|
location.type = LocationType.Logical
|
||||||
location.real = False
|
location.real = False
|
||||||
if l not in ['Ganon', 'Agahnim 1', 'Agahnim 2']:
|
if l not in ['Ganon', 'Agahnim 1', 'Agahnim 2']:
|
||||||
location.skip = True
|
from ItemList import follower_quests
|
||||||
|
if not world.shuffle_followers[player] or l not in follower_quests:
|
||||||
|
location.skip = True
|
||||||
|
|
||||||
|
|
||||||
def valid_pot_location(pot, pot_set, world, player):
|
def valid_pot_location(pot, pot_set, world, player):
|
||||||
@@ -1413,9 +1416,12 @@ location_events = {
|
|||||||
'Ice Palace - Boss Kill': 'Beat Boss',
|
'Ice Palace - Boss Kill': 'Beat Boss',
|
||||||
'Misery Mire - Boss Kill': 'Beat Boss',
|
'Misery Mire - Boss Kill': 'Beat Boss',
|
||||||
'Turtle Rock - Boss Kill': 'Beat Boss',
|
'Turtle Rock - Boss Kill': 'Beat Boss',
|
||||||
|
'Locksmith': 'Sign Vandalized',
|
||||||
'Lost Old Man': 'Escort Old Man',
|
'Lost Old Man': 'Escort Old Man',
|
||||||
'Old Man Drop Off': 'Return Old Man',
|
'Old Man Drop Off': 'Return Old Man',
|
||||||
'Floodgate': 'Open Floodgate',
|
'Floodgate': 'Open Floodgate',
|
||||||
|
'Kiki': 'Pick Up Kiki',
|
||||||
|
'Kiki Assistance': 'Dark Palace Opened',
|
||||||
'Big Bomb': 'Pick Up Big Bomb',
|
'Big Bomb': 'Pick Up Big Bomb',
|
||||||
'Pyramid Crack': 'Detonate Big Bomb',
|
'Pyramid Crack': 'Detonate Big Bomb',
|
||||||
'Frog': 'Get Frog',
|
'Frog': 'Get Frog',
|
||||||
@@ -1431,8 +1437,8 @@ location_events = {
|
|||||||
'Revealing Light': 'Maiden Unmasked',
|
'Revealing Light': 'Maiden Unmasked',
|
||||||
'Ice Block Drop': 'Convenient Block',
|
'Ice Block Drop': 'Convenient Block',
|
||||||
'Skull Star Tile': 'Hidden Pits',
|
'Skull Star Tile': 'Hidden Pits',
|
||||||
'Zelda Pickup': None,
|
'Zelda Pickup': 'Zelda Herself',
|
||||||
'Zelda Drop Off': None
|
'Zelda Drop Off': 'Zelda Delivered'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1671,9 +1677,12 @@ location_table = {'Mushroom': (0x180013, 0x186df8, False, 'in the woods'),
|
|||||||
'Ice Palace - Boss Kill': (None, None, False, None),
|
'Ice Palace - Boss Kill': (None, None, False, None),
|
||||||
'Misery Mire - Boss Kill': (None, None, False, None),
|
'Misery Mire - Boss Kill': (None, None, False, None),
|
||||||
'Turtle Rock - Boss Kill': (None, None, False, None),
|
'Turtle Rock - Boss Kill': (None, None, False, None),
|
||||||
|
'Locksmith': (None, None, False, None),
|
||||||
'Lost Old Man': (None, None, False, None),
|
'Lost Old Man': (None, None, False, None),
|
||||||
'Old Man Drop Off': (None, None, False, None),
|
'Old Man Drop Off': (None, None, False, None),
|
||||||
'Floodgate': (None, None, False, None),
|
'Floodgate': (None, None, False, None),
|
||||||
|
'Kiki': (None, None, False, None),
|
||||||
|
'Kiki Assistance': (None, None, False, None),
|
||||||
'Frog': (None, None, False, None),
|
'Frog': (None, None, False, None),
|
||||||
'Missing Smith': (None, None, False, None),
|
'Missing Smith': (None, None, False, None),
|
||||||
'Dark Blacksmith Ruins': (None, None, False, None),
|
'Dark Blacksmith Ruins': (None, None, False, None),
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'f66602d4d018afe44fe4b096146fbc71'
|
RANDOMIZERBASEHASH = 'f68e3c6169462af6e95c56b65b40701b'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -474,6 +474,13 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
rom.write_byte(location.player_address, location.item.player)
|
rom.write_byte(location.player_address, location.item.player)
|
||||||
else:
|
else:
|
||||||
itemid = 0x5A
|
itemid = 0x5A
|
||||||
|
|
||||||
|
if not location.locked and ((location.item.smallkey and world.keyshuffle[player] == 'none') or (
|
||||||
|
location.item.bigkey and world.bigkeyshuffle[player] == 'none') or (
|
||||||
|
location.item.map and world.mapshuffle[player] == 'none') or (
|
||||||
|
location.item.compass and world.compassshuffle[player] == 'none')):
|
||||||
|
itemid = handle_native_dungeon(location, itemid)
|
||||||
|
|
||||||
rom.write_byte(location.address, itemid)
|
rom.write_byte(location.address, itemid)
|
||||||
for dungeon in [d for d in world.dungeons if d.player == player]:
|
for dungeon in [d for d in world.dungeons if d.player == player]:
|
||||||
if dungeon.prize:
|
if dungeon.prize:
|
||||||
@@ -632,10 +639,6 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
write_int16(rom, 0x150002, owMode)
|
write_int16(rom, 0x150002, owMode)
|
||||||
write_int16(rom, 0x150004, owFlags)
|
write_int16(rom, 0x150004, owFlags)
|
||||||
|
|
||||||
from OverworldShuffle import can_reach_smith
|
|
||||||
if not can_reach_smith(world, player):
|
|
||||||
rom.write_byte(0x180043, 0x01) # patch for deleting smith on S+Q
|
|
||||||
|
|
||||||
# patch entrance/exits/holes
|
# patch entrance/exits/holes
|
||||||
for region in world.regions:
|
for region in world.regions:
|
||||||
for exit in region.exits:
|
for exit in region.exits:
|
||||||
@@ -721,7 +724,7 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
dr_flags |= DROptions.DarkWorld_Spawns # no longer experimental
|
dr_flags |= DROptions.DarkWorld_Spawns # no longer experimental
|
||||||
if world.logic[player] not in ['owglitches', 'hybridglitches', 'nologic']:
|
if world.logic[player] not in ['owglitches', 'hybridglitches', 'nologic']:
|
||||||
dr_flags |= DROptions.Fix_EG
|
dr_flags |= DROptions.Fix_EG
|
||||||
if world.door_type_mode[player] in ['big', 'all', 'chaos']:
|
if world.door_type_mode[player] in ['big', 'all', 'chaos'] and world.doorShuffle[player] != 'vanilla':
|
||||||
dr_flags |= DROptions.BigKeyDoor_Shuffle
|
dr_flags |= DROptions.BigKeyDoor_Shuffle
|
||||||
if world.dropshuffle[player] in ['underworld']:
|
if world.dropshuffle[player] in ['underworld']:
|
||||||
dr_flags |= DROptions.EnemyDropIndicator
|
dr_flags |= DROptions.EnemyDropIndicator
|
||||||
@@ -1320,6 +1323,17 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
rom.write_byte(0x18003C, compass_mode)
|
rom.write_byte(0x18003C, compass_mode)
|
||||||
|
|
||||||
def get_entrance_coords(ent):
|
def get_entrance_coords(ent):
|
||||||
|
if ent is None:
|
||||||
|
owid_map = [0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47]
|
||||||
|
x_map_position_generic = [0x03c0, 0x0740, 0xff00, 0x03c0, 0x01c0, 0x0bc0, 0x05c0, 0x09c0, 0x0ac0, 0x07c0, 0x0dc0]
|
||||||
|
y_map_position_generic = [0xff00, 0xff00, 0xff00, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0xff00, 0x0fc0, 0x0fc0]
|
||||||
|
world_indicator = 0x0000
|
||||||
|
idx = int((map_index-2)/2)
|
||||||
|
owid = owid_map[idx]
|
||||||
|
if owid != 0xFF:
|
||||||
|
if (owid < 0x40) == (world.is_tile_swapped(owid, player)):
|
||||||
|
world_indicator = 0x8000
|
||||||
|
return [world_indicator | x_map_position_generic[idx], y_map_position_generic[idx]]
|
||||||
if type(ent) is Location:
|
if type(ent) is Location:
|
||||||
from OverworldShuffle import OWTileRegions
|
from OverworldShuffle import OWTileRegions
|
||||||
if ent.name == 'Hobo':
|
if ent.name == 'Hobo':
|
||||||
@@ -1352,22 +1366,15 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
|
|
||||||
# write out dislocated coords
|
# write out dislocated coords
|
||||||
if map_index >= 0x02 and map_index < 0x18 and (world.overworld_map[player] != 'default' or world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby']):
|
if map_index >= 0x02 and map_index < 0x18 and (world.overworld_map[player] != 'default' or world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby']):
|
||||||
owid_map = [0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47]
|
coords = get_entrance_coords(None)
|
||||||
x_map_position_generic = [0x03c0, 0x0740, 0xff00, 0x03c0, 0x01c0, 0x0bc0, 0x05c0, 0x09c0, 0x0ac0, 0x07c0, 0x0dc0]
|
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+4, coords)
|
||||||
y_map_position_generic = [0xff00, 0xff00, 0xff00, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0xff00, 0x0fc0, 0x0fc0]
|
|
||||||
world_indicator = 0x0000
|
|
||||||
idx = int((map_index-2)/2)
|
|
||||||
owid = owid_map[idx]
|
|
||||||
if owid != 0xFF:
|
|
||||||
if (owid < 0x40) == (world.is_tile_swapped(owid, player)):
|
|
||||||
world_indicator = 0x8000
|
|
||||||
write_int16(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+4, world_indicator | x_map_position_generic[idx])
|
|
||||||
write_int16(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+6, y_map_position_generic[idx])
|
|
||||||
|
|
||||||
# write out icon coord data
|
# write out icon coord data
|
||||||
if world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby'] and dungeon_table[dungeon].prize:
|
if world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby'] and dungeon_table[dungeon].prize:
|
||||||
dungeon_obj = world.get_dungeon(dungeon, player)
|
dungeon_obj = world.get_dungeon(dungeon, player)
|
||||||
entrance = dungeon_obj.prize.get_map_location()
|
entrance = None
|
||||||
|
if dungeon_obj.prize:
|
||||||
|
entrance = dungeon_obj.prize.get_map_location()
|
||||||
coords = get_entrance_coords(entrance)
|
coords = get_entrance_coords(entrance)
|
||||||
# prize location
|
# prize location
|
||||||
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords)
|
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords)
|
||||||
@@ -1547,9 +1554,44 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
rom.write_byte(snes_to_pc(0x0DB810), 0x8A) # allows heart pieces to travel across water
|
rom.write_byte(snes_to_pc(0x0DB810), 0x8A) # allows heart pieces to travel across water
|
||||||
# rom.write_byte(snes_to_pc(0x0DB730), 0x08) # allows chickens to travel across water
|
# rom.write_byte(snes_to_pc(0x0DB730), 0x08) # allows chickens to travel across water
|
||||||
|
|
||||||
# allow smith into multi-entrance caves in appropriate shuffles
|
|
||||||
if world.shuffle[player] in ['restricted', 'simple', 'full', 'lite', 'lean', 'district', 'swapped', 'crossed', 'insanity']:
|
if world.shuffle_followers[player]:
|
||||||
rom.write_byte(0x18004C, 0x01)
|
from ItemList import follower_locations, follower_pickups
|
||||||
|
|
||||||
|
for loc_name, address in follower_locations.items():
|
||||||
|
loc = world.get_location(loc_name, player)
|
||||||
|
rom.write_byte(address, follower_pickups[loc.item.name])
|
||||||
|
|
||||||
|
rom.write_byte(0x18004C, 0x02) # enable follower shuffle
|
||||||
|
rom.write_byte(snes_to_pc(0x1BBD3A), 0x80) # allow all followers thru entrances
|
||||||
|
rom.write_bytes(snes_to_pc(0x1DFC70), [0xEA, 0xEA]) # allow followers at dig game
|
||||||
|
rom.write_byte(snes_to_pc(0x02823B), 0x80) # allow super bomb indoors
|
||||||
|
rom.write_byte(snes_to_pc(0x0283FB), 0x80) # allow maiden to go outside
|
||||||
|
rom.write_bytes(snes_to_pc(0x02D6F2), [0xEA, 0xEA]) # disable old man checkpoint
|
||||||
|
rom.write_byte(snes_to_pc(0x05DEFA), 0xAF) # no follower despawn at uncle
|
||||||
|
rom.write_byte(snes_to_pc(0x05DF3C), 0xAF) # no follower despawn at uncle
|
||||||
|
rom.write_bytes(snes_to_pc(0x079448), [0xEA, 0xEA]) # dont draw super bomb while falling into holes
|
||||||
|
rom.write_byte(snes_to_pc(0x079595), 0x80) # allow super bomb to follow into OW holes
|
||||||
|
rom.write_bytes(snes_to_pc(0x07A132), [0xEA, 0xEA]) # allow bomb use with super bomb
|
||||||
|
rom.write_byte(snes_to_pc(0x07A4B4), 0x80) # allow ether use with super bomb
|
||||||
|
rom.write_byte(snes_to_pc(0x07A589), 0x80) # allow bombos use with super bomb
|
||||||
|
rom.write_byte(snes_to_pc(0x07A66B), 0x80) # allow quake use with super bomb
|
||||||
|
rom.write_byte(snes_to_pc(0x07A919), 0x80) # disable kiki dialogue during mirror
|
||||||
|
rom.write_byte(snes_to_pc(0x07AAC5), 0xAF) # keep all followers after mirroring
|
||||||
|
rom.write_byte(snes_to_pc(0x08DED6), 0x80) # allow locksmith to follow with flute
|
||||||
|
rom.write_bytes(snes_to_pc(0x09A045), [0xEA, 0xEA]) # allow super bomb to follow into UW holes
|
||||||
|
rom.write_byte(snes_to_pc(0x09ACDF), 0x6B) # allow kiki/locksmith to follow after screen transition
|
||||||
|
|
||||||
|
if world.enemy_shuffle[player] != 'none':
|
||||||
|
# informs zelda and maiden to draw over gfx slots that are guaranteed unused
|
||||||
|
rom.write_bytes(0x1802C1, world.data_tables[player].room_headers[0x80].free_gfx[0:2])
|
||||||
|
rom.write_bytes(0x1802C7, world.data_tables[player].room_headers[0x45].free_gfx[0:2])
|
||||||
|
else:
|
||||||
|
from OverworldShuffle import can_reach_smith
|
||||||
|
if not can_reach_smith(world, player):
|
||||||
|
rom.write_byte(0x180043, 0x01) # patch for deleting smith on S+Q
|
||||||
|
if world.shuffle[player] in ['restricted', 'simple', 'full', 'lite', 'lean', 'district', 'swapped', 'crossed', 'insanity']:
|
||||||
|
rom.write_byte(0x18004C, 0x01) # allow smith into multi-entrance caves in appropriate shuffles
|
||||||
|
|
||||||
# set correct flag for hera basement item
|
# set correct flag for hera basement item
|
||||||
hera_basement = world.get_location('Tower of Hera - Basement Cage', player)
|
hera_basement = world.get_location('Tower of Hera - Basement Cage', player)
|
||||||
@@ -2340,9 +2382,20 @@ def write_strings(rom, world, player, team):
|
|||||||
silverarrow_hint = f'Did you find the silver arrows {hint_phrase}?' if progressive_silvers else no_silver_text
|
silverarrow_hint = f'Did you find the silver arrows {hint_phrase}?' if progressive_silvers else no_silver_text
|
||||||
tt['ganon_phase_3_no_silvers_alt'] = silverarrow_hint
|
tt['ganon_phase_3_no_silvers_alt'] = silverarrow_hint
|
||||||
|
|
||||||
crystal5 = world.find_items('Crystal 5', player)[0]
|
crystal5 = world.find_items('Crystal 5', player)
|
||||||
crystal6 = world.find_items('Crystal 6', player)[0]
|
crystal6 = world.find_items('Crystal 6', player)
|
||||||
greenpendant = world.find_items('Green Pendant', player)[0]
|
greenpendant = world.find_items('Green Pendant', player)
|
||||||
|
def missing_prize():
|
||||||
|
from BaseClasses import Dungeon
|
||||||
|
d = Dungeon('your pocket', [], None, [], [], player, 0)
|
||||||
|
i = ItemFactory('Nothing', player)
|
||||||
|
i.dungeon_object = d
|
||||||
|
r = Region('Nowhere', RegionType.Menu, 'in your pocket', player)
|
||||||
|
r.dungeon = d
|
||||||
|
loc = Location(player, 'Nowhere', parent=r, hint_text='in your pocket')
|
||||||
|
loc.item = i
|
||||||
|
return loc
|
||||||
|
(crystal5, crystal6, greenpendant) = tuple([x[0] if x else missing_prize() for x in [crystal5, crystal6, greenpendant]])
|
||||||
if world.prizeshuffle[player] in ['none', 'dungeon']:
|
if world.prizeshuffle[player] in ['none', 'dungeon']:
|
||||||
(crystal5, crystal6, greenpendant) = tuple([x.parent_region.dungeon.name for x in [crystal5, crystal6, greenpendant]])
|
(crystal5, crystal6, greenpendant) = tuple([x.parent_region.dungeon.name for x in [crystal5, crystal6, greenpendant]])
|
||||||
tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % (crystal5, crystal6)
|
tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % (crystal5, crystal6)
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player))
|
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player))
|
||||||
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player))
|
set_rule(world.get_location('Flute Spot', player), lambda state: state.has('Shovel', player))
|
||||||
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player))
|
||||||
|
set_rule(world.get_location('Kiki Assistance', player), lambda state: state.has('Pick Up Kiki', player)) # Can S&Q with chest
|
||||||
set_rule(world.get_location('Middle Aged Man', player), lambda state: state.has('Pick Up Purple Chest', player)) # Can S&Q with chest
|
set_rule(world.get_location('Middle Aged Man', player), lambda state: state.has('Pick Up Purple Chest', player)) # Can S&Q with chest
|
||||||
set_rule(world.get_location('Purple Chest', player), lambda state: state.has('Deliver Purple Chest', player)) # Can S&Q with chest
|
set_rule(world.get_location('Purple Chest', player), lambda state: state.has('Deliver Purple Chest', player)) # Can S&Q with chest
|
||||||
set_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player))
|
set_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player))
|
||||||
@@ -406,6 +407,7 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has_Boots(player))
|
set_rule(world.get_entrance('Bonk Fairy (Dark)', player), lambda state: state.has_Boots(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave', player), lambda state: state.can_lift_rocks(player))
|
||||||
|
|
||||||
|
set_rule(world.get_entrance('Palace of Darkness', player), lambda state: state.has('Dark Palace Opened', player))
|
||||||
set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player))
|
set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player))
|
||||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!)
|
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!)
|
||||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Turtle Opened', player))
|
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Turtle Opened', player))
|
||||||
@@ -1128,6 +1130,8 @@ def ow_bunny_rules(world, player):
|
|||||||
add_bunny_rule(world.get_location('Maze Race', player), player)
|
add_bunny_rule(world.get_location('Maze Race', player), player)
|
||||||
add_bunny_rule(world.get_location('Flute Spot', player), player)
|
add_bunny_rule(world.get_location('Flute Spot', player), player)
|
||||||
add_bunny_rule(world.get_location('Catfish', player), player)
|
add_bunny_rule(world.get_location('Catfish', player), player)
|
||||||
|
add_bunny_rule(world.get_location('Kiki', player), player)
|
||||||
|
add_bunny_rule(world.get_location('Locksmith', player), player)
|
||||||
|
|
||||||
# entrances
|
# entrances
|
||||||
add_bunny_rule(world.get_entrance('Lost Woods Hideout Drop', player), player)
|
add_bunny_rule(world.get_entrance('Lost Woods Hideout Drop', player), player)
|
||||||
@@ -1148,7 +1152,6 @@ def ow_bunny_rules(world, player):
|
|||||||
add_bunny_rule(world.get_entrance('Skull Woods Final Section', player), player) # bunny cannot use fire rod
|
add_bunny_rule(world.get_entrance('Skull Woods Final Section', player), player) # bunny cannot use fire rod
|
||||||
add_bunny_rule(world.get_entrance('Hookshot Cave', player), player)
|
add_bunny_rule(world.get_entrance('Hookshot Cave', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Thieves Town', player), player) # bunny cannot pull
|
add_bunny_rule(world.get_entrance('Thieves Town', player), player) # bunny cannot pull
|
||||||
add_bunny_rule(world.get_entrance('Palace of Darkness', player), player) # kiki needs pearl
|
|
||||||
add_bunny_rule(world.get_entrance('Hammer Peg Cave', player), player)
|
add_bunny_rule(world.get_entrance('Hammer Peg Cave', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Bonk Fairy (Dark)', player), player)
|
add_bunny_rule(world.get_entrance('Bonk Fairy (Dark)', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Misery Mire', player), player)
|
add_bunny_rule(world.get_entrance('Misery Mire', player), player)
|
||||||
@@ -1639,7 +1642,6 @@ def standard_rules(world, player):
|
|||||||
else:
|
else:
|
||||||
add_rule(loc, lambda state: standard_escape_rule(state))
|
add_rule(loc, lambda state: standard_escape_rule(state))
|
||||||
|
|
||||||
set_rule(world.get_location('Zelda Pickup', player), lambda state: state.has('Big Key (Escape)', player))
|
|
||||||
set_rule(world.get_entrance('Hyrule Castle Tapestry Backwards', player), lambda state: state.has('Zelda Herself', player))
|
set_rule(world.get_entrance('Hyrule Castle Tapestry Backwards', player), lambda state: state.has('Zelda Herself', player))
|
||||||
|
|
||||||
def check_rule_list(state, r_list):
|
def check_rule_list(state, r_list):
|
||||||
@@ -1702,7 +1704,7 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree',
|
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree',
|
||||||
'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Old Man',
|
'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Old Man',
|
||||||
'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins',
|
'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins',
|
||||||
'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Purple Chest', 'Blacksmith',
|
'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Kiki Assistance', 'Purple Chest', 'Blacksmith',
|
||||||
'Missing Smith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge',
|
'Missing Smith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge',
|
||||||
'Pyramid Crack', 'Big Bomb', 'Stumpy', 'Lost Old Man', 'Old Man Drop Off', 'Murahdahla',
|
'Pyramid Crack', 'Big Bomb', 'Stumpy', 'Lost Old Man', 'Old Man Drop Off', 'Murahdahla',
|
||||||
'Kakariko Shop - Left', 'Kakariko Shop - Middle', 'Kakariko Shop - Right',
|
'Kakariko Shop - Left', 'Kakariko Shop - Middle', 'Kakariko Shop - Right',
|
||||||
|
|||||||
Binary file not shown.
@@ -289,6 +289,22 @@ start_inventory:
|
|||||||
|
|
||||||
To start with multiple copies of progressive items, list them more than once.
|
To start with multiple copies of progressive items, list them more than once.
|
||||||
|
|
||||||
|
There are some additional non-standard keywords available that can be added as starting inventory:
|
||||||
|
|
||||||
|
* `RandomWeapon` - This grants the player with the same random weapon options that Uncle gives in standard starts, including ammo for that weapon.
|
||||||
|
* `Beat Agahnim 1` - This enables post-Agahnim world state by default and flags Agahnim 1 as defeated.
|
||||||
|
* `Return Old Man` - This enables the Mountain Cave starting location by default. This also removes one item location from the game.
|
||||||
|
* Followers - These are the companions that can follow Link until you complete their quest. These can only be added if you have `Follower Shuffle` enabled. If standard start is enabled, a follower will only start following after the escape has been completed, unless it is set to start with Zelda.
|
||||||
|
* `Zelda Herself`
|
||||||
|
* `Escort Old Man`
|
||||||
|
* `Maiden Rescued`
|
||||||
|
* `Get Frog`
|
||||||
|
* `Sign Vandalized` (Locksmith)
|
||||||
|
* `Pick Up Kiki`
|
||||||
|
* `Pick Up Purple Chest`
|
||||||
|
* `Pick Up Big Bomb`
|
||||||
|
* `RandomFollower` - This will pick any of the above as a random follower to start
|
||||||
|
|
||||||
##### Known Issue
|
##### Known Issue
|
||||||
|
|
||||||
This conflicts with the mystery yaml, if specified. These start inventory items will be added after those are added.
|
This conflicts with the mystery yaml, if specified. These start inventory items will be added after those are added.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ settings:
|
|||||||
pseudoboots: true
|
pseudoboots: true
|
||||||
pottery: keys
|
pottery: keys
|
||||||
shopsanity: true
|
shopsanity: true
|
||||||
|
shuffle_followers: true
|
||||||
shuffle: crossed
|
shuffle: crossed
|
||||||
shufflelinks: true
|
shufflelinks: true
|
||||||
ow_shuffle: parallel
|
ow_shuffle: parallel
|
||||||
|
|||||||
@@ -89,6 +89,10 @@
|
|||||||
"expert"
|
"expert"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"shuffle_followers": {
|
||||||
|
"action": "store_true",
|
||||||
|
"type": "bool"
|
||||||
|
},
|
||||||
"shopsanity": {
|
"shopsanity": {
|
||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
|
|||||||
@@ -264,6 +264,9 @@
|
|||||||
"ow_whirlpool": [
|
"ow_whirlpool": [
|
||||||
"Whirlpools will be shuffled and paired together."
|
"Whirlpools will be shuffled and paired together."
|
||||||
],
|
],
|
||||||
|
"shuffle_followers": [
|
||||||
|
"Followers like Purple Chest and Old Man are shuffled."
|
||||||
|
],
|
||||||
"bonk_drops": [
|
"bonk_drops": [
|
||||||
"Bonk drops from trees, rocks, and statues are shuffled with the item pool."
|
"Bonk drops from trees, rocks, and statues are shuffled with the item pool."
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -283,8 +283,7 @@
|
|||||||
"randomizer.generation.rom.dialog.allfiles": "All Files",
|
"randomizer.generation.rom.dialog.allfiles": "All Files",
|
||||||
|
|
||||||
"randomizer.item.hints": "Hints",
|
"randomizer.item.hints": "Hints",
|
||||||
"randomizer.item.race": "Generate \"Race\" ROM",
|
"randomizer.item.race": "Race",
|
||||||
"randomizer.item.retro": "Retro mode",
|
|
||||||
"randomizer.item.pseudoboots": "Pseudoboots",
|
"randomizer.item.pseudoboots": "Pseudoboots",
|
||||||
"randomizer.item.collection_rate": "Display Collection Rate",
|
"randomizer.item.collection_rate": "Display Collection Rate",
|
||||||
"randomizer.item.mirrorscroll": "Mirror Scroll",
|
"randomizer.item.mirrorscroll": "Mirror Scroll",
|
||||||
@@ -294,7 +293,7 @@
|
|||||||
"randomizer.item.worldstate.open": "Open",
|
"randomizer.item.worldstate.open": "Open",
|
||||||
"randomizer.item.worldstate.inverted": "Inverted",
|
"randomizer.item.worldstate.inverted": "Inverted",
|
||||||
"randomizer.item.worldstate.retro": "Retro",
|
"randomizer.item.worldstate.retro": "Retro",
|
||||||
"randomizer.item.retro": "Enable Retro",
|
"randomizer.item.retro": "Retro",
|
||||||
|
|
||||||
"randomizer.item.logiclevel": "Logic Level",
|
"randomizer.item.logiclevel": "Logic Level",
|
||||||
"randomizer.item.logiclevel.noglitches": "No Glitches",
|
"randomizer.item.logiclevel.noglitches": "No Glitches",
|
||||||
@@ -371,6 +370,8 @@
|
|||||||
"randomizer.item.timer.ohko": "OHKO",
|
"randomizer.item.timer.ohko": "OHKO",
|
||||||
"randomizer.item.timer.timed-countdown": "Timed Countdown",
|
"randomizer.item.timer.timed-countdown": "Timed Countdown",
|
||||||
|
|
||||||
|
"randomizer.item.followers": "Followers",
|
||||||
|
|
||||||
"randomizer.item.shopsanity": "Shopsanity",
|
"randomizer.item.shopsanity": "Shopsanity",
|
||||||
|
|
||||||
"randomizer.item.bonk_drops": "Bonk Drops",
|
"randomizer.item.bonk_drops": "Bonk Drops",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"collection_rate": {"type": "checkbox"},
|
"collection_rate": {"type": "checkbox"},
|
||||||
"race": { "type": "checkbox" }
|
"race": { "type": "checkbox" }
|
||||||
},
|
},
|
||||||
"leftItemFrame": {
|
"worldstateFrame": {
|
||||||
"worldstate": {
|
"worldstate": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"default": "open",
|
"default": "open",
|
||||||
@@ -14,8 +14,13 @@
|
|||||||
"standard",
|
"standard",
|
||||||
"open",
|
"open",
|
||||||
"inverted"
|
"inverted"
|
||||||
]
|
],
|
||||||
},
|
"config": {
|
||||||
|
"width": 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"leftItemFrame": {
|
||||||
"logiclevel": {
|
"logiclevel": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"options": [
|
"options": [
|
||||||
@@ -64,12 +69,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rightItemFrame": {
|
"rightItemFrame": {
|
||||||
"retro": {
|
|
||||||
"type": "button",
|
|
||||||
"config": {
|
|
||||||
"command": "retro"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sortingalgo": {
|
"sortingalgo": {
|
||||||
"type": "selectbox",
|
"type": "selectbox",
|
||||||
"default": "balanced",
|
"default": "balanced",
|
||||||
@@ -125,6 +124,10 @@
|
|||||||
"bonk_drops": {
|
"bonk_drops": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"default": false
|
"default": false
|
||||||
|
},
|
||||||
|
"followers": {
|
||||||
|
"type": "checkbox",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"leftPoolFrame": {
|
"leftPoolFrame": {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ class CustomSettings(object):
|
|||||||
args.ow_mixed[p] = get_setting(settings['ow_mixed'], args.ow_mixed[p])
|
args.ow_mixed[p] = get_setting(settings['ow_mixed'], args.ow_mixed[p])
|
||||||
args.ow_whirlpool[p] = get_setting(settings['ow_whirlpool'], args.ow_whirlpool[p])
|
args.ow_whirlpool[p] = get_setting(settings['ow_whirlpool'], args.ow_whirlpool[p])
|
||||||
args.ow_fluteshuffle[p] = get_setting(settings['ow_fluteshuffle'], args.ow_fluteshuffle[p])
|
args.ow_fluteshuffle[p] = get_setting(settings['ow_fluteshuffle'], args.ow_fluteshuffle[p])
|
||||||
|
args.shuffle_followers[p] = get_setting(settings['shuffle_followers'], args.shuffle_followers[p])
|
||||||
args.bonk_drops[p] = get_setting(settings['bonk_drops'], args.bonk_drops[p])
|
args.bonk_drops[p] = get_setting(settings['bonk_drops'], args.bonk_drops[p])
|
||||||
args.shuffle[p] = get_setting(settings['shuffle'], args.shuffle[p])
|
args.shuffle[p] = get_setting(settings['shuffle'], args.shuffle[p])
|
||||||
args.door_shuffle[p] = get_setting(settings['door_shuffle'], args.door_shuffle[p])
|
args.door_shuffle[p] = get_setting(settings['door_shuffle'], args.door_shuffle[p])
|
||||||
@@ -348,6 +349,7 @@ class CustomSettings(object):
|
|||||||
settings_dict[p]['ow_mixed'] = world.owMixed[p]
|
settings_dict[p]['ow_mixed'] = world.owMixed[p]
|
||||||
settings_dict[p]['ow_whirlpool'] = world.owWhirlpoolShuffle[p]
|
settings_dict[p]['ow_whirlpool'] = world.owWhirlpoolShuffle[p]
|
||||||
settings_dict[p]['ow_fluteshuffle'] = world.owFluteShuffle[p]
|
settings_dict[p]['ow_fluteshuffle'] = world.owFluteShuffle[p]
|
||||||
|
settings_dict[p]['shuffle_followers'] = world.shuffle_followers[p]
|
||||||
settings_dict[p]['bonk_drops'] = world.shuffle_bonk_drops[p]
|
settings_dict[p]['bonk_drops'] = world.shuffle_bonk_drops[p]
|
||||||
settings_dict[p]['shuffle'] = world.shuffle[p]
|
settings_dict[p]['shuffle'] = world.shuffle[p]
|
||||||
settings_dict[p]['door_shuffle'] = world.doorShuffle[p]
|
settings_dict[p]['door_shuffle'] = world.doorShuffle[p]
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ SETTINGSTOPROCESS = {
|
|||||||
"restrict_boss_items": "restrict_boss_items",
|
"restrict_boss_items": "restrict_boss_items",
|
||||||
"itemfunction": "item_functionality",
|
"itemfunction": "item_functionality",
|
||||||
"timer": "timer",
|
"timer": "timer",
|
||||||
|
"followers": "shuffle_followers",
|
||||||
|
|
||||||
"shopsanity": "shopsanity",
|
"shopsanity": "shopsanity",
|
||||||
"bonk_drops": "bonk_drops",
|
"bonk_drops": "bonk_drops",
|
||||||
|
|||||||
@@ -349,7 +349,8 @@ def determine_paths_for_dungeon(world, player, all_regions, name):
|
|||||||
paths.append(boss)
|
paths.append(boss)
|
||||||
if 'Thieves Boss' in all_r_names:
|
if 'Thieves Boss' in all_r_names:
|
||||||
paths.append('Thieves Boss')
|
paths.append('Thieves Boss')
|
||||||
if world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind':
|
if world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind' \
|
||||||
|
and not world.shuffle_followers[player]:
|
||||||
paths.append(('Thieves Blind\'s Cell', 'Thieves Boss'))
|
paths.append(('Thieves Blind\'s Cell', 'Thieves Boss'))
|
||||||
for drop_check in drop_path_checks:
|
for drop_check in drop_path_checks:
|
||||||
if drop_check in all_r_names:
|
if drop_check in all_r_names:
|
||||||
|
|||||||
@@ -315,6 +315,7 @@ class RoomHeader:
|
|||||||
self.byte_0 = byte_array[0] # bg2, collision, lights out
|
self.byte_0 = byte_array[0] # bg2, collision, lights out
|
||||||
self.sprite_sheet = byte_array[3] # sprite gfx #
|
self.sprite_sheet = byte_array[3] # sprite gfx #
|
||||||
self.effect = byte_array[4]
|
self.effect = byte_array[4]
|
||||||
|
self.free_gfx = []
|
||||||
|
|
||||||
def write_to_rom(self, rom, base_address):
|
def write_to_rom(self, rom, base_address):
|
||||||
room_offest = self.room_id*14
|
room_offest = self.room_id*14
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ def add_kholdstare_to_list(sprite_list, room_id):
|
|||||||
|
|
||||||
|
|
||||||
def add_vitreous_to_list(sprite_list, room_id):
|
def add_vitreous_to_list(sprite_list, room_id):
|
||||||
sprite_list.clear() # vitreous does not play nice which other sprites on the tile, just kill them
|
sprite_list[:] = [x for x in sprite_list if x.sub_type == SpriteType.Overlord] # vitreous does not play nice which other sprites on the tile, just kill them
|
||||||
sprite_list.append(create_sprite(room_id, EnemySprite.Vitreous, 0x00, 0, 0x07, 0x05))
|
sprite_list.insert(0, create_sprite(room_id, EnemySprite.Vitreous, 0x00, 0, 0x07, 0x05))
|
||||||
|
|
||||||
|
|
||||||
def add_trinexx_to_list(sprite_list, room_id):
|
def add_trinexx_to_list(sprite_list, room_id):
|
||||||
@@ -178,8 +178,9 @@ def boss_writes(world, player, rom):
|
|||||||
remove_shell_from_boss_room(data_tables, dungeon.name, level, 0xF95)
|
remove_shell_from_boss_room(data_tables, dungeon.name, level, 0xF95)
|
||||||
if boss.name != 'Blind' and dungeon.name == 'Thieves Town' and level is None:
|
if boss.name != 'Blind' and dungeon.name == 'Thieves Town' and level is None:
|
||||||
rom.write_byte(snes_to_pc(0x368101), 1) # set blind boss door flag
|
rom.write_byte(snes_to_pc(0x368101), 1) # set blind boss door flag
|
||||||
# maiden is deleted
|
if not world.shuffle_followers[player]:
|
||||||
del data_tables.uw_enemy_table.room_map[0x45][0]
|
# maiden is deleted
|
||||||
|
del data_tables.uw_enemy_table.room_map[0x45][0]
|
||||||
if not arrghus_can_swim and water_tiles_on:
|
if not arrghus_can_swim and water_tiles_on:
|
||||||
remove_water_tiles(data_tables)
|
remove_water_tiles(data_tables)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from Utils import snes_to_pc
|
|||||||
from source.dungeon.EnemyList import SpriteType, EnemySprite, sprite_translation
|
from source.dungeon.EnemyList import SpriteType, EnemySprite, sprite_translation
|
||||||
from source.dungeon.RoomList import Room010C
|
from source.dungeon.RoomList import Room010C
|
||||||
from source.enemizer.SpecialEnemyModes import set_mimics, write_mimic_changes
|
from source.enemizer.SpecialEnemyModes import set_mimics, write_mimic_changes
|
||||||
from source.enemizer.SpriteSheets import sub_group_choices
|
from source.enemizer.SpriteSheets import sub_group_choices, sheets_with_free_gfx
|
||||||
from source.enemizer.SpriteSheets import randomize_underworld_sprite_sheets, randomize_overworld_sprite_sheets
|
from source.enemizer.SpriteSheets import randomize_underworld_sprite_sheets, randomize_overworld_sprite_sheets
|
||||||
from source.enemizer.TilePattern import tile_patterns
|
from source.enemizer.TilePattern import tile_patterns
|
||||||
|
|
||||||
@@ -315,6 +315,21 @@ def randomize_underworld_rooms(data_tables, world, player, custom_uw):
|
|||||||
done = False
|
done = False
|
||||||
while not done:
|
while not done:
|
||||||
chosen_sheet = random.choice(candidate_sheets)
|
chosen_sheet = random.choice(candidate_sheets)
|
||||||
|
if world.shuffle_followers[player] and room_id in [0x80, 0x45]:
|
||||||
|
initial_chosen = chosen_sheet
|
||||||
|
while True:
|
||||||
|
candidate_sheets.remove(chosen_sheet)
|
||||||
|
free_gfx = next((sheets_with_free_gfx[s] for s in chosen_sheet.sub_groups if s in sheets_with_free_gfx), None)
|
||||||
|
if free_gfx:
|
||||||
|
data_tables.room_headers[room_id].free_gfx = free_gfx
|
||||||
|
break
|
||||||
|
elif len(candidate_sheets):
|
||||||
|
chosen_sheet = random.choice(candidate_sheets)
|
||||||
|
else:
|
||||||
|
chosen_sheet = initial_chosen
|
||||||
|
# TODO: This shouldn't happen for the current use case
|
||||||
|
# May need to limit the candidate_sprites below if needing gfx slots
|
||||||
|
break
|
||||||
data_tables.room_headers[room_id].sprite_sheet = chosen_sheet.id - 0x40
|
data_tables.room_headers[room_id].sprite_sheet = chosen_sheet.id - 0x40
|
||||||
candidate_sprites = get_possible_enemy_sprites(room_id, chosen_sheet, uw_candidates, data_tables)
|
candidate_sprites = get_possible_enemy_sprites(room_id, chosen_sheet, uw_candidates, data_tables)
|
||||||
randomized = True
|
randomized = True
|
||||||
|
|||||||
@@ -123,6 +123,9 @@ LenientTrapsForTesting = {0x16, 0x26, 0x3f, 0x40, 0x42, 0x46, 0x49, 0x4e, 0x57,
|
|||||||
0x65, 0x6a, 0x74, 0x76, 0x7d, 0x98,
|
0x65, 0x6a, 0x74, 0x76, 0x7d, 0x98,
|
||||||
0x9e, 0xaf, 0xba, 0xc6, 0xcb, 0xce, 0xd2, 0xd5,
|
0x9e, 0xaf, 0xba, 0xc6, 0xcb, 0xce, 0xd2, 0xd5,
|
||||||
0xd8, 0xdf, 0xe4, 0xe7, 0xee, 0xfd, 0x10c}
|
0xd8, 0xdf, 0xe4, 0xe7, 0xee, 0xfd, 0x10c}
|
||||||
|
PitRooms = {0x17, 0x1a, 0x2a, 0x31, 0x3c, 0x3d, 0x40, 0x44, 0x49, 0x4e, 0x56, 0x58, 0x5c, 0x67, 0x72,
|
||||||
|
0x7b, 0x7c, 0x7d, 0x7f, 0x82, 0x8b, 0x8d, 0x95, 0x96, 0x9b, 0x9c, 0x9d, 0x9e, 0xa0, 0xa5,
|
||||||
|
0xaf, 0xbc, 0xc0, 0xc5, 0xc6, 0xd1, 0xd5, 0xe7, 0xe8, 0xee, 0xf0, 0xf1, 0xfb, 0x123}
|
||||||
|
|
||||||
# wallmasters must not be on tiles near spiral staircases. Unknown if other stairs have issues
|
# wallmasters must not be on tiles near spiral staircases. Unknown if other stairs have issues
|
||||||
WallmasterInvalidRooms = {
|
WallmasterInvalidRooms = {
|
||||||
@@ -222,9 +225,12 @@ def init_sprite_requirements():
|
|||||||
SpriteRequirement(EnemySprite.Hoarder2).sub_group(3, 0x11).exclude({0x10c}),
|
SpriteRequirement(EnemySprite.Hoarder2).sub_group(3, 0x11).exclude({0x10c}),
|
||||||
SpriteRequirement(EnemySprite.TutorialGuard).affix(),
|
SpriteRequirement(EnemySprite.TutorialGuard).affix(),
|
||||||
SpriteRequirement(EnemySprite.LightningGate).affix().sub_group(3, 0x3f),
|
SpriteRequirement(EnemySprite.LightningGate).affix().sub_group(3, 0x3f),
|
||||||
SpriteRequirement(EnemySprite.BlueGuard).aquaphobia().sub_group(1, [0xd, 0x49]),
|
SpriteRequirement(EnemySprite.BlueGuard).aquaphobia().sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||||
SpriteRequirement(EnemySprite.GreenGuard).aquaphobia().sub_group(1, 0x49),
|
SpriteRequirement(EnemySprite.BlueGuard).aquaphobia().sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||||
SpriteRequirement(EnemySprite.RedSpearGuard).aquaphobia().sub_group(1, [0xd, 0x49]),
|
SpriteRequirement(EnemySprite.GreenGuard).aquaphobia().sub_group(1, 0x49).exclude(PitRooms),
|
||||||
|
SpriteRequirement(EnemySprite.GreenGuard).aquaphobia().sub_group(1, 0x49).sub_group(2, 0x13),
|
||||||
|
SpriteRequirement(EnemySprite.RedSpearGuard).aquaphobia().sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||||
|
SpriteRequirement(EnemySprite.RedSpearGuard).aquaphobia().sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||||
SpriteRequirement(EnemySprite.BluesainBolt).aquaphobia().sub_group(0, 0x46).sub_group(1, [0xd, 0x49]),
|
SpriteRequirement(EnemySprite.BluesainBolt).aquaphobia().sub_group(0, 0x46).sub_group(1, [0xd, 0x49]),
|
||||||
SpriteRequirement(EnemySprite.UsainBolt).aquaphobia().sub_group(1, [0xd, 0x49]),
|
SpriteRequirement(EnemySprite.UsainBolt).aquaphobia().sub_group(1, [0xd, 0x49]),
|
||||||
SpriteRequirement(EnemySprite.BlueArcher).sub_group(0, 0x48).sub_group(1, 0x49),
|
SpriteRequirement(EnemySprite.BlueArcher).sub_group(0, 0x48).sub_group(1, 0x49),
|
||||||
@@ -325,7 +331,7 @@ def init_sprite_requirements():
|
|||||||
SpriteRequirement(EnemySprite.BlueZirro).no_drop().sub_group(3, 0x1b).exclude(NoFlyingRooms),
|
SpriteRequirement(EnemySprite.BlueZirro).no_drop().sub_group(3, 0x1b).exclude(NoFlyingRooms),
|
||||||
SpriteRequirement(EnemySprite.Pikit).sub_group(3, 0x1b),
|
SpriteRequirement(EnemySprite.Pikit).sub_group(3, 0x1b),
|
||||||
SpriteRequirement(EnemySprite.CrystalMaiden).affix(),
|
SpriteRequirement(EnemySprite.CrystalMaiden).affix(),
|
||||||
SpriteRequirement(EnemySprite.OldMan).affix().sub_group(0, 0x46).sub_group(1, 0x49).sub_group(2, 0x1c),
|
SpriteRequirement(EnemySprite.OldMan).affix().sub_group(2, 0x1c),
|
||||||
SpriteRequirement(EnemySprite.PipeDown).affix(),
|
SpriteRequirement(EnemySprite.PipeDown).affix(),
|
||||||
SpriteRequirement(EnemySprite.PipeUp).affix(),
|
SpriteRequirement(EnemySprite.PipeUp).affix(),
|
||||||
SpriteRequirement(EnemySprite.PipeRight).affix(),
|
SpriteRequirement(EnemySprite.PipeRight).affix(),
|
||||||
@@ -470,6 +476,34 @@ required_boss_sheets = {EnemySprite.ArmosKnight: 9, EnemySprite.Lanmolas: 11, En
|
|||||||
EnemySprite.Blind: 32, EnemySprite.Kholdstare: 22, EnemySprite.Vitreous: 22,
|
EnemySprite.Blind: 32, EnemySprite.Kholdstare: 22, EnemySprite.Vitreous: 22,
|
||||||
EnemySprite.TrinexxRockHead: 23}
|
EnemySprite.TrinexxRockHead: 23}
|
||||||
|
|
||||||
|
sheets_with_free_gfx = {
|
||||||
|
# intended for identifying gfx slots on each sheet that are unused during general enemization
|
||||||
|
# (ie. Catfish gfx unused when used elsewhere other than the usual Catfish screen)
|
||||||
|
# TODO: Could also provide sprite ID/s of replaced gfx slots indicated to be used as verification
|
||||||
|
0x0E: [0x08, 0x0C],
|
||||||
|
0x10: [0xCC, 0xCE, 0xEC, 0xEE],
|
||||||
|
0x11: [0xEA, 0xEC, 0xEE],
|
||||||
|
0x12: [0x88, 0x8A, 0xAA, 0x8C, 0xAC, 0x8E, 0xAE],
|
||||||
|
0x13: [0xA2, 0xA4],
|
||||||
|
0x14: [0xC0, 0xC2, 0xC4, 0xE0, 0xE2],
|
||||||
|
0x15: [0xC8, 0xEE],
|
||||||
|
0x18: [0x86, 0x8C, 0x8E],
|
||||||
|
0x19: [0xCE, 0xEC, 0xEE],
|
||||||
|
0x1C: [0xA0, 0xAC, 0xAE],
|
||||||
|
0x22: [0x8C, 0x8E, 0xAA, 0xAC, 0xAE],
|
||||||
|
0x24: [0xAC, 0xAE],
|
||||||
|
0x26: [0xA6, 0xA8, 0xAA, 0xAC, 0xAE],
|
||||||
|
0x27: [0x84, 0xA4],
|
||||||
|
0x29: [0x82, 0x84],
|
||||||
|
0x2A: [0x80, 0x82, 0x84, 0x86, 0x88],
|
||||||
|
0x2E: [0x80, 0x82, 0x84, 0x86, 0x88],
|
||||||
|
0x2F: [0x2C, 0x0A, 0x0C, 0x0E, 0x2E, 0x24],
|
||||||
|
0x36: [0xE7, 0xE9, 0xEB, 0xED, 0xC7, 0xC9, 0xCB, 0xCD],
|
||||||
|
0x48: [0x2B, 0x2D],
|
||||||
|
0x52: [0xE8, 0xC6, 0xC8, 0xCE, 0xEE, 0xCA, 0xCC, 0xEA],
|
||||||
|
0x53: [0xE8, 0xEA, 0xCA, 0xCC, 0xC6, 0xC8]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SpriteSheet:
|
class SpriteSheet:
|
||||||
def __init__(self, id, default_sub_groups):
|
def __init__(self, id, default_sub_groups):
|
||||||
@@ -525,9 +559,9 @@ def init_sprite_sheets(requirements):
|
|||||||
|
|
||||||
def setup_required_dungeon_groups(sheets, data_tables):
|
def setup_required_dungeon_groups(sheets, data_tables):
|
||||||
|
|
||||||
sheets[did(1)].add_sprite_to_sheet([70, 73, 28, 82], {0xe4, 0xf0}) # old man
|
sheets[did(1)].add_sprite_to_sheet([None, None, 28, None], {0xe4, 0xf0}) # old man
|
||||||
# various npcs
|
# various npcs
|
||||||
sheets[did(5)].add_sprite_to_sheet([75, 77, 74, 90], {0xf3, 0x109, 0x10e, 0x10f, 0x110, 0x111, 0x112,
|
sheets[did(5)].add_sprite_to_sheet([75, 77, 74, 90], {0xf3, 0xff, 0x109, 0x10e, 0x10f, 0x110, 0x111, 0x112,
|
||||||
0x11a, 0x11c, 0x11f, 0x122})
|
0x11a, 0x11c, 0x11f, 0x122})
|
||||||
sheets[did(7)].add_sprite_to_sheet([75, 77, 57, 54], {0x8, 0x2c, 0x114, 0x115, 0x116}) # big fairies
|
sheets[did(7)].add_sprite_to_sheet([75, 77, 57, 54], {0x8, 0x2c, 0x114, 0x115, 0x116}) # big fairies
|
||||||
sheets[did(13)].add_sprite_to_sheet([81, None, None, None], {0x55, 0x102, 0x104}) # uncle, sick kid
|
sheets[did(13)].add_sprite_to_sheet([81, None, None, None], {0x55, 0x102, 0x104}) # uncle, sick kid
|
||||||
@@ -542,15 +576,13 @@ def setup_required_dungeon_groups(sheets, data_tables):
|
|||||||
sheets[did(3)].add_sprite_to_sheet([93, None, None, None], {0x51}) # mantle
|
sheets[did(3)].add_sprite_to_sheet([93, None, None, None], {0x51}) # mantle
|
||||||
sheets[did(42)].add_sprite_to_sheet([21, None, None, None], {0x11e}) # hype cave
|
sheets[did(42)].add_sprite_to_sheet([21, None, None, None], {0x11e}) # hype cave
|
||||||
sheets[did(10)].add_sprite_to_sheet([47, None, 46, None], {0x5c, 0x75, 0xb9, 0xd9}) # cannonballs
|
sheets[did(10)].add_sprite_to_sheet([47, None, 46, None], {0x5c, 0x75, 0xb9, 0xd9}) # cannonballs
|
||||||
sheets[did(37)].add_sprite_to_sheet([31, None, 39, 82], {0x24, 0xb4, 0xb5, 0xc6, 0xc7, 0xd6}) # somaria platforms
|
sheets[did(37)].add_sprite_to_sheet([None, None, 39, 82], {0x24, 0xb4, 0xb5, 0xc6, 0xc7, 0xd6}) # somaria platforms
|
||||||
# not sure 31 is needed above
|
|
||||||
|
|
||||||
free_sheet_reqs = [
|
free_sheet_reqs = [
|
||||||
([75, None, None, None], [0xff, 0x11f]), # shopkeepers
|
|
||||||
([None, 77, None, 21], [0x121]), # smithy
|
([None, 77, None, 21], [0x121]), # smithy
|
||||||
([None, None, None, 80], [0x108]), # chicken house
|
([None, None, None, 80], [0x108]), # chicken house
|
||||||
([14, 30, None, None], [0x123]), # mini moldorm (shutter door)
|
([14, 30, None, None], [0x123]), # mini moldorm (shutter door)
|
||||||
([None, None, 34, None], [0x36, 0x46, 0x66, 0x76]), # pirogusu spawners
|
([None, None, 34, None], [0x36, 0x46, 0x66]), # pirogusu spawners
|
||||||
([None, 32, None, None], [0x9f]), # babasu spawners
|
([None, 32, None, None], [0x9f]), # babasu spawners
|
||||||
([31, None, None, None], [0x7f]), # force baris
|
([31, None, None, None], [0x7f]), # force baris
|
||||||
([None, None, 35, None], [0x39, 0x49]), # wallmasters
|
([None, None, 35, None], [0x39, 0x49]), # wallmasters
|
||||||
@@ -570,7 +602,7 @@ def setup_required_dungeon_groups(sheets, data_tables):
|
|||||||
([None, None, (28, 36), 82], [0x2, 0x64]), # pull switches (snakes)
|
([None, None, (28, 36), 82], [0x2, 0x64]), # pull switches (snakes)
|
||||||
([None, None, None, 82], [0x1a, 0x3d, 0x44, 0x5e, 0x7c, 0x95, 0xc3]), # collapsing bridges
|
([None, None, None, 82], [0x1a, 0x3d, 0x44, 0x5e, 0x7c, 0x95, 0xc3]), # collapsing bridges
|
||||||
([None, None, None, 83], [0x3f, 0xce]), # pull tongue
|
([None, None, None, 83], [0x3f, 0xce]), # pull tongue
|
||||||
([None, None, None, 83], [0x35, 0x37, 0x76]), # swamp drains
|
([None, None, None, 83], [0x35, 0x37]), # swamp drains
|
||||||
([None, None, 34, None], [0x28]), # tektike forced? - spawn chest
|
([None, None, 34, None], [0x28]), # tektike forced? - spawn chest
|
||||||
([None, None, 37, None], [0x97]), # wizzrobe spawner - in middle of room...
|
([None, None, 37, None], [0x97]), # wizzrobe spawner - in middle of room...
|
||||||
|
|
||||||
@@ -701,17 +733,18 @@ def setup_required_overworld_groups(sheets):
|
|||||||
sheets[6].add_sprite_to_sheet([0x4F, 0x49, 0x4A, 0x50], {0x18, 0x22, 0x28, 0xA8, 0xB2, 0xB8})
|
sheets[6].add_sprite_to_sheet([0x4F, 0x49, 0x4A, 0x50], {0x18, 0x22, 0x28, 0xA8, 0xB2, 0xB8})
|
||||||
sheets[8].add_sprite_to_sheet([None, None, 18, None], {0x30, 0xC0}) # Desert (pre/post-Aga)
|
sheets[8].add_sprite_to_sheet([None, None, 18, None], {0x30, 0xC0}) # Desert (pre/post-Aga)
|
||||||
sheets[10].add_sprite_to_sheet([None, None, None, 17], {0x3A, 0xCA}) # M-rock (pre/post-Aga)
|
sheets[10].add_sprite_to_sheet([None, None, None, 17], {0x3A, 0xCA}) # M-rock (pre/post-Aga)
|
||||||
sheets[22].add_sprite_to_sheet([None, None, 24, None], {0x4F, 0xDF}) # Catfish (pre/post-Aga)
|
sheets[22].add_sprite_to_sheet([None, None, 24, None], {0x4F}) # Catfish
|
||||||
sheets[21].add_sprite_to_sheet([21, None, None, 21], {0x62, 0xF2}) # Smith DW (pre/post-Aga)
|
sheets[21].add_sprite_to_sheet([None, None, None, 21], {0x62, 0x69}) # Smith DW/VoO South
|
||||||
sheets[27].add_sprite_to_sheet([None, 42, None, None], {0x68, 0xF8}) # Dig Game (pre/post-Aga)
|
sheets[27].add_sprite_to_sheet([None, 42, None, None], {0x68}) # Dig Game
|
||||||
sheets[13].add_sprite_to_sheet([None, None, 76, None], {0x16, 0xA6}) # Witch hut (pre/post-Aga)
|
sheets[13].add_sprite_to_sheet([None, None, 76, None], {0x16, 0xA6}) # Witch hut (pre/post-Aga)
|
||||||
sheets[29].add_sprite_to_sheet([None, 77, None, 21], {0x69, 0xF9}) # VoO South (pre/post-Aga)
|
#sheets[29].add_sprite_to_sheet([None, 77, None, 21], {0x69}) # VoO South
|
||||||
sheets[15].add_sprite_to_sheet([None, None, 78, None], {0x2A, 0xBA}) # Haunted Grove (pre/post-Aga)
|
sheets[15].add_sprite_to_sheet([None, None, 78, None], {0x2A, 0xBA}) # Haunted Grove (pre/post-Aga)
|
||||||
sheets[17].add_sprite_to_sheet([None, None, None, 76], {0x6A, 0xFA}) # Stumpy (pre/post-Aga)
|
sheets[17].add_sprite_to_sheet([None, None, None, 76], {0x6A}) # Stumpy
|
||||||
sheets[12].add_sprite_to_sheet([None, None, 55, 54], {0x80, 0x110}) # Specials (pre/post-Aga)
|
sheets[12].add_sprite_to_sheet([None, None, 55, 54], {0x80}) # Specials
|
||||||
sheets[14].add_sprite_to_sheet([None, None, 12, 68], {0x81, 0x111}) # Zora's Domain (pre/post-Aga)
|
sheets[14].add_sprite_to_sheet([None, None, 12, 68], {0x81}) # Zora's Domain
|
||||||
sheets[26].add_sprite_to_sheet([15, None, None, None], {0x92}) # Lumberjacks post-Aga
|
sheets[26].add_sprite_to_sheet([15, None, None, None], {0x92}) # Lumberjacks post-Aga
|
||||||
sheets[23].add_sprite_to_sheet([None, None, None, 25], {0x5E, 0xEE}) # PoD pre/post-Aga
|
sheets[23].add_sprite_to_sheet([None, None, None, 25], {0x5E}) # PoD
|
||||||
|
sheets[19].add_sprite_to_sheet([None, 26, None, None], {0x5B}) # Pyramid post-Aga2 bat crash
|
||||||
|
|
||||||
free_sheet_reqs = [
|
free_sheet_reqs = [
|
||||||
[None, None, None, 0x14], # bully+pink ball needs this
|
[None, None, None, 0x14], # bully+pink ball needs this
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ UwGeneralDeny:
|
|||||||
- [ 0x001a, 7, [ "RollerHorizontalRight", "RollerHorizontalLeft" ]] # Too long
|
- [ 0x001a, 7, [ "RollerHorizontalRight", "RollerHorizontalLeft" ]] # Too long
|
||||||
- [ 0x001b, 3, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Palace of Darkness - Mimics 2 - Red Eyegore"
|
- [ 0x001b, 3, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Palace of Darkness - Mimics 2 - Red Eyegore"
|
||||||
- [ 0x001b, 4, [ "RollerVerticalUp" ] ] #"Palace of Darkness - Mimics 2 - Green Eyegore L"
|
- [ 0x001b, 4, [ "RollerVerticalUp" ] ] #"Palace of Darkness - Mimics 2 - Green Eyegore L"
|
||||||
- [ 0x001e, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Red Bari 3"
|
- [ 0x001e, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper", "AntiFairyCircle" ] ] #"Ice Palace - Blob Ambush - Red Bari 3"
|
||||||
- [ 0x001e, 4, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Red Bari 4"
|
- [ 0x001e, 4, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper", "AntiFairyCircle" ] ] #"Ice Palace - Blob Ambush - Red Bari 4"
|
||||||
- [ 0x001e, 5, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 1"
|
- [ 0x001e, 5, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 1"
|
||||||
- [ 0x001e, 6, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 2"
|
- [ 0x001e, 6, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 2"
|
||||||
- [0x001f, 0, ["RollerHorizontalRight", "RollerHorizontalLeft"]] #"Ice Palace - Big Key View - Pengator 1"
|
- [0x001f, 0, ["RollerHorizontalRight", "RollerHorizontalLeft"]] #"Ice Palace - Big Key View - Pengator 1"
|
||||||
@@ -82,10 +82,10 @@ UwGeneralDeny:
|
|||||||
- [ 0x0038, 4, [ "RollerHorizontalRight" ] ] #"Swamp Palace - Long Hall - Kyameron 2"
|
- [ 0x0038, 4, [ "RollerHorizontalRight" ] ] #"Swamp Palace - Long Hall - Kyameron 2"
|
||||||
- [ 0x0039, 3, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Skull Woods - Play Pen - Mini Helmasaur"
|
- [ 0x0039, 3, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Skull Woods - Play Pen - Mini Helmasaur"
|
||||||
- [ 0x0039, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 1"
|
- [ 0x0039, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 1"
|
||||||
- [0x0039, 5, ["RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Bumper"]] #"Skull Woods - Play Pen - Hardhat Beetle"
|
- [0x0039, 5, ["RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Bumper", "AntiFairyCircle"]] #"Skull Woods - Play Pen - Hardhat Beetle"
|
||||||
- [ 0x0039, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 2"
|
- [ 0x0039, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 2"
|
||||||
- [0x003a, 1, ["RollerVerticalUp"]]
|
- [0x003a, 1, ["RollerVerticalUp"]]
|
||||||
- [ 0x003b, 1, [ "Bumper" ]]
|
- [ 0x003b, 1, [ "Bumper", "AntiFairyCircle" ]]
|
||||||
- [ 0x003b, 4, ["RollerVerticalUp", "RollerVerticalDown"]]
|
- [ 0x003b, 4, ["RollerVerticalUp", "RollerVerticalDown"]]
|
||||||
- [ 0x003c, 0, ["BigSpike"]]
|
- [ 0x003c, 0, ["BigSpike"]]
|
||||||
- [ 0x003c, 1, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hookshot Cave - Blue Bari 1"
|
- [ 0x003c, 1, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hookshot Cave - Blue Bari 1"
|
||||||
@@ -129,8 +129,8 @@ UwGeneralDeny:
|
|||||||
- [0x004b, 0, ["Beamos", "AntiFairyCircle", "Bumper", "BigSpike"]] #"Palace of Darkness - Mimics 1 - Red Eyegore"
|
- [0x004b, 0, ["Beamos", "AntiFairyCircle", "Bumper", "BigSpike"]] #"Palace of Darkness - Mimics 1 - Red Eyegore"
|
||||||
- [ 0x004b, 1, [ "RollerHorizontalRight" ] ] #"Palace of Darkness - Warp Hint - Antifairy 1"
|
- [ 0x004b, 1, [ "RollerHorizontalRight" ] ] #"Palace of Darkness - Warp Hint - Antifairy 1"
|
||||||
- [ 0x004b, 5, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 1"
|
- [ 0x004b, 5, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 1"
|
||||||
- [ 0x004b, 6, [ "AntiFairyCircle", "BigSpike" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 2"
|
- [ 0x004b, 6, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 2"
|
||||||
- [ 0x004b, 7, [ "AntiFairyCircle", "BigSpike" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 3"
|
- [ 0x004b, 7, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 3"
|
||||||
- [ 0x004e, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 1"
|
- [ 0x004e, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 1"
|
||||||
- [ 0x004e, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 2"
|
- [ 0x004e, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 2"
|
||||||
- [ 0x004e, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 3"
|
- [ 0x004e, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 3"
|
||||||
@@ -138,9 +138,9 @@ UwGeneralDeny:
|
|||||||
- [ 0x0050, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 1"
|
- [ 0x0050, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 1"
|
||||||
- [ 0x0050, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 2"
|
- [ 0x0050, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 2"
|
||||||
- [0x0051, 2, ["Zoro"]] # Zoro clips off and doesn't return
|
- [0x0051, 2, ["Zoro"]] # Zoro clips off and doesn't return
|
||||||
- [ 0x0052, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Guard"
|
- [ 0x0052, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper", "Zoro"]] #"Hyrule Castle - North East Passage - Green Guard"
|
||||||
- [ 0x0052, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Knife Guard 1"
|
- [ 0x0052, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper", "Zoro"]] #"Hyrule Castle - North East Passage - Green Knife Guard 1"
|
||||||
- [ 0x0052, 2, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Knife Guard 2"
|
- [ 0x0052, 2, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper", "Zoro"]] #"Hyrule Castle - North East Passage - Green Knife Guard 2"
|
||||||
- [ 0x0053, 1, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - Bridge - Beamos 1"
|
- [ 0x0053, 1, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - Bridge - Beamos 1"
|
||||||
- [ 0x0053, 5, [ "RollerVerticalDown" ] ] #"Desert Palace - Popo Genocide - Popo TL"
|
- [ 0x0053, 5, [ "RollerVerticalDown" ] ] #"Desert Palace - Popo Genocide - Popo TL"
|
||||||
- [ 0x0053, 7, ["Beamos", "AntiFairyCircle", "Bumper", "RollerVerticalUp", "RollerVerticalDown"]] #"Desert Palace - Bridge - Popo 5"
|
- [ 0x0053, 7, ["Beamos", "AntiFairyCircle", "Bumper", "RollerVerticalUp", "RollerVerticalDown"]] #"Desert Palace - Bridge - Popo 5"
|
||||||
@@ -166,7 +166,7 @@ UwGeneralDeny:
|
|||||||
- [ 0x0058, 4, ["Statue"]]
|
- [ 0x0058, 4, ["Statue"]]
|
||||||
- [ 0x0058, 6, ["Statue"]]
|
- [ 0x0058, 6, ["Statue"]]
|
||||||
- [ 0x0058, 7, [ "RollerHorizontalLeft", "Statue" ] ] #"Skull Woods - Lever Room - Hardhat Beetle 2"
|
- [ 0x0058, 7, [ "RollerHorizontalLeft", "Statue" ] ] #"Skull Woods - Lever Room - Hardhat Beetle 2"
|
||||||
- [ 0x0058, 8, ["Statue"]]
|
- [ 0x0058, 8, ["Statue", "AntiFairyCircle", "Bumper"]]
|
||||||
- [ 0x0059, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 1"
|
- [ 0x0059, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 1"
|
||||||
- [ 0x0059, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 2"
|
- [ 0x0059, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 2"
|
||||||
- [0x0059, 5, ["RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
|
- [0x0059, 5, ["RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
|
||||||
@@ -177,7 +177,7 @@ UwGeneralDeny:
|
|||||||
- [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2"
|
- [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2"
|
||||||
- [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper", "Beamos", "SpikeBlock" ] ] #"Hyrule Castle - West - Blue Guard"
|
- [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper", "Beamos", "SpikeBlock" ] ] #"Hyrule Castle - West - Blue Guard"
|
||||||
- [ 0x0062, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hyrule Castle - East - Blue Guard"
|
- [ 0x0062, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hyrule Castle - East - Blue Guard"
|
||||||
- [ 0x0064, 2, [ "Bumper" , "Beamos" ] ] #"Thieves' Town - Attic Hall Left - Keese 2"
|
- [ 0x0064, 2, [ "Bumper", "AntiFairyCircle", "Beamos" ] ] #"Thieves' Town - Attic Hall Left - Keese 2"
|
||||||
- [ 0x0064, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x0064, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x0064, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Hall Left - Rat 1"
|
- [ 0x0064, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Hall Left - Rat 1"
|
||||||
- [ 0x0065, 0, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 1"
|
- [ 0x0065, 0, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 1"
|
||||||
@@ -186,9 +186,9 @@ UwGeneralDeny:
|
|||||||
- [ 0x0066, 0, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Waterfall Room - Hover 1"
|
- [ 0x0066, 0, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Waterfall Room - Hover 1"
|
||||||
- [ 0x0066, 2, [ "AntiFairyCircle", "Bumper"]]
|
- [ 0x0066, 2, [ "AntiFairyCircle", "Bumper"]]
|
||||||
- [ 0x0067, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper"]] #"Skull Woods - Firebar Pits - Blue Bari 1"
|
- [ 0x0067, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper"]] #"Skull Woods - Firebar Pits - Blue Bari 1"
|
||||||
- [ 0x0067, 2, ["Bumper"]] #"Skull Woods - Firebar Pits - Blue Bari 2"
|
- [ 0x0067, 2, ["Bumper", "AntiFairyCircle"]] #"Skull Woods - Firebar Pits - Blue Bari 2"
|
||||||
- [ 0x0067, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 1"
|
- [ 0x0067, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 1"
|
||||||
- [ 0x0067, 4, [ "AntiFairyCircle", "Bumper" ]]
|
- [0x0067, 4, [ "AntiFairyCircle", "Bumper", "RollerVerticalUp"]]
|
||||||
- [ 0x0067, 5, ["RollerVerticalDown", "Beamos"]] #"Skull Woods - Firebar Pits - Hardhat Beetle 3"
|
- [ 0x0067, 5, ["RollerVerticalDown", "Beamos"]] #"Skull Woods - Firebar Pits - Hardhat Beetle 3"
|
||||||
- [ 0x0067, 6, [ "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 4"
|
- [ 0x0067, 6, [ "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 4"
|
||||||
- [ 0x0067, 7, [ "Beamos", "AntiFairyCircle", "Bumper", "BunnyBeam" ] ] #"Skull Woods - Firebar Pits - Fire Bar (Clockwise)"
|
- [ 0x0067, 7, [ "Beamos", "AntiFairyCircle", "Bumper", "BunnyBeam" ] ] #"Skull Woods - Firebar Pits - Fire Bar (Clockwise)"
|
||||||
@@ -209,6 +209,7 @@ UwGeneralDeny:
|
|||||||
- [ 0x0076, 3, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Hover 2"
|
- [ 0x0076, 3, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Hover 2"
|
||||||
- [ 0x0076, 4, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Zol"
|
- [ 0x0076, 4, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Zol"
|
||||||
- [ 0x0076, 6, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Toilet Left - Blue Bari"
|
- [ 0x0076, 6, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Toilet Left - Blue Bari"
|
||||||
|
- [0x0077, 0, [ "AntiFairyCircle", "Bumper"]]
|
||||||
- [ 0x007b, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 1"
|
- [ 0x007b, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 1"
|
||||||
- [ 0x007b, 1, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 2"
|
- [ 0x007b, 1, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 2"
|
||||||
- [ 0x007b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - DMs Room - Statue"
|
- [ 0x007b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - DMs Room - Statue"
|
||||||
@@ -239,6 +240,7 @@ UwGeneralDeny:
|
|||||||
- [ 0x0084, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Main Room - Left - Leever 2"
|
- [ 0x0084, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Main Room - Left - Leever 2"
|
||||||
- [ 0x0085, 2, [ "RollerHorizontalRight" ] ] #"Desert Palace - Compass Room - Popo TL"
|
- [ 0x0085, 2, [ "RollerHorizontalRight" ] ] #"Desert Palace - Compass Room - Popo TL"
|
||||||
- [ 0x0085, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Right Hallway - Leever 2"
|
- [ 0x0085, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Right Hallway - Leever 2"
|
||||||
|
- [0x0087, 0, ["RollerHorizontalLeft"]] # First moldorm in Tri-dorm room
|
||||||
- [ 0x008b, 3, ["RollerHorizontalRight"]]
|
- [ 0x008b, 3, ["RollerHorizontalRight"]]
|
||||||
- [ 0x008b, 4, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "BigSpike"]] #"Ganon's Tower - Map Room - Spike Trap"
|
- [ 0x008b, 4, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "BigSpike"]] #"Ganon's Tower - Map Room - Spike Trap"
|
||||||
- [ 0x008b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Map Room - Fire Bar (Clockwise)"
|
- [ 0x008b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Map Room - Fire Bar (Clockwise)"
|
||||||
@@ -254,10 +256,10 @@ UwGeneralDeny:
|
|||||||
- [ 0x0092, 8, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Misery Mire - Dark Weave - Spike Trap"
|
- [ 0x0092, 8, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Misery Mire - Dark Weave - Spike Trap"
|
||||||
- [ 0x0092, 9, [ "RollerHorizontalRight" ] ] #"Misery Mire - Dark Weave - Antifairy 3"
|
- [ 0x0092, 9, [ "RollerHorizontalRight" ] ] #"Misery Mire - Dark Weave - Antifairy 3"
|
||||||
- [ 0x0092, 10, [ "RollerHorizontalLeft" ] ] #"Misery Mire - Dark Weave - Stalfos"
|
- [ 0x0092, 10, [ "RollerHorizontalLeft" ] ] #"Misery Mire - Dark Weave - Stalfos"
|
||||||
- [ 0x0095, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 1"
|
- [ 0x0095, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "Bumper", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 1"
|
||||||
- [ 0x0095, 1, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 2"
|
- [ 0x0095, 1, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 2"
|
||||||
- [ 0x0095, 2, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 3"
|
- [ 0x0095, 2, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 3"
|
||||||
- [ 0x0095, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 4"
|
- [ 0x0095, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "Bumper", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 4"
|
||||||
- [ 0x0096, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 1 - Fire Bar (Clockwise)"
|
- [ 0x0096, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 1 - Fire Bar (Clockwise)"
|
||||||
- [ 0x0098, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 1"
|
- [ 0x0098, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 1"
|
||||||
- [ 0x0098, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 2"
|
- [ 0x0098, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 2"
|
||||||
@@ -278,7 +280,7 @@ UwGeneralDeny:
|
|||||||
- [ 0x009c, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 4"
|
- [ 0x009c, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 4"
|
||||||
- [ 0x009c, 5, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 5"
|
- [ 0x009c, 5, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 5"
|
||||||
- [0x009c, 6, ["AntiFairyCircle", "Bumper"]]
|
- [0x009c, 6, ["AntiFairyCircle", "Bumper"]]
|
||||||
- [0x009d, 2, ["AntiFairyCircle"]]
|
- [0x009d, 2, ["AntiFairyCircle", "Bumper"]]
|
||||||
- [ 0x009d, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Compass Room - Gibdo 2"
|
- [ 0x009d, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Compass Room - Gibdo 2"
|
||||||
- [ 0x009d, 6, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Ganon's Tower - Compass Room - Blue Bari 1"
|
- [ 0x009d, 6, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Ganon's Tower - Compass Room - Blue Bari 1"
|
||||||
- [ 0x009d, 7, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Compass Room - Blue Bari 2"
|
- [ 0x009d, 7, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Compass Room - Blue Bari 2"
|
||||||
@@ -305,7 +307,7 @@ UwGeneralDeny:
|
|||||||
- [0x00b0, 8, [ "StalfosKnight", "Blob", "Stal", "Wizzrobe"]] # blocked, but Geldmen are probably okay
|
- [0x00b0, 8, [ "StalfosKnight", "Blob", "Stal", "Wizzrobe"]] # blocked, but Geldmen are probably okay
|
||||||
- [ 0x00b1, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 1"
|
- [ 0x00b1, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 1"
|
||||||
- [ 0x00b1, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 2"
|
- [ 0x00b1, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 2"
|
||||||
- [ 0x00b1, 4, ["Bumper", "BigSpike", "AntiFairyCircle" ]]
|
- [0x00b1, 4, ["Bumper", "BigSpike", "AntiFairyCircle", "Statue"]] # Wizzrobe near door
|
||||||
- [ 0x00b2, 1, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x00b2, 1, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x00b2, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x00b2, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x00b2, 6, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Misery Mire - Sluggula Cross - Sluggula TR"
|
- [ 0x00b2, 6, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Misery Mire - Sluggula Cross - Sluggula TR"
|
||||||
@@ -332,12 +334,12 @@ UwGeneralDeny:
|
|||||||
- [ 0x00bc, 7, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Toilet - Stalfos 3"
|
- [ 0x00bc, 7, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Toilet - Stalfos 3"
|
||||||
- [ 0x00bc, 8, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Thieves' Town - Toilet - Stalfos 4"
|
- [ 0x00bc, 8, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Thieves' Town - Toilet - Stalfos 4"
|
||||||
- [ 0x00bf, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on collision
|
- [ 0x00bf, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on collision
|
||||||
- [ 0x00c1, 3, [ "RollerVerticalUp", "RollerHorizontalLeft", "Bumper" ] ] #"Misery Mire - 4 Rails - Stalfos 1"
|
- [ 0x00c1, 3, [ "RollerVerticalUp", "RollerHorizontalLeft", "Bumper", "AntiFairyCircle" ] ] #"Misery Mire - 4 Rails - Stalfos 1"
|
||||||
- [ 0x00c2, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Misery Mire - Main Lobby - blue - Fire Snake 1"
|
- [ 0x00c2, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Misery Mire - Main Lobby - blue - Fire Snake 1"
|
||||||
- [ 0x00c2, 5, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x00c2, 5, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x00c5, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Catwalk - Mini Helmasaur"
|
- [ 0x00c5, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Catwalk - Mini Helmasaur"
|
||||||
- [ 0x00c5, 7, [ "Statue" ] ] #"Turtle Rock - Catwalk - Laser Eye (Left) 4"
|
- [ 0x00c5, 7, [ "Statue" ] ] #"Turtle Rock - Catwalk - Laser Eye (Left) 4"
|
||||||
- [0x00c6, 5, ["Bumper"]]
|
- [0x00c6, 5, ["Bumper", "AntiFairyCircle"]]
|
||||||
- [ 0x00cb, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x00cb, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x00cb, 3, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 1"
|
- [ 0x00cb, 3, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 1"
|
||||||
- [ 0x00cb, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 2"
|
- [ 0x00cb, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 2"
|
||||||
@@ -385,11 +387,11 @@ UwGeneralDeny:
|
|||||||
- [ 0x00d8, 8, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Kill Room 1 - Red Eyegore"
|
- [ 0x00d8, 8, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Kill Room 1 - Red Eyegore"
|
||||||
- [ 0x00d9, 1, [ "RollerHorizontalRight" ] ] #"Eastern Palace - Dodgeball - Green Eyegore 1"
|
- [ 0x00d9, 1, [ "RollerHorizontalRight" ] ] #"Eastern Palace - Dodgeball - Green Eyegore 1"
|
||||||
- [ 0x00db, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
- [ 0x00db, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
|
||||||
- [ 0x00db, 3, [ "Bumper" ] ] # Okay in vanilla
|
- [ 0x00db, 3, [ "Bumper", "AntiFairyCircle" ] ] # Okay in vanilla
|
||||||
- [ 0x00dc, 2, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ]
|
- [ 0x00dc, 2, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ]
|
||||||
- [ 0x00dc, 9, [ "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Thieves' Town - Grand Room SE - Fire Snake 2"
|
- [ 0x00dc, 9, [ "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Thieves' Town - Grand Room SE - Fire Snake 2"
|
||||||
- [ 0x00df, 0, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Paradox Cave - Top - Mini Moldorm 1"
|
- [ 0x00df, 0, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Paradox Cave - Top - Mini Moldorm 1"
|
||||||
- [ 0x00df, 1, [ "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle" ] ] #"Paradox Cave - Top - Mini Moldorm 2"
|
- [ 0x00df, 1, [ "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "Bumper" ] ] #"Paradox Cave - Top - Mini Moldorm 2"
|
||||||
- [ 0x00e4, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 1"
|
- [ 0x00e4, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 1"
|
||||||
- [ 0x00e4, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 2"
|
- [ 0x00e4, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 2"
|
||||||
- [ 0x00e4, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 3"
|
- [ 0x00e4, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 3"
|
||||||
@@ -420,8 +422,8 @@ UwGeneralDeny:
|
|||||||
- [0x0107, 1, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
|
- [0x0107, 1, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
|
||||||
- [0x0107, 2, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
|
- [0x0107, 2, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
|
||||||
- [0x010b, 6, ["RollerHorizontalRight"]]
|
- [0x010b, 6, ["RollerHorizontalRight"]]
|
||||||
- [0x010c, 4, ["AntiFairyCircle"]]
|
- [0x010c, 4, ["AntiFairyCircle", "Bumper"]]
|
||||||
- [0x010c, 5, ["AntiFairyCircle"]]
|
- [0x010c, 5, ["AntiFairyCircle", "Bumper"]]
|
||||||
- [0x010c, 6, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
|
- [0x010c, 6, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
|
||||||
- [0x010c, 7, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
|
- [0x010c, 7, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
|
||||||
- [0x011e, 0, ["RollerVerticalDown"]]
|
- [0x011e, 0, ["RollerVerticalDown"]]
|
||||||
@@ -450,6 +452,7 @@ OwGeneralDeny:
|
|||||||
- [0x40, 16, ["RollerVerticalUp", "RollerVerticalDown"]] # Ropa near back hole is really large as a roller
|
- [0x40, 16, ["RollerVerticalUp", "RollerVerticalDown"]] # Ropa near back hole is really large as a roller
|
||||||
- [0x55, 6, ["BigSpike"]]
|
- [0x55, 6, ["BigSpike"]]
|
||||||
- [0x57, 5, ["RollerVerticalUp", "RollerVerticalDown"]]
|
- [0x57, 5, ["RollerVerticalUp", "RollerVerticalDown"]]
|
||||||
|
- [0x5b, 0, ["AntiFairyCircle", "Bumper"]] # ropa on pyramid
|
||||||
- [0x5e, 0, ["Gibo"]] # kiki eating Gibo
|
- [0x5e, 0, ["Gibo"]] # kiki eating Gibo
|
||||||
- [0x5e, 1, ["Gibo", "RollerVerticalUp", "RollerVerticalDown"]] # kiki eating Gibo
|
- [0x5e, 1, ["Gibo", "RollerVerticalUp", "RollerVerticalDown"]] # kiki eating Gibo
|
||||||
- [0x5e, 2, ["Gibo"]] # kiki eating Gibo
|
- [0x5e, 2, ["Gibo"]] # kiki eating Gibo
|
||||||
@@ -473,9 +476,9 @@ OwGeneralDeny:
|
|||||||
- [0x5e, 20, ["Gibo"]] # kiki eating Gibo
|
- [0x5e, 20, ["Gibo"]] # kiki eating Gibo
|
||||||
- [0x62, 1, ["RollerVerticalUp", "RollerVerticalDown"]] # hard to avoid roller around hammer pegs
|
- [0x62, 1, ["RollerVerticalUp", "RollerVerticalDown"]] # hard to avoid roller around hammer pegs
|
||||||
- [0x62, 3, ["RollerVerticalUp", "RollerVerticalDown"]] # hard to avoid roller around hammer pegs
|
- [0x62, 3, ["RollerVerticalUp", "RollerVerticalDown"]] # hard to avoid roller around hammer pegs
|
||||||
- [0x6d, 3, ["Bumper"]] # can block path with multiple bumpers
|
- [0x6d, 3, ["Bumper", "AntiFairyCircle"]] # can block path with multiple bumpers
|
||||||
- [0x77, 1, ["Bumper"]] # soft-lock potential near ladder
|
- [0x77, 1, ["Bumper", "AntiFairyCircle"]] # soft-lock potential near ladder
|
||||||
- [0x7f, 1, ["Bumper"]] # soft-lock potential near ladder
|
- [0x7f, 1, ["Bumper", "AntiFairyCircle"]] # soft-lock potential near ladder
|
||||||
UwEnemyDrop:
|
UwEnemyDrop:
|
||||||
- [0x0085, 9, ["Babasu"]] # ran off the edge and didn't return
|
- [0x0085, 9, ["Babasu"]] # ran off the edge and didn't return
|
||||||
- [0x00cb, 3, ["Zoro"]] # layer issues
|
- [0x00cb, 3, ["Zoro"]] # layer issues
|
||||||
@@ -576,7 +579,7 @@ UwEnemyDrop:
|
|||||||
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
||||||
- [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "Hover",
|
- [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "Hover",
|
||||||
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
|
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
|
||||||
"BombGuard", "GreenKnifeGuard", "Bumper", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
"BombGuard", "GreenKnifeGuard", "Bumper", "AntiFairyCircle", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
||||||
- [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "Hover",
|
- [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "Hover",
|
||||||
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
|
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
|
||||||
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
|
||||||
@@ -621,6 +624,7 @@ UwEnemyDrop:
|
|||||||
- [0x0067, 6, ["Wizzrobe"]]
|
- [0x0067, 6, ["Wizzrobe"]]
|
||||||
- [0x0067, 7, ["Wizzrobe", "Stal"]]
|
- [0x0067, 7, ["Wizzrobe", "Stal"]]
|
||||||
- [0x0067, 8, ["Wizzrobe", "Stal"]]
|
- [0x0067, 8, ["Wizzrobe", "Stal"]]
|
||||||
|
- [0x006b, 4, ["Wizzrobe"]] # crystal switch interaction?
|
||||||
- [0x0074, 5, ["Wizzrobe"]]
|
- [0x0074, 5, ["Wizzrobe"]]
|
||||||
- [0x007c, 1, ["Wizzrobe", "Stal"]]
|
- [0x007c, 1, ["Wizzrobe", "Stal"]]
|
||||||
- [0x007c, 3, ["Wizzrobe", "Stal"]]
|
- [0x007c, 3, ["Wizzrobe", "Stal"]]
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ def create_guiargs(parent):
|
|||||||
arg = options[mainpage][subpage][widget] if subpage != "" else options[mainpage][widget]
|
arg = options[mainpage][subpage][widget] if subpage != "" else options[mainpage][widget]
|
||||||
page = parent.pages[mainpage].pages[subpage] if subpage != "" else parent.pages[mainpage]
|
page = parent.pages[mainpage].pages[subpage] if subpage != "" else parent.pages[mainpage]
|
||||||
pagewidgets = page.content.customWidgets if mainpage == "custom" else page.content.startingWidgets if mainpage == "startinventory" else page.widgets
|
pagewidgets = page.content.customWidgets if mainpage == "custom" else page.content.startingWidgets if mainpage == "startinventory" else page.widgets
|
||||||
if hasattr(pagewidgets[widget], 'storageVar'):
|
if widget in pagewidgets and hasattr(pagewidgets[widget], 'storageVar'):
|
||||||
setattr(guiargs, arg, pagewidgets[widget].storageVar.get())
|
setattr(guiargs, arg, pagewidgets[widget].storageVar.get())
|
||||||
|
|
||||||
# Get Multiworld Worlds count
|
# Get Multiworld Worlds count
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from tkinter import ttk, font, Frame, E, W, NW, TOP, LEFT, RIGHT, Y, Label
|
from tkinter import messagebox, ttk, font, Button, Frame, E, W, TOP, LEFT, RIGHT, X, Y, Label
|
||||||
import source.gui.widgets as widgets
|
import source.gui.widgets as widgets
|
||||||
|
from source.classes.Empty import Empty
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -28,6 +29,16 @@ def item_page(parent):
|
|||||||
|
|
||||||
self.frames["leftItemFrame"] = Frame(self.frames["mainFrame"])
|
self.frames["leftItemFrame"] = Frame(self.frames["mainFrame"])
|
||||||
self.frames["leftItemFrame"].pack(side=LEFT)
|
self.frames["leftItemFrame"].pack(side=LEFT)
|
||||||
|
self.frames["worldstateFrame"] = Frame(self.frames["leftItemFrame"])
|
||||||
|
self.frames["worldstateFrame"].pack(side=TOP, fill=X)
|
||||||
|
|
||||||
|
## Retro Button
|
||||||
|
widget = Empty()
|
||||||
|
widget.pieces = {}
|
||||||
|
widget.type = "button"
|
||||||
|
widget.pieces["button"] = Button(self.frames["worldstateFrame"], text="Retro", command=lambda: retro(widget))
|
||||||
|
widget.pieces["button"].pack(side=RIGHT, padx=(1, 2))
|
||||||
|
|
||||||
self.frames["rightItemFrame"] = Frame(self.frames["mainFrame"])
|
self.frames["rightItemFrame"] = Frame(self.frames["mainFrame"])
|
||||||
self.frames["rightItemFrame"].pack(side=RIGHT)
|
self.frames["rightItemFrame"].pack(side=RIGHT)
|
||||||
|
|
||||||
@@ -65,8 +76,6 @@ def item_page(parent):
|
|||||||
for key in dictWidgets:
|
for key in dictWidgets:
|
||||||
self.widgets[key] = dictWidgets[key]
|
self.widgets[key] = dictWidgets[key]
|
||||||
packAttrs = {"anchor":E}
|
packAttrs = {"anchor":E}
|
||||||
if key == "retro":
|
|
||||||
packAttrs["side"] = RIGHT
|
|
||||||
if self.widgets[key].type == "checkbox" or framename.startswith("leftPoolFrame"):
|
if self.widgets[key].type == "checkbox" or framename.startswith("leftPoolFrame"):
|
||||||
packAttrs["anchor"] = W
|
packAttrs["anchor"] = W
|
||||||
if framename == "checkboxes":
|
if framename == "checkboxes":
|
||||||
@@ -75,7 +84,32 @@ def item_page(parent):
|
|||||||
elif framename == "leftPoolHeader":
|
elif framename == "leftPoolHeader":
|
||||||
packAttrs["side"] = LEFT
|
packAttrs["side"] = LEFT
|
||||||
packAttrs["padx"] = (0, 20)
|
packAttrs["padx"] = (0, 20)
|
||||||
|
elif framename == "rightItemFrame" and self.widgets[key].type == "checkbox":
|
||||||
|
packAttrs["side"] = LEFT
|
||||||
|
packAttrs["padx"] = (118, 0)
|
||||||
packAttrs = widgets.add_padding_from_config(packAttrs, theseWidgets[key])
|
packAttrs = widgets.add_padding_from_config(packAttrs, theseWidgets[key])
|
||||||
self.widgets[key].pack(packAttrs)
|
self.widgets[key].pack(packAttrs)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def retro(baseWidget):
|
||||||
|
widget = baseWidget.pieces['button']
|
||||||
|
root = widget.winfo_toplevel()
|
||||||
|
text_output = ""
|
||||||
|
temp_widget = root.pages["randomizer"].pages["dungeon"].widgets["smallkeyshuffle"]
|
||||||
|
text_output += f'\n {temp_widget.label.cget("text")}'
|
||||||
|
temp_widget.storageVar.set('universal')
|
||||||
|
|
||||||
|
temp_widget = root.pages["randomizer"].pages["item"].widgets["bow_mode"]
|
||||||
|
text_output += f'\n {temp_widget.label.cget("text")}'
|
||||||
|
if temp_widget.storageVar.get() == 'progressive':
|
||||||
|
temp_widget.storageVar.set('retro')
|
||||||
|
elif temp_widget.storageVar.get() == 'silvers':
|
||||||
|
temp_widget.storageVar.set('retro_silvers')
|
||||||
|
|
||||||
|
temp_widget = root.pages["randomizer"].pages["item"].widgets["take_any"]
|
||||||
|
text_output += f'\n {temp_widget.label.cget("text")}'
|
||||||
|
if temp_widget.storageVar.get() == 'none':
|
||||||
|
temp_widget.storageVar.set('random')
|
||||||
|
|
||||||
|
messagebox.showinfo('', f'The following settings were changed:{text_output}')
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ def check_requirements(console=False):
|
|||||||
'pyyaml': 'yaml'}
|
'pyyaml': 'yaml'}
|
||||||
missing = []
|
missing = []
|
||||||
for package, import_name in check_packages.items():
|
for package, import_name in check_packages.items():
|
||||||
spec = importlib.util.find_spec(import_name)
|
try:
|
||||||
if spec is None:
|
__import__(import_name)
|
||||||
|
except ImportError:
|
||||||
missing.append(package)
|
missing.append(package)
|
||||||
if len(missing) > 0:
|
if len(missing) > 0:
|
||||||
packages = ','.join(missing)
|
packages = ','.join(missing)
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ def roll_settings(weights):
|
|||||||
ret.ow_whirlpool = get_choice_bool('whirlpool_shuffle')
|
ret.ow_whirlpool = get_choice_bool('whirlpool_shuffle')
|
||||||
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'
|
||||||
|
ret.shuffle_followers = get_choice_bool('shuffle_followers')
|
||||||
ret.bonk_drops = get_choice_bool('bonk_drops')
|
ret.bonk_drops = get_choice_bool('bonk_drops')
|
||||||
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'
|
||||||
|
|||||||
Reference in New Issue
Block a user