Files
initiative/packages/domain/src/retreat-turn.ts

60 lines
1.4 KiB
TypeScript

import type { DomainEvent } from "./events.js";
import type { DomainError, Encounter } from "./types.js";
interface RetreatTurnSuccess {
readonly encounter: Encounter;
readonly events: DomainEvent[];
}
export function retreatTurn(
encounter: Encounter,
): RetreatTurnSuccess | DomainError {
if (encounter.combatants.length === 0) {
return {
kind: "domain-error",
code: "invalid-encounter",
message: "Cannot retreat turn on an encounter with no combatants",
};
}
if (encounter.roundNumber === 1 && encounter.activeIndex === 0) {
return {
kind: "domain-error",
code: "no-previous-turn",
message: "Cannot retreat before the start of the encounter",
};
}
const previousIndex = encounter.activeIndex;
const wraps = previousIndex === 0;
const newIndex = wraps ? encounter.combatants.length - 1 : previousIndex - 1;
const newRoundNumber = wraps
? encounter.roundNumber - 1
: encounter.roundNumber;
const events: DomainEvent[] = [
{
type: "TurnRetreated",
previousCombatantId: encounter.combatants[previousIndex].id,
newCombatantId: encounter.combatants[newIndex].id,
roundNumber: newRoundNumber,
},
];
if (wraps) {
events.push({
type: "RoundRetreated",
newRoundNumber,
});
}
return {
encounter: {
combatants: encounter.combatants,
activeIndex: newIndex,
roundNumber: newRoundNumber,
},
events,
};
}