level-up/frontend/screens/InteractionsScreen.vue
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

115 lines
No EOL
3.3 KiB
Vue

<template>
<div class="h-full flex flex-col relative">
<div class="flex-shrink-0 flex order-1">
<ObjectCardDropZone
label="Benutzen"
class="bg-green-800"
:has-floating="useFloatingObjectIds.size > 0"
@object-change="(v, i) => createSetInclusionSetter(useFloatingObjectIds)(v, i)"
@object-drop="onObjectUseDrop"
/>
<ObjectCardDropZone
label="Kombinieren"
class="bg-blue-900"
:has-floating="combineFloatingObjectIds.size > 0"
@object-change="(v, i) => createSetInclusionSetter(combineFloatingObjectIds)(v, i)"
@object-drop="onObjectInteractionDrop"
/>
</div>
<transition-group tag="div" name="list" class="grid gap-3 grid-cols-2 flex-grow auto-rows-min p-4 pt-0 relative">
<ObjectCard
v-for="object in game.visibleObjectsById.values()"
:key="object.id"
:object="object"
:is-over-dropzone="allFloatingObjectIds.has(object.id)"
:marked-for="getMarkedFor(object.id)"
@drag-start="onObjectDragStart"
@drag-end="onObjectDragEnd"
/>
</transition-group>
</div>
</template>
<style module lang="scss">
</style>
<script setup lang="ts">
import ObjectCard from "../components/ObjectCard.vue"
import { useGame } from "../game"
import { computed, reactive, ref } from "vue"
import { useScrollLock } from "@vueuse/core"
import ObjectCardDropZone from "../components/ObjectCardDropZone.vue"
const game = useGame()
const dragCounter = ref(0)
const useFloatingObjectIds = reactive(new Set())
const combineFloatingObjectIds = reactive(new Set())
const allFloatingObjectIds = computed(() => new Set([...useFloatingObjectIds, ...combineFloatingObjectIds]))
const firstCombinationObjectId = ref<null | string>(null)
function createSetInclusionSetter<T>(set: Set<T>) {
return (value: T, isIncluded: boolean) => {
if (isIncluded) set.add(value)
else set.delete(value)
}
}
function getMarkedFor(objectId: string) {
if (firstCombinationObjectId.value !== null) {
if (firstCombinationObjectId.value === objectId) return "combine-first"
} else if (game.currentInteraction !== null) {
switch (game.currentInteraction.type) {
case "use":
if (game.currentInteraction.objectId === objectId) return "use"
break
case "combine":
if (game.currentInteraction.objectIds.has(objectId)) return "combine"
break
}
}
return null
}
function onObjectDragStart() {
dragCounter.value++
}
function onObjectDragEnd() {
dragCounter.value--
if (dragCounter.value <= 0) {
// lock scrolling?
}
}
function onObjectUseDrop(objectId: string) {
game.voteForInteraction({
type: "use",
objectId
})
}
function onObjectInteractionDrop(objectId: string) {
if (firstCombinationObjectId.value === null) {
game.revokeCurrentInteractionVote()
firstCombinationObjectId.value = objectId
} else {
if (firstCombinationObjectId.value === objectId) {
firstCombinationObjectId.value = null
return
}
game.voteForInteraction({
type: "combine",
objectIds: new Set([firstCombinationObjectId.value, objectId])
})
firstCombinationObjectId.value = null
}
}
</script>