Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2023-12-02 06:48:47 -06:00
27 changed files with 925 additions and 106 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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
View File

@@ -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,

View File

@@ -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

View File

@@ -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)

View File

@@ -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']) \

View File

@@ -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
View File

@@ -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()

View File

@@ -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)
@@ -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:
@@ -943,21 +950,21 @@ def bomb_rules(world, player):
('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
# ('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))
else:
@@ -976,10 +983,10 @@ def bomb_rules(world, player):
'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',
@@ -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':
@@ -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)
@@ -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",
@@ -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):

View File

@@ -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.

View File

@@ -269,3 +269,6 @@
shuffle_sfx:
on: 1
off: 1
shuffle_songinstruments:
on: 1
off: 1

View File

@@ -199,3 +199,6 @@ rom:
shuffle_sfx:
on: 1
off: 1
shuffle_songinstruments:
on: 1
off: 1

View File

@@ -347,6 +347,10 @@
"action": "store_true",
"type": "bool"
},
"shuffle_songinstruments": {
"action": "store_true",
"type": "bool"
},
"msu_resume": {
"action": "store_true",
"type": "bool"

View File

@@ -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)" ],

View File

@@ -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": {

View File

@@ -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"
}
}

View File

@@ -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": {

View File

@@ -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):

View File

@@ -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)
]

View File

@@ -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": {

View File

@@ -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()

View File

@@ -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]

View File

@@ -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"
}
}
}

View File

@@ -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)

View File

@@ -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