From 8513b7f270ff890e4b41c742df08de4c1aa8d816 Mon Sep 17 00:00:00 2001 From: "Mike A. Trethewey" Date: Sun, 22 Mar 2020 02:53:40 -0700 Subject: [PATCH] Fix var loading again Update Deprecated Args Parse CLI Parse Settings Fix defaults Fix priority Add Enemizer error Fix Custom Item Array again Make output more verbose Fix double-negative options --- CLI.py | 69 ++++++++++++------- DungeonRandomizer.py | 14 ++-- Gui.py | 16 ++--- ItemList.py | 10 +-- Main.py | 26 ++++--- Mystery.py | 4 +- Rom.py | 10 +-- Utils.py | 32 +++++++++ resources/app/cli/args.json | 40 +++++++---- resources/app/cli/lang/en.json | 8 ++- resources/app/gui/lang/en.json | 3 +- .../gui/randomize/generation/checkboxes.json | 3 +- source/classes/constants.py | 3 +- source/gui/bottom.py | 23 +++++-- source/gui/loadcliargs.py | 9 ++- 15 files changed, 185 insertions(+), 85 deletions(-) diff --git a/CLI.py b/CLI.py index 0565f570..32879689 100644 --- a/CLI.py +++ b/CLI.py @@ -11,27 +11,22 @@ import sys import source.classes.constants as CONST from source.classes.BabelFish import BabelFish +from Utils import update_deprecated_args + class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): def _get_help_string(self, action): return textwrap.dedent(action.help) -def parse_arguments(argv, no_defaults=False): +def parse_cli(argv, no_defaults=False): def defval(value): return value if not no_defaults else None # get settings - settings = get_settings() + settings = parse_settings() lang = "en" - if argv is not None: - priority = get_args_priority(None, None, argv) - if "load" in priority: - priority = priority["load"] - if "lang" in priority: - lang = priority["lang"] - fish = BabelFish(lang=lang) # we need to know how many players we have first @@ -57,13 +52,18 @@ def parse_arguments(argv, no_defaults=False): argatts["const"] = argdata["choices"][0] argatts["default"] = argdata["choices"][0] argatts["nargs"] = "?" - elif arg in settings: - argatts["default"] = defval(settings[arg] != 0) if "type" in argdata and argdata["type"] == "bool" else defval(settings[arg]) + if arg in settings: + default = settings[arg] + if "type" in argdata and argdata["type"] == "bool": + default = settings[arg] != 0 + argatts["default"] = defval(default) arghelp = fish.translate("cli","help",arg) if "help" in argdata and argdata["help"] == "suppress": argatts["help"] = argparse.SUPPRESS elif not isinstance(arghelp,str): argatts["help"] = '\n'.join(arghelp).replace("\\'","'") + else: + argatts["help"] = arghelp + " " + argatts["help"] parser.add_argument(argname,**argatts) parser.add_argument('--seed', default=defval(int(settings["seed"]) if settings["seed"] != "" and settings["seed"] is not None else None), help="\n".join(fish.translate("cli","help","seed")), type=int) @@ -87,7 +87,7 @@ def parse_arguments(argv, no_defaults=False): 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) + playerargs = parse_cli(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', @@ -105,7 +105,7 @@ def parse_arguments(argv, no_defaults=False): return ret -def get_settings(): +def parse_settings(): # set default settings settings = { "lang": "en", @@ -151,14 +151,16 @@ def get_settings(): "quickswap": False, "heartcolor": "red", "heartbeep": "normal", - "sprite": None, + "sprite": os.path.join(".","data","sprites","official","001.link.1.zspr"), "fastmenu": "normal", "ow_palettes": "default", "uw_palettes": "default", "create_spoiler": False, "skip_playthrough": False, + "calc_playthrough": True, "suppress_rom": False, + "create_rom": True, "usestartinventory": False, "custom": False, "rom": os.path.join(".", "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"), @@ -267,8 +269,8 @@ def get_settings(): # 3: Canned defaults def get_args_priority(settings_args, gui_args, cli_args): args = {} - args["settings"] = get_settings() if settings_args is None else settings_args - args["gui"] = {} if gui_args is None else gui_args + args["settings"] = parse_settings() if settings_args is None else settings_args + args["gui"] = gui_args args["cli"] = cli_args args["load"] = args["settings"] @@ -279,17 +281,38 @@ def get_args_priority(settings_args, gui_args, cli_args): if args["cli"] is None: args["cli"] = {} - cli = vars(parse_arguments(None)) + cli = vars(parse_cli(None)) for k, v in cli.items(): if isinstance(v, dict) and 1 in v: args["cli"][k] = v[1] else: args["cli"][k] = v - load_doesnt_have_key = k not in args["load"] - different_val = (k in args["load"] and k in args["cli"]) and (args["load"][k] != args["cli"][k]) - cli_has_empty_dict = k in args["cli"] and isinstance(args["cli"][k], dict) and len(args["cli"][k]) == 0 - if load_doesnt_have_key or different_val: - if not cli_has_empty_dict: - args["load"][k] = args["cli"][k] + args["cli"] = argparse.Namespace(**args["cli"]) + + cli = vars(args["cli"]) + for k in vars(args["cli"]): + load_doesnt_have_key = k not in args["load"] + cli_val = cli[k] + if isinstance(cli_val,dict) and 1 in cli_val: + cli_val = cli_val[1] + different_val = (k in args["load"] and k in cli) and (str(args["load"][k]) != str(cli_val)) + cli_has_empty_dict = k in cli and isinstance(cli_val, dict) and len(cli_val) == 0 + if load_doesnt_have_key or different_val: + if not cli_has_empty_dict: + args["load"][k] = cli_val + + newArgs = {} + for key in [ "settings", "gui", "cli", "load" ]: + if args[key]: + if isinstance(args[key],dict): + newArgs[key] = argparse.Namespace(**args[key]) + else: + newArgs[key] = args[key] + + newArgs[key] = update_deprecated_args(newArgs[key]) + else: + newArgs[key] = args[key] + + args = newArgs return args diff --git a/DungeonRandomizer.py b/DungeonRandomizer.py index 4a0c04e3..ca008a96 100755 --- a/DungeonRandomizer.py +++ b/DungeonRandomizer.py @@ -10,14 +10,14 @@ import sys from source.classes.BabelFish import BabelFish -from CLI import parse_arguments, get_args_priority -from Main import main +from CLI import parse_cli, get_args_priority +from Main import main, EnemizerError from Rom import get_sprite_from_name from Utils import is_bundled, close_console from Fill import FillError def start(): - args = parse_arguments(None) + args = parse_cli(None) if is_bundled() and len(sys.argv) == 1: # for the bundled builds, if we have no arguments, the user @@ -44,10 +44,10 @@ def start(): loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[args.loglevel] logging.basicConfig(format='%(message)s', level=loglevel) - settings = get_args_priority(None, None, None) + priority = get_args_priority(None, None, args) lang = "en" - if "load" in settings and "lang" in settings["load"]: - lang = settings["load"]["lang"] + if "load" in priority and "lang" in priority["load"]: + lang = priority["load"].lang fish = BabelFish(lang=lang) if args.gui: @@ -61,7 +61,7 @@ def start(): try: main(seed=seed, args=args, fish=fish) logger.info('%s %s', fish.translate("cli","cli","finished.run"), _+1) - except (FillError, Exception, RuntimeError) as err: + except (FillError, EnemizerError, Exception, RuntimeError) as err: failures.append((err, seed)) logger.warning('%s: %s', fish.translate("cli","cli","generation.failed"), err) seed = random.randint(0, 999999999) diff --git a/Gui.py b/Gui.py index ebe39f33..66fd4999 100755 --- a/Gui.py +++ b/Gui.py @@ -5,7 +5,7 @@ import sys from tkinter import Tk, Button, BOTTOM, TOP, StringVar, BooleanVar, X, BOTH, RIGHT, ttk, messagebox from CLI import get_args_priority -from DungeonRandomizer import parse_arguments +from DungeonRandomizer import parse_cli from source.gui.adjust.overview import adjust_page from source.gui.startinventory.overview import startinventory_page from source.gui.custom.overview import custom_page @@ -77,9 +77,13 @@ def guiMain(args=None): # get args # getting Settings & CLI (no GUI built yet) self.args = get_args_priority(None, None, None) + lang = "en" + if "load" in self.args and "lang" in self.args["load"]: + lang = self.args["load"].lang + self.fish = BabelFish(lang=lang) # get saved settings - self.settings = self.args["settings"] + self.settings = vars(self.args["settings"]) # make array for pages self.pages = {} @@ -146,12 +150,6 @@ def guiMain(args=None): # add randomizer notebook to main window self.pages["randomizer"].notebook.pack() - settings = get_args_priority(None, None, None) - lang = "en" - if "load" in settings and "lang" in settings["load"]: - lang = settings["load"]["lang"] - self.fish = BabelFish(lang=lang) - # bottom of window: Open Output Directory, Open Documentation (if exists) self.pages["bottom"] = Empty() self.pages["bottom"].pages = {} @@ -196,5 +194,5 @@ def guiMain(args=None): if __name__ == '__main__': - args = parse_arguments(None) + args = parse_cli(None) guiMain(args) diff --git a/ItemList.py b/ItemList.py index ffb6579e..27c0b384 100644 --- a/ItemList.py +++ b/ItemList.py @@ -258,7 +258,7 @@ def generate_itempool(world, player): # set up item pool if world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray) - world.rupoor_cost = min(world.customitemarray["rupoorcost"], 9999) + world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.doorShuffle[player]) @@ -322,9 +322,9 @@ def generate_itempool(world, player): # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) - if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and world.customitemarray["heartcontainer"] == 0): + if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and world.customitemarray[player]["heartcontainer"] == 0): [item for item in items if item.name == 'Boss Heart Container'][0].advancement = True - elif world.difficulty[player] in ['expert'] and not (world.custom and world.customitemarray["heartpiece"] < 4): + elif world.difficulty[player] in ['expert'] and not (world.custom and world.customitemarray[player]["heartpiece"] < 4): adv_heart_pieces = [item for item in items if item.name == 'Piece of Heart'][0:4] for hp in adv_heart_pieces: hp.advancement = True @@ -601,6 +601,8 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, r return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, customitemarray): + if isinstance(customitemarray,dict) and 1 in customitemarray: + customitemarray = customitemarray[1] pool = [] placed_items = {} precollected_items = [] @@ -698,7 +700,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode if itemtotal < total_items_to_place: nothings = total_items_to_place - itemtotal - print("Placing " + str(nothings) + " Nothings") +# print("Placing " + str(nothings) + " Nothings") pool.extend(['Nothing'] * nothings) return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) diff --git a/Main.py b/Main.py index 6ccb1719..407af108 100644 --- a/Main.py +++ b/Main.py @@ -26,6 +26,8 @@ from Utils import output_path, parse_player_names, print_wiki_doors_by_region, p __version__ = '0.0.18.6d' +class EnemizerError(RuntimeError): + pass def main(args, seed=None, fish=None): if args.outputpath: @@ -180,13 +182,12 @@ def main(args, seed=None, fish=None): if not world.can_beat_game(): raise RuntimeError(world.fish.translate("cli","cli","cannot.beat.game")) - logger.info(world.fish.translate("cli","cli","patching.rom")) - outfilebase = 'DR_%s' % (args.outputname if args.outputname else world.seed) rom_names = [] jsonout = {} if not args.suppress_rom: + logger.info(world.fish.translate("cli","cli","patching.rom")) for team in range(world.teams): for player in range(1, world.players + 1): sprite_random_on_hit = type(args.sprite[player]) is str and args.sprite[player].lower() == 'randomonhit' @@ -199,13 +200,17 @@ def main(args, seed=None, fish=None): patch_rom(world, rom, player, team, use_enemizer) if use_enemizer and (args.enemizercli or not args.jsonout): + if args.rom and not(os.path.isfile(args.rom)): + raise RuntimeError("Could not find valid base rom for enemizing at expected path %s." % args.rom) if os.path.exists(args.enemizercli): patch_enemizer(world, player, rom, args.rom, args.enemizercli, args.shufflepots[player], sprite_random_on_hit) if not args.jsonout: rom = LocalRom.fromJsonRom(rom, args.rom, 0x400000) else: - logging.warning(world.fish.translate("cli","cli","enemizer.not.found") + ': ' + args.enemizercli) - logging.warning(world.fish.translate("cli","cli","enemizer.nothing.applied")) + enemizerMsg = world.fish.translate("cli","cli","enemizer.not.found") + ': ' + args.enemizercli + "\n" + enemizerMsg += world.fish.translate("cli","cli","enemizer.nothing.applied") + logging.warning(enemizerMsg) + raise EnemizerError(enemizerMsg) if args.race: patch_race_rom(rom) @@ -255,19 +260,24 @@ def main(args, seed=None, fish=None): with open(output_path('%s_multidata' % outfilebase), 'wb') as f: f.write(multidata) - if args.create_spoiler and not args.jsonout: - world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase)) - if not args.skip_playthrough: logger.info(world.fish.translate("cli","cli","calc.playthrough")) create_playthrough(world) if args.jsonout: print(json.dumps({**jsonout, 'spoiler': world.spoiler.to_json()})) - elif args.create_spoiler and not args.skip_playthrough: + elif args.create_spoiler: + logger.info(world.fish.translate("cli","cli","patching.spoiler")) world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase)) + YES = world.fish.translate("cli","cli","yes") + NO = world.fish.translate("cli","cli","no") + logger.info("") logger.info(world.fish.translate("cli","cli","done")) + logger.info("") + logger.info(world.fish.translate("cli","cli","made.rom") % (YES if (args.create_rom) else NO)) + logger.info(world.fish.translate("cli","cli","made.playthrough") % (YES if (args.calc_playthrough) else NO)) + logger.info(world.fish.translate("cli","cli","made.spoiler") % (YES if (not args.jsonout and args.create_spoiler) else NO)) logger.info(world.fish.translate("cli","cli","seed") + ": %d", world.seed) logger.info(world.fish.translate("cli","cli","total.time"), time.perf_counter() - start) diff --git a/Mystery.py b/Mystery.py index d175be3e..f42123fd 100644 --- a/Mystery.py +++ b/Mystery.py @@ -5,7 +5,7 @@ import urllib.request import urllib.parse import re -from DungeonRandomizer import parse_arguments +from DungeonRandomizer import parse_cli from Main import main as DRMain def parse_yaml(txt): @@ -71,7 +71,7 @@ def main(): weights_cache[path] = get_weights(path) print(f"P{player} Weights: {path} >> {weights_cache[path]['description']}") - erargs = parse_arguments(['--multi', str(args.multi)]) + erargs = parse_cli(['--multi', str(args.multi)]) erargs.seed = seed erargs.names = args.names erargs.create_spoiler = args.create_spoiler diff --git a/Rom.py b/Rom.py index 7f74a53f..b2344e7f 100644 --- a/Rom.py +++ b/Rom.py @@ -78,6 +78,8 @@ class LocalRom(object): self.name = name self.hash = hash self.orig_buffer = None + if not os.path.isfile(file): + raise RuntimeError("Could not find valid local base rom for patching at expected path %s." % args.rom) with open(file, 'rb') as stream: self.buffer = read_rom(stream) if patch: @@ -759,10 +761,10 @@ def patch_rom(world, rom, player, team, enemized): difficulty.progressive_shield_limit, overflow_replacement, difficulty.progressive_armor_limit, overflow_replacement, difficulty.progressive_bottle_limit, overflow_replacement]) - + #Work around for json patch ordering issues - write bow limit separately so that it is replaced in the patch rom.write_bytes(0x180098, [difficulty.progressive_bow_limit, overflow_replacement]) - + if difficulty.progressive_bow_limit < 2 and world.swords == 'swordless': rom.write_bytes(0x180098, [2, overflow_replacement]) rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon @@ -2089,9 +2091,9 @@ def patch_shuffled_dark_sanc(world, rom, player): dark_sanc_entrance = str(world.get_region('Inverted Dark Sanctuary', player).entrances[0].name) room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[dark_sanc_entrance][1] door_index = door_addresses[str(dark_sanc_entrance)][0] - + rom.write_byte(0x180241, 0x01) - rom.write_byte(0x180248, door_index + 1) + rom.write_byte(0x180248, door_index + 1) write_int16(rom, 0x180250, room_id) rom.write_byte(0x180252, ow_area) write_int16s(rom, 0x180253, [vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x]) diff --git a/Utils.py b/Utils.py index 72d02161..63670d78 100644 --- a/Utils.py +++ b/Utils.py @@ -248,6 +248,38 @@ def print_wiki_doors_by_region(d_regions, world, player): with open(os.path.join(".","resources", "user", "regions-" + d + ".txt"),"w+") as f: f.write(toprint) +def update_deprecated_args(args): + argVars = vars(args) + truthy = [ 1, True, "True", "true" ] + # Don't do: Yes + # Do: No + if "suppress_rom" in argVars: + args.create_rom = args.suppress_rom not in truthy + # Don't do: No + # Do: Yes + if "create_rom" in argVars: + args.suppress_rom = not args.create_rom in truthy + + # Don't do: Yes + # Do: No + if "no_shuffleganon" in argVars: + args.shuffleganon = not args.no_shuffleganon in truthy + # Don't do: No + # Do: Yes + if "shuffleganon" in argVars: + args.no_shuffleganon = not args.shuffleganon in truthy + + # Don't do: Yes + # Do: No + if "skip_playthrough" in argVars: + args.calc_playthrough = not args.skip_playthrough in truthy + # Don't do: No + # Do: Yes + if "calc_playthrough" in argVars: + args.skip_playthrough = not args.calc_playthrough in truthy + + return args + def print_wiki_doors_by_room(d_regions, world, player): for d, region_list in d_regions.items(): tile_map = {} diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index b991620f..cc639ab5 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -107,10 +107,10 @@ }, "dungeon_counters": { "choices": [ + "default", "off", "on", - "pickup", - "default" + "pickup" ] }, "crystals_ganon": { @@ -198,15 +198,6 @@ "action": "store_true", "type": "bool" }, - "shuffleganon": { - "action": "store_true", - "type": "bool" - }, - "no-shuffleganon": { - "action": "store_false", - "dest": "shuffleganon", - "help": "suppress" - }, "heartbeep": { "choices": [ "normal", @@ -240,20 +231,39 @@ ] }, "sprite": {}, + "create_rom": { + "action": "store_false", + "type": "bool" + }, "suppress_rom": { "action": "store_true", + "dest": "create_rom", + "help": "suppress" + }, + "shuffleganon": { + "action": "store_false", "type": "bool" }, + "no_shuffleganon": { + "action": "store_true", + "dest": "shuffleganon", + "help": "suppress" + }, + "calc_playthrough": { + "action": "store_false", + "type": "bool" + }, + "skip_playthrough": { + "action": "store_true", + "dest": "calc_playthrough", + "help": "suppress" + }, "gui": { "action": "store_true" }, "jsonout": { "action": "store_true" }, - "skip_playthrough": { - "action": "store_true", - "type": "bool" - }, "enemizercli": { "setting": "enemizercli" }, diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index fdd58163..9c6519a4 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -1,5 +1,7 @@ { "cli": { + "yes": "Yes", + "no": "No", "app.title": "ALttP Door Randomizer Version %s - Seed: %d", "version": "Version", "seed": "Seed", @@ -33,7 +35,11 @@ "cannot.reach.progression": "Not all progression items reachable. Something went terribly wrong here.", "cannot.reach.required": "Not all required items reachable. Something went terribly wrong here.", "patching.rom": "Patching ROM", + "patching.spoiler": "Creating Spoiler", "calc.playthrough": "Calculating playthrough", + "made.rom": "Patched ROM: %s", + "made.playthrough": "Printed Playthrough: %s", + "made.spoiler": "Printed Spoiler: %s", "done": "Done. Enjoy.", "total.time": "Total Time: %s", "finished.run": "Finished run", @@ -262,7 +268,7 @@ "Alternatively, can be a ALttP Rom patched with a Link", "sprite that will be extracted." ], - "suppress_rom": [ "Do not create an output rom file. (default: %(default)s)" ], + "create_rom": [ "Create an output rom file. (default: %(default)s)" ], "gui": [ "Launch the GUI. (default: %(default)s)" ], "jsonout": [ "Output .json patch to stdout instead of a patched rom. Used", diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index d67963e5..da499b03 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -155,7 +155,8 @@ "randomizer.generation.spoiler": "Create Spoiler Log", - "randomizer.generation.suppressrom": "Do Not create Patched ROM", + "randomizer.generation.createrom": "Create Patched ROM", + "randomizer.generation.calcplaythrough": "Calculate Playthrough", "randomizer.generation.usestartinventory": "Use Starting Inventory", "randomizer.generation.usecustompool": "Use Custom Item Pool", diff --git a/resources/app/gui/randomize/generation/checkboxes.json b/resources/app/gui/randomize/generation/checkboxes.json index 5839e0d4..db020e6d 100644 --- a/resources/app/gui/randomize/generation/checkboxes.json +++ b/resources/app/gui/randomize/generation/checkboxes.json @@ -1,7 +1,8 @@ { "checkboxes": { "spoiler": { "type": "checkbox" }, - "suppressrom": { "type": "checkbox" }, + "createrom": { "type": "checkbox" }, + "calcplaythrough": { "type": "checkbox" }, "usestartinventory": { "type": "checkbox" }, "usecustompool": { "type": "checkbox" } } diff --git a/source/classes/constants.py b/source/classes/constants.py index 93064e7d..e8145f66 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -102,7 +102,8 @@ SETTINGSTOPROCESS = { }, "generation": { "spoiler": "create_spoiler", - "suppressrom": "suppress_rom", + "createrom": "create_rom", + "calcplaythrough": "calc_playthrough", "usestartinventory": "usestartinventory", "usecustompool": "custom", "saveonexit": "saveonexit" diff --git a/source/gui/bottom.py b/source/gui/bottom.py index 63eec2f9..cb01b471 100644 --- a/source/gui/bottom.py +++ b/source/gui/bottom.py @@ -3,9 +3,10 @@ from argparse import Namespace import logging import os import random -from CLI import parse_arguments -from Main import main -from Utils import local_path, output_path, open_file +from CLI import parse_cli +from Fill import FillError +from Main import main, EnemizerError +from Utils import local_path, output_path, open_file, update_deprecated_args import source.classes.constants as CONST from source.gui.randomize.multiworld import multiworld_page import source.gui.widgets as widgets @@ -68,7 +69,7 @@ def bottom_frame(self, parent, args=None): def generateRom(): guiargs = create_guiargs(parent) # get default values for missing parameters - for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items(): + for k,v in vars(parse_cli(['--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 @@ -81,11 +82,18 @@ def bottom_frame(self, parent, args=None): seed = random.randint(0, 999999999) else: main(seed=guiargs.seed, args=guiargs, fish=parent.fish) - except Exception as e: + except (FillError, EnemizerError, Exception, RuntimeError) as e: logging.exception(e) messagebox.showerror(title="Error while creating seed", message=str(e)) else: - messagebox.showinfo(title="Success", message="Rom patched successfully") + YES = parent.fish.translate("cli","cli","yes") + NO = parent.fish.translate("cli","cli","no") + successMsg = "" + successMsg += (parent.fish.translate("cli","cli","made.rom").strip() % (YES if (guiargs.create_rom) else NO)) + "\n" + successMsg += (parent.fish.translate("cli","cli","made.playthrough").strip() % (YES if (guiargs.calc_playthrough) else NO)) + "\n" + successMsg += (parent.fish.translate("cli","cli","made.spoiler").strip() % (YES if (not guiargs.jsonout and guiargs.create_spoiler) else NO)) + + messagebox.showinfo(title="Success", message=successMsg) ## Generate Button # widget ID @@ -226,4 +234,7 @@ def create_guiargs(parent): # Get output path guiargs.outputpath = parent.outputPath.get() + + guiargs = update_deprecated_args(guiargs) + return guiargs diff --git a/source/gui/loadcliargs.py b/source/gui/loadcliargs.py index 6db02220..83342892 100644 --- a/source/gui/loadcliargs.py +++ b/source/gui/loadcliargs.py @@ -1,6 +1,7 @@ from source.classes.SpriteSelector import SpriteSelector as spriteSelector from source.gui.randomize.gameoptions import set_sprite from Rom import Sprite, get_sprite_from_name +from Utils import update_deprecated_args import source.classes.constants as CONST from source.classes.BabelFish import BabelFish from source.classes.Empty import Empty @@ -8,10 +9,12 @@ from source.classes.Empty import Empty # Load args/settings for most tabs def loadcliargs(gui, args, settings=None): if args is not None: + args = update_deprecated_args(args) + args = vars(args) fish = BabelFish() -# for k, v in vars(args).items(): -# if type(v) is dict: -# setattr(args, k, v[1]) # only get values for player 1 for now + for k, v in args.items(): + if isinstance(v,dict) and 1 in v: + setattr(args, k, v[1]) # only get values for player 1 for now # load values from commandline args # set up options to get