From 3fe2c0282451656599412bb553aaa95e0798522c Mon Sep 17 00:00:00 2001 From: "Mike A. Trethewey" Date: Sat, 15 Feb 2020 01:41:21 -0800 Subject: [PATCH] Arrayify more stuff Ignore settings file Rip out working_dirs in favor of settings Set main pages to array Set bottom frame to array --- .gitignore | 1 + CLI.py | 170 ++++++++++++++++++++++++++++++------ Gui.py | 56 ++++-------- gui/adjust/overview.py | 8 +- gui/bottom.py | 12 +-- gui/loadcliargs.py | 4 +- gui/randomize/enemizer.py | 10 +-- gui/randomize/generation.py | 8 +- gui/randomize/multiworld.py | 8 +- 9 files changed, 187 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index c242b833..9f9fc87a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ EnemizerCLI/ RaceRom.py weights/ +settings.json working_dirs.json venv diff --git a/CLI.py b/CLI.py index 32895166..1098b6ae 100644 --- a/CLI.py +++ b/CLI.py @@ -23,8 +23,8 @@ def parse_arguments(argv, no_defaults=False): def defval(value): return value if not no_defaults else None - # get working dirs - working_dirs = get_working_dirs() + # get settings + settings = get_settings() # we need to know how many players we have first parser = argparse.ArgumentParser(add_help=False) @@ -206,10 +206,10 @@ def parse_arguments(argv, no_defaults=False): 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(working_dirs["rom.base"]), help='Path to an ALttP JAP(1.0) rom to use as a base.') + parser.add_argument('--rom', default=defval(settings["rom"]), 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', default=defval(int(working_dirs["gen.seed"]) if working_dirs["gen.seed"] is not "" and working_dirs["gen.seed"] is not None else None), help='Define seed number to generate.', type=int) - parser.add_argument('--count', default=defval(int(working_dirs["gen.count"])), help='''\ + parser.add_argument('--seed', default=defval(int(settings["seed"]) if settings["seed"] is not "" and settings["seed"] is not None else None), help='Define seed number to generate.', type=int) + parser.add_argument('--count', default=defval(int(settings["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 @@ -274,7 +274,7 @@ def parse_arguments(argv, no_defaults=False): 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(working_dirs["enemizer.cli"])) + parser.add_argument('--enemizercli', default=defval(settings["enemizercli"])) 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']) @@ -282,10 +282,10 @@ def parse_arguments(argv, no_defaults=False): 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(working_dirs["multi.worlds"]), type=lambda value: min(max(int(value), 1), 255)) - parser.add_argument('--names', default=defval(working_dirs["multi.names"])) + parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255)) + parser.add_argument('--names', default=defval(settings["names"])) parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1)) - parser.add_argument('--outputpath', default=defval(working_dirs["outputpath"])) + parser.add_argument('--outputpath', default=defval(settings["outputpath"])) parser.add_argument('--race', default=defval(False), action='store_true') parser.add_argument('--outputname') @@ -294,6 +294,7 @@ def parse_arguments(argv, no_defaults=False): parser.add_argument(f'--p{player}', default=defval(''), help=argparse.SUPPRESS) ret = parser.parse_args(argv) + print(ret) if ret.keysanity: ret.mapshuffle, ret.compassshuffle, ret.keyshuffle, ret.bigkeyshuffle = [True] * 4 @@ -317,26 +318,141 @@ def parse_arguments(argv, no_defaults=False): 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("."), +def get_settings(): + # set default settings + settings = { + "multi": 1, + "names": "", + "seed": null, + "count": null, + "mode": "open", + "logic": "noglitches", + "goal": "ganon", + "crystals_gt": "7", + "crystals_ganon": "7", + "swords": "random", + "difficulty": "normal", + "item_functionality": "normal", + "timer": "none", + "progressive": "on", + "accessibility": "items", + "algorithm": "balanced", + "shuffle": "vanilla", + "door_shuffle": "basic", + "experimental": 0, + "heartbeep": "normal", + "heartcolor": "red", + "fastmenu": "normal", + "create_spoiler": false, + "skip_playthrough": true, + "suppress_rom": false, + "openpyramid": false, + "mapshuffle": false, + "compassshuffle": false, + "keyshuffle": false, + "bigkeyshuffle": false, + "retro": false, + "quickswap": false, + "disablemusic": false, + "ow_palettes": "default", + "uw_palettes": "default", + "shuffleganon": true, + "hints": false, + "enemizercli": os.path.join(".","EnemizerCLI","EnemizerCLI.Core"), + "shufflebosses": "none", + "shuffleenemies": "none", + "enemy_health": "default", + "enemy_damage": "default", + "shufflepots": false, + "custom": false, + "customitemarray": [ + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 4, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 2, + 1, + 1, + 24, + 10, + 1, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 3, + 0, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 12, + 0, + 13, + 2, + 4, + 28, + 7, + 1, + 5, + 0, + 0, + 0, + 0, + 2, + 1, + 0, + 0, + 0, + 10, + 0 + ], + "rom": os.path.join(".","Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"), + "sprite": null, + "randomSprite": false, + "outputpath": os.path.join(".") } if sys.platform.lower().find("windows"): - working_dirs["enemizer.cli"] += ".exe" + settings["enemizercli"] += ".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: + # read saved settings file if it exists and set these + settings_path = os.path.join(".", "resources", "user", "settings.json") + if os.path.exists(settings_path): + with(open(settings_path)) as json_file: data = json.load(json_file) + if 'sprite' in data.keys() and data['sprite']: + data['sprite'] = get_sprite_from_name(data['sprite']) for k,v in data.items(): - working_dirs[k] = v - return working_dirs + settings[k] = v + return settings_args diff --git a/Gui.py b/Gui.py index f23ac200..0e26c8bb 100755 --- a/Gui.py +++ b/Gui.py @@ -5,7 +5,7 @@ import sys from tkinter import Tk, BOTTOM, TOP, StringVar, BooleanVar, X, BOTH, ttk from argparse import Namespace -from CLI import get_working_dirs +from CLI import get_settings from DungeonRandomizer import parse_arguments from gui.adjust.overview import adjust_page from gui.custom.overview import custom_page @@ -24,16 +24,6 @@ from Rom import get_sprite_from_name def guiMain(args=None): - # save working dirs - def save_working_dirs(): - user_resources_path = os.path.join(".","resources","user") - working_dirs_path = os.path.join(user_resources_path) - if not os.path.exists(working_dirs_path): - os.makedirs(working_dirs_path) - with open(os.path.join(working_dirs_path, "working_dirs.json"),"w+") as f: - f.write(json.dumps(self.working_dirs, indent=2)) - os.chmod(os.path.join(working_dirs_path, "working_dirs.json"),0o755) - def save_settings(args): user_resources_path = os.path.join(".", "resources", "user") settings_path = os.path.join(user_resources_path) @@ -41,10 +31,10 @@ def guiMain(args=None): os.makedirs(settings_path) with open(os.path.join(settings_path, "settings.json"), "w+") as f: f.write(json.dumps(args, indent=2)) + os.chmod(os.path.join(settings_path, "settings.json"),0o755) # routine for exiting the app def guiExit(): - save_working_dirs() gui_args = vars(create_guiargs(self)) if self.randomSprite.get(): gui_args['sprite'] = 'random' @@ -63,16 +53,16 @@ def guiMain(args=None): # set program icon set_icon(mainWindow) - # get working dirs - self.working_dirs = get_working_dirs() + # get saved settings + self.settings = get_settings() 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') + self.pages["randomizer"] = ttk.Frame(notebook) + self.pages["adjust"] = ttk.Frame(notebook) + self.pages["custom"] = ttk.Frame(notebook) + notebook.add(self.pages["randomizer"], text='Randomize') + notebook.add(self.pages["adjust"], text='Adjust') + notebook.add(self.pages["custom"], text='Custom') notebook.pack() # randomizer controls @@ -86,7 +76,7 @@ def guiMain(args=None): # Multiworld: Multiworld settings # Game Options: Cosmetic settings that don't affect logic/placement # Generation Setup: Primarily one&done settings - self.randomizerNotebook = ttk.Notebook(self.randomizerWindow) + self.randomizerNotebook = ttk.Notebook(self.pages["randomizer"]) # Item Randomizer self.itemWindow = item_page(self.randomizerNotebook) @@ -97,7 +87,7 @@ def guiMain(args=None): self.randomizerNotebook.add(self.entrandoWindow, text="Entrances") # Enemizer - self.enemizerWindow,self.working_dirs = enemizer_page(self.randomizerNotebook,self.working_dirs) + self.enemizerWindow,self.settings = enemizer_page(self.randomizerNotebook,self.settings) self.randomizerNotebook.add(self.enemizerWindow, text="Enemizer") # Dungeon Shuffle @@ -105,7 +95,7 @@ def guiMain(args=None): self.randomizerNotebook.add(self.dungeonRandoWindow, text="Dungeon Shuffle") # Multiworld - self.multiworldWindow,self.working_dirs = multiworld_page(self.randomizerNotebook,self.working_dirs) + self.multiworldWindow,self.settings = multiworld_page(self.randomizerNotebook,self.settings) self.randomizerNotebook.add(self.multiworldWindow, text="Multiworld") # Game Options @@ -113,26 +103,26 @@ def guiMain(args=None): self.randomizerNotebook.add(self.gameOptionsWindow, text="Game Options") # Generation Setup - self.generationSetupWindow,self.working_dirs = generation_page(self.randomizerNotebook,self.working_dirs) + self.generationSetupWindow,self.settings = generation_page(self.randomizerNotebook,self.settings) self.randomizerNotebook.add(self.generationSetupWindow, text="Generation Setup") # add randomizer notebook to main window self.randomizerNotebook.pack() # bottom of window: Open Output Directory, Open Documentation (if exists) - self.farBottomFrame = bottom_frame(self, self, None) + self.frames["bottom"] = bottom_frame(self, self, None) # set bottom frame to main window - self.farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) + self.frames["bottom"].pack(side=BOTTOM, fill=X, padx=5, pady=5) self.outputPath = StringVar() self.randomSprite = BooleanVar() # Adjuster Controls - self.adjustContent,self.working_dirs = adjust_page(self, self.adjustWindow, self.working_dirs) + self.adjustContent,self.settings = adjust_page(self, self.pages["adjust"], self.settings) self.adjustContent.pack(side=TOP, fill=BOTH, expand=True) # Custom Controls - self.customContent = custom_page(self,self.customWindow) + self.customContent = custom_page(self,self.pages["custom"]) self.customContent.pack(side=TOP, pady=(17,0)) def validation(P): @@ -145,16 +135,6 @@ def guiMain(args=None): # load args from CLI into options loadcliargs(self, args) - # load settings second - settings_path = os.path.join(".", "resources", "user", "settings.json") - if os.path.exists(settings_path): - with(open(settings_path)) as json_file: - data = json.load(json_file) - if 'sprite' in data.keys() and data['sprite']: - data['sprite'] = get_sprite_from_name(data['sprite']) - settings_args = Namespace(**data) - loadcliargs(self, settings_args) - mainWindow.mainloop() diff --git a/gui/adjust/overview.py b/gui/adjust/overview.py index 7d28cadd..18669b7c 100644 --- a/gui/adjust/overview.py +++ b/gui/adjust/overview.py @@ -6,7 +6,7 @@ import gui.widgets as widgets import logging -def adjust_page(top, parent, working_dirs): +def adjust_page(top, parent, settings): # Adjust page self = ttk.Frame(parent) @@ -164,13 +164,13 @@ def adjust_page(top, parent, working_dirs): adjustRomFrame = Frame(bottomAdjustFrame) adjustRomLabel = Label(adjustRomFrame, text='Rom to adjust: ') - self.romVar2 = StringVar(value=working_dirs["adjust.rom"]) + self.romVar2 = StringVar(value=settings["rom"]) romEntry2 = Entry(adjustRomFrame, textvariable=self.romVar2) def RomSelect2(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")]) if rom: - working_dirs["adjust.rom"] = rom + settings["rom"] = rom self.romVar2.set(rom) romSelectButton2 = Button(adjustRomFrame, text='Select Rom', command=RomSelect2) @@ -202,4 +202,4 @@ def adjust_page(top, parent, working_dirs): adjustButton = Button(bottomAdjustFrame, text='Adjust Rom', command=adjustRom) adjustButton.pack(side=BOTTOM, padx=(5, 0)) - return self,working_dirs + return self,settings diff --git a/gui/bottom.py b/gui/bottom.py index de80b8b5..d3e097f6 100644 --- a/gui/bottom.py +++ b/gui/bottom.py @@ -3,7 +3,7 @@ from argparse import Namespace import logging import os import random -from CLI import parse_arguments, get_working_dirs +from CLI import parse_arguments, get_settings from Main import main from Utils import local_path, output_path, open_file import gui.widgets as widgets @@ -20,11 +20,11 @@ def bottom_frame(self, parent, args=None): seedCountFrame.pack() ## Seed # seedLabel = Label(self, text='Seed #') - savedSeed = parent.working_dirs["gen.seed"] + savedSeed = parent.settings["seed"] self.seedVar = StringVar(value=savedSeed) def saveSeed(caller,_,mode): savedSeed = self.seedVar.get() - parent.working_dirs["gen.seed"] = int(savedSeed) if savedSeed.isdigit() else None + parent.settings["seed"] = int(savedSeed) if savedSeed.isdigit() else None self.seedVar.trace_add("write",saveSeed) seedEntry = Entry(self, width=15, textvariable=self.seedVar) seedLabel.pack(side=LEFT) @@ -72,7 +72,7 @@ def bottom_frame(self, parent, args=None): if args and args.outputpath: open_file(output_path(args.outputpath)) else: - open_file(output_path(parent.working_dirs["outputpath"])) + open_file(output_path(parent.settings["outputpath"])) openOutputButton = Button(self, text='Open Output Directory', command=open_output) openOutputButton.pack(side=RIGHT) @@ -90,8 +90,8 @@ def create_guiargs(parent): guiargs = Namespace() guiargs.multi = int(parent.multiworldWindow.multiworldWidgets["worlds"].storageVar.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.bottomWidgets["generationcount"].storageVar.get()) if parent.farBottomFrame.bottomWidgets["generationcount"].storageVar.get() != '1' else None + guiargs.seed = int(parent.frames["bottom"].seedVar.get()) if parent.frames["bottom"].seedVar.get() else None + guiargs.count = int(parent.frames["bottom"].bottomWidgets["generationcount"].storageVar.get()) if parent.frames["bottom"].bottomWidgets["generationcount"].storageVar.get() != '1' else None guiargs.mode = parent.itemWindow.itemWidgets["worldstate"].storageVar.get() guiargs.logic = parent.itemWindow.itemWidgets["logiclevel"].storageVar.get() diff --git a/gui/loadcliargs.py b/gui/loadcliargs.py index 113d3437..b0974e86 100644 --- a/gui/loadcliargs.py +++ b/gui/loadcliargs.py @@ -22,9 +22,9 @@ def loadcliargs(gui, args): if args.multi: gui.multiworldWindow.multiworldWidgets["worlds"].storageVar.set(str(args.multi)) if args.count: - gui.farBottomFrame.bottomWidgets["generationcount"].storageVar.set(str(args.count)) + gui.frames["bottom"].bottomWidgets["generationcount"].storageVar.set(str(args.count)) if args.seed: - gui.farBottomFrame.seedVar.set(str(args.seed)) + gui.frames["bottom"].seedVar.set(str(args.seed)) gui.itemWindow.itemWidgets["worldstate"].storageVar.set(args.mode) gui.itemWindow.itemWidgets["weapons"].storageVar.set(args.swords) gui.itemWindow.itemWidgets["itempool"].storageVar.set(args.difficulty) diff --git a/gui/randomize/enemizer.py b/gui/randomize/enemizer.py index 74e570d7..d3c08ebd 100644 --- a/gui/randomize/enemizer.py +++ b/gui/randomize/enemizer.py @@ -2,7 +2,7 @@ import os from tkinter import ttk, filedialog, IntVar, StringVar, Button, Checkbutton, Entry, Frame, Label, LabelFrame, OptionMenu, N, E, W, LEFT, RIGHT, X import gui.widgets as widgets -def enemizer_page(parent,working_dirs): +def enemizer_page(parent,settings): # Enemizer self = ttk.Frame(parent) @@ -24,9 +24,9 @@ def enemizer_page(parent,working_dirs): enemizerPathFrame = Frame(self) enemizerCLIlabel = Label(enemizerPathFrame, text="EnemizerCLI path: ") enemizerCLIlabel.pack(side=LEFT) - self.enemizerCLIpathVar = StringVar(value=working_dirs["enemizer.cli"]) + self.enemizerCLIpathVar = StringVar(value=settings["enemizercli"]) def saveEnemizerPath(caller,_,mode): - working_dirs["enemizer.cli"] = self.enemizerCLIpathVar.get() + settings["enemizercli"] = self.enemizerCLIpathVar.get() self.enemizerCLIpathVar.trace_add("write",saveEnemizerPath) enemizerCLIpathEntry = Entry(enemizerPathFrame, textvariable=self.enemizerCLIpathVar) enemizerCLIpathEntry.pack(side=LEFT, fill=X, expand=True) @@ -34,7 +34,7 @@ def enemizer_page(parent,working_dirs): path = filedialog.askopenfilename(filetypes=[("EnemizerCLI executable", "*EnemizerCLI*")], initialdir=os.path.join(".")) if path: self.enemizerCLIpathVar.set(path) - working_dirs["enemizer.cli"] = path + settings["enemizercli"] = path enemizerCLIbrowseButton = Button(enemizerPathFrame, text='...', command=EnemizerSelectPath) enemizerCLIbrowseButton.pack(side=LEFT) enemizerPathFrame.pack(fill=X, expand=True) @@ -115,4 +115,4 @@ def enemizer_page(parent,working_dirs): ) self.enemizerWidgets[key].pack(anchor=E) - return self,working_dirs + return self,settings diff --git a/gui/randomize/generation.py b/gui/randomize/generation.py index ecccd3e3..aea9c5e9 100644 --- a/gui/randomize/generation.py +++ b/gui/randomize/generation.py @@ -2,7 +2,7 @@ import os from tkinter import ttk, filedialog, IntVar, StringVar, Button, Checkbutton, Entry, Frame, Label, E, W, LEFT, RIGHT, X import gui.widgets as widgets -def generation_page(parent,working_dirs): +def generation_page(parent,settings): # Generation Setup self = ttk.Frame(parent) @@ -47,10 +47,10 @@ def generation_page(parent,working_dirs): baseRomLabel = Label(baseRomFrame, text='Base Rom: ') self.romVar = StringVar() def saveBaseRom(caller,_,mode): - working_dirs["rom.base"] = self.romVar.get() + settings["rom"] = self.romVar.get() self.romVar.trace_add("write",saveBaseRom) romEntry = Entry(baseRomFrame, textvariable=self.romVar) - self.romVar.set(working_dirs["rom.base"]) + self.romVar.set(settings["rom"]) def RomSelect(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")], initialdir=os.path.join(".")) @@ -62,4 +62,4 @@ def generation_page(parent,working_dirs): romSelectButton.pack(side=LEFT) baseRomFrame.pack(fill=X, expand=True) - return self,working_dirs + return self,settings diff --git a/gui/randomize/multiworld.py b/gui/randomize/multiworld.py index 8e5e6f7c..ee8b9d47 100644 --- a/gui/randomize/multiworld.py +++ b/gui/randomize/multiworld.py @@ -1,7 +1,7 @@ from tkinter import ttk, StringVar, Entry, Frame, Label, Spinbox, N, E, W, X, LEFT, RIGHT import gui.widgets as widgets -def multiworld_page(parent,working_dirs): +def multiworld_page(parent,settings): # Multiworld self = ttk.Frame(parent) @@ -23,13 +23,13 @@ def multiworld_page(parent,working_dirs): ## List of Player Names namesFrame = Frame(self) namesLabel = Label(namesFrame, text='Player names') - self.namesVar = StringVar(value=working_dirs["multi.names"]) + self.namesVar = StringVar(value=settings["names"]) def saveMultiNames(caller,_,mode): - working_dirs["multi.names"] = self.namesVar.get() + settings["names"] = self.namesVar.get() self.namesVar.trace_add("write",saveMultiNames) namesEntry = Entry(namesFrame, textvariable=self.namesVar) namesLabel.pack(side=LEFT) namesEntry.pack(side=LEFT, fill=X, expand=True) namesFrame.pack(anchor=N, fill=X, expand=True) - return self,working_dirs + return self,settings