From 3498bbb8ad2dd6b20de0e77a046977822e6172f5 Mon Sep 17 00:00:00 2001 From: Moritz Ruth Date: Mon, 14 Apr 2025 17:37:03 +0200 Subject: [PATCH] Add virtual curtain --- backend/game.ts | 9 +++++++++ backend/trpc/crew.ts | 8 ++++++++ frontend/game.ts | 12 +++++++++++- frontend/scene-types/interaction/InteractTab.vue | 5 +++-- .../{ObjectCard.vue => PlayerObjectCard.vue} | 4 ++++ frontend/scene-types/interaction/index.ts | 2 ++ frontend/screens/DuoScreen.vue | 3 +++ frontend/screens/PlayerScreen.vue | 3 +++ shared/broadcast.ts | 3 ++- 9 files changed, 45 insertions(+), 4 deletions(-) rename frontend/scene-types/interaction/{ObjectCard.vue => PlayerObjectCard.vue} (90%) diff --git a/backend/game.ts b/backend/game.ts index ab7a554..f9a1cf5 100644 --- a/backend/game.ts +++ b/backend/game.ts @@ -21,6 +21,8 @@ export class Game { private currentScene: CurrentScene public eventBus = new EventEmitter({ captureRejections: false }) + private isVirtualCurtainOpen = false + constructor() { this.switchScene("pre-start") @@ -33,6 +35,7 @@ export class Game { const events: PlayerBroadcast[] = [] events.push({ type: "scene-changed", sceneId: this.currentScene.id }) events.push(...this.currentScene.state.getConnectionEvents().map((event: SceneEvent) => ({ type: "scene-event", event }))) + events.push({ type: "virtual-curtain-changed", isOpen: this.isVirtualCurtainOpen }) return events } @@ -62,6 +65,12 @@ export class Game { return null } } + + setVirtualCurtainOpen(isOpen: boolean) { + if (this.isVirtualCurtainOpen === isOpen) return + this.isVirtualCurtainOpen = isOpen + this.eventBus.emit("player-broadcast", { type: "virtual-curtain-changed", isOpen: this.isVirtualCurtainOpen }) + } } export const game = new Game() \ No newline at end of file diff --git a/backend/trpc/crew.ts b/backend/trpc/crew.ts index d852310..4d97803 100644 --- a/backend/trpc/crew.ts +++ b/backend/trpc/crew.ts @@ -18,6 +18,14 @@ export const crewRouter = t.router({ game.switchScene(input.sceneId) }), + setVirtualCurtainOpen: crewProcedure + .input(z.object({ + isOpen: z.boolean() + })) + .mutation(async ({ input }) => { + game.setVirtualCurtainOpen(input.isOpen) + }), + interactionScene: t.router({ setObjectVisibility: crewProcedure .input(z.object({ diff --git a/frontend/game.ts b/frontend/game.ts index b018fe1..b01d327 100644 --- a/frontend/game.ts +++ b/frontend/game.ts @@ -22,6 +22,8 @@ export const useGame = defineStore("gameState", () => { controller: markRaw(sceneTypesById.text.createController(script.scenesById.get("pre-start") as TextSceneDefinition)) }) + const isVirtualCurtainOpen = ref(false) + const isConnected = ref(false) const isCrew = window.localStorage.getItem("crew-token") !== null @@ -47,6 +49,10 @@ export const useGame = defineStore("gameState", () => { case "scene-event": currentScene.value.controller.handleEvent(broadcast.event) break + + case "virtual-curtain-changed": + isVirtualCurtainOpen.value = broadcast.isOpen + break } } @@ -67,6 +73,10 @@ export const useGame = defineStore("gameState", () => { isCrew, isConnected, currentScene, - switchScene + isVirtualCurtainOpen, + switchScene, + async setVirtualCurtainOpen(isOpen: boolean) { + await trpcClient.crew.setVirtualCurtainOpen.mutate({ isOpen }) + } } }) \ No newline at end of file diff --git a/frontend/scene-types/interaction/InteractTab.vue b/frontend/scene-types/interaction/InteractTab.vue index 72b7fcd..88f7484 100644 --- a/frontend/scene-types/interaction/InteractTab.vue +++ b/frontend/scene-types/interaction/InteractTab.vue @@ -17,13 +17,14 @@ /> - @@ -36,7 +37,7 @@