diff --git a/src/mudlib/combat/engine.py b/src/mudlib/combat/engine.py index 3668b81..8b575cd 100644 --- a/src/mudlib/combat/engine.py +++ b/src/mudlib/combat/engine.py @@ -42,6 +42,14 @@ def start_encounter(attacker: Entity, defender: Entity) -> CombatEncounter: ) active_encounters.append(encounter) + # Cancel any active power-up tasks + for entity in (attacker, defender): + task = getattr(entity, "_power_task", None) + if task is not None: + task.cancel() + if hasattr(entity, "_power_task"): + entity._power_task = None # type: ignore[attr-defined] + return encounter diff --git a/tests/test_power.py b/tests/test_power.py index 4a521ae..133bf39 100644 --- a/tests/test_power.py +++ b/tests/test_power.py @@ -307,3 +307,51 @@ async def test_power_to_number_raises_with_loop(player): # Should be increasing toward 80 assert player.pl > 10.0 assert player.stamina < 100.0 # deducting stamina + + +@pytest.mark.asyncio +async def test_combat_start_cancels_power_up(player, nearby_player): + """Test starting combat cancels any active power-up task.""" + from mudlib.combat.engine import start_encounter + + # Start player powering up + player.pl = 10.0 + player.max_pl = 100.0 + player.stamina = 100.0 + + await cmd_power(player, "up") + await asyncio.sleep(0.05) # Let power-up start + + # Verify power-up is active + assert player._power_task is not None + assert not player._power_task.done() + + # Start combat encounter + start_encounter(player, nearby_player) + + # Power-up task should be cancelled + assert player._power_task is None or player._power_task.cancelled() + + +@pytest.mark.asyncio +async def test_combat_start_cancels_defender_power_up(player, nearby_player): + """Test starting combat cancels defender's active power-up task.""" + from mudlib.combat.engine import start_encounter + + # Start nearby_player powering up + nearby_player.pl = 10.0 + nearby_player.max_pl = 100.0 + nearby_player.stamina = 100.0 + + await cmd_power(nearby_player, "up") + await asyncio.sleep(0.05) # Let power-up start + + # Verify power-up is active + assert nearby_player._power_task is not None + assert not nearby_player._power_task.done() + + # Start combat encounter (nearby_player is defender) + start_encounter(player, nearby_player) + + # Power-up task should be cancelled + assert nearby_player._power_task is None or nearby_player._power_task.cancelled()