"""Verb system for interactive objects.""" from __future__ import annotations from collections.abc import Callable from typing import TYPE_CHECKING if TYPE_CHECKING: from mudlib.object import Object from mudlib.player import Player def verb(name: str) -> Callable: """Decorator to mark a method as a verb handler. Usage: class Fountain(Thing): @verb("drink") async def drink(self, player, args): await player.send("You drink from the fountain.\\r\\n") """ def decorator(func: Callable) -> Callable: func._verb_name = name # type: ignore return func return decorator def find_object(name: str, player: Player) -> Object | None: """Find an object by name or alias. Searches inventory first, then ground at player position. Works on all Objects that have a name and optional aliases attribute. """ name_lower = name.lower() # Search inventory first for obj in player.contents: if obj.name.lower() == name_lower: return obj # Check aliases if the object has them aliases = getattr(obj, "aliases", None) if aliases and name_lower in (a.lower() for a in aliases): return obj # Search ground at player position if player.location is not None: from mudlib.zone import Zone if isinstance(player.location, Zone): for obj in player.location.contents_at(player.x, player.y): if obj is player: continue if obj.name.lower() == name_lower: return obj # Check aliases if the object has them aliases = getattr(obj, "aliases", None) if aliases and name_lower in (a.lower() for a in aliases): return obj return None