Files
initiative/packages/domain/src/set-side.ts
Lukas 94e1806112
All checks were successful
CI / check (push) Successful in 2m18s
CI / build-image (push) Successful in 17s
Add combatant side assignment for encounter difficulty
Combatants can now be assigned to party or enemy side via a toggle
in the difficulty breakdown panel. Party-side NPCs subtract their XP
from the encounter total, letting allied NPCs reduce difficulty.
PCs default to party, non-PCs to enemy — users who don't use sides
see no change. Side persists across reload and export/import.

Closes #22

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:15:12 +02:00

55 lines
1.1 KiB
TypeScript

import type { DomainEvent } from "./events.js";
import {
type CombatantId,
type DomainError,
type Encounter,
findCombatant,
isDomainError,
} from "./types.js";
export interface SetSideSuccess {
readonly encounter: Encounter;
readonly events: DomainEvent[];
}
const VALID_SIDES = new Set(["party", "enemy"]);
export function setSide(
encounter: Encounter,
combatantId: CombatantId,
value: "party" | "enemy",
): SetSideSuccess | DomainError {
const found = findCombatant(encounter, combatantId);
if (isDomainError(found)) return found;
if (!VALID_SIDES.has(value)) {
return {
kind: "domain-error",
code: "invalid-side",
message: `Side must be "party" or "enemy", got "${value}"`,
};
}
const previousSide = found.combatant.side;
const updatedCombatants = encounter.combatants.map((c) =>
c.id === combatantId ? { ...c, side: value } : c,
);
return {
encounter: {
combatants: updatedCombatants,
activeIndex: encounter.activeIndex,
roundNumber: encounter.roundNumber,
},
events: [
{
type: "SideSet",
combatantId,
previousSide,
newSide: value,
},
],
};
}