diff --git a/Adjuster.py b/Adjuster.py index bda1e8e8..2e732dda 100755 --- a/Adjuster.py +++ b/Adjuster.py @@ -10,6 +10,12 @@ from Rom import Sprite, LocalRom, apply_rom_settings from Utils import output_path +class AdjusterWorld(object): + def __init__(self, sprite_pool): + import random + self.sprite_pool = {1: sprite_pool} + self.rom_seeds = {1: random} + class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): def _get_help_string(self, action): @@ -101,10 +107,14 @@ def adjust(args): palettes_options['sword']=args.sword_palettes palettes_options['shield']=args.shield_palettes # palettes_options['link']=args.link_palettesvera + racerom = rom.read_byte(0x180213) > 0 + world = None + if hasattr(args, "world"): + world = getattr(args, "world") apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, - args.sprite, palettes_options, reduceflashing=args.reduceflashing or racerom) + args.sprite, palettes_options, reduceflashing=args.reduceflashing or racerom, world=world) path = output_path(f'{os.path.basename(args.rom)[:-4]}_adjusted.sfc') rom.write_to_file(path) @@ -160,8 +170,14 @@ def adjustGUI(): guiargs.rom = romVar2.get() guiargs.baserom = romVar.get() guiargs.sprite = rom_vars.sprite + if rom_vars.sprite_pool: + guiargs.world = AdjusterWorld(rom_vars.sprite_pool) + try: guiargs, path = adjust(args=guiargs) + if rom_vars.sprite_pool: + guiargs.sprite_pool = rom_vars.sprite_pool + delattr(guiargs, "world") except Exception as e: logging.exception(e) messagebox.showerror(title="Error while adjusting Rom", message=str(e)) diff --git a/Gui.py b/Gui.py index d04f7352..fd567ba9 100755 --- a/Gui.py +++ b/Gui.py @@ -501,6 +501,9 @@ def guiMain(args=None): guiargs.rom = romVar.get() guiargs.create_diff = patchesVar.get() guiargs.sprite = rom_vars.sprite + if rom_vars.sprite_pool: + guiargs.sprite_pool = rom_vars.sprite_pool + messagebox.showinfo(title="Sprite Pool", message=", ".join(guiargs.sprite_pool)) # get default values for missing parameters for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items(): if k not in vars(guiargs): @@ -1308,7 +1311,8 @@ def get_rom_options_frame(parent=None): spriteEntry = Label(spriteDialogFrame, textvariable=vars.spriteNameVar) def SpriteSelect(): - SpriteSelector(parent, set_sprite) + nonlocal vars + SpriteSelector(parent, set_sprite, spritePool=vars.sprite_pool) spriteSelectButton = Button(spriteDialogFrame, text='...', command=SpriteSelect) @@ -1392,21 +1396,57 @@ def get_rom_options_frame(parent=None): shieldPalettesOptionMenu = OptionMenu(shieldPalettesFrame, vars.shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke') shieldPalettesOptionMenu.pack(side=LEFT) + spritePoolFrame = Frame(romOptionsFrame) + spritePoolFrame.grid(row=5, column=1) + baseSpritePoolLabel = Label(spritePoolFrame, text='Sprite Pool:') + + vars.spritePoolCountVar = StringVar() + vars.sprite_pool = [] + def set_sprite_pool(sprite_param): + nonlocal vars + if isinstance(sprite_param, str): + vars.sprite_pool.append(sprite_param) + elif sprite_param and sprite_param.valid: + vars.sprite_pool.append(sprite_param.name) + vars.spritePoolCountVar.set(str(len(vars.sprite_pool))) + + set_sprite_pool(None) + vars.spritePoolCountVar.set('0') + spritePoolEntry = Label(spritePoolFrame, textvariable=vars.spritePoolCountVar) + + def SpritePoolSelect(): + SpriteSelector(parent, set_sprite_pool, randomOnEvent=False) + + def SpritePoolClear(): + nonlocal vars + vars.sprite_pool.clear() + vars.spritePoolCountVar.set('0') + + spritePoolSelectButton = Button(spritePoolFrame, text='...', command=SpritePoolSelect) + spritePoolClearButton = Button(spritePoolFrame, text='Clear', command=SpritePoolClear) + + baseSpritePoolLabel.pack(side=LEFT) + spritePoolEntry.pack(side=LEFT) + spritePoolSelectButton.pack(side=LEFT) + spritePoolClearButton.pack(side=LEFT) + return romOptionsFrame, vars, set_sprite class SpriteSelector(): - def __init__(self, parent, callback, adjuster=False): + def __init__(self, parent, callback, adjuster=False, randomOnEvent=True, spritePool=None): self.deploy_icons() self.parent = parent self.window = Toplevel(parent) self.callback = callback self.adjuster = adjuster + self.randomOnEvent = randomOnEvent self.window.wm_title("TAKE ANY ONE YOU WANT") self.window['padx'] = 5 self.window['pady'] = 5 self.all_sprites = [] + self.sprite_pool = spritePool def open_custom_sprite_dir(_evt): open_file(self.custom_sprite_dir) @@ -1447,24 +1487,29 @@ class SpriteSelector(): self.randomOnSlashVar = IntVar() self.randomOnItemVar = IntVar() self.randomOnBonkVar = IntVar() + self.randomOnRandomVar = IntVar() - button = Checkbutton(frame, text="Hit", command=self.update_random_button, variable=self.randomOnHitVar) - button.pack(side=LEFT, padx=(0, 5)) + if self.randomOnEvent: + button = Checkbutton(frame, text="Hit", command=self.update_random_button, variable=self.randomOnHitVar) + button.pack(side=LEFT, padx=(0, 5)) - button = Checkbutton(frame, text="Enter", command=self.update_random_button, variable=self.randomOnEnterVar) - button.pack(side=LEFT, padx=(0, 5)) + button = Checkbutton(frame, text="Enter", command=self.update_random_button, variable=self.randomOnEnterVar) + button.pack(side=LEFT, padx=(0, 5)) - button = Checkbutton(frame, text="Exit", command=self.update_random_button, variable=self.randomOnExitVar) - button.pack(side=LEFT, padx=(0, 5)) + button = Checkbutton(frame, text="Exit", command=self.update_random_button, variable=self.randomOnExitVar) + button.pack(side=LEFT, padx=(0, 5)) - button = Checkbutton(frame, text="Slash", command=self.update_random_button, variable=self.randomOnSlashVar) - button.pack(side=LEFT, padx=(0, 5)) + button = Checkbutton(frame, text="Slash", command=self.update_random_button, variable=self.randomOnSlashVar) + button.pack(side=LEFT, padx=(0, 5)) - button = Checkbutton(frame, text="Item", command=self.update_random_button, variable=self.randomOnItemVar) - button.pack(side=LEFT, padx=(0, 5)) + button = Checkbutton(frame, text="Item", command=self.update_random_button, variable=self.randomOnItemVar) + button.pack(side=LEFT, padx=(0, 5)) - button = Checkbutton(frame, text="Bonk", command=self.update_random_button, variable=self.randomOnBonkVar) - button.pack(side=LEFT, padx=(0, 5)) + button = Checkbutton(frame, text="Bonk", command=self.update_random_button, variable=self.randomOnBonkVar) + button.pack(side=LEFT, padx=(0, 5)) + + button = Checkbutton(frame, text="Random", command=self.update_random_button, variable=self.randomOnRandomVar) + button.pack(side=LEFT, padx=(0, 5)) if adjuster: button = Button(frame, text="Current sprite from rom", command=self.use_default_sprite) @@ -1553,18 +1598,30 @@ class SpriteSelector(): self.window.destroy() def update_random_button(self): - randomon = "-hit" if self.randomOnHitVar.get() else "" - randomon += "-enter" if self.randomOnEnterVar.get() else "" - randomon += "-exit" if self.randomOnExitVar.get() else "" - randomon += "-slash" if self.randomOnSlashVar.get() else "" - randomon += "-item" if self.randomOnItemVar.get() else "" - randomon += "-bonk" if self.randomOnBonkVar.get() else "" + if self.randomOnRandomVar.get(): + randomon = "random" + else: + randomon = "-hit" if self.randomOnHitVar.get() else "" + randomon += "-enter" if self.randomOnEnterVar.get() else "" + randomon += "-exit" if self.randomOnExitVar.get() else "" + randomon += "-slash" if self.randomOnSlashVar.get() else "" + randomon += "-item" if self.randomOnItemVar.get() else "" + randomon += "-bonk" if self.randomOnBonkVar.get() else "" + self.randomOnEventText.set(f"randomon{randomon}" if randomon else None) self.randomButtonText.set("Random On Event" if randomon else "Random") def use_random_sprite(self): - randomon = self.randomOnEventText.get() - self.callback(randomon if randomon else (random.choice(self.all_sprites) if self.all_sprites else None)) + if not self.randomOnEvent: + self.callback("random") + elif self.randomOnEventText.get(): + self.callback(self.randomOnEventText.get()) + elif self.sprite_pool: + self.callback(random.choice(self.sprite_pool)) + elif self.all_sprites: + self.callback(random.choice(self.all_sprites)) + else: + self.callback(None) self.window.destroy() def select_sprite(self, spritename): diff --git a/Rom.py b/Rom.py index 94a45d20..fed5a5f0 100644 --- a/Rom.py +++ b/Rom.py @@ -226,6 +226,9 @@ def apply_random_sprite_on_event(rom: LocalRom, sprite, local_random, allow_rand elif sprite == 'randomonnone': # Allows for opting into random on events on race rom seeds, without actually enabling any of the events initially. onevent = 0x0000 + elif sprite == 'randomonrandom': + # Allows random to take the wheel on which events apply. (at least one event will be applied.) + onevent = local_random.randint(0x0001, 0x003F) elif userandomsprites: onevent = 0x01 if 'hit' in sprite else 0x00 onevent += 0x02 if 'enter' in sprite else 0x00 @@ -536,6 +539,8 @@ class Sprite(object): self.valid = False return (sprite, palette, self.name, self.author_name) = result + if self.name == "": + self.name = os.path.split(filename)[1].split(".")[0] if len(sprite) != 0x7000: self.valid = False return diff --git a/Utils.py b/Utils.py index afda1693..2885ccee 100644 --- a/Utils.py +++ b/Utils.py @@ -334,6 +334,7 @@ def get_adjuster_settings(romfile: str) -> typing.Tuple[str, bool]: import Patch adjuster_settings.rom = romfile adjuster_settings.baserom = Patch.get_base_rom_path() + adjuster_settings.world = None whitelist = {"disablemusic", "fastmenu", "heartbeep", "heartcolor", "ow_palettes", "quickswap", "uw_palettes", "sprite"} printed_options = {name: value for name, value in vars(adjuster_settings).items() if name in whitelist} @@ -347,9 +348,16 @@ def get_adjuster_settings(romfile: str) -> typing.Tuple[str, bool]: f"{pprint.pformat(printed_options)}\n" f"Enter yes, no or never: ") if adjust_wanted and adjust_wanted.startswith("y"): + if hasattr(adjuster_settings, "sprite_pool"): + from Adjuster import AdjusterWorld + adjuster_settings.world = AdjusterWorld(getattr(adjuster_settings, "sprite_pool")) + adjusted = True import Adjuster _, romfile = Adjuster.adjust(adjuster_settings) + + if hasattr(adjuster_settings, "world"): + delattr(adjuster_settings, "world") elif adjust_wanted and "never" in adjust_wanted: persistent_store("adjuster", "never_adjust", True) return romfile, False