Files
initiative/packages/domain/src/set-ac.ts

57 lines
1.2 KiB
TypeScript

import type { DomainEvent } from "./events.js";
import type { CombatantId, DomainError, Encounter } from "./types.js";
export interface SetAcSuccess {
readonly encounter: Encounter;
readonly events: DomainEvent[];
}
export function setAc(
encounter: Encounter,
combatantId: CombatantId,
value: number | undefined,
): SetAcSuccess | DomainError {
const targetIdx = encounter.combatants.findIndex((c) => c.id === combatantId);
if (targetIdx === -1) {
return {
kind: "domain-error",
code: "combatant-not-found",
message: `No combatant found with ID "${combatantId}"`,
};
}
if (value !== undefined) {
if (!Number.isInteger(value) || value < 0) {
return {
kind: "domain-error",
code: "invalid-ac",
message: `AC must be a non-negative integer, got ${value}`,
};
}
}
const target = encounter.combatants[targetIdx];
const previousAc = target.ac;
const updatedCombatants = encounter.combatants.map((c) =>
c.id === combatantId ? { ...c, ac: value } : c,
);
return {
encounter: {
combatants: updatedCombatants,
activeIndex: encounter.activeIndex,
roundNumber: encounter.roundNumber,
},
events: [
{
type: "AcSet",
combatantId,
previousAc,
newAc: value,
},
],
};
}