diff --git a/src/sequencer/project-sequence-steps.ts b/src/sequencer/project-sequence-steps.ts index 0391215c..ac8b7c98 100644 --- a/src/sequencer/project-sequence-steps.ts +++ b/src/sequencer/project-sequence-steps.ts @@ -8,52 +8,70 @@ import { } from "../interactions/interaction-links"; import type { ProjectScheduleRoutine } from "../scheduler/project-scheduler"; -export interface ControlSequenceStep { +export interface HeldControlSequenceStep { + stepClass: "held"; + type: "controlEffect"; + effect: ControlEffect; +} + +export interface ImpulseControlSequenceStep { + stepClass: "impulse"; type: "controlEffect"; effect: ControlEffect; } export interface StartDialogueSequenceStep { + stepClass: "impulse"; type: "startDialogue"; dialogueId: string; } export interface TeleportPlayerSequenceStep { + stepClass: "impulse"; type: "teleportPlayer"; targetEntityId: string; } export interface ToggleVisibilitySequenceStep { + stepClass: "impulse"; type: "toggleVisibility"; targetBrushId: string; visible?: boolean; } -export type SequenceStep = - | ControlSequenceStep +export type HeldSequenceStep = HeldControlSequenceStep; + +export type ImpulseSequenceStep = + | ImpulseControlSequenceStep | StartDialogueSequenceStep | TeleportPlayerSequenceStep | ToggleVisibilitySequenceStep; +export type SequenceStep = HeldSequenceStep | ImpulseSequenceStep; + export function cloneSequenceStep(step: SequenceStep): SequenceStep { switch (step.type) { case "controlEffect": return { + stepClass: step.stepClass, type: "controlEffect", effect: cloneControlEffect(step.effect) }; case "startDialogue": return { + stepClass: "impulse", type: "startDialogue", dialogueId: step.dialogueId }; case "teleportPlayer": return { + stepClass: "impulse", type: "teleportPlayer", targetEntityId: step.targetEntityId }; case "toggleVisibility": return { + stepClass: "impulse", type: "toggleVisibility", targetBrushId: step.targetBrushId, visible: step.visible @@ -65,14 +83,15 @@ export function cloneSequenceSteps(steps: SequenceStep[]): SequenceStep[] { return steps.map(cloneSequenceStep); } -export function getInteractionLinkSequenceSteps( +export function getInteractionLinkImpulseSteps( link: InteractionLink -): SequenceStep[] { +): ImpulseSequenceStep[] { const controlEffect = getInteractionActionControlEffect(link.action); if (controlEffect !== null) { return [ { + stepClass: "impulse", type: "controlEffect", effect: controlEffect } @@ -83,6 +102,7 @@ export function getInteractionLinkSequenceSteps( case "teleportPlayer": return [ { + stepClass: "impulse", type: "teleportPlayer", targetEntityId: link.action.targetEntityId } @@ -90,6 +110,7 @@ export function getInteractionLinkSequenceSteps( case "toggleVisibility": return [ { + stepClass: "impulse", type: "toggleVisibility", targetBrushId: link.action.targetBrushId, visible: link.action.visible @@ -98,6 +119,7 @@ export function getInteractionLinkSequenceSteps( case "startDialogue": return [ { + stepClass: "impulse", type: "startDialogue", dialogueId: link.action.dialogueId } @@ -113,11 +135,46 @@ export function getInteractionLinkSequenceSteps( } } -export function getProjectScheduleRoutineSequenceSteps( - routine: ProjectScheduleRoutine +export function getInteractionLinkSequenceSteps( + link: InteractionLink ): SequenceStep[] { + return getInteractionLinkImpulseSteps(link); +} + +export function getProjectScheduleRoutineHeldSteps( + routine: ProjectScheduleRoutine +): HeldSequenceStep[] { return routine.effects.map((effect) => ({ + stepClass: "held" as const, type: "controlEffect" as const, effect: cloneControlEffect(effect) })); } + +export function getProjectScheduleRoutineSequenceSteps( + routine: ProjectScheduleRoutine +): SequenceStep[] { + return getProjectScheduleRoutineHeldSteps(routine); +} + +export function getHeldSequenceControlEffects( + steps: readonly HeldSequenceStep[] +): ControlEffect[] { + return steps + .filter((step): step is HeldControlSequenceStep => step.type === "controlEffect") + .map((step) => cloneControlEffect(step.effect)); +} + +export function findHeldSequenceControlEffect< + TType extends ControlEffect["type"] +>( + steps: readonly HeldSequenceStep[], + type: TType +): Extract | null { + return ( + getHeldSequenceControlEffects(steps).find( + (effect): effect is Extract => + effect.type === type + ) ?? null + ); +}