Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -36,7 +36,8 @@ def main():
|
||||
parser.add_argument('--ow_palettes', default='default', choices=['default', 'random', 'blackout'])
|
||||
parser.add_argument('--uw_palettes', default='default', choices=['default', 'random', 'blackout'])
|
||||
parser.add_argument('--reduce_flashing', help='Reduce some in-game flashing.', action='store_true')
|
||||
parser.add_argument('--shuffle_sfx', help='Shuffles sound sfx', action='store_true')
|
||||
parser.add_argument('--shuffle_sfx', help='Shuffles sfx instruments', action='store_true')
|
||||
parser.add_argument('--shuffle_songinstruments', help='Shuffles sound sfx', action='store_true')
|
||||
parser.add_argument('--msu_resume', help='Enable MSU resume', action='store_true')
|
||||
parser.add_argument('--sprite', help='''\
|
||||
Path to a sprite sheet to use for Link. Needs to be in
|
||||
|
||||
@@ -10,6 +10,7 @@ except ImportError:
|
||||
|
||||
from Utils import output_path
|
||||
from Rom import LocalRom, apply_rom_settings
|
||||
from source.classes.SFX import output_song_data
|
||||
from source.tools.BPS import bps_read_vlv
|
||||
|
||||
|
||||
@@ -33,11 +34,14 @@ def adjust(args):
|
||||
|
||||
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
|
||||
args.sprite, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx,
|
||||
args.msu_resume)
|
||||
args.shuffle_songinstruments, args.msu_resume)
|
||||
|
||||
output_path.cached_path = args.outputpath
|
||||
rom.write_to_file(output_path('%s.sfc' % outfilebase))
|
||||
|
||||
if args.shuffle_songinstruments:
|
||||
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfilebase)
|
||||
|
||||
logger.info('Done. Enjoy.')
|
||||
logger.debug('Total Time: %s', time.process_time() - start)
|
||||
|
||||
@@ -68,11 +72,14 @@ def patch(args):
|
||||
|
||||
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
|
||||
args.sprite, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx,
|
||||
args.msu_resume)
|
||||
args.shuffle_songinstruments, args.msu_resume)
|
||||
|
||||
output_path.cached_path = args.outputpath
|
||||
rom.write_to_file(output_path('%s.sfc' % outfile_base))
|
||||
|
||||
if args.shuffle_songinstruments:
|
||||
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfile_base)
|
||||
|
||||
logger.info('Done. Enjoy.')
|
||||
logger.debug('Total Time: %s', time.process_time() - start)
|
||||
|
||||
|
||||
@@ -1627,7 +1627,7 @@ class Entrance(object):
|
||||
explored_regions[region] = path
|
||||
for exit in region.exits:
|
||||
if exit.connected_region and (not ignore_ledges or exit.spot_type != 'Ledge') \
|
||||
and exit.connected_region.name not in ['Dig Game Area'] \
|
||||
and exit.name not in ['Dig Game To Ledge Drop'] \
|
||||
and exit.access_rule(state):
|
||||
if exit.connected_region == destination:
|
||||
found = True
|
||||
|
||||
3
CLI.py
3
CLI.py
@@ -140,7 +140,7 @@ def parse_cli(argv, no_defaults=False):
|
||||
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
|
||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
||||
'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle',
|
||||
'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx',
|
||||
'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', 'shuffle_songinstruments',
|
||||
'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode',
|
||||
'bonk_drops', 'trap_door_mode', 'key_logic_algorithm', 'door_self_loops']:
|
||||
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
||||
@@ -258,6 +258,7 @@ def parse_settings():
|
||||
"uw_palettes": "default",
|
||||
"reduce_flashing": False,
|
||||
"shuffle_sfx": False,
|
||||
"shuffle_songinstruments": False,
|
||||
"msu_resume": False,
|
||||
"collection_rate": False,
|
||||
|
||||
|
||||
@@ -1800,7 +1800,7 @@ def imp_locations_factory(world, player):
|
||||
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
||||
if world.mode[player] == 'standard':
|
||||
imp_locations.append('Zelda Pickup')
|
||||
imp_locations.append('Zelda Dropoff')
|
||||
imp_locations.append('Zelda Drop Off')
|
||||
return imp_locations
|
||||
|
||||
|
||||
|
||||
7
Main.py
7
Main.py
@@ -35,8 +35,9 @@ from source.item.FillUtil import create_item_pool_config, massage_item_pool, dis
|
||||
from source.overworld.EntranceShuffle2 import link_entrances_new
|
||||
from source.tools.BPS import create_bps_from_data
|
||||
from source.classes.CustomSettings import CustomSettings
|
||||
from source.classes.SFX import output_song_data
|
||||
|
||||
version_number = '1.2.0.21'
|
||||
version_number = '1.2.0.22'
|
||||
version_branch = '-u'
|
||||
__version__ = f'{version_number}{version_branch}'
|
||||
|
||||
@@ -393,7 +394,7 @@ def main(args, seed=None, fish=None):
|
||||
apply_rom_settings(rom, args.heartbeep[player], args.heartcolor[player], args.quickswap[player],
|
||||
args.fastmenu[player], args.disablemusic[player], args.sprite[player],
|
||||
args.ow_palettes[player], args.uw_palettes[player], args.reduce_flashing[player],
|
||||
args.shuffle_sfx[player], args.msu_resume[player])
|
||||
args.shuffle_sfx[player], args.shuffle_songinstruments[player], args.msu_resume[player])
|
||||
|
||||
if args.jsonout:
|
||||
jsonout[f'patch_t{team}_p{player}'] = rom.patches
|
||||
@@ -404,6 +405,8 @@ def main(args, seed=None, fish=None):
|
||||
if world.players > 1 or world.teams > 1:
|
||||
outfilepname += f"_{world.player_names[player][team].replace(' ', '_')}" if world.player_names[player][team] != 'Player %d' % player else ''
|
||||
outfilesuffix = f'_{Settings.make_code(world, player)}' if not args.outputname else ''
|
||||
if args.shuffle_songinstruments:
|
||||
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfilebase)
|
||||
if args.bps:
|
||||
patchfile = output_path(f'{outfilebase}{outfilepname}{outfilesuffix}.bps')
|
||||
patch = create_bps_from_data(LocalRom(args.rom, patch=False).buffer, rom.buffer)
|
||||
|
||||
@@ -8,7 +8,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
|
||||
from OverworldGlitchRules import create_owg_connections
|
||||
from Utils import bidict
|
||||
|
||||
version_number = '0.3.3.1'
|
||||
version_number = '0.3.3.2'
|
||||
# branch indicator is intentionally different across branches
|
||||
version_branch = ''
|
||||
|
||||
@@ -1173,6 +1173,7 @@ def define_tile_groups(world, do_grouped, player):
|
||||
(lw_regions if id < 0x40 or id >= 0x80 else dw_regions).extend(OWTileRegions.inverse[id])
|
||||
tile_groups.append((group, lw_regions, dw_regions))
|
||||
|
||||
random.shuffle(tile_groups)
|
||||
return tile_groups, flipped_groups, nonflipped_groups, undefined_chance
|
||||
|
||||
def remove_reserved(world, groupedlist, connected_edges, player):
|
||||
@@ -1378,7 +1379,7 @@ def can_reach_smith(world, player):
|
||||
elif exit.connected_region.name == 'Blacksmiths Hut' and exit.access_rule(blank_state):
|
||||
found = True
|
||||
return
|
||||
elif exit.connected_region.name not in explored_regions:
|
||||
elif exit.connected_region.name not in explored_regions and exit.name != "Dig Game To Ledge Drop":
|
||||
if (region.type == RegionType.Dungeon and exit.connected_region.name.endswith(' Portal')) \
|
||||
or (exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld] \
|
||||
and exit.access_rule(blank_state)):
|
||||
@@ -1623,7 +1624,7 @@ def validate_layout(world, player):
|
||||
or (entrance.name == 'Big Bomb Shop' and (world.mode[player] != 'inverted' or not world.shufflelinks[player] or world.shuffle[player] in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])) \
|
||||
or (entrance.name == 'Ganons Tower' and (world.mode[player] != 'inverted' and not world.shuffle_ganon[player])) \
|
||||
or (entrance.name in ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] and world.shuffle[player] not in ['insanity']) \
|
||||
or entrance.name == 'Tavern North':
|
||||
or (entrance.name == 'Tavern North' and not world.shuffletavern[player]):
|
||||
continue # these are fixed entrances and cannot be used for gaining access to region
|
||||
if entrance.name not in drop_entrances \
|
||||
and ((entrance.name in dungeon_entrances and world.shuffle[player] not in ['dungeonssimple', 'simple', 'restricted']) \
|
||||
|
||||
@@ -109,6 +109,13 @@ These are now independent of retro mode and have three options: None, Random, an
|
||||
|
||||
# Bug Fixes and Notes
|
||||
|
||||
* 1.2.0.22u
|
||||
* Flute can't be activated in rain state (except glitched modes) (Thanks codemann!)
|
||||
* ER: Minor fix for Link's House on DM in Insanity (escape cave should not be re-used)
|
||||
* Logic issues:
|
||||
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
|
||||
* More advanced bunny-walking logic in dungeons (multiple paths considred)
|
||||
* MSU: GTBK song fix for DR (Thanks codemann!)
|
||||
* 1.2.0.21u
|
||||
* Fix that should force items needed for leaving Zelda's cell to before the throne room, so S&Q isn't mandatory
|
||||
* Small fix for Tavern Shuffle (thanks Catobat)
|
||||
|
||||
11
Rom.py
11
Rom.py
@@ -32,13 +32,13 @@ from EntranceShuffle import door_addresses, exit_ids, ow_prize_table
|
||||
from OverworldShuffle import default_flute_connections, flute_data
|
||||
from InitialSram import InitialSram
|
||||
|
||||
from source.classes.SFX import randomize_sfx
|
||||
from source.classes.SFX import randomize_sfx, randomize_songinstruments
|
||||
from source.item.FillUtil import valid_pot_items
|
||||
from source.dungeon.RoomList import Room0127
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '52317b2dd4fb303887f26ecc40a4cae3'
|
||||
RANDOMIZERBASEHASH = 'fe9e7870071daa40829c1072829bf30b'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -109,6 +109,9 @@ class LocalRom(object):
|
||||
self.patch_base_rom()
|
||||
self.orig_buffer = self.buffer.copy()
|
||||
|
||||
def read_byte(self, address):
|
||||
return self.buffer[address]
|
||||
|
||||
def write_byte(self, address, value):
|
||||
self.buffer[address] = value
|
||||
|
||||
@@ -1826,7 +1829,7 @@ def hud_format_text(text):
|
||||
|
||||
|
||||
def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite,
|
||||
ow_palettes, uw_palettes, reduce_flashing, shuffle_sfx, msu_resume):
|
||||
ow_palettes, uw_palettes, reduce_flashing, shuffle_sfx, shuffle_songinstruments, msu_resume):
|
||||
|
||||
if not os.path.exists("data/sprites/official/001.link.1.zspr") and rom.orig_buffer:
|
||||
dump_zspr(rom.orig_buffer[0x80000:0x87000], rom.orig_buffer[0xdd308:0xdd380],
|
||||
@@ -1932,6 +1935,8 @@ def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, spr
|
||||
|
||||
if shuffle_sfx:
|
||||
randomize_sfx(rom)
|
||||
if shuffle_songinstruments:
|
||||
randomize_songinstruments(rom)
|
||||
|
||||
if isinstance(rom, LocalRom):
|
||||
rom.write_crc()
|
||||
|
||||
145
Rules.py
145
Rules.py
@@ -128,9 +128,11 @@ def mirrorless_path_to_castle_courtyard(world, player):
|
||||
queue.append((entrance.connected_region, new_path))
|
||||
seen.add(entrance.connected_region)
|
||||
|
||||
|
||||
def set_rule(spot, rule):
|
||||
spot.access_rule = rule
|
||||
|
||||
|
||||
def set_defeat_dungeon_boss_rule(location):
|
||||
# Lambda required to defer evaluation of dungeon.boss since it will change later if boos shuffle is used
|
||||
set_rule(location, lambda state: location.parent_region.dungeon.boss.can_defeat(state))
|
||||
@@ -139,6 +141,7 @@ def set_defeat_dungeon_boss_rule(location):
|
||||
def set_always_allow(spot, rule):
|
||||
spot.always_allow = rule
|
||||
|
||||
|
||||
def add_rule(spot, rule, combine='and'):
|
||||
old_rule = spot.access_rule
|
||||
if combine == 'or':
|
||||
@@ -167,22 +170,26 @@ def forbid_item(location, item, player):
|
||||
old_rule = location.item_rule
|
||||
location.item_rule = lambda i: (i.name != item or i.player != player) and old_rule(i)
|
||||
|
||||
|
||||
def add_item_rule(location, rule):
|
||||
old_rule = location.item_rule
|
||||
location.item_rule = lambda item: rule(item) and old_rule(item)
|
||||
|
||||
|
||||
def item_in_locations(state, item, player, locations):
|
||||
for location in locations:
|
||||
if item_name(state, location[0], location[1]) == (item, player):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def item_name(state, location, player):
|
||||
location = state.world.get_location(location, player)
|
||||
if location.item is None:
|
||||
return None
|
||||
return (location.item.name, location.item.player)
|
||||
|
||||
|
||||
def global_rules(world, player):
|
||||
# ganon can only carry triforce
|
||||
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
|
||||
@@ -732,7 +739,7 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Swamp Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Swamp Barrier', player), player))
|
||||
|
||||
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Swamp Crystal Switch Outer', player), player))) # It is the length of the sword, not the beam itself that allows this
|
||||
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Swamp Crystal Switch Outer', player), player))) # It is the length of the sword, not the beam itself that allows this
|
||||
set_rule(world.get_entrance('Swamp Crystal Switch Outer to Inner Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
||||
set_rule(world.get_entrance('Swamp Crystal Switch Inner to Outer Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player))
|
||||
|
||||
@@ -775,8 +782,8 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Mire Crystal Left Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Left', player), player))
|
||||
|
||||
set_rule(world.get_entrance('Mire Conveyor to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: True) # Can always throw pots
|
||||
set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic?
|
||||
set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: True) # Can always throw pots
|
||||
set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic?
|
||||
|
||||
set_rule(world.get_location('Turtle Rock - Chain Chomps', player), lambda state: state.can_reach('TR Chain Chomps Top', 'Region', player) and state.can_hit_crystal_through_barrier(player))
|
||||
set_rule(world.get_entrance('TR Chain Chomps Top to Bottom Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('TR Chain Chomps Top', player), player))
|
||||
@@ -798,14 +805,14 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('TR Pokey 2 Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('TR Crystaroller Top to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('TR Crystal Maze Start to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('TR Chain Chomps Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Chain Chomps Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Pokey 2 Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('TR Pokey 2 Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Crystaroller Bottom to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Crystaroller Middle to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Middle', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Chain Chomps Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Chain Chomps Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Pokey 2 Bottom to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('TR Pokey 2 Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Crystaroller Bottom to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Bottom', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Crystaroller Middle to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('TR Crystaroller Middle', player), player))) # or state.has_beam_sword(player)
|
||||
set_rule(world.get_entrance('TR Crystaroller Middle to Bottom Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player))
|
||||
set_rule(world.get_entrance('TR Crystal Maze End to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) # or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) // These work by clipping the rang through the two stone blocks, which works sometimes.
|
||||
set_rule(world.get_entrance('TR Crystal Maze Interior to End Bypass', player), lambda state: state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # Beam sword does NOT work
|
||||
set_rule(world.get_entrance('TR Crystal Maze Interior to Start Bypass', player), lambda state: True) # Can always grab a pot from the interior and walk it to the start region and throw it there
|
||||
set_rule(world.get_entrance('TR Crystal Maze End to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) # or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) // These work by clipping the rang through the two stone blocks, which works sometimes.
|
||||
set_rule(world.get_entrance('TR Crystal Maze Interior to End Bypass', player), lambda state: state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # Beam sword does NOT work
|
||||
set_rule(world.get_entrance('TR Crystal Maze Interior to Start Bypass', player), lambda state: True) # Can always grab a pot from the interior and walk it to the start region and throw it there
|
||||
|
||||
set_rule(world.get_entrance('GT Hookshot Platform Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Platform', player), player))
|
||||
set_rule(world.get_entrance('GT Hookshot Entry Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('GT Hookshot South Entry', player), player))
|
||||
@@ -922,7 +929,7 @@ def bomb_rules(world, player):
|
||||
('TR Tongue Pull WS', True),
|
||||
('TR Twin Pokeys NW', False),
|
||||
]
|
||||
for killdoor,bombable in easy_kill_rooms:
|
||||
for killdoor, bombable in easy_kill_rooms:
|
||||
if bombable:
|
||||
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||
else:
|
||||
@@ -939,47 +946,47 @@ def bomb_rules(world, player):
|
||||
if world.get_entrance('Mire Cross SW', player).door.trapped:
|
||||
add_rule(world.get_entrance('Mire Cross SW', player), lambda state: state.can_kill_most_things(player))
|
||||
|
||||
enemy_kill_drops = [ # Location, bool-bombable
|
||||
enemy_kill_drops = [ # Location, bool-bombable
|
||||
('Hyrule Castle - Map Guard Key Drop', True),
|
||||
('Hyrule Castle - Boomerang Guard Key Drop', True),
|
||||
('Hyrule Castle - Key Rat Key Drop', True),
|
||||
# ('Hyrule Castle - Big Key Drop', True), # Pots are available
|
||||
# ('Eastern Palace - Dark Eyegore Key Drop', True), # Pots are available
|
||||
# ('Hyrule Castle - Big Key Drop', True), # Pots are available
|
||||
# ('Eastern Palace - Dark Eyegore Key Drop', True), # Pots are available
|
||||
('Castle Tower - Dark Archer Key Drop', True),
|
||||
# ('Castle Tower - Circle of Pots Key Drop', True), # Pots are available
|
||||
# ('Skull Woods - Spike Corner Key Drop', True), # Pots are available
|
||||
# ('Castle Tower - Circle of Pots Key Drop', True), # Pots are available
|
||||
# ('Skull Woods - Spike Corner Key Drop', True), # Pots are available
|
||||
('Ice Palace - Jelly Key Drop', True),
|
||||
('Ice Palace - Conveyor Key Drop', True),
|
||||
('Misery Mire - Conveyor Crystal Key Drop', True),
|
||||
('Turtle Rock - Pokey 1 Key Drop', True),
|
||||
('Turtle Rock - Pokey 2 Key Drop', True),
|
||||
# ('Ganons Tower - Mini Helmasaur Key Drop', True) # Pots are available
|
||||
('Castle Tower - Room 03', True), # Two spring soliders
|
||||
('Ice Palace - Compass Chest', True) # Pengators
|
||||
# ('Ganons Tower - Mini Helmasaur Key Drop', True) # Pots are available
|
||||
('Castle Tower - Room 03', True), # Two spring soliders
|
||||
('Ice Palace - Compass Chest', True) # Pengators
|
||||
]
|
||||
for location,bombable in enemy_kill_drops:
|
||||
for location, bombable in enemy_kill_drops:
|
||||
if bombable:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.can_kill_most_things(player))
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.can_kill_most_things(player))
|
||||
else:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player))
|
||||
|
||||
add_rule(world.get_location('Attic Cracked Floor', player), lambda state: state.can_use_bombs(player))
|
||||
add_rule(world.get_location('Attic Cracked Floor', player), lambda state: state.can_use_bombs(player))
|
||||
bombable_floors = ['PoD Pit Room Bomb Hole', 'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole', 'GT Bob\'s Room Hole']
|
||||
for entrance in bombable_floors:
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||
|
||||
if world.doorShuffle[player] == 'vanilla':
|
||||
add_rule(world.get_entrance('TR Lazy Eyes SE', player), lambda state: state.can_use_bombs(player)) # ToDo: Add always true for inverted, cross-entrance, and door-variants and so on.
|
||||
add_rule(world.get_entrance('Turtle Rock Ledge Exit (West)', player), lambda state: state.can_use_bombs(player)) # Is this the same as above?
|
||||
add_rule(world.get_entrance('TR Lazy Eyes SE', player), lambda state: state.can_use_bombs(player)) # ToDo: Add always true for inverted, cross-entrance, and door-variants and so on.
|
||||
add_rule(world.get_entrance('Turtle Rock Ledge Exit (West)', player), lambda state: state.can_use_bombs(player)) # Is this the same as above?
|
||||
|
||||
dungeon_bonkable = ['Sewers Rat Path WS', 'Sewers Rat Path WN',
|
||||
'PoD Warp Hint SE', 'PoD Jelly Hall NW', 'PoD Jelly Hall NE', 'PoD Mimics 1 SW',
|
||||
'Thieves Ambush E', 'Thieves Rail Ledge W',
|
||||
'TR Dash Room NW', 'TR Crystaroller SW', 'TR Dash Room ES',
|
||||
'GT Four Torches NW','GT Fairy Abyss SW'
|
||||
'GT Four Torches NW', 'GT Fairy Abyss SW'
|
||||
]
|
||||
dungeon_bombable = ['PoD Map Balcony WS', 'PoD Arena Ledge ES', 'PoD Dark Maze E', 'PoD Big Chest Balcony W',
|
||||
'Swamp Pot Row WN','Swamp Map Ledge EN', 'Swamp Hammer Switch WN', 'Swamp Hub Dead Ledge EN', 'Swamp Waterway N', 'Swamp I S',
|
||||
'Swamp Pot Row WN', 'Swamp Map Ledge EN', 'Swamp Hammer Switch WN', 'Swamp Hub Dead Ledge EN', 'Swamp Waterway N', 'Swamp I S',
|
||||
'Skull Pot Circle WN', 'Skull Pull Switch EN', 'Skull Big Key EN', 'Skull Lone Pot WN',
|
||||
'Thieves Rail Ledge NW', 'Thieves Pot Alcove Bottom SW',
|
||||
'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole',
|
||||
@@ -987,9 +994,9 @@ def bomb_rules(world, player):
|
||||
'GT Warp Maze (Rails) WS', 'GT Bob\'s Room Hole', 'GT Randomizer Room ES', 'GT Bomb Conveyor SW', 'GT Crystal Circles NW', 'GT Cannonball Bridge SE', 'GT Refill NE'
|
||||
]
|
||||
for entrance in dungeon_bonkable:
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||
for entrance in dungeon_bombable:
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||
add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player))
|
||||
else:
|
||||
doors_to_bomb_check = [x for x in world.doors if x.player == player and x.type in [DoorType.Normal, DoorType.Interior]]
|
||||
for door in doors_to_bomb_check:
|
||||
@@ -1146,12 +1153,12 @@ def ow_bunny_rules(world, player):
|
||||
add_bunny_rule(world.get_entrance('20 Rupee Cave', player), player)
|
||||
add_bunny_rule(world.get_entrance('50 Rupee Cave', player), player)
|
||||
|
||||
add_bunny_rule(world.get_entrance('Skull Woods First Section Hole (North)', player), player) # bunny cannot lift bush
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Second Section Hole', player), player) # bunny cannot lift bush
|
||||
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 First Section Hole (North)', player), player) # bunny cannot lift bush
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Second Section Hole', player), player) # bunny cannot lift bush
|
||||
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('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('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('Bonk Fairy (Dark)', player), player)
|
||||
add_bunny_rule(world.get_entrance('Misery Mire', player), player)
|
||||
@@ -1378,6 +1385,7 @@ def forbid_bomb_jump_requirements(world, player):
|
||||
set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Ice Lake Iceberg Bomb Jump', player), lambda state: False)
|
||||
|
||||
|
||||
def add_conditional_lamps(world, player):
|
||||
def add_conditional_lamp(spot, spottype='Location'):
|
||||
if spottype == 'Location':
|
||||
@@ -1478,33 +1486,33 @@ def swordless_rules(world, player):
|
||||
|
||||
# todo: new traps
|
||||
std_kill_rooms = {
|
||||
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
||||
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
||||
'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots
|
||||
'Desert Compass Room': ['Desert Compass NE'], # Three popos
|
||||
'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos
|
||||
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
||||
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
||||
'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots
|
||||
'Desert Compass Room': ['Desert Compass NE'], # Three popos
|
||||
'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos
|
||||
'Hera Beetles': ['Hera Beetles WS'], # Three blue beetles and only two pots, and bombs don't work.
|
||||
'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain
|
||||
'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain
|
||||
'Tower Dark Archers': ['Tower Dark Archers WN'], # Not a kill room
|
||||
'Tower Red Spears': ['Tower Red Spears WN'], # Two spear soldiers
|
||||
'Tower Red Guards': ['Tower Red Guards EN', 'Tower Red Guards SW'], # Two usain bolts
|
||||
'Tower Circle of Pots': ['Tower Circle of Pots NW'], # Two spear soldiers. Plenty of pots.
|
||||
'Tower Red Guards': ['Tower Red Guards EN', 'Tower Red Guards SW'], # Two usain bolts
|
||||
'Tower Circle of Pots': ['Tower Circle of Pots NW'], # Two spear soldiers. Plenty of pots.
|
||||
'PoD Turtle Party': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], # Lots of turtles.
|
||||
'Thieves Basement Block': ['Thieves Basement Block WN'], # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
||||
'Ice Stalfos Hint': ['Ice Stalfos Hint SE'], # Need bombs for big stalfos knights
|
||||
'Ice Pengator Trap': ['Ice Pengator Trap NE'], # Five pengators. Bomb-doable?
|
||||
'Mire 2': ['Mire 2 NE'], # Wizzrobes. Bombs dont work.
|
||||
'Mire Cross': ['Mire Cross ES'], # 4 Sluggulas. Bombs don't work
|
||||
'TR Twin Pokeys': ['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], # Two pokeys
|
||||
'GT Petting Zoo': ['GT Petting Zoo SE'], # Dont make anyone do this room with bombs.
|
||||
'GT DMs Room': ['GT DMs Room SW'], # Four red stalfos
|
||||
'GT Gauntlet 1': ['GT Gauntlet 1 WN'], # Stalfos/zazaks
|
||||
'GT Gauntlet 2': ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], # Red stalfos
|
||||
'GT Gauntlet 3': ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], # Blue zazaks
|
||||
'GT Gauntlet 4': ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], # Red zazaks
|
||||
'GT Gauntlet 5': ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], # Stalfos and zazak
|
||||
'GT Wizzrobes 1': ['GT Wizzrobes 1 SW'], # Wizzrobes. Bombs don't work
|
||||
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
||||
'Thieves Basement Block': ['Thieves Basement Block WN'], # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
||||
'Ice Stalfos Hint': ['Ice Stalfos Hint SE'], # Need bombs for big stalfos knights
|
||||
'Ice Pengator Trap': ['Ice Pengator Trap NE'], # Five pengators. Bomb-doable?
|
||||
'Mire 2': ['Mire 2 NE'], # Wizzrobes. Bombs dont work.
|
||||
'Mire Cross': ['Mire Cross ES'], # 4 Sluggulas. Bombs don't work
|
||||
'TR Twin Pokeys': ['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], # Two pokeys
|
||||
'GT Petting Zoo': ['GT Petting Zoo SE'], # Dont make anyone do this room with bombs.
|
||||
'GT DMs Room': ['GT DMs Room SW'], # Four red stalfos
|
||||
'GT Gauntlet 1': ['GT Gauntlet 1 WN'], # Stalfos/zazaks
|
||||
'GT Gauntlet 2': ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], # Red stalfos
|
||||
'GT Gauntlet 3': ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], # Blue zazaks
|
||||
'GT Gauntlet 4': ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], # Red zazaks
|
||||
'GT Gauntlet 5': ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], # Stalfos and zazak
|
||||
'GT Wizzrobes 1': ['GT Wizzrobes 1 SW'], # Wizzrobes. Bombs don't work
|
||||
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
||||
} # all trap rooms?
|
||||
|
||||
std_kill_doors_if_trapped = {
|
||||
@@ -1519,6 +1527,7 @@ std_kill_doors_if_trapped = {
|
||||
# 'Ice Lobby S' # can melt rule is sufficient
|
||||
}
|
||||
|
||||
|
||||
def add_connection(parent_name, target_name, entrance_name, world, player):
|
||||
parent = world.get_region(parent_name, player)
|
||||
target = world.get_region(target_name, player)
|
||||
@@ -1554,7 +1563,7 @@ def standard_rules(world, player):
|
||||
return loc.item and loc.item.name in ['Bomb Upgrade (+10)' if world.bombbag[player] else 'Bombs (10)']
|
||||
|
||||
def standard_escape_rule(state):
|
||||
return state.can_kill_most_things(player) or bomb_escape_rule()
|
||||
return state.can_kill_most_things(player) or bomb_escape_rule()
|
||||
|
||||
add_item_rule(world.get_location('Link\'s Uncle', player), uncle_item_rule)
|
||||
|
||||
@@ -1581,6 +1590,7 @@ def standard_rules(world, player):
|
||||
|
||||
def check_rule_list(state, r_list):
|
||||
return True if len(r_list) <= 0 else r_list[0](state) and check_rule_list(state, r_list[1:])
|
||||
|
||||
rule_list, debug_path = find_rules_for_zelda_delivery(world, player)
|
||||
set_rule(world.get_entrance('Hyrule Castle Throne Room Tapestry', player),
|
||||
lambda state: state.has('Zelda Herself', player) and check_rule_list(state, rule_list))
|
||||
@@ -1619,16 +1629,15 @@ def find_rules_for_zelda_delivery(world, player):
|
||||
if not rule(blank_state):
|
||||
rule_list.append(rule)
|
||||
next_path.append(ext.name)
|
||||
if connect.name == 'Sanctuary':
|
||||
if connect.name == 'Hyrule Castle Throne Room':
|
||||
return rule_list, next_path
|
||||
else:
|
||||
visited.add(connect)
|
||||
queue.append((connect, rule_list, next_path))
|
||||
raise Exception('No path to Sanctuary found')
|
||||
raise Exception('No path to Throne Room found')
|
||||
|
||||
|
||||
def set_bunny_rules(world, player, inverted):
|
||||
|
||||
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
|
||||
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
|
||||
bunny_impassable_caves = ['Bumper Cave (top)', 'Bumper Cave (bottom)', 'Two Brothers House',
|
||||
@@ -1668,13 +1677,14 @@ def set_bunny_rules(world, player, inverted):
|
||||
return region.is_light_world
|
||||
else:
|
||||
return region.is_dark_world
|
||||
|
||||
def is_link(region):
|
||||
if inverted:
|
||||
return region.is_dark_world
|
||||
else:
|
||||
return region.is_light_world
|
||||
|
||||
def get_rule_to_add(region, location = None, connecting_entrance = None):
|
||||
def get_rule_to_add(region, location=None, connecting_entrance=None):
|
||||
# In OWG, a location can potentially be superbunny-mirror accessible or
|
||||
# bunny revival accessible.
|
||||
if world.logic[player] == 'owglitches':
|
||||
@@ -1795,7 +1805,6 @@ drop_dungeon_entrances = {
|
||||
"Skull Back Drop"
|
||||
}
|
||||
|
||||
|
||||
bunny_revivable_entrances = {
|
||||
"Sewers Pull Switch", "TR Dash Room", "Swamp Boss", "Hera Boss",
|
||||
"Tower Agahnim 1", "Ice Lobby", "Sewers Rat Path", "PoD Falling Bridge",
|
||||
@@ -1855,14 +1864,14 @@ bunny_impassible_doors = {
|
||||
'PoD Arena Landing Bonk Path', 'PoD Sexy Statue NW', 'PoD Map Balcony Drop Down',
|
||||
'PoD Mimics 1 NW', 'PoD Falling Bridge Path N', 'PoD Falling Bridge Path S',
|
||||
'PoD Mimics 2 NW', 'PoD Bow Statue Down Ladder', 'PoD Dark Pegs Landing to Right',
|
||||
'PoD Dark Pegs Left to Middle Barrier - Blue', 'PoD Dark Pegs Left to Ranged Crystal',
|
||||
'PoD Dark Pegs Left to Middle Barrier - Blue', 'PoD Dark Pegs Left to Ranged Crystal',
|
||||
'PoD Turtle Party ES', 'PoD Turtle Party NW', 'PoD Callback Warp', 'Swamp Lobby Moat', 'Swamp Entrance Moat',
|
||||
'Swamp Trench 1 Approach Swim Depart', 'Swamp Trench 1 Approach Key', 'Swamp Trench 1 Key Approach',
|
||||
'Swamp Trench 1 Key Ledge Depart', 'Swamp Trench 1 Departure Approach', 'Swamp Trench 1 Departure Key',
|
||||
'Swamp Hub Hook Path', 'Swamp Shortcut Blue Barrier', 'Swamp Trench 2 Pots Blue Barrier',
|
||||
'Swamp Trench 2 Pots Wet', 'Swamp Trench 2 Departure Wet', 'Swamp West Ledge Hook Path', 'Swamp Barrier Ledge Hook Path',
|
||||
'Swamp Attic Left Pit', 'Swamp Attic Right Pit', 'Swamp Push Statue NW', 'Swamp Push Statue NE',
|
||||
'Swamp Drain Right Switch', 'Swamp Waterway NE', 'Swamp Waterway N', 'Swamp Waterway NW',
|
||||
'Swamp Drain Right Switch', 'Swamp Waterway NE', 'Swamp Waterway N', 'Swamp Waterway NW',
|
||||
'Skull Pot Circle WN', 'Skull Pot Circle Star Path', 'Skull Pull Switch S', 'Skull Big Chest N',
|
||||
'Skull Big Chest Hookpath', 'Skull 2 East Lobby NW', 'Skull Back Drop Star Path', 'Skull 2 West Lobby NW',
|
||||
'Skull 3 Lobby EN', 'Skull Star Pits SW', 'Skull Star Pits ES', 'Skull Torch Room WN', 'Skull Vines NW',
|
||||
@@ -1897,7 +1906,7 @@ bunny_impassible_doors = {
|
||||
'GT Double Switch Exit to Blue Barrier', 'GT Firesnake Room Hook Path', 'GT Falling Bridge WN', 'GT Falling Bridge WS',
|
||||
'GT Ice Armos NE', 'GT Ice Armos WS', 'GT Crystal Paths SW', 'GT Mimics 1 NW', 'GT Mimics 1 ES', 'GT Mimics 2 WS',
|
||||
'GT Mimics 2 NE', 'GT Hidden Spikes EN', 'GT Cannonball Bridge SE', 'GT Gauntlet 1 WN', 'GT Gauntlet 2 EN',
|
||||
'GT Gauntlet 2 SW', 'GT Gauntlet 3 NW', 'GT Gauntlet 3 SW', 'GT Gauntlet 4 NW', 'GT Gauntlet 4 SW',
|
||||
'GT Gauntlet 2 SW', 'GT Gauntlet 3 NW', 'GT Gauntlet 3 SW', 'GT Gauntlet 4 NW', 'GT Gauntlet 4 SW',
|
||||
'GT Gauntlet 5 NW', 'GT Gauntlet 5 WS', 'GT Lanmolas 2 ES', 'GT Lanmolas 2 NW', 'GT Wizzrobes 1 SW',
|
||||
'GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE', 'GT Torch Cross ES', 'GT Falling Torches NE', 'GT Moldorm Gap',
|
||||
'GT Validation Block Path'
|
||||
@@ -2047,7 +2056,7 @@ def create_key_rule(small_key_name, player, keys):
|
||||
|
||||
def create_key_rule_allow_small(small_key_name, player, keys, location):
|
||||
loc = location.name
|
||||
return lambda state: state.has_sm_key(small_key_name, player, keys) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys-1))
|
||||
return lambda state: state.has_sm_key(small_key_name, player, keys) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys - 1))
|
||||
|
||||
|
||||
def create_key_rule_bk_exception(small_key_name, big_key_name, player, keys, bk_keys, bk_locs):
|
||||
@@ -2058,7 +2067,7 @@ def create_key_rule_bk_exception(small_key_name, big_key_name, player, keys, bk_
|
||||
def create_key_rule_bk_exception_or_allow(small_key_name, big_key_name, player, keys, location, bk_keys, bk_locs):
|
||||
loc = location.name
|
||||
chest_names = [x.name for x in bk_locs]
|
||||
return lambda state: (state.has_sm_key(small_key_name, player, keys) and not item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names)))) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys-1)) or (item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names))) and state.has_sm_key(small_key_name, player, bk_keys))
|
||||
return lambda state: (state.has_sm_key(small_key_name, player, keys) and not item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names)))) or (item_name(state, loc, player) in [(small_key_name, player)] and state.has_sm_key(small_key_name, player, keys - 1)) or (item_in_locations(state, big_key_name, player, zip(chest_names, [player] * len(chest_names))) and state.has_sm_key(small_key_name, player, bk_keys))
|
||||
|
||||
|
||||
def create_advanced_key_rule(key_logic, player, rule):
|
||||
|
||||
@@ -29,6 +29,9 @@ BCS OWDetectTransitionReturn
|
||||
org $02a999
|
||||
jsl OWEdgeTransition : nop #4 ;LDA $02A4E3,X : ORA $7EF3CA
|
||||
|
||||
org $02aa07
|
||||
JSL OWMarkVisited : NOP
|
||||
|
||||
org $04e8ae
|
||||
JSL OWDetectSpecialTransition
|
||||
RTL : NOP
|
||||
@@ -169,11 +172,6 @@ plb : rtl
|
||||
nop #3
|
||||
+
|
||||
|
||||
; follower hooks
|
||||
;org $8689D9
|
||||
;SpritePrep_BombShoppe:
|
||||
;JML BombShoppe_ConditionalSpawn : NOP
|
||||
|
||||
;Code
|
||||
org $aa8800
|
||||
OWTransitionDirection:
|
||||
@@ -345,6 +343,16 @@ OWOldManSpeed:
|
||||
lda #$0c : sta $5e ; what we wrote over
|
||||
rtl
|
||||
}
|
||||
OWMarkVisited:
|
||||
{
|
||||
LDX.b $8A : STZ.w $0412 ; what we wrote over
|
||||
LDA.b $10 : CMP.b #$14 : BCS .return
|
||||
LDA.l OverworldEventDataWRAM,X
|
||||
ORA.b #$80 : STA.l OverworldEventDataWRAM,X
|
||||
|
||||
.return
|
||||
RTL
|
||||
}
|
||||
|
||||
LoadMapDarkOrMixed:
|
||||
{
|
||||
@@ -541,7 +549,6 @@ OWBonkDrops:
|
||||
INX : LDA.w OWBonkPrizeData,X : PHX : PHA ; S = FlagBitmask, X (row + 2)
|
||||
LDX.b $8A : LDA.l OverworldEventDataWRAM,X : AND 1,S : PHA : BNE + ; S = Collected, FlagBitmask, X (row + 2)
|
||||
LDA.b #$1B : STA $12F ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx
|
||||
; JSLSpriteSFX_QueueSFX3WithPan
|
||||
+
|
||||
LDA 3,S : TAX : INX : LDA.w OWBonkPrizeData,X
|
||||
PHA : INX : LDA.w OWBonkPrizeData,X : BEQ +
|
||||
@@ -873,7 +880,6 @@ OWNewDestination:
|
||||
++ lda $84 : !add 1,s : sta $84 : pla : pla
|
||||
|
||||
.adjustMainAxis
|
||||
;LDA $84 : SEC : SBC #$0400 : AND #$0F80 : ASL : XBA : STA $88 ; vram
|
||||
LDA $84 : SEC : SBC #$0400 : AND #$0F00 : ASL : XBA : STA $88 ; vram
|
||||
LDA $84 : SEC : SBC #$0010 : AND #$003E : LSR : STA $86
|
||||
|
||||
@@ -936,7 +942,6 @@ OWNewDestination:
|
||||
sep #$30 : lda $04 : and #$3f : !add OWOppSlotOffset,y : asl : sta $700
|
||||
|
||||
; crossed OW shuffle and terrain
|
||||
;lda $8a : JSR OWDetermineScreensPaletteSet : STX $04
|
||||
ldx $05 : ldy $08 : jsr OWWorldTerrainUpdate
|
||||
|
||||
ldx $8a : lda $05 : sta $8a : stx $05 ; $05 is prev screen id, $8a is dest screen
|
||||
@@ -1161,14 +1166,6 @@ OWEndScrollTransition:
|
||||
RTL
|
||||
}
|
||||
|
||||
; BombShoppe_ConditionalSpawn:
|
||||
; {
|
||||
; nop
|
||||
; INC.w $0BA0,X : LDA.b #$B5 ; what we wrote over
|
||||
; JML SpritePrep_BombShoppe+5
|
||||
; nop#20
|
||||
; }
|
||||
|
||||
;Data
|
||||
org $aaa000
|
||||
OWEdgeOffsets:
|
||||
|
||||
Binary file not shown.
@@ -269,3 +269,6 @@
|
||||
shuffle_sfx:
|
||||
on: 1
|
||||
off: 1
|
||||
shuffle_songinstruments:
|
||||
on: 1
|
||||
off: 1
|
||||
|
||||
@@ -199,3 +199,6 @@ rom:
|
||||
shuffle_sfx:
|
||||
on: 1
|
||||
off: 1
|
||||
shuffle_songinstruments:
|
||||
on: 1
|
||||
off: 1
|
||||
|
||||
@@ -347,6 +347,10 @@
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
},
|
||||
"shuffle_songinstruments": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
},
|
||||
"msu_resume": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
|
||||
@@ -425,6 +425,7 @@
|
||||
],
|
||||
"reduce_flashing": [ "Reduce some in-game flashing (default: %(default)s)" ],
|
||||
"shuffle_sfx": [ "Shuffle sounds effects (default: %(default)s)" ],
|
||||
"shuffle_songinstruments": [ "Shuffle song instruments (default: %(default)s)" ],
|
||||
"msu_resume": [ "Enable MSU Resume (default: %(default)s)" ],
|
||||
"create_rom": [ "Create an output rom file. (default: %(default)s)" ],
|
||||
"gui": [ "Launch the GUI. (default: %(default)s)" ],
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"msu_resume": { "type": "checkbox" },
|
||||
"quickswap": { "type": "checkbox" },
|
||||
"reduce_flashing": {"type": "checkbox" },
|
||||
"shuffle_sfx": {"type": "checkbox" }
|
||||
"shuffle_sfx": {"type": "checkbox" },
|
||||
"shuffle_songinstruments": {"type": "checkbox" }
|
||||
},
|
||||
"leftAdjustFrame": {
|
||||
"heartcolor": {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"adjust.quickswap": "L/R Quickswapping",
|
||||
"adjust.reduce_flashing": "Reduce Flashing",
|
||||
"adjust.shuffle_sfx": "Shuffle Sound Effects",
|
||||
"adjust.shuffle_songinstruments": "Shuffle Song Instruments",
|
||||
"adjust.msu_resume": "MSU Resume",
|
||||
|
||||
"adjust.heartcolor": "Heart Color",
|
||||
@@ -190,6 +191,7 @@
|
||||
"randomizer.gameoptions.quickswap": "L/R Quickswapping",
|
||||
"randomizer.gameoptions.reduce_flashing": "Reduce Flashing",
|
||||
"randomizer.gameoptions.shuffle_sfx": "Shuffle Sound Effects",
|
||||
"randomizer.gameoptions.shuffle_songinstruments": "Shuffle Song Instruments",
|
||||
"randomizer.gameoptions.msu_resume": "MSU Resume",
|
||||
|
||||
"randomizer.gameoptions.heartcolor": "Heart Color",
|
||||
@@ -391,7 +393,7 @@
|
||||
"bottom.content.dialog.error": "Error while creating seed",
|
||||
"bottom.content.dialog.success": "Success",
|
||||
"bottom.content.dialog.success.message": "Rom created successfully.",
|
||||
"bottom.content.outputdir": "Open Output Directory",
|
||||
"bottom.content.outputdir": "Select Destination",
|
||||
"bottom.content.docs": "Open Documentation"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"msu_resume": { "type": "checkbox" },
|
||||
"quickswap": { "type": "checkbox" },
|
||||
"reduce_flashing": { "type": "checkbox" },
|
||||
"shuffle_sfx": { "type": "checkbox" }
|
||||
"shuffle_sfx": { "type": "checkbox" },
|
||||
"shuffle_songinstruments": { "type": "checkbox" }
|
||||
},
|
||||
"leftRomOptionsFrame": {
|
||||
"heartcolor": {
|
||||
|
||||
@@ -183,6 +183,7 @@ class CustomSettings(object):
|
||||
args.ow_palettes[p] = get_setting(settings['ow_palettes'], args.ow_palettes[p])
|
||||
args.uw_palettes[p] = get_setting(settings['uw_palettes'], args.uw_palettes[p])
|
||||
args.shuffle_sfx[p] = get_setting(settings['shuffle_sfx'], args.shuffle_sfx[p])
|
||||
args.shuffle_songinstruments[p] = get_setting(settings['shuffle_songinstruments'], args.shuffle_songinstruments[p])
|
||||
args.msu_resume[p] = get_setting(settings['msu_resume'], args.msu_resume[p])
|
||||
|
||||
def get_item_pool(self):
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from aenum import IntEnum
|
||||
import random
|
||||
from Utils import int16_as_bytes, snes_to_pc
|
||||
|
||||
|
||||
class SFX(object):
|
||||
|
||||
def __init__(self, name, sfx_set, orig_id, addr, chain, accomp=False):
|
||||
self.name = name
|
||||
self.sfx_set = sfx_set
|
||||
@@ -16,6 +16,68 @@ class SFX(object):
|
||||
self.target_id = None
|
||||
self.target_chain = None
|
||||
|
||||
class MusicType(IntEnum):
|
||||
NONE = 0x00,
|
||||
Ambient = 0x01,
|
||||
Melody = 0x02,
|
||||
Rhythm = 0x04,
|
||||
Beat = 0x08
|
||||
|
||||
class Instrument(object):
|
||||
def __init__(self, name, id, srcn, adsr, gain, mult):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.srcn = srcn
|
||||
self.adsr = adsr
|
||||
self.gain = gain
|
||||
self.mult = mult
|
||||
|
||||
self.target_id = None
|
||||
|
||||
class SFXInstrument(Instrument):
|
||||
pass
|
||||
|
||||
class SPCInstrument(Instrument):
|
||||
def __init__(self, name, srcn, adsr, gain, mult, min=9999, max=0):
|
||||
Instrument.__init__(self, name, srcn, srcn, adsr, gain, mult)
|
||||
|
||||
self.type = MusicType.NONE
|
||||
self.primary_type = MusicType.NONE
|
||||
self.replacements = []
|
||||
|
||||
def add_type(self, type, force_primary):
|
||||
if force_primary or self.type == MusicType.NONE:
|
||||
self.primary_type |= type
|
||||
self.type |= type
|
||||
|
||||
def amb(self, force_primary=False):
|
||||
self.add_type(MusicType.Ambient, force_primary)
|
||||
return self
|
||||
|
||||
def mel(self, force_primary=False):
|
||||
self.add_type(MusicType.Melody, force_primary)
|
||||
return self
|
||||
|
||||
def bass(self, force_primary=False):
|
||||
self.add_type(MusicType.Rhythm, force_primary)
|
||||
return self
|
||||
|
||||
def beat(self, force_primary=False):
|
||||
self.add_type(MusicType.Beat, force_primary)
|
||||
return self
|
||||
|
||||
class InstrumentChange(object):
|
||||
def __init__(self, song_id, segment_id, tracks, orig_instrument, type=MusicType.NONE, ban=[]):
|
||||
self.song_id = song_id
|
||||
self.segment_id = segment_id
|
||||
self.tracks = tracks
|
||||
self.orig_instrument = orig_instrument
|
||||
|
||||
self.type = type
|
||||
self.banned_list = ban
|
||||
|
||||
self.target_instrument = None
|
||||
|
||||
|
||||
def init_sfx_data():
|
||||
sfx_pool = [SFX('Slash1', 0x02, 0x01, 0x2614, []), SFX('Slash2', 0x02, 0x02, 0x2625, []),
|
||||
@@ -178,3 +240,694 @@ def randomize_sfx(rom):
|
||||
last = chained
|
||||
rom.write_byte(ac_base + last - 1, 0)
|
||||
|
||||
|
||||
def output_song_data(rom, filepath, outfilebase):
|
||||
with open(filepath, 'w') as outfile:
|
||||
last_song = 0
|
||||
last_segment = -1
|
||||
outfile.write(f'{outfilebase}\n')
|
||||
for change in spc_instrument_changes:
|
||||
if last_song != change.song_id:
|
||||
last_song = change.song_id
|
||||
last_segment = change.segment_id
|
||||
outfile.write(f'\nSong{change.song_id:02X}.{change.segment_id:02X}.')
|
||||
elif last_segment != change.segment_id:
|
||||
last_segment = change.segment_id
|
||||
outfile.write(f'\n {change.segment_id:02X}.')
|
||||
else:
|
||||
outfile.write(f'\n ')
|
||||
tracks = 8
|
||||
for track_id in change.tracks.keys():
|
||||
outfile.write(f'{track_id:01X}')
|
||||
tracks -= 1
|
||||
if tracks > 0:
|
||||
outfile.write(' ' * tracks)
|
||||
outfile.write(f' = {rom.read_byte(snes_to_pc(next(iter(change.tracks.values()))[0])):02X}')
|
||||
|
||||
|
||||
def randomize_songinstruments(rom):
|
||||
# categorize instruments in pools
|
||||
ambients, melodies, rhythms, beats = [], [], [], []
|
||||
inst_lists = {
|
||||
MusicType.Ambient: ambients,
|
||||
MusicType.Melody: melodies,
|
||||
MusicType.Rhythm: rhythms,
|
||||
MusicType.Beat: beats
|
||||
}
|
||||
for instrument in spc_instruments.values():
|
||||
for ins, lst in inst_lists.items():
|
||||
if instrument.type & ins > 0:
|
||||
lst.append(instrument)
|
||||
for instrument in spc_instruments.values():
|
||||
for ins, lst in inst_lists.items():
|
||||
if instrument.primary_type & ins > 0:
|
||||
instrument.replacements += [i for i in lst if i not in instrument.replacements]
|
||||
|
||||
# randomize each instrument change
|
||||
for change in spc_instrument_changes:
|
||||
if type(change.type) is list:
|
||||
candidates = [spc_instruments[i] for i in change.type]
|
||||
elif change.type != MusicType.NONE:
|
||||
candidates = []
|
||||
for ins, lst in inst_lists.items():
|
||||
if change.type & ins > 0:
|
||||
candidates += [i for i in lst if i not in candidates]
|
||||
else:
|
||||
candidates = spc_instruments[change.orig_instrument].replacements
|
||||
candidates = [i for i in candidates if i.id not in change.banned_list]
|
||||
change.target_instrument = random.choice(candidates).id
|
||||
|
||||
for change in spc_instrument_changes:
|
||||
for track_addresses in change.tracks.values():
|
||||
for addr in track_addresses:
|
||||
rom.write_byte(snes_to_pc(addr), change.target_instrument)
|
||||
|
||||
|
||||
sfx_instruments = { # table @ $1A9C04
|
||||
0x00: SFXInstrument("Fwoosh", 0x00, 0x00, [0xF6, 0x6A], 0xB8, 0x03),
|
||||
0x01: SFXInstrument("Swish", 0x01, 0x01, [0x8E, 0xE0], 0xB8, 0x02),
|
||||
0x02: SFXInstrument("Bomp", 0x02, 0x14, [0xFE, 0x6A], 0xB8, 0x02),
|
||||
0x03: SFXInstrument("Ting", 0x03, 0x03, [0xFE, 0xF8], 0xB8, 0x0D),
|
||||
0x04: SFXInstrument("Rrrrr", 0x04, 0x04, [0xFE, 0x6A], 0x7F, 0x03),
|
||||
0x05: SFXInstrument("Clunk", 0x05, 0x02, [0xFE, 0x6A], 0x7F, 0x03),
|
||||
0x06: SFXInstrument("Ching", 0x06, 0x05, [0xFE, 0x6A], 0x70, 0x03),
|
||||
0x07: SFXInstrument("Fwomp", 0x07, 0x06, [0xFE, 0x6A], 0x70, 0x03),
|
||||
0x08: SFXInstrument("Squee", 0x08, 0x08, [0xFA, 0x6A], 0x70, 0x03),
|
||||
0x09: SFXInstrument("Unused", 0x09, 0x06, [0xFE, 0x6A], 0x70, 0x01),
|
||||
0x0A: SFXInstrument("Bzzzrt", 0x0A, 0x07, [0xFE, 0x6A], 0x70, 0x05),
|
||||
0x0B: SFXInstrument("Brrfft", 0x0B, 0x0B, [0xFE, 0x6A], 0xB8, 0x03),
|
||||
0x0C: SFXInstrument("Brrwwww", 0x0C, 0x0C, [0xFE, 0xE0], 0xB8, 0x02),
|
||||
0x0D: SFXInstrument("Twee", 0x0D, 0x0D, [0xF9, 0x6E], 0xB8, 0x03),
|
||||
0x0E: SFXInstrument("Pwing", 0x0E, 0x0E, [0xFE, 0xF5], 0xB8, 0x07),
|
||||
0x0F: SFXInstrument("Pling", 0x0F, 0x0F, [0xFE, 0xF5], 0xB8, 0x06),
|
||||
0x10: SFXInstrument("Chshtsh", 0x10, 0x01, [0xFE, 0xFC], 0xB8, 0x03),
|
||||
0x11: SFXInstrument("Splssh", 0x11, 0x10, [0x8E, 0xE0], 0xB8, 0x03),
|
||||
0x12: SFXInstrument("Weewoo", 0x12, 0x08, [0x8E, 0xE0], 0xB8, 0x02),
|
||||
0x13: SFXInstrument("Brbrbrb", 0x13, 0x14, [0x8E, 0xE0], 0xB8, 0x02),
|
||||
0x14: SFXInstrument("Bwow", 0x14, 0x0A, [0x88, 0xE0], 0xB8, 0x02),
|
||||
0x15: SFXInstrument("Uughf", 0x15, 0x17, [0x8E, 0xE0], 0xB8, 0x02),
|
||||
0x16: SFXInstrument("Aaaaaa", 0x16, 0x15, [0xFF, 0xE0], 0xB8, 0x04),
|
||||
0x17: SFXInstrument("Twing", 0x17, 0x03, [0xDF, 0x11], 0xB8, 0x0F),
|
||||
0x18: SFXInstrument("Whooo", 0x18, 0x01, [0x88, 0xE0], 0xB8, 0x01)
|
||||
}
|
||||
|
||||
spc_instruments = { # table @ $19FB1C
|
||||
0x00: SPCInstrument("Noise", 0x00, [0xFF, 0xE0], 0xB8, 0x0470),
|
||||
0x01: SPCInstrument("Rain", 0x01, [0xFF, 0xE0], 0xB8, 0x0790).amb(),
|
||||
0x02: SPCInstrument("Timpani", 0x02, [0xFF, 0xE0], 0xB8, 0x09C0).beat(),
|
||||
0x03: SPCInstrument("Square Wave", 0x03, [0xFF, 0xE0], 0xB8, 0x0400).bass().mel(),
|
||||
0x04: SPCInstrument("Saw Wave", 0x04, [0xFF, 0xE0], 0xB8, 0x0400).bass(),
|
||||
0x05: SPCInstrument("Clink", 0x05, [0xFF, 0xE0], 0xB8, 0x0470).amb(),
|
||||
0x06: SPCInstrument("Wobbly Lead", 0x06, [0xFF, 0xE0], 0xB8, 0x0470).amb(),
|
||||
0x07: SPCInstrument("Compound Saw", 0x07, [0xFF, 0xE0], 0xB8, 0x0470),
|
||||
0x08: SPCInstrument("Tweet", 0x08, [0xFF, 0xE0], 0xB8, 0x07A0).amb(),
|
||||
0x09: SPCInstrument("Strings A", 0x09, [0x8F, 0xE9], 0xB8, 0x01E0).mel().bass(True),
|
||||
0x0A: SPCInstrument("Strings B", 0x0A, [0x8A, 0xE9], 0xB8, 0x01E0).mel().bass(True),
|
||||
0x0B: SPCInstrument("Trombone", 0x0B, [0xFF, 0xE0], 0xB8, 0x0300).mel().bass(True).beat(),
|
||||
0x0C: SPCInstrument("Cymbal", 0x0C, [0xFF, 0xE0], 0xB8, 0x03A0).beat(),
|
||||
0x0D: SPCInstrument("Ocarina", 0x0D, [0xFF, 0xE0], 0xB8, 0x0100).bass(),
|
||||
0x0E: SPCInstrument("Chimes", 0x0E, [0xFF, 0xEF], 0xB8, 0x0EA0).amb(),
|
||||
0x0F: SPCInstrument("Harp", 0x0F, [0xFF, 0xEF], 0xB8, 0x0600).mel().bass(True).beat(),
|
||||
0x10: SPCInstrument("Splash", 0x10, [0xFF, 0xE0], 0xB8, 0x03D0).amb().beat(),
|
||||
0x11: SPCInstrument("Trumpet", 0x11, [0x8F, 0xE0], 0xB8, 0x0300).mel().bass(True),
|
||||
0x12: SPCInstrument("Horn", 0x12, [0x8F, 0xE0], 0xB8, 0x06F0).mel().bass(True),
|
||||
0x13: SPCInstrument("Snare A", 0x13, [0xFD, 0xE0], 0xB8, 0x07A0).beat(),
|
||||
0x14: SPCInstrument("Snare B", 0x14, [0xFF, 0xE0], 0xB8, 0x07A0).beat(),
|
||||
0x15: SPCInstrument("Choir", 0x15, [0xFF, 0xE0], 0xB8, 0x03D0).mel().bass(True),
|
||||
0x16: SPCInstrument("Flute", 0x16, [0x8F, 0xE0], 0xB8, 0x0300).mel().bass(True),
|
||||
0x17: SPCInstrument("Oof", 0x17, [0xFF, 0xE0], 0xB8, 0x02C0).amb().beat(True),
|
||||
0x18: SPCInstrument("Piano", 0x18, [0xFE, 0x8F], 0xB8, 0x06F0).mel().bass(True)
|
||||
}
|
||||
|
||||
Me = MusicType.Melody
|
||||
Rh = MusicType.Rhythm
|
||||
Be = MusicType.Beat
|
||||
Am = MusicType.Ambient
|
||||
|
||||
spc_instrument_changes = [
|
||||
InstrumentChange(0x01, 0x00, {0x00: [0x1A9F5B],
|
||||
0x01: [0x1A9F9D],
|
||||
0x02: [0x1A9FBB],
|
||||
0x03: [0x1A9FDA],
|
||||
0x04: [0x1A9FE8]}, 0x0F),
|
||||
InstrumentChange(0x01, 0x01, {0x00: [0x1ACA1A],
|
||||
0x01: [0x1ACA39],
|
||||
0x02: [0x1ACA5E],
|
||||
0x07: [0x1ACC01]}, 0x0B),
|
||||
InstrumentChange(0x01, 0x01, {0x03: [0x1ACAA3],
|
||||
0x04: [0x1ACAE2]}, 0x11),
|
||||
InstrumentChange(0x01, 0x01, {0x05: [0x1ACB25, 0x1ACC78]}, 0x02),
|
||||
InstrumentChange(0x01, 0x01, {0x05: [0x1ACB3A, 0x1ACC51],
|
||||
0x06: [0x1ACBA9, 0x1ACC7D]}, 0x13),
|
||||
InstrumentChange(0x01, 0x01, {0x06: [0x1ACB94, 0x1ACCA3]}, 0x0C),
|
||||
|
||||
InstrumentChange(0x02, 0x00, {0x00: [0x1AA04B],
|
||||
0x03: [0x1AA10E],
|
||||
0x04: [0x1AA143],
|
||||
0x07: [0x1AA1D1]}, 0x0B),
|
||||
InstrumentChange(0x02, 0x00, {0x01: [0x1AA087],
|
||||
0x05: [0x1AA176]}, 0x11),
|
||||
InstrumentChange(0x02, 0x00, {0x02: [0x1AA0CC],
|
||||
0x06: [0x1AA1BF]}, 0x13),
|
||||
InstrumentChange(0x02, 0x00, {0x06: [0x1AA1C7]}, 0x0C),
|
||||
InstrumentChange(0x02, 0x01, {0x02: [0x1AA27B]}, 0x13),
|
||||
InstrumentChange(0x02, 0x01, {0x03: [0x1AA2A2]}, 0x0A),
|
||||
InstrumentChange(0x02, 0x01, {0x04: [0x1AA2CD]}, 0x02),
|
||||
InstrumentChange(0x02, 0x01, {0x05: [0x1AA2E0],
|
||||
0x07: [0x1AA34D]}, 0x0B),
|
||||
InstrumentChange(0x02, 0x02, {0x00: [0x1AA5A8],
|
||||
0x05: [0x1AA449]}, 0x0B),
|
||||
InstrumentChange(0x02, 0x02, {0x03: [0x1AA3FF],
|
||||
0x04: [0x1AA42A]}, 0x0A),
|
||||
InstrumentChange(0x02, 0x02, {0x06: [0x1AA49E, 0x1AA4CB]}, 0x13),
|
||||
InstrumentChange(0x02, 0x02, {0x06: [0x1AA4C0, 0x1AA4EA]}, 0x0C),
|
||||
InstrumentChange(0x02, 0x02, {0x06: [0x1AA752]}, 0x02),
|
||||
|
||||
InstrumentChange(0x03, 0x00, {0x00: [0x1AA84A],
|
||||
0x01: [0x1AA864],
|
||||
0x03: [0x1AA885]}, 0x0A),
|
||||
InstrumentChange(0x03, 0x01, {0x00: [0x1AA89E],
|
||||
0x01: [0x1AA8B8],
|
||||
0x03: [0x1AA8D9]}, 0x12),
|
||||
InstrumentChange(0x03, 0x01, {0x02: [0x1AAB86],
|
||||
0x04: [0x1AA8F2],
|
||||
0x05: [0x1AA93C]}, 0x0A),
|
||||
|
||||
InstrumentChange(0x04, 0x00, {0x00: [0x1AACA3],
|
||||
0x01: [0x1AACB1],
|
||||
0x02: [0x1AACC7]}, 0x12),
|
||||
InstrumentChange(0x04, 0x01, {0x00: [0x1AABF5],
|
||||
0x01: [0x1AAC0B]}, 0x12),
|
||||
InstrumentChange(0x04, 0x01, {0x02: [0x1AAC21]}, 0x12),
|
||||
InstrumentChange(0x04, 0x02, {0x01: [0x1AAC55],
|
||||
0x02: [0x1AAC6B]}, 0x12),
|
||||
InstrumentChange(0x04, 0x03, {0x00: [0x1AAD93],
|
||||
0x01: [0x1AACED],
|
||||
0x02: [0x1AAD07],
|
||||
0x03: [0x1AAD75],
|
||||
0x04: [0x1AADB1]}, 0x12),
|
||||
|
||||
InstrumentChange(0x05, 0x00, {0x00: [0x1AAE3F],
|
||||
0x02: [0x1AAE72],
|
||||
0x03: [0x1AAEAD],
|
||||
0x07: [0x1AAF02]}, 0x0A),
|
||||
InstrumentChange(0x05, 0x00, {0x01: [0x1AAE64]}, 0x09),
|
||||
InstrumentChange(0x05, 0x00, {0x04: [0x1AAEE8]}, 0x16),
|
||||
InstrumentChange(0x05, 0x01, {0x00: [0x1AB156],
|
||||
0x03: [0x1AAF48],
|
||||
0x04: [0x1AAF71],
|
||||
0x07: [0x1AB1D3]}, 0x0A),
|
||||
InstrumentChange(0x05, 0x01, {0x02: [0x1AB186]}, 0x16),
|
||||
InstrumentChange(0x05, 0x02, {0x00: [0x1AB088],
|
||||
0x03: [0x1AB0CF],
|
||||
0x04: [0x1AB0F8],
|
||||
0x07: [0x1AB11F]}, 0x0A),
|
||||
InstrumentChange(0x05, 0x02, {0x02: [0x1AB0A7]}, 0x16),
|
||||
|
||||
InstrumentChange(0x06, 0x00, {0x00: [0x1AB338]}, 0x0A),
|
||||
InstrumentChange(0x06, 0x01, {0x01: [0x1AB68F],
|
||||
0x02: [0x1AB69D],
|
||||
0x03: [0x1AB6B2],
|
||||
0x05: [0x1AB3D7]}, 0x0A),
|
||||
InstrumentChange(0x06, 0x02, {0x00: [0x1AB622],
|
||||
0x01: [0x1AB63A],
|
||||
0x02: [0x1AB648],
|
||||
0x03: [0x1AB670],
|
||||
0x04: [0x1AB6C4],
|
||||
0x05: [0x1AB49D]}, 0x0A),
|
||||
InstrumentChange(0x06, 0x03, {0x05: [0x1AB548]}, 0x0A),
|
||||
InstrumentChange(0x06, 0x04, {0x00: [0x1AB722],
|
||||
0x01: [0x1AB739],
|
||||
0x02: [0x1AB745],
|
||||
0x03: [0x1AB759],
|
||||
0x04: [0x1AB765],
|
||||
0x05: [0x1AB5E3]}, 0x0A),
|
||||
|
||||
InstrumentChange(0x07, 0x00, {0x00: [0x1ABB1F]}, 0x0A),
|
||||
InstrumentChange(0x07, 0x00, {0x01: [0x1ABB31],
|
||||
0x02: [0x1ABBE6],
|
||||
0x03: [0x1ABC0B]}, 0x09),
|
||||
InstrumentChange(0x07, 0x00, {0x04: [0x1ABB53, 0x1AB8C9]}, 0x16),
|
||||
InstrumentChange(0x07, 0x01, {0x04: [0x1AB8E6]}, 0x0E, type=Am|Me|Rh, ban=[0x06]),
|
||||
InstrumentChange(0x07, 0x01, {0x05: [0x1AB8EB]}, 0x0A),
|
||||
InstrumentChange(0x07, 0x02, {0x04: [0x1AB981]}, 0x16),
|
||||
InstrumentChange(0x07, 0x03, {0x02: [0x1ABC37],
|
||||
0x03: [0x1ABC66]}, 0x09),
|
||||
InstrumentChange(0x07, 0x03, {0x04: [0x1ABA09]}, 0x16),
|
||||
InstrumentChange(0x07, 0x03, {0x05: [0x1ABC8F]}, 0x0A),
|
||||
InstrumentChange(0x07, 0x05, {0x02: [0x1ABC9D],
|
||||
0x03: [0x1ABCBA]}, 0x09),
|
||||
InstrumentChange(0x07, 0x05, {0x05: [0x1ABCD1]}, 0x0A),
|
||||
InstrumentChange(0x07, 0x06, {0x00: [0x1ABB72]}, 0x0A),
|
||||
InstrumentChange(0x07, 0x06, {0x01: [0x1ABB83],
|
||||
0x02: [0x1ABB95],
|
||||
0x03: [0x1ABBAA]}, 0x09),
|
||||
InstrumentChange(0x07, 0x06, {0x04: [0x1ABBBD]}, 0x16),
|
||||
InstrumentChange(0x07, 0x06, {0x05: [0x1ABCE6]}, 0x0A),
|
||||
|
||||
InstrumentChange(0x08, 0x00, {0x00: [0x1ABD3A],
|
||||
0x01: [0x1ABD5B]}, 0x06, type=Me|Rh|Am),
|
||||
InstrumentChange(0x08, 0x00, {0x02: [0x1ABD70],
|
||||
0x05: [0x1ABE06]}, 0x0F),
|
||||
InstrumentChange(0x08, 0x00, {0x03: [0x1ABDAC]}, 0x0A),
|
||||
InstrumentChange(0x08, 0x00, {0x04: [0x1ABDC8]}, 0x01),
|
||||
InstrumentChange(0x08, 0x00, {0x06: [0x1ABE3A]}, 0x09),
|
||||
|
||||
InstrumentChange(0x09, 0x00, {0x00: [0x1AC25A],
|
||||
0x05: [0x1AC28E]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x00, {0x01: [0x1AC26E]}, 0x14),
|
||||
InstrumentChange(0x09, 0x01, {0x01: [0x1ABF0A]}, 0x14),
|
||||
InstrumentChange(0x09, 0x01, {0x06: [0x1ABF43]}, 0x09),
|
||||
InstrumentChange(0x09, 0x02, {0x00: [0x1AC450],
|
||||
0x05: [0x1AC56D],
|
||||
0x07: [0x1AC595]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x02, {0x01: [0x1AC2AF]}, 0x14),
|
||||
InstrumentChange(0x09, 0x02, {0x03: [0x1AC4B3],
|
||||
0x04: [0x1AC510]}, 0x11),
|
||||
InstrumentChange(0x09, 0x02, {0x06: [0x1AC2E9]}, 0x09),
|
||||
InstrumentChange(0x09, 0x03, {0x00: [0x1ABF63]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x03, {0x01: [0x1ABF80]}, 0x14),
|
||||
InstrumentChange(0x09, 0x03, {0x03: [0x1ABFA4]}, 0x11),
|
||||
InstrumentChange(0x09, 0x03, {0x05: [0x1AC01C]}, 0x16),
|
||||
InstrumentChange(0x09, 0x04, {0x00: [0x1AC04D]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x04, {0x01: [0x1AC05D]}, 0x14),
|
||||
InstrumentChange(0x09, 0x04, {0x02: [0x1AC5CF]}, 0x18),
|
||||
InstrumentChange(0x09, 0x04, {0x03: [0x1AC085],
|
||||
0x04: [0x1AC5ED]}, 0x11),
|
||||
InstrumentChange(0x09, 0x04, {0x05: [0x1AC137]}, 0x16),
|
||||
InstrumentChange(0x09, 0x04, {0x06: [0x1AC146]}, 0x12),
|
||||
InstrumentChange(0x09, 0x05, {0x00: [0x1AC178],
|
||||
0x07: [0x1AC229]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x05, {0x01: [0x1AC196]}, 0x14),
|
||||
InstrumentChange(0x09, 0x05, {0x02: [0x1AC19E]}, 0x18),
|
||||
InstrumentChange(0x09, 0x05, {0x03: [0x1AC1D3],
|
||||
0x04: [0x1AC1F4]}, 0x12),
|
||||
InstrumentChange(0x09, 0x06, {0x00: [0x1AC317],
|
||||
0x07: [0x1AC3ED]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x06, {0x01: [0x1AC332]}, 0x14),
|
||||
InstrumentChange(0x09, 0x06, {0x02: [0x1AC33A]}, 0x18),
|
||||
InstrumentChange(0x09, 0x06, {0x03: [0x1AC36F],
|
||||
0x04: [0x1AC3A4],
|
||||
0x05: [0x1AC3D9]}, 0x12),
|
||||
InstrumentChange(0x09, 0x07, {0x00: [0x1AC40A],
|
||||
0x05: [0x1AC43C]}, 0x0A),
|
||||
InstrumentChange(0x09, 0x07, {0x01: [0x1AC41C]}, 0x14),
|
||||
InstrumentChange(0x09, 0x07, {0x02: [0x1AC492]}, 0x18),
|
||||
InstrumentChange(0x09, 0x07, {0x03: [0x1AC680],
|
||||
0x04: [0x1AC6C1]}, 0x11),
|
||||
|
||||
InstrumentChange(0x0A, 0x00, {0x00: [0x1AC72F],
|
||||
0x01: [0x1AC751],
|
||||
0x02: [0x1AC772],
|
||||
0x03: [0x1AC793]}, 0x0F),
|
||||
InstrumentChange(0x0A, 0x00, {0x00: [0x1AC740],
|
||||
0x01: [0x1AC765],
|
||||
0x02: [0x1AC786],
|
||||
0x03: [0x1AC7A7],
|
||||
0x04: [0x1AC7B4, 0x1AC7C9],
|
||||
0x05: [0x1AC7D1]}, 0x09),
|
||||
|
||||
InstrumentChange(0x0B, 0x00, {0x00: [0x1A9EEC, 0x1A9D26]}, 0x0F, ban=[0x0B]),
|
||||
InstrumentChange(0x0B, 0x01, {0x01: [0x1A9D3F],
|
||||
0x02: [0x1A9D5A],
|
||||
0x03: [0x1A9D75],
|
||||
0x04: [0x1A9D90],
|
||||
0x05: [0x1A9DBB],
|
||||
0x06: [0x1A9DE9]}, 0x0F),
|
||||
|
||||
InstrumentChange(0x0C, 0x00, {0x00: [0x1AC83A],
|
||||
0x01: [0x1AC84A],
|
||||
0x02: [0x1AC857],
|
||||
0x03: [0x1AC864],
|
||||
0x04: [0x1AC871],
|
||||
0x05: [0x1AC87E]}, 0x0B),
|
||||
InstrumentChange(0x0C, 0x01, {0x02: [0x1AC89A],
|
||||
0x03: [0x1AC8AD]}, 0x11),
|
||||
InstrumentChange(0x0C, 0x01, {0x04: [0x1AC8B7]}, 0x0E),
|
||||
InstrumentChange(0x0C, 0x01, {0x05: [0x1AC8C3]}, 0x02),
|
||||
InstrumentChange(0x0C, 0x02, {0x02: [0x1AC8E0],
|
||||
0x03: [0x1AC8F3]}, 0x11),
|
||||
InstrumentChange(0x0C, 0x02, {0x04: [0x1AC8FD]}, 0x0E),
|
||||
InstrumentChange(0x0C, 0x02, {0x05: [0x1AC909]}, 0x02),
|
||||
|
||||
InstrumentChange(0x0D, 0x00, {0x00: [0x1AD003],
|
||||
0x03: [0x1AD02C],
|
||||
0x04: [0x1AD03A]}, 0x11),
|
||||
InstrumentChange(0x0D, 0x00, {0x01: [0x1AD010]}, 0x02),
|
||||
InstrumentChange(0x0D, 0x00, {0x02: [0x1AD07F]}, 0x14),
|
||||
InstrumentChange(0x0D, 0x01, {0x00: [0x1ACD10],
|
||||
0x04: [0x1ACD9A]}, 0x0B),
|
||||
InstrumentChange(0x0D, 0x01, {0x01: [0x1ACD41]}, 0x02),
|
||||
InstrumentChange(0x0D, 0x01, {0x03: [0x1ACD7F],
|
||||
0x05: [0x1ACDCA]}, 0x11),
|
||||
InstrumentChange(0x0D, 0x03, {0x00: [0x1ACE8E],
|
||||
0x01: [0x1ACEB8]}, 0x0A),
|
||||
InstrumentChange(0x0D, 0x03, {0x02: [0x1ACED4]}, 0x14),
|
||||
InstrumentChange(0x0D, 0x03, {0x03: [0x1ACEE0],
|
||||
0x04: [0x1ACF07]}, 0x11),
|
||||
InstrumentChange(0x0D, 0x04, {0x05: [0x1ACFE3]}, 0x02),
|
||||
|
||||
InstrumentChange(0x0E, 0x00, {0x00: [0x1AD29C]}, 0x16),
|
||||
InstrumentChange(0x0E, 0x00, {0x01: [0x1AD2AD],
|
||||
0x03: [0x1AD2CB],
|
||||
0x04: [0x1AD2D9]}, 0x18),
|
||||
InstrumentChange(0x0E, 0x00, {0x02: [0x1AD2BB]}, 0x12),
|
||||
InstrumentChange(0x0E, 0x01, {0x00: [0x1AD1A6]}, 0x16),
|
||||
InstrumentChange(0x0E, 0x01, {0x01: [0x1AD1AF],
|
||||
0x03: [0x1AD1CD]}, 0x18),
|
||||
InstrumentChange(0x0E, 0x01, {0x02: [0x1AD1C5]}, 0x0A),
|
||||
InstrumentChange(0x0E, 0x02, {0x00: [0x1AD24C]}, 0x16),
|
||||
InstrumentChange(0x0E, 0x02, {0x01: [0x1AD255],
|
||||
0x03: [0x1AD273]}, 0x18),
|
||||
InstrumentChange(0x0E, 0x02, {0x02: [0x1AD26B]}, 0x0A),
|
||||
InstrumentChange(0x0E, 0x03, {0x00: [0x1AD1E4],
|
||||
0x01: [0x1AD1ED],
|
||||
0x03: [0x1AD212],
|
||||
0x04: [0x1AD22F]}, 0x18),
|
||||
InstrumentChange(0x0E, 0x03, {0x02: [0x1AD20A]}, 0x12),
|
||||
|
||||
InstrumentChange(0x10, 0x00, {0x00: [0x1B816D],
|
||||
0x02: [0x1B81A0],
|
||||
0x03: [0x1B81C0],
|
||||
0x07: [0x1B827F]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x00, {0x01: [0x1B818C]}, 0x11),
|
||||
InstrumentChange(0x10, 0x00, {0x04: [0x1B81E0],
|
||||
0x05: [0x1B8220, 0x1B8229]}, 0x02),
|
||||
InstrumentChange(0x10, 0x00, {0x05: [0x1B8224]}, 0x0C),
|
||||
InstrumentChange(0x10, 0x00, {0x06: [0x1B825F]}, 0x16),
|
||||
InstrumentChange(0x10, 0x01, {0x00: [0x1B811F]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x01, {0x03: [0x1B813B],
|
||||
0x05: [0x1B814E]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x02, {0x00: [0x1B829E],
|
||||
0x05: [0x1B8310]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x02, {0x01: [0x1B82C0],
|
||||
0x03: [0x1B82E3],
|
||||
0x06: [0x1B8342]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x02, {0x04: [0x1B8308],
|
||||
0x04: [0x1B83F2]}, 0x02),
|
||||
InstrumentChange(0x10, 0x03, {0x00: [0x1B8360],
|
||||
0x02: [0x1B83AD],
|
||||
0x05: [0x1B83FA]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x03, {0x01: [0x1B8396],
|
||||
0x03: [0x1B83CC],
|
||||
0x06: [0x1B842E]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x04, {0x00: [0x1B844D],
|
||||
0x02: [0x1B84A0]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x04, {0x01: [0x1B847B],
|
||||
0x03: [0x1B84CD]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x04, {0x04: [0x1B84ED],
|
||||
0x05: [0x1B84F5]}, 0x02),
|
||||
InstrumentChange(0x10, 0x05, {0x00: [0x1B8548],
|
||||
0x01: [0x1B8575],
|
||||
0x03: [0x1B85B6]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x05, {0x02: [0x1B859B],
|
||||
0x07: [0x1B867F]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x05, {0x04: [0x1B85D0],
|
||||
0x05: [0x1B862C]}, 0x02),
|
||||
InstrumentChange(0x10, 0x06, {0x02: [0x1B8726],
|
||||
0x06: [0x1B8745]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x07, {0x00: [0x1B8768]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x07, {0x00: [0x1B8B04],
|
||||
0x01: [0x1B8B10],
|
||||
0x02: [0x1B8775],
|
||||
0x06: [0x1B87AD]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x07, {0x05: [0x1B8792]}, 0x16),
|
||||
InstrumentChange(0x10, 0x08, {0x02: [0x1B86B3]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x09, {0x00: [0x1B8A63],
|
||||
0x05: [0x1B8879],
|
||||
0x06: [0x1B8AED]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x09, {0x01: [0x1B8A87],
|
||||
0x02: [0x1B87E5]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x0A, {0x00: [0x1B88C8],
|
||||
0x02: [0x1B8946],
|
||||
0x03: [0x1B88E5]}, 0x0B),
|
||||
InstrumentChange(0x10, 0x0A, {0x01: [0x1B892C],
|
||||
0x07: [0x1B8905]}, 0x0A),
|
||||
InstrumentChange(0x10, 0x0A, {0x04: [0x1B897D]}, 0x02),
|
||||
|
||||
InstrumentChange(0x11, 0x00, {0x00: [0x1B8C95],
|
||||
0x01: [0x1B8CA2],
|
||||
0x02: [0x1B8CB1],
|
||||
0x03: [0x1B8CC0],
|
||||
0x04: [0x1B8CCF]}, 0x0A, type=Me, ban=[0x0D]),
|
||||
InstrumentChange(0x11, 0x01, {0x05: [0x1B8CFF]}, 0x0A, ban=[0x04]),
|
||||
InstrumentChange(0x11, 0x02, {0x03: [0x1B8D6B]}, 0x09),
|
||||
InstrumentChange(0x11, 0x04, {0x04: [0x1B8E2B]}, 0x11),
|
||||
InstrumentChange(0x11, 0x05, {0x05: [0x1B90F6]}, 0x11),
|
||||
|
||||
InstrumentChange(0x12, 0x00, {0x00: [0x1B9275],
|
||||
0x01: [0x1B9282],
|
||||
0x05: [0x1B92DE]}, 0x0A),
|
||||
InstrumentChange(0x12, 0x00, {0x02: [0x1B9290],
|
||||
0x03: [0x1B92AB]}, 0x11),
|
||||
InstrumentChange(0x12, 0x00, {0x04: [0x1B92C6]}, 0x02),
|
||||
InstrumentChange(0x12, 0x00, {0x05: [0x1B92D3]}, 0x10, type=[0x08, 0x10, 0x17]),
|
||||
InstrumentChange(0x12, 0x01, {0x00: [0x1B917D],
|
||||
0x01: [0x1B918A],
|
||||
0x05: [0x1B91E6],
|
||||
0x06: [0x1B9229]}, 0x0A),
|
||||
InstrumentChange(0x12, 0x01, {0x02: [0x1B9198],
|
||||
0x03: [0x1B91B3]}, 0x11),
|
||||
InstrumentChange(0x12, 0x01, {0x04: [0x1B91CE]}, 0x02),
|
||||
InstrumentChange(0x12, 0x01, {0x05: [0x1B91DB],
|
||||
0x06: [0x1B921E]}, 0x10, type=[0x08, 0x10, 0x17]),
|
||||
InstrumentChange(0x12, 0x02, {0x00: [0x1B9313],
|
||||
0x01: [0x1B9320],
|
||||
0x05: [0x1B937C],
|
||||
0x06: [0x1B93BF]}, 0x0A),
|
||||
InstrumentChange(0x12, 0x02, {0x02: [0x1B932E],
|
||||
0x03: [0x1B9349]}, 0x11),
|
||||
InstrumentChange(0x12, 0x02, {0x04: [0x1B9364]}, 0x02),
|
||||
InstrumentChange(0x12, 0x02, {0x05: [0x1B9371],
|
||||
0x06: [0x1B93B4]}, 0x10, type=[0x08, 0x10, 0x17]),
|
||||
|
||||
InstrumentChange(0x13, 0x00, {0x00: [0x1B9458],
|
||||
0x02: [0x1B94DA],
|
||||
0x03: [0x1B953E],
|
||||
0x04: [0x1B95A2],
|
||||
0x05: [0x1B9606]}, 0x0B),
|
||||
InstrumentChange(0x13, 0x00, {0x01: [0x1B94A4]}, 0x11),
|
||||
InstrumentChange(0x13, 0x00, {0x06: [0x1B9650],
|
||||
0x07: [0x1B9696]}, 0x0F),
|
||||
InstrumentChange(0x13, 0x00, {0x06: [0x1B967B],
|
||||
0x07: [0x1B96C0]}, 0x02),
|
||||
|
||||
InstrumentChange(0x14, 0x00, {0x00: [0x1B9901, 0x1B97A8]}, 0x15),
|
||||
InstrumentChange(0x14, 0x01, {0x01: [0x1B97C4],
|
||||
0x02: [0x1B97DE],
|
||||
0x03: [0x1B97FD],
|
||||
0x04: [0x1B9813],
|
||||
0x05: [0x1B982A]}, 0x15),
|
||||
|
||||
InstrumentChange(0x15, 0x00, {0x00: [0x1B9A32],
|
||||
0x01: [0x1B9A50],
|
||||
0x02: [0x1B9A6D],
|
||||
0x03: [0x1B9A8A]}, 0x0B),
|
||||
InstrumentChange(0x15, 0x00, {0x04: [0x1B9AA0]}, 0x02),
|
||||
InstrumentChange(0x15, 0x01, {0x00: [0x1B9971]}, 0x02),
|
||||
InstrumentChange(0x15, 0x01, {0x01: [0x1B9984],
|
||||
0x02: [0x1B99AA],
|
||||
0x03: [0x1B99D7]}, 0x0B),
|
||||
InstrumentChange(0x15, 0x01, {0x04: [0x1B9A04]}, 0x14),
|
||||
InstrumentChange(0x15, 0x02, {0x00: [0x1B9B45]}, 0x02),
|
||||
InstrumentChange(0x15, 0x02, {0x01: [0x1B9B58],
|
||||
0x02: [0x1B9B7E],
|
||||
0x03: [0x1B9BAB]}, 0x0B),
|
||||
InstrumentChange(0x15, 0x02, {0x04: [0x1B9BD8]}, 0x14),
|
||||
|
||||
InstrumentChange(0x16, 0x00, {0x00: [0x1B9CE6],
|
||||
0x01: [0x1B9CF1]}, 0x09),
|
||||
InstrumentChange(0x16, 0x01, {0x00: [0x1B9C82],
|
||||
0x01: [0x1B9C8B],
|
||||
0x02: [0x1B9C93],
|
||||
0x03: [0x1B9CAA]}, 0x09),
|
||||
InstrumentChange(0x16, 0x01, {0x04: [0x1B9CBA]}, 0x09),
|
||||
InstrumentChange(0x16, 0x02, {0x00: [0x1B9CFB],
|
||||
0x01: [0x1B9D44]}, 0x09),
|
||||
InstrumentChange(0x16, 0x03, {0x00: [0x1B9DBE],
|
||||
0x01: [0x1B9E47],
|
||||
0x05: [0x1B9EE4]}, 0x09),
|
||||
|
||||
InstrumentChange(0x17, 0x00, {0x00: [0x1BA287],
|
||||
0x03: [0x1BA26A]}, 0x0E, type=Am|Rh, ban=[0x01, 0x05, 0x06, 0x10, 0x17]),
|
||||
InstrumentChange(0x17, 0x01, {0x01: [0x1BA20F],
|
||||
0x02: [0x1BA231],
|
||||
0x03: [0x1BA24F]}, 0x0E, type=Am|Rh, ban=[0x01, 0x05, 0x06, 0x10]),
|
||||
|
||||
InstrumentChange(0x19, 0x00, {0x00: [0x1BA476],
|
||||
0x01: [0x1BA49C],
|
||||
0x02: [0x1BA4C1],
|
||||
0x03: [0x1BA4D5],
|
||||
0x04: [0x1BA4F4],
|
||||
0x05: [0x1BA513]}, 0x0A),
|
||||
InstrumentChange(0x19, 0x01, {0x00: [0x1BA357],
|
||||
0x01: [0x1BA379],
|
||||
0x03: [0x1BA38C],
|
||||
0x04: [0x1BA39D]}, 0x0A),
|
||||
InstrumentChange(0x19, 0x02, {0x02: [0x1BA3D3]}, 0x15),
|
||||
InstrumentChange(0x19, 0x03, {0x00: [0x1BA3F8]}, 0x16),
|
||||
InstrumentChange(0x19, 0x03, {0x02: [0x1BA40D]}, 0x0A),
|
||||
|
||||
InstrumentChange(0x1A, 0x00, {0x00: [0x1BA70E, 0x1BA71A],
|
||||
0x01: [0x1BA729],
|
||||
0x02: [0x1BA743],
|
||||
0x03: [0x1BA763],
|
||||
0x04: [0x1BA783],
|
||||
0x05: [0x1BA7A2],
|
||||
0x06: [0x1BA7B9],
|
||||
0x07: [0x1BA7D0]}, 0x0E),
|
||||
InstrumentChange(0x1A, 0x01, {0x00: [0x1BA5C1],
|
||||
0x05: [0x1BA68F],
|
||||
0x06: [0x1BA6A6],
|
||||
0x07: [0x1BA6DD]}, 0x0A),
|
||||
|
||||
InstrumentChange(0x1B, 0x00, {0x00: [0x1BAA55],
|
||||
0x01: [0x1BAA66],
|
||||
0x02: [0x1BAA75],
|
||||
0x03: [0x1BAA86],
|
||||
0x04: [0x1BAA97]}, 0x0F),
|
||||
InstrumentChange(0x1B, 0x01, {0x00: [0x1BA956],
|
||||
0x01: [0x1BA96F],
|
||||
0x02: [0x1BA98A],
|
||||
0x03: [0x1BA9A5],
|
||||
0x04: [0x1BA9C0],
|
||||
0x05: [0x1BA9EB],
|
||||
0x06: [0x1BAA19]}, 0x0F),
|
||||
|
||||
InstrumentChange(0x1C, 0x00, {0x00: [0x1BACB6, 0x1BABAD]}, 0x09),
|
||||
InstrumentChange(0x1C, 0x01, {0x01: [0x1BABC7],
|
||||
0x02: [0x1BABE0],
|
||||
0x03: [0x1BABF4],
|
||||
0x04: [0x1BAC0B]}, 0x09),
|
||||
InstrumentChange(0x1C, 0x02, {0x00: [0x1BAC26],
|
||||
0x01: [0x1BAC44],
|
||||
0x02: [0x1BAC61]}, 0x09),
|
||||
|
||||
InstrumentChange(0x1D, 0x00, {0x00: [0x1BACEA],
|
||||
0x01: [0x1BAD06],
|
||||
0x02: [0x1BAD23],
|
||||
0x03: [0x1BAD40],
|
||||
0x04: [0x1BAD5D]}, 0x0B),
|
||||
|
||||
InstrumentChange(0x1E, 0x00, {0x00: [0x1BB14D],
|
||||
0x01: [0x1BB169],
|
||||
0x02: [0x1BB17E],
|
||||
0x03: [0x1BB193],
|
||||
0x04: [0x1BB1A8]}, 0x09),
|
||||
InstrumentChange(0x1E, 0x00, {0x05: [0x1BB1BD]}, 0x02),
|
||||
|
||||
InstrumentChange(0x1F, 0x00, {0x00: [0x1BAE86],
|
||||
0x03: [0x1BAEC6],
|
||||
0x04: [0x1BAEE4]}, 0x0B),
|
||||
InstrumentChange(0x1F, 0x00, {0x00: [0x1BAE9C]}, 0x18),
|
||||
InstrumentChange(0x1F, 0x00, {0x02: [0x1BAEBC]}, 0x13),
|
||||
InstrumentChange(0x1F, 0x00, {0x06: [0x1BAF02]}, 0x02),
|
||||
InstrumentChange(0x1F, 0x01, {0x03: [0x1BAE15],
|
||||
0x04: [0x1BAE32],
|
||||
0x05: [0x1BAE4F]}, 0x11),
|
||||
InstrumentChange(0x1F, 0x02, {0x01: [0x1BAF2C]}, 0x0B),
|
||||
InstrumentChange(0x1F, 0x02, {0x03: [0x1BAF53],
|
||||
0x04: [0x1BAF69],
|
||||
0x05: [0x1BAF7F]}, 0x11),
|
||||
InstrumentChange(0x1F, 0x04, {0x02: [0x1BAFAA]}, 0x13),
|
||||
|
||||
InstrumentChange(0x20, 0x00, {0x00: [0x1AD49A],
|
||||
0x01: [0x1AD4BA],
|
||||
0x02: [0x1AD4D3],
|
||||
0x03: [0x1AD4EE],
|
||||
0x04: [0x1AD507]}, 0x0A),
|
||||
InstrumentChange(0x20, 0x01, {0x05: [0x1AD475]}, 0x18),
|
||||
|
||||
InstrumentChange(0x21, 0x00, {0x00: [0x1AE8E3],
|
||||
0x01: [0x1AF18E],
|
||||
0x02: [0x1AF1A9],
|
||||
0x03: [0x1AF1B7],
|
||||
0x04: [0x1AF1D2],
|
||||
0x05: [0x1AF1E4],
|
||||
0x06: [0x1AF201],
|
||||
0x07: [0x1AF21C]}, 0x0F),
|
||||
InstrumentChange(0x21, 0x01, {0x00: [0x1AE518]}, 0x12),
|
||||
InstrumentChange(0x21, 0x01, {0x01: [0x1AE540],
|
||||
0x03: [0x1AE58D]}, 0x0B),
|
||||
InstrumentChange(0x21, 0x01, {0x02: [0x1AE564]}, 0x09),
|
||||
InstrumentChange(0x21, 0x01, {0x04: [0x1AE5B1],
|
||||
0x05: [0x1AE5D4]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x01, {0x06: [0x1AE5EB, 0x1AE60F]}, 0x02),
|
||||
InstrumentChange(0x21, 0x01, {0x06: [0x1AE5F9],
|
||||
0x07: [0x1AE61B]}, 0x0C),
|
||||
InstrumentChange(0x21, 0x02, {0x03: [0x1AE651],
|
||||
0x05: [0x1AE69A]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x03, {0x00: [0x1AEC5E],
|
||||
0x01: [0x1AEC71],
|
||||
0x02: [0x1AEC90]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x04, {0x01: [0x1AECB6]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x04, {0x07: [0x1AF3A3]}, 0x0F),
|
||||
InstrumentChange(0x21, 0x05, {0x00: [0x1AE6D5],
|
||||
0x01: [0x1AE6FD],
|
||||
0x03: [0x1AE748],
|
||||
0x04: [0x1AE75E]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x05, {0x02: [0x1AE72A]}, 0x09),
|
||||
InstrumentChange(0x21, 0x06, {0x00: [0x1AE774]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x06, {0x02: [0x1AE7BE],
|
||||
0x04: [0x1AE825]}, 0x09),
|
||||
InstrumentChange(0x21, 0x07, {0x00: [0x1AED48],
|
||||
0x01: [0x1AED7B],
|
||||
0x03: [0x1AEDCD],
|
||||
0x04: [0x1AEDF4]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x07, {0x02: [0x1AEDB1]}, 0x09),
|
||||
InstrumentChange(0x21, 0x08, {0x00: [0x1AE876],
|
||||
0x01: [0x1AE881]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x0A, {0x02: [0x1AF17C],
|
||||
0x03: [0x1AE8BB]}, 0x09),
|
||||
InstrumentChange(0x21, 0x0B, {0x00: [0x1AEE0F]}, 0x11),
|
||||
InstrumentChange(0x21, 0x0B, {0x01: [0x1AEE22],
|
||||
0x03: [0x1AEE46],
|
||||
0x04: [0x1AEE74]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x0C, {0x01: [0x1AEECD],
|
||||
0x03: [0x1AEEF9],
|
||||
0x04: [0x1AEF2B]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x0D, {0x00: [0x1AE954],
|
||||
0x03: [0x1AE9D4],
|
||||
0x04: [0x1AEA03]}, 0x18),
|
||||
InstrumentChange(0x21, 0x0D, {0x00: [0x1AE971]}, 0x12),
|
||||
InstrumentChange(0x21, 0x0D, {0x01: [0x1AE983]}, 0x09),
|
||||
InstrumentChange(0x21, 0x0D, {0x01: [0x1AE9A6],
|
||||
0x03: [0x1AE9F3]}, 0x0B),
|
||||
InstrumentChange(0x21, 0x0D, {0x02: [0x1AE9B6]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x0E, {0x00: [0x1AEA4F]}, 0x12),
|
||||
InstrumentChange(0x21, 0x0E, {0x01: [0x1AEA84],
|
||||
0x03: [0x1AEAE7],
|
||||
0x05: [0x1AEB94]}, 0x0B),
|
||||
InstrumentChange(0x21, 0x0E, {0x02: [0x1AEAAF]}, 0x09),
|
||||
InstrumentChange(0x21, 0x0E, {0x04: [0x1AEB69]}, 0x0A),
|
||||
InstrumentChange(0x21, 0x0E, {0x06: [0x1AEC03]}, 0x02),
|
||||
InstrumentChange(0x21, 0x0E, {0x07: [0x1AEC3C]}, 0x0C),
|
||||
|
||||
InstrumentChange(0x22, 0x00, {0x00: [0x1ADA2D],
|
||||
0x01: [0x1ADA41],
|
||||
0x02: [0x1ADA51],
|
||||
0x03: [0x1ADA6C],
|
||||
0x04: [0x1ADA83]}, 0x0A),
|
||||
InstrumentChange(0x22, 0x01, {0x05: [0x1ADAC9]}, 0x0A),
|
||||
InstrumentChange(0x22, 0x02, {0x07: [0x1ADB60]}, 0x0A),
|
||||
InstrumentChange(0x22, 0x03, {0x06: [0x1ADC10]}, 0x16),
|
||||
InstrumentChange(0x22, 0x05, {0x05: [0x1AD7CC]}, 0x09),
|
||||
InstrumentChange(0x22, 0x05, {0x06: [0x1AD803]}, 0x11),
|
||||
InstrumentChange(0x22, 0x05, {0x07: [0x1AD81B]}, 0x0A),
|
||||
InstrumentChange(0x22, 0x06, {0x02: [0x1AD8A6]}, 0x11),
|
||||
InstrumentChange(0x22, 0x06, {0x03: [0x1AD959]}, 0x13),
|
||||
InstrumentChange(0x22, 0x06, {0x06: [0x1AD9B7]}, 0x16),
|
||||
InstrumentChange(0x22, 0x07, {0x00: [0x1ADCCD]}, 0x0B),
|
||||
InstrumentChange(0x22, 0x07, {0x02: [0x1ADD73]}, 0x11),
|
||||
InstrumentChange(0x22, 0x07, {0x04: [0x1ADDE0],
|
||||
0x07: [0x1ADE9E]}, 0x0A),
|
||||
InstrumentChange(0x22, 0x07, {0x05: [0x1ADE14]}, 0x12),
|
||||
InstrumentChange(0x22, 0x07, {0x06: [0x1ADE62]}, 0x16),
|
||||
InstrumentChange(0x22, 0x08, {0x00: [0x1ADF02],
|
||||
0x04: [0x1ADFA8]}, 0x0B),
|
||||
InstrumentChange(0x22, 0x08, {0x01: [0x1ADF2A]}, 0x11),
|
||||
InstrumentChange(0x22, 0x08, {0x02: [0x1ADF83],
|
||||
0x05: [0x1ADFED]}, 0x09),
|
||||
InstrumentChange(0x22, 0x08, {0x06: [0x1AE02D],
|
||||
0x07: [0x1AE047]}, 0x0A)
|
||||
]
|
||||
@@ -139,6 +139,7 @@ SETTINGSTOPROCESS = {
|
||||
"uwpalettes": "uw_palettes",
|
||||
"reduce_flashing": "reduce_flashing",
|
||||
"shuffle_sfx": "shuffle_sfx",
|
||||
"shuffle_songinstruments": "shuffle_songinstruments",
|
||||
'msu_resume': 'msu_resume',
|
||||
},
|
||||
"generation": {
|
||||
|
||||
@@ -107,6 +107,7 @@ def adjust_page(top, parent, settings):
|
||||
"reduce_flashing": "reduce_flashing",
|
||||
'msu_resume': 'msu_resume',
|
||||
"shuffle_sfx": "shuffle_sfx",
|
||||
"shuffle_songinstruments": "shuffle_songinstruments",
|
||||
}
|
||||
guiargs = Namespace()
|
||||
for option in options:
|
||||
@@ -158,6 +159,7 @@ def adjust_page(top, parent, settings):
|
||||
"nobgm": "disablemusic",
|
||||
"reduce_flashing": "reduce_flashing",
|
||||
"shuffle_sfx": "shuffle_sfx",
|
||||
"shuffle_songinstruments": "shuffle_songinstruments",
|
||||
"msu_resume": "msu_resume"
|
||||
}
|
||||
guiargs = Namespace()
|
||||
|
||||
@@ -154,6 +154,12 @@ def bottom_frame(self, parent, args=None):
|
||||
|
||||
open_file(output_path('.'))
|
||||
|
||||
def select_output():
|
||||
from tkinter import filedialog
|
||||
folder_selected = filedialog.askdirectory()
|
||||
if folder_selected is not None:
|
||||
args.outputpath = parent.settings["outputpath"] = folder_selected
|
||||
|
||||
## Output Button
|
||||
# widget ID
|
||||
widget = "outputdir"
|
||||
@@ -168,7 +174,7 @@ def bottom_frame(self, parent, args=None):
|
||||
|
||||
# button
|
||||
self.widgets[widget].type = "button"
|
||||
self.widgets[widget].pieces["button"] = Button(self, text='Open Output Directory', command=open_output)
|
||||
self.widgets[widget].pieces["button"] = Button(self, text='Open Output Directory', command=select_output)
|
||||
# button: pack
|
||||
self.widgets[widget].pieces["button"].pack(side=RIGHT)
|
||||
|
||||
@@ -253,7 +259,10 @@ def create_guiargs(parent):
|
||||
"heartbeep": "heartbeep",
|
||||
"menuspeed": "fastmenu",
|
||||
"owpalettes": "ow_palettes",
|
||||
"uwpalettes": "uw_palettes"
|
||||
"uwpalettes": "uw_palettes",
|
||||
"reduce_flashing": "reduce_flashing",
|
||||
"shuffle_sfx": "shuffle_sfx",
|
||||
"shuffle_songinstruments": "shuffle_songinstruments"
|
||||
}
|
||||
for adjustarg in adjustargs:
|
||||
internal = adjustargs[adjustarg]
|
||||
|
||||
@@ -206,7 +206,10 @@ def loadadjustargs(gui, settings):
|
||||
"heartbeep": "adjust.heartbeep",
|
||||
"menuspeed": "adjust.menuspeed",
|
||||
"owpalettes": "adjust.owpalettes",
|
||||
"uwpalettes": "adjust.uwpalettes"
|
||||
"uwpalettes": "adjust.uwpalettes",
|
||||
"reduce_flashing": "adjust.reduce_flashing",
|
||||
"shuffle_sfx": "adjust.shuffle_sfx",
|
||||
"shuffle_songinstruments": "adjust.shuffle_songinstruments"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,7 +711,10 @@ def do_links_house(entrances, exits, avail, cross_world):
|
||||
connect_entrance(chosen_dm_escape, chosen_exit_start, avail)
|
||||
connect_exit(chosen_exit_end, chosen_landing, avail)
|
||||
entrances.remove(chosen_dm_escape)
|
||||
avail.decoupled_exits.remove(chosen_exit_start)
|
||||
avail.decoupled_entrances.remove(chosen_landing)
|
||||
# chosen cave has already been removed from exits
|
||||
exits.add(chosen_exit_start) # this needs to be added back in
|
||||
if len(chosen_cave):
|
||||
exits.update([x for x in chosen_cave])
|
||||
exits.update([x for item in multi_exit_caves for x in item])
|
||||
@@ -1675,7 +1678,7 @@ def connect_entrance(entrancename, exit_name, avail):
|
||||
|
||||
|
||||
def connect_exit(exit_name, entrancename, avail):
|
||||
world, player = avail.world, avail. player
|
||||
world, player = avail.world, avail.player
|
||||
entrance = world.get_entrance(entrancename, player)
|
||||
exit = world.get_entrance(exit_name, player)
|
||||
|
||||
|
||||
@@ -219,6 +219,7 @@ def roll_settings(weights):
|
||||
ret.ow_palettes = get_choice('ow_palettes', romweights)
|
||||
ret.uw_palettes = get_choice('uw_palettes', romweights)
|
||||
ret.shuffle_sfx = get_choice('shuffle_sfx', romweights) == 'on'
|
||||
ret.shuffle_songinstruments = get_choice('shuffle_songinstruments', romweights) == 'on'
|
||||
ret.msu_resume = get_choice('msu_resume', romweights) == 'on'
|
||||
|
||||
return ret
|
||||
|
||||
Reference in New Issue
Block a user