From 2e79255aece8008f36721909d2e148108ac13666 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Wed, 11 Feb 2026 20:01:10 -0500 Subject: [PATCH] Show ground items in look command After the viewport, look lists Things at the player's position in a "On the ground: item1, item2" line. No output when empty. --- src/mudlib/commands/look.py | 10 ++++++ tests/test_commands.py | 64 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/mudlib/commands/look.py b/src/mudlib/commands/look.py index 521e7e6..3e96e9e 100644 --- a/src/mudlib/commands/look.py +++ b/src/mudlib/commands/look.py @@ -5,6 +5,7 @@ from mudlib.effects import get_effects_at from mudlib.entity import Entity from mudlib.player import Player from mudlib.render.ansi import RESET, colorize_terrain +from mudlib.thing import Thing from mudlib.zone import Zone # Viewport dimensions @@ -99,6 +100,15 @@ async def cmd_look(player: Player, args: str) -> None: # Send to player player.writer.write("\r\n".join(output_lines) + "\r\n") + + # Show items on the ground at player's position + ground_items = [ + obj for obj in zone.contents_at(player.x, player.y) if isinstance(obj, Thing) + ] + if ground_items: + names = ", ".join(item.name for item in ground_items) + player.writer.write(f"On the ground: {names}\r\n") + await player.writer.drain() diff --git a/tests/test_commands.py b/tests/test_commands.py index e97ac4d..4bf419b 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -368,3 +368,67 @@ async def test_dispatch_allows_matching_mode(player): await commands.dispatch(player, "strike") assert called + + +@pytest.mark.asyncio +async def test_look_shows_ground_items(player, test_zone): + """look shows things on the ground at the player's position.""" + from mudlib.player import players + from mudlib.thing import Thing + + players.clear() + players[player.name] = player + + Thing(name="rock", location=test_zone, x=5, y=5) + await look.cmd_look(player, "") + + output = "".join([call[0][0] for call in player.writer.write.call_args_list]) + assert "rock" in output.lower() + + +@pytest.mark.asyncio +async def test_look_shows_multiple_ground_items(player, test_zone): + """look shows all things at the player's position.""" + from mudlib.player import players + from mudlib.thing import Thing + + players.clear() + players[player.name] = player + + Thing(name="rock", location=test_zone, x=5, y=5) + Thing(name="sword", location=test_zone, x=5, y=5) + await look.cmd_look(player, "") + + output = "".join([call[0][0] for call in player.writer.write.call_args_list]) + assert "rock" in output.lower() + assert "sword" in output.lower() + + +@pytest.mark.asyncio +async def test_look_no_ground_items_no_extra_output(player, test_zone): + """look with no ground items doesn't mention items.""" + from mudlib.player import players + + players.clear() + players[player.name] = player + + await look.cmd_look(player, "") + + output = "".join([call[0][0] for call in player.writer.write.call_args_list]) + assert "on the ground" not in output.lower() + + +@pytest.mark.asyncio +async def test_look_ignores_items_at_other_positions(player, test_zone): + """look doesn't show items that are at different positions.""" + from mudlib.player import players + from mudlib.thing import Thing + + players.clear() + players[player.name] = player + + Thing(name="far_rock", location=test_zone, x=9, y=9) + await look.cmd_look(player, "") + + output = "".join([call[0][0] for call in player.writer.write.call_args_list]) + assert "far_rock" not in output.lower()