Refactoring of modalShown booleans
This commit is contained in:
parent
14aa696197
commit
791830fd6f
12
src/App.vue
12
src/App.vue
@ -2,7 +2,7 @@
|
|||||||
<Debug />
|
<Debug />
|
||||||
<Notifications />
|
<Notifications />
|
||||||
<BackgroundImageLoader />
|
<BackgroundImageLoader />
|
||||||
<GmPanel v-if="gameStore.character?.role === 'gm'" />
|
<GmPanel v-if="gameStore.character?.role === 'gm'" @open-map-editor="isEditorShown = true"/>
|
||||||
<component :is="currentScreen" />
|
<component :is="currentScreen" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -17,24 +17,26 @@ import BackgroundImageLoader from '@/components/utilities/BackgroundImageLoader.
|
|||||||
import Debug from '@/components/utilities/Debug.vue'
|
import Debug from '@/components/utilities/Debug.vue'
|
||||||
import Notifications from '@/components/utilities/Notifications.vue'
|
import Notifications from '@/components/utilities/Notifications.vue'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||||
|
import { computed, ref, useTemplateRef, watch } from 'vue'
|
||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { computed, watch } from 'vue'
|
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const mapEditor = useMapEditorComposable()
|
|
||||||
|
const isEditorShown = ref(false)
|
||||||
|
|
||||||
const currentScreen = computed(() => {
|
const currentScreen = computed(() => {
|
||||||
if (!gameStore.game.isLoaded) return Loading
|
if (!gameStore.game.isLoaded) return Loading
|
||||||
if (!gameStore.connection) return Login
|
if (!gameStore.connection) return Login
|
||||||
if (!gameStore.token) return Login
|
if (!gameStore.token) return Login
|
||||||
if (!gameStore.character) return Characters
|
if (!gameStore.character) return Characters
|
||||||
if (mapEditor.active.value) return MapEditor
|
if (isEditorShown.value) return MapEditor
|
||||||
return Game
|
return Game
|
||||||
})
|
})
|
||||||
|
|
||||||
// Watch mapEditor.active and empty gameStore.game.loadedAssets
|
// Watch mapEditor.active and empty gameStore.game.loadedAssets
|
||||||
watch(
|
watch(
|
||||||
() => mapEditor.active.value,
|
() => isEditorShown.value,
|
||||||
() => {
|
() => {
|
||||||
gameStore.game.loadedTextures = []
|
gameStore.game.loadedTextures = []
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ export type Map = {
|
|||||||
name: string
|
name: string
|
||||||
width: number
|
width: number
|
||||||
height: number
|
height: number
|
||||||
tiles: any | null
|
tiles: string[][]
|
||||||
pvp: boolean
|
pvp: boolean
|
||||||
mapEffects: MapEffect[]
|
mapEffects: MapEffect[]
|
||||||
mapEventTiles: MapEventTile[]
|
mapEventTiles: MapEventTile[]
|
||||||
@ -105,7 +105,7 @@ export enum MapEventTileType {
|
|||||||
|
|
||||||
export type MapEventTile = {
|
export type MapEventTile = {
|
||||||
id: UUID
|
id: UUID
|
||||||
map: Map
|
mapId: UUID
|
||||||
type: MapEventTileType
|
type: MapEventTileType
|
||||||
positionX: number
|
positionX: number
|
||||||
positionY: number
|
positionY: number
|
||||||
|
@ -147,9 +147,11 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
let character = props.mapCharacter.character
|
||||||
|
|
||||||
const characterTypeStorage = new CharacterTypeStorage()
|
const characterTypeStorage = new CharacterTypeStorage()
|
||||||
|
|
||||||
const spriteId = await characterTypeStorage.getSpriteId(props.mapCharacter.character.characterType!)
|
const spriteId = await characterTypeStorage.getSpriteId(character.characterType!)
|
||||||
if (!spriteId) return
|
if (!spriteId) return
|
||||||
|
|
||||||
charSpriteId.value = spriteId
|
charSpriteId.value = spriteId
|
||||||
@ -161,14 +163,14 @@ onMounted(async () => {
|
|||||||
|
|
||||||
charContainer.value!.setName(props.mapCharacter.character!.name)
|
charContainer.value!.setName(props.mapCharacter.character!.name)
|
||||||
|
|
||||||
if (props.mapCharacter.character.id === gameStore.character!.id) {
|
if (character.id === gameStore.character!.id) {
|
||||||
mapStore.setCharacterLoaded(true)
|
mapStore.setCharacterLoaded(true)
|
||||||
|
|
||||||
// #146 : Set camera position to character, need to be improved still
|
// #146 : Set camera position to character, need to be improved still
|
||||||
scene.cameras.main.startFollow(charContainer.value as Phaser.GameObjects.Container)
|
scene.cameras.main.startFollow(charContainer.value as Phaser.GameObjects.Container)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePosition(props.mapCharacter.character.positionX, props.mapCharacter.character.positionY, props.mapCharacter.character.rotation)
|
updatePosition(character.positionX, character.positionY, character.rotation)
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import config from '@/application/config'
|
import config from '@/application/config'
|
||||||
import type { UUID } from '@/application/types'
|
import type { UUID, Map as MapT} from '@/application/types'
|
||||||
import { unduplicateArray } from '@/application/utilities'
|
import { unduplicateArray } from '@/application/utilities'
|
||||||
import Controls from '@/components/utilities/Controls.vue'
|
import Controls from '@/components/utilities/Controls.vue'
|
||||||
import { FlattenMapArray, loadMapTilesIntoScene, setLayerTiles } from '@/composables/mapComposable'
|
import { loadMapTilesIntoScene, setLayerTiles } from '@/composables/mapComposable'
|
||||||
import { MapStorage } from '@/storage/storages'
|
import { MapStorage } from '@/storage/storages'
|
||||||
import { useMapStore } from '@/stores/mapStore'
|
import { useMapStore } from '@/stores/mapStore'
|
||||||
import { useScene } from 'phavuer'
|
import { useScene } from 'phavuer'
|
||||||
@ -23,10 +23,10 @@ const mapStorage = new MapStorage()
|
|||||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||||
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||||
|
|
||||||
function createTileMap(mapData: any) {
|
function createTileMap(map: MapT) {
|
||||||
const mapConfig = new Phaser.Tilemaps.MapData({
|
const mapConfig = new Phaser.Tilemaps.MapData({
|
||||||
width: mapData?.width,
|
width: map.width,
|
||||||
height: mapData?.height,
|
height: map.height,
|
||||||
tileWidth: config.tile_size.width,
|
tileWidth: config.tile_size.width,
|
||||||
tileHeight: config.tile_size.height,
|
tileHeight: config.tile_size.height,
|
||||||
orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
|
orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
|
||||||
@ -39,7 +39,7 @@ function createTileMap(mapData: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap, mapData: any) {
|
function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap, mapData: any) {
|
||||||
const tilesArray = unduplicateArray(FlattenMapArray(mapData?.tiles ?? []))
|
const tilesArray = unduplicateArray(mapData?.tiles.flat())
|
||||||
|
|
||||||
const tilesetImages = tilesArray.map((tile: string, index: number) => {
|
const tilesetImages = tilesArray.map((tile: string, index: number) => {
|
||||||
return currentTileMap.addTilesetImage(tile, tile, config.tile_size.width, config.tile_size.height, 1, 2, index + 1, { x: 0, y: -config.tile_size.height })
|
return currentTileMap.addTilesetImage(tile, tile, config.tile_size.width, config.tile_size.height, 1, 2, index + 1, { x: 0, y: -config.tile_size.height })
|
||||||
@ -58,9 +58,10 @@ function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap, mapData: any)
|
|||||||
loadMapTilesIntoScene(mapStore.mapId as UUID, scene)
|
loadMapTilesIntoScene(mapStore.mapId as UUID, scene)
|
||||||
.then(() => mapStorage.get(mapStore.mapId))
|
.then(() => mapStorage.get(mapStore.mapId))
|
||||||
.then((mapData) => {
|
.then((mapData) => {
|
||||||
|
if (!mapData || !mapData?.tiles) return
|
||||||
tileMap.value = createTileMap(mapData)
|
tileMap.value = createTileMap(mapData)
|
||||||
tileLayer.value = createTileLayer(tileMap.value, mapData)
|
tileLayer.value = createTileLayer(tileMap.value, mapData)
|
||||||
setLayerTiles(tileMap.value, tileLayer.value, mapData?.tiles)
|
setLayerTiles(tileMap.value, tileLayer.value, mapData.tiles)
|
||||||
})
|
})
|
||||||
.catch((error) => console.error('Failed to initialize map:', error))
|
.catch((error) => console.error('Failed to initialize map:', error))
|
||||||
|
|
||||||
|
@ -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">Users</button>
|
||||||
<button @mousedown.stop class="btn-cyan py-1.5 px-4 min-w-24">Chats</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 @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="() => mapEditor.toggleActive()">Map editor</button>
|
<button class="btn-cyan py-1.5 px-4 min-w-24" type="button" @click="$emit('open-map-editor')">Map editor</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #modalBody>
|
<template #modalBody>
|
||||||
@ -24,6 +24,7 @@ import { useGameStore } from '@/stores/gameStore'
|
|||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineEmits(['open-map-editor'])
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<MapTiles @tileMap:create="tileMap = $event" />
|
<MapTiles ref="mapTiles" :tileMap="tileMap" @tileMap:create="tileMap = $event" />
|
||||||
<PlacedMapObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
|
<PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMap="tileMap as Phaser.Tilemaps.Tilemap" />
|
||||||
<MapEventTiles v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
|
<MapEventTiles ref="eventTiles" v-if="tileMap" :tileMap="tileMap as Phaser.Tilemaps.Tilemap" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import config from '@/application/config'
|
||||||
|
import type { Map as MapT } from '@/application/types'
|
||||||
import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEventTiles.vue'
|
import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEventTiles.vue'
|
||||||
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
|
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
|
||||||
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
|
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
|
||||||
@ -14,6 +16,50 @@ import { onMounted, onUnmounted, shallowRef } from 'vue'
|
|||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||||
|
|
||||||
|
const selectedMap = ref<MapT>()
|
||||||
|
const mapEditorStore = useMapEditorStore()
|
||||||
|
const mapEditor = useMapEditorComposable()
|
||||||
|
|
||||||
|
const mapTiles = useTemplateRef('mapTiles')
|
||||||
|
const mapObjects = useTemplateRef('mapObjects')
|
||||||
|
const eventTiles = useTemplateRef('eventTiles')
|
||||||
|
|
||||||
|
const scene = useScene()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||||
|
if (!mapTiles.value || !mapObjects.value || !eventTiles.value) 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 draw mode is tile
|
||||||
|
switch (mapEditorStore.drawMode) {
|
||||||
|
case 'tile':
|
||||||
|
mapTiles.value.handlePointer(pointer)
|
||||||
|
// case 'map_object':
|
||||||
|
// mapObjects.value.handlePointer(pointer)
|
||||||
|
case 'event tile':
|
||||||
|
eventTiles.value.handlePointer(pointer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => mapEditor.currentMap, async (map) => {
|
||||||
|
if (!map.value) return
|
||||||
|
selectedMap.value = map.value
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointer)
|
||||||
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointer)
|
||||||
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
mapEditor.reset()
|
mapEditor.reset()
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Image v-for="tile in mapEditorStore.map?.mapEventTiles" v-bind="getImageProps(tile)" />
|
<Image v-for="tile in mapEditor.currentMap.value?.mapEventTiles" v-bind="getImageProps(tile)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -8,62 +8,55 @@ import { uuidv4 } from '@/application/utilities'
|
|||||||
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/mapComposable'
|
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/mapComposable'
|
||||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||||
import { Image, useScene } from 'phavuer'
|
import { Image, useScene } from 'phavuer'
|
||||||
import { onMounted, onUnmounted } from 'vue'
|
import { type Map as MapT } from "@/application/types"
|
||||||
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
|
import { shallowRef, watch } from 'vue'
|
||||||
|
|
||||||
const scene = useScene()
|
|
||||||
const mapEditorStore = useMapEditorStore()
|
const mapEditorStore = useMapEditorStore()
|
||||||
|
const mapEditor = useMapEditorComposable()
|
||||||
|
|
||||||
|
defineExpose({handlePointer})
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tilemap: Phaser.Tilemaps.Tilemap
|
tileMap: Phaser.Tilemaps.Tilemap
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||||
|
|
||||||
function getImageProps(tile: MapEventTile) {
|
function getImageProps(tile: MapEventTile) {
|
||||||
return {
|
return {
|
||||||
x: tileToWorldX(props.tilemap, tile.positionX, tile.positionY),
|
x: tileToWorldX(props.tileMap, tile.positionX, tile.positionY),
|
||||||
y: tileToWorldY(props.tilemap, tile.positionX, tile.positionY),
|
y: tileToWorldY(props.tileMap, tile.positionX, tile.positionY),
|
||||||
texture: tile.type,
|
texture: tile.type,
|
||||||
depth: 999
|
depth: 999
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pencil(pointer: Phaser.Input.Pointer) {
|
function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||||
// Check if map is set
|
if (!tileLayer.value) return
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditorStore.tool !== 'pencil') return
|
|
||||||
|
|
||||||
// Check if draw mode is blocking tile or teleport
|
|
||||||
if (mapEditorStore.drawMode !== 'blocking tile' && mapEditorStore.drawMode !== 'teleport') 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 there is a tile
|
// Check if there is a tile
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Check if event tile already exists on position
|
// Check if event tile already exists on position
|
||||||
const existingEventTile = mapEditorStore.map.mapEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
|
const existingEventTile = map.mapEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
|
||||||
if (existingEventTile) return
|
if (existingEventTile) return
|
||||||
|
|
||||||
// If teleport, check if there is a selected map
|
// If teleport, check if there is a selected map
|
||||||
if (mapEditorStore.drawMode === 'teleport' && !mapEditorStore.teleportSettings.toMap) return
|
if (mapEditorStore.drawMode === 'teleport' && !mapEditorStore.teleportSettings.toMapId) return
|
||||||
|
|
||||||
const newEventTile = {
|
const newEventTile = {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
mapId: mapEditorStore.map.id,
|
mapId: map?.id,
|
||||||
map: mapEditorStore.map,
|
map: map?.id,
|
||||||
type: mapEditorStore.drawMode === 'blocking tile' ? MapEventTileType.BLOCK : MapEventTileType.TELEPORT,
|
type: mapEditorStore.drawMode === 'blocking tile' ? MapEventTileType.BLOCK : MapEventTileType.TELEPORT,
|
||||||
positionX: tile.x,
|
positionX: tile.x,
|
||||||
positionY: tile.y,
|
positionY: tile.y,
|
||||||
teleport:
|
teleport:
|
||||||
mapEditorStore.drawMode === 'teleport'
|
mapEditorStore.drawMode === 'teleport'
|
||||||
? {
|
? {
|
||||||
toMap: mapEditorStore.teleportSettings.toMap,
|
toMap: mapEditorStore.teleportSettings.toMapId,
|
||||||
toPositionX: mapEditorStore.teleportSettings.toPositionX,
|
toPositionX: mapEditorStore.teleportSettings.toPositionX,
|
||||||
toPositionY: mapEditorStore.teleportSettings.toPositionY,
|
toPositionY: mapEditorStore.teleportSettings.toPositionY,
|
||||||
toRotation: mapEditorStore.teleportSettings.toRotation
|
toRotation: mapEditorStore.teleportSettings.toRotation
|
||||||
@ -71,18 +64,26 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
|||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
mapEditorStore.map.mapEventTiles = mapEditorStore.map.mapEventTiles.concat(newEventTile as MapEventTile)
|
map!.mapEventTiles = map!.mapEventTiles.concat(newEventTile as MapEventTile)
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraser(pointer: Phaser.Input.Pointer) {
|
function erase(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||||
// Check if map is set
|
if (!tileLayer.value) return
|
||||||
if (!mapEditorStore.map) return
|
// Check if there is a tile
|
||||||
|
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
||||||
|
if (!tile) return
|
||||||
|
|
||||||
// Check if tool is pencil
|
// Check if event tile already exists on position
|
||||||
if (mapEditorStore.tool !== 'eraser') return
|
const existingEventTile = map.mapEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
|
||||||
|
if (!existingEventTile) return
|
||||||
|
|
||||||
// Check if draw mode is blocking tile or teleport
|
// Remove existing event tile
|
||||||
if (mapEditorStore.eraserMode !== 'blocking tile' && mapEditorStore.eraserMode !== 'teleport') return
|
map.mapEventTiles = map.mapEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||||
|
const map = mapEditor.currentMap.value
|
||||||
|
if (!map) return
|
||||||
|
|
||||||
// Check if left mouse button is pressed
|
// Check if left mouse button is pressed
|
||||||
if (!pointer.isDown) return
|
if (!pointer.isDown) return
|
||||||
@ -90,29 +91,12 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
|||||||
// Check if shift is not pressed, this means we are moving the camera
|
// Check if shift is not pressed, this means we are moving the camera
|
||||||
if (pointer.event.shiftKey) return
|
if (pointer.event.shiftKey) return
|
||||||
|
|
||||||
// Check if there is a tile
|
if (mapEditorStore.drawMode !== 'blocking tile' && mapEditorStore.drawMode !== 'teleport') return
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
|
||||||
if (!tile) return
|
|
||||||
|
|
||||||
// Check if event tile already exists on position
|
switch (mapEditorStore.tool) {
|
||||||
const existingEventTile = mapEditorStore.map.mapEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
|
case 'pencil': pencil(pointer, map)
|
||||||
if (!existingEventTile) return
|
case 'eraser': erase(pointer, map)
|
||||||
|
}
|
||||||
// Remove existing event tile
|
|
||||||
mapEditorStore.map.mapEventTiles = mapEditorStore.map.mapEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -22,6 +22,8 @@ const tileStorage = new TileStorage()
|
|||||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||||
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||||
|
|
||||||
|
defineExpose({handlePointer})
|
||||||
|
|
||||||
function createTileMap() {
|
function createTileMap() {
|
||||||
const mapData = new Phaser.Tilemaps.MapData({
|
const mapData = new Phaser.Tilemaps.MapData({
|
||||||
width: mapEditor.currentMap.value?.width,
|
width: mapEditor.currentMap.value?.width,
|
||||||
@ -32,9 +34,7 @@ function createTileMap() {
|
|||||||
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
||||||
})
|
})
|
||||||
|
|
||||||
const newTileMap = new Phaser.Tilemaps.Tilemap(scene, mapData)
|
return new Phaser.Tilemaps.Tilemap(scene, mapData)
|
||||||
emit('tileMap:create', newTileMap)
|
|
||||||
return newTileMap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap) {
|
async function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap) {
|
||||||
@ -55,111 +55,81 @@ async function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap) {
|
|||||||
return layer
|
return layer
|
||||||
}
|
}
|
||||||
|
|
||||||
function pencil(pointer: Phaser.Input.Pointer) {
|
function pencil(pointer: Phaser.Input.Pointer, tileMap: Phaser.Tilemaps.Tilemap, tileLayer: Phaser.Tilemaps.TilemapLayer) {
|
||||||
if (!tileMap.value || !tileLayer.value) return
|
var map = mapEditor.currentMap.value
|
||||||
|
if (!map) return
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditor.currentMap.value) return
|
|
||||||
console.log(mapEditor.tool.value)
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditor.tool.value !== 'pencil') return
|
|
||||||
|
|
||||||
// Check if draw mode is tile
|
|
||||||
if (mapEditor.drawMode.value !== 'tile') return
|
|
||||||
|
|
||||||
// Check if there is a selected tile
|
|
||||||
if (!mapEditor.selectedTile.value) return // Changed this line to access .value
|
|
||||||
|
|
||||||
// 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 there is a tile
|
// Check if there is a tile
|
||||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
const tile = tileLayer.getTileAtWorldXY(pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Place tile
|
// Place tile
|
||||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, mapEditor.selectedTile.value)
|
placeTile(tileMap, tileLayer, tile.x, tile.y, mapEditorStore.selectedTile)
|
||||||
|
|
||||||
// Adjust mapEditor tiles
|
// Adjust mapEditorStore.map.tiles
|
||||||
mapEditor.currentMap.value.tiles[tile.y][tile.x] = mapEditor.selectedTile.value
|
tileMap.tiles[tile.y][tile.x] = map.tiles[tile.y][tile.x]
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraser(pointer: Phaser.Input.Pointer) {
|
function eraser(pointer: Phaser.Input.Pointer, tileMap: Phaser.Tilemaps.Tilemap, tileLayer: Phaser.Tilemaps.TilemapLayer) {
|
||||||
if (!tileMap.value || !tileLayer.value) return
|
let map = mapEditor.currentMap.value
|
||||||
|
if (!map) return
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditor.currentMap.value) return
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditor.tool.value !== 'eraser') return
|
|
||||||
|
|
||||||
// Check if draw mode is tile
|
|
||||||
if (mapEditor.eraserMode.value !== '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
|
// Check if there is a tile
|
||||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileLayer, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Place tile
|
// Place tile
|
||||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, 'blank_tile')
|
placeTile(tileMap, tileLayer, tile.x, tile.y, 'blank_tile')
|
||||||
|
|
||||||
// Adjust mapEditor.map.tiles
|
// Adjust mapEditorStore.map.tiles
|
||||||
mapEditor.currentMap.value.tiles[tile.y][tile.x] = 'blank_tile'
|
map.tiles[tile.y][tile.x] = 'blank_tile'
|
||||||
}
|
}
|
||||||
|
|
||||||
function paint(pointer: Phaser.Input.Pointer) {
|
function paint(pointer: Phaser.Input.Pointer, tileMap: Phaser.Tilemaps.Tilemap, tileLayer: Phaser.Tilemaps.TilemapLayer) {
|
||||||
if (!tileMap.value || !tileLayer.value) return
|
|
||||||
|
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditor.currentMap.value) return
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditor.tool.value !== 'paint') return
|
|
||||||
|
|
||||||
// Check if there is a selected tile
|
|
||||||
if (!mapEditor.selectedTile.value) 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
|
|
||||||
|
|
||||||
// Set new tileArray with selected tile
|
// Set new tileArray with selected tile
|
||||||
setLayerTiles(tileMap.value, tileLayer.value, createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value))
|
setLayerTiles(tileMap, tileLayer, createTileArray(tileMap.width, tileMap.height, mapEditorStore.selectedTile))
|
||||||
|
|
||||||
// Adjust mapEditor.map.tiles
|
// Adjust mapEditorStore.map.tiles
|
||||||
mapEditor.currentMap.value.tiles = createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value)
|
if (mapEditor.currentMap.value) {
|
||||||
|
mapEditor.currentMap.value.tiles = createTileArray(tileMap.width, tileMap.height, mapEditorStore.selectedTile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When alt is pressed, and the pointer is down, select the tile that the pointer is over
|
// When alt is pressed, and the pointer is down, select the tile that the pointer is over
|
||||||
function tilePicker(pointer: Phaser.Input.Pointer) {
|
function tilePicker(pointer: Phaser.Input.Pointer, tileLayer: Phaser.Tilemaps.TilemapLayer) {
|
||||||
if (!tileMap.value || !tileLayer.value) return
|
let map = mapEditor.currentMap.value
|
||||||
|
if (!map) return
|
||||||
|
|
||||||
// Check if map is set
|
// Check if there is a tile
|
||||||
|
const tile = getTile(tileLayer, pointer.worldX, pointer.worldY)
|
||||||
|
if (!tile) return
|
||||||
|
|
||||||
|
// Select the tile
|
||||||
|
mapEditorStore.setSelectedTile(map.tiles[tile.y][tile.x])
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => mapEditorStore.shouldClearTiles,
|
||||||
|
(shouldClear) => {
|
||||||
|
if (shouldClear && mapEditor.currentMap.value && tileMap.value && tileLayer.value) {
|
||||||
|
const blankTiles = createTileArray(tileLayer.value.width, tileLayer.value.height, 'blank_tile')
|
||||||
|
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
||||||
|
mapEditor.currentMap.value.tiles = blankTiles
|
||||||
|
mapEditorStore.resetClearTilesFlag()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||||
if (!mapEditor.currentMap.value) return
|
if (!mapEditor.currentMap.value) return
|
||||||
|
|
||||||
// Check if tool is pencil
|
if (!tileMap.value || !tileLayer.value) return
|
||||||
if (mapEditor.tool.value !== 'pencil') return
|
|
||||||
|
|
||||||
// Check if draw mode is tile
|
// Check if tool is pencil
|
||||||
if (mapEditor.drawMode.value !== 'tile') return
|
if (mapEditorStore.drawMode !== 'tile') return
|
||||||
|
|
||||||
|
// Check if there is a selected tile
|
||||||
|
if (!mapEditorStore.selectedTile) return
|
||||||
|
|
||||||
// Check if left mouse button is pressed
|
// Check if left mouse button is pressed
|
||||||
if (!pointer.isDown) return
|
if (!pointer.isDown) return
|
||||||
@ -170,25 +140,18 @@ function tilePicker(pointer: Phaser.Input.Pointer) {
|
|||||||
// Check if alt is pressed
|
// Check if alt is pressed
|
||||||
if (!pointer.event.altKey) return
|
if (!pointer.event.altKey) return
|
||||||
|
|
||||||
// Check if there is a tile
|
// Check if draw mode is tile
|
||||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
switch (mapEditorStore.tool) {
|
||||||
if (!tile) return
|
case 'pencil':
|
||||||
|
pencil(pointer, tileMap.value, tileLayer.value)
|
||||||
// Select the tile
|
case 'eraser':
|
||||||
mapEditor.setSelectedTile(mapEditor.currentMap.value.tiles[tile.y][tile.x])
|
eraser(pointer, tileMap.value, tileLayer.value)
|
||||||
}
|
case 'paint':
|
||||||
|
paint(pointer, tileMap.value, tileLayer.value)
|
||||||
watch(
|
case 'tile picker':
|
||||||
() => mapEditor.shouldClearTiles.value,
|
tilePicker(pointer, tileLayer.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
|
|
||||||
mapEditor.resetClearTilesFlag()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (!mapEditor.currentMap.value?.tiles) return
|
if (!mapEditor.currentMap.value?.tiles) return
|
||||||
@ -211,19 +174,9 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
||||||
|
|
||||||
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(() => {
|
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)
|
|
||||||
|
|
||||||
if (tileMap.value) {
|
if (tileMap.value) {
|
||||||
tileMap.value.destroyLayer('tiles')
|
tileMap.value.destroyLayer('tiles')
|
||||||
tileMap.value.removeAllLayers()
|
tileMap.value.removeAllLayers()
|
||||||
|
@ -11,7 +11,7 @@ import { Image, useScene } from 'phavuer'
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tilemap: Phaser.Tilemaps.Tilemap
|
tileMap: Phaser.Tilemaps.Tilemap
|
||||||
placedMapObject: PlacedMapObject
|
placedMapObject: PlacedMapObject
|
||||||
selectedPlacedMapObject: PlacedMapObject | null
|
selectedPlacedMapObject: PlacedMapObject | null
|
||||||
movingPlacedMapObject: PlacedMapObject | null
|
movingPlacedMapObject: PlacedMapObject | null
|
||||||
@ -24,8 +24,8 @@ const imageProps = computed(() => ({
|
|||||||
alpha: props.movingPlacedMapObject?.id === props.placedMapObject.id ? 0.5 : 1,
|
alpha: props.movingPlacedMapObject?.id === props.placedMapObject.id ? 0.5 : 1,
|
||||||
tint: props.selectedPlacedMapObject?.id === props.placedMapObject.id ? 0x00ff00 : 0xffffff,
|
tint: props.selectedPlacedMapObject?.id === props.placedMapObject.id ? 0x00ff00 : 0xffffff,
|
||||||
depth: calculateIsometricDepth(props.placedMapObject.positionX, props.placedMapObject.positionY, props.placedMapObject.mapObject.frameWidth, props.placedMapObject.mapObject.frameHeight),
|
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),
|
x: tileToWorldX(props.tileMap, props.placedMapObject.positionX, props.placedMapObject.positionY),
|
||||||
y: tileToWorldY(props.tilemap, props.placedMapObject.positionX, props.placedMapObject.positionY),
|
y: tileToWorldY(props.tileMap, props.placedMapObject.positionX, props.placedMapObject.positionY),
|
||||||
flipX: props.placedMapObject.isRotated,
|
flipX: props.placedMapObject.isRotated,
|
||||||
texture: props.placedMapObject.mapObject.id,
|
texture: props.placedMapObject.mapObject.id,
|
||||||
originY: Number(props.placedMapObject.mapObject.originX),
|
originY: Number(props.placedMapObject.mapObject.originX),
|
||||||
|
@ -1,142 +1,87 @@
|
|||||||
<template>
|
<template>
|
||||||
<SelectedPlacedMapObjectComponent v-if="selectedPlacedMapObject" :placedMapObject="selectedPlacedMapObject" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
<SelectedPlacedMapObjectComponent v-if="selectedPlacedMapObject" :placedMapObject="selectedPlacedMapObject" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
||||||
<PlacedMapObject v-for="placedMapObject in mapEditorStore.map?.placedMapObjects" :tilemap="tilemap" :placedMapObject :selectedPlacedMapObject :movingPlacedMapObject @pointerup="clickPlacedMapObject(placedMapObject)" />
|
<PlacedMapObject v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :tilemap="tileMap" :placedMapObject :selectedPlacedMapObject :movingPlacedMapObject @pointerup="clickPlacedMapObject(placedMapObject)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PlacedMapObject as PlacedMapObjectT } from '@/application/types'
|
import type { Map as MapT, PlacedMapObject as PlacedMapObjectT } from '@/application/types'
|
||||||
import { uuidv4 } from '@/application/utilities'
|
import { uuidv4 } from '@/application/utilities'
|
||||||
import PlacedMapObject from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObject.vue'
|
import PlacedMapObject from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObject.vue'
|
||||||
import SelectedPlacedMapObjectComponent from '@/components/gameMaster/mapEditor/partials/SelectedPlacedMapObject.vue'
|
import SelectedPlacedMapObjectComponent from '@/components/gameMaster/mapEditor/partials/SelectedPlacedMapObject.vue'
|
||||||
import { getTile } from '@/composables/mapComposable'
|
import { getTile } from '@/composables/mapComposable'
|
||||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||||
import { useScene } from 'phavuer'
|
import { useScene } from 'phavuer'
|
||||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
const mapEditorStore = useMapEditorStore()
|
const mapEditorStore = useMapEditorStore()
|
||||||
|
const mapEditor = useMapEditorComposable()
|
||||||
const selectedPlacedMapObject = ref<PlacedMapObjectT | null>(null)
|
const selectedPlacedMapObject = ref<PlacedMapObjectT | null>(null)
|
||||||
const movingPlacedMapObject = ref<PlacedMapObjectT | null>(null)
|
const movingPlacedMapObject = ref<PlacedMapObjectT | null>(null)
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tilemap: Phaser.Tilemaps.Tilemap
|
tileMap: Phaser.Tilemaps.Tilemap
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
function pencil(pointer: Phaser.Input.Pointer) {
|
defineExpose({handlePointer})
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditorStore.tool !== 'pencil') return
|
|
||||||
|
|
||||||
// Check if draw mode is map_object
|
|
||||||
if (mapEditorStore.drawMode !== 'map_object') return
|
|
||||||
|
|
||||||
// Check if there is a selected object
|
|
||||||
if (!mapEditorStore.selectedMapObject) 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, this means we are selecting the object
|
|
||||||
if (pointer.event.altKey) return
|
|
||||||
|
|
||||||
|
function pencil(pointer: Phaser.Input.Pointer, tileMapLayer: Phaser.Tilemaps.TilemapLayer, map: MapT) {
|
||||||
// Check if there is a tile
|
// Check if there is a tile
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileMapLayer, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Check if object already exists on position
|
// Check if object already exists on position
|
||||||
const existingPlacedMapObject = mapEditorStore.map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
const existingPlacedMapObject = map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
||||||
if (existingPlacedMapObject) return
|
if (existingPlacedMapObject) return
|
||||||
|
|
||||||
const newPlacedMapObject = {
|
const newPlacedMapObject: PlacedMapObjectT = {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
map: mapEditorStore.map,
|
depth: 0,
|
||||||
mapObject: mapEditorStore.selectedMapObject,
|
map: map,
|
||||||
|
mapObject: mapEditorStore.selectedMapObject!,
|
||||||
isRotated: false,
|
isRotated: false,
|
||||||
positionX: tile.x,
|
positionX: tile.x,
|
||||||
positionY: tile.y
|
positionY: tile.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new object to mapObjects
|
// Add new object to mapObjects
|
||||||
mapEditorStore.map.placedMapObjects = mapEditorStore.map.placedMapObjects.concat(newPlacedMapObject as PlacedMapObjectT)
|
map.placedMapObjects.concat(newPlacedMapObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraser(pointer: Phaser.Input.Pointer) {
|
function eraser(pointer: Phaser.Input.Pointer, tileMapLayer: Phaser.Tilemaps.TilemapLayer, map: MapT) {
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
// Check if tool is eraser
|
|
||||||
if (mapEditorStore.tool !== 'eraser') return
|
|
||||||
|
|
||||||
// Check if draw mode is map_object
|
|
||||||
if (mapEditorStore.eraserMode !== 'map_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
|
|
||||||
|
|
||||||
// Check if alt is pressed, this means we are selecting the object
|
|
||||||
if (pointer.event.altKey) return
|
|
||||||
|
|
||||||
// Check if there is a tile
|
// Check if there is a tile
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileMapLayer, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Check if object already exists on position
|
// Check if object already exists on position
|
||||||
const existingPlacedMapObject = mapEditorStore.map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
const existingPlacedMapObject = map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
||||||
if (!existingPlacedMapObject) return
|
if (!existingPlacedMapObject) return
|
||||||
|
|
||||||
// Remove existing object
|
// Remove existing object
|
||||||
mapEditorStore.map.placedMapObjects = mapEditorStore.map.placedMapObjects.filter((placedMapObject) => placedMapObject.id !== existingPlacedMapObject.id)
|
map.placedMapObjects = map.placedMapObjects.filter((placedMapObject) => placedMapObject.id !== existingPlacedMapObject.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
function objectPicker(pointer: Phaser.Input.Pointer) {
|
function objectPicker(pointer: Phaser.Input.Pointer, tileMapLayer: Phaser.Tilemaps.TilemapLayer, map: MapT) {
|
||||||
// Check if map is set
|
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
// Check if tool is pencil
|
|
||||||
if (mapEditorStore.tool !== 'pencil') return
|
|
||||||
|
|
||||||
// Check if draw mode is map_object
|
|
||||||
if (mapEditorStore.drawMode !== 'map_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
|
// Check if there is a tile
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileMapLayer, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
// Check if object already exists on position
|
// Check if object already exists on position
|
||||||
const existingPlacedMapObject = mapEditorStore.map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
const existingPlacedMapObject = map.placedMapObjects.find((placedMapObject) => placedMapObject.positionX === tile.x && placedMapObject.positionY === tile.y)
|
||||||
if (!existingPlacedMapObject) return
|
if (!existingPlacedMapObject) return
|
||||||
|
|
||||||
// Select the object
|
// Select the object
|
||||||
mapEditorStore.setSelectedMapObject(existingPlacedMapObject.mapObject)
|
mapEditorStore.setSelectedMapObject(existingPlacedMapObject.mapObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveMapObject(id: string) {
|
function moveMapObject(id: string, tileMapLayer: Phaser.Tilemaps.TilemapLayer, map: MapT) {
|
||||||
// Check if map is set
|
movingPlacedMapObject.value = map.placedMapObjects.find((object) => object.id === id) as PlacedMapObjectT
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
movingPlacedMapObject.value = mapEditorStore.map.placedMapObjects.find((object) => object.id === id) as PlacedMapObjectT
|
|
||||||
|
|
||||||
function handlePointerMove(pointer: Phaser.Input.Pointer) {
|
function handlePointerMove(pointer: Phaser.Input.Pointer) {
|
||||||
if (!movingPlacedMapObject.value) return
|
if (!movingPlacedMapObject.value) return
|
||||||
|
|
||||||
const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
|
const tile = getTile(tileMapLayer, pointer.worldX, pointer.worldY)
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
movingPlacedMapObject.value.positionX = tile.x
|
movingPlacedMapObject.value.positionX = tile.x
|
||||||
@ -153,11 +98,8 @@ function moveMapObject(id: string) {
|
|||||||
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotatePlacedMapObject(id: string) {
|
function rotatePlacedMapObject(id: string, map: MapT) {
|
||||||
// Check if map is set
|
map.placedMapObjects = map.placedMapObjects.map((placedMapObject) => {
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
mapEditorStore.map.placedMapObjects = mapEditorStore.map.placedMapObjects.map((placedMapObject) => {
|
|
||||||
if (placedMapObject.id === id) {
|
if (placedMapObject.id === id) {
|
||||||
return {
|
return {
|
||||||
...placedMapObject,
|
...placedMapObject,
|
||||||
@ -168,11 +110,8 @@ function rotatePlacedMapObject(id: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function deletePlacedMapObject(id: string) {
|
function deletePlacedMapObject(id: string, map: MapT) {
|
||||||
// Check if map is set
|
map.placedMapObjects = map.placedMapObjects.filter((object) => object.id !== id)
|
||||||
if (!mapEditorStore.map) return
|
|
||||||
|
|
||||||
mapEditorStore.map.placedMapObjects = mapEditorStore.map.placedMapObjects.filter((object) => object.id !== id)
|
|
||||||
selectedPlacedMapObject.value = null
|
selectedPlacedMapObject.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,37 +124,48 @@ function clickPlacedMapObject(placedMapObject: PlacedMapObjectT) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
function handlePointer(pointer: Phaser.Input.Pointer, tileMapLayer: Phaser.Tilemaps.TilemapLayer) {
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
|
const map = mapEditor.currentMap.value
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
if (!map) return
|
||||||
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(() => {
|
if (mapEditorStore.drawMode !== 'map_object') return
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
// Check if left mouse button is pressed
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
|
if (!pointer.isDown) return
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
|
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, objectPicker)
|
// 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 tool is pencil
|
||||||
|
switch (mapEditorStore.tool) {
|
||||||
|
case 'pencil':
|
||||||
|
if (mapEditorStore.selectedMapObject) pencil(pointer, tileMapLayer, map)
|
||||||
|
case 'eraser':
|
||||||
|
eraser(pointer, tileMapLayer, map)
|
||||||
|
case 'object picker':
|
||||||
|
objectPicker(pointer, tileMapLayer, map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// watch mapEditorStore.mapObjectList and update originX and originY of objects in mapObjects
|
// watch mapEditorStore.mapObjectList and update originX and originY of objects in mapObjects
|
||||||
watch(
|
watch(
|
||||||
() => mapEditorStore.mapObjectList,
|
() => mapEditor.currentMap.value,
|
||||||
(newMapObjects) => {
|
() => {
|
||||||
if (!mapEditorStore.map) return
|
const map = mapEditor.currentMap.value
|
||||||
|
if (!map) return
|
||||||
|
|
||||||
const updatedMapObjects = mapEditorStore.map.placedMapObjects.map((mapObject) => {
|
const updatedMapObjects = map.placedMapObjects.map((mapObject) => {
|
||||||
const updatedMapObject = newMapObjects.find((obj) => obj.id === mapObject.mapObject.id)
|
const updatedMapObject = map.placedMapObjects.find((obj) => obj.id === mapObject.mapObject.id)
|
||||||
if (updatedMapObject) {
|
if (updatedMapObject) {
|
||||||
return {
|
return {
|
||||||
...mapObject,
|
...mapObject,
|
||||||
mapObject: {
|
mapObject: {
|
||||||
...mapObject.mapObject,
|
...mapObject.mapObject,
|
||||||
originX: updatedMapObject.originX,
|
originX: updatedMapObject.positionX,
|
||||||
originY: updatedMapObject.originY
|
originY: updatedMapObject.positionY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,19 +173,16 @@ watch(
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Update the map with the new mapObjects
|
// Update the map with the new mapObjects
|
||||||
mapEditorStore.setMap({
|
map.placedMapObjects = [...map.placedMapObjects, ...updatedMapObjects]
|
||||||
...mapEditorStore.map,
|
|
||||||
placedMapObjects: updatedMapObjects
|
|
||||||
})
|
|
||||||
|
|
||||||
// Update selectedMapObject if it's set
|
// Update mapObject if it's set
|
||||||
if (mapEditorStore.selectedMapObject) {
|
if (mapEditorStore.selectedMapObject) {
|
||||||
const updatedMapObject = newMapObjects.find((obj) => obj.id === mapEditorStore.selectedMapObject?.id)
|
const updatedMapObject = map.placedMapObjects.find((obj) => obj.id === mapEditorStore.selectedMapObject?.id)
|
||||||
if (updatedMapObject) {
|
if (updatedMapObject) {
|
||||||
mapEditorStore.setSelectedMapObject({
|
mapEditorStore.setSelectedMapObject({
|
||||||
...mapEditorStore.selectedMapObject,
|
...mapEditorStore.selectedMapObject,
|
||||||
originX: updatedMapObject.originX,
|
originX: updatedMapObject.positionX,
|
||||||
originY: updatedMapObject.originY
|
originY: updatedMapObject.positionY
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :isModalOpen="mapEditor.isCreateMapModalShown.value" @modal:close="() => mapEditor.toggleCreateMapModal()" :modal-width="300" :modal-height="420" :is-resizable="false" :bg-style="'none'">
|
<Modal ref="modalRef" :modal-width="300" :modal-height="420" :is-resizable="false" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="m-0 font-medium shrink-0 text-white">Create new map</h3>
|
<h3 class="m-0 font-medium shrink-0 text-white">Create new map</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -47,6 +47,7 @@ const emit = defineEmits(['create'])
|
|||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
const mapStorage = new MapStorage()
|
const mapStorage = new MapStorage()
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
const name = ref('')
|
const name = ref('')
|
||||||
const width = ref(0)
|
const width = ref(0)
|
||||||
@ -79,6 +80,6 @@ async function submit() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Close modal
|
// Close modal
|
||||||
mapEditor.toggleCreateMapModal()
|
modalRef.value?.close()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :is-modal-open="mapEditor.isMapListModalShown.value" @modal:close="() => mapEditor.toggleMapListModal()" :is-resizable="false" :modal-width="300" :modal-height="360" :bg-style="'none'">
|
<Modal ref="modalRef" :is-resizable="false" :modal-width="300" :modal-height="360" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="text-lg text-white">Maps</h3>
|
<h3 class="text-lg text-white">Maps</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<div class="my-4 mx-auto h-full">
|
<div class="my-4 mx-auto h-full">
|
||||||
<div class="text-center mb-4 px-2 flex gap-2.5">
|
<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="fetchMaps">Refresh</button>
|
||||||
<button class="btn-cyan py-1.5 min-w-[calc(50%_-_5px)]" @click="() => mapEditor.toggleCreateMapModal()">New</button>
|
<button class="btn-cyan py-1.5 min-w-[calc(50%_-_5px)]" @click="() => $emit('open-create-map')">New</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-y-auto h-[calc(100%-20px)]">
|
<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">
|
<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>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<CreateMap @create="fetchMaps" v-if="mapEditor.isMapListModalShown.value" />
|
<CreateMap @create="fetchMaps" v-if="modalRef?.isModalOpen" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -35,13 +35,21 @@ import Modal from '@/components/utilities/Modal.vue'
|
|||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { MapStorage } from '@/storage/storages'
|
import { MapStorage } from '@/storage/storages'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { onMounted, ref } from 'vue'
|
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||||
|
import { onMounted, ref, useTemplateRef } from 'vue'
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
const mapStorage = new MapStorage()
|
const mapStorage = new MapStorage()
|
||||||
const mapList = ref<Map[]>([])
|
const mapList = ref<Map[]>([])
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
|
defineEmits(['open-create-map'])
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open: () => modalRef.value?.open()
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchMaps()
|
await fetchMaps()
|
||||||
@ -55,7 +63,7 @@ function loadMap(id: UUID) {
|
|||||||
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
|
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
|
||||||
mapEditor.loadMap(response)
|
mapEditor.loadMap(response)
|
||||||
})
|
})
|
||||||
mapEditor.toggleMapListModal()
|
modalRef.value?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteMap(id: UUID) {
|
async function deleteMap(id: UUID) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :isModalOpen="mapEditor.isMapObjectListModalShown.value" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditor.isMapObjectListModalShown.value = false)" :bg-style="'none'">
|
<Modal ref="modalRef" :modal-width="645" :modal-height="260" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="text-lg text-white">Map objects</h3>
|
<h3 class="text-lg text-white">Map objects</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -47,7 +47,7 @@ import Modal from '@/components/utilities/Modal.vue'
|
|||||||
import { MapObjectStorage } from '@/storage/storages'
|
import { MapObjectStorage } from '@/storage/storages'
|
||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { liveQuery } from 'dexie'
|
import { liveQuery } from 'dexie'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
||||||
|
|
||||||
const mapObjectStorage = new MapObjectStorage()
|
const mapObjectStorage = new MapObjectStorage()
|
||||||
const isModalOpen = ref(false)
|
const isModalOpen = ref(false)
|
||||||
@ -55,6 +55,11 @@ const mapEditor = useMapEditorComposable()
|
|||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
const selectedTags = ref<string[]>([])
|
const selectedTags = ref<string[]>([])
|
||||||
const mapObjectList = ref<MapObject[]>([])
|
const mapObjectList = ref<MapObject[]>([])
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open: () => modalRef.value?.open()
|
||||||
|
})
|
||||||
|
|
||||||
const uniqueTags = computed(() => {
|
const uniqueTags = computed(() => {
|
||||||
const allTags = mapObjectList.value.flatMap((obj) => obj.tags || [])
|
const allTags = mapObjectList.value.flatMap((obj) => obj.tags || [])
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :is-modal-open="mapEditor.isSettingsModalShown.value" @modal:close="() => mapEditor.toggleSettingsModal()" :modal-width="600" :modal-height="430" :bg-style="'none'">
|
<Modal ref="modalRef" :modal-width="600" :modal-height="430" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="m-0 font-medium shrink-0 text-white">Map settings</h3>
|
<h3 class="m-0 font-medium shrink-0 text-white">Map settings</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -61,6 +61,11 @@ const width = ref(mapEditor.currentMap.value?.width)
|
|||||||
const height = ref(mapEditor.currentMap.value?.height)
|
const height = ref(mapEditor.currentMap.value?.height)
|
||||||
const pvp = ref(mapEditor.currentMap.value?.pvp)
|
const pvp = ref(mapEditor.currentMap.value?.pvp)
|
||||||
const mapEffects = ref(mapEditor.currentMap.value?.mapEffects || [])
|
const mapEffects = ref(mapEditor.currentMap.value?.mapEffects || [])
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open: () => modalRef.value?.open()
|
||||||
|
})
|
||||||
|
|
||||||
watch(name, (value) => {
|
watch(name, (value) => {
|
||||||
mapEditor.updateProperty('name', value!)
|
mapEditor.updateProperty('name', value!)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :is-modal-open="showTeleportModal" @modal:close="() => mapEditorStore.setTool('move')" :modal-width="300" :modal-height="350" :is-resizable="false" :bg-style="'none'">
|
<Modal ref="modalRef" @modal:close="() => mapEditorStore.setTool('move')" :modal-width="300" :modal-height="350" :is-resizable="false" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="m-0 font-medium shrink-0 text-white">Teleport settings</h3>
|
<h3 class="m-0 font-medium shrink-0 text-white">Teleport settings</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<label for="toMap">Map to teleport to</label>
|
<label for="toMap">Map to teleport to</label>
|
||||||
<select v-model="toMap" class="input-field" name="toMap" id="toMap">
|
<select v-model="toMap" class="input-field" name="toMap" id="toMap">
|
||||||
<option :value="null">Select map</option>
|
<option :value="null">Select map</option>
|
||||||
<option v-for="map in mapEditorStore.mapList" :key="map.id" :value="map">{{ map.name }}</option>
|
<option v-for="map in mapList" :key="map.id" :value="map">{{ map.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,18 +43,22 @@ import type { Map } from '@/application/types'
|
|||||||
import Modal from '@/components/utilities/Modal.vue'
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||||
import { computed, onMounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, useTemplateRef, watch } from 'vue'
|
||||||
|
|
||||||
const showTeleportModal = computed(() => mapEditorStore.tool === 'pencil' && mapEditorStore.drawMode === 'teleport')
|
const showTeleportModal = computed(() => mapEditorStore.tool === 'pencil' && mapEditorStore.drawMode === 'teleport')
|
||||||
const mapEditorStore = useMapEditorStore()
|
const mapEditorStore = useMapEditorStore()
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
const mapList = ref<Map[]>([])
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open: () => modalRef.value?.open(),
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(fetchMaps)
|
onMounted(fetchMaps)
|
||||||
|
|
||||||
function fetchMaps() {
|
function fetchMaps() {
|
||||||
gameStore.connection?.emit('gm:map:list', {}, (response: Map[]) => {
|
gameStore.connection?.emit('gm:map:list', {}, (response: Map[]) => { mapList.value = response })
|
||||||
mapEditorStore.setMapList(response)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { toPositionX, toPositionY, toRotation, toMap } = useRefTeleportSettings()
|
const { toPositionX, toPositionY, toRotation, toMap } = useRefTeleportSettings()
|
||||||
@ -65,7 +69,7 @@ function useRefTeleportSettings() {
|
|||||||
toPositionX: ref(settings.toPositionX),
|
toPositionX: ref(settings.toPositionX),
|
||||||
toPositionY: ref(settings.toPositionY),
|
toPositionY: ref(settings.toPositionY),
|
||||||
toRotation: ref(settings.toRotation),
|
toRotation: ref(settings.toRotation),
|
||||||
toMap: ref(settings.toMap)
|
toMap: ref(settings.toMapId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +80,7 @@ function updateTeleportSettings() {
|
|||||||
toPositionX: toPositionX.value,
|
toPositionX: toPositionX.value,
|
||||||
toPositionY: toPositionY.value,
|
toPositionY: toPositionY.value,
|
||||||
toRotation: toRotation.value,
|
toRotation: toRotation.value,
|
||||||
toMap: toMap.value
|
toMapId: toMap.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :isModalOpen="mapEditor.isTileListModalShown.value" :modal-width="645" :modal-height="600" @modal:close="() => (mapEditor.isTileListModalShown.value = false)" :bg-style="'none'">
|
<Modal ref="modalRef" :modal-width="645" :modal-height="600" :bg-style="'none'">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="text-lg text-white">Tiles</h3>
|
<h3 class="text-lg text-white">Tiles</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -87,7 +87,7 @@ import Modal from '@/components/utilities/Modal.vue'
|
|||||||
import { TileStorage } from '@/storage/storages'
|
import { TileStorage } from '@/storage/storages'
|
||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { liveQuery } from 'dexie'
|
import { liveQuery } from 'dexie'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
||||||
|
|
||||||
const tileStorage = new TileStorage()
|
const tileStorage = new TileStorage()
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
@ -96,6 +96,11 @@ const selectedTags = ref<string[]>([])
|
|||||||
const tileCategories = ref<Map<string, string>>(new Map())
|
const tileCategories = ref<Map<string, string>>(new Map())
|
||||||
const selectedGroup = ref<{ parent: Tile; children: Tile[] } | null>(null)
|
const selectedGroup = ref<{ parent: Tile; children: Tile[] } | null>(null)
|
||||||
const tiles = ref<Tile[]>([])
|
const tiles = ref<Tile[]>([])
|
||||||
|
const modalRef = useTemplateRef('modalRef')
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open: () => modalRef.value?.open()
|
||||||
|
})
|
||||||
|
|
||||||
const uniqueTags = computed(() => {
|
const uniqueTags = computed(() => {
|
||||||
const allTags = tiles.value.flatMap((tile) => tile.tags || [])
|
const allTags = tiles.value.flatMap((tile) => tile.tags || [])
|
||||||
|
@ -72,10 +72,10 @@
|
|||||||
</div>
|
</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">
|
<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="() => mapEditor.toggleMapListModal()">Load</button>
|
<button class="btn-cyan px-3.5" @click="() => emit('open-maps')">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('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="() => emit('clear')" v-if="mapEditor.currentMap.value">Clear</button>
|
||||||
<button class="btn-cyan px-3.5" @click="() => mapEditor.toggleActive()">Exit</button>
|
<button class="btn-cyan px-3.5" @click="() => emit('close-editor')">Exit</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,11 +84,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||||
import { onClickOutside } from '@vueuse/core'
|
import { onClickOutside } from '@vueuse/core'
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
|
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
|
|
||||||
const emit = defineEmits(['save', 'clear'])
|
const emit = defineEmits(['save', 'clear', 'open-maps', 'open-settings', 'close-editor', 'open-tile-list', 'open-map-object-list'])
|
||||||
|
|
||||||
// track when clicked outside of toolbar items
|
// track when clicked outside of toolbar items
|
||||||
const toolbar = ref(null)
|
const toolbar = ref(null)
|
||||||
@ -97,10 +97,15 @@ const toolbar = ref(null)
|
|||||||
let selectPencilOpen = ref(false)
|
let selectPencilOpen = ref(false)
|
||||||
let selectEraserOpen = ref(false)
|
let selectEraserOpen = ref(false)
|
||||||
|
|
||||||
|
let tileListShown = ref(false)
|
||||||
|
let mapObjectListShown = ref(false)
|
||||||
|
|
||||||
|
defineExpose({tileListShown, mapObjectListShown})
|
||||||
|
|
||||||
// drawMode
|
// drawMode
|
||||||
function setDrawMode(value: string) {
|
function setDrawMode(value: string) {
|
||||||
mapEditor.isTileListModalShown.value = value === 'tile'
|
if (value === 'tile') emit('open-tile-list')
|
||||||
mapEditor.isMapObjectListModalShown.value = value === 'map_object'
|
if (value === 'map_object') emit('open-map-object-list')
|
||||||
|
|
||||||
mapEditor.setDrawMode(value)
|
mapEditor.setDrawMode(value)
|
||||||
selectPencilOpen.value = false
|
selectPencilOpen.value = false
|
||||||
@ -108,13 +113,13 @@ function setDrawMode(value: string) {
|
|||||||
|
|
||||||
// drawMode
|
// drawMode
|
||||||
function setEraserMode(value: string) {
|
function setEraserMode(value: string) {
|
||||||
mapEditor.setEraserMode(value)
|
mapEditorStore.setTool('eraser')
|
||||||
selectEraserOpen.value = false
|
selectEraserOpen.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClick(tool: string) {
|
function handleClick(tool: string) {
|
||||||
if (tool === 'settings') {
|
if (tool === 'settings') {
|
||||||
mapEditor.toggleSettingsModal()
|
emit('open-settings')
|
||||||
} else {
|
} else {
|
||||||
mapEditor.setTool(tool)
|
mapEditor.setTool(tool)
|
||||||
}
|
}
|
||||||
@ -125,8 +130,7 @@ function handleClick(tool: string) {
|
|||||||
|
|
||||||
function cycleToolMode(tool: 'pencil' | 'eraser') {
|
function cycleToolMode(tool: 'pencil' | 'eraser') {
|
||||||
const modes = ['tile', 'object', 'teleport', 'blocking tile']
|
const modes = ['tile', 'object', 'teleport', 'blocking tile']
|
||||||
const currentMode = tool === 'pencil' ? mapEditor.drawMode : mapEditor.eraserMode
|
const currentIndex = modes.indexOf(mapEditorStore.drawMode)
|
||||||
const currentIndex = modes.indexOf(currentMode.value)
|
|
||||||
const nextIndex = (currentIndex + 1) % modes.length
|
const nextIndex = (currentIndex + 1) % modes.length
|
||||||
const nextMode = modes[nextIndex]
|
const nextMode = modes[nextIndex]
|
||||||
|
|
||||||
|
@ -4,13 +4,16 @@
|
|||||||
<Scene name="main" @preload="preloadScene">
|
<Scene name="main" @preload="preloadScene">
|
||||||
<div v-if="!isLoaded" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-white text-3xl font-ui">Loading...</div>
|
<div v-if="!isLoaded" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-white text-3xl font-ui">Loading...</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<Map :key="mapEditor.currentMap.value?.id" />
|
<Map :key="currentMap?.id" />
|
||||||
<Toolbar @save="save" @clear="clear" />
|
<Toolbar ref="toolbar" @save="save" @clear="clear" @open-maps="mapModal?.open()" @open-settings="mapSettingsModal?.open()"
|
||||||
<MapList />
|
@close-editor="$emit('close-editor')"
|
||||||
<TileList />
|
@open-tile-list="tileModal?.open()"
|
||||||
<ObjectList />
|
@open-map-object-list="objectModal?.open()"/>
|
||||||
<MapSettings />
|
<MapList ref="mapModal" @open-create-map="mapSettingsModal?.open()"/>
|
||||||
<TeleportModal />
|
<TileList ref="tileModal"/>
|
||||||
|
<ObjectList ref="objectModal"/>
|
||||||
|
<MapSettings ref="mapSettingsModal" />
|
||||||
|
<TeleportModal ref="teleportModal" />
|
||||||
</div>
|
</div>
|
||||||
</Scene>
|
</Scene>
|
||||||
</Game>
|
</Game>
|
||||||
@ -33,11 +36,20 @@ import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
|||||||
import { MapStorage } from '@/storage/storages'
|
import { MapStorage } from '@/storage/storages'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { Game, Scene } from 'phavuer'
|
import { Game, Scene } from 'phavuer'
|
||||||
import { ref } from 'vue'
|
import { provide, ref, useTemplateRef, watch } from 'vue'
|
||||||
|
|
||||||
const mapStorage = new MapStorage()
|
const mapStorage = new MapStorage()
|
||||||
const mapEditor = useMapEditorComposable()
|
const mapEditor = useMapEditorComposable()
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
const mapEditorStore = useMapEditorStore()
|
||||||
|
const currentMap = ref<MapT | null>(null)
|
||||||
|
|
||||||
|
const toolbar = useTemplateRef("toolbar")
|
||||||
|
const mapModal = useTemplateRef("mapModal")
|
||||||
|
const tileModal = useTemplateRef("tileModal")
|
||||||
|
const objectModal = useTemplateRef("objectModal")
|
||||||
|
const mapSettingsModal = useTemplateRef("mapSettingsModal")
|
||||||
|
const teleportModal = useTemplateRef("teleportModal")
|
||||||
|
|
||||||
const isLoaded = ref(false)
|
const isLoaded = ref(false)
|
||||||
|
|
||||||
@ -76,22 +88,18 @@ const preloadScene = async (scene: Phaser.Scene) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
if (!mapEditor.currentMap.value) return
|
if (!currentMap.value) return
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
mapId: mapEditor.currentMap.value.id,
|
mapId: currentMap.value.id,
|
||||||
name: mapEditor.currentMap.value.name,
|
name: currentMap.value.name,
|
||||||
width: mapEditor.currentMap.value.width,
|
width: currentMap.value.width,
|
||||||
height: mapEditor.currentMap.value.height,
|
height: currentMap.value.height,
|
||||||
tiles: mapEditor.currentMap.value.tiles,
|
tiles: currentMap.value.tiles,
|
||||||
pvp: mapEditor.currentMap.value.pvp,
|
pvp: currentMap.value.pvp,
|
||||||
mapEffects: mapEditor.currentMap.value.mapEffects?.map(({ id, effect, strength }) => ({ id, effect, strength })) ?? [],
|
mapEffects: currentMap.value.mapEffects?.map(({ id, effect, strength }) => ({ id, effect, strength })) ?? [],
|
||||||
mapEventTiles: mapEditor.currentMap.value.mapEventTiles?.map(({ id, type, positionX, positionY, teleport }) => ({ id, type, positionX, positionY, teleport })) ?? [],
|
mapEventTiles: currentMap.value.mapEventTiles?.map(({ id, type, positionX, positionY, teleport }) => ({ id, type, positionX, positionY, teleport })) ?? [],
|
||||||
placedMapObjects: mapEditor.currentMap.value.placedMapObjects?.map(({ id, mapObject, depth, isRotated, positionX, positionY }) => ({ id, mapObject, depth, isRotated, positionX, positionY })) ?? []
|
placedMapObjects: currentMap.value.placedMapObjects?.map(({ id, mapObject, depth, isRotated, positionX, positionY }) => ({ id, mapObject, depth, isRotated, positionX, positionY })) ?? []
|
||||||
}
|
|
||||||
|
|
||||||
if (mapEditor.isSettingsModalShown.value) {
|
|
||||||
mapEditor.toggleSettingsModal()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStore.connection?.emit('gm:map:update', data, (response: MapT) => {
|
gameStore.connection?.emit('gm:map:update', data, (response: MapT) => {
|
||||||
@ -99,8 +107,10 @@ function save() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(() => mapEditor.currentMap, (value) => { currentMap.value = value.value })
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
if (!mapEditor.currentMap.value) return
|
if (!currentMap.value) return
|
||||||
|
|
||||||
// Clear placed objects, event tiles and tiles
|
// Clear placed objects, event tiles and tiles
|
||||||
mapEditor.clearMap()
|
mapEditor.clearMap()
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<button v-if="canFullScreen" @click="toggleFullScreen" class="w-5 h-5 m-0 p-0 relative hover:scale-110 transition-transform duration-300 ease-in-out">
|
<button v-if="canFullScreen" @click="toggleFullScreen" class="w-5 h-5 m-0 p-0 relative hover:scale-110 transition-transform duration-300 ease-in-out">
|
||||||
<img :alt="isFullScreen ? 'exit full-screen' : 'full-screen'" :src="isFullScreen ? '/assets/icons/modal/minimize.svg' : '/assets/icons/modal/increase-size-option.svg'" class="w-3.5 h-3.5 invert" draggable="false" />
|
<img :alt="isFullScreen ? 'exit full-screen' : 'full-screen'" :src="isFullScreen ? '/assets/icons/modal/minimize.svg' : '/assets/icons/modal/increase-size-option.svg'" class="w-3.5 h-3.5 invert" draggable="false" />
|
||||||
</button>
|
</button>
|
||||||
<button v-if="closable" @click="emit('modal:close')" class="w-3.5 h-3.5 m-0 p-0 relative hover:rotate-180 transition-transform duration-300 ease-in-out">
|
<button v-if="closable" @click="isModalOpenRef=false" class="w-3.5 h-3.5 m-0 p-0 relative hover:rotate-180 transition-transform duration-300 ease-in-out">
|
||||||
<img alt="close" src="/assets/icons/modal/close-button-white.svg" class="w-full h-full" draggable="false" />
|
<img alt="close" src="/assets/icons/modal/close-button-white.svg" class="w-full h-full" draggable="false" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -46,7 +46,7 @@
|
|||||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
interface ModalProps {
|
interface ModalProps {
|
||||||
isModalOpen: boolean
|
isModalOpen?: boolean
|
||||||
closable?: boolean
|
closable?: boolean
|
||||||
isResizable?: boolean
|
isResizable?: boolean
|
||||||
isFullScreen?: boolean
|
isFullScreen?: boolean
|
||||||
@ -79,10 +79,18 @@ const props = withDefaults(defineProps<ModalProps>(), {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
'modal:open': []
|
||||||
'modal:close': []
|
'modal:close': []
|
||||||
'character:create': []
|
'character:create': []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
defineExpose(
|
||||||
|
{
|
||||||
|
open: () => isModalOpenRef.value = true,
|
||||||
|
close: () => isModalOpenRef.value = false,
|
||||||
|
toggle: () => isModalOpenRef.value = !isModalOpenRef.value,
|
||||||
|
})
|
||||||
|
|
||||||
const isModalOpenRef = ref(props.isModalOpen)
|
const isModalOpenRef = ref(props.isModalOpen)
|
||||||
const width = ref(props.modalWidth)
|
const width = ref(props.modalWidth)
|
||||||
const height = ref(props.modalHeight)
|
const height = ref(props.modalHeight)
|
||||||
|
@ -9,10 +9,10 @@ import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
|||||||
import Tileset = Phaser.Tilemaps.Tileset
|
import Tileset = Phaser.Tilemaps.Tileset
|
||||||
import Tile = Phaser.Tilemaps.Tile
|
import Tile = Phaser.Tilemaps.Tile
|
||||||
|
|
||||||
|
import type { Tile as TileT } from '@/application/types'
|
||||||
|
|
||||||
export function getTile(layer: TilemapLayer | Tilemap, positionX: number, positionY: number): Tile | null {
|
export function getTile(layer: TilemapLayer | Tilemap, positionX: number, positionY: number): Tile | null {
|
||||||
const tile = layer?.getTileAtWorldXY(positionX, positionY)
|
return layer.getTileAtWorldXY(positionX, positionY)
|
||||||
if (!tile) return null
|
|
||||||
return tile
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tileToWorldXY(layer: TilemapLayer | Tilemap, positionX: number, positionY: number) {
|
export function tileToWorldXY(layer: TilemapLayer | Tilemap, positionX: number, positionY: number) {
|
||||||
@ -77,14 +77,18 @@ export const calculateIsometricDepth = (positionX: number, positionY: number, wi
|
|||||||
return baseDepth + (width + height) / (2 * config.tile_size.width)
|
return baseDepth + (width + height) / (2 * config.tile_size.width)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FlattenMapArray(tiles: string[][]) {
|
async function getTiles(tiles: TileT[], scene: Phaser.Scene) {
|
||||||
const normalArray = []
|
// Load each tile into the scene
|
||||||
|
for (const tile of tiles) {
|
||||||
for (const row of tiles) {
|
if (!tile) continue
|
||||||
normalArray.push(...row)
|
const textureData = {
|
||||||
|
key: tile.id,
|
||||||
|
data: '/textures/tiles/' + tile.id + '.png',
|
||||||
|
group: 'tiles',
|
||||||
|
updatedAt: tile.updatedAt
|
||||||
|
} as TextureData
|
||||||
|
await loadTexture(scene, textureData)
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalArray
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadMapTilesIntoScene(map_id: UUID, scene: Phaser.Scene) {
|
export async function loadMapTilesIntoScene(map_id: UUID, scene: Phaser.Scene) {
|
||||||
@ -93,50 +97,22 @@ export async function loadMapTilesIntoScene(map_id: UUID, scene: Phaser.Scene) {
|
|||||||
const map = await mapStorage.get(map_id)
|
const map = await mapStorage.get(map_id)
|
||||||
if (!map) return
|
if (!map) return
|
||||||
|
|
||||||
const tileArray = unduplicateArray(FlattenMapArray(map.tiles))
|
const tileArray = unduplicateArray(map.tiles)
|
||||||
const tiles = await tileStorage.getByIds(tileArray)
|
const tiles = await tileStorage.getByIds(tileArray)
|
||||||
|
|
||||||
// Load each tile into the scene
|
await getTiles(tiles, scene)
|
||||||
for (const tile of tiles) {
|
|
||||||
const textureData = {
|
|
||||||
key: tile.id,
|
|
||||||
data: '/textures/tiles/' + tile.id + '.png',
|
|
||||||
group: 'tiles',
|
|
||||||
updatedAt: tile.updatedAt
|
|
||||||
} as TextureData
|
|
||||||
await loadTexture(scene, textureData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadTilesIntoScene(tileIds: string[], scene: Phaser.Scene) {
|
export async function loadTilesIntoScene(tileIds: string[], scene: Phaser.Scene) {
|
||||||
const tileStorage = new TileStorage()
|
const tileStorage = new TileStorage()
|
||||||
|
|
||||||
const tiles = await tileStorage.getByIds(tileIds)
|
const tiles = await tileStorage.getByIds(tileIds)
|
||||||
|
|
||||||
// Load each tile into the scene
|
await getTiles(tiles, scene)
|
||||||
for (const tile of tiles) {
|
|
||||||
const textureData = {
|
|
||||||
key: tile.id,
|
|
||||||
data: '/textures/tiles/' + tile.id + '.png',
|
|
||||||
group: 'tiles',
|
|
||||||
updatedAt: tile.updatedAt
|
|
||||||
} as TextureData
|
|
||||||
await loadTexture(scene, textureData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadAllTilesIntoScene(scene: Phaser.Scene) {
|
export async function loadAllTilesIntoScene(scene: Phaser.Scene) {
|
||||||
const tileStorage = new TileStorage()
|
const tileStorage = new TileStorage()
|
||||||
const tiles = await tileStorage.getAll()
|
const tiles = await tileStorage.getAll()
|
||||||
|
|
||||||
// Load each tile into the scene
|
getTiles(tiles, scene)
|
||||||
for (const tile of tiles) {
|
|
||||||
const textureData = {
|
|
||||||
key: tile.id,
|
|
||||||
data: '/textures/tiles/' + tile.id + '.png',
|
|
||||||
group: 'tiles',
|
|
||||||
updatedAt: tile.updatedAt
|
|
||||||
} as TextureData
|
|
||||||
await loadTexture(scene, textureData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
||||||
pointerStartPosition.value = { x: pointer.x, y: pointer.y }
|
pointerStartPosition.value = pointer.position
|
||||||
gameStore.setPlayerDraggingCamera(true)
|
gameStore.setPlayerDraggingCamera(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,10 +34,9 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema
|
|||||||
|
|
||||||
if (!gameStore.game.isPlayerDraggingCamera) return
|
if (!gameStore.game.isPlayerDraggingCamera) return
|
||||||
|
|
||||||
const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)
|
|
||||||
|
|
||||||
// If the distance is less than the drag threshold, return
|
// If the distance is less than the drag threshold, return
|
||||||
// We do this to prevent the camera from scrolling too quickly
|
// We do this to prevent the camera from scrolling too quickly
|
||||||
|
const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)
|
||||||
if (distance <= dragThreshold) return
|
if (distance <= dragThreshold) return
|
||||||
|
|
||||||
camera.setScroll(camera.scrollX - (pointer.x - pointer.prevPosition.x) / camera.zoom, camera.scrollY - (pointer.y - pointer.prevPosition.y) / camera.zoom)
|
camera.setScroll(camera.scrollX - (pointer.x - pointer.prevPosition.x) / camera.zoom, camera.scrollY - (pointer.y - pointer.prevPosition.y) / camera.zoom)
|
||||||
@ -46,12 +45,6 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema
|
|||||||
function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
||||||
gameStore.setPlayerDraggingCamera(false)
|
gameStore.setPlayerDraggingCamera(false)
|
||||||
|
|
||||||
const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)
|
|
||||||
|
|
||||||
// If the distance is greater than the drag threshold, return
|
|
||||||
// We do this to prevent the camera from scrolling too quickly
|
|
||||||
if (distance > dragThreshold) return
|
|
||||||
|
|
||||||
const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
|
const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
|
||||||
if (!pointerTile) return
|
if (!pointerTile) return
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export function useMapEditorPointerHandlers(scene: Phaser.Scene, layer: Phaser.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
||||||
pointerStartPosition.value = { x: pointer.x, y: pointer.y }
|
pointerStartPosition.value = pointer.position
|
||||||
if (isMoveTool.value || pointer.event.shiftKey) {
|
if (isMoveTool.value || pointer.event.shiftKey) {
|
||||||
gameStore.setPlayerDraggingCamera(true)
|
gameStore.setPlayerDraggingCamera(true)
|
||||||
}
|
}
|
||||||
@ -37,8 +37,9 @@ export function useMapEditorPointerHandlers(scene: Phaser.Scene, layer: Phaser.T
|
|||||||
function dragMap(pointer: Phaser.Input.Pointer) {
|
function dragMap(pointer: Phaser.Input.Pointer) {
|
||||||
if (!gameStore.game.isPlayerDraggingCamera) return
|
if (!gameStore.game.isPlayerDraggingCamera) return
|
||||||
|
|
||||||
|
// If the distance is less than the drag threshold, return
|
||||||
|
// We do this to prevent the camera from scrolling too quickly
|
||||||
const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)
|
const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)
|
||||||
|
|
||||||
if (distance <= dragThreshold) return
|
if (distance <= dragThreshold) return
|
||||||
|
|
||||||
camera.setScroll(camera.scrollX - (pointer.x - pointer.prevPosition.x) / camera.zoom, camera.scrollY - (pointer.y - pointer.prevPosition.y) / camera.zoom)
|
camera.setScroll(camera.scrollX - (pointer.x - pointer.prevPosition.x) / camera.zoom, camera.scrollY - (pointer.y - pointer.prevPosition.y) / camera.zoom)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { MapObject } from '@/application/types'
|
import type { MapObject } from '@/application/types'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
import type { Map as MapT } from '@/application/types'
|
||||||
|
|
||||||
export type TeleportSettings = {
|
export type TeleportSettings = {
|
||||||
toMapId: string
|
toMapId: string
|
||||||
@ -11,17 +12,11 @@ export type TeleportSettings = {
|
|||||||
export const useMapEditorStore = defineStore('mapEditor', {
|
export const useMapEditorStore = defineStore('mapEditor', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
active: false,
|
active: true,
|
||||||
tool: 'move',
|
tool: 'move',
|
||||||
drawMode: 'tile',
|
drawMode: 'tile',
|
||||||
eraserMode: 'tile',
|
|
||||||
selectedTile: '',
|
selectedTile: '',
|
||||||
selectedMapObject: null as MapObject | null,
|
selectedMapObject: null as MapObject | null,
|
||||||
isTileListModalShown: false,
|
|
||||||
isMapObjectListModalShown: false,
|
|
||||||
isMapListModalShown: false,
|
|
||||||
isCreateMapModalShown: false,
|
|
||||||
isSettingsModalShown: false,
|
|
||||||
shouldClearTiles: false,
|
shouldClearTiles: false,
|
||||||
teleportSettings: {
|
teleportSettings: {
|
||||||
toMapId: '',
|
toMapId: '',
|
||||||
@ -32,35 +27,18 @@ export const useMapEditorStore = defineStore('mapEditor', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
toggleActive() {
|
|
||||||
if (this.active) this.reset()
|
|
||||||
this.active = !this.active
|
|
||||||
},
|
|
||||||
setTool(tool: string) {
|
setTool(tool: string) {
|
||||||
this.tool = tool
|
this.tool = tool
|
||||||
},
|
},
|
||||||
setDrawMode(mode: string) {
|
setDrawMode(mode: string) {
|
||||||
this.drawMode = mode
|
this.drawMode = mode
|
||||||
},
|
},
|
||||||
setEraserMode(mode: string) {
|
|
||||||
this.eraserMode = mode
|
|
||||||
},
|
|
||||||
setSelectedTile(tile: string) {
|
setSelectedTile(tile: string) {
|
||||||
this.selectedTile = tile
|
this.selectedTile = tile
|
||||||
},
|
},
|
||||||
setSelectedMapObject(object: MapObject) {
|
setSelectedMapObject(object: MapObject) {
|
||||||
this.selectedMapObject = object
|
this.selectedMapObject = object
|
||||||
},
|
},
|
||||||
toggleSettingsModal() {
|
|
||||||
this.isSettingsModalShown = !this.isSettingsModalShown
|
|
||||||
},
|
|
||||||
toggleMapListModal() {
|
|
||||||
this.isMapListModalShown = !this.isMapListModalShown
|
|
||||||
this.isCreateMapModalShown = false
|
|
||||||
},
|
|
||||||
toggleCreateMapModal() {
|
|
||||||
this.isCreateMapModalShown = !this.isCreateMapModalShown
|
|
||||||
},
|
|
||||||
setTeleportSettings(teleportSettings: TeleportSettings) {
|
setTeleportSettings(teleportSettings: TeleportSettings) {
|
||||||
this.teleportSettings = teleportSettings
|
this.teleportSettings = teleportSettings
|
||||||
},
|
},
|
||||||
@ -75,11 +53,6 @@ export const useMapEditorStore = defineStore('mapEditor', {
|
|||||||
this.drawMode = 'tile'
|
this.drawMode = 'tile'
|
||||||
this.selectedTile = ''
|
this.selectedTile = ''
|
||||||
this.selectedMapObject = null
|
this.selectedMapObject = null
|
||||||
this.isTileListModalShown = false
|
|
||||||
this.isMapObjectListModalShown = false
|
|
||||||
this.isSettingsModalShown = false
|
|
||||||
this.isMapListModalShown = false
|
|
||||||
this.isCreateMapModalShown = false
|
|
||||||
this.shouldClearTiles = false
|
this.shouldClearTiles = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user