Map editor improvements
This commit is contained in:
parent
ae0841889b
commit
ef807982a5
@ -15,7 +15,7 @@ export type HttpResponse<T> = {
|
||||
export type AssetDataT = {
|
||||
key: string
|
||||
data: string
|
||||
group: 'tiles' | 'objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
|
||||
group: 'tiles' | 'map_objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
|
||||
updatedAt: Date
|
||||
originX?: number
|
||||
originY?: number
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MapObject v-for="mapObject in mapStore.map?.mapObjects" :tilemap="tilemap" :mapObject />
|
||||
<MapObject v-for="mapObject in mapStore.map?.mapObjects" :tilemap="tilemap" :placedMapObject />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Image v-if="gameStore.getLoadedAsset(props.mapObject.object.id)" v-bind="imageProps" />
|
||||
<Image v-if="gameStore.getLoadedAsset(props.placedMapObject.mapObject.id)" v-bind="imageProps" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -12,29 +12,29 @@ import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
tilemap: Phaser.Tilemaps.Tilemap
|
||||
mapObject: PlacedMapObject
|
||||
placedMapObject: PlacedMapObject
|
||||
}>()
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const scene = useScene()
|
||||
|
||||
const imageProps = computed(() => ({
|
||||
depth: calculateIsometricDepth(props.mapObject.positionX, props.mapObject.positionY, props.mapObject.object.frameWidth, props.mapObject.object.frameHeight),
|
||||
x: tileToWorldX(props.tilemap, props.mapObject.positionX, props.mapObject.positionY),
|
||||
y: tileToWorldY(props.tilemap, props.mapObject.positionX, props.mapObject.positionY),
|
||||
flipX: props.mapObject.isRotated,
|
||||
texture: props.mapObject.object.id,
|
||||
originY: Number(props.mapObject.object.originX),
|
||||
originX: Number(props.mapObject.object.originY)
|
||||
depth: calculateIsometricDepth(props.placedMapObject.positionX, props.placedMapObject.positionY, props.placedMapObject.mapObject.frameWidth, props.placedMapObject.mapObject.frameHeight),
|
||||
x: tileToWorldX(props.tilemap, props.placedMapObject.positionX, props.placedMapObject.positionY),
|
||||
y: tileToWorldY(props.tilemap, props.placedMapObject.positionX, props.placedMapObject.positionY),
|
||||
flipX: props.placedMapObject.isRotated,
|
||||
texture: props.placedMapObject.mapObject.id,
|
||||
originY: Number(props.placedMapObject.mapObject.originX),
|
||||
originX: Number(props.placedMapObject.mapObject.originY)
|
||||
}))
|
||||
|
||||
loadTexture(scene, {
|
||||
key: props.mapObject.object.id,
|
||||
data: '/assets/objects/' + props.mapObject.object.id + '.png',
|
||||
group: 'objects',
|
||||
updatedAt: props.mapObject.object.updatedAt,
|
||||
frameWidth: props.mapObject.object.frameWidth,
|
||||
frameHeight: props.mapObject.object.frameHeight
|
||||
key: props.placedMapObject.mapObject.id,
|
||||
data: '/assets/map_objects/' + props.placedMapObject.mapObject.id + '.png',
|
||||
group: 'map_objects',
|
||||
updatedAt: props.placedMapObject.mapObject.updatedAt,
|
||||
frameWidth: props.placedMapObject.mapObject.frameWidth,
|
||||
frameHeight: props.placedMapObject.mapObject.frameHeight
|
||||
} as AssetDataT).catch((error) => {
|
||||
console.error('Error loading texture:', error)
|
||||
})
|
||||
|
@ -98,11 +98,11 @@ function removeObject() {
|
||||
})
|
||||
}
|
||||
|
||||
function refreshObjectList(unsetSelectedObject = true) {
|
||||
function refreshObjectList(unsetSelectedMapObject = true) {
|
||||
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
|
||||
assetManagerStore.setMapObjectList(response)
|
||||
|
||||
if (unsetSelectedObject) {
|
||||
if (unsetSelectedMapObject) {
|
||||
assetManagerStore.setSelectedMapObject(null)
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import MapObjects from '@/components/gameMaster/mapEditor/mapPartials/MapObjects
|
||||
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
|
||||
import MapList from '@/components/gameMaster/mapEditor/partials/MapList.vue'
|
||||
import MapSettings from '@/components/gameMaster/mapEditor/partials/MapSettings.vue'
|
||||
import ObjectList from '@/components/gameMaster/mapEditor/partials/ObjectList.vue'
|
||||
import ObjectList from '@/components/gameMaster/mapEditor/partials/MapObjectList.vue'
|
||||
import TeleportModal from '@/components/gameMaster/mapEditor/partials/TeleportModal.vue'
|
||||
import TileList from '@/components/gameMaster/mapEditor/partials/TileList.vue'
|
||||
// Components
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<SelectedMapObject v-if="selectedMapObject" :mapObject="selectedMapObject" :movingMapObject="movingMapObject" @move="moveMapObject" @rotate="rotateMapObject" @delete="deleteMapObject" />
|
||||
<MapObject v-for="mapObject in mapEditorStore.map?.mapObjects" :tilemap="tilemap" :mapObject :selectedMapObject :movingMapObject @pointerup="clickMapObject(mapObject)" />
|
||||
<MapObject v-for="mapObject in mapEditorStore.map?.placedMapObjects" :tilemap="tilemap" :mapObject :selectedMapObject :movingMapObject @pointerup="clickMapObject(mapObject)" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -33,7 +33,7 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
||||
if (mapEditorStore.drawMode !== 'object') return
|
||||
|
||||
// Check if there is a selected object
|
||||
if (!mapEditorStore.selectedObject) return
|
||||
if (!mapEditorStore.selectedMapObject) return
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown) return
|
||||
@ -56,8 +56,8 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
||||
id: uuidv4(),
|
||||
mapId: mapEditorStore.map.id,
|
||||
map: mapEditorStore.map,
|
||||
objectId: mapEditorStore.selectedObject.id,
|
||||
object: mapEditorStore.selectedObject,
|
||||
objectId: mapEditorStore.selectedMapObject.id,
|
||||
object: mapEditorStore.selectedMapObject,
|
||||
depth: 0,
|
||||
isRotated: false,
|
||||
positionX: tile.x,
|
||||
@ -123,11 +123,11 @@ function objectPicker(pointer: Phaser.Input.Pointer) {
|
||||
if (!tile) return
|
||||
|
||||
// Check if object already exists on position
|
||||
const existingObject = mapEditorStore.map.placedMapObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y)
|
||||
if (!existingObject) return
|
||||
const existingMapObject = mapEditorStore.map.placedMapObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y)
|
||||
if (!existingMapObject) return
|
||||
|
||||
// Select the object
|
||||
mapEditorStore.setSelectedObject(existingObject)
|
||||
mapEditorStore.setSelectedMapObject(existingMapObject)
|
||||
}
|
||||
|
||||
function moveMapObject(id: string) {
|
||||
@ -184,7 +184,7 @@ function clickMapObject(mapObject: MapObjectT) {
|
||||
|
||||
// If alt is pressed, select the object
|
||||
if (scene.input.activePointer.event.altKey) {
|
||||
mapEditorStore.setSelectedObject(mapObject.object)
|
||||
mapEditorStore.setSelectedMapObject(mapObject.mapObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,20 +204,20 @@ onUnmounted(() => {
|
||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, objectPicker)
|
||||
})
|
||||
|
||||
// watch mapEditorStore.objectList and update originX and originY of objects in mapObjects
|
||||
// watch mapEditorStore.mapObjectList and update originX and originY of objects in mapObjects
|
||||
watch(
|
||||
() => mapEditorStore.objectList,
|
||||
() => mapEditorStore.mapObjectList,
|
||||
(newObjects) => {
|
||||
if (!mapEditorStore.map) return
|
||||
|
||||
console.log(mapEditorStore.map.placedMapObjects)
|
||||
const updatedMapObjects = mapEditorStore.map.placedMapObjects.map((mapObject) => {
|
||||
const updatedObject = newObjects.find((obj) => obj.id === mapObject.object.id)
|
||||
const updatedObject = newObjects.find((obj) => obj.id === mapObject.mapObject.id)
|
||||
if (updatedObject) {
|
||||
return {
|
||||
...mapObject,
|
||||
object: {
|
||||
...mapObject.object,
|
||||
...mapObject.mapObject,
|
||||
originX: updatedObject.originX,
|
||||
originY: updatedObject.originY
|
||||
}
|
||||
@ -232,12 +232,12 @@ watch(
|
||||
mapObjects: updatedMapObjects
|
||||
})
|
||||
|
||||
// Update selectedObject if it's set
|
||||
if (mapEditorStore.selectedObject) {
|
||||
const updatedObject = newObjects.find((obj) => obj.id === mapEditorStore.selectedObject?.id)
|
||||
// Update selectedMapObject if it's set
|
||||
if (mapEditorStore.selectedMapObject) {
|
||||
const updatedObject = newObjects.find((obj) => obj.id === mapEditorStore.selectedMapObject?.id)
|
||||
if (updatedObject) {
|
||||
mapEditorStore.setSelectedObject({
|
||||
...mapEditorStore.selectedObject,
|
||||
mapEditorStore.setSelectedMapObject({
|
||||
...mapEditorStore.selectedMapObject,
|
||||
originX: updatedObject.originX,
|
||||
originY: updatedObject.originY
|
||||
})
|
||||
|
@ -26,7 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Map } from '@/application/types'
|
||||
import type { Map, UUID } from '@/application/types'
|
||||
import CreateMap from '@/components/gameMaster/mapEditor/partials/CreateMap.vue'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -46,14 +46,14 @@ function fetchMaps() {
|
||||
})
|
||||
}
|
||||
|
||||
function loadMap(id: number) {
|
||||
function loadMap(id: UUID) {
|
||||
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
|
||||
mapEditorStore.setMap(response)
|
||||
})
|
||||
mapEditorStore.toggleMapListModal()
|
||||
}
|
||||
|
||||
function deleteMap(id: number) {
|
||||
function deleteMap(id: UUID) {
|
||||
gameStore.connection?.emit('gm:map:delete', { mapId: id }, () => {
|
||||
fetchMaps()
|
||||
})
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :isModalOpen="mapEditorStore.isObjectListModalShown" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditorStore.isObjectListModalShown = false)" :bg-style="'none'">
|
||||
<Modal :isModalOpen="mapEditorStore.isMapObjectListModalShown" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditorStore.isMapObjectListModalShown = false)" :bg-style="'none'">
|
||||
<template #modalHeader>
|
||||
<h3 class="text-lg text-white">Objects</h3>
|
||||
</template>
|
||||
@ -20,16 +20,16 @@
|
||||
</div>
|
||||
<div class="h-full overflow-auto">
|
||||
<div class="flex justify-between flex-wrap gap-2.5 items-center">
|
||||
<div v-for="(object, index) in filteredObjects" :key="index" class="max-w-1/4 inline-block">
|
||||
<div v-for="(mapObject, index) in filteredMapObjects" :key="index" class="max-w-1/4 inline-block">
|
||||
<img
|
||||
class="border-2 border-solid max-w-full"
|
||||
:src="`${config.server_endpoint}/assets/objects/${object.id}.png`"
|
||||
:src="`${config.server_endpoint}/assets/objects/${mapObject.id}.png`"
|
||||
alt="Object"
|
||||
@click="mapEditorStore.setSelectedObject(object)"
|
||||
@click="mapEditorStore.setSelectedMapObject(mapObject)"
|
||||
:class="{
|
||||
'cursor-pointer transition-all duration-300': true,
|
||||
'border-cyan shadow-lg scale-105': mapEditorStore.selectedObject?.id === object.id,
|
||||
'border-transparent hover:border-gray-300': mapEditorStore.selectedObject?.id !== object.id
|
||||
'border-cyan shadow-lg scale-105': mapEditorStore.selectedMapObject?.id === mapObject.id,
|
||||
'border-transparent hover:border-gray-300': mapEditorStore.selectedMapObject?.id !== mapObject.id
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import type { MapObject, PlacedMapObject } from '@/application/types'
|
||||
import type { MapObject } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
@ -55,12 +55,12 @@ const searchQuery = ref('')
|
||||
const selectedTags = ref<string[]>([])
|
||||
|
||||
const uniqueTags = computed(() => {
|
||||
const allTags = mapEditorStore.objectList.flatMap((obj) => obj.tags || [])
|
||||
const allTags = mapEditorStore.mapObjectList.flatMap((obj) => obj.tags || [])
|
||||
return Array.from(new Set(allTags))
|
||||
})
|
||||
|
||||
const filteredObjects = computed(() => {
|
||||
return mapEditorStore.objectList.filter((object) => {
|
||||
const filteredMapObjects = computed(() => {
|
||||
return mapEditorStore.mapObjectList.filter((object) => {
|
||||
const matchesSearch = !searchQuery.value || object.name.toLowerCase().includes(searchQuery.value.toLowerCase())
|
||||
const matchesTags = selectedTags.value.length === 0 || (object.tags && selectedTags.value.some((tag) => object.tags.includes(tag)))
|
||||
return matchesSearch && matchesTags
|
||||
@ -77,7 +77,7 @@ const toggleTag = (tag: string) => {
|
||||
|
||||
onMounted(async () => {
|
||||
isModalOpen.value = true
|
||||
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
|
||||
gameStore.connection?.emit('', {}, (response: MapObject[]) => {
|
||||
mapEditorStore.setMapObjectList(response)
|
||||
})
|
||||
})
|
@ -33,7 +33,7 @@ export const useAssetManagerStore = defineStore('assetManager', () => {
|
||||
mapObjectList.value = objects
|
||||
}
|
||||
|
||||
function setSelectedObject(object: MapObject | null) {
|
||||
function setSelectedMapObject(object: MapObject | null) {
|
||||
selectedMapObject.value = object
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ export const useAssetManagerStore = defineStore('assetManager', () => {
|
||||
setSelectedTile,
|
||||
setMapObjectList,
|
||||
setCharacterTypeList,
|
||||
setSelectedMapObject: setSelectedObject,
|
||||
setSelectedMapObject: setSelectedMapObject,
|
||||
setSpriteList,
|
||||
setSelectedSprite,
|
||||
setSelectedCharacterType,
|
||||
|
@ -21,7 +21,7 @@ export const useMapEditorStore = defineStore('mapEditor', {
|
||||
tileList: [] as Tile[],
|
||||
mapObjectList: [] as MapObject[],
|
||||
selectedTile: '',
|
||||
selectedObject: null as MapObject | null,
|
||||
selectedMapObject: null as MapObject | null,
|
||||
isTileListModalShown: false,
|
||||
isMapObjectListModalShown: false,
|
||||
isMapListModalShown: false,
|
||||
@ -91,8 +91,8 @@ export const useMapEditorStore = defineStore('mapEditor', {
|
||||
setSelectedTile(tile: string) {
|
||||
this.selectedTile = tile
|
||||
},
|
||||
setSelectedObject(object: MapObject) {
|
||||
this.selectedObject = object
|
||||
setSelectedMapObject(object: MapObject) {
|
||||
this.selectedMapObject = object
|
||||
},
|
||||
toggleSettingsModal() {
|
||||
this.isSettingsModalShown = !this.isSettingsModalShown
|
||||
@ -122,7 +122,7 @@ export const useMapEditorStore = defineStore('mapEditor', {
|
||||
this.tool = 'move'
|
||||
this.drawMode = 'tile'
|
||||
this.selectedTile = ''
|
||||
this.selectedObject = null
|
||||
this.selectedMapObject = null
|
||||
this.isTileListModalShown = false
|
||||
this.isMapObjectListModalShown = false
|
||||
this.isSettingsModalShown = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user