import dataclasses from typing import Mapping, Optional, Sequence, Union from agame.action import Action __all__ = ( "ItemInst", "Item", ) @dataclasses.dataclass class ItemInst: """ An instance of an item in the game. """ # Reference to the global item that this is an instance of. item: "Item" # Gets whether this item can be taken. fixed: bool = False # Gets how many of this item instance are present in this stack. count: int = 1 # Gets whether this item is revealed or not. revealed: bool = True @property def id(self) -> str: return self.item.id @property def name(self) -> str: return self.item.name @property def desc(self) -> Optional[str]: return self.item.desc @property def synonyms(self) -> Sequence[str]: return self.item.synonyms @property def room_desc(self) -> Optional[Union[str, Sequence[str]]]: return self.item.room_desc @property def triggers(self) -> Mapping[str, Sequence[Action]]: return self.item.triggers @property def use_actions(self) -> Mapping[str, Sequence[Action]]: return self.item.use_actions @dataclasses.dataclass class Item: """ A game item. """ # The ID of this item. This is how items are looked up in the game. id: str # The printable name of this item. name: str # A long description for this item. desc: Optional[str] = None # A list of all synonyms for this item. synonyms: Sequence[str] = dataclasses.field(default_factory=list) # The description that is used in the context of a room's `look` command. # # When someone wants to look at the entire room, all items that have been # revealed will also be displayed. # # If you want to disable this behavior entirely, `room_desc` should be set # to `None`. # # If you want to use the default text, "You see a (({item.name}))", # `room_desc` should be set to the blank string, `""`. # # Otherwise, the `room_desc` string will be colorized and printed as # written. room_desc: Optional[Union[str, Sequence[str]]] = None # A list of triggers that a game may use. Since this is just a mapping of # strings to action sequences, only one set of actions is allowed per # trigger. # # Valid triggers include: # * get # * use # * put # * look # * open # * close # ...more to come triggers: Mapping[str, Sequence[Action]] = dataclasses.field(default_factory=dict) # A mapping of other items that this item may be used with, specifically on # the USE command. # # USE is a strange beast, because instead of just one implicit target (which # is verified to exist by the trigger, of all things) we have *two* targets: # the subject and the direct object. And not always! # # For example, we have an item, paintbrush. These are some options: # use paintbrush # <- on what? # use paintbrush on canvas # <- you paint a beautiful masterpiece. # use paintbrush on car # <- that's not allowed (custom text) # use paintbrush on fake item # <- that item doesn't exist # # We can't really represent this with the current str -> sequence[action] # stuff we have in place right now, so a special field will be good enough # until a more insane/robust solution is implemented. use_actions: Mapping[str, Sequence[Action]] = dataclasses.field( default_factory=dict ) def create_inst(self, *args, **kwargs): """ Creates a new item instance, passing the supplied args and kwargs to the ItemInst constructor. """ return ItemInst(item=self, *args, **kwargs)