Changes to mapeditorcomposable, fix pencil and fill tool for tiles
Locked in, made mapeditor my bi-
This commit is contained in:
parent
cfac1d508b
commit
14aa696197
10
src/App.vue
10
src/App.vue
@ -17,24 +17,24 @@ import BackgroundImageLoader from '@/components/utilities/BackgroundImageLoader.
|
||||
import Debug from '@/components/utilities/Debug.vue'
|
||||
import Notifications from '@/components/utilities/Notifications.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { computed, watch } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
|
||||
const currentScreen = computed(() => {
|
||||
if (!gameStore.game.isLoaded) return Loading
|
||||
if (!gameStore.connection) return Login
|
||||
if (!gameStore.token) return Login
|
||||
if (!gameStore.character) return Characters
|
||||
if (mapEditorStore.active) return MapEditor
|
||||
if (mapEditor.active.value) return MapEditor
|
||||
return Game
|
||||
})
|
||||
|
||||
// Watch mapEditorStore.active and empty gameStore.game.loadedAssets
|
||||
// Watch mapEditor.active and empty gameStore.game.loadedAssets
|
||||
watch(
|
||||
() => mapEditorStore.active,
|
||||
() => mapEditor.active.value,
|
||||
() => {
|
||||
gameStore.game.loadedTextures = []
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
<button @mousedown.stop class="btn-cyan py-1.5 px-4 min-w-24">Users</button>
|
||||
<button @mousedown.stop class="btn-cyan py-1.5 px-4 min-w-24">Chats</button>
|
||||
<button @mousedown.stop class="btn-cyan active py-1.5 px-4 min-w-24">Asset manager</button>
|
||||
<button class="btn-cyan py-1.5 px-4 min-w-24" type="button" @click="() => mapEditorStore.toggleActive()">Map editor</button>
|
||||
<button class="btn-cyan py-1.5 px-4 min-w-24" type="button" @click="() => mapEditor.toggleActive()">Map editor</button>
|
||||
</div>
|
||||
</template>
|
||||
<template #modalBody>
|
||||
@ -21,11 +21,11 @@
|
||||
import AssetManager from '@/components/gameMaster/assetManager/AssetManager.vue'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
|
||||
let toggle = ref('asset-manager')
|
||||
</script>
|
||||
|
@ -29,7 +29,6 @@ import ChipsInput from '@/components/forms/ChipsInput.vue'
|
||||
import { TileStorage } from '@/storage/storages'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
|
@ -8,13 +8,13 @@
|
||||
import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEventTiles.vue'
|
||||
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
|
||||
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { onMounted, onUnmounted, shallowRef } from 'vue'
|
||||
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
|
||||
onUnmounted(() => {
|
||||
mapEditorStore.reset()
|
||||
mapEditor.reset()
|
||||
})
|
||||
</script>
|
||||
|
@ -8,7 +8,6 @@ import Controls from '@/components/utilities/Controls.vue'
|
||||
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/mapComposable'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { TileStorage } from '@/storage/storages'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useScene } from 'phavuer'
|
||||
import { onMounted, onUnmounted, shallowRef, watch } from 'vue'
|
||||
|
||||
@ -18,7 +17,6 @@ const emit = defineEmits(['tileMap:create'])
|
||||
|
||||
const scene = useScene()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const tileStorage = new TileStorage()
|
||||
|
||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
@ -62,15 +60,16 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
||||
|
||||
// Check if map is set
|
||||
if (!mapEditor.currentMap.value) return
|
||||
console.log(mapEditor.tool.value)
|
||||
|
||||
// Check if tool is pencil
|
||||
if (mapEditorStore.tool !== 'pencil') return
|
||||
if (mapEditor.tool.value !== 'pencil') return
|
||||
|
||||
// Check if draw mode is tile
|
||||
if (mapEditorStore.drawMode !== 'tile') return
|
||||
if (mapEditor.drawMode.value !== 'tile') return
|
||||
|
||||
// Check if there is a selected tile
|
||||
if (!mapEditorStore.selectedTile) return
|
||||
if (!mapEditor.selectedTile.value) return // Changed this line to access .value
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown) return
|
||||
@ -83,10 +82,10 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
||||
if (!tile) return
|
||||
|
||||
// Place tile
|
||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, mapEditorStore.selectedTile)
|
||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, mapEditor.selectedTile.value)
|
||||
|
||||
// Adjust mapEditorStore.map.tiles
|
||||
mapEditor.currentMap.value.tiles[tile.y][tile.x] = mapEditor.currentMap.value.tiles[tile.y][tile.x]
|
||||
// Adjust mapEditor tiles
|
||||
mapEditor.currentMap.value.tiles[tile.y][tile.x] = mapEditor.selectedTile.value
|
||||
}
|
||||
|
||||
function eraser(pointer: Phaser.Input.Pointer) {
|
||||
@ -96,10 +95,10 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
// Check if tool is pencil
|
||||
if (mapEditorStore.tool !== 'eraser') return
|
||||
if (mapEditor.tool.value !== 'eraser') return
|
||||
|
||||
// Check if draw mode is tile
|
||||
if (mapEditorStore.eraserMode !== 'tile') return
|
||||
if (mapEditor.eraserMode.value !== 'tile') return
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown) return
|
||||
@ -117,7 +116,7 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
||||
// Place tile
|
||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, 'blank_tile')
|
||||
|
||||
// Adjust mapEditorStore.map.tiles
|
||||
// Adjust mapEditor.map.tiles
|
||||
mapEditor.currentMap.value.tiles[tile.y][tile.x] = 'blank_tile'
|
||||
}
|
||||
|
||||
@ -128,10 +127,10 @@ function paint(pointer: Phaser.Input.Pointer) {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
// Check if tool is pencil
|
||||
if (mapEditorStore.tool !== 'paint') return
|
||||
if (mapEditor.tool.value !== 'paint') return
|
||||
|
||||
// Check if there is a selected tile
|
||||
if (!mapEditorStore.selectedTile) return
|
||||
if (!mapEditor.selectedTile.value) return
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown) return
|
||||
@ -143,10 +142,10 @@ function paint(pointer: Phaser.Input.Pointer) {
|
||||
if (pointer.event.altKey) return
|
||||
|
||||
// Set new tileArray with selected tile
|
||||
setLayerTiles(tileMap.value, tileLayer.value, createTileArray(tileMap.value.width, tileMap.value.height, mapEditorStore.selectedTile))
|
||||
setLayerTiles(tileMap.value, tileLayer.value, createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value))
|
||||
|
||||
// Adjust mapEditorStore.map.tiles
|
||||
mapEditor.currentMap.value.tiles = createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.currentMap.value.tiles)
|
||||
// Adjust mapEditor.map.tiles
|
||||
mapEditor.currentMap.value.tiles = createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value)
|
||||
}
|
||||
|
||||
// When alt is pressed, and the pointer is down, select the tile that the pointer is over
|
||||
@ -157,10 +156,10 @@ function tilePicker(pointer: Phaser.Input.Pointer) {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
// Check if tool is pencil
|
||||
if (mapEditorStore.tool !== 'pencil') return
|
||||
if (mapEditor.tool.value !== 'pencil') return
|
||||
|
||||
// Check if draw mode is tile
|
||||
if (mapEditorStore.drawMode !== 'tile') return
|
||||
if (mapEditor.drawMode.value !== 'tile') return
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown) return
|
||||
@ -176,17 +175,17 @@ function tilePicker(pointer: Phaser.Input.Pointer) {
|
||||
if (!tile) return
|
||||
|
||||
// Select the tile
|
||||
mapEditorStore.setSelectedMapObject(mapEditor.currentMap.value.tiles[tile.y][tile.x])
|
||||
mapEditor.setSelectedTile(mapEditor.currentMap.value.tiles[tile.y][tile.x])
|
||||
}
|
||||
|
||||
watch(
|
||||
() => mapEditorStore.shouldClearTiles,
|
||||
() => mapEditor.shouldClearTiles.value,
|
||||
(shouldClear) => {
|
||||
if (shouldClear && mapEditor.currentMap.value && tileMap.value && tileLayer.value) {
|
||||
const blankTiles = createTileArray(tileMap.value.width, tileMap.value.height, 'blank_tile')
|
||||
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
||||
mapEditor.currentMap.value.tiles = blankTiles
|
||||
mapEditorStore.resetClearTilesFlag()
|
||||
mapEditor.resetClearTilesFlag()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :isModalOpen="mapEditorStore.isCreateMapModalShown" @modal:close="() => mapEditorStore.toggleCreateMapModal()" :modal-width="300" :modal-height="420" :is-resizable="false" :bg-style="'none'">
|
||||
<Modal :isModalOpen="mapEditor.isCreateMapModalShown.value" @modal:close="() => mapEditor.toggleCreateMapModal()" :modal-width="300" :modal-height="420" :is-resizable="false" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="m-0 font-medium shrink-0 text-white">Create new map</h3>
|
||||
</template>
|
||||
@ -39,13 +39,13 @@ import type { Map } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { MapStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const emit = defineEmits(['create'])
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const mapStorage = new MapStorage()
|
||||
|
||||
const name = ref('')
|
||||
@ -79,6 +79,6 @@ async function submit() {
|
||||
})
|
||||
|
||||
// Close modal
|
||||
mapEditorStore.toggleCreateMapModal()
|
||||
mapEditor.toggleCreateMapModal()
|
||||
}
|
||||
</script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :is-modal-open="mapEditorStore.isMapListModalShown" @modal:close="() => mapEditorStore.toggleMapListModal()" :is-resizable="false" :modal-width="300" :modal-height="360" :bg-style="'none'">
|
||||
<Modal :is-modal-open="mapEditor.isMapListModalShown.value" @modal:close="() => mapEditor.toggleMapListModal()" :is-resizable="false" :modal-width="300" :modal-height="360" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="text-lg text-white">Maps</h3>
|
||||
</template>
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="my-4 mx-auto h-full">
|
||||
<div class="text-center mb-4 px-2 flex gap-2.5">
|
||||
<button class="btn-cyan py-1.5 min-w-[calc(50%_-_5px)]" @click="fetchMaps">Refresh</button>
|
||||
<button class="btn-cyan py-1.5 min-w-[calc(50%_-_5px)]" @click="() => mapEditorStore.toggleCreateMapModal()">New</button>
|
||||
<button class="btn-cyan py-1.5 min-w-[calc(50%_-_5px)]" @click="() => mapEditor.toggleCreateMapModal()">New</button>
|
||||
</div>
|
||||
<div class="overflow-y-auto h-[calc(100%-20px)]">
|
||||
<div class="relative p-2.5 cursor-pointer flex gap-y-2.5 gap-x-5 flex-wrap" v-for="(map, index) in mapList" :key="map.id">
|
||||
@ -25,7 +25,7 @@
|
||||
</template>
|
||||
</Modal>
|
||||
|
||||
<CreateMap @create="fetchMaps" v-if="mapEditorStore.isMapListModalShown" />
|
||||
<CreateMap @create="fetchMaps" v-if="mapEditor.isMapListModalShown.value" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -35,11 +35,9 @@ import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { MapStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const mapStorage = new MapStorage()
|
||||
@ -57,7 +55,7 @@ function loadMap(id: UUID) {
|
||||
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
|
||||
mapEditor.loadMap(response)
|
||||
})
|
||||
mapEditorStore.toggleMapListModal()
|
||||
mapEditor.toggleMapListModal()
|
||||
}
|
||||
|
||||
async function deleteMap(id: UUID) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :isModalOpen="mapEditorStore.isMapObjectListModalShown" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditorStore.isMapObjectListModalShown = false)" :bg-style="'none'">
|
||||
<Modal :isModalOpen="mapEditor.isMapObjectListModalShown.value" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditor.isMapObjectListModalShown.value = false)" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="text-lg text-white">Map objects</h3>
|
||||
</template>
|
||||
@ -25,11 +25,11 @@
|
||||
class="border-2 border-solid max-w-full"
|
||||
:src="`${config.server_endpoint}/textures/map_objects/${mapObject.id}.png`"
|
||||
alt="Object"
|
||||
@click="mapEditorStore.setSelectedMapObject(mapObject)"
|
||||
@click="mapEditor.setSelectedMapObject(mapObject)"
|
||||
:class="{
|
||||
'cursor-pointer transition-all duration-300': true,
|
||||
'border-cyan shadow-lg scale-105': mapEditorStore.selectedMapObject?.id === mapObject.id,
|
||||
'border-transparent hover:border-gray-300': mapEditorStore.selectedMapObject?.id !== mapObject.id
|
||||
'border-cyan shadow-lg scale-105': mapEditor.selectedMapObject.value?.id === mapObject.id,
|
||||
'border-transparent hover:border-gray-300': mapEditor.selectedMapObject.value?.id !== mapObject.id
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
@ -45,14 +45,13 @@ import config from '@/application/config'
|
||||
import type { MapObject } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { MapObjectStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { liveQuery } from 'dexie'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const mapObjectStorage = new MapObjectStorage()
|
||||
const isModalOpen = ref(false)
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const searchQuery = ref('')
|
||||
const selectedTags = ref<string[]>([])
|
||||
const mapObjectList = ref<MapObject[]>([])
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :is-modal-open="mapEditorStore.isSettingsModalShown" @modal:close="() => mapEditorStore.toggleSettingsModal()" :modal-width="600" :modal-height="430" :bg-style="'none'">
|
||||
<Modal :is-modal-open="mapEditor.isSettingsModalShown.value" @modal:close="() => mapEditor.toggleSettingsModal()" :modal-width="600" :modal-height="430" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="m-0 font-medium shrink-0 text-white">Map settings</h3>
|
||||
</template>
|
||||
@ -51,11 +51,9 @@ import type { UUID } from '@/application/types'
|
||||
import { uuidv4 } from '@/application/utilities'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const screen = ref('settings')
|
||||
|
||||
const name = ref(mapEditor.currentMap.value?.name)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :isModalOpen="mapEditorStore.isTileListModalShown" :modal-width="645" :modal-height="600" @modal:close="() => (mapEditorStore.isTileListModalShown = false)" :bg-style="'none'">
|
||||
<Modal :isModalOpen="mapEditor.isTileListModalShown.value" :modal-width="645" :modal-height="600" @modal:close="() => (mapEditor.isTileListModalShown.value = false)" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="text-lg text-white">Tiles</h3>
|
||||
</template>
|
||||
@ -85,12 +85,12 @@ import config from '@/application/config'
|
||||
import type { Tile } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { TileStorage } from '@/storage/storages'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { liveQuery } from 'dexie'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const tileStorage = new TileStorage()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const searchQuery = ref('')
|
||||
const selectedTags = ref<string[]>([])
|
||||
const tileCategories = ref<Map<string, string>>(new Map())
|
||||
@ -222,11 +222,11 @@ function closeGroup() {
|
||||
}
|
||||
|
||||
function selectTile(tile: string) {
|
||||
mapEditorStore.setSelectedTile(tile)
|
||||
mapEditor.setSelectedTile(tile)
|
||||
}
|
||||
|
||||
function isActiveTile(tile: Tile): boolean {
|
||||
return mapEditorStore.selectedTile === tile.id
|
||||
return mapEditor.selectedTile.value === tile.id
|
||||
}
|
||||
|
||||
let subscription: any = null
|
||||
|
@ -2,20 +2,20 @@
|
||||
<div class="flex justify-center p-5">
|
||||
<div class="toolbar fixed bottom-0 left-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10">
|
||||
<div ref="toolbar" class="tools flex gap-2.5" v-if="mapEditor.currentMap.value">
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'move' }" @click="handleClick('move')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'move' }">(M)</span>
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'move' }" @click="handleClick('move')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'move' }">(M)</span>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'pencil' }" @click="handleClick('pencil')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/pencil.svg" alt="Pencil" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'pencil' }">(P)</span>
|
||||
<div class="select" v-if="mapEditorStore.tool === 'pencil'">
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'pencil' }" @click="handleClick('pencil')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/pencil.svg" alt="Pencil" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'pencil' }">(P)</span>
|
||||
<div class="select" v-if="mapEditor.tool.value === 'pencil'">
|
||||
<div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectPencilOpen }">
|
||||
{{ mapEditorStore.drawMode.replace('_', ' ') }}
|
||||
{{ mapEditor.drawMode.value.replace('_', ' ') }}
|
||||
<img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" alt="" />
|
||||
</div>
|
||||
<div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectPencilOpen && mapEditorStore.tool === 'pencil'">
|
||||
<div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectPencilOpen && mapEditor.tool.value === 'pencil'">
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setDrawMode('tile')">
|
||||
Tile
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
@ -35,11 +35,11 @@
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'eraser' }" @click="handleClick('eraser')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/eraser.svg" alt="Eraser" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'eraser' }">(E)</span>
|
||||
<div class="select" v-if="mapEditorStore.tool === 'eraser'">
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'eraser' }" @click="handleClick('eraser')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/eraser.svg" alt="Eraser" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'eraser' }">(E)</span>
|
||||
<div class="select" v-if="mapEditor.tool.value === 'eraser'">
|
||||
<div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectEraserOpen }">
|
||||
{{ mapEditorStore.eraserMode.replace('_', ' ') }}
|
||||
{{ mapEditor.eraserMode.value.replace('_', ' ') }}
|
||||
<img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" />
|
||||
</div>
|
||||
<div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectEraserOpen">
|
||||
@ -62,8 +62,8 @@
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'paint' }" @click="handleClick('paint')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/paint.svg" alt="Paint bucket" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'paint' }">(B)</span>
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'paint' }" @click="handleClick('paint')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/paint.svg" alt="Paint bucket" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'paint' }">(B)</span>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
@ -72,10 +72,10 @@
|
||||
</div>
|
||||
|
||||
<div class="toolbar fixed bottom-0 right-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10 space-x-2">
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditorStore.toggleMapListModal()">Load</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditor.toggleMapListModal()">Load</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => emit('save')" v-if="mapEditor.currentMap.value">Save</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => emit('clear')" v-if="mapEditor.currentMap.value">Clear</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditorStore.toggleActive()">Exit</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditor.toggleActive()">Exit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -83,12 +83,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
|
||||
const emit = defineEmits(['save', 'clear'])
|
||||
|
||||
@ -101,24 +99,24 @@ let selectEraserOpen = ref(false)
|
||||
|
||||
// drawMode
|
||||
function setDrawMode(value: string) {
|
||||
mapEditorStore.isTileListModalShown = value === 'tile'
|
||||
mapEditorStore.isMapObjectListModalShown = value === 'map_object'
|
||||
mapEditor.isTileListModalShown.value = value === 'tile'
|
||||
mapEditor.isMapObjectListModalShown.value = value === 'map_object'
|
||||
|
||||
mapEditorStore.setDrawMode(value)
|
||||
mapEditor.setDrawMode(value)
|
||||
selectPencilOpen.value = false
|
||||
}
|
||||
|
||||
// drawMode
|
||||
function setEraserMode(value: string) {
|
||||
mapEditorStore.setEraserMode(value)
|
||||
mapEditor.setEraserMode(value)
|
||||
selectEraserOpen.value = false
|
||||
}
|
||||
|
||||
function handleClick(tool: string) {
|
||||
if (tool === 'settings') {
|
||||
mapEditorStore.toggleSettingsModal()
|
||||
mapEditor.toggleSettingsModal()
|
||||
} else {
|
||||
mapEditorStore.setTool(tool)
|
||||
mapEditor.setTool(tool)
|
||||
}
|
||||
|
||||
selectPencilOpen.value = tool === 'pencil' ? !selectPencilOpen.value : false
|
||||
@ -127,8 +125,8 @@ function handleClick(tool: string) {
|
||||
|
||||
function cycleToolMode(tool: 'pencil' | 'eraser') {
|
||||
const modes = ['tile', 'object', 'teleport', 'blocking tile']
|
||||
const currentMode = tool === 'pencil' ? mapEditorStore.drawMode : mapEditorStore.eraserMode
|
||||
const currentIndex = modes.indexOf(currentMode)
|
||||
const currentMode = tool === 'pencil' ? mapEditor.drawMode : mapEditor.eraserMode
|
||||
const currentIndex = modes.indexOf(currentMode.value)
|
||||
const nextIndex = (currentIndex + 1) % modes.length
|
||||
const nextMode = modes[nextIndex]
|
||||
|
||||
@ -141,7 +139,7 @@ function cycleToolMode(tool: 'pencil' | 'eraser') {
|
||||
|
||||
function initKeyShortcuts(event: KeyboardEvent) {
|
||||
// Check if map is set
|
||||
if (!mapEditorStore.map) return
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
// prevent if focused on composables
|
||||
if (document.activeElement?.tagName === 'INPUT') return
|
||||
@ -156,7 +154,7 @@ function initKeyShortcuts(event: KeyboardEvent) {
|
||||
|
||||
if (keyActions.hasOwnProperty(event.key)) {
|
||||
const tool = keyActions[event.key]
|
||||
if ((tool === 'pencil' || tool === 'eraser') && mapEditorStore.tool === tool) {
|
||||
if ((tool === 'pencil' || tool === 'eraser') && mapEditor.tool.value === tool) {
|
||||
cycleToolMode(tool)
|
||||
} else {
|
||||
handleClick(tool)
|
||||
|
@ -32,14 +32,12 @@ import { loadAllTilesIntoScene } from '@/composables/mapComposable'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { MapStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { Game, Scene } from 'phavuer'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const mapStorage = new MapStorage()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
|
||||
const isLoaded = ref(false)
|
||||
|
||||
@ -92,8 +90,8 @@ function save() {
|
||||
placedMapObjects: mapEditor.currentMap.value.placedMapObjects?.map(({ id, mapObject, depth, isRotated, positionX, positionY }) => ({ id, mapObject, depth, isRotated, positionX, positionY })) ?? []
|
||||
}
|
||||
|
||||
if (mapEditorStore.isSettingsModalShown) {
|
||||
mapEditorStore.toggleSettingsModal()
|
||||
if (mapEditor.isSettingsModalShown.value) {
|
||||
mapEditor.toggleSettingsModal()
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:map:update', data, (response: MapT) => {
|
||||
@ -106,6 +104,6 @@ function clear() {
|
||||
|
||||
// Clear placed objects, event tiles and tiles
|
||||
mapEditor.clearMap()
|
||||
mapEditorStore.triggerClearTiles()
|
||||
mapEditor.triggerClearTiles()
|
||||
}
|
||||
</script>
|
||||
|
@ -1,13 +1,13 @@
|
||||
import config from '@/application/config'
|
||||
import { getTile, tileToWorldXY } from '@/composables/mapComposable'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { computed, ref, type Ref } from 'vue'
|
||||
|
||||
export function useMapEditorPointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Phaser.Cameras.Scene2D.Camera) {
|
||||
const gameStore = useGameStore()
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const isMoveTool = computed(() => mapEditorStore.tool === 'move')
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const isMoveTool = computed(() => mapEditor.tool.value === 'move')
|
||||
const pointerStartPosition = ref({ x: 0, y: 0 })
|
||||
const dragThreshold = 5 // pixels
|
||||
|
||||
|
@ -1,7 +1,32 @@
|
||||
import type { Map } from '@/application/types'
|
||||
import type { Map, MapObject } from '@/application/types'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export type TeleportSettings = {
|
||||
toMapId: string
|
||||
toPositionX: number
|
||||
toPositionY: number
|
||||
toRotation: number
|
||||
}
|
||||
|
||||
const currentMap = ref<Map | null>(null)
|
||||
const active = ref(false)
|
||||
const tool = ref('move')
|
||||
const drawMode = ref('tile')
|
||||
const eraserMode = ref('tile')
|
||||
const selectedTile = ref('')
|
||||
const selectedMapObject = ref<MapObject | null>(null)
|
||||
const isTileListModalShown = ref(false)
|
||||
const isMapObjectListModalShown = ref(false)
|
||||
const isMapListModalShown = ref(false)
|
||||
const isCreateMapModalShown = ref(false)
|
||||
const isSettingsModalShown = ref(false)
|
||||
const shouldClearTiles = ref(false)
|
||||
const teleportSettings = ref<TeleportSettings>({
|
||||
toMapId: '',
|
||||
toPositionX: 0,
|
||||
toPositionY: 0,
|
||||
toRotation: 0
|
||||
})
|
||||
|
||||
export function useMapEditorComposable() {
|
||||
const loadMap = (map: Map) => {
|
||||
@ -16,16 +41,107 @@ export function useMapEditorComposable() {
|
||||
|
||||
const clearMap = () => {
|
||||
if (!currentMap.value) return
|
||||
|
||||
currentMap.value.placedMapObjects = []
|
||||
currentMap.value.mapEventTiles = []
|
||||
currentMap.value.tiles = []
|
||||
}
|
||||
|
||||
const toggleActive = () => {
|
||||
if (active.value) reset()
|
||||
active.value = !active.value
|
||||
}
|
||||
|
||||
const setTool = (newTool: string) => {
|
||||
tool.value = newTool
|
||||
}
|
||||
|
||||
const setDrawMode = (mode: string) => {
|
||||
drawMode.value = mode
|
||||
}
|
||||
|
||||
const setEraserMode = (mode: string) => {
|
||||
eraserMode.value = mode
|
||||
}
|
||||
|
||||
const setSelectedTile = (tile: string) => {
|
||||
selectedTile.value = tile
|
||||
}
|
||||
|
||||
const setSelectedMapObject = (object: MapObject) => {
|
||||
selectedMapObject.value = object
|
||||
}
|
||||
|
||||
const toggleSettingsModal = () => {
|
||||
isSettingsModalShown.value = !isSettingsModalShown.value
|
||||
}
|
||||
|
||||
const toggleMapListModal = () => {
|
||||
isMapListModalShown.value = !isMapListModalShown.value
|
||||
isCreateMapModalShown.value = false
|
||||
}
|
||||
|
||||
const toggleCreateMapModal = () => {
|
||||
isCreateMapModalShown.value = !isCreateMapModalShown.value
|
||||
}
|
||||
|
||||
const setTeleportSettings = (settings: TeleportSettings) => {
|
||||
teleportSettings.value = settings
|
||||
}
|
||||
|
||||
const triggerClearTiles = () => {
|
||||
shouldClearTiles.value = true
|
||||
}
|
||||
|
||||
const resetClearTilesFlag = () => {
|
||||
shouldClearTiles.value = false
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
tool.value = 'move'
|
||||
drawMode.value = 'tile'
|
||||
selectedTile.value = ''
|
||||
selectedMapObject.value = null
|
||||
isTileListModalShown.value = false
|
||||
isMapObjectListModalShown.value = false
|
||||
isSettingsModalShown.value = false
|
||||
isMapListModalShown.value = false
|
||||
isCreateMapModalShown.value = false
|
||||
shouldClearTiles.value = false
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
currentMap,
|
||||
active,
|
||||
tool,
|
||||
drawMode,
|
||||
eraserMode,
|
||||
selectedTile,
|
||||
selectedMapObject,
|
||||
isTileListModalShown,
|
||||
isMapObjectListModalShown,
|
||||
isMapListModalShown,
|
||||
isCreateMapModalShown,
|
||||
isSettingsModalShown,
|
||||
shouldClearTiles,
|
||||
teleportSettings,
|
||||
|
||||
// Methods
|
||||
loadMap,
|
||||
updateProperty,
|
||||
clearMap
|
||||
clearMap,
|
||||
toggleActive,
|
||||
setTool,
|
||||
setDrawMode,
|
||||
setEraserMode,
|
||||
setSelectedTile,
|
||||
setSelectedMapObject,
|
||||
toggleSettingsModal,
|
||||
toggleMapListModal,
|
||||
toggleCreateMapModal,
|
||||
setTeleportSettings,
|
||||
triggerClearTiles,
|
||||
resetClearTilesFlag,
|
||||
reset
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +1,20 @@
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { computed, watch, type Ref } from 'vue'
|
||||
import { useGamePointerHandlers } from './pointerHandlers/useGamePointerHandlers'
|
||||
import { useMapEditorPointerHandlers } from './pointerHandlers/useMapEditorPointerHandlers'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
|
||||
export function usePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Phaser.Cameras.Scene2D.Camera) {
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const gameHandlers = useGamePointerHandlers(scene, layer, waypoint, camera)
|
||||
const mapEditorHandlers = useMapEditorPointerHandlers(scene, layer, waypoint, camera)
|
||||
|
||||
const currentHandlers = computed(() => (mapEditorStore.active ? mapEditorHandlers : gameHandlers))
|
||||
const currentHandlers = computed(() => (mapEditor.active.value ? mapEditorHandlers : gameHandlers))
|
||||
|
||||
const setupPointerHandlers = () => currentHandlers.value.setupPointerHandlers()
|
||||
const cleanupPointerHandlers = () => currentHandlers.value.cleanupPointerHandlers()
|
||||
|
||||
watch(
|
||||
() => mapEditorStore.active,
|
||||
() => mapEditor.active.value,
|
||||
() => {
|
||||
cleanupPointerHandlers()
|
||||
setupPointerHandlers()
|
||||
|
Loading…
x
Reference in New Issue
Block a user