From 7c259f455c5f2651154c743f5acc66c5fff94ae3 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Mon, 28 Oct 2024 23:41:26 +0100
Subject: [PATCH] Load all tiles in zone editor

---
 .../gameMaster/zoneEditor/ZoneEditor.vue      | 22 +++++++--
 src/components/gui/ResetPassword.vue          |  4 +-
 src/components/utilities/Modal.vue            | 20 ++++-----
 src/composables/zoneComposable.ts             |  9 ++--
 src/managers/assetManager.ts                  |  9 ++++
 src/screens/ZoneEditor.vue                    | 45 ++-----------------
 src/services/authentication.ts                |  2 +-
 src/utilities.ts                              |  2 +-
 8 files changed, 49 insertions(+), 64 deletions(-)

diff --git a/src/components/gameMaster/zoneEditor/ZoneEditor.vue b/src/components/gameMaster/zoneEditor/ZoneEditor.vue
index fdd7058..4c9f9a6 100644
--- a/src/components/gameMaster/zoneEditor/ZoneEditor.vue
+++ b/src/components/gameMaster/zoneEditor/ZoneEditor.vue
@@ -1,5 +1,7 @@
 <template>
-  <ZoneTiles @tilemap:create="tileMap = $event" />
+  <div v-if="isLoaded">
+    <ZoneTiles @tilemap:create="tileMap = $event" />
+  </div>
   <ZoneObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
   <ZoneEventTiles v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
 
@@ -14,10 +16,11 @@
 </template>
 
 <script setup lang="ts">
-import { onUnmounted, ref } from 'vue'
+import { useScene } from 'phavuer'
+import { onMounted, onUnmounted, ref } from 'vue'
 import { useGameStore } from '@/stores/gameStore'
 import { useZoneEditorStore } from '@/stores/zoneEditorStore'
-import { type Zone } from '@/types'
+import { type AssetT, type Zone } from '@/types'
 
 // Components
 import Toolbar from '@/components/gameMaster/zoneEditor/partials/Toolbar.vue'
@@ -29,11 +32,14 @@ import TeleportModal from '@/components/gameMaster/zoneEditor/partials/TeleportM
 import ZoneTiles from '@/components/gameMaster/zoneEditor/ZoneTiles.vue'
 import ZoneObjects from '@/components/gameMaster/zoneEditor/ZoneObjects.vue'
 import ZoneEventTiles from '@/components/gameMaster/zoneEditor/ZoneEventTiles.vue'
+import config from '@/config'
+import { loadZoneTileTexture } from '@/composables/zoneComposable'
 
+const scene = useScene()
 const gameStore = useGameStore()
 const zoneEditorStore = useZoneEditorStore()
-
 const tileMap = ref(null as Phaser.Tilemaps.Tilemap | null)
+const isLoaded = ref(false)
 
 function save() {
   if (!zoneEditorStore.zone) return
@@ -59,6 +65,14 @@ function save() {
   })
 }
 
+onMounted(async () => {
+  const tiles: AssetT[] = await fetch(config.server_endpoint + '/assets/list_tiles').then((response) => response.json())
+  for (const tile of tiles) {
+    await loadZoneTileTexture(scene, tile.key, tile.updatedAt)
+  }
+  isLoaded.value = true
+})
+
 onUnmounted(() => {
   zoneEditorStore.reset()
 })
diff --git a/src/components/gui/ResetPassword.vue b/src/components/gui/ResetPassword.vue
index 0133a37..ebe7bb0 100644
--- a/src/components/gui/ResetPassword.vue
+++ b/src/components/gui/ResetPassword.vue
@@ -1,5 +1,5 @@
 <template>
-    <Modal :is-modal-open="gameStore.uiSettings.isPasswordResetOpen" @modal:close="() => gameStore.togglePasswordReset()" :modal-width="400" :modal-height="300" :is-resizable="false">
+  <Modal :is-modal-open="gameStore.uiSettings.isPasswordResetOpen" @modal:close="() => gameStore.togglePasswordReset()" :modal-width="400" :modal-height="300" :is-resizable="false">
     <template #modalHeader>
       <h3 class="m-0 font-medium shrink-0 text-white">Reset Password</h3>
     </template>
@@ -47,4 +47,4 @@ async function resetPasswordFunc() {
     return
   }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/utilities/Modal.vue b/src/components/utilities/Modal.vue
index 4ba47ca..81792a7 100644
--- a/src/components/utilities/Modal.vue
+++ b/src/components/utilities/Modal.vue
@@ -223,23 +223,23 @@ watch(
 )
 
 onMounted(() => {
-  window.addEventListener('mousemove', drag)
-  window.addEventListener('mouseup', stopDrag)
-  window.addEventListener('mousemove', resizeModal)
-  window.addEventListener('mouseup', stopResize)
+  addEventListener('mousemove', drag)
+  addEventListener('mouseup', stopDrag)
+  addEventListener('mousemove', resizeModal)
+  addEventListener('mouseup', stopResize)
   if (props.modalPositionX !== 0 && props.modalPositionY !== 0) {
-    window.addEventListener('resize', handleResize)
+    addEventListener('resize', handleResize)
   }
   initializePosition()
 })
 
 onUnmounted(() => {
-  window.removeEventListener('mousemove', drag)
-  window.removeEventListener('mouseup', stopDrag)
-  window.removeEventListener('mousemove', resizeModal)
-  window.removeEventListener('mouseup', stopResize)
+  removeEventListener('mousemove', drag)
+  removeEventListener('mouseup', stopDrag)
+  removeEventListener('mousemove', resizeModal)
+  removeEventListener('mouseup', stopResize)
   if (props.modalPositionX !== 0 && props.modalPositionY !== 0) {
-    window.removeEventListener('resize', handleResize)
+    removeEventListener('resize', handleResize)
   }
 })
 </script>
diff --git a/src/composables/zoneComposable.ts b/src/composables/zoneComposable.ts
index a640927..678d03e 100644
--- a/src/composables/zoneComposable.ts
+++ b/src/composables/zoneComposable.ts
@@ -4,8 +4,7 @@ import TilemapLayer = Phaser.Tilemaps.TilemapLayer
 import Tileset = Phaser.Tilemaps.Tileset
 import Tile = Phaser.Tilemaps.Tile
 import { useAssetManager } from '@/managers/assetManager'
-import type { Zone as ZoneT } from '@/types'
-import { unduplicateArray } from '@/utilities'
+import type { AssetT, Zone as ZoneT } from '@/types'
 
 export function getTile(layer: TilemapLayer | Tilemap, x: number, y: number): Tile | undefined {
   const tile = layer.getTileAtWorldXY(x, y)
@@ -48,6 +47,7 @@ export function tileToWorldY(layer: TilemapLayer | Tilemap, pos_x: number, pos_y
 export function placeTile(zone: Tilemap, layer: TilemapLayer, x: number, y: number, tileName: string) {
   let tileImg = zone.getTileset(tileName) as Tileset
   if (!tileImg) {
+    console.log('tile not found:', tileName)
     tileImg = zone.getTileset('blank_tile') as Tileset
   }
   layer.putTileAt(tileImg.firstgid, x, y)
@@ -86,9 +86,10 @@ export function FlattenZoneArray(tiles: string[][]) {
 }
 
 export async function loadZoneTilesIntoScene(zone: ZoneT, scene: Phaser.Scene) {
-  const tileArray = unduplicateArray(FlattenZoneArray(zone.tiles))
+  const tileArray: AssetT[] = await fetch(config.server_endpoint + '/assets/list_tiles/' + zone.id).then((response) => response.json())
+  console.log(tileArray)
   for (const tile of tileArray) {
-    await loadZoneTileTexture(scene, tile, new Date())
+    await loadZoneTileTexture(scene, tile.key, tile.updatedAt)
   }
 }
 
diff --git a/src/managers/assetManager.ts b/src/managers/assetManager.ts
index 087c15a..083cf33 100644
--- a/src/managers/assetManager.ts
+++ b/src/managers/assetManager.ts
@@ -24,8 +24,17 @@ class AssetManager extends Dexie {
 
   async downloadAsset(key: string, url: string, group: string, updatedAt: Date, frameCount?: number, frameWidth?: number, frameHeight?: number) {
     try {
+      // Check if the asset already exists, then check if updatedAt is newer
+      const asset = await this.assets.get(key)
+      if (asset && asset.updatedAt > updatedAt) {
+        return
+      }
+
+      // Download the asset
       const response = await fetch(config.server_endpoint + url)
       const blob = await response.blob()
+
+      // Store the asset in the database
       await this.assets.put({ key, data: blob, group, updatedAt, frameCount, frameWidth, frameHeight })
     } catch (error) {
       console.error(`Failed to add asset ${key}:`, error)
diff --git a/src/screens/ZoneEditor.vue b/src/screens/ZoneEditor.vue
index 57f4d65..df46290 100644
--- a/src/screens/ZoneEditor.vue
+++ b/src/screens/ZoneEditor.vue
@@ -11,17 +11,16 @@
 <script setup lang="ts">
 import config from '@/config'
 import 'phaser'
-import { ref } from 'vue'
 import { Game, Scene } from 'phavuer'
 import { useGameStore } from '@/stores/gameStore'
 import { useZoneEditorStore } from '@/stores/zoneEditorStore'
 import ZoneEditor from '@/components/gameMaster/zoneEditor/ZoneEditor.vue'
 import AwaitLoaderPlugin from 'phaser3-rex-plugins/plugins/awaitloader-plugin'
-import { useAssetManager } from '@/managers/assetManager'
+import { loadZoneTilesIntoScene, loadZoneTileTexture } from '@/composables/zoneComposable'
+import type { AssetT, Tile } from '@/types'
 
 const gameStore = useGameStore()
 const zoneEditorStore = useZoneEditorStore()
-const assetManager = useAssetManager
 
 const gameConfig = {
   name: config.name,
@@ -66,45 +65,7 @@ const preloadScene = async (scene: Phaser.Scene) => {
   scene.load.image('TELEPORT', '/assets/zone/tp_tile.png')
   scene.load.image('blank_tile', '/assets/zone/blank_tile.png')
   scene.load.image('waypoint', '/assets/waypoint.png')
-
-  /**
-   *  We're using rex-await-loader to load assets asynchronously
-   *  Phaser does not support this out of the box, so we're using this plugin
-   */
-  // scene.load.rexAwait(async function (successCallback) {
-  //   await assetManager.getAssetsByGroup('tiles').then((assets) => {
-  //     assets.forEach((asset) => {
-  //       if (scene.load.textureManager.exists(asset.key)) return
-  //       scene.textures.addBase64(asset.key, asset.data)
-  //     })
-  //   })
-  //
-  //   // Load objects
-  //   await assetManager.getAssetsByGroup('objects').then((assets) => {
-  //     assets.forEach((asset) => {
-  //       if (scene.load.textureManager.exists(asset.key)) return
-  //       scene.textures.addBase64(asset.key, asset.data)
-  //     })
-  //   })
-  //
-  //   successCallback()
-  // })
 }
 
-const createScene = async (scene: Phaser.Scene) => {
-  /**
-   * Create sprite animations
-   * This is done here because phaser forces us to
-   */
-  // assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
-  //   assets.forEach((asset) => {
-  //     scene.anims.create({
-  //       key: asset.key,
-  //       frameRate: 7,
-  //       frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
-  //       repeat: -1
-  //     })
-  //   })
-  // })
-}
+const createScene = async (scene: Phaser.Scene) => {}
 </script>
diff --git a/src/services/authentication.ts b/src/services/authentication.ts
index 4c9ab2a..ccf778f 100644
--- a/src/services/authentication.ts
+++ b/src/services/authentication.ts
@@ -33,4 +33,4 @@ export async function resetPassword(email: string) {
   } catch (error: any) {
     return { error: error.response.data.message }
   }
-}
\ No newline at end of file
+}
diff --git a/src/utilities.ts b/src/utilities.ts
index 0567050..905dc81 100644
--- a/src/utilities.ts
+++ b/src/utilities.ts
@@ -4,4 +4,4 @@ export function uuidv4() {
 
 export function unduplicateArray(array: any[]) {
   return [...new Set(array.flat())]
-}
\ No newline at end of file
+}