Cancel power-up tasks when combat starts

When combat begins, any active power-up task on either the attacker
or defender should be cancelled to prevent background power changes
during combat. This ensures players can't continue charging while
fighting.

The fix checks both entities for a _power_task attribute and cancels
it if present, then clears the reference.
This commit is contained in:
Jared Miller 2026-02-13 23:56:19 -05:00
parent 2a546a3171
commit a4c9f31056
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 56 additions and 0 deletions

View file

@ -42,6 +42,14 @@ def start_encounter(attacker: Entity, defender: Entity) -> CombatEncounter:
) )
active_encounters.append(encounter) 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 return encounter

View file

@ -307,3 +307,51 @@ async def test_power_to_number_raises_with_loop(player):
# Should be increasing toward 80 # Should be increasing toward 80
assert player.pl > 10.0 assert player.pl > 10.0
assert player.stamina < 100.0 # deducting stamina 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()