99 lines
No EOL
4.3 KiB
TypeScript
99 lines
No EOL
4.3 KiB
TypeScript
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 | Interaction>(null)
|
|
const currentInteractionId = computed(() =>
|
|
currentInteraction.value === null ? null : getInteractionQueueItemId(currentInteraction.value))
|
|
|
|
const interactionQueue = reactive(new Map<string, InteractionQueueItem>())
|
|
const sortedInteractionQueue = computed(() =>
|
|
[...interactionQueue.values()].sort((a, b) => b.votes - a.votes))
|
|
|
|
const visibleObjectIds = reactive(new Set<string>())
|
|
|
|
return {
|
|
currentRoomId,
|
|
currentRoom,
|
|
interactionQueue,
|
|
visibleObjectIds,
|
|
sortedInteractionQueue,
|
|
allObjectsById: computed(() => {
|
|
const map = new Map<string, SceneObjectDefinition>()
|
|
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<string, SceneObjectDefinition>()
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}) |