diff --git a/schemas/Manual.game.schema.json b/schemas/Manual.game.schema.json index 360dda4f..11ad351f 100644 --- a/schemas/Manual.game.schema.json +++ b/schemas/Manual.game.schema.json @@ -17,8 +17,11 @@ "type": "string" }, "filler_item_name": { - "description": "Name of the filler items that get placed when there's no more real items to place.", - "type": "string" + "description": "Names of the filler items that get placed when there's no more real items to place.", + "type": ["string", "array"], + "items": { + "type":"string" + } }, "starting_items": { "description": "(Optional) Starting inventory", diff --git a/src/Items.py b/src/Items.py index 402f37ed..0369b215 100644 --- a/src/Items.py +++ b/src/Items.py @@ -15,7 +15,7 @@ count = starting_index -filler_found = False +filler_found: set[str] = set() # add sequential generated ids to the lists for key, val in enumerate(item_table): @@ -30,13 +30,25 @@ item_table[key]["progression"] = val["progression"] if "progression" in val else False if isinstance(val.get("category", []), str): item_table[key]["category"] = [val["category"]] - if item_table[key].get("name") == filler_item_name: - filler_found = True + if isinstance(filler_item_name, list): + if item_table[key].get("name") in filler_item_name: + filler_found.add(item_table[key].get("name")) + elif isinstance(filler_item_name, str): + if item_table[key].get("name") == filler_item_name: + filler_found.add(item_table[key].get("name")) count += 1 # add the filler item to the list of items for lookup -if filler_item_name and not filler_found: +if isinstance(filler_item_name, list): + for generic_filler in filler_item_name: + if generic_filler not in filler_found: + item_table.append({ + "name": generic_filler, + "id": count, + }) + count += 1 +elif isinstance(filler_item_name, str) and not filler_found: item_table.append({ "name": filler_item_name, "id": count, diff --git a/src/__init__.py b/src/__init__.py index fb363ddc..3489f12b 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -75,7 +75,16 @@ class ManualWorld(World): origin_region_name = "Manual" def get_filler_item_name(self) -> str: - return hook_get_filler_item_name(self, self.multiworld, self.player) or self.filler_item_name + hook_result = hook_get_filler_item_name(self, self.multiworld, self.player) + if hook_result and isinstance(hook_result, str): + return hook_result + elif hook_result and isinstance(hook_result, list): + return self.random.choice(hook_result) + elif isinstance(filler_item_name, str): + return self.filler_item_name + else: + random_filler_name = self.random.choice(filler_item_name) + return random_filler_name def interpret_slot_data(self, slot_data: dict[str, Any]) -> dict[str, Any]: #this is called by tools like UT @@ -126,7 +135,11 @@ def create_items(self): items_config: dict[str, int|dict[ItemClassification | str | int, int]] = {} for name in configured_item_names.values(): if name == "__Victory__": continue - if name == filler_item_name: continue # intentionally using the Game.py filler_item_name here because it's a non-Items item + # intentionally using the Game.py filler_item_name here because it can be a non-Items item + if isinstance(filler_item_name, str): + if name == filler_item_name: continue + elif isinstance(filler_item_name, list): + if name in filler_item_name: continue item = self.item_name_to_item[name] item_count = int(item.get("count", 1)) diff --git a/src/hooks/World.py b/src/hooks/World.py index 930f476b..d523424d 100644 --- a/src/hooks/World.py +++ b/src/hooks/World.py @@ -34,7 +34,7 @@ # Use this function to change the valid filler items to be created to replace item links or starting items. # Default value is the `filler_item_name` from game.json -def hook_get_filler_item_name(world: World, multiworld: MultiWorld, player: int) -> str | bool: +def hook_get_filler_item_name(world: World, multiworld: MultiWorld, player: int) -> list[str] | str | bool: return False def before_generate_early(world: World, multiworld: MultiWorld, player: int) -> None: