import type { DungeonDefinition } from "./dungeonTypes"; import type { DungeonEncounterDefinition } from "./dungeonEncounterTypes"; /** Authored completion bookkeeping, independent of reviewed RoM encounter scripts. */ export function withRunewakerCompletion(definition: DungeonDefinition): DungeonDefinition { if (definition.expansion !== "runewaker" || definition.bosses.length === 0) return definition; const objectives = [...new Map([...definition.objectiveOrder, ...definition.bosses] .map((objective) => [objective.id, objective] as const)).values()]; const encounter: DungeonEncounterDefinition = { id: `${definition.id}:completion-baseline`, dungeonId: definition.id, initialPhase: "running", initialState: { flags: { "dungeon-complete": false } }, source: { fidelity: "healer-man-authored", scope: "instance-orchestration", files: ["src/game/runewakerCompletion.ts"], reviewedBehavior: "Records defeated dungeon bosses and completes the required objectives.", adaptations: ["Completion bookkeeping uses runtime spawn ids and persists across checkpoints."], remainingGaps: [], }, rules: [ ...objectives.filter((objective) => !objective.eventOnly).map((objective) => ({ id: `defeated:${objective.id}`, trigger: { kind: "entities-dead" as const, entityIds: [objective.id] }, actions: [{ id: `record:${objective.id}`, kind: "complete-objective" as const, objectiveId: objective.id, persistence: "run" as const }], })), { id: "complete", trigger: { kind: "tick" }, guards: objectives.filter((objective) => !objective.optional).map((objective) => ({ kind: "objective-complete", objectiveId: objective.id, equals: true, })), actions: [{ id: "complete", kind: "set-flag", flagId: "dungeon-complete", value: true, persistence: "run" }], }, ], }; return { ...definition, encounters: [...definition.encounters ?? [], encounter] }; }