fix(combat): show the potion heal immediately instead of folding it into the monster's reply

This commit is contained in:
Bastian Wagner
2026-08-20 23:54:02 +02:00
parent 1aac3416fa
commit 62d6677298
2 changed files with 60 additions and 1 deletions

View File

@@ -339,6 +339,51 @@ describe('CombatPageComponent', () => {
expect(monster?.classList.contains('sprite--lunge')).toBe(false);
});
it('shows the potion heal at the first checkpoint instead of waiting for the riposte reveal', async () => {
const fixture = await setup({
...activeCombat,
player: { ...activeCombat.player, currentHp: 70 },
});
const healed: Combat = {
...activeCombat,
round: 3,
player: { ...activeCombat.player, currentHp: 80, potionsRemaining: 1 },
events: [
...activeCombat.events,
{ round: 2, sequence: 3, type: 'HEAL', source: 'PLAYER', target: 'PLAYER', amount: 15 },
{ round: 2, sequence: 4, type: 'DAMAGE', source: 'MONSTER', target: 'PLAYER', amount: 5 },
],
};
combatStore.performAction.mockImplementation(async () => {
combatStore.combat.set(healed);
});
vi.useFakeTimers();
const element = fixture.nativeElement as HTMLElement;
element.querySelector<HTMLButtonElement>('[data-combat-potion]')?.click();
fixture.detectChanges();
// Before the checkpoint: the pre-heal HP and potion count still show.
expect(element.textContent).toContain('70 / 100');
expect(element.querySelector('[data-combat-potion]')?.textContent).toContain('Trank 2/2');
// First checkpoint: the heal already landed from the player's own action,
// so the HP bar and potion count update here -- well before the monster's
// held-back reply resolves.
await vi.advanceTimersByTimeAsync(540);
fixture.detectChanges();
expect(element.textContent).toContain('85 / 100');
expect(element.querySelector('[data-combat-potion]')?.textContent).toContain('Trank 1/2');
expect(element.textContent).toContain('Aric Duskwalker trinkt einen Trank und heilt 15 Lebenspunkte.');
// The monster's reply is still held back at this point.
expect(countOccurrences(element.textContent, monsterHitLine)).toBe(1);
await vi.advanceTimersByTimeAsync(1260);
fixture.detectChanges();
expect(element.textContent).toContain('80 / 100');
});
it('skips the recoil when the round ends without the monster striking back', async () => {
const fixture = await setup(activeCombat);
const won: Combat = {