from __future__ import annotations import uuid from dataclasses import dataclass, field from engine.character import Character from engine.defs import DefRegistry from engine.item import ItemInstance @dataclass class DevSpawnMenu: """Dev-mode-only cheat tool: cycle through every loaded item def and materialize one straight into the player's inventory (first free-fitting slot). Gated off in normal play by engine/dev_config.py::DevConfig.enabled - see main.py's dev_spawn_object handling. No world floor-item system exists in this engine yet (items only ever live in an Inventory, or worn/held on a Character), so "spawning" here means "into inventory", not placing a loose item on the ground - that's a bigger feature this doesn't attempt. """ registry: DefRegistry item_ids: list[str] = field(default_factory=list) selected_index: int = 0 def __post_init__(self) -> None: if not self.item_ids: self.item_ids = sorted(self.registry.item_defs) def cycle(self, delta: int) -> None: if self.item_ids: self.selected_index = (self.selected_index + delta) % len(self.item_ids) def selected_item_id(self) -> str | None: if not self.item_ids: return None return self.item_ids[self.selected_index] def spawn_into(self, character: Character) -> bool: """Returns whether it actually fit - a no-op (False) if the character has no inventory or the selected item has nowhere left to go. """ item_id = self.selected_item_id() if item_id is None or character.inventory is None: return False item_def = self.registry.get_item_def(item_id) slot = character.inventory.find_first_fit(item_def) if slot is None: return False instance = ItemInstance(f"dev-spawn-{uuid.uuid4().hex[:8]}", item_id) return character.inventory.place(instance, item_def, *slot)