mud/src/mudlib/commands/things.py
Jared Miller e96fd50de5
Add inventory command with alias "i"
Lists Thing objects in player.contents with 2-space indented format.
Shows "You aren't carrying anything." when inventory is empty.
2026-02-11 20:01:05 -05:00

96 lines
2.9 KiB
Python

"""Get, drop, and inventory commands for items."""
from mudlib.commands import CommandDefinition, register
from mudlib.player import Player
from mudlib.thing import Thing
from mudlib.zone import Zone
def _find_thing_at(name: str, zone: Zone, x: int, y: int) -> Thing | None:
"""Find a thing on the ground matching name or alias."""
name_lower = name.lower()
for obj in zone.contents_at(x, y):
if not isinstance(obj, Thing):
continue
if obj.name.lower() == name_lower:
return obj
if name_lower in (a.lower() for a in obj.aliases):
return obj
return None
def _find_thing_in_inventory(name: str, player: Player) -> Thing | None:
"""Find a thing in the player's inventory matching name or alias."""
name_lower = name.lower()
for obj in player.contents:
if not isinstance(obj, Thing):
continue
if obj.name.lower() == name_lower:
return obj
if name_lower in (a.lower() for a in obj.aliases):
return obj
return None
async def cmd_get(player: Player, args: str) -> None:
"""Pick up an item from the ground."""
if not args.strip():
await player.send("Get what?\r\n")
return
zone = player.location
if zone is None or not isinstance(zone, Zone):
await player.send("You are nowhere.\r\n")
return
thing = _find_thing_at(args.strip(), zone, player.x, player.y)
if thing is None:
await player.send(f"You don't see '{args.strip()}' here.\r\n")
return
if not player.can_accept(thing):
await player.send("You can't pick that up.\r\n")
return
thing.move_to(player)
await player.send(f"You pick up {thing.name}.\r\n")
async def cmd_drop(player: Player, args: str) -> None:
"""Drop an item from inventory onto the ground."""
if not args.strip():
await player.send("Drop what?\r\n")
return
zone = player.location
if zone is None or not isinstance(zone, Zone):
await player.send("You can't drop things here.\r\n")
return
thing = _find_thing_in_inventory(args.strip(), player)
if thing is None:
await player.send(f"You're not carrying '{args.strip()}'.\r\n")
return
thing.move_to(zone, x=player.x, y=player.y)
await player.send(f"You drop {thing.name}.\r\n")
async def cmd_inventory(player: Player, args: str) -> None:
"""List items in the player's inventory."""
things = [obj for obj in player.contents if isinstance(obj, Thing)]
if not things:
await player.send("You aren't carrying anything.\r\n")
return
lines = ["You are carrying:\r\n"]
for thing in things:
lines.append(f" {thing.name}\r\n")
await player.send("".join(lines))
register(CommandDefinition("get", cmd_get, aliases=["take", "pick"]))
register(CommandDefinition("drop", cmd_drop))
register(CommandDefinition("inventory", cmd_inventory, aliases=["i"]))