forked from noxious/client
202 lines
6.9 KiB
Vue
202 lines
6.9 KiB
Vue
<template>
|
|
<PlacedMapObject
|
|
v-if="mapEditor.tool.value === 'pencil' && mapEditor.drawMode.value === 'map_object' && mapEditor.isPlacedMapObjectPreviewEnabled.value && mapEditor.selectedMapObject.value && previewPlacedMapObject"
|
|
:tileMap
|
|
:tileMapLayer
|
|
:key="previewPlacedMapObject?.id"
|
|
:placedMapObject="previewPlacedMapObject as PlacedMapObjectT"
|
|
/>
|
|
<SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :key="mapEditor.selectedPlacedObject.value.id" :map :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
|
<PlacedMapObject v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :tileMap :tileMapLayer :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" />
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { MapObject, Map as MapT, PlacedMapObject as PlacedMapObjectT } from '@/application/types'
|
|
import { uuidv4 } from '@/application/utilities'
|
|
import PlacedMapObject from '@/components/game/map/partials/PlacedMapObject.vue'
|
|
import SelectedPlacedMapObjectComponent from '@/components/gameMaster/mapEditor/partials/SelectedPlacedMapObject.vue'
|
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
|
import { getTile } from '@/services/mapService'
|
|
import { useScene } from 'phavuer'
|
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
|
|
import Tilemap = Phaser.Tilemaps.Tilemap
|
|
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
|
|
|
const scene = useScene()
|
|
const mapEditor = useMapEditorComposable()
|
|
const map = computed(() => mapEditor.currentMap.value!)
|
|
|
|
const emit = defineEmits<{ (e: 'update', map: MapT): void; (e: 'updateAndCommit', map: MapT): void; (e: 'pauseObjectTracking'): void; (e: 'resumeObjectTracking'): void }>()
|
|
|
|
defineExpose({ handlePointer })
|
|
|
|
const props = defineProps<{
|
|
tileMap: Tilemap
|
|
tileMapLayer: TilemapLayer
|
|
}>()
|
|
|
|
const previewPosition = ref({ x: 0, y: 0 })
|
|
const previewPlacedMapObject = computed(() => ({
|
|
id: mapEditor.selectedMapObject.value!.id,
|
|
mapObject: mapEditor.selectedMapObject.value!.id,
|
|
isRotated: false,
|
|
positionX: previewPosition.value.x,
|
|
positionY: previewPosition.value.y
|
|
}))
|
|
|
|
function updatePreviewPosition(pointer: Phaser.Input.Pointer) {
|
|
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
|
if (!tile || (previewPosition.value.x === tile.x && previewPosition.value.y === tile.y)) return
|
|
|
|
previewPosition.value = { x: tile.x, y: tile.y }
|
|
}
|
|
|
|
function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
|
emit('pauseObjectTracking')
|
|
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
|
|
// Check if object already exists on position
|
|
const existingPlacedMapObject = findObjectByPointer(pointer, mapEditor.currentMap.value!)
|
|
if (existingPlacedMapObject) return
|
|
|
|
if (!mapEditor.selectedMapObject.value) return
|
|
|
|
const newPlacedMapObject: PlacedMapObjectT = {
|
|
id: uuidv4(),
|
|
mapObject: mapEditor.selectedMapObject.value.id,
|
|
isRotated: false,
|
|
positionX: tile.x,
|
|
positionY: tile.y
|
|
}
|
|
|
|
// Add new object to mapObjects
|
|
mapEditor.selectedPlacedObject.value = newPlacedMapObject
|
|
map.placedMapObjects.push(newPlacedMapObject)
|
|
|
|
emit('update', map)
|
|
}
|
|
|
|
function eraser(pointer: Phaser.Input.Pointer, map: MapT) {
|
|
emit('pauseObjectTracking')
|
|
|
|
// Check if object already exists on position
|
|
const existingPlacedMapObject = findObjectByPointer(pointer, map)
|
|
if (!existingPlacedMapObject) return
|
|
|
|
// Remove existing object
|
|
map.placedMapObjects = map.placedMapObjects.filter((placedMapObject) => placedMapObject.id !== existingPlacedMapObject.id)
|
|
|
|
emit('update', map)
|
|
}
|
|
|
|
function findObjectByPointer(pointer: Phaser.Input.Pointer, map: MapT): PlacedMapObjectT | undefined {
|
|
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
|
if (!tile) return undefined
|
|
|
|
return map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
|
}
|
|
|
|
function objectPicker(pointer: Phaser.Input.Pointer, map: MapT) {
|
|
// Check if object already exists on position
|
|
const existingPlacedMapObject = findObjectByPointer(pointer, map)
|
|
if (!existingPlacedMapObject) return
|
|
|
|
// Select the object
|
|
mapEditor.setSelectedMapObject(existingPlacedMapObject.mapObject as MapObject)
|
|
}
|
|
|
|
function moveMapObject(id: string, map: MapT) {
|
|
mapEditor.movingPlacedObject.value = map.placedMapObjects.find((object) => object.id === id) as PlacedMapObjectT
|
|
|
|
emit('pauseObjectTracking')
|
|
|
|
function handlePointerMove(pointer: Phaser.Input.Pointer) {
|
|
if (!mapEditor.movingPlacedObject.value) return
|
|
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
|
|
mapEditor.movingPlacedObject.value.positionX = tile.x
|
|
mapEditor.movingPlacedObject.value.positionY = tile.y
|
|
}
|
|
|
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
|
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
|
|
|
function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
|
|
|
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
console.log(id)
|
|
map.placedMapObjects.map((placed) => {
|
|
if (placed.id === id) {
|
|
placed.positionX = tile.x
|
|
placed.positionY = tile.y
|
|
}
|
|
})
|
|
|
|
mapEditor.movingPlacedObject.value = null
|
|
|
|
scene.input.off(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
|
emit('resumeObjectTracking')
|
|
emit('updateAndCommit', map)
|
|
}
|
|
}
|
|
|
|
function rotatePlacedMapObject(id: string, map: MapT) {
|
|
map.placedMapObjects.map((placed) => {
|
|
if (placed.id === id) {
|
|
placed.isRotated = !placed.isRotated
|
|
}
|
|
})
|
|
|
|
emit('updateAndCommit', map)
|
|
}
|
|
|
|
function deletePlacedMapObject(id: string, map: MapT) {
|
|
map.placedMapObjects = map.placedMapObjects.filter((object) => object.id !== id)
|
|
mapEditor.selectedPlacedObject.value = null
|
|
emit('updateAndCommit', map)
|
|
}
|
|
|
|
function clickPlacedMapObject(placedMapObject: PlacedMapObjectT) {
|
|
mapEditor.selectedPlacedObject.value = placedMapObject
|
|
|
|
// If alt is pressed, select the object
|
|
if (scene.input.activePointer.event.altKey) {
|
|
mapEditor.setSelectedMapObject(placedMapObject.mapObject as MapObject)
|
|
}
|
|
}
|
|
|
|
function handlePointer(pointer: Phaser.Input.Pointer) {
|
|
const map = mapEditor.currentMap.value
|
|
if (!map) return
|
|
|
|
// Check if alt is pressed, this means we are selecting the object
|
|
if (pointer.event.altKey) return
|
|
|
|
// Check if tool is pencil
|
|
switch (mapEditor.tool.value) {
|
|
case 'pencil':
|
|
pencil(pointer, map)
|
|
break
|
|
case 'eraser':
|
|
eraser(pointer, map)
|
|
break
|
|
case 'object picker':
|
|
objectPicker(pointer, map)
|
|
break
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, updatePreviewPosition)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, updatePreviewPosition)
|
|
})
|
|
</script>
|