Files
initiative/packages/domain/src/events.ts
Lukas e62c49434c
All checks were successful
CI / check (push) Successful in 2m21s
CI / build-image (push) Successful in 24s
Add Pathfinder 2e game system mode
Implements PF2e as an alternative game system alongside D&D 5e/5.5e.
Settings modal "Game System" selector switches conditions, bestiary,
stat block layout, and initiative calculation between systems.

- Valued conditions with increment/decrement UX (Clumsy 2, Frightened 3)
- 2,502 PF2e creatures from bundled search index (77 sources)
- PF2e stat block: level, traits, Perception, Fort/Ref/Will, ability mods
- Perception-based initiative rolling
- System-scoped source cache (D&D and PF2e sources don't collide)
- Backwards-compatible condition rehydration (ConditionId[] → ConditionEntry[])
- Difficulty indicator hidden in PF2e mode (excluded from MVP)

Closes dostulata/initiative#19

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 01:26:22 +02:00

182 lines
4.4 KiB
TypeScript

import type { ConditionId } from "./conditions.js";
import type { CreatureId } from "./creature-types.js";
import type { PlayerCharacterId } from "./player-character-types.js";
import type { CombatantId } from "./types.js";
export interface TurnAdvanced {
readonly type: "TurnAdvanced";
readonly previousCombatantId: CombatantId;
readonly newCombatantId: CombatantId;
readonly roundNumber: number;
}
export interface RoundAdvanced {
readonly type: "RoundAdvanced";
readonly newRoundNumber: number;
}
export interface CombatantAdded {
readonly type: "CombatantAdded";
readonly combatantId: CombatantId;
readonly name: string;
readonly position: number;
readonly init?: {
readonly maxHp?: number;
readonly ac?: number;
readonly initiative?: number;
readonly creatureId?: CreatureId;
readonly color?: string;
readonly icon?: string;
readonly playerCharacterId?: PlayerCharacterId;
};
}
export interface CombatantRemoved {
readonly type: "CombatantRemoved";
readonly combatantId: CombatantId;
readonly name: string;
}
export interface CombatantUpdated {
readonly type: "CombatantUpdated";
readonly combatantId: CombatantId;
readonly oldName: string;
readonly newName: string;
}
export interface InitiativeSet {
readonly type: "InitiativeSet";
readonly combatantId: CombatantId;
readonly previousValue: number | undefined;
readonly newValue: number | undefined;
}
export interface MaxHpSet {
readonly type: "MaxHpSet";
readonly combatantId: CombatantId;
readonly previousMaxHp: number | undefined;
readonly newMaxHp: number | undefined;
readonly previousCurrentHp: number | undefined;
readonly newCurrentHp: number | undefined;
}
export interface CurrentHpAdjusted {
readonly type: "CurrentHpAdjusted";
readonly combatantId: CombatantId;
readonly previousHp: number;
readonly newHp: number;
readonly delta: number;
}
export interface TempHpSet {
readonly type: "TempHpSet";
readonly combatantId: CombatantId;
readonly previousTempHp: number | undefined;
readonly newTempHp: number | undefined;
}
export interface TurnRetreated {
readonly type: "TurnRetreated";
readonly previousCombatantId: CombatantId;
readonly newCombatantId: CombatantId;
readonly roundNumber: number;
}
export interface RoundRetreated {
readonly type: "RoundRetreated";
readonly newRoundNumber: number;
}
export interface AcSet {
readonly type: "AcSet";
readonly combatantId: CombatantId;
readonly previousAc: number | undefined;
readonly newAc: number | undefined;
}
export interface CrSet {
readonly type: "CrSet";
readonly combatantId: CombatantId;
readonly previousCr: string | undefined;
readonly newCr: string | undefined;
}
export interface SideSet {
readonly type: "SideSet";
readonly combatantId: CombatantId;
readonly previousSide: "party" | "enemy" | undefined;
readonly newSide: "party" | "enemy";
}
export interface ConditionAdded {
readonly type: "ConditionAdded";
readonly combatantId: CombatantId;
readonly condition: ConditionId;
readonly value?: number;
}
export interface ConditionRemoved {
readonly type: "ConditionRemoved";
readonly combatantId: CombatantId;
readonly condition: ConditionId;
readonly value?: number;
}
export interface ConcentrationStarted {
readonly type: "ConcentrationStarted";
readonly combatantId: CombatantId;
}
export interface ConcentrationEnded {
readonly type: "ConcentrationEnded";
readonly combatantId: CombatantId;
}
export interface EncounterCleared {
readonly type: "EncounterCleared";
readonly combatantCount: number;
}
export interface PlayerCharacterCreated {
readonly type: "PlayerCharacterCreated";
readonly playerCharacterId: PlayerCharacterId;
readonly name: string;
}
export interface PlayerCharacterUpdated {
readonly type: "PlayerCharacterUpdated";
readonly playerCharacterId: PlayerCharacterId;
readonly oldName: string;
readonly newName: string;
}
export interface PlayerCharacterDeleted {
readonly type: "PlayerCharacterDeleted";
readonly playerCharacterId: PlayerCharacterId;
readonly name: string;
}
export type DomainEvent =
| TurnAdvanced
| RoundAdvanced
| CombatantAdded
| CombatantRemoved
| CombatantUpdated
| InitiativeSet
| MaxHpSet
| CurrentHpAdjusted
| TempHpSet
| TurnRetreated
| RoundRetreated
| AcSet
| CrSet
| SideSet
| ConditionAdded
| ConditionRemoved
| ConcentrationStarted
| ConcentrationEnded
| EncounterCleared
| PlayerCharacterCreated
| PlayerCharacterUpdated
| PlayerCharacterDeleted;