@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
package/src/Game/Map.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RpgCommonMap,
|
|
3
|
+
cloneLightingState,
|
|
4
|
+
normalizeLightingState,
|
|
5
|
+
type LightSpot,
|
|
6
|
+
type LightingState,
|
|
3
7
|
type WeatherState,
|
|
4
8
|
type MapPhysicsInitContext,
|
|
5
9
|
type MapPhysicsEntityContext,
|
|
@@ -11,6 +15,43 @@ import { RpgClientEvent } from "./Event";
|
|
|
11
15
|
import { RpgClientEngine } from "../RpgClientEngine";
|
|
12
16
|
import { inject } from "../core/inject";
|
|
13
17
|
|
|
18
|
+
type TestGlobalScope = typeof globalThis & {
|
|
19
|
+
process?: {
|
|
20
|
+
env?: {
|
|
21
|
+
TEST?: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
__RPGJS_TEST__?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const lightingColorsEqual = (
|
|
28
|
+
left: LightSpot["color"],
|
|
29
|
+
right: LightSpot["color"],
|
|
30
|
+
): boolean => {
|
|
31
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
32
|
+
return Array.isArray(left)
|
|
33
|
+
&& Array.isArray(right)
|
|
34
|
+
&& left.length === right.length
|
|
35
|
+
&& left.every((value, index) => value === right[index]);
|
|
36
|
+
}
|
|
37
|
+
return left === right;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const lightSpotsEqual = (left: LightSpot | undefined, right: LightSpot): boolean => {
|
|
41
|
+
if (!left) return false;
|
|
42
|
+
return left.id === right.id
|
|
43
|
+
&& left.x === right.x
|
|
44
|
+
&& left.y === right.y
|
|
45
|
+
&& left.radius === right.radius
|
|
46
|
+
&& left.intensity === right.intensity
|
|
47
|
+
&& lightingColorsEqual(left.color, right.color)
|
|
48
|
+
&& left.flicker === right.flicker
|
|
49
|
+
&& left.flickerSpeed === right.flickerSpeed
|
|
50
|
+
&& left.pulse === right.pulse
|
|
51
|
+
&& left.pulseSpeed === right.pulseSpeed
|
|
52
|
+
&& left.phase === right.phase;
|
|
53
|
+
};
|
|
54
|
+
|
|
14
55
|
export class RpgClientMap extends RpgCommonMap<any> {
|
|
15
56
|
engine: RpgClientEngine = inject(RpgClientEngine)
|
|
16
57
|
@users(RpgClientPlayer) players = signal<Record<string, RpgClientPlayer>>({});
|
|
@@ -18,19 +59,43 @@ export class RpgClientMap extends RpgCommonMap<any> {
|
|
|
18
59
|
currentPlayer = computed(() => this.players()[this.engine.playerIdSignal()!])
|
|
19
60
|
weatherState = signal<WeatherState | null>(null);
|
|
20
61
|
localWeatherOverride = signal<WeatherState | null>(null);
|
|
62
|
+
lightingState = signal<LightingState | null>(null);
|
|
63
|
+
localLightSpots = signal<Record<string, LightSpot>>({});
|
|
21
64
|
weather = computed<WeatherState | null>(() => {
|
|
22
65
|
const local = this.localWeatherOverride()
|
|
23
66
|
const state = this.weatherState()
|
|
24
67
|
return local ?? state
|
|
25
68
|
});
|
|
69
|
+
lighting = computed<LightingState | null>(() => {
|
|
70
|
+
const state = cloneLightingState(this.lightingState());
|
|
71
|
+
const localSpots = Object.entries(this.localLightSpots()).map(([id, spot]) => ({
|
|
72
|
+
...spot,
|
|
73
|
+
id: spot.id ?? id,
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
if (!state && localSpots.length === 0) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const next: LightingState = { ...(state ?? {}) };
|
|
81
|
+
if (!state?.ambient) {
|
|
82
|
+
delete next.ambient;
|
|
83
|
+
}
|
|
84
|
+
next.spots = [
|
|
85
|
+
...(state?.spots ?? []),
|
|
86
|
+
...localSpots,
|
|
87
|
+
];
|
|
88
|
+
return next;
|
|
89
|
+
});
|
|
26
90
|
private manualClientPhysicsTick = false;
|
|
27
91
|
private readonly isTestEnvironment: boolean;
|
|
28
92
|
|
|
29
93
|
constructor() {
|
|
30
94
|
super();
|
|
31
95
|
// Détecter l'environnement de test
|
|
32
|
-
const
|
|
33
|
-
|
|
96
|
+
const testGlobal = globalThis as TestGlobalScope;
|
|
97
|
+
const isTest = testGlobal.process?.env?.TEST === 'true'
|
|
98
|
+
|| testGlobal.__RPGJS_TEST__ === true;
|
|
34
99
|
this.isTestEnvironment = isTest;
|
|
35
100
|
if (isTest) {
|
|
36
101
|
this.autoTickEnabled = false;
|
|
@@ -51,6 +116,16 @@ export class RpgClientMap extends RpgCommonMap<any> {
|
|
|
51
116
|
const currentPlayer = !force && currentPlayerId
|
|
52
117
|
? this.players()[currentPlayerId]
|
|
53
118
|
: undefined;
|
|
119
|
+
const players = this.players();
|
|
120
|
+
const events = this.events();
|
|
121
|
+
|
|
122
|
+
Object.entries(players).forEach(([id, player]) => {
|
|
123
|
+
if (!player || (!force && id === currentPlayerId)) return;
|
|
124
|
+
(player as any).resetAnimationState?.();
|
|
125
|
+
});
|
|
126
|
+
Object.values(events).forEach((event) => {
|
|
127
|
+
(event as any)?.resetAnimationState?.();
|
|
128
|
+
});
|
|
54
129
|
|
|
55
130
|
this.players.set(
|
|
56
131
|
currentPlayerId && currentPlayer ? { [currentPlayerId]: currentPlayer } : {}
|
|
@@ -58,6 +133,8 @@ export class RpgClientMap extends RpgCommonMap<any> {
|
|
|
58
133
|
this.events.set({})
|
|
59
134
|
this.weatherState.set(null);
|
|
60
135
|
this.localWeatherOverride.set(null);
|
|
136
|
+
this.lightingState.set(null);
|
|
137
|
+
this.localLightSpots.set({});
|
|
61
138
|
this.clearPhysic()
|
|
62
139
|
}
|
|
63
140
|
|
|
@@ -73,6 +150,61 @@ export class RpgClientMap extends RpgCommonMap<any> {
|
|
|
73
150
|
this.localWeatherOverride.set(null);
|
|
74
151
|
}
|
|
75
152
|
|
|
153
|
+
getLighting(): LightingState | null {
|
|
154
|
+
return this.lighting();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
addLightSpot(id: string, spot: LightSpot): void {
|
|
158
|
+
const normalized = normalizeLightingState({ spots: [{ ...spot, id }] });
|
|
159
|
+
const nextSpot = normalized?.spots?.[0];
|
|
160
|
+
if (!nextSpot) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
this.localLightSpots.update((spots) => {
|
|
164
|
+
if (lightSpotsEqual(spots[id], nextSpot)) {
|
|
165
|
+
return spots;
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
...spots,
|
|
169
|
+
[id]: nextSpot,
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
patchLightSpot(id: string, patch: Partial<LightSpot>): void {
|
|
175
|
+
this.localLightSpots.update((spots) => {
|
|
176
|
+
const current = spots[id];
|
|
177
|
+
if (!current) {
|
|
178
|
+
return spots;
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
...spots,
|
|
182
|
+
[id]: {
|
|
183
|
+
...current,
|
|
184
|
+
...patch,
|
|
185
|
+
id,
|
|
186
|
+
x: patch.x ?? current.x,
|
|
187
|
+
y: patch.y ?? current.y,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
removeLightSpot(id: string): void {
|
|
194
|
+
this.localLightSpots.update((spots) => {
|
|
195
|
+
if (!(id in spots)) {
|
|
196
|
+
return spots;
|
|
197
|
+
}
|
|
198
|
+
const next = { ...spots };
|
|
199
|
+
delete next[id];
|
|
200
|
+
return next;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
clearLightSpots(): void {
|
|
205
|
+
this.localLightSpots.set({});
|
|
206
|
+
}
|
|
207
|
+
|
|
76
208
|
stepClientPhysics(deltaMs: number): number {
|
|
77
209
|
if (!this.manualClientPhysicsTick) {
|
|
78
210
|
return 0;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { signal } from "canvasengine";
|
|
3
|
+
import { appendFramePayload, RpgClientObject, withGraphicDisplayScale } from "./Object";
|
|
4
|
+
|
|
5
|
+
vi.mock("../RpgClientEngine", () => ({
|
|
6
|
+
RpgClientEngine: class RpgClientEngine {},
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
vi.mock("../core/inject", () => ({
|
|
10
|
+
inject: () => ({}),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
function createObject() {
|
|
14
|
+
const object = Object.create(RpgClientObject.prototype) as RpgClientObject;
|
|
15
|
+
object.animationName = signal("stand");
|
|
16
|
+
object.graphics = signal(["hero"]) as any;
|
|
17
|
+
object.animationCurrentIndex = signal(0);
|
|
18
|
+
object.animationIsPlaying = signal(false);
|
|
19
|
+
return object;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("RpgClientObject animations", () => {
|
|
23
|
+
test("accepts a single frame payload without requiring iterable spread", () => {
|
|
24
|
+
expect(
|
|
25
|
+
appendFramePayload({ stale: true }, { x: 10, y: 20, ts: 1 }),
|
|
26
|
+
).toEqual([{ x: 10, y: 20, ts: 1 }]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("keeps instance scale outside the spritesheet transform scale", () => {
|
|
30
|
+
expect(withGraphicDisplayScale({ id: "hero" }, 0.5)).toEqual({
|
|
31
|
+
id: "hero",
|
|
32
|
+
displayScale: 0.5,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("marks temporary animation as finished before restoring locomotion animation", async () => {
|
|
37
|
+
const object = createObject();
|
|
38
|
+
const animationChanges: Array<{ name: string; isPlaying: boolean }> = [];
|
|
39
|
+
|
|
40
|
+
object.animationName.observable.subscribe((name) => {
|
|
41
|
+
animationChanges.push({
|
|
42
|
+
name,
|
|
43
|
+
isPlaying: object.animationIsPlaying(),
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const done = object.setAnimation("attack", 1, { timeoutMs: 10000 });
|
|
48
|
+
object.animationCurrentIndex.set(1);
|
|
49
|
+
|
|
50
|
+
await done;
|
|
51
|
+
|
|
52
|
+
expect(object.animationName()).toBe("stand");
|
|
53
|
+
expect(object.animationIsPlaying()).toBe(false);
|
|
54
|
+
expect(animationChanges).toContainEqual({
|
|
55
|
+
name: "stand",
|
|
56
|
+
isPlaying: false,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
package/src/Game/Object.ts
CHANGED
|
@@ -1,15 +1,51 @@
|
|
|
1
1
|
import { Hooks, ModulesToken, RpgCommonPlayer } from "@rpgjs/common";
|
|
2
|
-
import { trigger, signal,
|
|
3
|
-
import {
|
|
2
|
+
import { trigger, signal, type Trigger } from "canvasengine";
|
|
3
|
+
import { combineLatest, from, map, of, startWith, Subscription, switchMap } from "rxjs";
|
|
4
4
|
import { inject } from "../core/inject";
|
|
5
5
|
import { RpgClientEngine } from "../RpgClientEngine";
|
|
6
|
-
|
|
6
|
+
type Frame = { x: number; y: number; ts: number };
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
type AnimationRestoreOptions = {
|
|
9
|
+
restoreAnimationName?: string;
|
|
10
|
+
restoreGraphics?: any[];
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
};
|
|
11
13
|
|
|
12
|
-
type
|
|
14
|
+
type FlashType = 'alpha' | 'tint' | 'both';
|
|
15
|
+
|
|
16
|
+
type FlashOptions = {
|
|
17
|
+
type?: FlashType;
|
|
18
|
+
duration?: number;
|
|
19
|
+
cycles?: number;
|
|
20
|
+
alpha?: number;
|
|
21
|
+
tint?: number | string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type FlashTriggerOptions = Omit<FlashOptions, "tint"> & {
|
|
25
|
+
tint: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type ConfigurableTrigger<T> = Omit<Trigger<T>, "start"> & {
|
|
29
|
+
start(config?: T): Promise<void>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const withGraphicDisplayScale = (spritesheet: any, scale: unknown): any => {
|
|
33
|
+
if (!spritesheet || typeof spritesheet !== "object") return spritesheet;
|
|
34
|
+
if (scale === undefined || scale === null) return spritesheet;
|
|
35
|
+
return {
|
|
36
|
+
...spritesheet,
|
|
37
|
+
displayScale: scale,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const appendFramePayload = (current: unknown, items: unknown): Frame[] => {
|
|
42
|
+
const frameItems = Array.isArray(items) ? items : items ? [items] : [];
|
|
43
|
+
const nextFrames = frameItems.flatMap((item): Frame[] =>
|
|
44
|
+
Array.isArray(item) ? item : [item as Frame]
|
|
45
|
+
);
|
|
46
|
+
const currentFrames = Array.isArray(current) ? current as Frame[] : [];
|
|
47
|
+
return currentFrames.concat(nextFrames);
|
|
48
|
+
};
|
|
13
49
|
|
|
14
50
|
export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
15
51
|
abstract _type: string;
|
|
@@ -20,51 +56,45 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
20
56
|
_param = signal({});
|
|
21
57
|
frames: Frame[] = [];
|
|
22
58
|
graphicsSignals = signal<any[]>([]);
|
|
23
|
-
|
|
24
|
-
|
|
59
|
+
flashTrigger: ConfigurableTrigger<FlashTriggerOptions> = trigger<FlashTriggerOptions>();
|
|
60
|
+
private animationRestoreState?: {
|
|
61
|
+
animationName: string;
|
|
62
|
+
graphics: any[];
|
|
63
|
+
};
|
|
25
64
|
|
|
26
65
|
constructor() {
|
|
27
66
|
super();
|
|
67
|
+
const engine = this.engine;
|
|
28
68
|
this.hooks.callHooks("client-sprite-onInit", this).subscribe();
|
|
29
69
|
|
|
30
70
|
this._frames.observable.subscribe(({ items }) => {
|
|
31
71
|
if (!this.id) return;
|
|
32
72
|
//if (this.id == this.engine.playerIdSignal()!) return;
|
|
33
|
-
|
|
34
|
-
Array.isArray(item) ? item : [item]
|
|
35
|
-
);
|
|
36
|
-
this.frames = [...this.frames, ...nextFrames];
|
|
73
|
+
this.frames = appendFramePayload(this.frames, items);
|
|
37
74
|
});
|
|
38
75
|
|
|
39
|
-
this.graphics.observable
|
|
76
|
+
const graphics$ = this.graphics.observable.pipe(map(({ items }) => items));
|
|
77
|
+
const graphicScale$ = this._graphicScale.observable.pipe(
|
|
78
|
+
startWith({ value: this._graphicScale() }),
|
|
79
|
+
map((payload: any) => payload?.value ?? payload),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
combineLatest([graphics$, graphicScale$])
|
|
40
83
|
.pipe(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
84
|
+
switchMap(([graphics, scale]) => {
|
|
85
|
+
const graphicRefs = Array.isArray(graphics) ? graphics : [];
|
|
86
|
+
if (graphicRefs.length === 0) return of([]);
|
|
87
|
+
return from(Promise.all(graphicRefs.map(async (graphic) => {
|
|
88
|
+
const spritesheet = await engine.getSpriteSheet(graphic);
|
|
89
|
+
return withGraphicDisplayScale(spritesheet, scale);
|
|
90
|
+
})));
|
|
91
|
+
})
|
|
44
92
|
)
|
|
45
93
|
.subscribe((sheets) => {
|
|
46
94
|
this.graphicsSignals.set(sheets);
|
|
47
95
|
});
|
|
48
96
|
|
|
49
|
-
|
|
50
|
-
.pipe(
|
|
51
|
-
filter(value => value !== null && value !== undefined),
|
|
52
|
-
map((value) => typeof value === 'string' ? JSON.parse(value) : value),
|
|
53
|
-
)
|
|
54
|
-
.subscribe(({components}) => {
|
|
55
|
-
for (const component of components) {
|
|
56
|
-
for (const [key, value] of Object.entries(component)) {
|
|
57
|
-
this._component = value as any; // temporary component memory
|
|
58
|
-
console.log(value)
|
|
59
|
-
const type = (value as any).type as keyof typeof DYNAMIC_COMPONENTS;
|
|
60
|
-
if (DYNAMIC_COMPONENTS[type]) {
|
|
61
|
-
this.engine.addSpriteComponentInFront(DYNAMIC_COMPONENTS[type]);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
this.engine.tick
|
|
97
|
+
engine.tick
|
|
68
98
|
.pipe
|
|
69
99
|
//throttleTime(10)
|
|
70
100
|
()
|
|
@@ -72,7 +102,7 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
72
102
|
const frame = this.frames.shift();
|
|
73
103
|
if (frame) {
|
|
74
104
|
if (typeof frame.x !== "number" || typeof frame.y !== "number") return;
|
|
75
|
-
|
|
105
|
+
engine.scene.setBodyPosition(
|
|
76
106
|
this.id,
|
|
77
107
|
frame.x,
|
|
78
108
|
frame.y,
|
|
@@ -101,6 +131,38 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
101
131
|
}
|
|
102
132
|
|
|
103
133
|
private animationSubscription?: Subscription;
|
|
134
|
+
private animationResetTimeout?: ReturnType<typeof setTimeout>;
|
|
135
|
+
private animationWaitResolve?: () => void;
|
|
136
|
+
|
|
137
|
+
private clearAnimationControls() {
|
|
138
|
+
if (this.animationSubscription) {
|
|
139
|
+
this.animationSubscription.unsubscribe();
|
|
140
|
+
this.animationSubscription = undefined;
|
|
141
|
+
}
|
|
142
|
+
if (this.animationResetTimeout) {
|
|
143
|
+
clearTimeout(this.animationResetTimeout);
|
|
144
|
+
this.animationResetTimeout = undefined;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private resolveAnimationWait() {
|
|
149
|
+
const resolve = this.animationWaitResolve;
|
|
150
|
+
this.animationWaitResolve = undefined;
|
|
151
|
+
resolve?.();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private finishTemporaryAnimation() {
|
|
155
|
+
const restoreState = this.animationRestoreState;
|
|
156
|
+
this.clearAnimationControls();
|
|
157
|
+
this.animationCurrentIndex.set(0);
|
|
158
|
+
this.animationRestoreState = undefined;
|
|
159
|
+
this.animationIsPlaying.set(false);
|
|
160
|
+
if (restoreState) {
|
|
161
|
+
this.animationName.set(restoreState.animationName);
|
|
162
|
+
this.graphics.set([...restoreState.graphics]);
|
|
163
|
+
}
|
|
164
|
+
this.resolveAnimationWait();
|
|
165
|
+
}
|
|
104
166
|
|
|
105
167
|
/**
|
|
106
168
|
* Trigger a flash animation on this sprite
|
|
@@ -148,13 +210,7 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
148
210
|
* });
|
|
149
211
|
* ```
|
|
150
212
|
*/
|
|
151
|
-
flash(options?: {
|
|
152
|
-
type?: 'alpha' | 'tint' | 'both';
|
|
153
|
-
duration?: number;
|
|
154
|
-
cycles?: number;
|
|
155
|
-
alpha?: number;
|
|
156
|
-
tint?: number | string;
|
|
157
|
-
}): void {
|
|
213
|
+
flash(options?: FlashOptions): void {
|
|
158
214
|
const flashOptions = {
|
|
159
215
|
type: options?.type || 'alpha',
|
|
160
216
|
duration: options?.duration ?? 300,
|
|
@@ -199,12 +255,14 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
199
255
|
* ```
|
|
200
256
|
*/
|
|
201
257
|
resetAnimationState() {
|
|
258
|
+
if (this.animationRestoreState) {
|
|
259
|
+
this.finishTemporaryAnimation();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
202
262
|
this.animationIsPlaying.set(false);
|
|
203
263
|
this.animationCurrentIndex.set(0);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.animationSubscription = undefined;
|
|
207
|
-
}
|
|
264
|
+
this.clearAnimationControls();
|
|
265
|
+
this.resolveAnimationWait();
|
|
208
266
|
}
|
|
209
267
|
|
|
210
268
|
/**
|
|
@@ -216,17 +274,19 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
216
274
|
*
|
|
217
275
|
* @param animationName - Name of the animation to play
|
|
218
276
|
* @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
|
|
277
|
+
* @param options - Restore and timeout options
|
|
278
|
+
* @returns A promise resolved when a finite animation finishes, is interrupted, or times out
|
|
219
279
|
*
|
|
220
280
|
* @example
|
|
221
281
|
* ```ts
|
|
222
282
|
* // Play attack animation 3 times
|
|
223
|
-
* player.setAnimation('attack', 3);
|
|
283
|
+
* await player.setAnimation('attack', 3);
|
|
224
284
|
*
|
|
225
285
|
* // Play continuous spell animation
|
|
226
286
|
* player.setAnimation('spell');
|
|
227
287
|
* ```
|
|
228
288
|
*/
|
|
229
|
-
setAnimation(animationName: string, nbTimes?: number): void
|
|
289
|
+
setAnimation(animationName: string, nbTimes?: number, options?: AnimationRestoreOptions): Promise<void>;
|
|
230
290
|
/**
|
|
231
291
|
* Set a custom animation with temporary graphic change
|
|
232
292
|
*
|
|
@@ -237,37 +297,68 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
237
297
|
* @param animationName - Name of the animation to play
|
|
238
298
|
* @param graphic - The graphic(s) to temporarily use during the animation
|
|
239
299
|
* @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
|
|
300
|
+
* @param options - Restore and timeout options
|
|
301
|
+
* @returns A promise resolved when a finite animation finishes, is interrupted, or times out
|
|
240
302
|
*
|
|
241
303
|
* @example
|
|
242
304
|
* ```ts
|
|
243
305
|
* // Play attack animation with temporary graphic change
|
|
244
|
-
* player.setAnimation('attack', 'hero_attack', 3);
|
|
306
|
+
* await player.setAnimation('attack', 'hero_attack', 3);
|
|
245
307
|
* ```
|
|
246
308
|
*/
|
|
247
|
-
setAnimation(animationName: string, graphic?: string | string[], nbTimes?: number): void
|
|
248
|
-
setAnimation(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
309
|
+
setAnimation(animationName: string, graphic?: string | string[], nbTimes?: number, options?: AnimationRestoreOptions): Promise<void>;
|
|
310
|
+
setAnimation(
|
|
311
|
+
animationName: string,
|
|
312
|
+
graphicOrNbTimes?: string | string[] | number,
|
|
313
|
+
nbTimesOrOptions?: number | AnimationRestoreOptions,
|
|
314
|
+
options?: AnimationRestoreOptions
|
|
315
|
+
): Promise<void> {
|
|
255
316
|
let graphic: string | string[] | undefined;
|
|
256
317
|
let finalNbTimes: number = Infinity;
|
|
318
|
+
let restoreOptions: AnimationRestoreOptions | undefined = options;
|
|
257
319
|
|
|
258
320
|
// Handle overloads
|
|
259
321
|
if (typeof graphicOrNbTimes === 'number') {
|
|
260
322
|
// setAnimation(animationName, nbTimes)
|
|
261
323
|
finalNbTimes = graphicOrNbTimes;
|
|
324
|
+
restoreOptions = typeof nbTimesOrOptions === 'object' ? nbTimesOrOptions : options;
|
|
262
325
|
} else if (graphicOrNbTimes !== undefined) {
|
|
263
326
|
// setAnimation(animationName, graphic, nbTimes)
|
|
264
327
|
graphic = graphicOrNbTimes;
|
|
265
|
-
|
|
328
|
+
if (typeof nbTimesOrOptions === 'number') {
|
|
329
|
+
finalNbTimes = nbTimesOrOptions;
|
|
330
|
+
} else {
|
|
331
|
+
finalNbTimes = Infinity;
|
|
332
|
+
restoreOptions = nbTimesOrOptions ?? options;
|
|
333
|
+
}
|
|
266
334
|
} else {
|
|
267
335
|
// setAnimation(animationName) - nbTimes remains Infinity
|
|
268
336
|
finalNbTimes = Infinity;
|
|
269
337
|
}
|
|
270
338
|
|
|
339
|
+
if (this.animationIsPlaying()) {
|
|
340
|
+
this.finishTemporaryAnimation();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const waitPromise =
|
|
344
|
+
finalNbTimes === Infinity
|
|
345
|
+
? Promise.resolve()
|
|
346
|
+
: new Promise<void>((resolve) => {
|
|
347
|
+
this.animationWaitResolve = resolve;
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
this.animationIsPlaying.set(true);
|
|
351
|
+
const previousAnimationName =
|
|
352
|
+
restoreOptions?.restoreAnimationName ?? this.animationName();
|
|
353
|
+
const previousGraphics = restoreOptions?.restoreGraphics
|
|
354
|
+
? [...restoreOptions.restoreGraphics]
|
|
355
|
+
: [...this.graphics()];
|
|
356
|
+
this.animationRestoreState = {
|
|
357
|
+
animationName: previousAnimationName,
|
|
358
|
+
graphics: previousGraphics,
|
|
359
|
+
};
|
|
360
|
+
this.animationCurrentIndex.set(0);
|
|
361
|
+
|
|
271
362
|
// Temporarily change graphic if provided
|
|
272
363
|
if (graphic !== undefined) {
|
|
273
364
|
if (Array.isArray(graphic)) {
|
|
@@ -277,28 +368,26 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
277
368
|
}
|
|
278
369
|
}
|
|
279
370
|
|
|
280
|
-
|
|
281
|
-
if (this.animationSubscription) {
|
|
282
|
-
this.animationSubscription.unsubscribe();
|
|
283
|
-
}
|
|
371
|
+
this.clearAnimationControls();
|
|
284
372
|
|
|
285
373
|
this.animationSubscription =
|
|
286
374
|
this.animationCurrentIndex.observable.subscribe((index) => {
|
|
287
375
|
if (index >= finalNbTimes) {
|
|
288
|
-
this.
|
|
289
|
-
this.animationName.set(previousAnimationName);
|
|
290
|
-
// Reset graphic to previous value if it was changed
|
|
291
|
-
if (graphic !== undefined) {
|
|
292
|
-
this.graphics.set(previousGraphics);
|
|
293
|
-
}
|
|
294
|
-
this.animationIsPlaying.set(false);
|
|
295
|
-
if (this.animationSubscription) {
|
|
296
|
-
this.animationSubscription.unsubscribe();
|
|
297
|
-
this.animationSubscription = undefined;
|
|
298
|
-
}
|
|
376
|
+
this.finishTemporaryAnimation();
|
|
299
377
|
}
|
|
300
378
|
});
|
|
379
|
+
|
|
380
|
+
if (finalNbTimes !== Infinity) {
|
|
381
|
+
this.animationResetTimeout = setTimeout(() => {
|
|
382
|
+
if (this.animationIsPlaying()) {
|
|
383
|
+
this.finishTemporaryAnimation();
|
|
384
|
+
}
|
|
385
|
+
}, restoreOptions?.timeoutMs ?? Math.max(1000, finalNbTimes * 1000));
|
|
386
|
+
}
|
|
387
|
+
|
|
301
388
|
this.animationName.set(animationName);
|
|
389
|
+
|
|
390
|
+
return waitPromise;
|
|
302
391
|
}
|
|
303
392
|
|
|
304
393
|
/**
|
|
@@ -306,10 +395,25 @@ export abstract class RpgClientObject extends RpgCommonPlayer {
|
|
|
306
395
|
*
|
|
307
396
|
* @param id - Identifier of the component animation to play.
|
|
308
397
|
* @param params - Parameters forwarded to the animation effect.
|
|
398
|
+
* @returns A promise resolved when the animation component calls `onFinish`.
|
|
309
399
|
*/
|
|
310
|
-
showComponentAnimation(id: string, params: any) {
|
|
400
|
+
showComponentAnimation(id: string, params: any): Promise<void> {
|
|
311
401
|
const engine = inject(RpgClientEngine);
|
|
312
|
-
engine.getComponentAnimation(id).displayEffect(params, this);
|
|
402
|
+
return engine.getComponentAnimation(id).displayEffect(params, this);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Display a registered spritesheet animation effect on this object.
|
|
407
|
+
*
|
|
408
|
+
* @param graphic - Identifier of the spritesheet to use.
|
|
409
|
+
* @param animationName - Name of the animation inside the spritesheet.
|
|
410
|
+
* @returns A promise resolved when the animation component calls `onFinish`.
|
|
411
|
+
*/
|
|
412
|
+
showAnimation(graphic: string, animationName: string = 'default'): Promise<void> {
|
|
413
|
+
return this.showComponentAnimation('animation', {
|
|
414
|
+
graphic,
|
|
415
|
+
animationName,
|
|
416
|
+
});
|
|
313
417
|
}
|
|
314
418
|
|
|
315
419
|
/**
|