from dataclasses import dataclass, field from typing import Dict, Optional @dataclass class Outcome: text: str items_reward: Dict[str, int] = field(default_factory=dict) damage_taken: int = 0 @dataclass class Action: id: str label: str stamina_cost: int outcomes: Dict[str, Outcome] = field(default_factory=dict) def add_outcome(self, name: str, outcome: Outcome): self.outcomes[name] = outcome @dataclass class Interactable: id: str name: str actions: Dict[str, Action] = field(default_factory=dict) image_path: Optional[str] = None def add_action(self, action: Action): self.actions[action.id] = action def get_action(self, action_id: str) -> Optional[Action]: return self.actions.get(action_id) @dataclass class Location: id: str name: str description: str exits: Dict[str, str] = field(default_factory=dict) interactables: Dict[str, Interactable] = field(default_factory=dict) # Key is now the INSTANCE_ID image_path: Optional[str] = None x: float = 0.0 # X coordinate for map positioning y: float = 0.0 # Y coordinate for map positioning tags: list = field(default_factory=list) # Location tags like 'workbench', 'safe_zone', etc. npcs: list = field(default_factory=list) # NPCs at this location danger_level: int = 0 # Danger level of the location def add_exit(self, direction: str, destination_id: str): self.exits[direction] = destination_id def add_interactable(self, instance_id: str, interactable_template: Interactable): """Adds an instance of an interactable template to the location.""" self.interactables[instance_id] = interactable_template def get_interactable(self, instance_id: str) -> Optional[Interactable]: return self.interactables.get(instance_id) class World: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super(World, cls).__new__(cls) cls._instance.locations = {} return cls._instance def add_location(self, location: Location): self.locations[location.id] = location def get_location(self, location_id: str) -> Optional[Location]: return self.locations.get(location_id)