diff --git a/package-lock.json b/package-lock.json index a97d82e..e022937 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1244,9 +1244,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.0.tgz", - "integrity": "sha512-qFcFto9figFLz2g25DxJ1WWL9+c91fTxnGuwhToCl8BaqDsDYMl/kOnBXAyAqkkzAWimYMSWNPWEjt+ADAHuoQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", "cpu": [ "arm" ], @@ -1258,9 +1258,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.0.tgz", - "integrity": "sha512-vqrQdusvVl7dthqNjWCL043qelBK+gv9v3ZiqdxgaJvmZyIAAXMjeGVSqZynKq69T7062T5VrVTuikKSAAVP6A==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", "cpu": [ "arm64" ], @@ -1272,9 +1272,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.0.tgz", - "integrity": "sha512-617pd92LhdA9+wpixnzsyhVft3szYiN16aNUMzVkf2N+yAk8UXY226Bfp36LvxYTUt7MO/ycqGFjQgJ0wlMaWQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", "cpu": [ "arm64" ], @@ -1286,9 +1286,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.0.tgz", - "integrity": "sha512-Y3b4oDoaEhCypg8ajPqigKDcpi5ZZovemQl9Edpem0uNv6UUjXv7iySBpGIUTSs2ovWOzYpfw9EbFJXF/fJHWw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", "cpu": [ "x64" ], @@ -1300,9 +1300,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.0.tgz", - "integrity": "sha512-3REQJ4f90sFIBfa0BUokiCdrV/E4uIjhkWe1bMgCkhFXbf4D8YN6C4zwJL881GM818qVYE9BO3dGwjKhpo2ABA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", "cpu": [ "arm64" ], @@ -1314,9 +1314,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.0.tgz", - "integrity": "sha512-ZtY3Y8icbe3Cc+uQicsXG5L+CRGUfLZjW6j2gn5ikpltt3Whqjfo5mkyZ86UiuHF9Q3ZsaQeW7YswlHnN+lAcg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", "cpu": [ "x64" ], @@ -1328,9 +1328,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.0.tgz", - "integrity": "sha512-bsPGGzfiHXMhQGuFGpmo2PyTwcrh2otL6ycSZAFTESviUoBOuxF7iBbAL5IJXc/69peXl5rAtbewBFeASZ9O0g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", "cpu": [ "arm" ], @@ -1342,9 +1342,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.0.tgz", - "integrity": "sha512-kvyIECEhs2DrrdfQf++maCWJIQ974EI4txlz1nNSBaCdtf7i5Xf1AQCEJWOC5rEBisdaMFFnOWNLYt7KpFqy5A==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", "cpu": [ "arm" ], @@ -1356,9 +1356,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.0.tgz", - "integrity": "sha512-CFE7zDNrokaotXu+shwIrmWrFxllg79vciH4E/zeK7NitVuWEaXRzS0mFfFvyhZfn8WfVOG/1E9u8/DFEgK7WQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", "cpu": [ "arm64" ], @@ -1370,9 +1370,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.0.tgz", - "integrity": "sha512-MctNTBlvMcIBP0t8lV/NXiUwFg9oK5F79CxLU+a3xgrdJjfBLVIEHSAjQ9+ipofN2GKaMLnFFXLltg1HEEPaGQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", "cpu": [ "arm64" ], @@ -1384,9 +1384,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.0.tgz", - "integrity": "sha512-fBpoYwLEPivL3q368+gwn4qnYnr7GVwM6NnMo8rJ4wb0p/Y5lg88vQRRP077gf+tc25akuqd+1Sxbn9meODhwA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", "cpu": [ "loong64" ], @@ -1398,9 +1398,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.0.tgz", - "integrity": "sha512-1hiHPV6dUaqIMXrIjN+vgJqtfkLpqHS1Xsg0oUfUVD98xGp1wX89PIXgDF2DWra1nxAd8dfE0Dk59MyeKaBVAw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", "cpu": [ "ppc64" ], @@ -1412,9 +1412,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.0.tgz", - "integrity": "sha512-U0xcC80SMpEbvvLw92emHrNjlS3OXjAM0aVzlWfar6PR0ODWCTQtKeeB+tlAPGfZQXicv1SpWwRz9Hyzq3Jx3g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", "cpu": [ "riscv64" ], @@ -1426,9 +1426,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.0.tgz", - "integrity": "sha512-VU/P/IODrNPasgZDLIFJmMiLGez+BN11DQWfTVlViJVabyF3JaeaJkP6teI8760f18BMGCQOW9gOmuzFaI1pUw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", "cpu": [ "s390x" ], @@ -1440,9 +1440,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.0.tgz", - "integrity": "sha512-laQVRvdbKmjXuFA3ZiZj7+U24FcmoPlXEi2OyLfbpY2MW1oxLt9Au8q9eHd0x6Pw/Kw4oe9gwVXWwIf2PVqblg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", "cpu": [ "x64" ], @@ -1454,9 +1454,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.0.tgz", - "integrity": "sha512-3wzKzduS7jzxqcOvy/ocU/gMR3/QrHEFLge5CD7Si9fyHuoXcidyYZ6jyx8OPYmCcGm3uKTUl+9jUSAY74Ln5A==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", "cpu": [ "x64" ], @@ -1468,9 +1468,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.0.tgz", - "integrity": "sha512-jROwnI1+wPyuv696rAFHp5+6RFhXGGwgmgSfzE8e4xfit6oLRg7GyMArVUoM3ChS045OwWr9aTnU+2c1UdBMyw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", "cpu": [ "arm64" ], @@ -1482,9 +1482,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.0.tgz", - "integrity": "sha512-duzweyup5WELhcXx5H1jokpr13i3BV9b48FMiikYAwk/MT1LrMYYk2TzenBd0jj4ivQIt58JWSxc19y4SvLP4g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", "cpu": [ "ia32" ], @@ -1496,9 +1496,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.0.tgz", - "integrity": "sha512-DYvxS0M07PvgvavMIybCOBYheyrqlui6ZQBHJs6GqduVzHSZ06TPPvlfvnYstjODHQ8UUXFwt5YE+h0jFI8kwg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", "cpu": [ "x64" ], @@ -1510,9 +1510,9 @@ ] }, "node_modules/@rushstack/eslint-patch": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", - "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.5.tgz", + "integrity": "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==", "dev": true, "license": "MIT" }, @@ -2948,9 +2948,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.76", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", - "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", + "version": "1.5.78", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.78.tgz", + "integrity": "sha512-UmwIt7HRKN1rsJfddG5UG7rCTCTAKoS9JeOy/R0zSenAyaZ8SU3RuXlwcratxhdxGRNpk03iq8O7BA3W7ibLVw==", "dev": true, "license": "ISC" }, @@ -5425,9 +5425,9 @@ } }, "node_modules/rollup": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.0.tgz", - "integrity": "sha512-sDnr1pcjTgUT69qBksNF1N1anwfbyYG6TBQ22b03bII8EdiUQ7J0TlozVaTMjT/eEJAO49e1ndV7t+UZfL1+vA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", "dev": true, "license": "MIT", "dependencies": { @@ -5441,25 +5441,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.30.0", - "@rollup/rollup-android-arm64": "4.30.0", - "@rollup/rollup-darwin-arm64": "4.30.0", - "@rollup/rollup-darwin-x64": "4.30.0", - "@rollup/rollup-freebsd-arm64": "4.30.0", - "@rollup/rollup-freebsd-x64": "4.30.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.30.0", - "@rollup/rollup-linux-arm-musleabihf": "4.30.0", - "@rollup/rollup-linux-arm64-gnu": "4.30.0", - "@rollup/rollup-linux-arm64-musl": "4.30.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.30.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.30.0", - "@rollup/rollup-linux-riscv64-gnu": "4.30.0", - "@rollup/rollup-linux-s390x-gnu": "4.30.0", - "@rollup/rollup-linux-x64-gnu": "4.30.0", - "@rollup/rollup-linux-x64-musl": "4.30.0", - "@rollup/rollup-win32-arm64-msvc": "4.30.0", - "@rollup/rollup-win32-ia32-msvc": "4.30.0", - "@rollup/rollup-win32-x64-msvc": "4.30.0", + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", "fsevents": "~2.3.2" } }, diff --git a/src/App.vue b/src/App.vue index 898ff90..cce5d03 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,4 +1,5 @@ <template> + <Debug /> <Notifications /> <BackgroundImageLoader /> <GmPanel v-if="gameStore.character?.role === 'gm'" /> @@ -16,7 +17,8 @@ import BackgroundImageLoader from '@/components/utilities/BackgroundImageLoader. import Notifications from '@/components/utilities/Notifications.vue' import { useGameStore } from '@/stores/gameStore' import { useMapEditorStore } from '@/stores/mapEditorStore' -import { computed, watch } from 'vue' +import { computed, onMounted, onUnmounted, watch } from 'vue' +import Debug from '@/components/utilities/Debug.vue' const gameStore = useGameStore() const mapEditorStore = useMapEditorStore() diff --git a/src/application/types.ts b/src/application/types.ts index f1f0998..b3dc3f3 100644 --- a/src/application/types.ts +++ b/src/application/types.ts @@ -174,10 +174,9 @@ export type Character = { positionX: number positionY: number rotation: number - characterType: CharacterType | null | string - characterHair: CharacterHair | null - mapId: UUID - map: Map + characterType: UUID | null + characterHair: UUID | null + map: UUID chats: Chat[] items: CharacterItem[] equipment: CharacterEquipment[] @@ -256,6 +255,6 @@ export type WeatherState = { } export type mapLoadData = { - map: Map + mapId: UUID characters: MapCharacter[] } diff --git a/src/components/game/character/Character.vue b/src/components/game/character/Character.vue index 9a88243..aeae488 100644 --- a/src/components/game/character/Character.vue +++ b/src/components/game/character/Character.vue @@ -2,7 +2,7 @@ <ChatBubble :mapCharacter="props.mapCharacter" :currentX="currentX" :currentY="currentY" /> <Healthbar :mapCharacter="props.mapCharacter" :currentX="currentX" :currentY="currentY" /> <Container ref="charContainer" :depth="isometricDepth" :x="currentX" :y="currentY"> - <CharacterHair :mapCharacter="props.mapCharacter" :currentX="currentX" :currentY="currentY" /> +<!-- <CharacterHair :mapCharacter="props.mapCharacter" :currentX="currentX" :currentY="currentY" />--> <!-- <CharacterChest :mapCharacter="props.mapCharacter" :currentX="currentX" :currentY="currentY" />--> <Sprite ref="charSprite" :origin-y="1" :flipX="isFlippedX" /> </Container> @@ -109,7 +109,7 @@ const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.r const charTexture = computed(() => { const { rotation, characterType } = props.mapCharacter.character - const spriteId = characterType?.sprite ?? 'idle_right_down' + const spriteId = characterType ?? 'idle_right_down' const action = props.mapCharacter.isMoving ? 'walk' : 'idle' const direction = [0, 6].includes(rotation) ? 'left_up' : 'right_down' @@ -152,7 +152,7 @@ watch( watch(() => props.mapCharacter, updateSprite) -loadSpriteTextures(scene, props.mapCharacter.character.characterType?.sprite as string) +loadSpriteTextures(scene, props.mapCharacter.character.characterType as string) .then(() => { charSprite.value!.setTexture(charTexture.value) charSprite.value!.setFlipX(isFlippedX.value) diff --git a/src/components/game/map/Map.vue b/src/components/game/map/Map.vue index 913c398..9b5a22c 100644 --- a/src/components/game/map/Map.vue +++ b/src/components/game/map/Map.vue @@ -1,11 +1,11 @@ <template> - <MapTiles :key="mapStore.map?.id ?? 0" @tileMap:create="tileMap = $event" /> + <MapTiles :key="mapStore.mapId" @tileMap:create="tileMap = $event" /> <MapObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" /> <Characters v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" /> </template> <script setup lang="ts"> -import type { MapCharacter, mapLoadData, UUID } from '@/application/types' +import type { MapCharacter, mapLoadData, UUID, Map } from '@/application/types' import Characters from '@/components/game/map/Characters.vue' import MapTiles from '@/components/game/map/MapTiles.vue' import MapObjects from '@/components/game/map/PlacedMapObjects.vue' @@ -14,10 +14,13 @@ import { useGameStore } from '@/stores/gameStore' import { useMapStore } from '@/stores/mapStore' import { useScene } from 'phavuer' import { onUnmounted, ref, shallowRef } from 'vue' +import { MapStorage } from '@/storage/storages' const scene = useScene() const gameStore = useGameStore() const mapStore = useMapStore() +const mapStorage = new MapStorage() +const mapData = ref<Map>() const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>() @@ -31,8 +34,7 @@ onUnmounted(() => { // Event listeners gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) => { - await loadMapTilesIntoScene(data.map.id, scene) - mapStore.setMap(data.map) + mapStore.setMapId(data.mapId) mapStore.setCharacters(data.characters) }) diff --git a/src/components/game/map/MapTiles.vue b/src/components/game/map/MapTiles.vue index f72f0b9..22f473b 100644 --- a/src/components/game/map/MapTiles.vue +++ b/src/components/game/map/MapTiles.vue @@ -1,57 +1,54 @@ <template> - <Controls :layer="tileLayer" :depth="0" /> + <Controls v-if="isInitialized" :layer="tileLayer" :depth="0" /> </template> <script setup lang="ts"> import config from '@/application/config' import { unduplicateArray } from '@/application/utilities' import Controls from '@/components/utilities/Controls.vue' -import { FlattenMapArray, setLayerTiles } from '@/composables/mapComposable' +import { FlattenMapArray, loadMapTilesIntoScene, setLayerTiles } from '@/composables/mapComposable' import { useMapStore } from '@/stores/mapStore' import { useScene } from 'phavuer' -import { onBeforeUnmount } from 'vue' +import { onBeforeUnmount, onMounted, ref } from 'vue' +import { MapStorage } from '@/storage/storages' +import type { UUID } from '@/application/types' const emit = defineEmits(['tileMap:create']) const scene = useScene() const mapStore = useMapStore() -const tileMap = createTileMap() -const tileLayer = createTileLayer() +const mapStorage = new MapStorage() -/** - * A Tilemap is a container for Tilemap data. - * This isn't a display object, rather, it holds data about the map and allows you to add tilesets and tilemap layers to it. - * A map can have one or more tilemap layers, which are the display objects that actually render the tiles. - */ -function createTileMap() { - const mapData = new Phaser.Tilemaps.MapData({ - width: mapStore.map?.width, - height: mapStore.map?.height, +let tileMap: Phaser.Tilemaps.Tilemap +let tileLayer: Phaser.Tilemaps.TilemapLayer +let isInitialized = ref(false) + +function createTileMap(mapData: any) { + const mapConfig = new Phaser.Tilemaps.MapData({ + width: mapData?.width, + height: mapData?.height, tileWidth: config.tile_size.x, tileHeight: config.tile_size.y, orientation: Phaser.Tilemaps.Orientation.ISOMETRIC, format: Phaser.Tilemaps.Formats.ARRAY_2D }) - const newTileMap = new Phaser.Tilemaps.Tilemap(scene, mapData) + const newTileMap = new Phaser.Tilemaps.Tilemap(scene, mapConfig) emit('tileMap:create', newTileMap) return newTileMap } -/** - * A Tileset is a combination of a single image containing the tiles and a container for data about each tile. - */ -function createTileLayer() { - const tilesArray = unduplicateArray(FlattenMapArray(mapStore.map?.tiles ?? [])) +function createTileLayer(mapData: any) { + const tilesArray = unduplicateArray(FlattenMapArray(mapData?.tiles ?? [])) const tilesetImages = Array.from(tilesArray).map((tile: any, index: number) => { return tileMap.addTilesetImage(tile, tile, config.tile_size.x, config.tile_size.y, 1, 2, index + 1, { x: 0, y: -config.tile_size.y }) - }) as any + }) // Add blank tile tilesetImages.push(tileMap.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.x, config.tile_size.y, 1, 2, 0, { x: 0, y: -config.tile_size.y })) - const layer = tileMap.createBlankLayer('tiles', tilesetImages, 0, config.tile_size.y) as Phaser.Tilemaps.TilemapLayer + const layer = tileMap.createBlankLayer('tiles', tilesetImages as any, 0, config.tile_size.y) as Phaser.Tilemaps.TilemapLayer layer.setDepth(0) layer.setCullPadding(2, 2) @@ -59,11 +56,28 @@ function createTileLayer() { return layer } -setLayerTiles(tileMap, tileLayer, mapStore.map?.tiles) +async function initialize() { + try { + await loadMapTilesIntoScene(mapStore.mapId as UUID, scene) + const mapData = await mapStorage.get(mapStore.mapId) + tileMap = createTileMap(mapData) + tileLayer = createTileLayer(mapData) + setLayerTiles(tileMap, tileLayer, mapData?.tiles) + isInitialized.value = true + } catch (error) { + console.error('Failed to initialize map:', error) + } +} + +onMounted(() => { + initialize() +}) onBeforeUnmount(() => { - tileMap.destroyLayer('tiles') - tileMap.removeAllLayers() - tileMap.destroy() + if (tileMap) { + tileMap.destroyLayer('tiles') + tileMap.removeAllLayers() + tileMap.destroy() + } }) -</script> +</script> \ No newline at end of file diff --git a/src/components/game/map/partials/PlacedMapObject.vue b/src/components/game/map/partials/PlacedMapObject.vue index 2dd3526..6d0c94e 100644 --- a/src/components/game/map/partials/PlacedMapObject.vue +++ b/src/components/game/map/partials/PlacedMapObject.vue @@ -1,5 +1,5 @@ <template> - <Image v-if="gameStore.getLoadedAsset(props.placedMapObject.mapObject.id)" v-bind="imageProps" /> + <Image v-if="gameStore.isAssetLoaded(props.placedMapObject.mapObject)" v-bind="imageProps" /> </template> <script setup lang="ts"> diff --git a/src/components/screens/Characters.vue b/src/components/screens/Characters.vue index b806776..ec3fb1e 100644 --- a/src/components/screens/Characters.vue +++ b/src/components/screens/Characters.vue @@ -34,27 +34,23 @@ <button class="ml-6 w-4 h-8 p-0"> <img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 m-auto" alt="Arrow left" /> </button> - <img class="w-24 object-contain mb-3.5" alt="Player avatar" :src="config.server_endpoint + '/avatar/s/' + characters.find((c) => c.id === selectedCharacterId)?.characterType?.id + '/' + (selectedHairId ?? 'default')" /> + <img class="w-24 object-contain mb-3.5" alt="Player avatar" :src="config.server_endpoint + '/avatar/s/' + characters.find((c) => c.id === selectedCharacterId)?.characterType + '/' + (selectedHairId ?? 'default')" /> <button class="mr-6 w-4 h-8 p-0"> <img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 -scale-x-100" alt="Arrow right" /> </button> </div> - <!-- <div class="flex justify-between w-[190px]">--> - <!-- <!– TODO: replace with color swatches –>--> - <!-- <button v-for="n in 9" class="w-4 h-4 rounded-sm bg-white"></button>--> - <!-- </div>--> </div> <!-- TODO: update gender on (selected) character --> - <div class="flex justify-between w-[190px]"> - <button class="btn-empty flex gap-2" :class="{ selected: characters.find((c) => c.id == selectedCharacterId)?.characterType?.gender === 'MALE' }"> - <img src="/assets/icons/male-icon.svg" class="w-4 h-4 m-auto" alt="Male symbol" /> - <span class="text-white">Male</span> - </button> - <button class="btn-empty flex gap-2" :class="{ selected: characters.find((c) => c.id == selectedCharacterId)?.characterType?.gender === 'FEMALE' }"> - <img src="/assets/icons/male-icon.svg" class="w-4 h-4 m-auto" alt="Male symbol" /> - <span class="text-white">Female</span> - </button> - </div> +<!-- <div class="flex justify-between w-[190px]">--> +<!-- <button class="btn-empty flex gap-2" :class="{ selected: characters.find((c) => c.id == selectedCharacterId)?.characterType?.gender === 'MALE' }">--> +<!-- <img src="/assets/icons/male-icon.svg" class="w-4 h-4 m-auto" alt="Male symbol" />--> +<!-- <span class="text-white">Male</span>--> +<!-- </button>--> +<!-- <button class="btn-empty flex gap-2" :class="{ selected: characters.find((c) => c.id == selectedCharacterId)?.characterType?.gender === 'FEMALE' }">--> +<!-- <img src="/assets/icons/male-icon.svg" class="w-4 h-4 m-auto" alt="Male symbol" />--> +<!-- <span class="text-white">Female</span>--> +<!-- </button>--> +<!-- </div>--> </div> </div> </div> @@ -74,7 +70,7 @@ v-for="hair in characterHairs" class="relative flex justify-center items-center bg-gray default-border w-[18px] h-[18px] p-2 rounded-sm hover:bg-gray-500 hover:border-gray-400 focus-visible:outline-none focus-visible:border-gray-300 focus-visible:bg-gray-500 has-[:checked]:bg-cyan has-[:checked]:border-transparent" > - <img class="h-4 object-contain" :src="config.server_endpoint + '/textures/sprites/' + hair.sprite?.id + '/front.png'" alt="Hair sprite" /> + <img class="h-4 object-contain" :src="config.server_endpoint + '/textures/sprites/' + hair.sprite + '/front.png'" alt="Hair sprite" /> <input type="radio" name="hair" :value="hair.id" v-model="selectedHairId" class="h-full w-full absolute left-0 top-0 m-0 z-10 hover:cursor-pointer focus-visible:outline-offset-0 focus-visible:outline-white" /> </div> </div> @@ -129,7 +125,8 @@ import config from '@/application/config' import { type CharacterHair, type Character as CharacterT, type Map } from '@/application/types' import Modal from '@/components/utilities/Modal.vue' import { useGameStore } from '@/stores/gameStore' -import { onBeforeUnmount, ref, watch } from 'vue' +import { onBeforeUnmount, onMounted, ref, watch } from 'vue' +import { CharacterHairStorage } from '@/storage/storages' const gameStore = useGameStore() const isLoading = ref<boolean>(true) @@ -140,6 +137,7 @@ const newCharacterName = ref<string>('') const characterHairs = ref<CharacterHair[]>([]) const selectedHairId = ref<number | null>(null) + // Fetch characters setTimeout(() => { gameStore.connection?.emit('character:list') @@ -148,12 +146,6 @@ setTimeout(() => { gameStore.connection?.on('character:list', (data: any) => { characters.value = data isLoading.value = false - - // Fetch hairs - // @TODO: This is hacky, we should have a better way to do this - gameStore.connection?.emit('character:hair:list', {}, (data: CharacterHair[]) => { - characterHairs.value = data - }) }) // Select character logics @@ -184,7 +176,13 @@ function createCharacter() { // Watch changes for selected character and update hairs watch(selectedCharacterId, (characterId) => { if (!characterId) return - selectedHairId.value = characters.value.find((c) => c.id == characterId)?.characterHairId ?? null + // selectedHairId.value = characters.value.find((c) => c.id == characterId)?.characterHairId ?? null +}) + +onMounted(async () => { + const characterHairStorage = new CharacterHairStorage() + characterHairs.value = await characterHairStorage.getAll() + console.log(characterHairs.value) }) onBeforeUnmount(() => { diff --git a/src/components/screens/Loading.vue b/src/components/screens/Loading.vue index 7cdee15..044fcc8 100644 --- a/src/components/screens/Loading.vue +++ b/src/components/screens/Loading.vue @@ -17,63 +17,53 @@ <script setup lang="ts" async> import config from '@/application/config' import type { HttpResponse, MapObject } from '@/application/types' -import { MapObjectStorage } from '@/dexie/mapObjects' -import { MapStorage } from '@/dexie/maps' // import type { Map } from '@/application/types' -import type { Map } from '@/dexie/maps' import { useGameStore } from '@/stores/gameStore' import { ref } from 'vue' +import type { BaseStorage } from '@/storage/baseStorage' +import { + CharacterHairStorage, + CharacterTypeStorage, + MapObjectStorage, + MapStorage, SpriteStorage, + TileStorage +} from '@/storage/storages' const gameStore = useGameStore() -const mapStorage = new MapStorage() -const mapObjectStorage = new MapObjectStorage() - const totalItems = ref(0) const currentItem = ref(0) -/** - * Download map cache from the server and add them to the storage - */ -async function downloadMaps() { - // Request to download maps - const request = await fetch(config.server_endpoint + '/cache/maps') - const response = (await request.json()) as HttpResponse<Map[]> +async function downloadAndStore<T extends { id: string }>( + endpoint: string, + storage: BaseStorage<T> +) { + const request = await fetch(`${config.server_endpoint}/cache/${endpoint}`) + const response = (await request.json()) as HttpResponse<T[]> + if (!response.success) { - console.error('Failed to download maps:', response.message) + console.error(`Failed to download ${endpoint}:`, response.message) return } - const maps = response.data ?? ([] as Map[]) - - // Add maps to storage - for (const map of maps) { - await mapStorage.add(map) + const items = response.data ?? [] + for (const item of items) { + await storage.add(item) } } -/** - * Download map objects cache from the server and add them to the storage - */ -async function downloadMapObjects() { - // Request to download map objects - const request = await fetch(config.server_endpoint + '/cache/map_objects') - const response = (await request.json()) as HttpResponse<MapObject[]> - if (!response.success) { - console.error('Failed to download map objects:', response.message) - return - } +const tileStorage = new TileStorage() +const mapStorage = new MapStorage() +const mapObjectStorage = new MapObjectStorage() - const mapObjects = response.data ?? ([] as MapObject[]) - - // Add map objects to storage - for (const mapObject of mapObjects) { - await mapObjectStorage.add(mapObject) - } -} - -Promise.all([downloadMaps(), downloadMapObjects()]).then(() => { - // Set isLoaded to true +Promise.all([ + downloadAndStore('tiles', tileStorage), + downloadAndStore('maps', mapStorage), + downloadAndStore('map_objects', mapObjectStorage), + downloadAndStore('sprites', new SpriteStorage()), + downloadAndStore('character_types', new CharacterTypeStorage()), + downloadAndStore('character_hair', new CharacterHairStorage()) +]).then(() => { gameStore.game.isLoaded = true }) </script> diff --git a/src/components/utilities/Debug.vue b/src/components/utilities/Debug.vue new file mode 100644 index 0000000..b907d85 --- /dev/null +++ b/src/components/utilities/Debug.vue @@ -0,0 +1,55 @@ +<template> + +</template> + +<script setup lang="ts"> +import { onMounted, onUnmounted } from 'vue' +import { + CharacterHairStorage, + CharacterTypeStorage, + MapObjectStorage, + MapStorage, SpriteStorage, + TileStorage +} from '@/storage/storages' +import { TextureStorage } from '@/storage/textureStorage' + +const mapStorage = new MapStorage() +const tileStorage = new TileStorage() +const mapObjectStorage = new MapObjectStorage() +const spriteStorage = new SpriteStorage() +const characterTypeStorage = new CharacterTypeStorage() +const characterHairStorage = new CharacterHairStorage() +const textureStorage = new TextureStorage() + +let currentString = '' + +async function handleKeyPress(event: KeyboardEvent) { + // Ignore if typing in input/textarea + if (document.activeElement?.tagName.toUpperCase() === 'INPUT' || + document.activeElement?.tagName.toUpperCase() === 'TEXTAREA') { + return + } + + currentString += event.key + + // Do something when string matches + if (currentString.includes('reset')) { + await mapStorage.destroy() + await tileStorage.destroy() + await mapObjectStorage.destroy() + await spriteStorage.destroy() + await characterTypeStorage.destroy() + await characterHairStorage.destroy() + await textureStorage.destroy() + currentString = '' // Reset + } + + // Reset string after a certain amount of time + setTimeout(() => { + currentString = '' + }, 60000) +} + +onMounted(() => window.addEventListener('keydown', handleKeyPress)) +onUnmounted(() => window.removeEventListener('keydown', handleKeyPress)) +</script> \ No newline at end of file diff --git a/src/composables/gameComposable.ts b/src/composables/gameComposable.ts index 106761f..8ce095f 100644 --- a/src/composables/gameComposable.ts +++ b/src/composables/gameComposable.ts @@ -1,13 +1,14 @@ import config from '@/application/config' import type { HttpResponse, Sprite, SpriteAction, TextureData } from '@/application/types' -import { Textures } from '@/dexie/textures' +import { TextureStorage } from '@/storage/textureStorage' import { useGameStore } from '@/stores/gameStore' +import { SpriteStorage } from '@/storage/storages' const textureLoadingPromises = new Map<string, Promise<boolean>>() export async function loadTexture(scene: Phaser.Scene, textureData: TextureData): Promise<boolean> { const gameStore = useGameStore() - const textures = new Textures() + const textureStorage = new TextureStorage() // Check if the texture is already loaded in Phaser if (gameStore.game.loadedAssets.find((asset) => asset.key === textureData.key)) { @@ -22,12 +23,12 @@ export async function loadTexture(scene: Phaser.Scene, textureData: TextureData) // Create new loading promise const loadingPromise = (async () => { // Check if the asset is already cached - let texture = await textures.get(textureData.key) + let texture = await textureStorage.get(textureData.key) // If asset is not found, download it if (!texture) { - await textures.download(textureData) - texture = await textures.get(textureData.key) + await textureStorage.download(textureData) + texture = await textureStorage.get(textureData.key) } // If asset is found, add it to the scene @@ -60,9 +61,12 @@ export async function loadSpriteTextures(scene: Phaser.Scene, sprite_id: string) if (!sprite_id) return // @TODO: Fix this - const sprite_actions: HttpResponse<any[]> = await fetch(config.server_endpoint + '/assets/list_sprite_actions/' + sprite_id).then((response) => response.json()) + const spriteStorage = new SpriteStorage() + const sprite = await spriteStorage.get(sprite_id) - for await (const sprite_action of sprite_actions.data ?? []) { + if (!sprite) return + + for await (const sprite_action of sprite.spriteActions) { await loadTexture(scene, { key: sprite_action.key, data: sprite_action.data, diff --git a/src/composables/mapComposable.ts b/src/composables/mapComposable.ts index 6df48fd..8311394 100644 --- a/src/composables/mapComposable.ts +++ b/src/composables/mapComposable.ts @@ -2,7 +2,7 @@ import config from '@/application/config' import type { HttpResponse, TextureData, UUID } from '@/application/types' import { unduplicateArray } from '@/application/utilities' import { loadTexture } from '@/composables/gameComposable' -import { MapStorage } from '@/dexie/maps' +import { MapStorage } from '@/storage/storages' import Tilemap = Phaser.Tilemaps.Tilemap import TilemapLayer = Phaser.Tilemaps.TilemapLayer @@ -94,8 +94,6 @@ export async function loadMapTilesIntoScene(map_id: UUID, scene: Phaser.Scene) { const tileArray = unduplicateArray(FlattenMapArray(map.tiles)) - console.log(tileArray) - // Load each tile into the scene for (const tile of tileArray) { const textureData = { diff --git a/src/dexie/mapObjects.ts b/src/dexie/mapObjects.ts deleted file mode 100644 index 7ed4ad2..0000000 --- a/src/dexie/mapObjects.ts +++ /dev/null @@ -1,88 +0,0 @@ -import type { MapObject } from '@/application/types' -import Dexie from 'dexie' - -export class MapObjectStorage { - private dexie: Dexie - - constructor() { - this.dexie = new Dexie('map_objects') - this.dexie.version(1).stores({ - map_objects: 'id, name, createdAt, updatedAt' - }) - } - - async add(mapObject: MapObject, overwrite = false) { - try { - // Check if map object already exists, don't add if it does and overwrite is false - const existingMapObject = await this.get(mapObject.id) - if (existingMapObject && !overwrite) return - - await this.dexie.table('map_objects').put({ - ...mapObject - }) - } catch (error) { - console.error(`Failed to add map object ${mapObject.id}:`, error) - } - } - - async get(id: string): Promise<MapObject | null> { - try { - const mapObject = await this.dexie.table('map_objects').get(id) - return mapObject || null - } catch (error) { - console.error(`Failed to retrieve map object ${id}:`, error) - return null - } - } - - async getAll(): Promise<MapObject[]> { - try { - return await this.dexie.table('map_objects').toArray() - } catch (error) { - console.error('Failed to retrieve all map objects:', error) - return [] - } - } - - async getByName(name: string): Promise<MapObject[]> { - try { - return await this.dexie.table('map_objects').where('name').equals(name).toArray() - } catch (error) { - console.error(`Failed to retrieve map objects with name ${name}:`, error) - return [] - } - } - - async delete(id: string) { - try { - await this.dexie.table('map_objects').delete(id) - } catch (error) { - console.error(`Failed to delete map object ${id}:`, error) - } - } - - async clear() { - try { - await this.dexie.table('map_objects').clear() - } catch (error) { - console.error('Failed to clear map objects storage:', error) - } - } - - async update(id: string, updates: Partial<MapObject>) { - try { - const mapObject = await this.get(id) - if (!mapObject) return false - - const updatedMapObject = { - ...mapObject, - ...updates - } - await this.add(updatedMapObject) - return true - } catch (error) { - console.error(`Failed to update map object ${id}:`, error) - return false - } - } -} diff --git a/src/dexie/maps.ts b/src/dexie/maps.ts deleted file mode 100644 index 28cf919..0000000 --- a/src/dexie/maps.ts +++ /dev/null @@ -1,111 +0,0 @@ -import Dexie from 'dexie' - -// import type { Map } from '@/application/types' - -export type Map = { - id: string // or string, depending on your ID type - name: string - width: number - height: number - tiles: any[] // You might want to be more specific about the tiles type - pvp: boolean - updatedAt: Date - placedMapObjects: { - id: string // or string - mapObject: string // or string - depth: number - isRotated: boolean - positionX: number - positionY: number - }[] - mapEffects: { - effect: string // or specific enum/type if available - strength: number - }[] -} - -export class MapStorage { - private dexie: Dexie - - constructor() { - this.dexie = new Dexie('maps') - this.dexie.version(1).stores({ - maps: 'id, name, createdAt, updatedAt' - }) - } - - async add(map: Map, overwrite = false) { - try { - // Check if map already exists, don't add if it does and overwrite is false - const existingMap = await this.get(map.id) - if (existingMap && !overwrite) return - - await this.dexie.table('maps').put({ - ...map - }) - } catch (error) { - console.error(`Failed to add map ${map.id}:`, error) - } - } - - async get(id: string): Promise<Map | null> { - try { - const map = await this.dexie.table('maps').get(id) - return map || null - } catch (error) { - console.error(`Failed to retrieve map ${id}:`, error) - return null - } - } - - async getAll(): Promise<Map[]> { - try { - return await this.dexie.table('maps').toArray() - } catch (error) { - console.error('Failed to retrieve all maps:', error) - return [] - } - } - - async getByName(name: string): Promise<Map[]> { - try { - return await this.dexie.table('maps').where('name').equals(name).toArray() - } catch (error) { - console.error(`Failed to retrieve maps with name ${name}:`, error) - return [] - } - } - - async delete(id: string) { - try { - await this.dexie.table('maps').delete(id) - } catch (error) { - console.error(`Failed to delete map ${id}:`, error) - } - } - - async clear() { - try { - await this.dexie.table('maps').clear() - } catch (error) { - console.error('Failed to clear maps storage:', error) - } - } - - async update(id: string, updates: Partial<Map>) { - try { - const map = await this.get(id) - if (!map) return false - - const updatedMap = { - ...map, - ...updates - } - await this.add(updatedMap) - return true - } catch (error) { - console.error(`Failed to update map ${id}:`, error) - return false - } - } -} diff --git a/src/storage/baseStorage.ts b/src/storage/baseStorage.ts new file mode 100644 index 0000000..b12036f --- /dev/null +++ b/src/storage/baseStorage.ts @@ -0,0 +1,60 @@ +import Dexie from 'dexie' + +export class BaseStorage<T extends { id: string }> { + protected dexie: Dexie + protected tableName: string + + constructor(tableName: string, schema: string) { + this.tableName = tableName + this.dexie = new Dexie(tableName) + this.dexie.version(1).stores({ + [tableName]: schema + }) + } + + async add(item: T, overwrite = false) { + try { + const existing = await this.get(item.id) + if (existing && !overwrite) return + + await this.dexie.table(this.tableName).put({ ...item }) + } catch (error) { + console.error(`Failed to add ${this.tableName} ${item.id}:`, error) + } + } + + async get(id: string): Promise<T | null> { + try { + const item = await this.dexie.table(this.tableName).get(id) + return item || null + } catch (error) { + console.error(`Failed to retrieve ${this.tableName} ${id}:`, error) + return null + } + } + + async getAll(): Promise<T[]> { + try { + return await this.dexie.table(this.tableName).toArray() + } catch (error) { + console.error(`Failed to retrieve all ${this.tableName}:`, error) + return [] + } + } + + async reset() { + try { + await this.dexie.table(this.tableName).clear() + } catch (error) { + console.error(`Failed to clear ${this.tableName}:`, error) + } + } + + async destroy() { + try { + await this.dexie.delete() + } catch (error) { + console.error(`Failed to destroy ${this.tableName}:`, error) + } + } +} \ No newline at end of file diff --git a/src/storage/storages.ts b/src/storage/storages.ts new file mode 100644 index 0000000..cbc59e1 --- /dev/null +++ b/src/storage/storages.ts @@ -0,0 +1,39 @@ +import type { Tile, Map, MapObject } from '@/application/types' +import { BaseStorage } from '@/storage/baseStorage' + +export class MapStorage extends BaseStorage<Map> { + constructor() { + super('maps', 'id, name, createdAt, updatedAt') + } +} + +export class TileStorage extends BaseStorage<Tile> { + constructor() { + super('tiles', 'id, name, createdAt, updatedAt') + } +} + +export class MapObjectStorage extends BaseStorage<MapObject> { + constructor() { + super('mapObjects', 'id, name, createdAt, updatedAt') + } +} + +export class SpriteStorage extends BaseStorage<any> { + constructor() { + super('sprites', 'id, name, createdAt, updatedAt') + } +} + +export class CharacterTypeStorage extends BaseStorage<any> { + constructor() { + super('characterTypes', 'id, name, createdAt, updatedAt') + } +} + +export class CharacterHairStorage extends BaseStorage<any> { + constructor() { + super('characterHairs', 'id, name, createdAt, updatedAt') + } +} + diff --git a/src/dexie/textures.ts b/src/storage/textureStorage.ts similarity index 86% rename from src/dexie/textures.ts rename to src/storage/textureStorage.ts index 398ed6c..2956390 100644 --- a/src/dexie/textures.ts +++ b/src/storage/textureStorage.ts @@ -2,7 +2,7 @@ import config from '@/application/config' import type { TextureData } from '@/application/types' import Dexie from 'dexie' -export class Textures { +export class TextureStorage { private dexie: Dexie constructor() { @@ -78,4 +78,20 @@ export class Textures { console.error(`Failed to delete texture ${key}:`, error) } } + + async reset() { + try { + await this.dexie.table('textures').clear() + } catch (error) { + console.error(`Failed to clear textures:`, error) + } + } + + async destroy() { + try { + await this.dexie.delete() + } catch (error) { + console.error(`Failed to destroy textures:`, error) + } + } } diff --git a/src/stores/gameStore.ts b/src/stores/gameStore.ts index f67f585..352188d 100644 --- a/src/stores/gameStore.ts +++ b/src/stores/gameStore.ts @@ -22,7 +22,7 @@ export const useGameStore = defineStore('game', { game: { isLoading: false, isLoaded: false, // isLoaded is currently being used to determine if the player has interacted with the game - loadedAssets: [] as TextureData[], + loadedAssets: [] as string[], isPlayerDraggingCamera: false, isCameraFollowingCharacter: false }, @@ -37,15 +37,9 @@ export const useGameStore = defineStore('game', { getLoadedAssets: (state) => { return state.game.loadedAssets }, - getLoadedAsset: (state) => { - return (key: string | undefined) => { - if (!key) return null - return state.game.loadedAssets.find((asset) => asset.key === key) - } + isAssetLoaded: (state) => { + return (key: string) => { return state.game.loadedAssets.includes(key)} }, - getLoadedAssetsByGroup: (state) => { - return (group: string) => state.game.loadedAssets.filter((asset) => asset.group === group) - } }, actions: { addNotification(notification: Notification) { diff --git a/src/stores/mapStore.ts b/src/stores/mapStore.ts index c03206a..fc798fd 100644 --- a/src/stores/mapStore.ts +++ b/src/stores/mapStore.ts @@ -4,7 +4,7 @@ import { defineStore } from 'pinia' export const useMapStore = defineStore('map', { state: () => { return { - map: null as Map | null, + mapId: '', characters: [] as MapCharacter[], characterLoaded: false } @@ -16,13 +16,10 @@ export const useMapStore = defineStore('map', { getCharacterCount: (state) => { return state.characters.length }, - isMapSet: (state) => { - return state.map !== null - } }, actions: { - setMap(map: Map | null) { - this.map = map + setMapId(mapId: UUID) { + this.mapId = mapId }, setCharacters(characters: MapCharacter[]) { this.characters = characters @@ -50,7 +47,7 @@ export const useMapStore = defineStore('map', { } }, reset() { - this.map = null + this.mapId = '' this.characters = [] this.characterLoaded = false }