diff --git a/CLI.py b/CLI.py new file mode 100644 index 00000000..2f18d21e --- /dev/null +++ b/CLI.py @@ -0,0 +1,339 @@ +import argparse +import copy +import json +import os +import logging +import random +import textwrap +import shlex +import sys + +from Main import main +from Rom import get_sprite_from_name +from Utils import is_bundled, close_console +from Fill import FillError + + +class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): + + def _get_help_string(self, action): + return textwrap.dedent(action.help) + +def parse_arguments(argv, no_defaults=False): + def defval(value): + return value if not no_defaults else None + + # we need to know how many players we have first + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('--multi', default=defval(1), type=lambda value: min(max(int(value), 1), 255)) + multiargs, _ = parser.parse_known_args(argv) + + parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) + parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true') + parser.add_argument('--logic', default=defval('noglitches'), const='noglitches', nargs='?', choices=['noglitches', 'minorglitches', 'nologic'], + help='''\ + Select Enforcement of Item Requirements. (default: %(default)s) + No Glitches: + Minor Glitches: May require Fake Flippers, Bunny Revival + and Dark Room Navigation. + No Logic: Distribute items without regard for + item requirements. + ''') + parser.add_argument('--mode', default=defval('open'), const='open', nargs='?', choices=['standard', 'open', 'inverted'], + help='''\ + Select game mode. (default: %(default)s) + Open: World starts with Zelda rescued. + Standard: Fixes Hyrule Castle Secret Entrance and Front Door + but may lead to weird rain state issues if you exit + through the Hyrule Castle side exits before rescuing + Zelda in a full shuffle. + Inverted: Starting locations are Dark Sanctuary in West Dark + World or at Link's House, which is shuffled freely. + Requires the moon pearl to be Link in the Light World + instead of a bunny. + ''') + parser.add_argument('--swords', default=defval('random'), const='random', nargs='?', choices= ['random', 'assured', 'swordless', 'vanilla'], + help='''\ + Select sword placement. (default: %(default)s) + Random: All swords placed randomly. + Assured: Start game with a sword already. + Swordless: No swords. Curtains in Skull Woods and Agahnim\'s + Tower are removed, Agahnim\'s Tower barrier can be + destroyed with hammer. Misery Mire and Turtle Rock + can be opened without a sword. Hammer damages Ganon. + Ether and Bombos Tablet can be activated with Hammer + (and Book). Bombos pads have been added in Ice + Palace, to allow for an alternative to firerod. + Vanilla: Swords are in vanilla locations. + ''') + parser.add_argument('--goal', default=defval('ganon'), const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'], + help='''\ + Select completion goal. (default: %(default)s) + Ganon: Collect all crystals, beat Agahnim 2 then + defeat Ganon. + Crystals: Collect all crystals then defeat Ganon. + Pedestal: Places the Triforce at the Master Sword Pedestal. + All Dungeons: Collect all crystals, pendants, beat both + Agahnim fights and then defeat Ganon. + Triforce Hunt: Places 30 Triforce Pieces in the world, collect + 20 of them to beat the game. + ''') + parser.add_argument('--difficulty', default=defval('normal'), const='normal', nargs='?', choices=['normal', 'hard', 'expert'], + help='''\ + Select game difficulty. Affects available itempool. (default: %(default)s) + Normal: Normal difficulty. + Hard: A harder setting with less equipment and reduced health. + Expert: A harder yet setting with minimum equipment and health. + ''') + parser.add_argument('--item_functionality', default=defval('normal'), const='normal', nargs='?', choices=['normal', 'hard', 'expert'], + help='''\ + Select limits on item functionality to increase difficulty. (default: %(default)s) + Normal: Normal functionality. + Hard: Reduced functionality. + Expert: Greatly reduced functionality. + ''') + parser.add_argument('--timer', default=defval('none'), const='normal', nargs='?', choices=['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'], + help='''\ + Select game timer setting. Affects available itempool. (default: %(default)s) + None: No timer. + Display: Displays a timer but does not affect + the itempool. + Timed: Starts with clock at zero. Green Clocks + subtract 4 minutes (Total: 20), Blue Clocks + subtract 2 minutes (Total: 10), Red Clocks add + 2 minutes (Total: 10). Winner is player with + lowest time at the end. + Timed OHKO: Starts clock at 10 minutes. Green Clocks add + 5 minutes (Total: 25). As long as clock is at 0, + Link will die in one hit. + OHKO: Like Timed OHKO, but no clock items are present + and the clock is permenantly at zero. + Timed Countdown: Starts with clock at 40 minutes. Same clocks as + Timed mode. If time runs out, you lose (but can + still keep playing). + ''') + parser.add_argument('--progressive', default=defval('on'), const='normal', nargs='?', choices=['on', 'off', 'random'], + help='''\ + Select progressive equipment setting. Affects available itempool. (default: %(default)s) + On: Swords, Shields, Armor, and Gloves will + all be progressive equipment. Each subsequent + item of the same type the player finds will + upgrade that piece of equipment by one stage. + Off: Swords, Shields, Armor, and Gloves will not + be progressive equipment. Higher level items may + be found at any time. Downgrades are not possible. + Random: Swords, Shields, Armor, and Gloves will, per + category, be randomly progressive or not. + Link will die in one hit. + ''') + parser.add_argument('--algorithm', default=defval('balanced'), const='balanced', nargs='?', choices=['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'], + help='''\ + Select item filling algorithm. (default: %(default)s + balanced: vt26 derivative that aims to strike a balance between + the overworld heavy vt25 and the dungeon heavy vt26 + algorithm. + vt26: Shuffle items and place them in a random location + that it is not impossible to be in. This includes + dungeon keys and items. + vt25: Shuffle items and place them in a random location + that it is not impossible to be in. + vt21: Unbiased in its selection, but has tendency to put + Ice Rod in Turtle Rock. + vt22: Drops off stale locations after 1/3 of progress + items were placed to try to circumvent vt21\'s + shortcomings. + Freshness: Keep track of stale locations (ones that cannot be + reached yet) and decrease likeliness of selecting + them the more often they were found unreachable. + Flood: Push out items starting from Link\'s House and + slightly biased to placing progression items with + less restrictions. + ''') + parser.add_argument('--shuffle', default=defval('vanilla'), const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple'], + help='''\ + Select Entrance Shuffling Algorithm. (default: %(default)s) + Full: Mix cave and dungeon entrances freely while limiting + multi-entrance caves to one world. + Simple: Shuffle Dungeon Entrances/Exits between each other + and keep all 4-entrance dungeons confined to one + location. All caves outside of death mountain are + shuffled in pairs and matched by original type. + Restricted: Use Dungeons shuffling from Simple but freely + connect remaining entrances. + Crossed: Mix cave and dungeon entrances freely while allowing + caves to cross between worlds. + Insanity: Decouple entrances and exits from each other and + shuffle them freely. Caves that used to be single + entrance will still exit to the same location from + which they are entered. + Vanilla: All entrances are in the same locations they were + in the base game. + Legacy shuffles preserve behavior from older versions of the + entrance randomizer including significant technical limitations. + The dungeon variants only mix up dungeons and keep the rest of + the overworld vanilla. + ''') + parser.add_argument('--door_shuffle', default=defval('basic'), const='vanilla', nargs='?', choices=['vanilla', 'basic', 'crossed', 'experimental'], + help='''\ + Select Door Shuffling Algorithm. (default: %(default)s) + Basic: Doors are mixed within a single dungeon. + (Not yet implemented) + Crossed: Doors are mixed between all dungeons. + (Not yet implemented) + Vanilla: All doors are connected the same way they were in the + base game. + Experimental: Experimental mixes live here. Use at your own risk. + ''') + parser.add_argument('--crystals_ganon', default=defval('7'), const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'], + help='''\ + How many crystals are needed to defeat ganon. Any other + requirements for ganon for the selected goal still apply. + This setting does not apply when the all dungeons goal is + selected. (default: %(default)s) + Random: Picks a random value between 0 and 7 (inclusive). + 0-7: Number of crystals needed + ''') + parser.add_argument('--crystals_gt', default=defval('7'), const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'], + help='''\ + How many crystals are needed to open GT. For inverted mode + this applies to the castle tower door instead. (default: %(default)s) + Random: Picks a random value between 0 and 7 (inclusive). + 0-7: Number of crystals needed + ''') + parser.add_argument('--openpyramid', default=defval(False), help='''\ + Pre-opens the pyramid hole, this removes the Agahnim 2 requirement for it + ''', action='store_true') + parser.add_argument('--rom', default=defval('Zelda no Densetsu - Kamigami no Triforce (Japan).sfc'), help='Path to an ALttP JAP(1.0) rom to use as a base.') + parser.add_argument('--loglevel', default=defval('info'), const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.') + parser.add_argument('--seed', help='Define seed number to generate.', type=int) + parser.add_argument('--count', help='''\ + Use to batch generate multiple seeds with same settings. + If --seed is provided, it will be used for the first seed, then + used to derive the next seed (i.e. generating 10 seeds with + --seed given will produce the same 10 (different) roms each + time). + ''', type=int) + parser.add_argument('--fastmenu', default=defval('normal'), const='normal', nargs='?', choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'], + help='''\ + Select the rate at which the menu opens and closes. + (default: %(default)s) + ''') + parser.add_argument('--quickswap', default=defval(False), help='Enable quick item swapping with L and R.', action='store_true') + parser.add_argument('--disablemusic', default=defval(False), help='Disables game music.', action='store_true') + parser.add_argument('--mapshuffle', default=defval(False), help='Maps are no longer restricted to their dungeons, but can be anywhere', action='store_true') + parser.add_argument('--compassshuffle', default=defval(False), help='Compasses are no longer restricted to their dungeons, but can be anywhere', action='store_true') + parser.add_argument('--keyshuffle', default=defval(False), help='Small Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true') + parser.add_argument('--bigkeyshuffle', default=defval(False), help='Big Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true') + parser.add_argument('--keysanity', default=defval(False), help=argparse.SUPPRESS, action='store_true') + parser.add_argument('--retro', default=defval(False), help='''\ + Keys are universal, shooting arrows costs rupees, + and a few other little things make this more like Zelda-1. + ''', action='store_true') + parser.add_argument('--startinventory', default=defval(''), help='Specifies a list of items that will be in your starting inventory (separated by commas)') + parser.add_argument('--custom', default=defval(False), help='Not supported.') + parser.add_argument('--customitemarray', default=defval(False), help='Not supported.') + parser.add_argument('--accessibility', default=defval('items'), const='items', nargs='?', choices=['items', 'locations', 'none'], help='''\ + Select Item/Location Accessibility. (default: %(default)s) + Items: You can reach all unique inventory items. No guarantees about + reaching all locations or all keys. + Locations: You will be able to reach every location in the game. + None: You will be able to reach enough locations to beat the game. + ''') + parser.add_argument('--hints', default=defval(False), help='''\ + Make telepathic tiles and storytellers give helpful hints. + ''', action='store_true') + # included for backwards compatibility + parser.add_argument('--shuffleganon', help=argparse.SUPPRESS, action='store_true', default=defval(True)) + parser.add_argument('--no-shuffleganon', help='''\ + If set, the Pyramid Hole and Ganon's Tower are not + included entrance shuffle pool. + ''', action='store_false', dest='shuffleganon') + parser.add_argument('--heartbeep', default=defval('normal'), const='normal', nargs='?', choices=['double', 'normal', 'half', 'quarter', 'off'], + help='''\ + Select the rate at which the heart beep sound is played at + low health. (default: %(default)s) + ''') + parser.add_argument('--heartcolor', default=defval('red'), const='red', nargs='?', choices=['red', 'blue', 'green', 'yellow', 'random'], + help='Select the color of Link\'s heart meter. (default: %(default)s)') + parser.add_argument('--ow_palettes', default=defval('default'), choices=['default', 'random', 'blackout']) + parser.add_argument('--uw_palettes', default=defval('default'), choices=['default', 'random', 'blackout']) + parser.add_argument('--sprite', help='''\ + Path to a sprite sheet to use for Link. Needs to be in + binary format and have a length of 0x7000 (28672) bytes, + or 0x7078 (28792) bytes including palette data. + Alternatively, can be a ALttP Rom patched with a Link + sprite that will be extracted. + ''') + parser.add_argument('--suppress_rom', help='Do not create an output rom file.', action='store_true') + parser.add_argument('--gui', help='Launch the GUI', action='store_true') + parser.add_argument('--jsonout', action='store_true', help='''\ + Output .json patch to stdout instead of a patched rom. Used + for VT site integration, do not use otherwise. + ''') + parser.add_argument('--skip_playthrough', action='store_true', default=defval(False)) + parser.add_argument('--enemizercli', default=defval('EnemizerCLI/EnemizerCLI.Core')) + parser.add_argument('--shufflebosses', default=defval('none'), choices=['none', 'basic', 'normal', 'chaos']) + parser.add_argument('--shuffleenemies', default=defval('none'), choices=['none', 'shuffled', 'chaos']) + parser.add_argument('--enemy_health', default=defval('default'), choices=['default', 'easy', 'normal', 'hard', 'expert']) + parser.add_argument('--enemy_damage', default=defval('default'), choices=['default', 'shuffled', 'chaos']) + parser.add_argument('--shufflepots', default=defval(False), action='store_true') + parser.add_argument('--beemizer', default=defval(0), type=lambda value: min(max(int(value), 0), 4)) + parser.add_argument('--remote_items', default=defval(False), action='store_true') + parser.add_argument('--multi', default=defval(1), type=lambda value: min(max(int(value), 1), 255)) + parser.add_argument('--names', default=defval('')) + parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1)) + parser.add_argument('--outputpath') + parser.add_argument('--race', default=defval(False), action='store_true') + parser.add_argument('--outputname') + + if multiargs.multi: + for player in range(1, multiargs.multi + 1): + parser.add_argument(f'--p{player}', default=defval(''), help=argparse.SUPPRESS) + + ret = parser.parse_args(argv) + if ret.keysanity: + ret.mapshuffle, ret.compassshuffle, ret.keyshuffle, ret.bigkeyshuffle = [True] * 4 + + if multiargs.multi: + defaults = copy.deepcopy(ret) + for player in range(1, multiargs.multi + 1): + playerargs = parse_arguments(shlex.split(getattr(ret,f"p{player}")), True) + + for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', + 'shuffle', 'door_shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid', + 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', + 'retro', 'accessibility', 'hints', 'beemizer', + 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', + 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', + 'remote_items']: + value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) + if player == 1: + setattr(ret, name, {1: value}) + else: + getattr(ret, name)[player] = value + + return ret + +def get_working_dirs(): + # set default working dirs to same dir as script + working_dirs = { + "adjust.rom": os.path.join("."), + "enemizer.cli": os.path.join(".","EnemizerCLI","EnemizerCLI.Core"), + "multi.worlds": 1, + "multi.names": "", + "rom.base": os.path.join(".","Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"), + "gen.seed": "", + "gen.count": 1, + "outputpath": os.path.join("."), + } + if sys.platform.lower().find("windows"): + working_dirs["enemizer.cli"] += ".exe" + + # read saved working dirs file if it exists and set these + working_dirs_path = os.path.join(".","resources","user","working_dirs.json") + if os.path.exists(working_dirs_path): + with(open(working_dirs_path)) as json_file: + data = json.load(json_file) + for k,v in data.items(): + working_dirs[k] = v + return working_dirs diff --git a/Gui.py b/Gui.py index b057046e..7a616284 100755 --- a/Gui.py +++ b/Gui.py @@ -19,6 +19,7 @@ from gui.randomize.dungeon import dungeon_page from gui.randomize.multiworld import multiworld_page from gui.randomize.gameoptions import gameoptions_page from gui.randomize.generation import generation_page +from gui.bottom import bottom_frame from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress from Main import main, __version__ as ESVersion from Rom import Sprite @@ -27,39 +28,20 @@ from Utils import is_bundled, local_path, output_path, open_file def guiMain(args=None): mainWindow = Tk() + self = mainWindow mainWindow.wm_title("Door Shuffle %s" % ESVersion) set_icon(mainWindow) - notebook = ttk.Notebook(mainWindow) - randomizerWindow = ttk.Frame(notebook) - adjustWindow = ttk.Frame(notebook) - customWindow = ttk.Frame(notebook) - notebook.add(randomizerWindow, text='Randomize') - notebook.add(adjustWindow, text='Adjust') - notebook.add(customWindow, text='Custom') + notebook = ttk.Notebook(self) + self.randomizerWindow = ttk.Frame(notebook) + self.adjustWindow = ttk.Frame(notebook) + self.customWindow = ttk.Frame(notebook) + notebook.add(self.randomizerWindow, text='Randomize') + notebook.add(self.adjustWindow, text='Adjust') + notebook.add(self.customWindow, text='Custom') notebook.pack() - # Shared Controls - - farBottomFrame = Frame(mainWindow) - - def open_output(): - if args and args.outputpath: - open_file(output_path(args.outputpath)) - else: - open_file(output_path('')) - - openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output) - - if os.path.exists(local_path('README.html')): - def open_readme(): - open_file(local_path('README.html')) - openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme) - openReadmeButton.pack(side=LEFT) - - farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) - # randomizer controls # Randomize notebook page: @@ -71,146 +53,52 @@ def guiMain(args=None): # Multiworld: Multiworld settings # Game Options: Cosmetic settings that don't affect logic/placement # Generation Setup: Primarily one&done settings - randomizerNotebook = ttk.Notebook(randomizerWindow) + self.randomizerNotebook = ttk.Notebook(self.randomizerWindow) # Item Randomizer - itemWindow = item_page(randomizerNotebook) - randomizerNotebook.add(itemWindow, text="Items") + self.itemWindow = item_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.itemWindow, text="Items") # Entrance Randomizer - entrandoWindow = entrando_page(randomizerNotebook) - randomizerNotebook.add(entrandoWindow, text="Entrances") + self.entrandoWindow = entrando_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.entrandoWindow, text="Entrances") # Enemizer - enemizerWindow = enemizer_page(randomizerNotebook) - randomizerNotebook.add(enemizerWindow, text="Enemizer") + self.enemizerWindow = enemizer_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.enemizerWindow, text="Enemizer") # Dungeon Shuffle - dungeonRandoWindow = dungeon_page(randomizerNotebook) - randomizerNotebook.add(dungeonRandoWindow, text="Dungeon Shuffle") + self.dungeonRandoWindow = dungeon_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.dungeonRandoWindow, text="Dungeon Shuffle") # Multiworld - multiworldWindow = multiworld_page(randomizerNotebook) - randomizerNotebook.add(multiworldWindow, text="Multiworld") + self.multiworldWindow = multiworld_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.multiworldWindow, text="Multiworld") # Game Options - gameOptionsWindow = gameoptions_page(randomizerNotebook) - randomizerNotebook.add(gameOptionsWindow, text="Game Options") + self.gameOptionsWindow = gameoptions_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.gameOptionsWindow, text="Game Options") # Generation Setup - generationSetupWindow = generation_page(randomizerNotebook) - randomizerNotebook.add(generationSetupWindow, text="Generation Setup") + self.generationSetupWindow = generation_page(self.randomizerNotebook) + self.randomizerNotebook.add(self.generationSetupWindow, text="Generation Setup") # add randomizer notebook to main window - randomizerNotebook.pack() + self.randomizerNotebook.pack() - bottomFrame = Frame(randomizerWindow, pady=5) - - seedLabel = Label(farBottomFrame, text='Seed #') - seedVar = StringVar() - seedEntry = Entry(farBottomFrame, width=15, textvariable=seedVar) - countLabel = Label(farBottomFrame, text='Count') - countVar = StringVar() - countSpinbox = Spinbox(farBottomFrame, from_=1, to=100, width=5, textvariable=countVar) - - def generateRom(): - guiargs = Namespace() - guiargs.multi = int(multiworldWindow.worldVar.get()) - guiargs.names = multiworldWindow.namesVar.get() - guiargs.seed = int(seedVar.get()) if seedVar.get() else None - guiargs.count = int(countVar.get()) if countVar.get() != '1' else None - guiargs.mode = itemWindow.modeVar.get() - guiargs.logic = itemWindow.logicVar.get() - - guiargs.goal = itemWindow.goalVar.get() - guiargs.crystals_gt = itemWindow.crystalsGTVar.get() - guiargs.crystals_ganon = itemWindow.crystalsGanonVar.get() - guiargs.swords = itemWindow.swordVar.get() - guiargs.difficulty = itemWindow.difficultyVar.get() - guiargs.item_functionality = itemWindow.itemfunctionVar.get() - guiargs.timer = itemWindow.timerVar.get() - guiargs.progressive = itemWindow.progressiveVar.get() - guiargs.accessibility = itemWindow.accessibilityVar.get() - guiargs.algorithm = itemWindow.algorithmVar.get() - guiargs.shuffle = entrandoWindow.shuffleVar.get() - guiargs.door_shuffle = dungeonRandoWindow.doorShuffleVar.get() - guiargs.heartbeep = gameOptionsWindow.heartbeepVar.get() - guiargs.heartcolor = gameOptionsWindow.heartcolorVar.get() - guiargs.fastmenu = gameOptionsWindow.fastMenuVar.get() - guiargs.create_spoiler = bool(generationSetupWindow.createSpoilerVar.get()) - guiargs.skip_playthrough = not bool(generationSetupWindow.createSpoilerVar.get()) - guiargs.suppress_rom = bool(generationSetupWindow.suppressRomVar.get()) - guiargs.openpyramid = bool(entrandoWindow.openpyramidVar.get()) - guiargs.mapshuffle = bool(dungeonRandoWindow.mapshuffleVar.get()) - guiargs.compassshuffle = bool(dungeonRandoWindow.compassshuffleVar.get()) - guiargs.keyshuffle = bool(dungeonRandoWindow.keyshuffleVar.get()) - guiargs.bigkeyshuffle = bool(dungeonRandoWindow.bigkeyshuffleVar.get()) - guiargs.retro = bool(itemWindow.retroVar.get()) - guiargs.quickswap = bool(gameOptionsWindow.quickSwapVar.get()) - guiargs.disablemusic = bool(gameOptionsWindow.disableMusicVar.get()) - guiargs.ow_palettes = gameOptionsWindow.owPalettesVar.get() - guiargs.uw_palettes = gameOptionsWindow.uwPalettesVar.get() - guiargs.shuffleganon = bool(entrandoWindow.shuffleGanonVar.get()) - guiargs.hints = bool(gameOptionsWindow.hintsVar.get()) - guiargs.enemizercli = enemizerWindow.enemizerCLIpathVar.get() - guiargs.shufflebosses = enemizerWindow.enemizerBossVar.get() - guiargs.shuffleenemies = enemizerWindow.enemyShuffleVar.get() - guiargs.enemy_health = enemizerWindow.enemizerHealthVar.get() - guiargs.enemy_damage = enemizerWindow.enemizerDamageVar.get() - guiargs.shufflepots = bool(enemizerWindow.potShuffleVar.get()) - guiargs.custom = bool(generationSetupWindow.customVar.get()) - guiargs.customitemarray = [int(bowVar.get()), int(silverarrowVar.get()), int(boomerangVar.get()), int(magicboomerangVar.get()), int(hookshotVar.get()), int(mushroomVar.get()), int(magicpowderVar.get()), int(firerodVar.get()), - int(icerodVar.get()), int(bombosVar.get()), int(etherVar.get()), int(quakeVar.get()), int(lampVar.get()), int(hammerVar.get()), int(shovelVar.get()), int(fluteVar.get()), int(bugnetVar.get()), - int(bookVar.get()), int(bottleVar.get()), int(somariaVar.get()), int(byrnaVar.get()), int(capeVar.get()), int(mirrorVar.get()), int(bootsVar.get()), int(powergloveVar.get()), int(titansmittVar.get()), - int(proggloveVar.get()), int(flippersVar.get()), int(pearlVar.get()), int(heartpieceVar.get()), int(fullheartVar.get()), int(sancheartVar.get()), int(sword1Var.get()), int(sword2Var.get()), - int(sword3Var.get()), int(sword4Var.get()), int(progswordVar.get()), int(shield1Var.get()), int(shield2Var.get()), int(shield3Var.get()), int(progshieldVar.get()), int(bluemailVar.get()), - int(redmailVar.get()), int(progmailVar.get()), int(halfmagicVar.get()), int(quartermagicVar.get()), int(bcap5Var.get()), int(bcap10Var.get()), int(acap5Var.get()), int(acap10Var.get()), - int(arrow1Var.get()), int(arrow10Var.get()), int(bomb1Var.get()), int(bomb3Var.get()), int(rupee1Var.get()), int(rupee5Var.get()), int(rupee20Var.get()), int(rupee50Var.get()), int(rupee100Var.get()), - int(rupee300Var.get()), int(rupoorVar.get()), int(blueclockVar.get()), int(greenclockVar.get()), int(redclockVar.get()), int(progbowVar.get()), int(bomb10Var.get()), int(triforcepieceVar.get()), - int(triforcecountVar.get()), int(triforceVar.get()), int(rupoorcostVar.get()), int(universalkeyVar.get())] - guiargs.rom = generationSetupWindow.romVar.get() -# guiargs.sprite = gameOptionsWindow.sprite - guiargs.outputpath = args.outputpath if args else None - # get default values for missing parameters - for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items(): - if k not in vars(guiargs): - setattr(guiargs, k, v) - elif type(v) is dict: # use same settings for every player - setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, guiargs.multi + 1)}) - try: - if guiargs.count is not None: - seed = guiargs.seed - for _ in range(guiargs.count): - main(seed=seed, args=guiargs) - seed = random.randint(0, 999999999) - else: - main(seed=guiargs.seed, args=guiargs) - except Exception as e: - logging.exception(e) - messagebox.showerror(title="Error while creating seed", message=str(e)) - else: - messagebox.showinfo(title="Success", message="Rom patched successfully") - - generateButton = Button(farBottomFrame, text='Generate Patched Rom', command=generateRom) - - seedLabel.pack(side=LEFT, padx=(5, 0)) - seedEntry.pack(side=LEFT) - countLabel.pack(side=LEFT, padx=(5, 0)) - countSpinbox.pack(side=LEFT) - generateButton.pack(side=LEFT, padx=(5, 0)) - - openOutputButton.pack(side=RIGHT) - - bottomFrame.pack(side=BOTTOM) + # bottom of window: Open Output Directory, Open Documentation (if exists) + self.farBottomFrame = bottom_frame(self,self,None) + # set bottom frame to main window + self.farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) # Adjuster Controls - topFrame2 = Frame(adjustWindow) + topFrame2 = Frame(self.adjustWindow) rightHalfFrame2 = Frame(topFrame2) checkBoxFrame2 = Frame(rightHalfFrame2) - quickSwapCheckbutton2 = Checkbutton(checkBoxFrame2, text="Enabled L/R Item quickswapping", variable=gameOptionsWindow.quickSwapVar) - disableMusicCheckbutton2 = Checkbutton(checkBoxFrame2, text="Disable game music", variable=gameOptionsWindow.disableMusicVar) + quickSwapCheckbutton2 = Checkbutton(checkBoxFrame2, text="Enabled L/R Item quickswapping", variable=self.gameOptionsWindow.quickSwapVar) + disableMusicCheckbutton2 = Checkbutton(checkBoxFrame2, text="Disable game music", variable=self.gameOptionsWindow.disableMusicVar) quickSwapCheckbutton2.pack(expand=True, anchor=W) disableMusicCheckbutton2.pack(expand=True, anchor=W) @@ -233,7 +121,7 @@ def guiMain(args=None): spriteDialogFrame2 = Frame(fileDialogFrame2) baseSpriteLabel2 = Label(spriteDialogFrame2, text='Link Sprite') - spriteEntry2 = Label(spriteDialogFrame2, textvariable=gameOptionsWindow.spriteNameVar) + spriteEntry2 = Label(spriteDialogFrame2, textvariable=self.gameOptionsWindow.spriteNameVar) def SpriteSelectAdjuster(): pass @@ -253,31 +141,31 @@ def guiMain(args=None): drowDownFrame2 = Frame(topFrame2) heartbeepFrame2 = Frame(drowDownFrame2) - heartbeepOptionMenu2 = OptionMenu(heartbeepFrame2, gameOptionsWindow.heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off') + heartbeepOptionMenu2 = OptionMenu(heartbeepFrame2, self.gameOptionsWindow.heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off') heartbeepOptionMenu2.pack(side=RIGHT) heartbeepLabel2 = Label(heartbeepFrame2, text='Heartbeep sound rate') heartbeepLabel2.pack(side=LEFT) heartcolorFrame2 = Frame(drowDownFrame2) - heartcolorOptionMenu2 = OptionMenu(heartcolorFrame2, gameOptionsWindow.heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random') + heartcolorOptionMenu2 = OptionMenu(heartcolorFrame2, self.gameOptionsWindow.heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random') heartcolorOptionMenu2.pack(side=RIGHT) heartcolorLabel2 = Label(heartcolorFrame2, text='Heart color') heartcolorLabel2.pack(side=LEFT) fastMenuFrame2 = Frame(drowDownFrame2) - fastMenuOptionMenu2 = OptionMenu(fastMenuFrame2, gameOptionsWindow.fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half') + fastMenuOptionMenu2 = OptionMenu(fastMenuFrame2, self.gameOptionsWindow.fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half') fastMenuOptionMenu2.pack(side=RIGHT) fastMenuLabel2 = Label(fastMenuFrame2, text='Menu speed') fastMenuLabel2.pack(side=LEFT) owPalettesFrame2 = Frame(drowDownFrame2) - owPalettesOptionMenu2 = OptionMenu(owPalettesFrame2, gameOptionsWindow.owPalettesVar, 'default', 'random', 'blackout') + owPalettesOptionMenu2 = OptionMenu(owPalettesFrame2, self.gameOptionsWindow.owPalettesVar, 'default', 'random', 'blackout') owPalettesOptionMenu2.pack(side=RIGHT) owPalettesLabel2 = Label(owPalettesFrame2, text='Overworld palettes') owPalettesLabel2.pack(side=LEFT) uwPalettesFrame2 = Frame(drowDownFrame2) - uwPalettesOptionMenu2 = OptionMenu(uwPalettesFrame2, gameOptionsWindow.uwPalettesVar, 'default', 'random', 'blackout') + uwPalettesOptionMenu2 = OptionMenu(uwPalettesFrame2, self.gameOptionsWindow.uwPalettesVar, 'default', 'random', 'blackout') uwPalettesOptionMenu2.pack(side=RIGHT) uwPalettesLabel2 = Label(uwPalettesFrame2, text='Dungeon palettes') uwPalettesLabel2.pack(side=LEFT) @@ -292,15 +180,15 @@ def guiMain(args=None): def adjustRom(): guiargs = Namespace() - guiargs.heartbeep = gameOptionsWindow.heartbeepVar.get() - guiargs.heartcolor = gameOptionsWindow.heartcolorVar.get() - guiargs.fastmenu = gameOptionsWindow.fastMenuVar.get() - guiargs.ow_palettes = gameOptionsWindow.owPalettesVar.get() - guiargs.uw_palettes = gameOptionsWindow.uwPalettesVar.get() - guiargs.quickswap = bool(gameOptionsWindow.quickSwapVar.get()) - guiargs.disablemusic = bool(gameOptionsWindow.disableMusicVar.get()) + guiargs.heartbeep = self.gameOptionsWindow.heartbeepVar.get() + guiargs.heartcolor = self.gameOptionsWindow.heartcolorVar.get() + guiargs.fastmenu = self.gameOptionsWindow.fastMenuVar.get() + guiargs.ow_palettes = self.gameOptionsWindow.owPalettesVar.get() + guiargs.uw_palettes = self.gameOptionsWindow.uwPalettesVar.get() + guiargs.quickswap = bool(self.gameOptionsWindow.quickSwapVar.get()) + guiargs.disablemusic = bool(self.gameOptionsWindow.disableMusicVar.get()) guiargs.rom = romVar2.get() - guiargs.baserom = generationSetupWindow.romVar.get() + guiargs.baserom = self.generationSetupWindow.romVar.get() # guiargs.sprite = sprite try: adjust(args=guiargs) @@ -321,7 +209,7 @@ def guiMain(args=None): # Custom Controls - topFrame3 = Frame(customWindow) + topFrame3 = Frame(self.customWindow) def validation(P): if str.isdigit(P) or P == "": @@ -338,568 +226,568 @@ def guiMain(args=None): bowFrame = Frame(itemList1) bowLabel = Label(bowFrame, text='Bow') - bowVar = StringVar(value='0') - bowEntry = Entry(bowFrame, textvariable=bowVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bowVar = StringVar(value='0') + bowEntry = Entry(bowFrame, textvariable=self.customWindow.bowVar, width=3, validate='all', vcmd=vcmd) bowFrame.pack() bowLabel.pack(anchor=W, side=LEFT, padx=(0,53)) bowEntry.pack(anchor=E) progbowFrame = Frame(itemList1) progbowLabel = Label(progbowFrame, text='Prog.Bow') - progbowVar = StringVar(value='2') - progbowEntry = Entry(progbowFrame, textvariable=progbowVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.progbowVar = StringVar(value='2') + progbowEntry = Entry(progbowFrame, textvariable=self.customWindow.progbowVar, width=3, validate='all', vcmd=vcmd) progbowFrame.pack() progbowLabel.pack(anchor=W, side=LEFT, padx=(0,25)) progbowEntry.pack(anchor=E) boomerangFrame = Frame(itemList1) boomerangLabel = Label(boomerangFrame, text='Boomerang') - boomerangVar = StringVar(value='1') - boomerangEntry = Entry(boomerangFrame, textvariable=boomerangVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.boomerangVar = StringVar(value='1') + boomerangEntry = Entry(boomerangFrame, textvariable=self.customWindow.boomerangVar, width=3, validate='all', vcmd=vcmd) boomerangFrame.pack() boomerangLabel.pack(anchor=W, side=LEFT, padx=(0,14)) boomerangEntry.pack(anchor=E) magicboomerangFrame = Frame(itemList1) magicboomerangLabel = Label(magicboomerangFrame, text='M.Boomerang') - magicboomerangVar = StringVar(value='1') - magicboomerangEntry = Entry(magicboomerangFrame, textvariable=magicboomerangVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.magicboomerangVar = StringVar(value='1') + magicboomerangEntry = Entry(magicboomerangFrame, textvariable=self.customWindow.magicboomerangVar, width=3, validate='all', vcmd=vcmd) magicboomerangFrame.pack() magicboomerangLabel.pack(anchor=W, side=LEFT) magicboomerangEntry.pack(anchor=E) hookshotFrame = Frame(itemList1) hookshotLabel = Label(hookshotFrame, text='Hookshot') - hookshotVar = StringVar(value='1') - hookshotEntry = Entry(hookshotFrame, textvariable=hookshotVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.hookshotVar = StringVar(value='1') + hookshotEntry = Entry(hookshotFrame, textvariable=self.customWindow.hookshotVar, width=3, validate='all', vcmd=vcmd) hookshotFrame.pack() hookshotLabel.pack(anchor=W, side=LEFT, padx=(0,24)) hookshotEntry.pack(anchor=E) mushroomFrame = Frame(itemList1) mushroomLabel = Label(mushroomFrame, text='Mushroom') - mushroomVar = StringVar(value='1') - mushroomEntry = Entry(mushroomFrame, textvariable=mushroomVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.mushroomVar = StringVar(value='1') + mushroomEntry = Entry(mushroomFrame, textvariable=self.customWindow.mushroomVar, width=3, validate='all', vcmd=vcmd) mushroomFrame.pack() mushroomLabel.pack(anchor=W, side=LEFT, padx=(0,17)) mushroomEntry.pack(anchor=E) magicpowderFrame = Frame(itemList1) magicpowderLabel = Label(magicpowderFrame, text='Magic Powder') - magicpowderVar = StringVar(value='1') - magicpowderEntry = Entry(magicpowderFrame, textvariable=magicpowderVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.magicpowderVar = StringVar(value='1') + magicpowderEntry = Entry(magicpowderFrame, textvariable=self.customWindow.magicpowderVar, width=3, validate='all', vcmd=vcmd) magicpowderFrame.pack() magicpowderLabel.pack(anchor=W, side=LEFT) magicpowderEntry.pack(anchor=E) firerodFrame = Frame(itemList1) firerodLabel = Label(firerodFrame, text='Fire Rod') - firerodVar = StringVar(value='1') - firerodEntry = Entry(firerodFrame, textvariable=firerodVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.firerodVar = StringVar(value='1') + firerodEntry = Entry(firerodFrame, textvariable=self.customWindow.firerodVar, width=3, validate='all', vcmd=vcmd) firerodFrame.pack() firerodLabel.pack(anchor=W, side=LEFT, padx=(0,33)) firerodEntry.pack(anchor=E) icerodFrame = Frame(itemList1) icerodLabel = Label(icerodFrame, text='Ice Rod') - icerodVar = StringVar(value='1') - icerodEntry = Entry(icerodFrame, textvariable=icerodVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.icerodVar = StringVar(value='1') + icerodEntry = Entry(icerodFrame, textvariable=self.customWindow.icerodVar, width=3, validate='all', vcmd=vcmd) icerodFrame.pack() icerodLabel.pack(anchor=W, side=LEFT, padx=(0,37)) icerodEntry.pack(anchor=E) bombosFrame = Frame(itemList1) bombosLabel = Label(bombosFrame, text='Bombos') - bombosVar = StringVar(value='1') - bombosEntry = Entry(bombosFrame, textvariable=bombosVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bombosVar = StringVar(value='1') + bombosEntry = Entry(bombosFrame, textvariable=self.customWindow.bombosVar, width=3, validate='all', vcmd=vcmd) bombosFrame.pack() bombosLabel.pack(anchor=W, side=LEFT, padx=(0,32)) bombosEntry.pack(anchor=E) etherFrame = Frame(itemList1) etherLabel = Label(etherFrame, text='Ether') - etherVar = StringVar(value='1') - etherEntry = Entry(etherFrame, textvariable=etherVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.etherVar = StringVar(value='1') + etherEntry = Entry(etherFrame, textvariable=self.customWindow.etherVar, width=3, validate='all', vcmd=vcmd) etherFrame.pack() etherLabel.pack(anchor=W, side=LEFT, padx=(0,49)) etherEntry.pack(anchor=E) quakeFrame = Frame(itemList1) quakeLabel = Label(quakeFrame, text='Quake') - quakeVar = StringVar(value='1') - quakeEntry = Entry(quakeFrame, textvariable=quakeVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.quakeVar = StringVar(value='1') + quakeEntry = Entry(quakeFrame, textvariable=self.customWindow.quakeVar, width=3, validate='all', vcmd=vcmd) quakeFrame.pack() quakeLabel.pack(anchor=W, side=LEFT, padx=(0,42)) quakeEntry.pack(anchor=E) lampFrame = Frame(itemList1) lampLabel = Label(lampFrame, text='Lamp') - lampVar = StringVar(value='1') - lampEntry = Entry(lampFrame, textvariable=lampVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.lampVar = StringVar(value='1') + lampEntry = Entry(lampFrame, textvariable=self.customWindow.lampVar, width=3, validate='all', vcmd=vcmd) lampFrame.pack() lampLabel.pack(anchor=W, side=LEFT, padx=(0,46)) lampEntry.pack(anchor=E) hammerFrame = Frame(itemList1) hammerLabel = Label(hammerFrame, text='Hammer') - hammerVar = StringVar(value='1') - hammerEntry = Entry(hammerFrame, textvariable=hammerVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.hammerVar = StringVar(value='1') + hammerEntry = Entry(hammerFrame, textvariable=self.customWindow.hammerVar, width=3, validate='all', vcmd=vcmd) hammerFrame.pack() hammerLabel.pack(anchor=W, side=LEFT, padx=(0,29)) hammerEntry.pack(anchor=E) shovelFrame = Frame(itemList1) shovelLabel = Label(shovelFrame, text='Shovel') - shovelVar = StringVar(value='1') - shovelEntry = Entry(shovelFrame, textvariable=shovelVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.shovelVar = StringVar(value='1') + shovelEntry = Entry(shovelFrame, textvariable=self.customWindow.shovelVar, width=3, validate='all', vcmd=vcmd) shovelFrame.pack() shovelLabel.pack(anchor=W, side=LEFT, padx=(0,41)) shovelEntry.pack(anchor=E) fluteFrame = Frame(itemList1) fluteLabel = Label(fluteFrame, text='Flute') - fluteVar = StringVar(value='1') - fluteEntry = Entry(fluteFrame, textvariable=fluteVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.fluteVar = StringVar(value='1') + fluteEntry = Entry(fluteFrame, textvariable=self.customWindow.fluteVar, width=3, validate='all', vcmd=vcmd) fluteFrame.pack() fluteLabel.pack(anchor=W, side=LEFT, padx=(0,50)) fluteEntry.pack(anchor=E) bugnetFrame = Frame(itemList2) bugnetLabel = Label(bugnetFrame, text='Bug Net') - bugnetVar = StringVar(value='1') - bugnetEntry = Entry(bugnetFrame, textvariable=bugnetVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bugnetVar = StringVar(value='1') + bugnetEntry = Entry(bugnetFrame, textvariable=self.customWindow.bugnetVar, width=3, validate='all', vcmd=vcmd) bugnetFrame.pack() bugnetLabel.pack(anchor=W, side=LEFT, padx=(0,41)) bugnetEntry.pack(anchor=E) bookFrame = Frame(itemList2) bookLabel = Label(bookFrame, text='Book') - bookVar = StringVar(value='1') - bookEntry = Entry(bookFrame, textvariable=bookVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bookVar = StringVar(value='1') + bookEntry = Entry(bookFrame, textvariable=self.customWindow.bookVar, width=3, validate='all', vcmd=vcmd) bookFrame.pack() bookLabel.pack(anchor=W, side=LEFT, padx=(0,57)) bookEntry.pack(anchor=E) bottleFrame = Frame(itemList2) bottleLabel = Label(bottleFrame, text='Bottle') - bottleVar = StringVar(value='4') - bottleEntry = Entry(bottleFrame, textvariable=bottleVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bottleVar = StringVar(value='4') + bottleEntry = Entry(bottleFrame, textvariable=self.customWindow.bottleVar, width=3, validate='all', vcmd=vcmd) bottleFrame.pack() bottleLabel.pack(anchor=W, side=LEFT, padx=(0,53)) bottleEntry.pack(anchor=E) somariaFrame = Frame(itemList2) somariaLabel = Label(somariaFrame, text='C.Somaria') - somariaVar = StringVar(value='1') - somariaEntry = Entry(somariaFrame, textvariable=somariaVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.somariaVar = StringVar(value='1') + somariaEntry = Entry(somariaFrame, textvariable=self.customWindow.somariaVar, width=3, validate='all', vcmd=vcmd) somariaFrame.pack() somariaLabel.pack(anchor=W, side=LEFT, padx=(0,30)) somariaEntry.pack(anchor=E) byrnaFrame = Frame(itemList2) byrnaLabel = Label(byrnaFrame, text='C.Byrna') - byrnaVar = StringVar(value='1') - byrnaEntry = Entry(byrnaFrame, textvariable=byrnaVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.byrnaVar = StringVar(value='1') + byrnaEntry = Entry(byrnaFrame, textvariable=self.customWindow.byrnaVar, width=3, validate='all', vcmd=vcmd) byrnaFrame.pack() byrnaLabel.pack(anchor=W, side=LEFT, padx=(0,43)) byrnaEntry.pack(anchor=E) capeFrame = Frame(itemList2) capeLabel = Label(capeFrame, text='Magic Cape') - capeVar = StringVar(value='1') - capeEntry = Entry(capeFrame, textvariable=capeVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.capeVar = StringVar(value='1') + capeEntry = Entry(capeFrame, textvariable=self.customWindow.capeVar, width=3, validate='all', vcmd=vcmd) capeFrame.pack() capeLabel.pack(anchor=W, side=LEFT, padx=(0,21)) capeEntry.pack(anchor=E) mirrorFrame = Frame(itemList2) mirrorLabel = Label(mirrorFrame, text='Magic Mirror') - mirrorVar = StringVar(value='1') - mirrorEntry = Entry(mirrorFrame, textvariable=mirrorVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.mirrorVar = StringVar(value='1') + mirrorEntry = Entry(mirrorFrame, textvariable=self.customWindow.mirrorVar, width=3, validate='all', vcmd=vcmd) mirrorFrame.pack() mirrorLabel.pack(anchor=W, side=LEFT, padx=(0,15)) mirrorEntry.pack(anchor=E) bootsFrame = Frame(itemList2) bootsLabel = Label(bootsFrame, text='Pegasus Boots') - bootsVar = StringVar(value='1') - bootsEntry = Entry(bootsFrame, textvariable=bootsVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bootsVar = StringVar(value='1') + bootsEntry = Entry(bootsFrame, textvariable=self.customWindow.bootsVar, width=3, validate='all', vcmd=vcmd) bootsFrame.pack() bootsLabel.pack(anchor=W, side=LEFT, padx=(0,8)) bootsEntry.pack(anchor=E) powergloveFrame = Frame(itemList2) powergloveLabel = Label(powergloveFrame, text='Power Glove') - powergloveVar = StringVar(value='0') - powergloveEntry = Entry(powergloveFrame, textvariable=powergloveVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.powergloveVar = StringVar(value='0') + powergloveEntry = Entry(powergloveFrame, textvariable=self.customWindow.powergloveVar, width=3, validate='all', vcmd=vcmd) powergloveFrame.pack() powergloveLabel.pack(anchor=W, side=LEFT, padx=(0,18)) powergloveEntry.pack(anchor=E) titansmittFrame = Frame(itemList2) titansmittLabel = Label(titansmittFrame, text='Titan\'s Mitt') - titansmittVar = StringVar(value='0') - titansmittEntry = Entry(titansmittFrame, textvariable=titansmittVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.titansmittVar = StringVar(value='0') + titansmittEntry = Entry(titansmittFrame, textvariable=self.customWindow.titansmittVar, width=3, validate='all', vcmd=vcmd) titansmittFrame.pack() titansmittLabel.pack(anchor=W, side=LEFT, padx=(0,24)) titansmittEntry.pack(anchor=E) proggloveFrame = Frame(itemList2) proggloveLabel = Label(proggloveFrame, text='Prog.Glove') - proggloveVar = StringVar(value='2') - proggloveEntry = Entry(proggloveFrame, textvariable=proggloveVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.proggloveVar = StringVar(value='2') + proggloveEntry = Entry(proggloveFrame, textvariable=self.customWindow.proggloveVar, width=3, validate='all', vcmd=vcmd) proggloveFrame.pack() proggloveLabel.pack(anchor=W, side=LEFT, padx=(0,26)) proggloveEntry.pack(anchor=E) flippersFrame = Frame(itemList2) flippersLabel = Label(flippersFrame, text='Flippers') - flippersVar = StringVar(value='1') - flippersEntry = Entry(flippersFrame, textvariable=flippersVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.flippersVar = StringVar(value='1') + flippersEntry = Entry(flippersFrame, textvariable=self.customWindow.flippersVar, width=3, validate='all', vcmd=vcmd) flippersFrame.pack() flippersLabel.pack(anchor=W, side=LEFT, padx=(0,43)) flippersEntry.pack(anchor=E) pearlFrame = Frame(itemList2) pearlLabel = Label(pearlFrame, text='Moon Pearl') - pearlVar = StringVar(value='1') - pearlEntry = Entry(pearlFrame, textvariable=pearlVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.pearlVar = StringVar(value='1') + pearlEntry = Entry(pearlFrame, textvariable=self.customWindow.pearlVar, width=3, validate='all', vcmd=vcmd) pearlFrame.pack() pearlLabel.pack(anchor=W, side=LEFT, padx=(0,23)) pearlEntry.pack(anchor=E) heartpieceFrame = Frame(itemList2) heartpieceLabel = Label(heartpieceFrame, text='Piece of Heart') - heartpieceVar = StringVar(value='24') - heartpieceEntry = Entry(heartpieceFrame, textvariable=heartpieceVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.heartpieceVar = StringVar(value='24') + heartpieceEntry = Entry(heartpieceFrame, textvariable=self.customWindow.heartpieceVar, width=3, validate='all', vcmd=vcmd) heartpieceFrame.pack() heartpieceLabel.pack(anchor=W, side=LEFT, padx=(0,10)) heartpieceEntry.pack(anchor=E) fullheartFrame = Frame(itemList2) fullheartLabel = Label(fullheartFrame, text='Heart Container') - fullheartVar = StringVar(value='10') - fullheartEntry = Entry(fullheartFrame, textvariable=fullheartVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.fullheartVar = StringVar(value='10') + fullheartEntry = Entry(fullheartFrame, textvariable=self.customWindow.fullheartVar, width=3, validate='all', vcmd=vcmd) fullheartFrame.pack() fullheartLabel.pack(anchor=W, side=LEFT) fullheartEntry.pack(anchor=E) sancheartFrame = Frame(itemList2) sancheartLabel = Label(sancheartFrame, text='Sanctuary Heart') - sancheartVar = StringVar(value='1') - sancheartEntry = Entry(sancheartFrame, textvariable=sancheartVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.sancheartVar = StringVar(value='1') + sancheartEntry = Entry(sancheartFrame, textvariable=self.customWindow.sancheartVar, width=3, validate='all', vcmd=vcmd) sancheartFrame.pack() sancheartLabel.pack(anchor=W, side=LEFT) sancheartEntry.pack(anchor=E) sword1Frame = Frame(itemList3) sword1Label = Label(sword1Frame, text='Sword 1') - sword1Var = StringVar(value='0') - sword1Entry = Entry(sword1Frame, textvariable=sword1Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.sword1Var = StringVar(value='0') + sword1Entry = Entry(sword1Frame, textvariable=self.customWindow.sword1Var, width=3, validate='all', vcmd=vcmd) sword1Frame.pack() sword1Label.pack(anchor=W, side=LEFT, padx=(0,34)) sword1Entry.pack(anchor=E) sword2Frame = Frame(itemList3) sword2Label = Label(sword2Frame, text='Sword 2') - sword2Var = StringVar(value='0') - sword2Entry = Entry(sword2Frame, textvariable=sword2Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.sword2Var = StringVar(value='0') + sword2Entry = Entry(sword2Frame, textvariable=self.customWindow.sword2Var, width=3, validate='all', vcmd=vcmd) sword2Frame.pack() sword2Label.pack(anchor=W, side=LEFT, padx=(0,34)) sword2Entry.pack(anchor=E) sword3Frame = Frame(itemList3) sword3Label = Label(sword3Frame, text='Sword 3') - sword3Var = StringVar(value='0') - sword3Entry = Entry(sword3Frame, textvariable=sword3Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.sword3Var = StringVar(value='0') + sword3Entry = Entry(sword3Frame, textvariable=self.customWindow.sword3Var, width=3, validate='all', vcmd=vcmd) sword3Frame.pack() sword3Label.pack(anchor=W, side=LEFT, padx=(0,34)) sword3Entry.pack(anchor=E) sword4Frame = Frame(itemList3) sword4Label = Label(sword4Frame, text='Sword 4') - sword4Var = StringVar(value='0') - sword4Entry = Entry(sword4Frame, textvariable=sword4Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.sword4Var = StringVar(value='0') + sword4Entry = Entry(sword4Frame, textvariable=self.customWindow.sword4Var, width=3, validate='all', vcmd=vcmd) sword4Frame.pack() sword4Label.pack(anchor=W, side=LEFT, padx=(0,34)) sword4Entry.pack(anchor=E) progswordFrame = Frame(itemList3) progswordLabel = Label(progswordFrame, text='Prog.Sword') - progswordVar = StringVar(value='4') - progswordEntry = Entry(progswordFrame, textvariable=progswordVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.progswordVar = StringVar(value='4') + progswordEntry = Entry(progswordFrame, textvariable=self.customWindow.progswordVar, width=3, validate='all', vcmd=vcmd) progswordFrame.pack() progswordLabel.pack(anchor=W, side=LEFT, padx=(0,15)) progswordEntry.pack(anchor=E) shield1Frame = Frame(itemList3) shield1Label = Label(shield1Frame, text='Shield 1') - shield1Var = StringVar(value='0') - shield1Entry = Entry(shield1Frame, textvariable=shield1Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.shield1Var = StringVar(value='0') + shield1Entry = Entry(shield1Frame, textvariable=self.customWindow.shield1Var, width=3, validate='all', vcmd=vcmd) shield1Frame.pack() shield1Label.pack(anchor=W, side=LEFT, padx=(0,35)) shield1Entry.pack(anchor=E) shield2Frame = Frame(itemList3) shield2Label = Label(shield2Frame, text='Shield 2') - shield2Var = StringVar(value='0') - shield2Entry = Entry(shield2Frame, textvariable=shield2Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.shield2Var = StringVar(value='0') + shield2Entry = Entry(shield2Frame, textvariable=self.customWindow.shield2Var, width=3, validate='all', vcmd=vcmd) shield2Frame.pack() shield2Label.pack(anchor=W, side=LEFT, padx=(0,35)) shield2Entry.pack(anchor=E) shield3Frame = Frame(itemList3) shield3Label = Label(shield3Frame, text='Shield 3') - shield3Var = StringVar(value='0') - shield3Entry = Entry(shield3Frame, textvariable=shield3Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.shield3Var = StringVar(value='0') + shield3Entry = Entry(shield3Frame, textvariable=self.customWindow.shield3Var, width=3, validate='all', vcmd=vcmd) shield3Frame.pack() shield3Label.pack(anchor=W, side=LEFT, padx=(0,35)) shield3Entry.pack(anchor=E) progshieldFrame = Frame(itemList3) progshieldLabel = Label(progshieldFrame, text='Prog.Shield') - progshieldVar = StringVar(value='3') - progshieldEntry = Entry(progshieldFrame, textvariable=progshieldVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.progshieldVar = StringVar(value='3') + progshieldEntry = Entry(progshieldFrame, textvariable=self.customWindow.progshieldVar, width=3, validate='all', vcmd=vcmd) progshieldFrame.pack() progshieldLabel.pack(anchor=W, side=LEFT, padx=(0,16)) progshieldEntry.pack(anchor=E) bluemailFrame = Frame(itemList3) bluemailLabel = Label(bluemailFrame, text='Blue Mail') - bluemailVar = StringVar(value='0') - bluemailEntry = Entry(bluemailFrame, textvariable=bluemailVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.bluemailVar = StringVar(value='0') + bluemailEntry = Entry(bluemailFrame, textvariable=self.customWindow.bluemailVar, width=3, validate='all', vcmd=vcmd) bluemailFrame.pack() bluemailLabel.pack(anchor=W, side=LEFT, padx=(0,27)) bluemailEntry.pack(anchor=E) redmailFrame = Frame(itemList3) redmailLabel = Label(redmailFrame, text='Red Mail') - redmailVar = StringVar(value='0') - redmailEntry = Entry(redmailFrame, textvariable=redmailVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.redmailVar = StringVar(value='0') + redmailEntry = Entry(redmailFrame, textvariable=self.customWindow.redmailVar, width=3, validate='all', vcmd=vcmd) redmailFrame.pack() redmailLabel.pack(anchor=W, side=LEFT, padx=(0,30)) redmailEntry.pack(anchor=E) progmailFrame = Frame(itemList3) progmailLabel = Label(progmailFrame, text='Prog.Mail') - progmailVar = StringVar(value='2') - progmailEntry = Entry(progmailFrame, textvariable=progmailVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.progmailVar = StringVar(value='2') + progmailEntry = Entry(progmailFrame, textvariable=self.customWindow.progmailVar, width=3, validate='all', vcmd=vcmd) progmailFrame.pack() progmailLabel.pack(anchor=W, side=LEFT, padx=(0,25)) progmailEntry.pack(anchor=E) halfmagicFrame = Frame(itemList3) halfmagicLabel = Label(halfmagicFrame, text='Half Magic') - halfmagicVar = StringVar(value='1') - halfmagicEntry = Entry(halfmagicFrame, textvariable=halfmagicVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.halfmagicVar = StringVar(value='1') + halfmagicEntry = Entry(halfmagicFrame, textvariable=self.customWindow.halfmagicVar, width=3, validate='all', vcmd=vcmd) halfmagicFrame.pack() halfmagicLabel.pack(anchor=W, side=LEFT, padx=(0,18)) halfmagicEntry.pack(anchor=E) quartermagicFrame = Frame(itemList3) quartermagicLabel = Label(quartermagicFrame, text='Quarter Magic') - quartermagicVar = StringVar(value='0') - quartermagicEntry = Entry(quartermagicFrame, textvariable=quartermagicVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.quartermagicVar = StringVar(value='0') + quartermagicEntry = Entry(quartermagicFrame, textvariable=self.customWindow.quartermagicVar, width=3, validate='all', vcmd=vcmd) quartermagicFrame.pack() quartermagicLabel.pack(anchor=W, side=LEFT) quartermagicEntry.pack(anchor=E) bcap5Frame = Frame(itemList3) bcap5Label = Label(bcap5Frame, text='Bomb C.+5') - bcap5Var = StringVar(value='0') - bcap5Entry = Entry(bcap5Frame, textvariable=bcap5Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.bcap5Var = StringVar(value='0') + bcap5Entry = Entry(bcap5Frame, textvariable=self.customWindow.bcap5Var, width=3, validate='all', vcmd=vcmd) bcap5Frame.pack() bcap5Label.pack(anchor=W, side=LEFT, padx=(0,16)) bcap5Entry.pack(anchor=E) bcap10Frame = Frame(itemList3) bcap10Label = Label(bcap10Frame, text='Bomb C.+10') - bcap10Var = StringVar(value='0') - bcap10Entry = Entry(bcap10Frame, textvariable=bcap10Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.bcap10Var = StringVar(value='0') + bcap10Entry = Entry(bcap10Frame, textvariable=self.customWindow.bcap10Var, width=3, validate='all', vcmd=vcmd) bcap10Frame.pack() bcap10Label.pack(anchor=W, side=LEFT, padx=(0,10)) bcap10Entry.pack(anchor=E) acap5Frame = Frame(itemList4) acap5Label = Label(acap5Frame, text='Arrow C.+5') - acap5Var = StringVar(value='0') - acap5Entry = Entry(acap5Frame, textvariable=acap5Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.acap5Var = StringVar(value='0') + acap5Entry = Entry(acap5Frame, textvariable=self.customWindow.acap5Var, width=3, validate='all', vcmd=vcmd) acap5Frame.pack() acap5Label.pack(anchor=W, side=LEFT, padx=(0,7)) acap5Entry.pack(anchor=E) acap10Frame = Frame(itemList4) acap10Label = Label(acap10Frame, text='Arrow C.+10') - acap10Var = StringVar(value='0') - acap10Entry = Entry(acap10Frame, textvariable=acap10Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.acap10Var = StringVar(value='0') + acap10Entry = Entry(acap10Frame, textvariable=self.customWindow.acap10Var, width=3, validate='all', vcmd=vcmd) acap10Frame.pack() acap10Label.pack(anchor=W, side=LEFT, padx=(0,1)) acap10Entry.pack(anchor=E) arrow1Frame = Frame(itemList4) arrow1Label = Label(arrow1Frame, text='Arrow (1)') - arrow1Var = StringVar(value='1') - arrow1Entry = Entry(arrow1Frame, textvariable=arrow1Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.arrow1Var = StringVar(value='1') + arrow1Entry = Entry(arrow1Frame, textvariable=self.customWindow.arrow1Var, width=3, validate='all', vcmd=vcmd) arrow1Frame.pack() arrow1Label.pack(anchor=W, side=LEFT, padx=(0,18)) arrow1Entry.pack(anchor=E) arrow10Frame = Frame(itemList4) arrow10Label = Label(arrow10Frame, text='Arrows (10)') - arrow10Var = StringVar(value='12') - arrow10Entry = Entry(arrow10Frame, textvariable=arrow10Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.arrow10Var = StringVar(value='12') + arrow10Entry = Entry(arrow10Frame, textvariable=self.customWindow.arrow10Var, width=3, validate='all', vcmd=vcmd) arrow10Frame.pack() arrow10Label.pack(anchor=W, side=LEFT, padx=(0,7)) arrow10Entry.pack(anchor=E) bomb1Frame = Frame(itemList4) bomb1Label = Label(bomb1Frame, text='Bomb (1)') - bomb1Var = StringVar(value='0') - bomb1Entry = Entry(bomb1Frame, textvariable=bomb1Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.bomb1Var = StringVar(value='0') + bomb1Entry = Entry(bomb1Frame, textvariable=self.customWindow.bomb1Var, width=3, validate='all', vcmd=vcmd) bomb1Frame.pack() bomb1Label.pack(anchor=W, side=LEFT, padx=(0,18)) bomb1Entry.pack(anchor=E) bomb3Frame = Frame(itemList4) bomb3Label = Label(bomb3Frame, text='Bombs (3)') - bomb3Var = StringVar(value='16') - bomb3Entry = Entry(bomb3Frame, textvariable=bomb3Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.bomb3Var = StringVar(value='16') + bomb3Entry = Entry(bomb3Frame, textvariable=self.customWindow.bomb3Var, width=3, validate='all', vcmd=vcmd) bomb3Frame.pack() bomb3Label.pack(anchor=W, side=LEFT, padx=(0,13)) bomb3Entry.pack(anchor=E) bomb10Frame = Frame(itemList4) bomb10Label = Label(bomb10Frame, text='Bombs (10)') - bomb10Var = StringVar(value='1') - bomb10Entry = Entry(bomb10Frame, textvariable=bomb10Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.bomb10Var = StringVar(value='1') + bomb10Entry = Entry(bomb10Frame, textvariable=self.customWindow.bomb10Var, width=3, validate='all', vcmd=vcmd) bomb10Frame.pack() bomb10Label.pack(anchor=W, side=LEFT, padx=(0,7)) bomb10Entry.pack(anchor=E) rupee1Frame = Frame(itemList4) rupee1Label = Label(rupee1Frame, text='Rupee (1)') - rupee1Var = StringVar(value='2') - rupee1Entry = Entry(rupee1Frame, textvariable=rupee1Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee1Var = StringVar(value='2') + rupee1Entry = Entry(rupee1Frame, textvariable=self.customWindow.rupee1Var, width=3, validate='all', vcmd=vcmd) rupee1Frame.pack() rupee1Label.pack(anchor=W, side=LEFT, padx=(0,17)) rupee1Entry.pack(anchor=E) rupee5Frame = Frame(itemList4) rupee5Label = Label(rupee5Frame, text='Rupees (5)') - rupee5Var = StringVar(value='4') - rupee5Entry = Entry(rupee5Frame, textvariable=rupee5Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee5Var = StringVar(value='4') + rupee5Entry = Entry(rupee5Frame, textvariable=self.customWindow.rupee5Var, width=3, validate='all', vcmd=vcmd) rupee5Frame.pack() rupee5Label.pack(anchor=W, side=LEFT, padx=(0,12)) rupee5Entry.pack(anchor=E) rupee20Frame = Frame(itemList4) rupee20Label = Label(rupee20Frame, text='Rupees (20)') - rupee20Var = StringVar(value='28') - rupee20Entry = Entry(rupee20Frame, textvariable=rupee20Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee20Var = StringVar(value='28') + rupee20Entry = Entry(rupee20Frame, textvariable=self.customWindow.rupee20Var, width=3, validate='all', vcmd=vcmd) rupee20Frame.pack() rupee20Label.pack(anchor=W, side=LEFT, padx=(0,6)) rupee20Entry.pack(anchor=E) rupee50Frame = Frame(itemList4) rupee50Label = Label(rupee50Frame, text='Rupees (50)') - rupee50Var = StringVar(value='7') - rupee50Entry = Entry(rupee50Frame, textvariable=rupee50Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee50Var = StringVar(value='7') + rupee50Entry = Entry(rupee50Frame, textvariable=self.customWindow.rupee50Var, width=3, validate='all', vcmd=vcmd) rupee50Frame.pack() rupee50Label.pack(anchor=W, side=LEFT, padx=(0,6)) rupee50Entry.pack(anchor=E) rupee100Frame = Frame(itemList4) rupee100Label = Label(rupee100Frame, text='Rupees (100)') - rupee100Var = StringVar(value='1') - rupee100Entry = Entry(rupee100Frame, textvariable=rupee100Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee100Var = StringVar(value='1') + rupee100Entry = Entry(rupee100Frame, textvariable=self.customWindow.rupee100Var, width=3, validate='all', vcmd=vcmd) rupee100Frame.pack() rupee100Label.pack(anchor=W, side=LEFT, padx=(0,0)) rupee100Entry.pack(anchor=E) rupee300Frame = Frame(itemList4) rupee300Label = Label(rupee300Frame, text='Rupees (300)') - rupee300Var = StringVar(value='5') - rupee300Entry = Entry(rupee300Frame, textvariable=rupee300Var, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupee300Var = StringVar(value='5') + rupee300Entry = Entry(rupee300Frame, textvariable=self.customWindow.rupee300Var, width=3, validate='all', vcmd=vcmd) rupee300Frame.pack() rupee300Label.pack(anchor=W, side=LEFT, padx=(0,0)) rupee300Entry.pack(anchor=E) blueclockFrame = Frame(itemList4) blueclockLabel = Label(blueclockFrame, text='Blue Clock') - blueclockVar = StringVar(value='0') - blueclockEntry = Entry(blueclockFrame, textvariable=blueclockVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.blueclockVar = StringVar(value='0') + blueclockEntry = Entry(blueclockFrame, textvariable=self.customWindow.blueclockVar, width=3, validate='all', vcmd=vcmd) blueclockFrame.pack() blueclockLabel.pack(anchor=W, side=LEFT, padx=(0,11)) blueclockEntry.pack(anchor=E) greenclockFrame = Frame(itemList4) greenclockLabel = Label(greenclockFrame, text='Green Clock') - greenclockVar = StringVar(value='0') - greenclockEntry = Entry(greenclockFrame, textvariable=greenclockVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.greenclockVar = StringVar(value='0') + greenclockEntry = Entry(greenclockFrame, textvariable=self.customWindow.greenclockVar, width=3, validate='all', vcmd=vcmd) greenclockFrame.pack() greenclockLabel.pack(anchor=W, side=LEFT, padx=(0,3)) greenclockEntry.pack(anchor=E) redclockFrame = Frame(itemList4) redclockLabel = Label(redclockFrame, text='Red Clock') - redclockVar = StringVar(value='0') - redclockEntry = Entry(redclockFrame, textvariable=redclockVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.redclockVar = StringVar(value='0') + redclockEntry = Entry(redclockFrame, textvariable=self.customWindow.redclockVar, width=3, validate='all', vcmd=vcmd) redclockFrame.pack() redclockLabel.pack(anchor=W, side=LEFT, padx=(0,14)) redclockEntry.pack(anchor=E) silverarrowFrame = Frame(itemList5) silverarrowLabel = Label(silverarrowFrame, text='Silver Arrow') - silverarrowVar = StringVar(value='0') - silverarrowEntry = Entry(silverarrowFrame, textvariable=silverarrowVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.silverarrowVar = StringVar(value='0') + silverarrowEntry = Entry(silverarrowFrame, textvariable=self.customWindow.silverarrowVar, width=3, validate='all', vcmd=vcmd) silverarrowFrame.pack() silverarrowLabel.pack(anchor=W, side=LEFT, padx=(0,64)) silverarrowEntry.pack(anchor=E) universalkeyFrame = Frame(itemList5) universalkeyLabel = Label(universalkeyFrame, text='Universal Key') - universalkeyVar = StringVar(value='0') - universalkeyEntry = Entry(universalkeyFrame, textvariable=universalkeyVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.universalkeyVar = StringVar(value='0') + universalkeyEntry = Entry(universalkeyFrame, textvariable=self.customWindow.universalkeyVar, width=3, validate='all', vcmd=vcmd) universalkeyFrame.pack() universalkeyLabel.pack(anchor=W, side=LEFT, padx=(0,57)) universalkeyEntry.pack(anchor=E) triforcepieceFrame = Frame(itemList5) triforcepieceLabel = Label(triforcepieceFrame, text='Triforce Piece') - triforcepieceVar = StringVar(value='0') - triforcepieceEntry = Entry(triforcepieceFrame, textvariable=triforcepieceVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.triforcepieceVar = StringVar(value='0') + triforcepieceEntry = Entry(triforcepieceFrame, textvariable=self.customWindow.triforcepieceVar, width=3, validate='all', vcmd=vcmd) triforcepieceFrame.pack() triforcepieceLabel.pack(anchor=W, side=LEFT, padx=(0,55)) triforcepieceEntry.pack(anchor=E) triforcecountFrame = Frame(itemList5) triforcecountLabel = Label(triforcecountFrame, text='Triforce Pieces Required') - triforcecountVar = StringVar(value='0') - triforcecountEntry = Entry(triforcecountFrame, textvariable=triforcecountVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.triforcecountVar = StringVar(value='0') + triforcecountEntry = Entry(triforcecountFrame, textvariable=self.customWindow.triforcecountVar, width=3, validate='all', vcmd=vcmd) triforcecountFrame.pack() triforcecountLabel.pack(anchor=W, side=LEFT, padx=(0,0)) triforcecountEntry.pack(anchor=E) triforceFrame = Frame(itemList5) triforceLabel = Label(triforceFrame, text='Triforce (win game)') - triforceVar = StringVar(value='0') - triforceEntry = Entry(triforceFrame, textvariable=triforceVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.triforceVar = StringVar(value='0') + triforceEntry = Entry(triforceFrame, textvariable=self.customWindow.triforceVar, width=3, validate='all', vcmd=vcmd) triforceFrame.pack() triforceLabel.pack(anchor=W, side=LEFT, padx=(0,23)) triforceEntry.pack(anchor=E) rupoorFrame = Frame(itemList5) rupoorLabel = Label(rupoorFrame, text='Rupoor') - rupoorVar = StringVar(value='0') - rupoorEntry = Entry(rupoorFrame, textvariable=rupoorVar, width=3, validate='all', vcmd=vcmd) + self.customWindow.rupoorVar = StringVar(value='0') + rupoorEntry = Entry(rupoorFrame, textvariable=self.customWindow.rupoorVar, width=3, validate='all', vcmd=vcmd) rupoorFrame.pack() rupoorLabel.pack(anchor=W, side=LEFT, padx=(0,87)) rupoorEntry.pack(anchor=E) rupoorcostFrame = Frame(itemList5) rupoorcostLabel = Label(rupoorcostFrame, text='Rupoor Cost') - rupoorcostVar = StringVar(value='10') - rupoorcostEntry = Entry(rupoorcostFrame, textvariable=rupoorcostVar, width=6, validate='all', vcmd=vcmd) + self.customWindow.rupoorcostVar = StringVar(value='10') + rupoorcostEntry = Entry(rupoorcostFrame, textvariable=self.customWindow.rupoorcostVar, width=6, validate='all', vcmd=vcmd) rupoorcostFrame.pack() rupoorcostLabel.pack(anchor=W, side=LEFT, padx=(0,43)) rupoorcostEntry.pack(anchor=E) @@ -916,363 +804,54 @@ def guiMain(args=None): if type(v) is dict: setattr(args, k, v[1]) # only get values for player 1 for now # load values from commandline args - generationSetupWindow.createSpoilerVar.set(int(args.create_spoiler)) - generationSetupWindow.suppressRomVar.set(int(args.suppress_rom)) - dungeonRandoWindow.mapshuffleVar.set(args.mapshuffle) - dungeonRandoWindow.compassshuffleVar.set(args.compassshuffle) - dungeonRandoWindow.keyshuffleVar.set(args.keyshuffle) - dungeonRandoWindow.bigkeyshuffleVar.set(args.bigkeyshuffle) - itemWindow.retroVar.set(args.retro) - entrandoWindow.openpyramidVar.set(args.openpyramid) - gameOptionsWindow.quickSwapVar.set(int(args.quickswap)) - gameOptionsWindow.disableMusicVar.set(int(args.disablemusic)) + self.generationSetupWindow.createSpoilerVar.set(int(args.create_spoiler)) + self.generationSetupWindow.suppressRomVar.set(int(args.suppress_rom)) + self.dungeonRandoWindow.mapshuffleVar.set(args.mapshuffle) + self.dungeonRandoWindow.compassshuffleVar.set(args.compassshuffle) + self.dungeonRandoWindow.keyshuffleVar.set(args.keyshuffle) + self.dungeonRandoWindow.bigkeyshuffleVar.set(args.bigkeyshuffle) + self.itemWindow.retroVar.set(args.retro) + self.entrandoWindow.openpyramidVar.set(args.openpyramid) + self.gameOptionsWindow.quickSwapVar.set(int(args.quickswap)) + self.gameOptionsWindow.disableMusicVar.set(int(args.disablemusic)) if args.multi: - multiworldWindow.worldVar.set(str(args.multi)) + self.multiworldWindow.worldVar.set(str(args.multi)) if args.count: - countVar.set(str(args.count)) + self.farBottomFrame.countVar.set(str(args.count)) if args.seed: - seedVar.set(str(args.seed)) - itemWindow.modeVar.set(args.mode) - itemWindow.swordVar.set(args.swords) - itemWindow.difficultyVar.set(args.difficulty) - itemWindow.itemfunctionVar.set(args.item_functionality) - itemWindow.timerVar.set(args.timer) - itemWindow.progressiveVar.set(args.progressive) - itemWindow.accessibilityVar.set(args.accessibility) - itemWindow.goalVar.set(args.goal) - itemWindow.crystalsGTVar.set(args.crystals_gt) - itemWindow.crystalsGanonVar.set(args.crystals_ganon) - itemWindow.algorithmVar.set(args.algorithm) - entrandoWindow.shuffleVar.set(args.shuffle) - dungeonRandoWindow.doorShuffleVar.set(args.door_shuffle) - gameOptionsWindow.heartcolorVar.set(args.heartcolor) - gameOptionsWindow.heartbeepVar.set(args.heartbeep) - gameOptionsWindow.fastMenuVar.set(args.fastmenu) - itemWindow.logicVar.set(args.logic) - generationSetupWindow.romVar.set(args.rom) - entrandoWindow.shuffleGanonVar.set(args.shuffleganon) - gameOptionsWindow.hintsVar.set(args.hints) - enemizerWindow.enemizerCLIpathVar.set(args.enemizercli) - enemizerWindow.potShuffleVar.set(args.shufflepots) - enemizerWindow.enemyShuffleVar.set(args.shuffleenemies) - enemizerWindow.enemizerBossVar.set(args.shufflebosses) - enemizerWindow.enemizerDamageVar.set(args.enemy_damage) - enemizerWindow.enemizerHealthVar.set(args.enemy_health) - gameOptionsWindow.owPalettesVar.set(args.ow_palettes) - gameOptionsWindow.uwPalettesVar.set(args.uw_palettes) + self.farBottomFrame.seedVar.set(str(args.seed)) + self.itemWindow.modeVar.set(args.mode) + self.itemWindow.swordVar.set(args.swords) + self.itemWindow.difficultyVar.set(args.difficulty) + self.itemWindow.itemfunctionVar.set(args.item_functionality) + self.itemWindow.timerVar.set(args.timer) + self.itemWindow.progressiveVar.set(args.progressive) + self.itemWindow.accessibilityVar.set(args.accessibility) + self.itemWindow.goalVar.set(args.goal) + self.itemWindow.crystalsGTVar.set(args.crystals_gt) + self.itemWindow.crystalsGanonVar.set(args.crystals_ganon) + self.itemWindow.algorithmVar.set(args.algorithm) + self.entrandoWindow.shuffleVar.set(args.shuffle) + self.dungeonRandoWindow.doorShuffleVar.set(args.door_shuffle) + self.gameOptionsWindow.heartcolorVar.set(args.heartcolor) + self.gameOptionsWindow.heartbeepVar.set(args.heartbeep) + self.gameOptionsWindow.fastMenuVar.set(args.fastmenu) + self.itemWindow.logicVar.set(args.logic) + self.generationSetupWindow.romVar.set(args.rom) + self.entrandoWindow.shuffleGanonVar.set(args.shuffleganon) + self.gameOptionsWindow.hintsVar.set(args.hints) + self.enemizerWindow.enemizerCLIpathVar.set(args.enemizercli) + self.enemizerWindow.potShuffleVar.set(args.shufflepots) + self.enemizerWindow.enemyShuffleVar.set(args.shuffleenemies) + self.enemizerWindow.enemizerBossVar.set(args.shufflebosses) + self.enemizerWindow.enemizerDamageVar.set(args.enemy_damage) + self.enemizerWindow.enemizerHealthVar.set(args.enemy_health) + self.gameOptionsWindow.owPalettesVar.set(args.ow_palettes) + self.gameOptionsWindow.uwPalettesVar.set(args.uw_palettes) # if args.sprite is not None: -# gameOptionsWindow.set_sprite(Sprite(args.sprite)) +# self.gameOptionsWindow.set_sprite(Sprite(args.sprite)) mainWindow.mainloop() -class SpriteSelector(object): - def __init__(self, parent, callback, adjuster=False): - if is_bundled(): - self.deploy_icons() - self.parent = parent - self.window = Toplevel(parent) - self.callback = callback - self.adjuster = adjuster - - self.window.wm_title("TAKE ANY ONE YOU WANT") - self.window['padx'] = 5 - self.window['pady'] = 5 - self.all_sprites = [] - - def open_unofficial_sprite_dir(_evt): - open_file(self.unofficial_sprite_dir) - - official_frametitle = Label(self.window, text='Official Sprites') - - unofficial_frametitle = Frame(self.window) - title_text = Label(unofficial_frametitle, text="Unofficial Sprites") - title_link = Label(unofficial_frametitle, text="(open)", fg="blue", cursor="hand2") - title_text.pack(side=LEFT) - title_link.pack(side=LEFT) - title_link.bind("", open_unofficial_sprite_dir) - - self.icon_section(official_frametitle, self.official_sprite_dir+'/*', 'Official sprites not found. Click "Update official sprites" to download them.') - self.icon_section(unofficial_frametitle, self.unofficial_sprite_dir+'/*', 'Put sprites in the unofficial sprites folder (see open link above) to have them appear here.') - - frame = Frame(self.window) - frame.pack(side=BOTTOM, fill=X, pady=5) - - button = Button(frame, text="Browse for file...", command=self.browse_for_sprite) - button.pack(side=RIGHT, padx=(5, 0)) - - button = Button(frame, text="Update official sprites", command=self.update_official_sprites) - button.pack(side=RIGHT, padx=(5, 0)) - - button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite) - button.pack(side=LEFT, padx=(0, 5)) - - button = Button(frame, text="Random sprite", command=self.use_random_sprite) - button.pack(side=LEFT, padx=(0, 5)) - - if adjuster: - button = Button(frame, text="Current sprite from rom", command=self.use_default_sprite) - button.pack(side=LEFT, padx=(0, 5)) - - set_icon(self.window) - self.window.focus() - - def icon_section(self, frame_label, path, no_results_label): - frame = LabelFrame(self.window, labelwidget=frame_label, padx=5, pady=5) - frame.pack(side=TOP, fill=X) - - sprites = [] - - for file in glob(output_path(path)): - sprites.append(Sprite(file)) - - sprites.sort(key=lambda s: str.lower(s.name or "").strip()) - - i = 0 - for sprite in sprites: - image = get_image_for_sprite(sprite) - if image is None: - continue - self.all_sprites.append(sprite) - button = Button(frame, image=image, command=lambda spr=sprite: self.select_sprite(spr)) - ToolTips.register(button, sprite.name + ("\nBy: %s" % sprite.author_name if sprite.author_name else "")) - button.image = image - button.grid(row=i // 16, column=i % 16) - i += 1 - - if i == 0: - label = Label(frame, text=no_results_label) - label.pack() - - - def update_official_sprites(self): - # need to wrap in try catch. We don't want errors getting the json or downloading the files to break us. - self.window.destroy() - self.parent.update() - def work(task): - resultmessage = "" - successful = True - - def finished(): - task.close_window() - if successful: - messagebox.showinfo("Sprite Updater", resultmessage) - else: - messagebox.showerror("Sprite Updater", resultmessage) - SpriteSelector(self.parent, self.callback, self.adjuster) - - try: - task.update_status("Downloading official sprites list") - with urlopen('https://alttpr.com/sprites') as response: - sprites_arr = json.loads(response.read().decode("utf-8")) - except Exception as e: - resultmessage = "Error getting list of official sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e) - successful = False - task.queue_event(finished) - return - - try: - task.update_status("Determining needed sprites") - current_sprites = [os.path.basename(file) for file in glob(self.official_sprite_dir+'/*')] - official_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path)) for sprite in sprites_arr] - needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in official_sprites if filename not in current_sprites] - bundled_sprites = [os.path.basename(file) for file in glob(self.local_official_sprite_dir+'/*')] - # todo: eventually use the above list to avoid downloading any sprites that we already have cached in the bundle. - - official_filenames = [filename for (_, filename) in official_sprites] - obsolete_sprites = [sprite for sprite in current_sprites if sprite not in official_filenames] - except Exception as e: - resultmessage = "Error Determining which sprites to update. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e) - successful = False - task.queue_event(finished) - return - - updated = 0 - for (sprite_url, filename) in needed_sprites: - try: - task.update_status("Downloading needed sprite %g/%g" % (updated + 1, len(needed_sprites))) - target = os.path.join(self.official_sprite_dir, filename) - with urlopen(sprite_url) as response, open(target, 'wb') as out: - shutil.copyfileobj(response, out) - except Exception as e: - resultmessage = "Error downloading sprite. Not all sprites updated.\n\n%s: %s" % (type(e).__name__, e) - successful = False - updated += 1 - - deleted = 0 - for sprite in obsolete_sprites: - try: - task.update_status("Removing obsolete sprite %g/%g" % (deleted + 1, len(obsolete_sprites))) - os.remove(os.path.join(self.official_sprite_dir, sprite)) - except Exception as e: - resultmessage = "Error removing obsolete sprite. Not all sprites updated.\n\n%s: %s" % (type(e).__name__, e) - successful = False - deleted += 1 - - if successful: - resultmessage = "official sprites updated successfully" - - task.queue_event(finished) - - BackgroundTaskProgress(self.parent, work, "Updating Sprites") - - - def browse_for_sprite(self): - sprite = filedialog.askopenfilename( - filetypes=[("All Sprite Sources", (".zspr", ".spr", ".sfc", ".smc")), - ("ZSprite files", ".zspr"), - ("Sprite files", ".spr"), - ("Rom Files", (".sfc", ".smc")), - ("All Files", "*")]) - try: - self.callback(Sprite(sprite)) - except Exception: - self.callback(None) - self.window.destroy() - - - def use_default_sprite(self): - self.callback(None) - self.window.destroy() - - def use_default_link_sprite(self): - self.callback(Sprite.default_link_sprite()) - self.window.destroy() - - def use_random_sprite(self): - self.callback(random.choice(self.all_sprites) if self.all_sprites else None) - self.window.destroy() - - def select_sprite(self, spritename): - self.callback(spritename) - self.window.destroy() - - - def deploy_icons(self): - if not os.path.exists(self.unofficial_sprite_dir): - os.makedirs(self.unofficial_sprite_dir) - if not os.path.exists(self.official_sprite_dir): - shutil.copytree(self.local_official_sprite_dir, self.official_sprite_dir) - - @property - def official_sprite_dir(self): - if is_bundled(): - return output_path("sprites/official") - return self.local_official_sprite_dir - - @property - def local_official_sprite_dir(self): - return local_path("data/sprites/official") - - @property - def unofficial_sprite_dir(self): - if is_bundled(): - return output_path("sprites/unofficial") - return self.local_unofficial_sprite_dir - - @property - def local_unofficial_sprite_dir(self): - return local_path("data/sprites/unofficial") - - -def get_image_for_sprite(sprite): - if not sprite.valid: - return None - height = 24 - width = 16 - - def draw_sprite_into_gif(add_palette_color, set_pixel_color_index): - - def drawsprite(spr, pal_as_colors, offset): - for y, row in enumerate(spr): - for x, pal_index in enumerate(row): - if pal_index: - color = pal_as_colors[pal_index - 1] - set_pixel_color_index(x + offset[0], y + offset[1], color) - - add_palette_color(16, (40, 40, 40)) - shadow = [ - [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0], - [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], - [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0], - ] - - drawsprite(shadow, [16], (2, 17)) - - palettes = sprite.decode_palette() - for i in range(15): - add_palette_color(i + 1, palettes[0][i]) - - body = sprite.decode16(0x4C0) - drawsprite(body, list(range(1, 16)), (0, 8)) - head = sprite.decode16(0x40) - drawsprite(head, list(range(1, 16)), (0, 0)) - - def make_gif(callback): - gif_header = b'GIF89a' - - gif_lsd = bytearray(7) - gif_lsd[0] = width - gif_lsd[2] = height - gif_lsd[4] = 0xF4 # 32 color palette follows. transparant + 15 for sprite + 1 for shadow=17 which rounds up to 32 as nearest power of 2 - gif_lsd[5] = 0 # background color is zero - gif_lsd[6] = 0 # aspect raio not specified - gif_gct = bytearray(3 * 32) - - gif_gce = bytearray(8) - gif_gce[0] = 0x21 # start of extention blocked - gif_gce[1] = 0xF9 # identifies this as the Graphics Control extension - gif_gce[2] = 4 # we are suppling only the 4 four bytes - gif_gce[3] = 0x01 # this gif includes transparency - gif_gce[4] = gif_gce[5] = 0 # animation frrame delay (unused) - gif_gce[6] = 0 # transparent color is index 0 - gif_gce[7] = 0 # end of gif_gce - gif_id = bytearray(10) - gif_id[0] = 0x2c - # byte 1,2 are image left. 3,4 are image top both are left as zerosuitsamus - gif_id[5] = width - gif_id[7] = height - gif_id[9] = 0 # no local color table - - gif_img_minimum_code_size = bytes([7]) # we choose 7 bits, so that each pixel is represented by a byte, for conviennce. - - clear = 0x80 - stop = 0x81 - - unchunked_image_data = bytearray(height * (width + 1) + 1) - # we technically need a Clear code once every 125 bytes, but we do it at the start of every row for simplicity - for row in range(height): - unchunked_image_data[row * (width + 1)] = clear - unchunked_image_data[-1] = stop - - def add_palette_color(index, color): - gif_gct[3 * index] = color[0] - gif_gct[3 * index + 1] = color[1] - gif_gct[3 * index + 2] = color[2] - - def set_pixel_color_index(x, y, color): - unchunked_image_data[y * (width + 1) + x + 1] = color - - callback(add_palette_color, set_pixel_color_index) - - def chunk_image(img): - for i in range(0, len(img), 255): - chunk = img[i:i + 255] - yield bytes([len(chunk)]) - yield chunk - - gif_img = b''.join([gif_img_minimum_code_size] + list(chunk_image(unchunked_image_data)) + [b'\x00']) - - gif = b''.join([gif_header, gif_lsd, gif_gct, gif_gce, gif_id, gif_img, b'\x3b']) - - return gif - - gif_data = make_gif(draw_sprite_into_gif) - image = PhotoImage(data=gif_data) - - return image.zoom(2) - if __name__ == '__main__': guiMain() diff --git a/gui/bottom.py b/gui/bottom.py new file mode 100644 index 00000000..25e38979 --- /dev/null +++ b/gui/bottom.py @@ -0,0 +1,133 @@ +from tkinter import ttk, messagebox, StringVar, Button, Entry, Frame, Label, Spinbox, E, W, LEFT, RIGHT, X +from argparse import Namespace +import logging +import os +import random +from CLI import parse_arguments, get_working_dirs +from Main import main +from Utils import local_path, output_path, open_file + +def bottom_frame(self,parent,args=None): +# working_dirs = get_working_dirs() + + self = ttk.Frame(parent) + seedCountFrame = Frame(self) + seedCountFrame.pack() + ## Seed # + seedLabel = Label(self, text='Seed #') +# self.seedVar = StringVar(value=parent.working_dirs["gen.seed"]) + self.seedVar = StringVar() + def saveSeed(caller,_,mode): + pass +# parent.working_dirs["gen.seed"] = self.seedVar.get() + self.seedVar.trace_add("write",saveSeed) + seedEntry = Entry(self, width=15, textvariable=self.seedVar) + seedLabel.pack(side=LEFT) + seedEntry.pack(side=LEFT) + ## Number of Generation attempts + countLabel = Label(self, text='Count') +# self.countVar = StringVar(value=working_dirs["gen.count"]) + self.countVar = StringVar() + countSpinbox = Spinbox(self, from_=1, to=100, width=5, textvariable=self.countVar) + countLabel.pack(side=LEFT) + countSpinbox.pack(side=LEFT) + + def generateRom(): + guiargs = Namespace() + guiargs.multi = int(parent.multiworldWindow.worldVar.get()) + guiargs.names = parent.multiworldWindow.namesVar.get() + guiargs.seed = int(parent.farBottomFrame.seedVar.get()) if parent.farBottomFrame.seedVar.get() else None + guiargs.count = int(parent.farBottomFrame.countVar.get()) if parent.farBottomFrame.countVar.get() != '1' else None + guiargs.mode = parent.itemWindow.modeVar.get() + guiargs.logic = parent.itemWindow.logicVar.get() + + guiargs.goal = parent.itemWindow.goalVar.get() + guiargs.crystals_gt = parent.itemWindow.crystalsGTVar.get() + guiargs.crystals_ganon = parent.itemWindow.crystalsGanonVar.get() + guiargs.swords = parent.itemWindow.swordVar.get() + guiargs.difficulty = parent.itemWindow.difficultyVar.get() + guiargs.item_functionality = parent.itemWindow.itemfunctionVar.get() + guiargs.timer = parent.itemWindow.timerVar.get() + guiargs.progressive = parent.itemWindow.progressiveVar.get() + guiargs.accessibility = parent.itemWindow.accessibilityVar.get() + guiargs.algorithm = parent.itemWindow.algorithmVar.get() + guiargs.shuffle = parent.entrandoWindow.shuffleVar.get() + guiargs.door_shuffle = parent.dungeonRandoWindow.doorShuffleVar.get() + guiargs.heartbeep = parent.gameOptionsWindow.heartbeepVar.get() + guiargs.heartcolor = parent.gameOptionsWindow.heartcolorVar.get() + guiargs.fastmenu = parent.gameOptionsWindow.fastMenuVar.get() + guiargs.create_spoiler = bool(parent.generationSetupWindow.createSpoilerVar.get()) + guiargs.skip_playthrough = not bool(parent.generationSetupWindow.createSpoilerVar.get()) + guiargs.suppress_rom = bool(parent.generationSetupWindow.suppressRomVar.get()) + guiargs.openpyramid = bool(parent.entrandoWindow.openpyramidVar.get()) + guiargs.mapshuffle = bool(parent.dungeonRandoWindow.mapshuffleVar.get()) + guiargs.compassshuffle = bool(parent.dungeonRandoWindow.compassshuffleVar.get()) + guiargs.keyshuffle = bool(parent.dungeonRandoWindow.keyshuffleVar.get()) + guiargs.bigkeyshuffle = bool(parent.dungeonRandoWindow.bigkeyshuffleVar.get()) + guiargs.retro = bool(parent.itemWindow.retroVar.get()) + guiargs.quickswap = bool(parent.gameOptionsWindow.quickSwapVar.get()) + guiargs.disablemusic = bool(parent.gameOptionsWindow.disableMusicVar.get()) + guiargs.ow_palettes = parent.gameOptionsWindow.owPalettesVar.get() + guiargs.uw_palettes = parent.gameOptionsWindow.uwPalettesVar.get() + guiargs.shuffleganon = bool(parent.entrandoWindow.shuffleGanonVar.get()) + guiargs.hints = bool(parent.gameOptionsWindow.hintsVar.get()) + guiargs.enemizercli = parent.enemizerWindow.enemizerCLIpathVar.get() + guiargs.shufflebosses = parent.enemizerWindow.enemizerBossVar.get() + guiargs.shuffleenemies = parent.enemizerWindow.enemyShuffleVar.get() + guiargs.enemy_health = parent.enemizerWindow.enemizerHealthVar.get() + guiargs.enemy_damage = parent.enemizerWindow.enemizerDamageVar.get() + guiargs.shufflepots = bool(parent.enemizerWindow.potShuffleVar.get()) + guiargs.custom = bool(parent.generationSetupWindow.customVar.get()) + guiargs.customitemarray = [int(parent.customWindow.bowVar.get()), int(parent.customWindow.silverarrowVar.get()), int(parent.customWindow.boomerangVar.get()), int(parent.customWindow.magicboomerangVar.get()), int(parent.customWindow.hookshotVar.get()), int(parent.customWindow.mushroomVar.get()), int(parent.customWindow.magicpowderVar.get()), int(parent.customWindow.firerodVar.get()), + int(parent.customWindow.icerodVar.get()), int(parent.customWindow.bombosVar.get()), int(parent.customWindow.etherVar.get()), int(parent.customWindow.quakeVar.get()), int(parent.customWindow.lampVar.get()), int(parent.customWindow.hammerVar.get()), int(parent.customWindow.shovelVar.get()), int(parent.customWindow.fluteVar.get()), int(parent.customWindow.bugnetVar.get()), + int(parent.customWindow.bookVar.get()), int(parent.customWindow.bottleVar.get()), int(parent.customWindow.somariaVar.get()), int(parent.customWindow.byrnaVar.get()), int(parent.customWindow.capeVar.get()), int(parent.customWindow.mirrorVar.get()), int(parent.customWindow.bootsVar.get()), int(parent.customWindow.powergloveVar.get()), int(parent.customWindow.titansmittVar.get()), + int(parent.customWindow.proggloveVar.get()), int(parent.customWindow.flippersVar.get()), int(parent.customWindow.pearlVar.get()), int(parent.customWindow.heartpieceVar.get()), int(parent.customWindow.fullheartVar.get()), int(parent.customWindow.sancheartVar.get()), int(parent.customWindow.sword1Var.get()), int(parent.customWindow.sword2Var.get()), + int(parent.customWindow.sword3Var.get()), int(parent.customWindow.sword4Var.get()), int(parent.customWindow.progswordVar.get()), int(parent.customWindow.shield1Var.get()), int(parent.customWindow.shield2Var.get()), int(parent.customWindow.shield3Var.get()), int(parent.customWindow.progshieldVar.get()), int(parent.customWindow.bluemailVar.get()), + int(parent.customWindow.redmailVar.get()), int(parent.customWindow.progmailVar.get()), int(parent.customWindow.halfmagicVar.get()), int(parent.customWindow.quartermagicVar.get()), int(parent.customWindow.bcap5Var.get()), int(parent.customWindow.bcap10Var.get()), int(parent.customWindow.acap5Var.get()), int(parent.customWindow.acap10Var.get()), + int(parent.customWindow.arrow1Var.get()), int(parent.customWindow.arrow10Var.get()), int(parent.customWindow.bomb1Var.get()), int(parent.customWindow.bomb3Var.get()), int(parent.customWindow.rupee1Var.get()), int(parent.customWindow.rupee5Var.get()), int(parent.customWindow.rupee20Var.get()), int(parent.customWindow.rupee50Var.get()), int(parent.customWindow.rupee100Var.get()), + int(parent.customWindow.rupee300Var.get()), int(parent.customWindow.rupoorVar.get()), int(parent.customWindow.blueclockVar.get()), int(parent.customWindow.greenclockVar.get()), int(parent.customWindow.redclockVar.get()), int(parent.customWindow.progbowVar.get()), int(parent.customWindow.bomb10Var.get()), int(parent.customWindow.triforcepieceVar.get()), + int(parent.customWindow.triforcecountVar.get()), int(parent.customWindow.triforceVar.get()), int(parent.customWindow.rupoorcostVar.get()), int(parent.customWindow.universalkeyVar.get())] + guiargs.rom = parent.generationSetupWindow.romVar.get() +# guiargs.sprite = parent.gameOptionsWindow.sprite + guiargs.outputpath = args.outputpath if args else None + # get default values for missing parameters + for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items(): + if k not in vars(guiargs): + setattr(guiargs, k, v) + elif type(v) is dict: # use same settings for every player + setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, guiargs.multi + 1)}) + try: + if guiargs.count is not None: + seed = guiargs.seed + for _ in range(guiargs.count): + main(seed=seed, args=guiargs) + seed = random.randint(0, 999999999) + else: + main(seed=guiargs.seed, args=guiargs) + except Exception as e: + logging.exception(e) + messagebox.showerror(title="Error while creating seed", message=str(e)) + else: + messagebox.showinfo(title="Success", message="Rom patched successfully") + + ## Generate Button + generateButton = Button(self, text='Generate Patched Rom', command=generateRom) + generateButton.pack(side=LEFT) + + def open_output(): + if args and args.outputpath: + open_file(output_path(args.outputpath)) + else: + open_file(output_path(".")) +# open_file(output_path(working_dirs["outputpath"])) + + openOutputButton = Button(self, text='Open Output Directory', command=open_output) + openOutputButton.pack(side=RIGHT) + + if os.path.exists(local_path('README.html')): + def open_readme(): + open_file(local_path('README.html')) + openReadmeButton = Button(self, text='Open Documentation', command=open_readme) + openReadmeButton.pack() + + return self