From 03431f0b83a5f32e285c72cb6759f4cefca82383 Mon Sep 17 00:00:00 2001 From: "Mike A. Trethewey" Date: Sat, 8 Feb 2020 19:01:15 -0800 Subject: [PATCH] Implement save system Add to .gitignore Add to default CLI args Add to each page that needs it * Rom Adjuster * Seed * Generation attempts * Enemizer CLI path * Base ROM * Multiworld worlds * Multiworld names --- .gitignore | 2 ++ CLI.py | 17 ++++++++++------- Gui.py | 32 ++++++++++++++++++++++++++++---- gui/adjust/overview.py | 9 ++++----- gui/bottom.py | 16 ++++++---------- gui/randomize/enemizer.py | 11 +++++------ gui/randomize/generation.py | 9 ++++----- gui/randomize/multiworld.py | 13 +++++-------- 8 files changed, 64 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 8c5d8669..c242b833 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,7 @@ EnemizerCLI/ RaceRom.py weights/ +working_dirs.json + venv test diff --git a/CLI.py b/CLI.py index 2f18d21e..d29a3b41 100644 --- a/CLI.py +++ b/CLI.py @@ -23,6 +23,9 @@ 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() + # 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)) @@ -203,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('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('--rom', default=defval(working_dirs["rom.base"]), 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='''\ + 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='''\ 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 @@ -271,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('EnemizerCLI/EnemizerCLI.Core')) + parser.add_argument('--enemizercli', default=defval(working_dirs["enemizer.cli"])) 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']) @@ -279,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(1), type=lambda value: min(max(int(value), 1), 255)) - parser.add_argument('--names', default=defval('')) + 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('--teams', default=defval(1), type=lambda value: max(int(value), 1)) - parser.add_argument('--outputpath') + parser.add_argument('--outputpath', default=defval(working_dirs["outputpath"])) parser.add_argument('--race', default=defval(False), action='store_true') parser.add_argument('--outputname') diff --git a/Gui.py b/Gui.py index 02db9e42..cd7ae882 100755 --- a/Gui.py +++ b/Gui.py @@ -6,11 +6,13 @@ import logging import random import os import shutil +import sys from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, BOTH, Entry, Spinbox, Button, filedialog, messagebox, ttk from urllib.parse import urlparse from urllib.request import urlopen from AdjusterMain import adjust +from CLI import get_working_dirs from DungeonRandomizer import parse_arguments from gui.adjust.overview import adjust_page from gui.custom.overview import custom_page @@ -30,12 +32,34 @@ from Utils import is_bundled, local_path, output_path, open_file 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) + + # routine for exiting the app + def guiExit(): + save_working_dirs() + sys.exit(0) + + # make main window + # add program title & version number mainWindow = Tk() self = mainWindow mainWindow.wm_title("Door Shuffle %s" % ESVersion) + mainWindow.protocol("WM_DELETE_WINDOW",guiExit) # intercept when user clicks the X + # set program icon set_icon(mainWindow) + # get working dirs + self.working_dirs = get_working_dirs() + notebook = ttk.Notebook(self) self.randomizerWindow = ttk.Frame(notebook) self.adjustWindow = ttk.Frame(notebook) @@ -67,7 +91,7 @@ def guiMain(args=None): self.randomizerNotebook.add(self.entrandoWindow, text="Entrances") # Enemizer - self.enemizerWindow = enemizer_page(self.randomizerNotebook) + self.enemizerWindow,self.working_dirs = enemizer_page(self.randomizerNotebook,self.working_dirs) self.randomizerNotebook.add(self.enemizerWindow, text="Enemizer") # Dungeon Shuffle @@ -75,7 +99,7 @@ def guiMain(args=None): self.randomizerNotebook.add(self.dungeonRandoWindow, text="Dungeon Shuffle") # Multiworld - self.multiworldWindow = multiworld_page(self.randomizerNotebook) + self.multiworldWindow,self.working_dirs = multiworld_page(self.randomizerNotebook,self.working_dirs) self.randomizerNotebook.add(self.multiworldWindow, text="Multiworld") # Game Options @@ -83,7 +107,7 @@ def guiMain(args=None): self.randomizerNotebook.add(self.gameOptionsWindow, text="Game Options") # Generation Setup - self.generationSetupWindow = generation_page(self.randomizerNotebook) + self.generationSetupWindow,self.working_dirs = generation_page(self.randomizerNotebook,self.working_dirs) self.randomizerNotebook.add(self.generationSetupWindow, text="Generation Setup") # add randomizer notebook to main window @@ -95,7 +119,7 @@ def guiMain(args=None): self.farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) # Adjuster Controls - self.adjustContent = adjust_page(self,self.adjustWindow) + self.adjustContent,self.working_dirs = adjust_page(self,self.adjustWindow,self.working_dirs) # self.adjustContent,self.working_dirs = adjust_page(self,self.adjustWindow,self.working_dirs) self.adjustContent.pack(side=TOP, fill=BOTH, expand=True) diff --git a/gui/adjust/overview.py b/gui/adjust/overview.py index 7344c2f1..842a9b37 100644 --- a/gui/adjust/overview.py +++ b/gui/adjust/overview.py @@ -4,7 +4,7 @@ from argparse import Namespace from classes.SpriteSelector import SpriteSelector import logging -def adjust_page(top,parent):#,working_dirs): +def adjust_page(top,parent,working_dirs): self = ttk.Frame(parent) # Disable BGM @@ -101,14 +101,13 @@ def adjust_page(top,parent):#,working_dirs): adjustRomFrame = Frame(bottomAdjustFrame) adjustRomLabel = Label(adjustRomFrame, text='Rom to adjust: ') - self.romVar2 = StringVar() -# romVar2 = StringVar(value=working_dirs["adjust.rom"]) + self.romVar2 = StringVar(value=working_dirs["adjust.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 + working_dirs["adjust.rom"] = rom self.romVar2.set(rom) romSelectButton2 = Button(adjustRomFrame, text='Select Rom', command=RomSelect2) @@ -140,4 +139,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,working_dirs diff --git a/gui/bottom.py b/gui/bottom.py index 25e38979..205bd16d 100644 --- a/gui/bottom.py +++ b/gui/bottom.py @@ -8,26 +8,23 @@ 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() + savedSeed = parent.working_dirs["gen.seed"] + self.seedVar = StringVar(value=savedSeed) def saveSeed(caller,_,mode): - pass -# parent.working_dirs["gen.seed"] = self.seedVar.get() + savedSeed = self.seedVar.get() + parent.working_dirs["gen.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) seedEntry.pack(side=LEFT) ## Number of Generation attempts countLabel = Label(self, text='Count') -# self.countVar = StringVar(value=working_dirs["gen.count"]) - self.countVar = StringVar() + self.countVar = StringVar(value=parent.working_dirs["gen.count"]) countSpinbox = Spinbox(self, from_=1, to=100, width=5, textvariable=self.countVar) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT) @@ -118,8 +115,7 @@ def bottom_frame(self,parent,args=None): if args and args.outputpath: open_file(output_path(args.outputpath)) else: - open_file(output_path(".")) -# open_file(output_path(working_dirs["outputpath"])) + open_file(output_path(parent.working_dirs["outputpath"])) openOutputButton = Button(self, text='Open Output Directory', command=open_output) openOutputButton.pack(side=RIGHT) diff --git a/gui/randomize/enemizer.py b/gui/randomize/enemizer.py index 9b0e7340..dfab0537 100644 --- a/gui/randomize/enemizer.py +++ b/gui/randomize/enemizer.py @@ -1,7 +1,7 @@ import os from tkinter import ttk, filedialog, IntVar, StringVar, Button, Checkbutton, Entry, Frame, Label, LabelFrame, OptionMenu, E, W, LEFT, RIGHT, X -def enemizer_page(parent):#,working_dirs): +def enemizer_page(parent,working_dirs): self = ttk.Frame(parent) # Enemizer @@ -16,10 +16,9 @@ def enemizer_page(parent):#,working_dirs): enemizerPathFrame.grid(row=0, column=0, columnspan=3, sticky=W+E) enemizerCLIlabel = Label(enemizerPathFrame, text="EnemizerCLI path: ") enemizerCLIlabel.pack(side=LEFT) - self.enemizerCLIpathVar = StringVar() + self.enemizerCLIpathVar = StringVar(value=working_dirs["enemizer.cli"]) def saveEnemizerPath(caller,_,mode): - pass - #working_dirs["enemizer.cli"] = self.enemizerCLIpathVar.get() + working_dirs["enemizer.cli"] = self.enemizerCLIpathVar.get() self.enemizerCLIpathVar.trace_add("write",saveEnemizerPath) enemizerCLIpathEntry = Entry(enemizerPathFrame, textvariable=self.enemizerCLIpathVar) enemizerCLIpathEntry.pack(side=LEFT, fill=X, expand=True) @@ -27,7 +26,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 + working_dirs["enemizer.cli"] = path enemizerCLIbrowseButton = Button(enemizerPathFrame, text='...', command=EnemizerSelectPath) enemizerCLIbrowseButton.pack(side=LEFT) @@ -76,4 +75,4 @@ def enemizer_page(parent):#,working_dirs): enemizerHealthOption = OptionMenu(enemizerHealthFrame, self.enemizerHealthVar, 'default', 'easy', 'normal', 'hard', 'expert') enemizerHealthOption.pack(side=LEFT) - return self#,working_dirs + return self,working_dirs diff --git a/gui/randomize/generation.py b/gui/randomize/generation.py index 9082d229..b0f7a565 100644 --- a/gui/randomize/generation.py +++ b/gui/randomize/generation.py @@ -1,7 +1,7 @@ import os from tkinter import ttk, filedialog, IntVar, StringVar, Button, Checkbutton, Entry, Frame, Label, E, W, LEFT, RIGHT, X -def generation_page(parent):#,working_dirs): +def generation_page(parent,working_dirs): self = ttk.Frame(parent) # Generation Setup options @@ -22,11 +22,10 @@ def generation_page(parent):#,working_dirs): baseRomLabel = Label(baseRomFrame, text='Base Rom: ') self.romVar = StringVar() def saveBaseRom(caller,_,mode): - pass -# working_dirs["rom.base"] = self.romVar.get() + working_dirs["rom.base"] = 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(working_dirs["rom.base"]) def RomSelect(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")], initialdir=os.path.join(".")) @@ -38,4 +37,4 @@ def generation_page(parent):#,working_dirs): romSelectButton.pack(side=LEFT) baseRomFrame.pack(fill=X, expand=True) - return self#,working_dirs + return self,working_dirs diff --git a/gui/randomize/multiworld.py b/gui/randomize/multiworld.py index 2e37a4dd..dcacf293 100644 --- a/gui/randomize/multiworld.py +++ b/gui/randomize/multiworld.py @@ -1,28 +1,25 @@ from tkinter import ttk, StringVar, Entry, Frame, Label, Spinbox, E, W, LEFT, RIGHT -def multiworld_page(parent):#,working_dirs): +def multiworld_page(parent,working_dirs): self = ttk.Frame(parent) # Multiworld multiFrame = Frame(self) ## Number of Worlds worldLabel = Label(multiFrame, text='Worlds') -# self.worldVar = StringVar(value=working_dirs["multi.worlds"]) - self.worldVar = StringVar(value="1") + self.worldVar = StringVar(value=working_dirs["multi.worlds"]) worldSpinbox = Spinbox(multiFrame, from_=1, to=100, width=5, textvariable=self.worldVar) worldLabel.pack(side=LEFT) worldSpinbox.pack(side=LEFT) ## List of Player Names namesLabel = Label(multiFrame, text='Player names') - self.namesVar = StringVar() -# self.namesVar = StringVar(value=working_dirs["multi.names"]) + self.namesVar = StringVar(value=working_dirs["multi.names"]) def saveMultiNames(caller,_,mode): - pass - #working_dirs["multi.names"] = self.namesVar.get() + working_dirs["multi.names"] = self.namesVar.get() self.namesVar.trace_add("write",saveMultiNames) namesEntry = Entry(multiFrame, textvariable=self.namesVar) namesLabel.pack(side=LEFT) namesEntry.pack(side=LEFT) multiFrame.pack(anchor=W) - return self#,working_dirs + return self,working_dirs