diff --git a/package-lock.json b/package-lock.json index 35a6bd5..cd1c0c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3124,9 +3124,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001676", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", - "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "dev": true, "funding": [ { @@ -4235,9 +4235,9 @@ } }, "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4246,7 +4246,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=14.14" + "node": ">=12" } }, "node_modules/fs-extra/node_modules/universalify": { @@ -7334,31 +7334,6 @@ "vite": ">=2.0.0" } }, - "node_modules/vite-plugin-compression/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-plugin-compression/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/vite-plugin-inspect": { "version": "0.8.7", "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.8.7.tgz", @@ -7391,6 +7366,21 @@ } } }, + "node_modules/vite-plugin-inspect/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/vite-plugin-inspect/node_modules/sirv": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", @@ -7406,6 +7396,16 @@ "node": ">= 10" } }, + "node_modules/vite-plugin-inspect/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/vite-plugin-vue-devtools": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.6.2.tgz", diff --git a/src/components/gameMaster/zoneEditor/ZoneObjects.vue b/src/components/gameMaster/zoneEditor/ZoneObjects.vue index f9d78f3..860d50e 100644 --- a/src/components/gameMaster/zoneEditor/ZoneObjects.vue +++ b/src/components/gameMaster/zoneEditor/ZoneObjects.vue @@ -1,6 +1,6 @@ <template> <SelectedZoneObject v-if="selectedZoneObject" :zoneObject="selectedZoneObject" :movingZoneObject="movingZoneObject" @move="moveZoneObject" @rotate="rotateZoneObject" @delete="deleteZoneObject" /> - <ZoneObject v-for="zoneObject in zoneEditorStore.zone?.zoneObjects" :tilemap="tilemap" :zoneObject :selectedZoneObject :movingZoneObject @pointerup="() => (selectedZoneObject = zoneObject)" /> + <ZoneObject v-for="zoneObject in zoneEditorStore.zone?.zoneObjects" :tilemap="tilemap" :zoneObject :selectedZoneObject :movingZoneObject @pointerup="clickZoneObject(zoneObject)" /> </template> <script setup lang="ts"> @@ -41,6 +41,9 @@ function pencil(pointer: Phaser.Input.Pointer) { // Check if shift is not pressed, this means we are moving the camera if (pointer.event.shiftKey) return + // Check if alt is pressed, this means we are selecting the object + if (pointer.event.altKey) return + // Check if there is a tile const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY) if (!tile) return @@ -53,7 +56,7 @@ function pencil(pointer: Phaser.Input.Pointer) { id: uuidv4(), zoneId: zoneEditorStore.zone.id, zone: zoneEditorStore.zone, - objectId: zoneEditorStore.selectedObject.id, + objectId: zoneEditorStore.selectedObject, object: zoneEditorStore.selectedObject, depth: 0, isRotated: false, @@ -81,6 +84,9 @@ function eraser(pointer: Phaser.Input.Pointer) { // Check if shift is not pressed, this means we are moving the camera if (pointer.event.shiftKey) return + // Check if alt is pressed, this means we are selecting the object + if (pointer.event.altKey) return + // Check if there is a tile const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY) if (!tile) return @@ -93,6 +99,37 @@ function eraser(pointer: Phaser.Input.Pointer) { zoneEditorStore.zone.zoneObjects = zoneEditorStore.zone.zoneObjects.filter((object) => object.id !== existingObject.id) } +function objectPicker(pointer: Phaser.Input.Pointer) { + // Check if zone is set + if (!zoneEditorStore.zone) return + + // Check if tool is pencil + if (zoneEditorStore.tool !== 'pencil') return + + // Check if draw mode is object + if (zoneEditorStore.drawMode !== 'object') return + + // Check if left mouse button is pressed + if (!pointer.isDown) return + + // Check if shift is not pressed, this means we are moving the camera + if (pointer.event.shiftKey) return + + // If alt is not pressed, return + if (!pointer.event.altKey) return + + // Check if there is a tile + const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY) + if (!tile) return + + // Check if object already exists on position + const existingObject = zoneEditorStore.zone.zoneObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y) + if (!existingObject) return + + // Select the object + zoneEditorStore.setSelectedObject(existingObject) +} + function moveZoneObject(id: string) { // Check if zone is set if (!zoneEditorStore.zone) return @@ -142,11 +179,21 @@ function deleteZoneObject(id: string) { selectedZoneObject.value = null } +function clickZoneObject(zoneObject: ZoneObjectT) { + selectedZoneObject.value = zoneObject + + // If alt is pressed, select the object + if (scene.input.activePointer.event.altKey) { + zoneEditorStore.setSelectedObject(zoneObject.object) + } +} + onMounted(() => { scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil) scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil) scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser) scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser) + scene.input.on(Phaser.Input.Events.POINTER_DOWN, objectPicker) }) onUnmounted(() => { @@ -154,6 +201,7 @@ onUnmounted(() => { scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil) scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser) scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser) + scene.input.off(Phaser.Input.Events.POINTER_DOWN, objectPicker) }) // watch zoneEditorStore.objectList and update originX and originY of objects in zoneObjects diff --git a/src/components/gameMaster/zoneEditor/ZoneTiles.vue b/src/components/gameMaster/zoneEditor/ZoneTiles.vue index d90ef2d..e8f82e1 100644 --- a/src/components/gameMaster/zoneEditor/ZoneTiles.vue +++ b/src/components/gameMaster/zoneEditor/ZoneTiles.vue @@ -83,10 +83,10 @@ function pencil(pointer: Phaser.Input.Pointer) { if (!tile) return // Place tile - placeTile(zoneTilemap, tiles, tile.x, tile.y, zoneEditorStore.selectedTile.id) + placeTile(zoneTilemap, tiles, tile.x, tile.y, zoneEditorStore.selectedTile) // Adjust zoneEditorStore.zone.tiles - zoneEditorStore.zone.tiles[tile.y][tile.x] = zoneEditorStore.selectedTile.id + zoneEditorStore.zone.tiles[tile.y][tile.x] = zoneEditorStore.selectedTile } function eraser(pointer: Phaser.Input.Pointer) { @@ -105,6 +105,9 @@ function eraser(pointer: Phaser.Input.Pointer) { // Check if shift is not pressed, this means we are moving the camera if (pointer.event.shiftKey) return + // Check if alt is pressed + if (pointer.event.altKey) return + // Check if there is a tile const tile = getTile(tiles, pointer.worldX, pointer.worldY) if (!tile) return @@ -129,6 +132,12 @@ function paint(pointer: Phaser.Input.Pointer) { // Check if left mouse button is pressed if (!pointer.isDown) return + // Check if shift is not pressed, this means we are moving the camera + if (pointer.event.shiftKey) return + + // Check if alt is pressed + if (pointer.event.altKey) return + // Set new tileArray with selected tile setLayerTiles(zoneTilemap, tiles, createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id)) @@ -136,6 +145,34 @@ function paint(pointer: Phaser.Input.Pointer) { zoneEditorStore.zone.tiles = createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id) } +// When alt is pressed, and the pointer is down, select the tile that the pointer is over +function tilePicker(pointer: Phaser.Input.Pointer) { + // Check if zone is set + if (!zoneEditorStore.zone) return + + // Check if tool is pencil + if (zoneEditorStore.tool !== 'pencil') return + + // Check if draw mode is tile + if (zoneEditorStore.drawMode !== 'tile') return + + // Check if left mouse button is pressed + if (!pointer.isDown) return + + // Check if shift is not pressed, this means we are moving the camera + if (pointer.event.shiftKey) return + + // Check if alt is pressed + if (!pointer.event.altKey) return + + // Check if there is a tile + const tile = getTile(tiles, pointer.worldX, pointer.worldY) + if (!tile) return + + // Select the tile + zoneEditorStore.setSelectedTile(zoneEditorStore.zone.tiles[tile.y][tile.x]) +} + onMounted(() => { if (!zoneEditorStore.zone?.tiles) { return @@ -145,12 +182,14 @@ onMounted(() => { scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil) scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser) scene.input.on(Phaser.Input.Events.POINTER_DOWN, paint) + scene.input.on(Phaser.Input.Events.POINTER_DOWN, tilePicker) }) onUnmounted(() => { scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil) scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser) scene.input.off(Phaser.Input.Events.POINTER_DOWN, paint) + scene.input.off(Phaser.Input.Events.POINTER_DOWN, tilePicker) zoneTilemap.destroyLayer('tiles') zoneTilemap.removeAllLayers() diff --git a/src/components/gameMaster/zoneEditor/partials/ObjectList.vue b/src/components/gameMaster/zoneEditor/partials/ObjectList.vue index ba2bb03..cd77314 100644 --- a/src/components/gameMaster/zoneEditor/partials/ObjectList.vue +++ b/src/components/gameMaster/zoneEditor/partials/ObjectList.vue @@ -42,23 +42,18 @@ <script setup lang="ts"> import config from '@/config' -import { ref, onMounted, computed, watch } from 'vue' +import { ref, onMounted, computed } from 'vue' import { useZoneEditorStore } from '@/stores/zoneEditorStore' import { useGameStore } from '@/stores/gameStore' import Modal from '@/components/utilities/Modal.vue' -import type { Object } from '@/types' +import type { Object, ZoneObject } from '@/types' const gameStore = useGameStore() const isModalOpen = ref(false) const zoneEditorStore = useZoneEditorStore() const searchQuery = ref('') -// const objectDepth = ref(0) const selectedTags = ref<string[]>([]) -// watch(objectDepth, (depth) => { -// zoneEditorStore.setObjectDepth(depth) -// }) - const uniqueTags = computed(() => { const allTags = zoneEditorStore.objectList.flatMap((obj) => obj.tags || []) return Array.from(new Set(allTags)) @@ -81,8 +76,6 @@ const toggleTag = (tag: string) => { } onMounted(async () => { - zoneEditorStore.setObjectDepth(0) - isModalOpen.value = true gameStore.connection?.emit('gm:object:list', {}, (response: Object[]) => { zoneEditorStore.setObjectList(response) diff --git a/src/components/gameMaster/zoneEditor/partials/TileList.vue b/src/components/gameMaster/zoneEditor/partials/TileList.vue index 9455f67..9a05bb3 100644 --- a/src/components/gameMaster/zoneEditor/partials/TileList.vue +++ b/src/components/gameMaster/zoneEditor/partials/TileList.vue @@ -52,7 +52,7 @@ class="max-w-full max-h-full border-2 border-solid cursor-pointer transition-all duration-300" :src="`${config.server_endpoint}/assets/tiles/${selectedGroup.parent.id}.png`" :alt="selectedGroup.parent.name" - @click="selectTile(selectedGroup.parent)" + @click="selectTile(selectedGroup.parent.id)" :class="{ 'border-cyan shadow-lg scale-105': isActiveTile(selectedGroup.parent), 'border-transparent hover:border-gray-300': !isActiveTile(selectedGroup.parent) @@ -65,7 +65,7 @@ class="max-w-full max-h-full border-2 border-solid cursor-pointer transition-all duration-300" :src="`${config.server_endpoint}/assets/tiles/${childTile.id}.png`" :alt="childTile.name" - @click="selectTile(childTile)" + @click="selectTile(childTile.id)" :class="{ 'border-cyan shadow-lg scale-105': isActiveTile(childTile), 'border-transparent hover:border-gray-300': !isActiveTile(childTile) @@ -218,7 +218,7 @@ function closeGroup() { selectedGroup.value = null } -function selectTile(tile: Tile) { +function selectTile(tile: string) { zoneEditorStore.setSelectedTile(tile) } diff --git a/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue b/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue index 126fcea..43ad2e7 100644 --- a/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue +++ b/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue @@ -1,13 +1,14 @@ <template> - <Image v-if="isTextureLoaded" v-bind="imageProps" /> + <Image v-if="gameStore.getLoadedAsset(props.zoneObject.object.id)" v-bind="imageProps" /> </template> <script setup lang="ts"> -import { ref, computed } from 'vue' +import { computed } from 'vue' import { Image, useScene } from 'phavuer' import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable' import { loadTexture } from '@/composables/gameComposable' import type { AssetDataT, ZoneObject } from '@/types' +import { useGameStore } from '@/stores/gameStore' const props = defineProps<{ tilemap: Phaser.Tilemaps.Tilemap @@ -16,8 +17,8 @@ const props = defineProps<{ movingZoneObject: ZoneObject | null }>() +const gameStore = useGameStore() const scene = useScene() -const isTextureLoaded = ref(false) const imageProps = computed(() => ({ alpha: props.movingZoneObject?.id === props.zoneObject.id ? 0.5 : 1, diff --git a/src/stores/zoneEditorStore.ts b/src/stores/zoneEditorStore.ts index 0981b16..dfe343e 100644 --- a/src/stores/zoneEditorStore.ts +++ b/src/stores/zoneEditorStore.ts @@ -1,6 +1,6 @@ import { defineStore } from 'pinia' import { useGameStore } from '@/stores/gameStore' -import type { Zone, Object, Tile, ZoneEffect } from '@/types' +import type { Zone, Object, Tile, ZoneEffect, ZoneObject } from '@/types' export type TeleportSettings = { toZoneId: number @@ -20,9 +20,8 @@ export const useZoneEditorStore = defineStore('zoneEditor', { zoneList: [] as Zone[], tileList: [] as Tile[], objectList: [] as Object[], - selectedTile: null as Tile | null, + selectedTile: '', selectedObject: null as Object | null, - objectDepth: 0, isTileListModalShown: false, isObjectListModalShown: false, isZoneListModalShown: false, @@ -88,15 +87,12 @@ export const useZoneEditorStore = defineStore('zoneEditor', { setObjectList(objects: Object[]) { this.objectList = objects }, - setSelectedTile(tile: Tile) { + setSelectedTile(tile: string) { this.selectedTile = tile }, - setSelectedObject(object: any) { + setSelectedObject(object: Object) { this.selectedObject = object }, - setObjectDepth(depth: number) { - this.objectDepth = depth - }, toggleSettingsModal() { this.isSettingsModalShown = !this.isSettingsModalShown }, @@ -117,9 +113,8 @@ export const useZoneEditorStore = defineStore('zoneEditor', { this.objectList = [] this.tool = 'move' this.drawMode = 'tile' - this.selectedTile = null + this.selectedTile = '' this.selectedObject = null - this.objectDepth = 0 this.isSettingsModalShown = false this.isZoneListModalShown = false this.isCreateZoneModalShown = false