This commit is contained in:
Bastian Wagner
2026-08-19 23:42:18 +02:00
parent fd9852bfbf
commit 67237f5ad8
4 changed files with 175 additions and 5 deletions

View File

@@ -15,6 +15,10 @@ interface CombatLogRound {
}
type CombatPhase = 'idle' | 'attacking' | 'hit';
// The monster is a single cut-out with no sheets, so its beats are pure
// CSS transforms and run offset from the player's: it flinches when the
// player's blow lands and lunges while the player is recoiling.
type MonsterPhase = 'idle' | 'flinch' | 'lunge';
const PLAYER_ICON = '/images/hud/runtime/CharacterIcon-128.png';
@@ -45,6 +49,7 @@ export class CombatPageComponent implements OnInit {
protected readonly combat = this.displayed.asReadonly();
protected readonly phase = signal<CombatPhase>('idle');
protected readonly monsterPhase = signal<MonsterPhase>('idle');
protected readonly busy = computed(() => this.replaying() || this.combatStore.actionPending());
protected readonly playerIcon = PLAYER_ICON;
@@ -67,6 +72,7 @@ export class CombatPageComponent implements OnInit {
this.replaying.set(true);
try {
this.phase.set('attacking');
this.monsterPhase.set('idle');
const swing = this.wait(SWING_MS);
await this.combatStore.attack();
await swing;
@@ -74,6 +80,7 @@ export class CombatPageComponent implements OnInit {
return;
}
this.phase.set('idle');
this.monsterPhase.set('flinch');
const after = this.combatStore.combat();
if (!after) {
@@ -103,12 +110,14 @@ export class CombatPageComponent implements OnInit {
}
this.phase.set('hit');
this.monsterPhase.set('lunge');
this.displayed.set(after);
await this.wait(RECOIL_MS);
if (this.destroyed) {
return;
}
this.phase.set('idle');
this.monsterPhase.set('idle');
} finally {
if (!this.destroyed) {
this.replaying.set(false);
@@ -192,6 +201,8 @@ export class CombatPageComponent implements OnInit {
await this.combatStore.loadCombat(combatId);
if (!this.destroyed) {
this.phase.set('idle');
this.monsterPhase.set('idle');
this.displayed.set(this.combatStore.combat());
}
}