Increment player.kills and player.mob_kills on mob defeat, player.deaths on player defeat. Session time accumulation via accumulate_play_time helper.
154 lines
4.4 KiB
Python
154 lines
4.4 KiB
Python
"""Tests for kill and death tracking in combat."""
|
|
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from mudlib.combat.engine import (
|
|
process_combat,
|
|
start_encounter,
|
|
)
|
|
from mudlib.combat.moves import CombatMove
|
|
from mudlib.entity import Mob
|
|
from mudlib.player import accumulate_play_time
|
|
|
|
|
|
@pytest.fixture
|
|
def punch_move():
|
|
"""Create a basic punch move for testing."""
|
|
return CombatMove(
|
|
name="punch right",
|
|
move_type="attack",
|
|
stamina_cost=5.0,
|
|
timing_window_ms=800,
|
|
damage_pct=0.15,
|
|
countered_by=[],
|
|
resolve_hit="{attacker} hits {defender}!",
|
|
resolve_miss="{defender} dodges!",
|
|
announce="{attacker} punches!",
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_player_kills_mob_increments_stats(player, test_zone, punch_move):
|
|
"""Player kills mob -> kills incremented, mob_kills tracked."""
|
|
# Create a goblin mob
|
|
goblin = Mob(name="goblin", x=0, y=0)
|
|
goblin.location = test_zone
|
|
test_zone._contents.append(goblin)
|
|
|
|
# Start encounter
|
|
encounter = start_encounter(player, goblin)
|
|
|
|
# Execute attack
|
|
encounter.attack(punch_move)
|
|
|
|
# Advance past telegraph (0.3s) + window (0.8s)
|
|
encounter.tick(time.monotonic() + 0.31) # -> WINDOW
|
|
encounter.tick(time.monotonic() + 1.2) # -> RESOLVE
|
|
|
|
# Set defender to very low pl so damage kills them
|
|
goblin.pl = 1.0
|
|
|
|
# Process combat (this will resolve and end encounter)
|
|
await process_combat()
|
|
|
|
# Verify stats
|
|
assert player.kills == 1
|
|
assert player.mob_kills["goblin"] == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_player_killed_by_mob_increments_deaths(player, test_zone, punch_move):
|
|
"""Player killed by mob -> deaths incremented."""
|
|
# Create a goblin mob
|
|
goblin = Mob(name="goblin", x=0, y=0)
|
|
goblin.location = test_zone
|
|
test_zone._contents.append(goblin)
|
|
|
|
# Start encounter with mob as attacker
|
|
encounter = start_encounter(goblin, player)
|
|
|
|
# Execute attack
|
|
encounter.attack(punch_move)
|
|
|
|
# Advance to RESOLVE
|
|
encounter.tick(time.monotonic() + 0.31)
|
|
encounter.tick(time.monotonic() + 1.2)
|
|
|
|
# Set player to low pl so they die
|
|
player.pl = 1.0
|
|
|
|
# Process combat
|
|
await process_combat()
|
|
|
|
# Verify deaths incremented
|
|
assert player.deaths == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_multiple_kills_accumulate(player, test_zone, punch_move):
|
|
"""After killing 3 goblins, player.kills == 3, player.mob_kills["goblin"] == 3."""
|
|
for _ in range(3):
|
|
# Create goblin
|
|
goblin = Mob(name="goblin", x=0, y=0)
|
|
goblin.location = test_zone
|
|
test_zone._contents.append(goblin)
|
|
|
|
# Create and resolve encounter
|
|
encounter = start_encounter(player, goblin)
|
|
encounter.attack(punch_move)
|
|
encounter.tick(time.monotonic() + 0.31)
|
|
encounter.tick(time.monotonic() + 1.2)
|
|
goblin.pl = 1.0
|
|
|
|
await process_combat()
|
|
|
|
# Verify accumulated kills
|
|
assert player.kills == 3
|
|
assert player.mob_kills["goblin"] == 3
|
|
|
|
|
|
def test_session_time_tracking(player):
|
|
"""Session time tracking accumulates correctly."""
|
|
# Set session start to a known time
|
|
start_time = time.monotonic()
|
|
player.session_start = start_time
|
|
|
|
# Simulate 5 seconds passing
|
|
time.sleep(0.01) # Small real delay to ensure monotonic() advances
|
|
player.session_start = start_time # Reset for predictable test
|
|
|
|
# Mock time to be 5 seconds later
|
|
import unittest.mock
|
|
|
|
with unittest.mock.patch("time.monotonic", return_value=start_time + 5.0):
|
|
accumulate_play_time(player)
|
|
|
|
# Should have accumulated 5 seconds
|
|
assert player.play_time_seconds == 5.0
|
|
|
|
# Session start should be reset to current time
|
|
with unittest.mock.patch("time.monotonic", return_value=start_time + 5.0):
|
|
assert player.session_start == start_time + 5.0
|
|
|
|
|
|
def test_accumulate_play_time_multiple_sessions(player):
|
|
"""Multiple accumulation calls should add up correctly."""
|
|
start_time = time.monotonic()
|
|
player.session_start = start_time
|
|
|
|
import unittest.mock
|
|
|
|
# First accumulation: 3 seconds
|
|
with unittest.mock.patch("time.monotonic", return_value=start_time + 3.0):
|
|
accumulate_play_time(player)
|
|
|
|
assert player.play_time_seconds == 3.0
|
|
|
|
# Second accumulation: 2 more seconds (from reset point)
|
|
with unittest.mock.patch("time.monotonic", return_value=start_time + 5.0):
|
|
accumulate_play_time(player)
|
|
|
|
# Should have 3 + 2 = 5 total
|
|
assert player.play_time_seconds == 5.0
|