@rpgjs/client 5.0.0-beta.2 → 5.0.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -0
- package/dist/Game/AnimationManager.d.ts +2 -1
- package/dist/Game/AnimationManager.js +21 -9
- package/dist/Game/AnimationManager.js.map +1 -1
- package/dist/Game/AnimationManager.spec.d.ts +1 -0
- package/dist/Game/ClientVisuals.d.ts +61 -0
- package/dist/Game/ClientVisuals.js +96 -0
- package/dist/Game/ClientVisuals.js.map +1 -0
- package/dist/Game/ClientVisuals.spec.d.ts +1 -0
- package/dist/Game/Event.js.map +1 -1
- package/dist/Game/EventComponentResolver.d.ts +16 -0
- package/dist/Game/EventComponentResolver.js +52 -0
- package/dist/Game/EventComponentResolver.js.map +1 -0
- package/dist/Game/EventComponentResolver.spec.d.ts +1 -0
- package/dist/Game/Map.d.ts +9 -1
- package/dist/Game/Map.js +83 -5
- package/dist/Game/Map.js.map +1 -1
- package/dist/Game/Object.d.ts +49 -15
- package/dist/Game/Object.js +101 -42
- package/dist/Game/Object.js.map +1 -1
- package/dist/Game/Object.spec.d.ts +1 -0
- package/dist/Game/Player.js.map +1 -1
- package/dist/Game/ProjectileManager.d.ts +98 -0
- package/dist/Game/ProjectileManager.js +196 -0
- package/dist/Game/ProjectileManager.js.map +1 -0
- package/dist/Game/ProjectileManager.spec.d.ts +1 -0
- package/dist/Gui/Gui.d.ts +20 -6
- package/dist/Gui/Gui.js +132 -57
- package/dist/Gui/Gui.js.map +1 -1
- package/dist/Gui/Gui.spec.d.ts +1 -0
- package/dist/Gui/NotificationManager.js.map +1 -1
- package/dist/Resource.js +1 -1
- package/dist/Resource.js.map +1 -1
- package/dist/RpgClient.d.ts +194 -15
- package/dist/RpgClientEngine.d.ts +191 -19
- package/dist/RpgClientEngine.js +693 -74
- package/dist/RpgClientEngine.js.map +1 -1
- package/dist/Sound.js.map +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.133.0/helpers/esm}/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.133.0/helpers/esm}/decorateMetadata.js +1 -1
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/components/animations/animation.ce.js +6 -5
- package/dist/components/animations/animation.ce.js.map +1 -1
- package/dist/components/animations/fx.ce.js +60 -0
- package/dist/components/animations/fx.ce.js.map +1 -0
- package/dist/components/animations/hit.ce.js +24 -28
- package/dist/components/animations/hit.ce.js.map +1 -1
- package/dist/components/animations/index.d.ts +1 -0
- package/dist/components/animations/index.js +6 -4
- package/dist/components/animations/index.js.map +1 -1
- package/dist/components/character.ce.js +748 -249
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/dynamics/bar.ce.js +99 -0
- package/dist/components/dynamics/bar.ce.js.map +1 -0
- package/dist/components/dynamics/image.ce.js +26 -0
- package/dist/components/dynamics/image.ce.js.map +1 -0
- package/dist/components/dynamics/parse-value.d.ts +3 -0
- package/dist/components/dynamics/parse-value.js +54 -35
- package/dist/components/dynamics/parse-value.js.map +1 -1
- package/dist/components/dynamics/parse-value.spec.d.ts +1 -0
- package/dist/components/dynamics/shape-utils.d.ts +16 -0
- package/dist/components/dynamics/shape-utils.js +73 -0
- package/dist/components/dynamics/shape-utils.js.map +1 -0
- package/dist/components/dynamics/shape-utils.spec.d.ts +1 -0
- package/dist/components/dynamics/shape.ce.js +86 -0
- package/dist/components/dynamics/shape.ce.js.map +1 -0
- package/dist/components/dynamics/text.ce.js +36 -56
- package/dist/components/dynamics/text.ce.js.map +1 -1
- package/dist/components/gui/box.ce.js +9 -9
- package/dist/components/gui/box.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +75 -65
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
- package/dist/components/gui/gameover.ce.js +47 -68
- package/dist/components/gui/gameover.ce.js.map +1 -1
- package/dist/components/gui/hud/hud.ce.js +23 -31
- package/dist/components/gui/hud/hud.ce.js.map +1 -1
- package/dist/components/gui/menu/equip-menu.ce.js +121 -172
- package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/exit-menu.ce.js +15 -10
- package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/items-menu.ce.js +62 -77
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/main-menu.ce.js +89 -104
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/options-menu.ce.js +12 -8
- package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/skills-menu.ce.js +17 -19
- package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
- package/dist/components/gui/mobile/index.d.ts +51 -2
- package/dist/components/gui/mobile/index.js +14 -6
- package/dist/components/gui/mobile/index.js.map +1 -1
- package/dist/components/gui/mobile/index.spec.d.ts +1 -0
- package/dist/components/gui/mobile/mobile.ce.js +309 -59
- package/dist/components/gui/mobile/mobile.ce.js.map +1 -1
- package/dist/components/gui/notification/notification.ce.js +28 -26
- package/dist/components/gui/notification/notification.ce.js.map +1 -1
- package/dist/components/gui/save-load.ce.js +81 -256
- package/dist/components/gui/save-load.ce.js.map +1 -1
- package/dist/components/gui/shop/shop.ce.js +107 -142
- package/dist/components/gui/shop/shop.ce.js.map +1 -1
- package/dist/components/gui/title-screen.ce.js +50 -73
- package/dist/components/gui/title-screen.ce.js.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +1 -0
- package/dist/components/interaction-components.ce.js +22 -0
- package/dist/components/interaction-components.ce.js.map +1 -0
- package/dist/components/player-components-utils.d.ts +67 -0
- package/dist/components/player-components-utils.js +162 -0
- package/dist/components/player-components-utils.js.map +1 -0
- package/dist/components/player-components-utils.spec.d.ts +1 -0
- package/dist/components/player-components.ce.js +191 -0
- package/dist/components/player-components.ce.js.map +1 -0
- package/dist/components/prebuilt/hp-bar.ce.js +45 -45
- package/dist/components/prebuilt/hp-bar.ce.js.map +1 -1
- package/dist/components/prebuilt/light-halo.ce.js +39 -60
- package/dist/components/prebuilt/light-halo.ce.js.map +1 -1
- package/dist/components/scenes/canvas.ce.js +205 -27
- package/dist/components/scenes/canvas.ce.js.map +1 -1
- package/dist/components/scenes/draw-map.ce.js +39 -39
- package/dist/components/scenes/draw-map.ce.js.map +1 -1
- package/dist/components/scenes/event-layer.ce.js +51 -10
- package/dist/components/scenes/event-layer.ce.js.map +1 -1
- package/dist/core/inject.js +1 -1
- package/dist/core/inject.js.map +1 -1
- package/dist/core/setup.js +1 -1
- package/dist/core/setup.js.map +1 -1
- package/dist/decorators/spritesheet.d.ts +1 -0
- package/dist/decorators/spritesheet.js +11 -0
- package/dist/decorators/spritesheet.js.map +1 -0
- package/dist/i18n.d.ts +55 -0
- package/dist/i18n.js +60 -0
- package/dist/i18n.js.map +1 -0
- package/dist/i18n.spec.d.ts +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +29 -21
- package/dist/module.js +45 -4
- package/dist/module.js.map +1 -1
- package/dist/node_modules/.pnpm/{@signe_di@2.9.0 → @signe_di@3.1.0}/node_modules/@signe/di/dist/index.js +7 -117
- package/dist/node_modules/.pnpm/@signe_di@3.1.0/node_modules/@signe/di/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js +239 -0
- package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/chunk-EUXUH3YW.js +13 -0
- package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/chunk-EUXUH3YW.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js +698 -0
- package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/client/index.js +43 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/client/index.js.map +1 -0
- package/dist/node_modules/.pnpm/{@signe_sync@2.9.0 → @signe_sync@3.1.0_react@19.2.7}/node_modules/@signe/sync/dist/index.js +57 -141
- package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/{partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js → partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/index.js} +30 -17
- package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/{partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js → partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/ws.js} +65 -34
- package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/ws.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js +13 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +106 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +13 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js +121 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js +10 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +110 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +99 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +82 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js.map +1 -0
- package/dist/node_modules/.pnpm/{zod@3.24.2/node_modules/zod/lib/index.js → zod@3.25.76/node_modules/zod/v3/types.js} +74 -611
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js.map +1 -0
- package/dist/presets/animation.js.map +1 -1
- package/dist/presets/faceset.js.map +1 -1
- package/dist/presets/icon.js.map +1 -1
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/lpc.js.map +1 -1
- package/dist/presets/rmspritesheet.js.map +1 -1
- package/dist/services/AbstractSocket.d.ts +2 -0
- package/dist/services/AbstractSocket.js.map +1 -1
- package/dist/services/actionInput.d.ts +14 -0
- package/dist/services/actionInput.js +59 -0
- package/dist/services/actionInput.js.map +1 -0
- package/dist/services/actionInput.spec.d.ts +1 -0
- package/dist/services/cameraFollow.d.ts +51 -0
- package/dist/services/cameraFollow.js +134 -0
- package/dist/services/cameraFollow.js.map +1 -0
- package/dist/services/cameraFollow.spec.d.ts +1 -0
- package/dist/services/interactions.d.ts +159 -0
- package/dist/services/interactions.js +460 -0
- package/dist/services/interactions.js.map +1 -0
- package/dist/services/interactions.spec.d.ts +1 -0
- package/dist/services/keyboardControls.d.ts +1 -0
- package/dist/services/keyboardControls.js +1 -0
- package/dist/services/keyboardControls.js.map +1 -1
- package/dist/services/loadMap.d.ts +9 -0
- package/dist/services/loadMap.js +1 -1
- package/dist/services/loadMap.js.map +1 -1
- package/dist/services/mmorpg-connection.d.ts +5 -0
- package/dist/services/mmorpg-connection.js +50 -0
- package/dist/services/mmorpg-connection.js.map +1 -0
- package/dist/services/mmorpg-connection.spec.d.ts +1 -0
- package/dist/services/mmorpg.d.ts +11 -4
- package/dist/services/mmorpg.js +57 -33
- package/dist/services/mmorpg.js.map +1 -1
- package/dist/services/pointerContext.d.ts +11 -0
- package/dist/services/pointerContext.js +48 -0
- package/dist/services/pointerContext.js.map +1 -0
- package/dist/services/pointerContext.spec.d.ts +1 -0
- package/dist/services/save.js.map +1 -1
- package/dist/services/save.spec.d.ts +1 -0
- package/dist/services/standalone-message.d.ts +1 -0
- package/dist/services/standalone-message.js +9 -0
- package/dist/services/standalone-message.js.map +1 -0
- package/dist/services/standalone.d.ts +4 -1
- package/dist/services/standalone.js +36 -16
- package/dist/services/standalone.js.map +1 -1
- package/dist/services/standalone.spec.d.ts +1 -0
- package/dist/utils/getEntityProp.js +4 -3
- package/dist/utils/getEntityProp.js.map +1 -1
- package/dist/utils/getEntityProp.spec.d.ts +1 -0
- package/dist/utils/mapId.d.ts +1 -0
- package/dist/utils/mapId.js +6 -0
- package/dist/utils/mapId.js.map +1 -0
- package/dist/utils/readPropValue.d.ts +2 -0
- package/dist/utils/readPropValue.js +13 -0
- package/dist/utils/readPropValue.js.map +1 -0
- package/package.json +13 -13
- package/src/Game/AnimationManager.spec.ts +30 -0
- package/src/Game/AnimationManager.ts +26 -10
- package/src/Game/ClientVisuals.spec.ts +56 -0
- package/src/Game/ClientVisuals.ts +184 -0
- package/src/Game/EventComponentResolver.spec.ts +84 -0
- package/src/Game/EventComponentResolver.ts +74 -0
- package/src/Game/Map.ts +134 -2
- package/src/Game/Object.spec.ts +59 -0
- package/src/Game/Object.ts +181 -77
- package/src/Game/ProjectileManager.spec.ts +449 -0
- package/src/Game/ProjectileManager.ts +346 -0
- package/src/Gui/Gui.spec.ts +359 -0
- package/src/Gui/Gui.ts +178 -67
- package/src/Resource.ts +1 -2
- package/src/RpgClient.ts +220 -17
- package/src/RpgClientEngine.ts +995 -133
- package/src/components/animations/fx.ce +101 -0
- package/src/components/animations/index.ts +4 -2
- package/src/components/character.ce +839 -45
- package/src/components/dynamics/bar.ce +88 -0
- package/src/components/dynamics/image.ce +21 -0
- package/src/components/dynamics/parse-value.spec.ts +83 -0
- package/src/components/dynamics/parse-value.ts +111 -37
- package/src/components/dynamics/shape-utils.spec.ts +46 -0
- package/src/components/dynamics/shape-utils.ts +61 -0
- package/src/components/dynamics/shape.ce +90 -0
- package/src/components/dynamics/text.ce +35 -149
- package/src/components/gui/dialogbox/index.ce +52 -21
- package/src/components/gui/gameover.ce +6 -4
- package/src/components/gui/menu/equip-menu.ce +11 -9
- package/src/components/gui/menu/exit-menu.ce +6 -4
- package/src/components/gui/menu/items-menu.ce +11 -9
- package/src/components/gui/menu/main-menu.ce +14 -12
- package/src/components/gui/menu/options-menu.ce +4 -3
- package/src/components/gui/menu/skills-menu.ce +2 -1
- package/src/components/gui/mobile/index.spec.ts +94 -0
- package/src/components/gui/mobile/index.ts +74 -6
- package/src/components/gui/mobile/mobile.ce +347 -65
- package/src/components/gui/notification/notification.ce +7 -1
- package/src/components/gui/save-load.ce +13 -11
- package/src/components/gui/shop/shop.ce +20 -18
- package/src/components/gui/title-screen.ce +6 -4
- package/src/components/index.ts +2 -1
- package/src/components/interaction-components.ce +23 -0
- package/src/components/player-components-utils.spec.ts +109 -0
- package/src/components/player-components-utils.ts +205 -0
- package/src/components/player-components.ce +222 -0
- package/src/components/prebuilt/hp-bar.ce +4 -3
- package/src/components/prebuilt/light-halo.ce +2 -2
- package/src/components/scenes/canvas.ce +219 -15
- package/src/components/scenes/draw-map.ce +34 -22
- package/src/components/scenes/event-layer.ce +55 -4
- package/src/core/setup.ts +2 -2
- package/src/decorators/spritesheet.ts +8 -0
- package/src/i18n.spec.ts +39 -0
- package/src/i18n.ts +59 -0
- package/src/index.ts +19 -0
- package/src/module.ts +61 -11
- package/src/services/AbstractSocket.ts +3 -0
- package/src/services/actionInput.spec.ts +155 -0
- package/src/services/actionInput.ts +120 -0
- package/src/services/cameraFollow.spec.ts +220 -0
- package/src/services/cameraFollow.ts +222 -0
- package/src/services/interactions.spec.ts +175 -0
- package/src/services/interactions.ts +722 -0
- package/src/services/keyboardControls.ts +2 -1
- package/src/services/loadMap.ts +5 -1
- package/src/services/mmorpg-connection.spec.ts +99 -0
- package/src/services/mmorpg-connection.ts +69 -0
- package/src/services/mmorpg.ts +70 -36
- package/src/services/pointerContext.spec.ts +36 -0
- package/src/services/pointerContext.ts +84 -0
- package/src/services/save.spec.ts +127 -0
- package/src/services/standalone-message.ts +7 -0
- package/src/services/standalone.spec.ts +54 -0
- package/src/services/standalone.ts +44 -12
- package/src/utils/getEntityProp.spec.ts +96 -0
- package/src/utils/getEntityProp.ts +4 -3
- package/src/utils/mapId.ts +2 -0
- package/src/utils/readPropValue.ts +16 -0
- package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js +0 -457
- package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js +0 -463
- package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js +0 -2191
- package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js +0 -10
- package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js +0 -91
- package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js +0 -14
- package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +0 -1
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +0 -1
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +0 -2
- package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +0 -1
|
@@ -1,31 +1,64 @@
|
|
|
1
|
-
<Container
|
|
1
|
+
<Container
|
|
2
|
+
x={smoothX}
|
|
3
|
+
y={smoothY}
|
|
4
|
+
zIndex={z}
|
|
5
|
+
controls
|
|
6
|
+
onBeforeDestroy
|
|
7
|
+
visible
|
|
8
|
+
cursor={interactionCursor}
|
|
9
|
+
pointerover={interactionPointerOver}
|
|
10
|
+
pointerout={interactionPointerOut}
|
|
11
|
+
pointerdown={interactionPointerDown}
|
|
12
|
+
pointerup={interactionPointerUp}
|
|
13
|
+
pointermove={interactionPointerMove}
|
|
14
|
+
click={interactionClick}
|
|
15
|
+
>
|
|
2
16
|
@for (compConfig of normalizedComponentsBehind) {
|
|
3
17
|
<Container>
|
|
4
|
-
<compConfig.component object ...compConfig.props />
|
|
18
|
+
<compConfig.component object={sprite} ...compConfig.props />
|
|
5
19
|
</Container>
|
|
6
20
|
}
|
|
21
|
+
<PlayerComponents object={sprite} position="bottom" graphicBounds />
|
|
22
|
+
<PlayerComponents object={sprite} position="left" graphicBounds />
|
|
7
23
|
<Particle emit={emitParticleTrigger} settings={particleSettings} zIndex={1000} name={particleName} />
|
|
8
24
|
<Container>
|
|
9
|
-
@for (graphicObj of
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
@for (graphicObj of renderedGraphics) {
|
|
26
|
+
<Container scale={graphicScale(graphicObj)}>
|
|
27
|
+
<Sprite
|
|
28
|
+
sheet={sheet(graphicObj)}
|
|
29
|
+
direction
|
|
30
|
+
tint
|
|
31
|
+
hitbox
|
|
32
|
+
shadowCaster={shadowCaster(graphicObj)}
|
|
33
|
+
flash={flashConfig}
|
|
34
|
+
/>
|
|
35
|
+
</Container>
|
|
36
|
+
}
|
|
37
|
+
@for (eventComponent of resolvedEventComponents) {
|
|
38
|
+
<Container dependencies={eventComponent.dependencies}>
|
|
39
|
+
<eventComponent.component ...eventComponent.props />
|
|
40
|
+
</Container>
|
|
17
41
|
}
|
|
18
42
|
</Container>
|
|
43
|
+
<PlayerComponents object={sprite} position="center" graphicBounds />
|
|
44
|
+
<PlayerComponents object={sprite} position="right" graphicBounds />
|
|
45
|
+
<PlayerComponents object={sprite} position="top" graphicBounds />
|
|
19
46
|
@for (compConfig of normalizedComponentsInFront) {
|
|
20
47
|
<Container dependencies={compConfig.dependencies}>
|
|
21
|
-
<compConfig.component object ...compConfig.props />
|
|
48
|
+
<compConfig.component object={sprite} ...compConfig.props />
|
|
22
49
|
</Container>
|
|
23
50
|
}
|
|
51
|
+
<InteractionComponents
|
|
52
|
+
object={sprite}
|
|
53
|
+
bounds={graphicBounds}
|
|
54
|
+
hitboxBounds={hitboxBounds}
|
|
55
|
+
graphicBounds={graphicBounds}
|
|
56
|
+
/>
|
|
24
57
|
@for (attachedGui of attachedGuis) {
|
|
25
58
|
@if (shouldDisplayAttachedGui) {
|
|
26
59
|
<Container>
|
|
27
|
-
<attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={
|
|
28
|
-
onAttachedGuiFinish(attachedGui, data)
|
|
60
|
+
<attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={sprite} guiOpenId={attachedGui.openId} onFinish={(data, guiOpenId) => {
|
|
61
|
+
onAttachedGuiFinish(attachedGui, data, guiOpenId)
|
|
29
62
|
}} onInteraction={(name, data) => {
|
|
30
63
|
onAttachedGuiInteraction(attachedGui, name, data)
|
|
31
64
|
}} />
|
|
@@ -36,28 +69,52 @@
|
|
|
36
69
|
|
|
37
70
|
<script>
|
|
38
71
|
import { signal, effect, mount, computed, tick, animatedSignal, on } from "canvasengine";
|
|
72
|
+
import { Assets } from "pixi.js";
|
|
39
73
|
|
|
40
74
|
import { lastValueFrom, combineLatest, pairwise, filter, map, startWith } from "rxjs";
|
|
41
75
|
import { Particle } from "@canvasengine/presets";
|
|
42
|
-
import { GameEngineToken, ModulesToken } from "@rpgjs/common";
|
|
76
|
+
import { GameEngineToken, ModulesToken, shouldRenderLightingShadows } from "@rpgjs/common";
|
|
43
77
|
import { RpgClientEngine } from "../RpgClientEngine";
|
|
78
|
+
import { applyCameraFollow, clearCameraFollowPlugins, ownsCameraFollowRevision } from "../services/cameraFollow";
|
|
44
79
|
import { inject } from "../core/inject";
|
|
45
|
-
import { Direction } from "@rpgjs/common";
|
|
80
|
+
import { Direction, Animation } from "@rpgjs/common";
|
|
81
|
+
import { normalizeEventComponent } from "../Game/EventComponentResolver";
|
|
46
82
|
import Hit from "./effects/hit.ce";
|
|
47
83
|
import PlayerComponents from "./player-components.ce";
|
|
84
|
+
import InteractionComponents from "./interaction-components.ce";
|
|
48
85
|
import { RpgGui } from "../Gui/Gui";
|
|
86
|
+
import { getCanMoveValue } from "../utils/readPropValue";
|
|
87
|
+
import {
|
|
88
|
+
getKeyboardControlBind,
|
|
89
|
+
keyboardEventMatchesBind,
|
|
90
|
+
resolveKeyboardActionInput,
|
|
91
|
+
resolveKeyboardDirectionInput,
|
|
92
|
+
} from "../services/actionInput";
|
|
49
93
|
|
|
50
94
|
const { object, id } = defineProps();
|
|
95
|
+
const sprite = object();
|
|
51
96
|
|
|
52
97
|
const client = inject(RpgClientEngine);
|
|
53
98
|
const hooks = inject(ModulesToken);
|
|
54
99
|
const guiService = inject(RpgGui);
|
|
55
100
|
|
|
56
101
|
const spritesheets = client.spritesheets;
|
|
57
|
-
const playerId = client.playerId;
|
|
58
102
|
const componentsBehind = client.spriteComponentsBehind;
|
|
59
103
|
const componentsInFront = client.spriteComponentsInFront;
|
|
60
|
-
const
|
|
104
|
+
const readProp = (value) => typeof value === 'function' ? value() : value;
|
|
105
|
+
const isCurrentPlayer = () => {
|
|
106
|
+
const playerId = client.playerIdSignal();
|
|
107
|
+
const currentPlayer = playerId ? client.sceneMap?.players?.()?.[playerId] : undefined;
|
|
108
|
+
return readProp(id) === playerId
|
|
109
|
+
|| readProp(sprite?.id) === playerId
|
|
110
|
+
|| sprite === currentPlayer
|
|
111
|
+
|| sprite === client.sceneMap?.getCurrentPlayer?.();
|
|
112
|
+
};
|
|
113
|
+
const isMe = computed(isCurrentPlayer);
|
|
114
|
+
const shadowsEnabled = computed(() => {
|
|
115
|
+
const lighting = client.sceneMap?.lighting?.();
|
|
116
|
+
return shouldRenderLightingShadows(lighting);
|
|
117
|
+
});
|
|
61
118
|
|
|
62
119
|
/**
|
|
63
120
|
* Normalize a single sprite component configuration
|
|
@@ -128,8 +185,8 @@
|
|
|
128
185
|
// The computed will be created in the template when needed
|
|
129
186
|
return {
|
|
130
187
|
component: componentRef,
|
|
131
|
-
props: typeof propsValue === 'function' ? propsValue(
|
|
132
|
-
dependencies: dependenciesFn ? dependenciesFn(
|
|
188
|
+
props: typeof propsValue === 'function' ? propsValue(sprite) : propsValue || {},
|
|
189
|
+
dependencies: dependenciesFn ? dependenciesFn(sprite) : []
|
|
133
190
|
};
|
|
134
191
|
};
|
|
135
192
|
|
|
@@ -189,6 +246,18 @@
|
|
|
189
246
|
const normalizedComponentsInFront = computed(() => {
|
|
190
247
|
return normalizeComponents(componentsInFront());
|
|
191
248
|
});
|
|
249
|
+
|
|
250
|
+
const isEventSprite = () => {
|
|
251
|
+
return typeof sprite?.isEvent === 'function'
|
|
252
|
+
? sprite.isEvent()
|
|
253
|
+
: sprite?._type === 'event';
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const resolvedEventComponents = computed(() => {
|
|
257
|
+
if (!isEventSprite()) return [];
|
|
258
|
+
const eventComponent = normalizeEventComponent(client.resolveEventComponent(sprite), sprite);
|
|
259
|
+
return eventComponent ? [eventComponent] : [];
|
|
260
|
+
});
|
|
192
261
|
|
|
193
262
|
/**
|
|
194
263
|
* Determine if the camera should follow this sprite
|
|
@@ -237,7 +306,13 @@
|
|
|
237
306
|
isConnected,
|
|
238
307
|
graphicsSignals,
|
|
239
308
|
flashTrigger
|
|
240
|
-
} =
|
|
309
|
+
} = sprite;
|
|
310
|
+
|
|
311
|
+
const renderedGraphics = computed(() => {
|
|
312
|
+
const eventComponent = resolvedEventComponents()[0];
|
|
313
|
+
if (eventComponent && !eventComponent.renderGraphic) return [];
|
|
314
|
+
return graphicsSignals();
|
|
315
|
+
});
|
|
241
316
|
|
|
242
317
|
/**
|
|
243
318
|
* Flash configuration signals for dynamic options
|
|
@@ -282,50 +357,266 @@
|
|
|
282
357
|
|
|
283
358
|
const particleSettings = client.particleSettings;
|
|
284
359
|
|
|
285
|
-
const canControls = () => isMe() &&
|
|
360
|
+
const canControls = () => isMe() && getCanMoveValue(sprite)
|
|
286
361
|
const keyboardControls = client.globalConfig.keyboardControls;
|
|
362
|
+
const activeDirectionKeys = new Map();
|
|
363
|
+
const activeControlDirections = new Map();
|
|
364
|
+
const activeControlDirectionReleaseTimers = new Map();
|
|
365
|
+
const CONTROL_DIRECTION_RELEASE_GRACE_MS = 160;
|
|
366
|
+
|
|
367
|
+
const hasHeldDirection = () =>
|
|
368
|
+
activeDirectionKeys.size > 0 || activeControlDirections.size > 0;
|
|
369
|
+
|
|
370
|
+
const publishMobileDebug = (type, payload = {}) => {
|
|
371
|
+
const target = typeof window !== "undefined" ? window : globalThis;
|
|
372
|
+
if (!target.__RPGJS_MOBILE_DEBUG__) return;
|
|
373
|
+
const event = {
|
|
374
|
+
source: "character",
|
|
375
|
+
type,
|
|
376
|
+
time: Date.now(),
|
|
377
|
+
isCurrentPlayer: isCurrentPlayer(),
|
|
378
|
+
animationName: animationName(),
|
|
379
|
+
realAnimationName: realAnimationName?.(),
|
|
380
|
+
activeKeyboardDirections: Array.from(activeDirectionKeys.values()),
|
|
381
|
+
activeControlDirections: Array.from(activeControlDirections.values()),
|
|
382
|
+
heldDirection: resolveHeldDirection(),
|
|
383
|
+
canControls: canControls(),
|
|
384
|
+
x: x(),
|
|
385
|
+
y: y(),
|
|
386
|
+
...payload
|
|
387
|
+
};
|
|
388
|
+
target.__RPGJS_MOBILE_DEBUG_EVENTS__ = [
|
|
389
|
+
...(target.__RPGJS_MOBILE_DEBUG_EVENTS__ || []).slice(-199),
|
|
390
|
+
event
|
|
391
|
+
];
|
|
392
|
+
target.__RPGJS_MOBILE_DEBUG_LAST__ = event;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
const resolveHeldDirection = () => {
|
|
396
|
+
const directions = [
|
|
397
|
+
...Array.from(activeDirectionKeys.values()),
|
|
398
|
+
...Array.from(activeControlDirections.values()),
|
|
399
|
+
];
|
|
400
|
+
return directions[directions.length - 1];
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const resolveSpriteDirection = () => {
|
|
404
|
+
const heldDirection = resolveHeldDirection();
|
|
405
|
+
if (heldDirection) return heldDirection;
|
|
406
|
+
if (typeof sprite.getDirection === 'function') return sprite.getDirection();
|
|
407
|
+
if (typeof sprite.direction === 'function') return sprite.direction();
|
|
408
|
+
return direction();
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
const directionToDashVector = (currentDirection) => {
|
|
412
|
+
switch (currentDirection) {
|
|
413
|
+
case Direction.Left:
|
|
414
|
+
return { x: -1, y: 0 };
|
|
415
|
+
case Direction.Right:
|
|
416
|
+
return { x: 1, y: 0 };
|
|
417
|
+
case Direction.Up:
|
|
418
|
+
return { x: 0, y: -1 };
|
|
419
|
+
case Direction.Down:
|
|
420
|
+
default:
|
|
421
|
+
return { x: 0, y: 1 };
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
const withCurrentDirection = (payload) => {
|
|
426
|
+
if (payload.action !== 'action') return payload;
|
|
427
|
+
const data = payload.data && typeof payload.data === 'object'
|
|
428
|
+
? { ...payload.data }
|
|
429
|
+
: {};
|
|
430
|
+
return {
|
|
431
|
+
...payload,
|
|
432
|
+
data: {
|
|
433
|
+
...data,
|
|
434
|
+
direction: data.direction ?? resolveSpriteDirection(),
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const resolveCurrentActionInput = () =>
|
|
440
|
+
withCurrentDirection(
|
|
441
|
+
resolveKeyboardActionInput(keyboardControls.action, client, sprite)
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
const playPredictedWalkAnimation = () => {
|
|
445
|
+
if (sprite.animationFixed) {
|
|
446
|
+
publishMobileDebug("walk:skip", { reason: "animationFixed" });
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (sprite.animationIsPlaying && sprite.animationIsPlaying()) {
|
|
450
|
+
publishMobileDebug("walk:skip", { reason: "animationIsPlaying" });
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
realAnimationName.set('walk');
|
|
454
|
+
publishMobileDebug("walk:set", { reason: "predicted" });
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
const resumeHeldDirectionWalkAnimation = () => {
|
|
458
|
+
if (!isCurrentPlayer()) {
|
|
459
|
+
publishMobileDebug("walk:resume-fail", { reason: "notCurrentPlayer" });
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
if (!hasHeldDirection()) {
|
|
463
|
+
publishMobileDebug("walk:resume-fail", { reason: "noHeldDirection" });
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
if (!canControls()) {
|
|
467
|
+
publishMobileDebug("walk:resume-fail", { reason: "cannotControl" });
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
if (sprite.animationFixed) {
|
|
471
|
+
publishMobileDebug("walk:resume-fail", { reason: "animationFixed" });
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
if (sprite.animationIsPlaying && sprite.animationIsPlaying()) {
|
|
475
|
+
publishMobileDebug("walk:resume-fail", { reason: "animationIsPlaying" });
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
realAnimationName.set('walk');
|
|
479
|
+
publishMobileDebug("walk:set", { reason: "resumeHeldDirection" });
|
|
480
|
+
return true;
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const processMovementInput = (input) => {
|
|
484
|
+
if (!canControls()) return;
|
|
485
|
+
publishMobileDebug("movement:input", { input });
|
|
486
|
+
client.processInput({ input });
|
|
487
|
+
playPredictedWalkAnimation();
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
const activateControlDirection = (name, directionInput) => {
|
|
491
|
+
const releaseTimer = activeControlDirectionReleaseTimers.get(name);
|
|
492
|
+
if (releaseTimer) {
|
|
493
|
+
clearTimeout(releaseTimer);
|
|
494
|
+
activeControlDirectionReleaseTimers.delete(name);
|
|
495
|
+
}
|
|
496
|
+
activeControlDirections.delete(name);
|
|
497
|
+
activeControlDirections.set(name, directionInput);
|
|
498
|
+
publishMobileDebug("control:activate", { name, directionInput });
|
|
499
|
+
resumeHeldDirectionWalkAnimation();
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
const releaseControlDirection = (name) => {
|
|
503
|
+
const previousTimer = activeControlDirectionReleaseTimers.get(name);
|
|
504
|
+
if (previousTimer) clearTimeout(previousTimer);
|
|
505
|
+
activeControlDirectionReleaseTimers.set(name, setTimeout(() => {
|
|
506
|
+
activeControlDirectionReleaseTimers.delete(name);
|
|
507
|
+
activeControlDirections.delete(name);
|
|
508
|
+
publishMobileDebug("control:release", { name });
|
|
509
|
+
if (!hasHeldDirection() && animationName() === 'stand') {
|
|
510
|
+
realAnimationName.set('stand');
|
|
511
|
+
publishMobileDebug("stand:set", { reason: "controlRelease" });
|
|
512
|
+
}
|
|
513
|
+
}, CONTROL_DIRECTION_RELEASE_GRACE_MS));
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const processDashInput = () => {
|
|
517
|
+
if (!canControls()) return;
|
|
518
|
+
client.processDash({
|
|
519
|
+
direction: directionToDashVector(resolveSpriteDirection()),
|
|
520
|
+
});
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
const actionBind = () => getKeyboardControlBind(keyboardControls.action);
|
|
524
|
+
const keyboardEventId = (event) => `${event.keyCode}:${event.code}:${event.key}`;
|
|
525
|
+
|
|
526
|
+
const handleNativeActionWhileMoving = (event) => {
|
|
527
|
+
const inputDirection = resolveKeyboardDirectionInput(event, keyboardControls);
|
|
528
|
+
if (inputDirection) {
|
|
529
|
+
const keyId = keyboardEventId(event);
|
|
530
|
+
if (event.type === 'keydown') {
|
|
531
|
+
activeDirectionKeys.delete(keyId);
|
|
532
|
+
activeDirectionKeys.set(keyId, inputDirection);
|
|
533
|
+
resumeHeldDirectionWalkAnimation();
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
activeDirectionKeys.delete(keyId);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (!isCurrentPlayer()) return;
|
|
541
|
+
if (event.type !== 'keydown' || event.repeat) return;
|
|
542
|
+
if (activeDirectionKeys.size === 0) return;
|
|
543
|
+
if (!keyboardEventMatchesBind(event, actionBind())) return;
|
|
544
|
+
if (!canControls()) return;
|
|
545
|
+
|
|
546
|
+
client.processAction(resolveCurrentActionInput());
|
|
547
|
+
};
|
|
287
548
|
|
|
288
549
|
const visible = computed(() => {
|
|
289
|
-
if (
|
|
550
|
+
if (sprite.isEvent()) {
|
|
290
551
|
return true
|
|
291
552
|
}
|
|
292
553
|
return isConnected()
|
|
293
554
|
});
|
|
294
555
|
|
|
295
|
-
const controls =
|
|
556
|
+
const controls = {
|
|
296
557
|
down: {
|
|
297
558
|
repeat: true,
|
|
298
559
|
bind: keyboardControls.down,
|
|
299
560
|
keyDown() {
|
|
300
|
-
|
|
561
|
+
activateControlDirection('down', Direction.Down)
|
|
562
|
+
processMovementInput(Direction.Down)
|
|
563
|
+
},
|
|
564
|
+
keyUp() {
|
|
565
|
+
releaseControlDirection('down')
|
|
301
566
|
},
|
|
302
567
|
},
|
|
303
568
|
up: {
|
|
304
569
|
repeat: true,
|
|
305
570
|
bind: keyboardControls.up,
|
|
306
571
|
keyDown() {
|
|
307
|
-
|
|
572
|
+
activateControlDirection('up', Direction.Up)
|
|
573
|
+
processMovementInput(Direction.Up)
|
|
574
|
+
},
|
|
575
|
+
keyUp() {
|
|
576
|
+
releaseControlDirection('up')
|
|
308
577
|
},
|
|
309
578
|
},
|
|
310
579
|
left: {
|
|
311
580
|
repeat: true,
|
|
312
581
|
bind: keyboardControls.left,
|
|
313
582
|
keyDown() {
|
|
314
|
-
|
|
583
|
+
activateControlDirection('left', Direction.Left)
|
|
584
|
+
processMovementInput(Direction.Left)
|
|
585
|
+
},
|
|
586
|
+
keyUp() {
|
|
587
|
+
releaseControlDirection('left')
|
|
315
588
|
},
|
|
316
589
|
},
|
|
317
590
|
right: {
|
|
318
591
|
repeat: true,
|
|
319
592
|
bind: keyboardControls.right,
|
|
320
593
|
keyDown() {
|
|
321
|
-
|
|
594
|
+
activateControlDirection('right', Direction.Right)
|
|
595
|
+
processMovementInput(Direction.Right)
|
|
596
|
+
},
|
|
597
|
+
keyUp() {
|
|
598
|
+
releaseControlDirection('right')
|
|
322
599
|
},
|
|
323
600
|
},
|
|
324
601
|
action: {
|
|
325
|
-
bind: keyboardControls.action,
|
|
602
|
+
bind: getKeyboardControlBind(keyboardControls.action),
|
|
326
603
|
keyDown() {
|
|
327
604
|
if (canControls()) {
|
|
328
|
-
client.processAction(
|
|
605
|
+
client.processAction(resolveCurrentActionInput())
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
},
|
|
609
|
+
dash: {
|
|
610
|
+
bind: keyboardControls.dash,
|
|
611
|
+
keyDown() {
|
|
612
|
+
processDashInput()
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
back: {
|
|
616
|
+
bind: keyboardControls.escape,
|
|
617
|
+
keyDown() {
|
|
618
|
+
if (canControls()) {
|
|
619
|
+
client.processAction({ action: 'escape' })
|
|
329
620
|
}
|
|
330
621
|
},
|
|
331
622
|
},
|
|
@@ -337,10 +628,25 @@
|
|
|
337
628
|
}
|
|
338
629
|
},
|
|
339
630
|
},
|
|
631
|
+
joystick: {
|
|
632
|
+
enabled: true,
|
|
633
|
+
directionMapping: {
|
|
634
|
+
top: 'up',
|
|
635
|
+
bottom: 'down',
|
|
636
|
+
left: 'left',
|
|
637
|
+
right: 'right',
|
|
638
|
+
top_left: ['up', 'left'],
|
|
639
|
+
top_right: ['up', 'right'],
|
|
640
|
+
bottom_left: ['down', 'left'],
|
|
641
|
+
bottom_right: ['down', 'right']
|
|
642
|
+
},
|
|
643
|
+
moveInterval: 50,
|
|
644
|
+
threshold: 0.1
|
|
645
|
+
},
|
|
340
646
|
gamepad: {
|
|
341
647
|
enabled: true
|
|
342
648
|
}
|
|
343
|
-
}
|
|
649
|
+
};
|
|
344
650
|
|
|
345
651
|
const smoothX = animatedSignal(x(), {
|
|
346
652
|
duration: isMe() ? 0 : 0
|
|
@@ -351,7 +657,8 @@
|
|
|
351
657
|
});
|
|
352
658
|
|
|
353
659
|
const z = computed(() => {
|
|
354
|
-
|
|
660
|
+
const box = hitbox?.()
|
|
661
|
+
return sprite.y() + (box?.h ?? 0) + sprite.z()
|
|
355
662
|
});
|
|
356
663
|
|
|
357
664
|
const realAnimationName = signal(animationName());
|
|
@@ -377,6 +684,344 @@
|
|
|
377
684
|
};
|
|
378
685
|
}
|
|
379
686
|
|
|
687
|
+
const graphicScale = (graphicObject) => {
|
|
688
|
+
const scale = graphicObject?.displayScale ?? graphicObject?.scale;
|
|
689
|
+
if (Array.isArray(scale)) return scale;
|
|
690
|
+
if (typeof scale === 'number') return [scale, scale];
|
|
691
|
+
if (scale && typeof scale === 'object') {
|
|
692
|
+
const x = typeof scale.x === 'number' ? scale.x : 1;
|
|
693
|
+
const y = typeof scale.y === 'number' ? scale.y : x;
|
|
694
|
+
return [x, y];
|
|
695
|
+
}
|
|
696
|
+
return undefined;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
const shadowCaster = (graphicObject) => {
|
|
700
|
+
const box = hitbox();
|
|
701
|
+
const bounds = graphicBounds();
|
|
702
|
+
const scale = graphicScale(graphicObject);
|
|
703
|
+
const scaleY = Array.isArray(scale) && typeof scale[1] === 'number' ? Math.abs(scale[1]) : 1;
|
|
704
|
+
const height = Math.max(bounds?.height ?? box?.h ?? 32, box?.h ?? 32) * scaleY;
|
|
705
|
+
|
|
706
|
+
return {
|
|
707
|
+
enabled: shadowsEnabled,
|
|
708
|
+
height,
|
|
709
|
+
footAnchor: { x: 0.5, y: 1 },
|
|
710
|
+
footOffset: { x: 0, y: 2 },
|
|
711
|
+
alpha: 0.5,
|
|
712
|
+
blur: 3.5,
|
|
713
|
+
gradientPower: 2,
|
|
714
|
+
hardness: 0.42,
|
|
715
|
+
minLength: Math.max(6, (box?.h ?? 32) * 0.25),
|
|
716
|
+
maxLength: Math.max(90, height * 1.8),
|
|
717
|
+
contactAlpha: 0.3,
|
|
718
|
+
contactScale: 0.3,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const imageDimensions = signal({});
|
|
723
|
+
const loadingImageDimensions = new Set();
|
|
724
|
+
|
|
725
|
+
const toPositiveNumber = (value) => {
|
|
726
|
+
const number = typeof value === 'number' ? value : parseFloat(value);
|
|
727
|
+
return Number.isFinite(number) && number > 0 ? number : undefined;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
const toFiniteNumber = (value, fallback = 0) => {
|
|
731
|
+
const number = typeof value === 'number' ? value : parseFloat(value);
|
|
732
|
+
return Number.isFinite(number) ? number : fallback;
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
const clampRatio = (value) => Math.min(1, Math.max(0, value));
|
|
736
|
+
|
|
737
|
+
const normalizePair = (value, fallback = [1, 1]) => {
|
|
738
|
+
if (Array.isArray(value)) {
|
|
739
|
+
const x = toFiniteNumber(value[0], fallback[0]);
|
|
740
|
+
const y = toFiniteNumber(value[1] ?? value[0], x);
|
|
741
|
+
return [x, y];
|
|
742
|
+
}
|
|
743
|
+
if (typeof value === 'number') {
|
|
744
|
+
return [value, value];
|
|
745
|
+
}
|
|
746
|
+
if (value && typeof value === 'object') {
|
|
747
|
+
const x = toFiniteNumber(value.x, fallback[0]);
|
|
748
|
+
const y = toFiniteNumber(value.y ?? value.x, x);
|
|
749
|
+
return [x, y];
|
|
750
|
+
}
|
|
751
|
+
return fallback;
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
const normalizeAnchor = (value) => {
|
|
755
|
+
if (!Array.isArray(value)) return undefined;
|
|
756
|
+
const [x, y] = normalizePair(value, [0, 0]);
|
|
757
|
+
return [clampRatio(x), clampRatio(y)];
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
const resolveImageSource = (image) => {
|
|
761
|
+
if (typeof image === 'string') return image;
|
|
762
|
+
if (typeof image?.default === 'string') return image.default;
|
|
763
|
+
return undefined;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
const parentTextureOptions = (graphicObject) => {
|
|
767
|
+
const props = [
|
|
768
|
+
'width',
|
|
769
|
+
'height',
|
|
770
|
+
'framesHeight',
|
|
771
|
+
'framesWidth',
|
|
772
|
+
'rectWidth',
|
|
773
|
+
'rectHeight',
|
|
774
|
+
'offset',
|
|
775
|
+
'image',
|
|
776
|
+
'sound',
|
|
777
|
+
'spriteRealSize',
|
|
778
|
+
'scale',
|
|
779
|
+
'anchor',
|
|
780
|
+
'pivot',
|
|
781
|
+
'x',
|
|
782
|
+
'y',
|
|
783
|
+
'opacity'
|
|
784
|
+
];
|
|
785
|
+
|
|
786
|
+
return props.reduce((options, prop) => {
|
|
787
|
+
if (graphicObject?.[prop] !== undefined) {
|
|
788
|
+
options[prop] = graphicObject[prop];
|
|
789
|
+
}
|
|
790
|
+
return options;
|
|
791
|
+
}, {});
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
const resolveTextureOptions = (graphicObject) => {
|
|
795
|
+
const textures = graphicObject?.textures ?? {};
|
|
796
|
+
const texture =
|
|
797
|
+
textures[realAnimationName()] ??
|
|
798
|
+
textures[Animation.Stand] ??
|
|
799
|
+
Object.values(textures)[0] ??
|
|
800
|
+
{};
|
|
801
|
+
|
|
802
|
+
return {
|
|
803
|
+
...parentTextureOptions(graphicObject),
|
|
804
|
+
...texture
|
|
805
|
+
};
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
const resolveFirstAnimationFrame = (textureOptions) => {
|
|
809
|
+
const animations = textureOptions?.animations;
|
|
810
|
+
if (!animations) return {};
|
|
811
|
+
|
|
812
|
+
try {
|
|
813
|
+
const frames = typeof animations === 'function'
|
|
814
|
+
? animations({ direction: direction() })
|
|
815
|
+
: animations;
|
|
816
|
+
if (!Array.isArray(frames)) return {};
|
|
817
|
+
const firstGroup = frames[0];
|
|
818
|
+
return Array.isArray(firstGroup) ? firstGroup[0] ?? {} : firstGroup ?? {};
|
|
819
|
+
}
|
|
820
|
+
catch {
|
|
821
|
+
return {};
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
const optionValue = (prop, frame, textureOptions, graphicObject) => {
|
|
826
|
+
return frame?.[prop] ?? textureOptions?.[prop] ?? graphicObject?.[prop];
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
const resolveFrameSize = (textureOptions, dimensions) => {
|
|
830
|
+
const framesWidth = toPositiveNumber(textureOptions?.framesWidth) ?? 1;
|
|
831
|
+
const framesHeight = toPositiveNumber(textureOptions?.framesHeight) ?? 1;
|
|
832
|
+
const imageSource = resolveImageSource(textureOptions?.image);
|
|
833
|
+
const loadedSize = imageSource ? dimensions[imageSource] : undefined;
|
|
834
|
+
const fullWidth = toPositiveNumber(textureOptions?.width) ?? loadedSize?.width;
|
|
835
|
+
const fullHeight = toPositiveNumber(textureOptions?.height) ?? loadedSize?.height;
|
|
836
|
+
const width = toPositiveNumber(textureOptions?.rectWidth) ??
|
|
837
|
+
toPositiveNumber(textureOptions?.spriteWidth) ??
|
|
838
|
+
(fullWidth ? fullWidth / framesWidth : undefined);
|
|
839
|
+
const height = toPositiveNumber(textureOptions?.rectHeight) ??
|
|
840
|
+
toPositiveNumber(textureOptions?.spriteHeight) ??
|
|
841
|
+
(fullHeight ? fullHeight / framesHeight : undefined);
|
|
842
|
+
|
|
843
|
+
return {
|
|
844
|
+
width,
|
|
845
|
+
height
|
|
846
|
+
};
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
const resolveHitboxAnchor = (spriteWidth, spriteHeight, realSize, box) => {
|
|
850
|
+
if (!spriteWidth || !spriteHeight || !box) {
|
|
851
|
+
return [0, 0];
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const heightOfSprite = typeof realSize === 'number' ? realSize : realSize?.height;
|
|
855
|
+
const resolvedHeight = toPositiveNumber(heightOfSprite) ?? spriteHeight;
|
|
856
|
+
const gap = Math.max(0, (spriteHeight - resolvedHeight) / 2);
|
|
857
|
+
const hitboxTopLeftX = clampRatio((spriteWidth - box.w) / 2 / spriteWidth);
|
|
858
|
+
const hitboxTopLeftY = clampRatio((spriteHeight - box.h - gap) / spriteHeight);
|
|
859
|
+
const hitboxCenterX = clampRatio(hitboxTopLeftX + box.w / 2 / spriteWidth);
|
|
860
|
+
const hitboxCenterY = clampRatio(hitboxTopLeftY + box.h / 2 / spriteHeight);
|
|
861
|
+
const footY = clampRatio((spriteHeight - gap) / spriteHeight);
|
|
862
|
+
|
|
863
|
+
switch (box.anchorMode ?? 'top-left') {
|
|
864
|
+
case 'center':
|
|
865
|
+
return [hitboxCenterX, hitboxCenterY];
|
|
866
|
+
case 'foot':
|
|
867
|
+
return [hitboxCenterX, footY];
|
|
868
|
+
case 'top-left':
|
|
869
|
+
default:
|
|
870
|
+
return [hitboxTopLeftX, hitboxTopLeftY];
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
const loadImageDimensions = (image) => {
|
|
875
|
+
const source = resolveImageSource(image);
|
|
876
|
+
if (!source || imageDimensions()[source] || loadingImageDimensions.has(source)) {
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
loadingImageDimensions.add(source);
|
|
881
|
+
Assets.load(source)
|
|
882
|
+
.then((texture) => {
|
|
883
|
+
const width = toPositiveNumber(texture?.width);
|
|
884
|
+
const height = toPositiveNumber(texture?.height);
|
|
885
|
+
if (!width || !height) return;
|
|
886
|
+
|
|
887
|
+
imageDimensions.update((dimensions) => ({
|
|
888
|
+
...dimensions,
|
|
889
|
+
[source]: { width, height }
|
|
890
|
+
}));
|
|
891
|
+
})
|
|
892
|
+
.catch(() => {})
|
|
893
|
+
.finally(() => {
|
|
894
|
+
loadingImageDimensions.delete(source);
|
|
895
|
+
});
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
effect(() => {
|
|
899
|
+
const sources = new Set();
|
|
900
|
+
|
|
901
|
+
graphicsSignals().forEach((graphicObject) => {
|
|
902
|
+
const baseImage = resolveImageSource(graphicObject?.image);
|
|
903
|
+
if (baseImage) sources.add(baseImage);
|
|
904
|
+
|
|
905
|
+
Object.values(graphicObject?.textures ?? {}).forEach((textureOptions) => {
|
|
906
|
+
const image = resolveImageSource(textureOptions?.image ?? graphicObject?.image);
|
|
907
|
+
if (image) sources.add(image);
|
|
908
|
+
});
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
sources.forEach((source) => loadImageDimensions(source));
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
const hitboxBounds = computed(() => {
|
|
915
|
+
const box = hitbox();
|
|
916
|
+
const width = box?.w ?? 0;
|
|
917
|
+
const height = box?.h ?? 0;
|
|
918
|
+
|
|
919
|
+
return {
|
|
920
|
+
left: 0,
|
|
921
|
+
top: 0,
|
|
922
|
+
right: width,
|
|
923
|
+
bottom: height,
|
|
924
|
+
width,
|
|
925
|
+
height,
|
|
926
|
+
centerX: width / 2,
|
|
927
|
+
centerY: height / 2
|
|
928
|
+
};
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
const graphicBounds = computed(() => {
|
|
932
|
+
const box = hitbox();
|
|
933
|
+
const fallback = hitboxBounds();
|
|
934
|
+
const customEventComponent = resolvedEventComponents()[0];
|
|
935
|
+
if (customEventComponent && !customEventComponent.renderGraphic) {
|
|
936
|
+
return fallback;
|
|
937
|
+
}
|
|
938
|
+
const dimensions = imageDimensions();
|
|
939
|
+
const graphics = graphicsSignals();
|
|
940
|
+
let bounds = null;
|
|
941
|
+
|
|
942
|
+
graphics.forEach((graphicObject) => {
|
|
943
|
+
const textureOptions = resolveTextureOptions(graphicObject);
|
|
944
|
+
const frame = resolveFirstAnimationFrame(textureOptions);
|
|
945
|
+
const size = resolveFrameSize(textureOptions, dimensions);
|
|
946
|
+
const spriteWidth = size.width ?? box?.w;
|
|
947
|
+
const spriteHeight = size.height ?? box?.h;
|
|
948
|
+
|
|
949
|
+
if (!spriteWidth || !spriteHeight) {
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
const explicitAnchor = normalizeAnchor(optionValue('anchor', frame, textureOptions, graphicObject));
|
|
954
|
+
const anchor = explicitAnchor ?? resolveHitboxAnchor(
|
|
955
|
+
spriteWidth,
|
|
956
|
+
spriteHeight,
|
|
957
|
+
optionValue('spriteRealSize', frame, textureOptions, graphicObject),
|
|
958
|
+
box
|
|
959
|
+
);
|
|
960
|
+
const scale = normalizePair(optionValue('scale', frame, textureOptions, graphicObject) ?? graphicScale(graphicObject));
|
|
961
|
+
const x = toFiniteNumber(optionValue('x', frame, textureOptions, graphicObject), 0);
|
|
962
|
+
const y = toFiniteNumber(optionValue('y', frame, textureOptions, graphicObject), 0);
|
|
963
|
+
const leftEdge = -anchor[0] * spriteWidth * scale[0];
|
|
964
|
+
const rightEdge = (1 - anchor[0]) * spriteWidth * scale[0];
|
|
965
|
+
const topEdge = -anchor[1] * spriteHeight * scale[1];
|
|
966
|
+
const bottomEdge = (1 - anchor[1]) * spriteHeight * scale[1];
|
|
967
|
+
const graphic = {
|
|
968
|
+
left: x + Math.min(leftEdge, rightEdge),
|
|
969
|
+
top: y + Math.min(topEdge, bottomEdge),
|
|
970
|
+
right: x + Math.max(leftEdge, rightEdge),
|
|
971
|
+
bottom: y + Math.max(topEdge, bottomEdge)
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
bounds = bounds
|
|
975
|
+
? {
|
|
976
|
+
left: Math.min(bounds.left, graphic.left),
|
|
977
|
+
top: Math.min(bounds.top, graphic.top),
|
|
978
|
+
right: Math.max(bounds.right, graphic.right),
|
|
979
|
+
bottom: Math.max(bounds.bottom, graphic.bottom)
|
|
980
|
+
}
|
|
981
|
+
: graphic;
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
if (!bounds) {
|
|
985
|
+
return fallback;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
const width = bounds.right - bounds.left;
|
|
989
|
+
const height = bounds.bottom - bounds.top;
|
|
990
|
+
|
|
991
|
+
return {
|
|
992
|
+
...bounds,
|
|
993
|
+
width,
|
|
994
|
+
height,
|
|
995
|
+
centerX: bounds.left + width / 2,
|
|
996
|
+
centerY: bounds.top + height / 2
|
|
997
|
+
};
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
const interactionBounds = () => ({
|
|
1001
|
+
bounds: graphicBounds(),
|
|
1002
|
+
hitbox: hitboxBounds(),
|
|
1003
|
+
graphic: graphicBounds()
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
const interactionCursor = computed(() =>
|
|
1007
|
+
client.interactions.cursorFor(sprite, interactionBounds())
|
|
1008
|
+
);
|
|
1009
|
+
|
|
1010
|
+
const handleInteraction = (type) => (event) => {
|
|
1011
|
+
client.updatePointerFromInteractionEvent(event);
|
|
1012
|
+
client.interactions.handle(sprite, type, {
|
|
1013
|
+
event,
|
|
1014
|
+
bounds: interactionBounds()
|
|
1015
|
+
});
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
const interactionPointerOver = handleInteraction('pointerover');
|
|
1019
|
+
const interactionPointerOut = handleInteraction('pointerout');
|
|
1020
|
+
const interactionPointerDown = handleInteraction('pointerdown');
|
|
1021
|
+
const interactionPointerUp = handleInteraction('pointerup');
|
|
1022
|
+
const interactionPointerMove = handleInteraction('pointermove');
|
|
1023
|
+
const interactionClick = handleInteraction('click');
|
|
1024
|
+
|
|
380
1025
|
// Combine animation change detection with movement state from smoothX/smoothY
|
|
381
1026
|
const movementAnimations = ['walk', 'stand'];
|
|
382
1027
|
const epsilon = 0; // movement threshold to consider the easing still running
|
|
@@ -400,25 +1045,91 @@
|
|
|
400
1045
|
filter(([prev, curr]) => prev !== curr)
|
|
401
1046
|
);
|
|
402
1047
|
|
|
1048
|
+
let beforeRemovePromise = null;
|
|
1049
|
+
let beforeRemoveTransitionValue = null;
|
|
1050
|
+
const resolveRemoveContext = () => {
|
|
1051
|
+
if (!sprite._removeTransition) return null;
|
|
1052
|
+
const value = sprite._removeTransition();
|
|
1053
|
+
if (!value || typeof value !== 'string') return null;
|
|
1054
|
+
try {
|
|
1055
|
+
const context = JSON.parse(value);
|
|
1056
|
+
if (!context || typeof context !== 'object' || !context.active) return null;
|
|
1057
|
+
context.__transitionValue = value;
|
|
1058
|
+
return context;
|
|
1059
|
+
}
|
|
1060
|
+
catch {
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
const withTimeout = (promise, timeoutMs = 0) => {
|
|
1066
|
+
if (!timeoutMs || timeoutMs <= 0) return promise;
|
|
1067
|
+
return Promise.race([
|
|
1068
|
+
promise,
|
|
1069
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs)),
|
|
1070
|
+
]);
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
const runBeforeRemove = () => {
|
|
1074
|
+
const context = resolveRemoveContext();
|
|
1075
|
+
if (!context) return Promise.resolve();
|
|
1076
|
+
if (beforeRemovePromise && beforeRemoveTransitionValue === context.__transitionValue) {
|
|
1077
|
+
return beforeRemovePromise;
|
|
1078
|
+
}
|
|
1079
|
+
beforeRemoveTransitionValue = context.__transitionValue;
|
|
1080
|
+
beforeRemovePromise = withTimeout(
|
|
1081
|
+
lastValueFrom(hooks.callHooks("client-sprite-onBeforeRemove", sprite, context)),
|
|
1082
|
+
context.timeoutMs
|
|
1083
|
+
);
|
|
1084
|
+
return beforeRemovePromise;
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
const removeTransitionSubscription = sprite._removeTransition?.observable?.subscribe(() => {
|
|
1088
|
+
if (resolveRemoveContext()) {
|
|
1089
|
+
runBeforeRemove();
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
|
|
403
1093
|
const animationMovementSubscription = combineLatest([animationChange$, moving$]).subscribe(([[prev, curr], isMoving]) => {
|
|
404
|
-
|
|
1094
|
+
const isMovementAnimation = movementAnimations.includes(curr);
|
|
1095
|
+
const isTemporaryAnimationPlaying =
|
|
1096
|
+
sprite.animationIsPlaying && sprite.animationIsPlaying();
|
|
1097
|
+
|
|
1098
|
+
if (sprite.animationFixed && isMovementAnimation) {
|
|
405
1099
|
realAnimationName.set(curr);
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
if (curr == 'stand' && !isMoving) {
|
|
1104
|
+
if (!resumeHeldDirectionWalkAnimation()) {
|
|
1105
|
+
realAnimationName.set(curr);
|
|
1106
|
+
}
|
|
406
1107
|
}
|
|
407
1108
|
else if (curr == 'walk' && isMoving) {
|
|
408
1109
|
realAnimationName.set(curr);
|
|
409
1110
|
}
|
|
410
|
-
else if (!
|
|
1111
|
+
else if (!isMovementAnimation) {
|
|
411
1112
|
realAnimationName.set(curr);
|
|
412
1113
|
}
|
|
413
|
-
if (!isMoving &&
|
|
414
|
-
if (
|
|
415
|
-
if (typeof
|
|
416
|
-
|
|
1114
|
+
if (!isMoving && isTemporaryAnimationPlaying) {
|
|
1115
|
+
if (isMovementAnimation) {
|
|
1116
|
+
if (typeof sprite.resetAnimationState === 'function') {
|
|
1117
|
+
sprite.resetAnimationState();
|
|
417
1118
|
}
|
|
418
1119
|
}
|
|
419
1120
|
}
|
|
420
1121
|
});
|
|
421
1122
|
|
|
1123
|
+
const resumeWalkSubscriptions = [
|
|
1124
|
+
sprite._canMove,
|
|
1125
|
+
sprite._animationFixed,
|
|
1126
|
+
sprite.animationIsPlaying,
|
|
1127
|
+
]
|
|
1128
|
+
.filter(signal => signal?.observable)
|
|
1129
|
+
.map(signal => signal.observable.subscribe(() => {
|
|
1130
|
+
resumeHeldDirectionWalkAnimation();
|
|
1131
|
+
}));
|
|
1132
|
+
|
|
422
1133
|
/**
|
|
423
1134
|
* Cleanup subscriptions and call hooks before sprite destruction.
|
|
424
1135
|
*
|
|
@@ -429,18 +1140,93 @@
|
|
|
429
1140
|
* @example
|
|
430
1141
|
* await onBeforeDestroy();
|
|
431
1142
|
*/
|
|
1143
|
+
const waitForTemporaryAnimationEnd = (maxDuration = 1200) => {
|
|
1144
|
+
if (!sprite.animationIsPlaying || !sprite.animationIsPlaying()) {
|
|
1145
|
+
return Promise.resolve();
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
return new Promise((resolve) => {
|
|
1149
|
+
let finished = false;
|
|
1150
|
+
let timeout;
|
|
1151
|
+
let subscription;
|
|
1152
|
+
const finish = () => {
|
|
1153
|
+
if (finished) return;
|
|
1154
|
+
finished = true;
|
|
1155
|
+
clearTimeout(timeout);
|
|
1156
|
+
subscription?.unsubscribe();
|
|
1157
|
+
resolve();
|
|
1158
|
+
};
|
|
1159
|
+
timeout = setTimeout(finish, maxDuration);
|
|
1160
|
+
subscription = sprite.animationIsPlaying.observable.subscribe((isPlaying) => {
|
|
1161
|
+
if (!isPlaying) finish();
|
|
1162
|
+
});
|
|
1163
|
+
if (finished) subscription.unsubscribe();
|
|
1164
|
+
});
|
|
1165
|
+
};
|
|
1166
|
+
|
|
432
1167
|
const onBeforeDestroy = async () => {
|
|
1168
|
+
await runBeforeRemove();
|
|
1169
|
+
await waitForTemporaryAnimationEnd();
|
|
1170
|
+
if (typeof document !== 'undefined') {
|
|
1171
|
+
document.removeEventListener('keydown', handleNativeActionWhileMoving);
|
|
1172
|
+
document.removeEventListener('keyup', handleNativeActionWhileMoving);
|
|
1173
|
+
}
|
|
1174
|
+
removeTransitionSubscription?.unsubscribe();
|
|
433
1175
|
animationMovementSubscription.unsubscribe();
|
|
1176
|
+
resumeWalkSubscriptions.forEach(subscription => subscription.unsubscribe());
|
|
1177
|
+
activeControlDirectionReleaseTimers.forEach(timer => clearTimeout(timer));
|
|
1178
|
+
activeControlDirectionReleaseTimers.clear();
|
|
434
1179
|
xSubscription.unsubscribe();
|
|
435
1180
|
ySubscription.unsubscribe();
|
|
436
|
-
await lastValueFrom(hooks.callHooks("client-sprite-onDestroy",
|
|
437
|
-
await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap,
|
|
1181
|
+
await lastValueFrom(hooks.callHooks("client-sprite-onDestroy", sprite))
|
|
1182
|
+
await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap, sprite))
|
|
438
1183
|
}
|
|
439
1184
|
|
|
440
1185
|
mount((element) => {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
1186
|
+
let appliedCameraFollowRevision = null;
|
|
1187
|
+
if (typeof document !== 'undefined') {
|
|
1188
|
+
document.addEventListener('keydown', handleNativeActionWhileMoving);
|
|
1189
|
+
document.addEventListener('keyup', handleNativeActionWhileMoving);
|
|
1190
|
+
}
|
|
1191
|
+
hooks.callHooks("client-sprite-onAdd", sprite).subscribe()
|
|
1192
|
+
hooks.callHooks("client-sceneMap-onAddSprite", client.sceneMap, sprite).subscribe()
|
|
1193
|
+
effect(() => {
|
|
1194
|
+
if (isCurrentPlayer()) {
|
|
1195
|
+
client.setKeyboardControls(element.directives.controls)
|
|
1196
|
+
}
|
|
1197
|
+
})
|
|
1198
|
+
|
|
1199
|
+
effect(() => {
|
|
1200
|
+
const followRevision = client.cameraFollowRevision();
|
|
1201
|
+
if (!shouldFollowCamera()) {
|
|
1202
|
+
appliedCameraFollowRevision = null;
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
const smoothMove = client.cameraFollowSmoothMove;
|
|
1207
|
+
const viewport = element.props.context?.viewport;
|
|
1208
|
+
const target = element.componentInstance;
|
|
1209
|
+
if (!viewport || !target) {
|
|
1210
|
+
appliedCameraFollowRevision = null;
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
const appliedCameraFollow = applyCameraFollow({
|
|
1215
|
+
viewport,
|
|
1216
|
+
target,
|
|
1217
|
+
smoothMove,
|
|
1218
|
+
followRevision,
|
|
1219
|
+
isCurrentRevision: (revision) => client.cameraFollowRevision() === revision,
|
|
1220
|
+
shouldFollowCamera
|
|
1221
|
+
});
|
|
1222
|
+
appliedCameraFollowRevision = appliedCameraFollow ? followRevision : null;
|
|
1223
|
+
})
|
|
1224
|
+
|
|
1225
|
+
return () => {
|
|
1226
|
+
if (ownsCameraFollowRevision(appliedCameraFollowRevision, client.cameraFollowRevision())) {
|
|
1227
|
+
clearCameraFollowPlugins(element.props.context?.viewport);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
444
1230
|
})
|
|
445
1231
|
|
|
446
1232
|
/**
|
|
@@ -449,8 +1235,16 @@
|
|
|
449
1235
|
* @param gui - The GUI instance
|
|
450
1236
|
* @param data - Data passed from the GUI component
|
|
451
1237
|
*/
|
|
452
|
-
const
|
|
453
|
-
|
|
1238
|
+
const normalizeOpenId = (value) => {
|
|
1239
|
+
const resolved = typeof value === "function" ? value() : value;
|
|
1240
|
+
return typeof resolved === "string" && resolved.length > 0 ? resolved : undefined;
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
const onAttachedGuiFinish = (gui, data, guiOpenId) => {
|
|
1244
|
+
const completedOpenId = normalizeOpenId(guiOpenId);
|
|
1245
|
+
const currentOpenId = normalizeOpenId(gui.openId);
|
|
1246
|
+
if (completedOpenId && currentOpenId && completedOpenId !== currentOpenId) return;
|
|
1247
|
+
guiService.guiClose(gui.name, data, completedOpenId ?? currentOpenId);
|
|
454
1248
|
};
|
|
455
1249
|
|
|
456
1250
|
/**
|
|
@@ -467,4 +1261,4 @@
|
|
|
467
1261
|
tick(() => {
|
|
468
1262
|
hooks.callHooks("client-sprite-onUpdate").subscribe()
|
|
469
1263
|
})
|
|
470
|
-
</script>
|
|
1264
|
+
</script>
|