level-up/frontend/game.ts
Moritz Ruth 88f0632194
All checks were successful
Build / build (push) Successful in 1m14s
Update dependencies, containerize, add build workflow
2025-03-03 00:35:21 +01:00

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 { GameObject, Interaction, InteractionQueueItem } from "../shared/script/types"
import { trpcClient } from "./trpc"
import type { GameEvent } from "../shared/gameEvents"
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, GameObject>()
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, GameObject>()
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: GameEvent) {
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
}
}
}
})