Implements a global examine/ex command that shows detailed descriptions of objects. Searches inventory first, then ground at player position. Works with Things, Containers, and Mobs.
80 lines
2.3 KiB
Python
80 lines
2.3 KiB
Python
"""Examine command for detailed object inspection."""
|
|
|
|
from mudlib.commands import CommandDefinition, register
|
|
from mudlib.entity import Entity
|
|
from mudlib.player import Player
|
|
from mudlib.thing import Thing
|
|
from mudlib.zone import Zone
|
|
|
|
|
|
def _find_object_in_inventory(name: str, player: Player) -> Thing | Entity | None:
|
|
"""Find an object in player inventory by name or alias."""
|
|
name_lower = name.lower()
|
|
for obj in player.contents:
|
|
# Only examine Things and Entities
|
|
if not isinstance(obj, (Thing, Entity)):
|
|
continue
|
|
|
|
# Match by name
|
|
if obj.name.lower() == name_lower:
|
|
return obj
|
|
|
|
# Match by alias (Things have aliases)
|
|
if isinstance(obj, Thing) and name_lower in (a.lower() for a in obj.aliases):
|
|
return obj
|
|
|
|
return None
|
|
|
|
|
|
def _find_object_at_position(name: str, player: Player) -> Thing | Entity | None:
|
|
"""Find an object on the ground at player position by name or alias."""
|
|
zone = player.location
|
|
if zone is None or not isinstance(zone, Zone):
|
|
return None
|
|
|
|
name_lower = name.lower()
|
|
for obj in zone.contents_at(player.x, player.y):
|
|
# Only examine Things and Entities
|
|
if not isinstance(obj, (Thing, Entity)):
|
|
continue
|
|
|
|
# Match by name
|
|
if obj.name.lower() == name_lower:
|
|
return obj
|
|
|
|
# Match by alias (Things have aliases)
|
|
if isinstance(obj, Thing) and name_lower in (a.lower() for a in obj.aliases):
|
|
return obj
|
|
|
|
return None
|
|
|
|
|
|
async def cmd_examine(player: Player, args: str) -> None:
|
|
"""Examine an object in detail."""
|
|
if not args.strip():
|
|
await player.send("Examine what?\r\n")
|
|
return
|
|
|
|
target_name = args.strip()
|
|
|
|
# Search inventory first
|
|
found = _find_object_in_inventory(target_name, player)
|
|
|
|
# Then search ground
|
|
if not found:
|
|
found = _find_object_at_position(target_name, player)
|
|
|
|
# Not found anywhere
|
|
if not found:
|
|
await player.send("You don't see that here.\r\n")
|
|
return
|
|
|
|
# Show description (both Thing and Entity have description)
|
|
desc = getattr(found, "description", "")
|
|
if desc:
|
|
await player.send(f"{desc}\r\n")
|
|
else:
|
|
await player.send("You see nothing special.\r\n")
|
|
|
|
|
|
register(CommandDefinition("examine", cmd_examine, aliases=["ex"], mode="*"))
|