Fix GMCP and MSDP support for rich clients
This commit is contained in:
parent
ca282851e3
commit
3d386fbf99
3 changed files with 24 additions and 11 deletions
|
|
@ -20,6 +20,7 @@ class Entity(Object):
|
|||
y: int = 0
|
||||
# Combat stats
|
||||
pl: float = 100.0 # power level (health and damage multiplier)
|
||||
max_pl: float = 100.0 # maximum power level
|
||||
stamina: float = 100.0 # current stamina
|
||||
max_stamina: float = 100.0 # stamina ceiling
|
||||
defense_locked_until: float = 0.0 # monotonic time when defense recovery ends
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@ log = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def send_char_vitals(player: Player) -> None:
|
||||
"""Send Char.Vitals — pl, stamina, max_stamina."""
|
||||
player.writer.send_gmcp(
|
||||
"""Send Char.Vitals — pl, max_pl, stamina, max_stamina."""
|
||||
player.send_gmcp(
|
||||
"Char.Vitals",
|
||||
{
|
||||
"pl": round(player.pl, 1),
|
||||
"max_pl": round(player.max_pl, 1),
|
||||
"stamina": round(player.stamina, 1),
|
||||
"max_stamina": round(player.max_stamina, 1),
|
||||
},
|
||||
|
|
@ -25,7 +26,7 @@ def send_char_vitals(player: Player) -> None:
|
|||
|
||||
def send_char_status(player: Player) -> None:
|
||||
"""Send Char.Status — flying, resting, mode, in_combat."""
|
||||
player.writer.send_gmcp(
|
||||
player.send_gmcp(
|
||||
"Char.Status",
|
||||
{
|
||||
"flying": player.flying,
|
||||
|
|
@ -53,13 +54,17 @@ def send_room_info(player: Player) -> None:
|
|||
("south", 0, 1),
|
||||
("east", 1, 0),
|
||||
("west", -1, 0),
|
||||
("northeast", 1, -1),
|
||||
("northwest", -1, -1),
|
||||
("southeast", 1, 1),
|
||||
("southwest", -1, 1),
|
||||
]
|
||||
for name, dx, dy in directions:
|
||||
nx, ny = player.x + dx, player.y + dy
|
||||
if zone.is_passable(nx, ny):
|
||||
exits.append(name)
|
||||
|
||||
player.writer.send_gmcp(
|
||||
player.send_gmcp(
|
||||
"Room.Info",
|
||||
{
|
||||
"zone": zone.name,
|
||||
|
|
@ -90,7 +95,7 @@ def send_map_data(player: Player) -> None:
|
|||
row.append(zone.terrain[wy][wx])
|
||||
rows.append(row)
|
||||
|
||||
player.writer.send_gmcp(
|
||||
player.send_gmcp(
|
||||
"Room.Map",
|
||||
{
|
||||
"x": player.x,
|
||||
|
|
@ -103,10 +108,10 @@ def send_map_data(player: Player) -> None:
|
|||
|
||||
def send_msdp_vitals(player: Player) -> None:
|
||||
"""Send MSDP variable updates for real-time gauges."""
|
||||
player.writer.send_msdp(
|
||||
player.send_msdp(
|
||||
{
|
||||
"HEALTH": str(round(player.pl, 1)),
|
||||
"HEALTH_MAX": str(round(player.pl, 1)),
|
||||
"HEALTH_MAX": str(round(player.max_pl, 1)),
|
||||
"STAMINA": str(round(player.stamina, 1)),
|
||||
"STAMINA_MAX": str(round(player.max_stamina, 1)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ def player(mock_writer, test_zone):
|
|||
p = Player(name="Goku", x=10, y=10, writer=mock_writer)
|
||||
p.location = test_zone
|
||||
p.pl = 85.5
|
||||
p.max_pl = 100.0
|
||||
p.stamina = 42.3
|
||||
p.max_stamina = 100.0
|
||||
players[p.name] = p
|
||||
|
|
@ -69,6 +70,7 @@ def test_send_char_vitals(player):
|
|||
"Char.Vitals",
|
||||
{
|
||||
"pl": 85.5,
|
||||
"max_pl": 100.0,
|
||||
"stamina": 42.3,
|
||||
"max_stamina": 100.0,
|
||||
},
|
||||
|
|
@ -131,13 +133,15 @@ def test_send_room_info(player):
|
|||
assert data["x"] == 10
|
||||
assert data["y"] == 10
|
||||
assert data["terrain"] == "."
|
||||
# All adjacent tiles should be passable except north (mountain at 10,5)
|
||||
# north is y-1 = 9, but mountain is at y=5
|
||||
# Player at 10,10 so adjacent tiles are all "." and passable
|
||||
# All adjacent tiles should be passable (player at 10,10, all tiles are ".")
|
||||
assert "north" in data["exits"]
|
||||
assert "south" in data["exits"]
|
||||
assert "east" in data["exits"]
|
||||
assert "west" in data["exits"]
|
||||
assert "northeast" in data["exits"]
|
||||
assert "northwest" in data["exits"]
|
||||
assert "southeast" in data["exits"]
|
||||
assert "southwest" in data["exits"]
|
||||
|
||||
|
||||
def test_send_room_info_blocked_exit(player, test_zone):
|
||||
|
|
@ -215,7 +219,7 @@ def test_send_msdp_vitals(player):
|
|||
player.writer.send_msdp.assert_called_once_with(
|
||||
{
|
||||
"HEALTH": "85.5",
|
||||
"HEALTH_MAX": "85.5",
|
||||
"HEALTH_MAX": "100.0",
|
||||
"STAMINA": "42.3",
|
||||
"STAMINA_MAX": "100.0",
|
||||
}
|
||||
|
|
@ -296,6 +300,7 @@ async def test_char_vitals_sent_on_rest_complete(player):
|
|||
assert second_call[0][0] == "Char.Vitals"
|
||||
assert second_call[0][1] == {
|
||||
"pl": round(player.pl, 1),
|
||||
"max_pl": round(player.max_pl, 1),
|
||||
"stamina": round(player.max_stamina, 1),
|
||||
"max_stamina": round(player.max_stamina, 1),
|
||||
}
|
||||
|
|
@ -364,6 +369,7 @@ async def test_char_vitals_sent_on_combat_resolve():
|
|||
attacker_call = mock_writer_1.send_gmcp.call_args[0]
|
||||
assert attacker_call[0] == "Char.Vitals"
|
||||
assert "pl" in attacker_call[1]
|
||||
assert "max_pl" in attacker_call[1]
|
||||
assert "stamina" in attacker_call[1]
|
||||
assert "max_stamina" in attacker_call[1]
|
||||
|
||||
|
|
@ -371,6 +377,7 @@ async def test_char_vitals_sent_on_combat_resolve():
|
|||
defender_call = mock_writer_2.send_gmcp.call_args[0]
|
||||
assert defender_call[0] == "Char.Vitals"
|
||||
assert "pl" in defender_call[1]
|
||||
assert "max_pl" in defender_call[1]
|
||||
assert "stamina" in defender_call[1]
|
||||
assert "max_stamina" in defender_call[1]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue