From 1a953046cc1674f1d34e288e21f212216f259ed9 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Thu, 2 Apr 2026 19:36:20 +0200 Subject: [PATCH] Add playSound and stopSound interaction actions --- src/interactions/interaction-links.ts | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/interactions/interaction-links.ts b/src/interactions/interaction-links.ts index 652f3888..10834a25 100644 --- a/src/interactions/interaction-links.ts +++ b/src/interactions/interaction-links.ts @@ -111,6 +111,16 @@ function cloneAction(action: InteractionAction): InteractionAction { type: "stopAnimation", targetModelInstanceId: action.targetModelInstanceId }; + case "playSound": + return { + type: "playSound", + targetSoundEmitterId: action.targetSoundEmitterId + }; + case "stopSound": + return { + type: "stopSound", + targetSoundEmitterId: action.targetSoundEmitterId + }; } } @@ -216,6 +226,36 @@ export function createStopAnimationInteractionLink(options: CreateStopAnimationI }; } +export function createPlaySoundInteractionLink(options: CreatePlaySoundInteractionLinkOptions): InteractionLink { + assertNonEmptyString(options.sourceEntityId, "Interaction source entity id"); + assertNonEmptyString(options.targetSoundEmitterId, "Play sound target sound emitter id"); + + return { + id: options.id ?? createOpaqueId("interaction-link"), + sourceEntityId: options.sourceEntityId, + trigger: options.trigger ?? "enter", + action: { + type: "playSound", + targetSoundEmitterId: options.targetSoundEmitterId + } + }; +} + +export function createStopSoundInteractionLink(options: CreateStopSoundInteractionLinkOptions): InteractionLink { + assertNonEmptyString(options.sourceEntityId, "Interaction source entity id"); + assertNonEmptyString(options.targetSoundEmitterId, "Stop sound target sound emitter id"); + + return { + id: options.id ?? createOpaqueId("interaction-link"), + sourceEntityId: options.sourceEntityId, + trigger: options.trigger ?? "enter", + action: { + type: "stopSound", + targetSoundEmitterId: options.targetSoundEmitterId + } + }; +} + export function cloneInteractionLink(link: InteractionLink): InteractionLink { return { id: link.id, @@ -250,6 +290,10 @@ export function areInteractionLinksEqual(left: InteractionLink, right: Interacti ); case "stopAnimation": return left.action.targetModelInstanceId === (right.action as StopAnimationAction).targetModelInstanceId; + case "playSound": + return left.action.targetSoundEmitterId === (right.action as PlaySoundAction).targetSoundEmitterId; + case "stopSound": + return left.action.targetSoundEmitterId === (right.action as StopSoundAction).targetSoundEmitterId; default: { // Exhaustive check — TypeScript should never reach here const _exhaustive: never = left.action;