diff --git a/Generate.py b/Generate.py index 509bf848d0..6855a6aaae 100644 --- a/Generate.py +++ b/Generate.py @@ -40,6 +40,8 @@ def mystery_argparse(argv: list[str] | None = None) -> argparse.Namespace: parser.add_argument('--spoiler', type=int, default=defaults.spoiler) parser.add_argument('--outputpath', default=settings.general_options.output_path, help="Path to output folder. Absolute or relative to cwd.") # absolute or relative to cwd + parser.add_argument('--allow_quantity', action="store_true", default=defaults.allow_quantity, + help='Allows the use of the quantity option in yamls. Default is the set value in the host.yaml.') parser.add_argument('--race', action='store_true', default=defaults.race) parser.add_argument('--meta_file_path', default=defaults.meta_file_path) parser.add_argument('--log_level', default=defaults.loglevel, help='Sets log level') @@ -123,6 +125,7 @@ def main(args=None) -> tuple[argparse.Namespace, int]: player_id: int = 1 player_files: dict[int, str] = {} player_errors: list[str] = [] + allow_quantity = args.allow_quantity for file in os.scandir(args.player_files_path): fname = file.name if file.is_file() and not fname.startswith(".") and not fname.lower().endswith(".ini") and \ @@ -134,7 +137,14 @@ def main(args=None) -> tuple[argparse.Namespace, int]: if yaml is None: logging.warning(f"Ignoring empty yaml document #{doc_idx + 1} in {fname}") else: - weights_for_file.append(yaml) + quantity = yaml.get("quantity", 1) + if quantity <= 0: + raise ValueError("A quantity of 0 or less is invalid. Please change it to at least 1.") + if not allow_quantity and quantity > 1: + raise ValueError("Quantity greater than 1 is deactivated by host settings.") + + for _ in range(quantity): + weights_for_file.append(yaml) weights_cache[fname] = tuple(weights_for_file) except Exception as e: diff --git a/settings.py b/settings.py index 3b3d0deec7..72ce53d92c 100644 --- a/settings.py +++ b/settings.py @@ -644,6 +644,12 @@ class GeneratorOptions(Group): class Players(int): """amount of players, 0 to infer from player files""" + class AllowQuantity(Bool): + """ + allow players to set an individual quantity for their yaml settings + with 'false' any amounts from the players will be ignored and set to 1 + """ + class WeightsFilePath(str): """ general weights file, within the stated player_files_path location @@ -690,6 +696,7 @@ class GeneratorOptions(Group): enemizer_path: EnemizerPath = EnemizerPath("EnemizerCLI/EnemizerCLI.Core") # + ".exe" is implied on Windows player_files_path: PlayerFilesPath = PlayerFilesPath("Players") players: Players = Players(0) + allow_quantity: AllowQuantity | bool = False weights_file_path: WeightsFilePath = WeightsFilePath("weights.yaml") meta_file_path: MetaFilePath = MetaFilePath("meta.yaml") spoiler: Spoiler = Spoiler(3) diff --git a/worlds/generic/docs/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md index 7dc0e6ba4c..6348ce2a58 100644 --- a/worlds/generic/docs/advanced_settings_en.md +++ b/worlds/generic/docs/advanced_settings_en.md @@ -60,7 +60,7 @@ adding more randomness and "mystery" to your options. Every configurable setting Currently, there are only a few options that are root options. Everything else should be nested within one of these root options or in some cases nested within other nested options. The only options that should exist in root -are `description`, `name`, `game`, `requires`, and the name of the games you want options for. +are `description`, `name`, `game`, `quantity`, `requires`, and the name of the games you want options for. * `description` is ignored by the generator and is simply a good way for you to organize if you have multiple files using this to detail the intention of the file. @@ -78,6 +78,9 @@ are `description`, `name`, `game`, `requires`, and the name of the games you wan * `game` is where either your chosen game goes or, if you would like, can be filled with multiple games each with different weights. +* `quantity` is the amount of times this yaml should be used when generating. This option is optional, the default value is 1. + To ensure that the name is unique with a value of at least two, the keywords from above must be used. + * `requires` details different requirements from the generator for the YAML to work as you expect it to. Generally this is good for detailing the version of Archipelago this YAML was prepared for. If it is rolled on an older version, options may be missing and as such it will not work as expected. If any plando is used in the file then requiring it