This commit is contained in:
parent
dd5e018477
commit
3498bbb8ad
9 changed files with 45 additions and 4 deletions
|
@ -21,6 +21,8 @@ export class Game {
|
||||||
private currentScene: CurrentScene
|
private currentScene: CurrentScene
|
||||||
public eventBus = new EventEmitter<Events>({ captureRejections: false })
|
public eventBus = new EventEmitter<Events>({ captureRejections: false })
|
||||||
|
|
||||||
|
private isVirtualCurtainOpen = false
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.switchScene("pre-start")
|
this.switchScene("pre-start")
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ export class Game {
|
||||||
const events: PlayerBroadcast[] = []
|
const events: PlayerBroadcast[] = []
|
||||||
events.push({ type: "scene-changed", sceneId: this.currentScene.id })
|
events.push({ type: "scene-changed", sceneId: this.currentScene.id })
|
||||||
events.push(...this.currentScene.state.getConnectionEvents().map((event: SceneEvent) => ({ type: "scene-event", event })))
|
events.push(...this.currentScene.state.getConnectionEvents().map((event: SceneEvent) => ({ type: "scene-event", event })))
|
||||||
|
events.push({ type: "virtual-curtain-changed", isOpen: this.isVirtualCurtainOpen })
|
||||||
|
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
@ -62,6 +65,12 @@ export class Game {
|
||||||
return null
|
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()
|
export const game = new Game()
|
|
@ -18,6 +18,14 @@ export const crewRouter = t.router({
|
||||||
game.switchScene(input.sceneId)
|
game.switchScene(input.sceneId)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
setVirtualCurtainOpen: crewProcedure
|
||||||
|
.input(z.object({
|
||||||
|
isOpen: z.boolean()
|
||||||
|
}))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
game.setVirtualCurtainOpen(input.isOpen)
|
||||||
|
}),
|
||||||
|
|
||||||
interactionScene: t.router({
|
interactionScene: t.router({
|
||||||
setObjectVisibility: crewProcedure
|
setObjectVisibility: crewProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
|
|
|
@ -22,6 +22,8 @@ export const useGame = defineStore("gameState", () => {
|
||||||
controller: markRaw(sceneTypesById.text.createController(script.scenesById.get("pre-start") as TextSceneDefinition))
|
controller: markRaw(sceneTypesById.text.createController(script.scenesById.get("pre-start") as TextSceneDefinition))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isVirtualCurtainOpen = ref(false)
|
||||||
|
|
||||||
const isConnected = ref(false)
|
const isConnected = ref(false)
|
||||||
const isCrew = window.localStorage.getItem("crew-token") !== null
|
const isCrew = window.localStorage.getItem("crew-token") !== null
|
||||||
|
|
||||||
|
@ -47,6 +49,10 @@ export const useGame = defineStore("gameState", () => {
|
||||||
case "scene-event":
|
case "scene-event":
|
||||||
currentScene.value.controller.handleEvent(broadcast.event)
|
currentScene.value.controller.handleEvent(broadcast.event)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case "virtual-curtain-changed":
|
||||||
|
isVirtualCurtainOpen.value = broadcast.isOpen
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +73,10 @@ export const useGame = defineStore("gameState", () => {
|
||||||
isCrew,
|
isCrew,
|
||||||
isConnected,
|
isConnected,
|
||||||
currentScene,
|
currentScene,
|
||||||
switchScene
|
isVirtualCurtainOpen,
|
||||||
|
switchScene,
|
||||||
|
async setVirtualCurtainOpen(isOpen: boolean) {
|
||||||
|
await trpcClient.crew.setVirtualCurtainOpen.mutate({ isOpen })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -17,13 +17,14 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<transition-group tag="div" name="list" class="grid gap-3 grid-cols-2 flex-grow auto-rows-min p-4 pt-0 relative">
|
<transition-group tag="div" name="list" class="grid gap-3 grid-cols-2 flex-grow auto-rows-min p-4 pt-0 relative">
|
||||||
<ObjectCard
|
<PlayerObjectCard
|
||||||
v-for="objectId in controller.visibleObjectIds.values()"
|
v-for="objectId in controller.visibleObjectIds.values()"
|
||||||
:key="objectId"
|
:key="objectId"
|
||||||
:objectId="objectId"
|
:objectId="objectId"
|
||||||
:object="definition.objectsById.get(objectId)!"
|
:object="definition.objectsById.get(objectId)!"
|
||||||
:is-over-dropzone="allFloatingObjectIds.has(objectId)"
|
:is-over-dropzone="allFloatingObjectIds.has(objectId)"
|
||||||
:marked-for="getMarkedFor(objectId)"
|
:marked-for="getMarkedFor(objectId)"
|
||||||
|
:completion-step="controller.objectCompletionById.get(objectId) ?? 0"
|
||||||
@drag-start="onObjectDragStart"
|
@drag-start="onObjectDragStart"
|
||||||
@drag-end="onObjectDragEnd"
|
@drag-end="onObjectDragEnd"
|
||||||
/>
|
/>
|
||||||
|
@ -36,7 +37,7 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ObjectCard from "./ObjectCard.vue"
|
import PlayerObjectCard from "./PlayerObjectCard.vue"
|
||||||
import { useGame } from "../../game"
|
import { useGame } from "../../game"
|
||||||
import { computed, reactive, ref } from "vue"
|
import { computed, reactive, ref } from "vue"
|
||||||
import ObjectCardDropZone from "./ObjectCardDropZone.vue"
|
import ObjectCardDropZone from "./ObjectCardDropZone.vue"
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
<div class="text-gray-200">
|
<div class="text-gray-200">
|
||||||
{{ object.label }}
|
{{ object.label }}
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="object.completion !== undefined" class="h-4px rounded-full w-80% bg-gray-700 overflow-hidden">
|
||||||
|
<div class="h-full bg-green-500 transition-all transition-duration-1s" :style="{ width: `${completionStep / object.completion.steps * 100}%` }"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -48,6 +51,7 @@
|
||||||
object: SceneObjectDefinition
|
object: SceneObjectDefinition
|
||||||
isOverDropzone: boolean
|
isOverDropzone: boolean
|
||||||
markedFor: null | "use" | "combine" | "combine-first"
|
markedFor: null | "use" | "combine" | "combine-first"
|
||||||
|
completionStep: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
|
@ -26,6 +26,7 @@ export const InteractionSceneType: SceneType<InteractionSceneDefinition, Interac
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visibleObjectIds,
|
visibleObjectIds,
|
||||||
|
objectCompletionById,
|
||||||
interactionQueue,
|
interactionQueue,
|
||||||
sortedInteractionQueue: computed(() => [...interactionQueue.values()].sort((a, b) => a.votes - b.votes)),
|
sortedInteractionQueue: computed(() => [...interactionQueue.values()].sort((a, b) => a.votes - b.votes)),
|
||||||
sortedInteractionQueueWithDefined: computed(() => {
|
sortedInteractionQueueWithDefined: computed(() => {
|
||||||
|
@ -147,6 +148,7 @@ export interface InteractionQueueItem {
|
||||||
export interface InteractionSceneController extends SceneController {
|
export interface InteractionSceneController extends SceneController {
|
||||||
visibleObjectIds: Reactive<Set<string>>
|
visibleObjectIds: Reactive<Set<string>>
|
||||||
interactionQueue: Reactive<Map<string, InteractionQueueItem>>
|
interactionQueue: Reactive<Map<string, InteractionQueueItem>>
|
||||||
|
objectCompletionById: Reactive<Map<string, number>>
|
||||||
sortedInteractionQueue: Readonly<Ref<Array<InteractionQueueItem>>>
|
sortedInteractionQueue: Readonly<Ref<Array<InteractionQueueItem>>>
|
||||||
sortedInteractionQueueWithDefined: Readonly<Ref<Array<InteractionQueueItem>>>
|
sortedInteractionQueueWithDefined: Readonly<Ref<Array<InteractionQueueItem>>>
|
||||||
suggestedInteraction: Ref<SuggestedInteraction | null>
|
suggestedInteraction: Ref<SuggestedInteraction | null>
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="bg-green-800 px-2 text-sm rounded-full" @click="game.setVirtualCurtainOpen(!game.isVirtualCurtainOpen)">Vorhang ist {{ game.isVirtualCurtainOpen ? "auf" : "zu" }}</button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<component :is="game.currentScene.type.crewView" :controller="game.currentScene.controller" :definition="game.currentScene.definition"/>
|
<component :is="game.currentScene.type.crewView" :controller="game.currentScene.controller" :definition="game.currentScene.definition"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<component :is="game.currentScene.type.playerView" :controller="game.currentScene.controller" :definition="game.currentScene.definition"/>
|
<component :is="game.currentScene.type.playerView" :controller="game.currentScene.controller" :definition="game.currentScene.definition"/>
|
||||||
|
<div class="flex flex-col justify-center items-center text-lg inset-0 absolute bg-dark-900 transition" :class="game.isVirtualCurtainOpen && 'opacity-0 pointer-events-none'">
|
||||||
|
<span class="text-center">mega_cooler_vorhang.jpg</span>
|
||||||
|
</div>
|
||||||
<div class="flex flex-col justify-center items-center text-lg inset-0 absolute bg-dark-900 transition" :class="game.isConnected && 'opacity-0 pointer-events-none'">
|
<div class="flex flex-col justify-center items-center text-lg inset-0 absolute bg-dark-900 transition" :class="game.isConnected && 'opacity-0 pointer-events-none'">
|
||||||
<span class="text-center">Verbindung wird hergestellt…</span>
|
<span class="text-center">Verbindung wird hergestellt…</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,4 +3,5 @@ import type { SceneEvent } from "../backend/scene-types"
|
||||||
export type PlayerBroadcast =
|
export type PlayerBroadcast =
|
||||||
| { type: "keep-alive" }
|
| { type: "keep-alive" }
|
||||||
| { type: "scene-changed"; sceneId: string }
|
| { type: "scene-changed"; sceneId: string }
|
||||||
| { type: "scene-event"; event: SceneEvent }
|
| { type: "scene-event"; event: SceneEvent }
|
||||||
|
| { type: "virtual-curtain-changed", isOpen: boolean }
|
Loading…
Add table
Reference in a new issue