From ec75793ac3178fdd894c5dafd25a45d0bcb3c508 Mon Sep 17 00:00:00 2001 From: Benjamin S Wolf Date: Sat, 5 Apr 2025 06:50:52 -0700 Subject: [PATCH] Core: Add spoiler-only output mode (#4059) * Core: Add spoiler-only output mode * spoiler-only exceptions * Move new errors to mystery_argparse --- Generate.py | 13 +++++++++++++ Main.py | 11 ++++++++++- WebHostLib/generate.py | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Generate.py b/Generate.py index 48161550..82386644 100644 --- a/Generate.py +++ b/Generate.py @@ -54,12 +54,22 @@ def mystery_argparse(): parser.add_argument("--skip_output", action="store_true", help="Skips generation assertion and output stages and skips multidata and spoiler output. " "Intended for debugging and testing purposes.") + parser.add_argument("--spoiler_only", action="store_true", + help="Skips generation assertion and multidata, outputting only a spoiler log. " + "Intended for debugging and testing purposes.") args = parser.parse_args() + + if args.skip_output and args.spoiler_only: + parser.error("Cannot mix --skip_output and --spoiler_only") + elif args.spoiler == 0 and args.spoiler_only: + parser.error("Cannot use --spoiler_only when --spoiler=0. Use --skip_output or set --spoiler to a different value") + if not os.path.isabs(args.weights_file_path): args.weights_file_path = os.path.join(args.player_files_path, args.weights_file_path) if not os.path.isabs(args.meta_file_path): args.meta_file_path = os.path.join(args.player_files_path, args.meta_file_path) args.plando: PlandoOptions = PlandoOptions.from_option_string(args.plando) + return args @@ -108,6 +118,8 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: raise Exception("Cannot mix --sameoptions with --meta") else: meta_weights = None + + player_id = 1 player_files = {} for file in os.scandir(args.player_files_path): @@ -164,6 +176,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: erargs.outputpath = args.outputpath erargs.skip_prog_balancing = args.skip_prog_balancing erargs.skip_output = args.skip_output + erargs.spoiler_only = args.spoiler_only erargs.name = {} erargs.csv_output = args.csv_output diff --git a/Main.py b/Main.py index d0e7a7f8..528db10c 100644 --- a/Main.py +++ b/Main.py @@ -81,7 +81,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No del item_digits, location_digits, item_count, location_count # This assertion method should not be necessary to run if we are not outputting any multidata. - if not args.skip_output: + if not args.skip_output and not args.spoiler_only: AutoWorld.call_stage(multiworld, "assert_generate") AutoWorld.call_all(multiworld, "generate_early") @@ -224,6 +224,15 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No logger.info(f'Beginning output...') outfilebase = 'AP_' + multiworld.seed_name + if args.spoiler_only: + if args.spoiler > 1: + logger.info('Calculating playthrough.') + multiworld.spoiler.create_playthrough(create_paths=args.spoiler > 2) + + multiworld.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase)) + logger.info('Done. Skipped multidata modification. Total time: %s', time.perf_counter() - start) + return multiworld + output = tempfile.TemporaryDirectory() with output as temp_dir: output_players = [player for player in multiworld.player_ids if AutoWorld.World.generate_output.__code__ diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 0bd9f7e5..34033a08 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -135,6 +135,7 @@ def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=Non {"bosses", "items", "connections", "texts"})) erargs.skip_prog_balancing = False erargs.skip_output = False + erargs.spoiler_only = False erargs.csv_output = False name_counter = Counter()