@rpgjs/client 5.0.0-beta.2 → 5.0.0-beta.20
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 +123 -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 +96 -54
- 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 +176 -11
- package/dist/RpgClientEngine.js +669 -68
- 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 +606 -248
- 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.js +2 -2
- package/dist/components/gui/mobile/index.js.map +1 -1
- package/dist/components/gui/mobile/mobile.ce.js +7 -5
- 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 +7 -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/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 +340 -0
- package/src/Gui/Gui.ts +129 -57
- package/src/Resource.ts +1 -2
- package/src/RpgClient.ts +220 -17
- package/src/RpgClientEngine.ts +959 -116
- package/src/components/animations/fx.ce +101 -0
- package/src/components/animations/index.ts +4 -2
- package/src/components/character.ce +681 -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/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 +7 -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/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,65 @@
|
|
|
1
|
-
<Container
|
|
1
|
+
<Container
|
|
2
|
+
x={smoothX}
|
|
3
|
+
y={smoothY}
|
|
4
|
+
zIndex={z}
|
|
5
|
+
viewportFollow={shouldFollowCamera}
|
|
6
|
+
controls
|
|
7
|
+
onBeforeDestroy
|
|
8
|
+
visible
|
|
9
|
+
cursor={interactionCursor}
|
|
10
|
+
pointerover={interactionPointerOver}
|
|
11
|
+
pointerout={interactionPointerOut}
|
|
12
|
+
pointerdown={interactionPointerDown}
|
|
13
|
+
pointerup={interactionPointerUp}
|
|
14
|
+
pointermove={interactionPointerMove}
|
|
15
|
+
click={interactionClick}
|
|
16
|
+
>
|
|
2
17
|
@for (compConfig of normalizedComponentsBehind) {
|
|
3
18
|
<Container>
|
|
4
|
-
<compConfig.component object ...compConfig.props />
|
|
19
|
+
<compConfig.component object={sprite} ...compConfig.props />
|
|
5
20
|
</Container>
|
|
6
21
|
}
|
|
22
|
+
<PlayerComponents object={sprite} position="bottom" graphicBounds />
|
|
23
|
+
<PlayerComponents object={sprite} position="left" graphicBounds />
|
|
7
24
|
<Particle emit={emitParticleTrigger} settings={particleSettings} zIndex={1000} name={particleName} />
|
|
8
25
|
<Container>
|
|
9
|
-
@for (graphicObj of
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
@for (graphicObj of renderedGraphics) {
|
|
27
|
+
<Container scale={graphicScale(graphicObj)}>
|
|
28
|
+
<Sprite
|
|
29
|
+
sheet={sheet(graphicObj)}
|
|
30
|
+
direction
|
|
31
|
+
tint
|
|
32
|
+
hitbox
|
|
33
|
+
shadowCaster={shadowCaster(graphicObj)}
|
|
34
|
+
flash={flashConfig}
|
|
35
|
+
/>
|
|
36
|
+
</Container>
|
|
37
|
+
}
|
|
38
|
+
@for (eventComponent of resolvedEventComponents) {
|
|
39
|
+
<Container dependencies={eventComponent.dependencies}>
|
|
40
|
+
<eventComponent.component ...eventComponent.props />
|
|
41
|
+
</Container>
|
|
17
42
|
}
|
|
18
43
|
</Container>
|
|
44
|
+
<PlayerComponents object={sprite} position="center" graphicBounds />
|
|
45
|
+
<PlayerComponents object={sprite} position="right" graphicBounds />
|
|
46
|
+
<PlayerComponents object={sprite} position="top" graphicBounds />
|
|
19
47
|
@for (compConfig of normalizedComponentsInFront) {
|
|
20
48
|
<Container dependencies={compConfig.dependencies}>
|
|
21
|
-
<compConfig.component object ...compConfig.props />
|
|
49
|
+
<compConfig.component object={sprite} ...compConfig.props />
|
|
22
50
|
</Container>
|
|
23
51
|
}
|
|
52
|
+
<InteractionComponents
|
|
53
|
+
object={sprite}
|
|
54
|
+
bounds={graphicBounds}
|
|
55
|
+
hitboxBounds={hitboxBounds}
|
|
56
|
+
graphicBounds={graphicBounds}
|
|
57
|
+
/>
|
|
24
58
|
@for (attachedGui of attachedGuis) {
|
|
25
59
|
@if (shouldDisplayAttachedGui) {
|
|
26
60
|
<Container>
|
|
27
|
-
<attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={
|
|
28
|
-
onAttachedGuiFinish(attachedGui, data)
|
|
61
|
+
<attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={sprite} guiOpenId={attachedGui.openId} onFinish={(data, guiOpenId) => {
|
|
62
|
+
onAttachedGuiFinish(attachedGui, data, guiOpenId)
|
|
29
63
|
}} onInteraction={(name, data) => {
|
|
30
64
|
onAttachedGuiInteraction(attachedGui, name, data)
|
|
31
65
|
}} />
|
|
@@ -36,28 +70,51 @@
|
|
|
36
70
|
|
|
37
71
|
<script>
|
|
38
72
|
import { signal, effect, mount, computed, tick, animatedSignal, on } from "canvasengine";
|
|
73
|
+
import { Assets } from "pixi.js";
|
|
39
74
|
|
|
40
75
|
import { lastValueFrom, combineLatest, pairwise, filter, map, startWith } from "rxjs";
|
|
41
76
|
import { Particle } from "@canvasengine/presets";
|
|
42
|
-
import { GameEngineToken, ModulesToken } from "@rpgjs/common";
|
|
77
|
+
import { GameEngineToken, ModulesToken, shouldRenderLightingShadows } from "@rpgjs/common";
|
|
43
78
|
import { RpgClientEngine } from "../RpgClientEngine";
|
|
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,53 +357,161 @@
|
|
|
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
|
+
|
|
364
|
+
const resolveHeldDirection = () => {
|
|
365
|
+
const directions = Array.from(activeDirectionKeys.values());
|
|
366
|
+
return directions[directions.length - 1];
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const resolveSpriteDirection = () => {
|
|
370
|
+
const heldDirection = resolveHeldDirection();
|
|
371
|
+
if (heldDirection) return heldDirection;
|
|
372
|
+
if (typeof sprite.getDirection === 'function') return sprite.getDirection();
|
|
373
|
+
if (typeof sprite.direction === 'function') return sprite.direction();
|
|
374
|
+
return direction();
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const directionToDashVector = (currentDirection) => {
|
|
378
|
+
switch (currentDirection) {
|
|
379
|
+
case Direction.Left:
|
|
380
|
+
return { x: -1, y: 0 };
|
|
381
|
+
case Direction.Right:
|
|
382
|
+
return { x: 1, y: 0 };
|
|
383
|
+
case Direction.Up:
|
|
384
|
+
return { x: 0, y: -1 };
|
|
385
|
+
case Direction.Down:
|
|
386
|
+
default:
|
|
387
|
+
return { x: 0, y: 1 };
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
const withCurrentDirection = (payload) => {
|
|
392
|
+
if (payload.action !== 'action') return payload;
|
|
393
|
+
const data = payload.data && typeof payload.data === 'object'
|
|
394
|
+
? { ...payload.data }
|
|
395
|
+
: {};
|
|
396
|
+
return {
|
|
397
|
+
...payload,
|
|
398
|
+
data: {
|
|
399
|
+
...data,
|
|
400
|
+
direction: data.direction ?? resolveSpriteDirection(),
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const resolveCurrentActionInput = () =>
|
|
406
|
+
withCurrentDirection(
|
|
407
|
+
resolveKeyboardActionInput(keyboardControls.action, client, sprite)
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
const playPredictedWalkAnimation = () => {
|
|
411
|
+
if (sprite.animationFixed) return;
|
|
412
|
+
if (sprite.animationIsPlaying && sprite.animationIsPlaying()) return;
|
|
413
|
+
realAnimationName.set('walk');
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const resumeHeldDirectionWalkAnimation = () => {
|
|
417
|
+
if (!isCurrentPlayer()) return false;
|
|
418
|
+
if (activeDirectionKeys.size === 0) return false;
|
|
419
|
+
if (!canControls()) return false;
|
|
420
|
+
if (sprite.animationFixed) return false;
|
|
421
|
+
if (sprite.animationIsPlaying && sprite.animationIsPlaying()) return false;
|
|
422
|
+
realAnimationName.set('walk');
|
|
423
|
+
return true;
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const processMovementInput = (input) => {
|
|
427
|
+
if (!canControls()) return;
|
|
428
|
+
client.processInput({ input });
|
|
429
|
+
playPredictedWalkAnimation();
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const processDashInput = () => {
|
|
433
|
+
if (!canControls()) return;
|
|
434
|
+
client.processDash({
|
|
435
|
+
direction: directionToDashVector(resolveSpriteDirection()),
|
|
436
|
+
});
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const actionBind = () => getKeyboardControlBind(keyboardControls.action);
|
|
440
|
+
const keyboardEventId = (event) => `${event.keyCode}:${event.code}:${event.key}`;
|
|
441
|
+
|
|
442
|
+
const handleNativeActionWhileMoving = (event) => {
|
|
443
|
+
const inputDirection = resolveKeyboardDirectionInput(event, keyboardControls);
|
|
444
|
+
if (inputDirection) {
|
|
445
|
+
const keyId = keyboardEventId(event);
|
|
446
|
+
if (event.type === 'keydown') {
|
|
447
|
+
activeDirectionKeys.delete(keyId);
|
|
448
|
+
activeDirectionKeys.set(keyId, inputDirection);
|
|
449
|
+
resumeHeldDirectionWalkAnimation();
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
activeDirectionKeys.delete(keyId);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (!isCurrentPlayer()) return;
|
|
457
|
+
if (event.type !== 'keydown' || event.repeat) return;
|
|
458
|
+
if (activeDirectionKeys.size === 0) return;
|
|
459
|
+
if (!keyboardEventMatchesBind(event, actionBind())) return;
|
|
460
|
+
if (!canControls()) return;
|
|
461
|
+
|
|
462
|
+
client.processAction(resolveCurrentActionInput());
|
|
463
|
+
};
|
|
287
464
|
|
|
288
465
|
const visible = computed(() => {
|
|
289
|
-
if (
|
|
466
|
+
if (sprite.isEvent()) {
|
|
290
467
|
return true
|
|
291
468
|
}
|
|
292
469
|
return isConnected()
|
|
293
470
|
});
|
|
294
471
|
|
|
295
|
-
const controls =
|
|
472
|
+
const controls = {
|
|
296
473
|
down: {
|
|
297
474
|
repeat: true,
|
|
298
475
|
bind: keyboardControls.down,
|
|
299
476
|
keyDown() {
|
|
300
|
-
|
|
477
|
+
processMovementInput(Direction.Down)
|
|
301
478
|
},
|
|
302
479
|
},
|
|
303
480
|
up: {
|
|
304
481
|
repeat: true,
|
|
305
482
|
bind: keyboardControls.up,
|
|
306
483
|
keyDown() {
|
|
307
|
-
|
|
484
|
+
processMovementInput(Direction.Up)
|
|
308
485
|
},
|
|
309
486
|
},
|
|
310
487
|
left: {
|
|
311
488
|
repeat: true,
|
|
312
489
|
bind: keyboardControls.left,
|
|
313
490
|
keyDown() {
|
|
314
|
-
|
|
491
|
+
processMovementInput(Direction.Left)
|
|
315
492
|
},
|
|
316
493
|
},
|
|
317
494
|
right: {
|
|
318
495
|
repeat: true,
|
|
319
496
|
bind: keyboardControls.right,
|
|
320
497
|
keyDown() {
|
|
321
|
-
|
|
498
|
+
processMovementInput(Direction.Right)
|
|
322
499
|
},
|
|
323
500
|
},
|
|
324
501
|
action: {
|
|
325
|
-
bind: keyboardControls.action,
|
|
502
|
+
bind: getKeyboardControlBind(keyboardControls.action),
|
|
326
503
|
keyDown() {
|
|
327
504
|
if (canControls()) {
|
|
328
|
-
client.processAction(
|
|
505
|
+
client.processAction(resolveCurrentActionInput())
|
|
329
506
|
}
|
|
330
507
|
},
|
|
331
508
|
},
|
|
509
|
+
dash: {
|
|
510
|
+
bind: keyboardControls.dash,
|
|
511
|
+
keyDown() {
|
|
512
|
+
processDashInput()
|
|
513
|
+
},
|
|
514
|
+
},
|
|
332
515
|
escape: {
|
|
333
516
|
bind: keyboardControls.escape,
|
|
334
517
|
keyDown() {
|
|
@@ -340,7 +523,7 @@
|
|
|
340
523
|
gamepad: {
|
|
341
524
|
enabled: true
|
|
342
525
|
}
|
|
343
|
-
}
|
|
526
|
+
};
|
|
344
527
|
|
|
345
528
|
const smoothX = animatedSignal(x(), {
|
|
346
529
|
duration: isMe() ? 0 : 0
|
|
@@ -351,7 +534,8 @@
|
|
|
351
534
|
});
|
|
352
535
|
|
|
353
536
|
const z = computed(() => {
|
|
354
|
-
|
|
537
|
+
const box = hitbox?.()
|
|
538
|
+
return sprite.y() + (box?.h ?? 0) + sprite.z()
|
|
355
539
|
});
|
|
356
540
|
|
|
357
541
|
const realAnimationName = signal(animationName());
|
|
@@ -377,6 +561,344 @@
|
|
|
377
561
|
};
|
|
378
562
|
}
|
|
379
563
|
|
|
564
|
+
const graphicScale = (graphicObject) => {
|
|
565
|
+
const scale = graphicObject?.displayScale ?? graphicObject?.scale;
|
|
566
|
+
if (Array.isArray(scale)) return scale;
|
|
567
|
+
if (typeof scale === 'number') return [scale, scale];
|
|
568
|
+
if (scale && typeof scale === 'object') {
|
|
569
|
+
const x = typeof scale.x === 'number' ? scale.x : 1;
|
|
570
|
+
const y = typeof scale.y === 'number' ? scale.y : x;
|
|
571
|
+
return [x, y];
|
|
572
|
+
}
|
|
573
|
+
return undefined;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const shadowCaster = (graphicObject) => {
|
|
577
|
+
const box = hitbox();
|
|
578
|
+
const bounds = graphicBounds();
|
|
579
|
+
const scale = graphicScale(graphicObject);
|
|
580
|
+
const scaleY = Array.isArray(scale) && typeof scale[1] === 'number' ? Math.abs(scale[1]) : 1;
|
|
581
|
+
const height = Math.max(bounds?.height ?? box?.h ?? 32, box?.h ?? 32) * scaleY;
|
|
582
|
+
|
|
583
|
+
return {
|
|
584
|
+
enabled: shadowsEnabled,
|
|
585
|
+
height,
|
|
586
|
+
footAnchor: { x: 0.5, y: 1 },
|
|
587
|
+
footOffset: { x: 0, y: 2 },
|
|
588
|
+
alpha: 0.5,
|
|
589
|
+
blur: 3.5,
|
|
590
|
+
gradientPower: 2,
|
|
591
|
+
hardness: 0.42,
|
|
592
|
+
minLength: Math.max(6, (box?.h ?? 32) * 0.25),
|
|
593
|
+
maxLength: Math.max(90, height * 1.8),
|
|
594
|
+
contactAlpha: 0.3,
|
|
595
|
+
contactScale: 0.3,
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const imageDimensions = signal({});
|
|
600
|
+
const loadingImageDimensions = new Set();
|
|
601
|
+
|
|
602
|
+
const toPositiveNumber = (value) => {
|
|
603
|
+
const number = typeof value === 'number' ? value : parseFloat(value);
|
|
604
|
+
return Number.isFinite(number) && number > 0 ? number : undefined;
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
const toFiniteNumber = (value, fallback = 0) => {
|
|
608
|
+
const number = typeof value === 'number' ? value : parseFloat(value);
|
|
609
|
+
return Number.isFinite(number) ? number : fallback;
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
const clampRatio = (value) => Math.min(1, Math.max(0, value));
|
|
613
|
+
|
|
614
|
+
const normalizePair = (value, fallback = [1, 1]) => {
|
|
615
|
+
if (Array.isArray(value)) {
|
|
616
|
+
const x = toFiniteNumber(value[0], fallback[0]);
|
|
617
|
+
const y = toFiniteNumber(value[1] ?? value[0], x);
|
|
618
|
+
return [x, y];
|
|
619
|
+
}
|
|
620
|
+
if (typeof value === 'number') {
|
|
621
|
+
return [value, value];
|
|
622
|
+
}
|
|
623
|
+
if (value && typeof value === 'object') {
|
|
624
|
+
const x = toFiniteNumber(value.x, fallback[0]);
|
|
625
|
+
const y = toFiniteNumber(value.y ?? value.x, x);
|
|
626
|
+
return [x, y];
|
|
627
|
+
}
|
|
628
|
+
return fallback;
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
const normalizeAnchor = (value) => {
|
|
632
|
+
if (!Array.isArray(value)) return undefined;
|
|
633
|
+
const [x, y] = normalizePair(value, [0, 0]);
|
|
634
|
+
return [clampRatio(x), clampRatio(y)];
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
const resolveImageSource = (image) => {
|
|
638
|
+
if (typeof image === 'string') return image;
|
|
639
|
+
if (typeof image?.default === 'string') return image.default;
|
|
640
|
+
return undefined;
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
const parentTextureOptions = (graphicObject) => {
|
|
644
|
+
const props = [
|
|
645
|
+
'width',
|
|
646
|
+
'height',
|
|
647
|
+
'framesHeight',
|
|
648
|
+
'framesWidth',
|
|
649
|
+
'rectWidth',
|
|
650
|
+
'rectHeight',
|
|
651
|
+
'offset',
|
|
652
|
+
'image',
|
|
653
|
+
'sound',
|
|
654
|
+
'spriteRealSize',
|
|
655
|
+
'scale',
|
|
656
|
+
'anchor',
|
|
657
|
+
'pivot',
|
|
658
|
+
'x',
|
|
659
|
+
'y',
|
|
660
|
+
'opacity'
|
|
661
|
+
];
|
|
662
|
+
|
|
663
|
+
return props.reduce((options, prop) => {
|
|
664
|
+
if (graphicObject?.[prop] !== undefined) {
|
|
665
|
+
options[prop] = graphicObject[prop];
|
|
666
|
+
}
|
|
667
|
+
return options;
|
|
668
|
+
}, {});
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
const resolveTextureOptions = (graphicObject) => {
|
|
672
|
+
const textures = graphicObject?.textures ?? {};
|
|
673
|
+
const texture =
|
|
674
|
+
textures[realAnimationName()] ??
|
|
675
|
+
textures[Animation.Stand] ??
|
|
676
|
+
Object.values(textures)[0] ??
|
|
677
|
+
{};
|
|
678
|
+
|
|
679
|
+
return {
|
|
680
|
+
...parentTextureOptions(graphicObject),
|
|
681
|
+
...texture
|
|
682
|
+
};
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const resolveFirstAnimationFrame = (textureOptions) => {
|
|
686
|
+
const animations = textureOptions?.animations;
|
|
687
|
+
if (!animations) return {};
|
|
688
|
+
|
|
689
|
+
try {
|
|
690
|
+
const frames = typeof animations === 'function'
|
|
691
|
+
? animations({ direction: direction() })
|
|
692
|
+
: animations;
|
|
693
|
+
if (!Array.isArray(frames)) return {};
|
|
694
|
+
const firstGroup = frames[0];
|
|
695
|
+
return Array.isArray(firstGroup) ? firstGroup[0] ?? {} : firstGroup ?? {};
|
|
696
|
+
}
|
|
697
|
+
catch {
|
|
698
|
+
return {};
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
const optionValue = (prop, frame, textureOptions, graphicObject) => {
|
|
703
|
+
return frame?.[prop] ?? textureOptions?.[prop] ?? graphicObject?.[prop];
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
const resolveFrameSize = (textureOptions, dimensions) => {
|
|
707
|
+
const framesWidth = toPositiveNumber(textureOptions?.framesWidth) ?? 1;
|
|
708
|
+
const framesHeight = toPositiveNumber(textureOptions?.framesHeight) ?? 1;
|
|
709
|
+
const imageSource = resolveImageSource(textureOptions?.image);
|
|
710
|
+
const loadedSize = imageSource ? dimensions[imageSource] : undefined;
|
|
711
|
+
const fullWidth = toPositiveNumber(textureOptions?.width) ?? loadedSize?.width;
|
|
712
|
+
const fullHeight = toPositiveNumber(textureOptions?.height) ?? loadedSize?.height;
|
|
713
|
+
const width = toPositiveNumber(textureOptions?.rectWidth) ??
|
|
714
|
+
toPositiveNumber(textureOptions?.spriteWidth) ??
|
|
715
|
+
(fullWidth ? fullWidth / framesWidth : undefined);
|
|
716
|
+
const height = toPositiveNumber(textureOptions?.rectHeight) ??
|
|
717
|
+
toPositiveNumber(textureOptions?.spriteHeight) ??
|
|
718
|
+
(fullHeight ? fullHeight / framesHeight : undefined);
|
|
719
|
+
|
|
720
|
+
return {
|
|
721
|
+
width,
|
|
722
|
+
height
|
|
723
|
+
};
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
const resolveHitboxAnchor = (spriteWidth, spriteHeight, realSize, box) => {
|
|
727
|
+
if (!spriteWidth || !spriteHeight || !box) {
|
|
728
|
+
return [0, 0];
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
const heightOfSprite = typeof realSize === 'number' ? realSize : realSize?.height;
|
|
732
|
+
const resolvedHeight = toPositiveNumber(heightOfSprite) ?? spriteHeight;
|
|
733
|
+
const gap = Math.max(0, (spriteHeight - resolvedHeight) / 2);
|
|
734
|
+
const hitboxTopLeftX = clampRatio((spriteWidth - box.w) / 2 / spriteWidth);
|
|
735
|
+
const hitboxTopLeftY = clampRatio((spriteHeight - box.h - gap) / spriteHeight);
|
|
736
|
+
const hitboxCenterX = clampRatio(hitboxTopLeftX + box.w / 2 / spriteWidth);
|
|
737
|
+
const hitboxCenterY = clampRatio(hitboxTopLeftY + box.h / 2 / spriteHeight);
|
|
738
|
+
const footY = clampRatio((spriteHeight - gap) / spriteHeight);
|
|
739
|
+
|
|
740
|
+
switch (box.anchorMode ?? 'top-left') {
|
|
741
|
+
case 'center':
|
|
742
|
+
return [hitboxCenterX, hitboxCenterY];
|
|
743
|
+
case 'foot':
|
|
744
|
+
return [hitboxCenterX, footY];
|
|
745
|
+
case 'top-left':
|
|
746
|
+
default:
|
|
747
|
+
return [hitboxTopLeftX, hitboxTopLeftY];
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
const loadImageDimensions = (image) => {
|
|
752
|
+
const source = resolveImageSource(image);
|
|
753
|
+
if (!source || imageDimensions()[source] || loadingImageDimensions.has(source)) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
loadingImageDimensions.add(source);
|
|
758
|
+
Assets.load(source)
|
|
759
|
+
.then((texture) => {
|
|
760
|
+
const width = toPositiveNumber(texture?.width);
|
|
761
|
+
const height = toPositiveNumber(texture?.height);
|
|
762
|
+
if (!width || !height) return;
|
|
763
|
+
|
|
764
|
+
imageDimensions.update((dimensions) => ({
|
|
765
|
+
...dimensions,
|
|
766
|
+
[source]: { width, height }
|
|
767
|
+
}));
|
|
768
|
+
})
|
|
769
|
+
.catch(() => {})
|
|
770
|
+
.finally(() => {
|
|
771
|
+
loadingImageDimensions.delete(source);
|
|
772
|
+
});
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
effect(() => {
|
|
776
|
+
const sources = new Set();
|
|
777
|
+
|
|
778
|
+
graphicsSignals().forEach((graphicObject) => {
|
|
779
|
+
const baseImage = resolveImageSource(graphicObject?.image);
|
|
780
|
+
if (baseImage) sources.add(baseImage);
|
|
781
|
+
|
|
782
|
+
Object.values(graphicObject?.textures ?? {}).forEach((textureOptions) => {
|
|
783
|
+
const image = resolveImageSource(textureOptions?.image ?? graphicObject?.image);
|
|
784
|
+
if (image) sources.add(image);
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
sources.forEach((source) => loadImageDimensions(source));
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
const hitboxBounds = computed(() => {
|
|
792
|
+
const box = hitbox();
|
|
793
|
+
const width = box?.w ?? 0;
|
|
794
|
+
const height = box?.h ?? 0;
|
|
795
|
+
|
|
796
|
+
return {
|
|
797
|
+
left: 0,
|
|
798
|
+
top: 0,
|
|
799
|
+
right: width,
|
|
800
|
+
bottom: height,
|
|
801
|
+
width,
|
|
802
|
+
height,
|
|
803
|
+
centerX: width / 2,
|
|
804
|
+
centerY: height / 2
|
|
805
|
+
};
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
const graphicBounds = computed(() => {
|
|
809
|
+
const box = hitbox();
|
|
810
|
+
const fallback = hitboxBounds();
|
|
811
|
+
const customEventComponent = resolvedEventComponents()[0];
|
|
812
|
+
if (customEventComponent && !customEventComponent.renderGraphic) {
|
|
813
|
+
return fallback;
|
|
814
|
+
}
|
|
815
|
+
const dimensions = imageDimensions();
|
|
816
|
+
const graphics = graphicsSignals();
|
|
817
|
+
let bounds = null;
|
|
818
|
+
|
|
819
|
+
graphics.forEach((graphicObject) => {
|
|
820
|
+
const textureOptions = resolveTextureOptions(graphicObject);
|
|
821
|
+
const frame = resolveFirstAnimationFrame(textureOptions);
|
|
822
|
+
const size = resolveFrameSize(textureOptions, dimensions);
|
|
823
|
+
const spriteWidth = size.width ?? box?.w;
|
|
824
|
+
const spriteHeight = size.height ?? box?.h;
|
|
825
|
+
|
|
826
|
+
if (!spriteWidth || !spriteHeight) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
const explicitAnchor = normalizeAnchor(optionValue('anchor', frame, textureOptions, graphicObject));
|
|
831
|
+
const anchor = explicitAnchor ?? resolveHitboxAnchor(
|
|
832
|
+
spriteWidth,
|
|
833
|
+
spriteHeight,
|
|
834
|
+
optionValue('spriteRealSize', frame, textureOptions, graphicObject),
|
|
835
|
+
box
|
|
836
|
+
);
|
|
837
|
+
const scale = normalizePair(optionValue('scale', frame, textureOptions, graphicObject) ?? graphicScale(graphicObject));
|
|
838
|
+
const x = toFiniteNumber(optionValue('x', frame, textureOptions, graphicObject), 0);
|
|
839
|
+
const y = toFiniteNumber(optionValue('y', frame, textureOptions, graphicObject), 0);
|
|
840
|
+
const leftEdge = -anchor[0] * spriteWidth * scale[0];
|
|
841
|
+
const rightEdge = (1 - anchor[0]) * spriteWidth * scale[0];
|
|
842
|
+
const topEdge = -anchor[1] * spriteHeight * scale[1];
|
|
843
|
+
const bottomEdge = (1 - anchor[1]) * spriteHeight * scale[1];
|
|
844
|
+
const graphic = {
|
|
845
|
+
left: x + Math.min(leftEdge, rightEdge),
|
|
846
|
+
top: y + Math.min(topEdge, bottomEdge),
|
|
847
|
+
right: x + Math.max(leftEdge, rightEdge),
|
|
848
|
+
bottom: y + Math.max(topEdge, bottomEdge)
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
bounds = bounds
|
|
852
|
+
? {
|
|
853
|
+
left: Math.min(bounds.left, graphic.left),
|
|
854
|
+
top: Math.min(bounds.top, graphic.top),
|
|
855
|
+
right: Math.max(bounds.right, graphic.right),
|
|
856
|
+
bottom: Math.max(bounds.bottom, graphic.bottom)
|
|
857
|
+
}
|
|
858
|
+
: graphic;
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
if (!bounds) {
|
|
862
|
+
return fallback;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const width = bounds.right - bounds.left;
|
|
866
|
+
const height = bounds.bottom - bounds.top;
|
|
867
|
+
|
|
868
|
+
return {
|
|
869
|
+
...bounds,
|
|
870
|
+
width,
|
|
871
|
+
height,
|
|
872
|
+
centerX: bounds.left + width / 2,
|
|
873
|
+
centerY: bounds.top + height / 2
|
|
874
|
+
};
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
const interactionBounds = () => ({
|
|
878
|
+
bounds: graphicBounds(),
|
|
879
|
+
hitbox: hitboxBounds(),
|
|
880
|
+
graphic: graphicBounds()
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
const interactionCursor = computed(() =>
|
|
884
|
+
client.interactions.cursorFor(sprite, interactionBounds())
|
|
885
|
+
);
|
|
886
|
+
|
|
887
|
+
const handleInteraction = (type) => (event) => {
|
|
888
|
+
client.updatePointerFromInteractionEvent(event);
|
|
889
|
+
client.interactions.handle(sprite, type, {
|
|
890
|
+
event,
|
|
891
|
+
bounds: interactionBounds()
|
|
892
|
+
});
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
const interactionPointerOver = handleInteraction('pointerover');
|
|
896
|
+
const interactionPointerOut = handleInteraction('pointerout');
|
|
897
|
+
const interactionPointerDown = handleInteraction('pointerdown');
|
|
898
|
+
const interactionPointerUp = handleInteraction('pointerup');
|
|
899
|
+
const interactionPointerMove = handleInteraction('pointermove');
|
|
900
|
+
const interactionClick = handleInteraction('click');
|
|
901
|
+
|
|
380
902
|
// Combine animation change detection with movement state from smoothX/smoothY
|
|
381
903
|
const movementAnimations = ['walk', 'stand'];
|
|
382
904
|
const epsilon = 0; // movement threshold to consider the easing still running
|
|
@@ -400,25 +922,91 @@
|
|
|
400
922
|
filter(([prev, curr]) => prev !== curr)
|
|
401
923
|
);
|
|
402
924
|
|
|
925
|
+
let beforeRemovePromise = null;
|
|
926
|
+
let beforeRemoveTransitionValue = null;
|
|
927
|
+
const resolveRemoveContext = () => {
|
|
928
|
+
if (!sprite._removeTransition) return null;
|
|
929
|
+
const value = sprite._removeTransition();
|
|
930
|
+
if (!value || typeof value !== 'string') return null;
|
|
931
|
+
try {
|
|
932
|
+
const context = JSON.parse(value);
|
|
933
|
+
if (!context || typeof context !== 'object' || !context.active) return null;
|
|
934
|
+
context.__transitionValue = value;
|
|
935
|
+
return context;
|
|
936
|
+
}
|
|
937
|
+
catch {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
const withTimeout = (promise, timeoutMs = 0) => {
|
|
943
|
+
if (!timeoutMs || timeoutMs <= 0) return promise;
|
|
944
|
+
return Promise.race([
|
|
945
|
+
promise,
|
|
946
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs)),
|
|
947
|
+
]);
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
const runBeforeRemove = () => {
|
|
951
|
+
const context = resolveRemoveContext();
|
|
952
|
+
if (!context) return Promise.resolve();
|
|
953
|
+
if (beforeRemovePromise && beforeRemoveTransitionValue === context.__transitionValue) {
|
|
954
|
+
return beforeRemovePromise;
|
|
955
|
+
}
|
|
956
|
+
beforeRemoveTransitionValue = context.__transitionValue;
|
|
957
|
+
beforeRemovePromise = withTimeout(
|
|
958
|
+
lastValueFrom(hooks.callHooks("client-sprite-onBeforeRemove", sprite, context)),
|
|
959
|
+
context.timeoutMs
|
|
960
|
+
);
|
|
961
|
+
return beforeRemovePromise;
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
const removeTransitionSubscription = sprite._removeTransition?.observable?.subscribe(() => {
|
|
965
|
+
if (resolveRemoveContext()) {
|
|
966
|
+
runBeforeRemove();
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
|
|
403
970
|
const animationMovementSubscription = combineLatest([animationChange$, moving$]).subscribe(([[prev, curr], isMoving]) => {
|
|
404
|
-
|
|
971
|
+
const isMovementAnimation = movementAnimations.includes(curr);
|
|
972
|
+
const isTemporaryAnimationPlaying =
|
|
973
|
+
sprite.animationIsPlaying && sprite.animationIsPlaying();
|
|
974
|
+
|
|
975
|
+
if (sprite.animationFixed && isMovementAnimation) {
|
|
405
976
|
realAnimationName.set(curr);
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (curr == 'stand' && !isMoving) {
|
|
981
|
+
if (!resumeHeldDirectionWalkAnimation()) {
|
|
982
|
+
realAnimationName.set(curr);
|
|
983
|
+
}
|
|
406
984
|
}
|
|
407
985
|
else if (curr == 'walk' && isMoving) {
|
|
408
986
|
realAnimationName.set(curr);
|
|
409
987
|
}
|
|
410
|
-
else if (!
|
|
988
|
+
else if (!isMovementAnimation) {
|
|
411
989
|
realAnimationName.set(curr);
|
|
412
990
|
}
|
|
413
|
-
if (!isMoving &&
|
|
414
|
-
if (
|
|
415
|
-
if (typeof
|
|
416
|
-
|
|
991
|
+
if (!isMoving && isTemporaryAnimationPlaying) {
|
|
992
|
+
if (isMovementAnimation) {
|
|
993
|
+
if (typeof sprite.resetAnimationState === 'function') {
|
|
994
|
+
sprite.resetAnimationState();
|
|
417
995
|
}
|
|
418
996
|
}
|
|
419
997
|
}
|
|
420
998
|
});
|
|
421
999
|
|
|
1000
|
+
const resumeWalkSubscriptions = [
|
|
1001
|
+
sprite._canMove,
|
|
1002
|
+
sprite._animationFixed,
|
|
1003
|
+
sprite.animationIsPlaying,
|
|
1004
|
+
]
|
|
1005
|
+
.filter(signal => signal?.observable)
|
|
1006
|
+
.map(signal => signal.observable.subscribe(() => {
|
|
1007
|
+
resumeHeldDirectionWalkAnimation();
|
|
1008
|
+
}));
|
|
1009
|
+
|
|
422
1010
|
/**
|
|
423
1011
|
* Cleanup subscriptions and call hooks before sprite destruction.
|
|
424
1012
|
*
|
|
@@ -429,18 +1017,58 @@
|
|
|
429
1017
|
* @example
|
|
430
1018
|
* await onBeforeDestroy();
|
|
431
1019
|
*/
|
|
1020
|
+
const waitForTemporaryAnimationEnd = (maxDuration = 1200) => {
|
|
1021
|
+
if (!sprite.animationIsPlaying || !sprite.animationIsPlaying()) {
|
|
1022
|
+
return Promise.resolve();
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
return new Promise((resolve) => {
|
|
1026
|
+
let finished = false;
|
|
1027
|
+
let timeout;
|
|
1028
|
+
let subscription;
|
|
1029
|
+
const finish = () => {
|
|
1030
|
+
if (finished) return;
|
|
1031
|
+
finished = true;
|
|
1032
|
+
clearTimeout(timeout);
|
|
1033
|
+
subscription?.unsubscribe();
|
|
1034
|
+
resolve();
|
|
1035
|
+
};
|
|
1036
|
+
timeout = setTimeout(finish, maxDuration);
|
|
1037
|
+
subscription = sprite.animationIsPlaying.observable.subscribe((isPlaying) => {
|
|
1038
|
+
if (!isPlaying) finish();
|
|
1039
|
+
});
|
|
1040
|
+
if (finished) subscription.unsubscribe();
|
|
1041
|
+
});
|
|
1042
|
+
};
|
|
1043
|
+
|
|
432
1044
|
const onBeforeDestroy = async () => {
|
|
1045
|
+
await runBeforeRemove();
|
|
1046
|
+
await waitForTemporaryAnimationEnd();
|
|
1047
|
+
if (typeof document !== 'undefined') {
|
|
1048
|
+
document.removeEventListener('keydown', handleNativeActionWhileMoving);
|
|
1049
|
+
document.removeEventListener('keyup', handleNativeActionWhileMoving);
|
|
1050
|
+
}
|
|
1051
|
+
removeTransitionSubscription?.unsubscribe();
|
|
433
1052
|
animationMovementSubscription.unsubscribe();
|
|
1053
|
+
resumeWalkSubscriptions.forEach(subscription => subscription.unsubscribe());
|
|
434
1054
|
xSubscription.unsubscribe();
|
|
435
1055
|
ySubscription.unsubscribe();
|
|
436
|
-
await lastValueFrom(hooks.callHooks("client-sprite-onDestroy",
|
|
437
|
-
await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap,
|
|
1056
|
+
await lastValueFrom(hooks.callHooks("client-sprite-onDestroy", sprite))
|
|
1057
|
+
await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap, sprite))
|
|
438
1058
|
}
|
|
439
1059
|
|
|
440
1060
|
mount((element) => {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
1061
|
+
if (typeof document !== 'undefined') {
|
|
1062
|
+
document.addEventListener('keydown', handleNativeActionWhileMoving);
|
|
1063
|
+
document.addEventListener('keyup', handleNativeActionWhileMoving);
|
|
1064
|
+
}
|
|
1065
|
+
hooks.callHooks("client-sprite-onAdd", sprite).subscribe()
|
|
1066
|
+
hooks.callHooks("client-sceneMap-onAddSprite", client.sceneMap, sprite).subscribe()
|
|
1067
|
+
effect(() => {
|
|
1068
|
+
if (isCurrentPlayer()) {
|
|
1069
|
+
client.setKeyboardControls(element.directives.controls)
|
|
1070
|
+
}
|
|
1071
|
+
})
|
|
444
1072
|
})
|
|
445
1073
|
|
|
446
1074
|
/**
|
|
@@ -449,8 +1077,16 @@
|
|
|
449
1077
|
* @param gui - The GUI instance
|
|
450
1078
|
* @param data - Data passed from the GUI component
|
|
451
1079
|
*/
|
|
452
|
-
const
|
|
453
|
-
|
|
1080
|
+
const normalizeOpenId = (value) => {
|
|
1081
|
+
const resolved = typeof value === "function" ? value() : value;
|
|
1082
|
+
return typeof resolved === "string" && resolved.length > 0 ? resolved : undefined;
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
const onAttachedGuiFinish = (gui, data, guiOpenId) => {
|
|
1086
|
+
const completedOpenId = normalizeOpenId(guiOpenId);
|
|
1087
|
+
const currentOpenId = normalizeOpenId(gui.openId);
|
|
1088
|
+
if (completedOpenId && currentOpenId && completedOpenId !== currentOpenId) return;
|
|
1089
|
+
guiService.guiClose(gui.name, data, completedOpenId ?? currentOpenId);
|
|
454
1090
|
};
|
|
455
1091
|
|
|
456
1092
|
/**
|
|
@@ -467,4 +1103,4 @@
|
|
|
467
1103
|
tick(() => {
|
|
468
1104
|
hooks.callHooks("client-sprite-onUpdate").subscribe()
|
|
469
1105
|
})
|
|
470
|
-
</script>
|
|
1106
|
+
</script>
|