115 lines
No EOL
3.3 KiB
Vue
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> |