From 221182483219b8c2111d042df1dccfca191cf2a3 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Wed, 21 Aug 2024 23:10:29 +0200
Subject: [PATCH] Replaced some code vars for consistency, added start of
 teleport logics

---
 src/components/World.vue                      |  2 +-
 .../utilities/zoneEditor/ZoneEditor.vue       | 38 +++++++--
 .../zoneEditor/partials/TeleportModal.vue     | 80 +++++++++++++++++++
 src/screens/Game.vue                          |  2 +-
 src/services/zone.ts                          |  2 +-
 src/stores/zoneEditor.ts                      | 16 +++-
 src/types.ts                                  |  2 +-
 7 files changed, 130 insertions(+), 12 deletions(-)
 create mode 100644 src/components/utilities/zoneEditor/partials/TeleportModal.vue

diff --git a/src/components/World.vue b/src/components/World.vue
index dc8b6fc..a2cf579 100644
--- a/src/components/World.vue
+++ b/src/components/World.vue
@@ -11,7 +11,7 @@
         :texture="item.object.id"
         :originY="Number(item.object.origin_x)"
         :originX="Number(item.object.origin_y)"
-        :depth="item.depth"
+        :depth="(item.depth > 0 ? item.depth : undefined)"
       />
       <Character v-else :layer="zoneTilemap as any" :character="item" :depth="item.depth" />
     </template>
diff --git a/src/components/utilities/zoneEditor/ZoneEditor.vue b/src/components/utilities/zoneEditor/ZoneEditor.vue
index 585b9ac..2b633eb 100644
--- a/src/components/utilities/zoneEditor/ZoneEditor.vue
+++ b/src/components/utilities/zoneEditor/ZoneEditor.vue
@@ -12,7 +12,7 @@
       :texture="object.object.id"
       :originY="Number(object.object.origin_x)"
       :originX="Number(object.object.origin_y)"
-      :depth="object.depth ?? calculateDepth(object.position_x, object.position_y, zoneTilemap.width)"
+      :depth="object.depth > 0 ? object.depth : undefined"
       @pointerup="() => zoneEditorStore.setSelectedZoneObject(object)"
     />
   </Container>
@@ -22,17 +22,18 @@
   </Container>
 
   <Toolbar :layer="tiles" @eraser="eraser" @pencil="pencil" @paint="paint" @clear="clear" @save="save" />
-  <SelectedZoneObject v-if="zoneEditorStore.selectedZoneObject" @update_depth="updateZoneObjectDepth" @delete="deleteZoneObject" @move="() => console.log('lol')" />
+  <SelectedZoneObject v-if="zoneEditorStore.selectedZoneObject" @update_depth="updateZoneObjectDepth" @delete="deleteZoneObject" @move="() => console.log('move btn clicked')" />
   <Tiles v-if="zoneEditorStore.isTileListModalShown" />
   <Objects v-if="zoneEditorStore.isObjectListModalShown" />
   <ZoneSettings v-if="zoneEditorStore.isSettingsModalShown" />
   <ZoneList v-if="zoneEditorStore.isZoneListModalShown" />
+  <TeleportModal v-if="zoneEditorStore.tool === 'pencil' && zoneEditorStore.drawMode === 'teleport'" />
 </template>
 
 <script setup lang="ts">
 import config from '@/config'
 import { Container, Image, TilemapLayer as TilemapLayerC, useScene } from 'phavuer'
-import { onBeforeMount, onBeforeUnmount, ref, toRaw, computed, watch } from 'vue'
+import { computed, onBeforeMount, onBeforeUnmount, ref, toRaw, watch } from 'vue'
 import Controls from '@/components/utilities/Controls.vue'
 import { useGameStore } from '@/stores/game'
 import Toolbar from '@/components/utilities/zoneEditor/partials/Toolbar.vue'
@@ -40,15 +41,16 @@ import Tiles from '@/components/utilities/zoneEditor/partials/TileList.vue'
 import SelectedZoneObject from '@/components/utilities/zoneEditor/partials/SelectedZoneObject.vue'
 import { useZoneEditorStore } from '@/stores/zoneEditor'
 import ZoneSettings from '@/components/utilities/zoneEditor/partials/ZoneSettings.vue'
-import { calculateDepth, placeTile, setAllTiles, tileToWorldX, tileToWorldY, sortByDepth } from '@/services/zone'
+import { placeTile, setAllTiles, sortByDepth, tileToWorldX, tileToWorldY } from '@/services/zone'
 import { useAssetStore } from '@/stores/assets'
 import Objects from '@/components/utilities/zoneEditor/partials/ObjectList.vue'
-import type { ZoneEventTile, ZoneObject } from '@/types'
+import { type ZoneEventTile, ZoneEventTileType, type ZoneObject } from '@/types'
 import { storeToRefs } from 'pinia'
 import ZoneList from '@/components/utilities/zoneEditor/partials/ZoneList.vue'
+import { uuidv4 } from '@/utilities'
+import TeleportModal from '@/components/utilities/zoneEditor/partials/TeleportModal.vue'
 import Tileset = Phaser.Tilemaps.Tileset
 import TilemapLayer = Phaser.Tilemaps.TilemapLayer
-import { uuidv4 } from '@/utilities'
 
 const scene = useScene()
 const gameStore = useGameStore()
@@ -110,6 +112,12 @@ function eraser(tile: Phaser.Tilemaps.Tile) {
       return zoneTileEvent.position_x !== tile.x || zoneTileEvent.position_y !== tile.y
     })
   }
+
+  if (zoneEditorStore.eraserMode === 'teleport') {
+    zoneEventTiles.value = zoneEventTiles.value.filter((zoneTileEvent) => {
+      return zoneTileEvent.type !== ZoneEventTileType.TELEPORT || zoneTileEvent.position_x !== tile.x || zoneTileEvent.position_y !== tile.y
+    })
+  }
 }
 
 function pencil(tile: Phaser.Tilemaps.Tile) {
@@ -145,7 +153,23 @@ function pencil(tile: Phaser.Tilemaps.Tile) {
       id: uuidv4(),
       zoneId: zoneEditorStore.zone.id,
       zone: zoneEditorStore.zone,
-      type: 'BLOCK',
+      type: ZoneEventTileType.BLOCK,
+      position_x: tile.x,
+      position_y: tile.y
+    })
+
+    // remove duplicates based on type, pos x and y
+    zoneEventTiles.value = zoneEventTiles.value.filter((zoneTileEvent, index, self) => index === self.findIndex((t) => t.type === zoneTileEvent.type && t.position_x === zoneTileEvent.position_x && t.position_y === zoneTileEvent.position_y))
+  }
+
+  if (zoneEditorStore.drawMode === 'teleport') {
+    if (zoneEditorStore.zone === null) return
+
+    zoneEventTiles.value.push({
+      id: uuidv4(),
+      zoneId: zoneEditorStore.zone.id,
+      zone: zoneEditorStore.zone,
+      type: ZoneEventTileType.TELEPORT,
       position_x: tile.x,
       position_y: tile.y
     })
diff --git a/src/components/utilities/zoneEditor/partials/TeleportModal.vue b/src/components/utilities/zoneEditor/partials/TeleportModal.vue
new file mode 100644
index 0000000..b8b5c39
--- /dev/null
+++ b/src/components/utilities/zoneEditor/partials/TeleportModal.vue
@@ -0,0 +1,80 @@
+<template>
+  <Modal :is-modal-open="true" @modal:close="() => zoneEditorStore.setTool('move')" :modal-width="300" :modal-height="250" :is-resizable="false">
+    <template #modalHeader>
+      <h3 class="m-0 font-medium shrink-0">Teleport settings</h3>
+    </template>
+
+    <template #modalBody>
+      <div class="m-4">
+        <form method="post" @submit.prevent="" class="inline">
+          <div class="gap-2.5 flex flex-wrap">
+            <div class="form-field-half">
+              <label for="name">X</label>
+              <input class="input-cyan" v-model="x" name="name" id="name" type="number" />
+            </div>
+            <div class="form-field-half">
+              <label for="name">Y</label>
+              <input class="input-cyan" v-model="y" name="name" id="name" type="number" />
+            </div>
+            <div class="form-field-full">
+              <label for="zoneId">Zone to teleport to</label>
+              <select v-model="zoneId" class="input-cyan" name="zoneId" id="zoneId">
+                <option :value="0">Select zone</option>
+                <option v-for="zone in zoneEditorStore.zoneList" :key="zone.id" :value="zone.id">{{ zone.name }}</option>
+              </select>
+            </div>
+          </div>
+        </form>
+      </div>
+    </template>
+  </Modal>
+</template>
+
+<script setup lang="ts">
+import { onMounted, ref, watch } from 'vue'
+import Modal from '@/components/utilities/Modal.vue'
+import { useZoneEditorStore } from '@/stores/zoneEditor'
+import { useGameStore } from '@/stores/game'
+import { Zone } from '@/types'
+
+const zoneEditorStore = useZoneEditorStore()
+const gameStore = useGameStore()
+
+onMounted(async () => {
+  fetchZones()
+})
+
+function fetchZones() {
+  gameStore.connection?.emit('gm:zone_editor:zone:list', {}, (response: Zone[]) => {
+    zoneEditorStore.setZoneList(response)
+  })
+}
+
+const x = ref(zoneEditorStore.teleportSettings.x)
+const y = ref(zoneEditorStore.teleportSettings.y)
+const zoneId = ref(zoneEditorStore.teleportSettings.zoneId)
+
+watch(zoneId, (value) => {
+  zoneEditorStore.setTeleportSettings({
+    x: x.value,
+    y: y.value,
+    zoneId: value
+  })
+})
+
+watch(x, (value) => {
+  zoneEditorStore.setTeleportSettings({
+    x: value,
+    y: y.value,
+    zoneId: zoneId.value
+  })
+})
+
+watch(y, (value) => {
+  zoneEditorStore.setTeleportSettings({
+    x: x.value,
+    y: value,
+    zoneId: zoneId.value
+  })
+})
+</script>
diff --git a/src/screens/Game.vue b/src/screens/Game.vue
index 3cc34dc..16a987b 100644
--- a/src/screens/Game.vue
+++ b/src/screens/Game.vue
@@ -131,7 +131,7 @@ const preloadScene = (scene: Phaser.Scene) => {
   })
 
   scene.load.image('BLOCK', '/assets/zone/bt_tile.png')
-  scene.load.image('WARP', '/assets/zone/tp_tile.png')
+  scene.load.image('TELEPORT', '/assets/zone/tp_tile.png')
   scene.load.image('blank_tile', '/assets/zone/blank_tile.png')
   scene.load.image('blank_object', '/assets/zone/blank_tile.png')
   scene.load.image('waypoint', '/assets/waypoint.png')
diff --git a/src/services/zone.ts b/src/services/zone.ts
index f90a106..82a8bd1 100644
--- a/src/services/zone.ts
+++ b/src/services/zone.ts
@@ -86,7 +86,7 @@ export const updateZoneTiles = (zoneTilemap: Tilemap, tiles: Phaser.Tilemaps.Til
     }
 
     // Update the tilemap with any new 'blank_tile' entries
-    zoneTiles.forEach((row, y) => {
+    zoneTiles.forEach((row: string[], y: number) => {
       row.forEach((tileId, x) => {
         placeTile(zoneTilemap, tiles, x, y, tileId)
       })
diff --git a/src/stores/zoneEditor.ts b/src/stores/zoneEditor.ts
index 6f3582c..4dc87c2 100644
--- a/src/stores/zoneEditor.ts
+++ b/src/stores/zoneEditor.ts
@@ -2,6 +2,12 @@ import { defineStore } from 'pinia'
 import { useGameStore } from '@/stores/game'
 import type { Zone, Object, Tile, ZoneObject } from '@/types'
 
+type TeleportSettings = {
+  x: number
+  y: number
+  zoneId: number
+}
+
 export const useZoneEditorStore = defineStore('zoneEditor', {
   state: () => ({
     active: false,
@@ -20,7 +26,12 @@ export const useZoneEditorStore = defineStore('zoneEditor', {
     isObjectListModalShown: false,
     isZoneListModalShown: false,
     isCreateZoneModalShown: false,
-    isSettingsModalShown: false
+    isSettingsModalShown: false,
+    teleportSettings: {
+      x: 0,
+      y: 0,
+      zoneId: 0
+    }
   }),
   actions: {
     toggleActive() {
@@ -93,6 +104,9 @@ export const useZoneEditorStore = defineStore('zoneEditor', {
     toggleCreateZoneModal() {
       this.isCreateZoneModalShown = !this.isCreateZoneModalShown
     },
+    setTeleportSettings(teleportSettings: TeleportSettings) {
+      this.teleportSettings = teleportSettings
+    },
     reset() {
       this.zoneList = []
       this.tileList = []
diff --git a/src/types.ts b/src/types.ts
index cda9808..6cce59b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -72,7 +72,7 @@ export type ZoneObject = {
 
 export enum ZoneEventTileType {
   BLOCK = 'BLOCK',
-  WARP = 'WARP',
+  TELEPORT = 'TELEPORT',
   NPC = 'NPC',
   ITEM = 'ITEM'
 }