import { defineStore } from "pinia" import { computed, reactive, ref } from "vue" import { script } from "../shared/script" import type { SceneObjectDefinition, Interaction, InteractionQueueItem } from "../shared/script/types" import { trpcClient } from "./trpc" import type { PlayerBroadcast } from "../shared/broadcast" import { getInteractionQueueItemId } from "../shared/util" export const useGame = defineStore("gameState", () => { const currentRoom = computed(() => script.roomsById.get(currentRoomId.value)!) const currentRoomId = ref(script.roomsById.values().next().value!.id) const currentInteraction = ref(null) const currentInteractionId = computed(() => currentInteraction.value === null ? null : getInteractionQueueItemId(currentInteraction.value)) const interactionQueue = reactive(new Map()) const sortedInteractionQueue = computed(() => [...interactionQueue.values()].sort((a, b) => b.votes - a.votes)) const visibleObjectIds = reactive(new Set()) return { currentRoomId, currentRoom, interactionQueue, visibleObjectIds, sortedInteractionQueue, allObjectsById: computed(() => { const map = new Map() currentRoom.value.initialObjects.forEach(o => map.set(o.id, o)) currentRoom.value.hiddenObjects.forEach(o => map.set(o.id, o)) return map }), visibleObjectsById: computed(() => { const map = new Map() currentRoom.value.initialObjects.values().filter(o => visibleObjectIds.has(o.id)).forEach(o => map.set(o.id, o)) currentRoom.value.hiddenObjects.values().filter(o => visibleObjectIds.has(o.id)).forEach(o => map.set(o.id, o)) return map }), currentInteraction, currentInteractionId, voteForInteraction(interaction: Interaction) { if (currentInteractionId.value === getInteractionQueueItemId(interaction)) return if (currentInteractionId.value !== null) trpcClient.player.removeInteractionVote.mutate({ queueItemId: currentInteractionId.value }) currentInteraction.value = interaction trpcClient.player.voteForInteraction.mutate({ interaction }) }, revokeCurrentInteractionVote() { if (currentInteractionId.value === null) return trpcClient.player.removeInteractionVote.mutate({ queueItemId: currentInteractionId.value }) currentInteraction.value = null }, switchRoom(roomId: string) { trpcClient.director.switchRoom.mutate({ roomId }) }, activateInteractionQueueItem(id: string) { trpcClient.director.activateInteractionQueueItem.mutate({ id }) }, removeInteractionQueueItem(id: string) { trpcClient.director.removeInteractionQueueItem.mutate({ id }) }, setObjectVisibility(id: string, isVisible: boolean) { trpcClient.director.setObjectVisibility.mutate({ id, isVisible }) }, handleGameEvent(event: PlayerBroadcast) { console.log(event) switch (event.type) { case "room-changed": currentInteraction.value = null currentRoomId.value = event.roomId interactionQueue.clear() visibleObjectIds.clear() currentRoom.value.initialObjects.forEach(o => visibleObjectIds.add(o.id)) break case "interaction-queued": interactionQueue.set(event.item.id, event.item) break case "interaction-votes-changed": if (event.votes <= 0) { interactionQueue.delete(event.id) if (currentInteractionId.value === event.id) currentInteraction.value = null } else { interactionQueue.get(event.id)!.votes = event.votes } break case "object-visibility-changed": if (event.isVisible) visibleObjectIds.add(event.id) else visibleObjectIds.delete(event.id) break } } } })