@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.
Files changed (325) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/dist/Game/AnimationManager.d.ts +2 -1
  3. package/dist/Game/AnimationManager.js +21 -9
  4. package/dist/Game/AnimationManager.js.map +1 -1
  5. package/dist/Game/AnimationManager.spec.d.ts +1 -0
  6. package/dist/Game/ClientVisuals.d.ts +61 -0
  7. package/dist/Game/ClientVisuals.js +96 -0
  8. package/dist/Game/ClientVisuals.js.map +1 -0
  9. package/dist/Game/ClientVisuals.spec.d.ts +1 -0
  10. package/dist/Game/Event.js.map +1 -1
  11. package/dist/Game/EventComponentResolver.d.ts +16 -0
  12. package/dist/Game/EventComponentResolver.js +52 -0
  13. package/dist/Game/EventComponentResolver.js.map +1 -0
  14. package/dist/Game/EventComponentResolver.spec.d.ts +1 -0
  15. package/dist/Game/Map.d.ts +9 -1
  16. package/dist/Game/Map.js +83 -5
  17. package/dist/Game/Map.js.map +1 -1
  18. package/dist/Game/Object.d.ts +49 -15
  19. package/dist/Game/Object.js +101 -42
  20. package/dist/Game/Object.js.map +1 -1
  21. package/dist/Game/Object.spec.d.ts +1 -0
  22. package/dist/Game/Player.js.map +1 -1
  23. package/dist/Game/ProjectileManager.d.ts +98 -0
  24. package/dist/Game/ProjectileManager.js +196 -0
  25. package/dist/Game/ProjectileManager.js.map +1 -0
  26. package/dist/Game/ProjectileManager.spec.d.ts +1 -0
  27. package/dist/Gui/Gui.d.ts +20 -6
  28. package/dist/Gui/Gui.js +132 -57
  29. package/dist/Gui/Gui.js.map +1 -1
  30. package/dist/Gui/Gui.spec.d.ts +1 -0
  31. package/dist/Gui/NotificationManager.js.map +1 -1
  32. package/dist/Resource.js +1 -1
  33. package/dist/Resource.js.map +1 -1
  34. package/dist/RpgClient.d.ts +194 -15
  35. package/dist/RpgClientEngine.d.ts +191 -19
  36. package/dist/RpgClientEngine.js +693 -74
  37. package/dist/RpgClientEngine.js.map +1 -1
  38. package/dist/Sound.js.map +1 -1
  39. package/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.133.0/helpers/esm}/decorate.js +1 -1
  40. package/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.133.0/helpers/esm}/decorateMetadata.js +1 -1
  41. package/dist/_virtual/_rolldown/runtime.js +13 -0
  42. package/dist/components/animations/animation.ce.js +6 -5
  43. package/dist/components/animations/animation.ce.js.map +1 -1
  44. package/dist/components/animations/fx.ce.js +60 -0
  45. package/dist/components/animations/fx.ce.js.map +1 -0
  46. package/dist/components/animations/hit.ce.js +24 -28
  47. package/dist/components/animations/hit.ce.js.map +1 -1
  48. package/dist/components/animations/index.d.ts +1 -0
  49. package/dist/components/animations/index.js +6 -4
  50. package/dist/components/animations/index.js.map +1 -1
  51. package/dist/components/character.ce.js +748 -249
  52. package/dist/components/character.ce.js.map +1 -1
  53. package/dist/components/dynamics/bar.ce.js +99 -0
  54. package/dist/components/dynamics/bar.ce.js.map +1 -0
  55. package/dist/components/dynamics/image.ce.js +26 -0
  56. package/dist/components/dynamics/image.ce.js.map +1 -0
  57. package/dist/components/dynamics/parse-value.d.ts +3 -0
  58. package/dist/components/dynamics/parse-value.js +54 -35
  59. package/dist/components/dynamics/parse-value.js.map +1 -1
  60. package/dist/components/dynamics/parse-value.spec.d.ts +1 -0
  61. package/dist/components/dynamics/shape-utils.d.ts +16 -0
  62. package/dist/components/dynamics/shape-utils.js +73 -0
  63. package/dist/components/dynamics/shape-utils.js.map +1 -0
  64. package/dist/components/dynamics/shape-utils.spec.d.ts +1 -0
  65. package/dist/components/dynamics/shape.ce.js +86 -0
  66. package/dist/components/dynamics/shape.ce.js.map +1 -0
  67. package/dist/components/dynamics/text.ce.js +36 -56
  68. package/dist/components/dynamics/text.ce.js.map +1 -1
  69. package/dist/components/gui/box.ce.js +9 -9
  70. package/dist/components/gui/box.ce.js.map +1 -1
  71. package/dist/components/gui/dialogbox/index.ce.js +75 -65
  72. package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
  73. package/dist/components/gui/gameover.ce.js +47 -68
  74. package/dist/components/gui/gameover.ce.js.map +1 -1
  75. package/dist/components/gui/hud/hud.ce.js +23 -31
  76. package/dist/components/gui/hud/hud.ce.js.map +1 -1
  77. package/dist/components/gui/menu/equip-menu.ce.js +121 -172
  78. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
  79. package/dist/components/gui/menu/exit-menu.ce.js +15 -10
  80. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
  81. package/dist/components/gui/menu/items-menu.ce.js +62 -77
  82. package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
  83. package/dist/components/gui/menu/main-menu.ce.js +89 -104
  84. package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
  85. package/dist/components/gui/menu/options-menu.ce.js +12 -8
  86. package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
  87. package/dist/components/gui/menu/skills-menu.ce.js +17 -19
  88. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
  89. package/dist/components/gui/mobile/index.d.ts +51 -2
  90. package/dist/components/gui/mobile/index.js +14 -6
  91. package/dist/components/gui/mobile/index.js.map +1 -1
  92. package/dist/components/gui/mobile/index.spec.d.ts +1 -0
  93. package/dist/components/gui/mobile/mobile.ce.js +309 -59
  94. package/dist/components/gui/mobile/mobile.ce.js.map +1 -1
  95. package/dist/components/gui/notification/notification.ce.js +28 -26
  96. package/dist/components/gui/notification/notification.ce.js.map +1 -1
  97. package/dist/components/gui/save-load.ce.js +81 -256
  98. package/dist/components/gui/save-load.ce.js.map +1 -1
  99. package/dist/components/gui/shop/shop.ce.js +107 -142
  100. package/dist/components/gui/shop/shop.ce.js.map +1 -1
  101. package/dist/components/gui/title-screen.ce.js +50 -73
  102. package/dist/components/gui/title-screen.ce.js.map +1 -1
  103. package/dist/components/index.d.ts +2 -1
  104. package/dist/components/index.js +1 -0
  105. package/dist/components/interaction-components.ce.js +22 -0
  106. package/dist/components/interaction-components.ce.js.map +1 -0
  107. package/dist/components/player-components-utils.d.ts +67 -0
  108. package/dist/components/player-components-utils.js +162 -0
  109. package/dist/components/player-components-utils.js.map +1 -0
  110. package/dist/components/player-components-utils.spec.d.ts +1 -0
  111. package/dist/components/player-components.ce.js +191 -0
  112. package/dist/components/player-components.ce.js.map +1 -0
  113. package/dist/components/prebuilt/hp-bar.ce.js +45 -45
  114. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -1
  115. package/dist/components/prebuilt/light-halo.ce.js +39 -60
  116. package/dist/components/prebuilt/light-halo.ce.js.map +1 -1
  117. package/dist/components/scenes/canvas.ce.js +205 -27
  118. package/dist/components/scenes/canvas.ce.js.map +1 -1
  119. package/dist/components/scenes/draw-map.ce.js +39 -39
  120. package/dist/components/scenes/draw-map.ce.js.map +1 -1
  121. package/dist/components/scenes/event-layer.ce.js +51 -10
  122. package/dist/components/scenes/event-layer.ce.js.map +1 -1
  123. package/dist/core/inject.js +1 -1
  124. package/dist/core/inject.js.map +1 -1
  125. package/dist/core/setup.js +1 -1
  126. package/dist/core/setup.js.map +1 -1
  127. package/dist/decorators/spritesheet.d.ts +1 -0
  128. package/dist/decorators/spritesheet.js +11 -0
  129. package/dist/decorators/spritesheet.js.map +1 -0
  130. package/dist/i18n.d.ts +55 -0
  131. package/dist/i18n.js +60 -0
  132. package/dist/i18n.js.map +1 -0
  133. package/dist/i18n.spec.d.ts +1 -0
  134. package/dist/index.d.ts +8 -0
  135. package/dist/index.js +29 -21
  136. package/dist/module.js +45 -4
  137. package/dist/module.js.map +1 -1
  138. package/dist/node_modules/.pnpm/{@signe_di@2.9.0 → @signe_di@3.1.0}/node_modules/@signe/di/dist/index.js +7 -117
  139. package/dist/node_modules/.pnpm/@signe_di@3.1.0/node_modules/@signe/di/dist/index.js.map +1 -0
  140. package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js +239 -0
  141. package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js.map +1 -0
  142. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/chunk-EUXUH3YW.js +13 -0
  143. 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
  144. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js +698 -0
  145. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js.map +1 -0
  146. package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/client/index.js +43 -0
  147. 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
  148. 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
  149. package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/index.js.map +1 -0
  150. 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
  151. package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/index.js.map +1 -0
  152. 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
  153. package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/ws.js.map +1 -0
  154. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js +13 -0
  155. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js.map +1 -0
  156. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +106 -0
  157. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js.map +1 -0
  158. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +13 -0
  159. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js.map +1 -0
  160. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js +121 -0
  161. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js.map +1 -0
  162. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js +10 -0
  163. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
  164. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +110 -0
  165. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
  166. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +99 -0
  167. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js.map +1 -0
  168. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +82 -0
  169. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js.map +1 -0
  170. 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
  171. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js.map +1 -0
  172. package/dist/presets/animation.js.map +1 -1
  173. package/dist/presets/faceset.js.map +1 -1
  174. package/dist/presets/icon.js.map +1 -1
  175. package/dist/presets/index.js.map +1 -1
  176. package/dist/presets/lpc.js.map +1 -1
  177. package/dist/presets/rmspritesheet.js.map +1 -1
  178. package/dist/services/AbstractSocket.d.ts +2 -0
  179. package/dist/services/AbstractSocket.js.map +1 -1
  180. package/dist/services/actionInput.d.ts +14 -0
  181. package/dist/services/actionInput.js +59 -0
  182. package/dist/services/actionInput.js.map +1 -0
  183. package/dist/services/actionInput.spec.d.ts +1 -0
  184. package/dist/services/cameraFollow.d.ts +51 -0
  185. package/dist/services/cameraFollow.js +134 -0
  186. package/dist/services/cameraFollow.js.map +1 -0
  187. package/dist/services/cameraFollow.spec.d.ts +1 -0
  188. package/dist/services/interactions.d.ts +159 -0
  189. package/dist/services/interactions.js +460 -0
  190. package/dist/services/interactions.js.map +1 -0
  191. package/dist/services/interactions.spec.d.ts +1 -0
  192. package/dist/services/keyboardControls.d.ts +1 -0
  193. package/dist/services/keyboardControls.js +1 -0
  194. package/dist/services/keyboardControls.js.map +1 -1
  195. package/dist/services/loadMap.d.ts +9 -0
  196. package/dist/services/loadMap.js +1 -1
  197. package/dist/services/loadMap.js.map +1 -1
  198. package/dist/services/mmorpg-connection.d.ts +5 -0
  199. package/dist/services/mmorpg-connection.js +50 -0
  200. package/dist/services/mmorpg-connection.js.map +1 -0
  201. package/dist/services/mmorpg-connection.spec.d.ts +1 -0
  202. package/dist/services/mmorpg.d.ts +11 -4
  203. package/dist/services/mmorpg.js +57 -33
  204. package/dist/services/mmorpg.js.map +1 -1
  205. package/dist/services/pointerContext.d.ts +11 -0
  206. package/dist/services/pointerContext.js +48 -0
  207. package/dist/services/pointerContext.js.map +1 -0
  208. package/dist/services/pointerContext.spec.d.ts +1 -0
  209. package/dist/services/save.js.map +1 -1
  210. package/dist/services/save.spec.d.ts +1 -0
  211. package/dist/services/standalone-message.d.ts +1 -0
  212. package/dist/services/standalone-message.js +9 -0
  213. package/dist/services/standalone-message.js.map +1 -0
  214. package/dist/services/standalone.d.ts +4 -1
  215. package/dist/services/standalone.js +36 -16
  216. package/dist/services/standalone.js.map +1 -1
  217. package/dist/services/standalone.spec.d.ts +1 -0
  218. package/dist/utils/getEntityProp.js +4 -3
  219. package/dist/utils/getEntityProp.js.map +1 -1
  220. package/dist/utils/getEntityProp.spec.d.ts +1 -0
  221. package/dist/utils/mapId.d.ts +1 -0
  222. package/dist/utils/mapId.js +6 -0
  223. package/dist/utils/mapId.js.map +1 -0
  224. package/dist/utils/readPropValue.d.ts +2 -0
  225. package/dist/utils/readPropValue.js +13 -0
  226. package/dist/utils/readPropValue.js.map +1 -0
  227. package/package.json +13 -13
  228. package/src/Game/AnimationManager.spec.ts +30 -0
  229. package/src/Game/AnimationManager.ts +26 -10
  230. package/src/Game/ClientVisuals.spec.ts +56 -0
  231. package/src/Game/ClientVisuals.ts +184 -0
  232. package/src/Game/EventComponentResolver.spec.ts +84 -0
  233. package/src/Game/EventComponentResolver.ts +74 -0
  234. package/src/Game/Map.ts +134 -2
  235. package/src/Game/Object.spec.ts +59 -0
  236. package/src/Game/Object.ts +181 -77
  237. package/src/Game/ProjectileManager.spec.ts +449 -0
  238. package/src/Game/ProjectileManager.ts +346 -0
  239. package/src/Gui/Gui.spec.ts +359 -0
  240. package/src/Gui/Gui.ts +178 -67
  241. package/src/Resource.ts +1 -2
  242. package/src/RpgClient.ts +220 -17
  243. package/src/RpgClientEngine.ts +995 -133
  244. package/src/components/animations/fx.ce +101 -0
  245. package/src/components/animations/index.ts +4 -2
  246. package/src/components/character.ce +839 -45
  247. package/src/components/dynamics/bar.ce +88 -0
  248. package/src/components/dynamics/image.ce +21 -0
  249. package/src/components/dynamics/parse-value.spec.ts +83 -0
  250. package/src/components/dynamics/parse-value.ts +111 -37
  251. package/src/components/dynamics/shape-utils.spec.ts +46 -0
  252. package/src/components/dynamics/shape-utils.ts +61 -0
  253. package/src/components/dynamics/shape.ce +90 -0
  254. package/src/components/dynamics/text.ce +35 -149
  255. package/src/components/gui/dialogbox/index.ce +52 -21
  256. package/src/components/gui/gameover.ce +6 -4
  257. package/src/components/gui/menu/equip-menu.ce +11 -9
  258. package/src/components/gui/menu/exit-menu.ce +6 -4
  259. package/src/components/gui/menu/items-menu.ce +11 -9
  260. package/src/components/gui/menu/main-menu.ce +14 -12
  261. package/src/components/gui/menu/options-menu.ce +4 -3
  262. package/src/components/gui/menu/skills-menu.ce +2 -1
  263. package/src/components/gui/mobile/index.spec.ts +94 -0
  264. package/src/components/gui/mobile/index.ts +74 -6
  265. package/src/components/gui/mobile/mobile.ce +347 -65
  266. package/src/components/gui/notification/notification.ce +7 -1
  267. package/src/components/gui/save-load.ce +13 -11
  268. package/src/components/gui/shop/shop.ce +20 -18
  269. package/src/components/gui/title-screen.ce +6 -4
  270. package/src/components/index.ts +2 -1
  271. package/src/components/interaction-components.ce +23 -0
  272. package/src/components/player-components-utils.spec.ts +109 -0
  273. package/src/components/player-components-utils.ts +205 -0
  274. package/src/components/player-components.ce +222 -0
  275. package/src/components/prebuilt/hp-bar.ce +4 -3
  276. package/src/components/prebuilt/light-halo.ce +2 -2
  277. package/src/components/scenes/canvas.ce +219 -15
  278. package/src/components/scenes/draw-map.ce +34 -22
  279. package/src/components/scenes/event-layer.ce +55 -4
  280. package/src/core/setup.ts +2 -2
  281. package/src/decorators/spritesheet.ts +8 -0
  282. package/src/i18n.spec.ts +39 -0
  283. package/src/i18n.ts +59 -0
  284. package/src/index.ts +19 -0
  285. package/src/module.ts +61 -11
  286. package/src/services/AbstractSocket.ts +3 -0
  287. package/src/services/actionInput.spec.ts +155 -0
  288. package/src/services/actionInput.ts +120 -0
  289. package/src/services/cameraFollow.spec.ts +220 -0
  290. package/src/services/cameraFollow.ts +222 -0
  291. package/src/services/interactions.spec.ts +175 -0
  292. package/src/services/interactions.ts +722 -0
  293. package/src/services/keyboardControls.ts +2 -1
  294. package/src/services/loadMap.ts +5 -1
  295. package/src/services/mmorpg-connection.spec.ts +99 -0
  296. package/src/services/mmorpg-connection.ts +69 -0
  297. package/src/services/mmorpg.ts +70 -36
  298. package/src/services/pointerContext.spec.ts +36 -0
  299. package/src/services/pointerContext.ts +84 -0
  300. package/src/services/save.spec.ts +127 -0
  301. package/src/services/standalone-message.ts +7 -0
  302. package/src/services/standalone.spec.ts +54 -0
  303. package/src/services/standalone.ts +44 -12
  304. package/src/utils/getEntityProp.spec.ts +96 -0
  305. package/src/utils/getEntityProp.ts +4 -3
  306. package/src/utils/mapId.ts +2 -0
  307. package/src/utils/readPropValue.ts +16 -0
  308. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js.map +0 -1
  309. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js +0 -457
  310. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js.map +0 -1
  311. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js +0 -463
  312. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js.map +0 -1
  313. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js +0 -2191
  314. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js.map +0 -1
  315. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js +0 -10
  316. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +0 -1
  317. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js +0 -91
  318. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js.map +0 -1
  319. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js.map +0 -1
  320. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js +0 -14
  321. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +0 -1
  322. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +0 -1
  323. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +0 -1
  324. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +0 -2
  325. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getEntityProp.js","names":[],"sources":["../../src/utils/getEntityProp.ts"],"sourcesContent":["import { computed, Signal } from \"canvasengine\";\nimport { RpgClientObject } from \"../Game/Object\";\n\nconst BUILTIN_PARAM_KEYS = [\n \"maxHp\",\n \"maxSp\",\n \"atk\",\n \"pdef\",\n \"sdef\",\n \"str\",\n \"agi\",\n \"int\",\n \"dex\",\n] as const;\n\ntype BuiltInParamKey = typeof BUILTIN_PARAM_KEYS[number];\ntype ParamPropKey = `params.${BuiltInParamKey}` | `params.${string}`;\n\nconst entityPropMap = {\n level: (entity: RpgClientObject) => entity._level(),\n exp: (entity: RpgClientObject) => entity._exp(),\n gold: (entity: RpgClientObject) => entity._gold(),\n hp: (entity: RpgClientObject) => entity.hpSignal(),\n sp: (entity: RpgClientObject) => entity.spSignal(),\n name: (entity: RpgClientObject) => entity.name(),\n type: (entity: RpgClientObject) => entity.type(),\n x: (entity: RpgClientObject) => entity.x(),\n y: (entity: RpgClientObject) => entity.y(),\n z: (entity: RpgClientObject) => entity.z(),\n tint: (entity: RpgClientObject) => entity.tint(),\n direction: (entity: RpgClientObject) => entity.direction(),\n speed: (entity: RpgClientObject) => entity.speed(),\n hitbox: (entity: RpgClientObject) => entity.hitbox(),\n animation: (entity: RpgClientObject) => entity.animationName(),\n canMove: (entity: RpgClientObject) => entity.canMove(),\n graphics: (entity: RpgClientObject) => entity.graphics(),\n items: (entity: RpgClientObject) => entity.items(),\n equipments: (entity: RpgClientObject) => entity.equipments(),\n states: (entity: RpgClientObject) => entity.states(),\n skills: (entity: RpgClientObject) => entity.skills(),\n effects: (entity: RpgClientObject) => entity._effects(),\n componentsTop: (entity: RpgClientObject) => entity.componentsTop(),\n componentsBottom: (entity: RpgClientObject) => entity.componentsBottom(),\n componentsCenter: (entity: RpgClientObject) => entity.componentsCenter(),\n componentsLeft: (entity: RpgClientObject) => entity.componentsLeft(),\n componentsRight: (entity: RpgClientObject) => entity.componentsRight(),\n} as const;\n\ntype EntityPropMap = typeof entityPropMap;\ntype EntityPropKey = keyof EntityPropMap | ParamPropKey;\ntype EntityPropValue<K extends EntityPropKey> = K extends keyof EntityPropMap\n ? ReturnType<EntityPropMap[K]>\n : K extends `params.${string}`\n ? number | undefined\n : never;\n\nconst isSignal = <T>(value: unknown): value is Signal<T> =>\n typeof value === \"function\";\n\nconst toSignal = <T>(value: Signal<T> | T): Signal<T> =>\n isSignal<T>(value) ? value : computed(() => value);\n\nexport const getEntityProp = <K extends EntityPropKey>(\n entity: Signal<RpgClientObject | undefined> | RpgClientObject | undefined,\n key: K\n): Signal<EntityPropValue<K>> => {\n const entitySignal = toSignal(entity);\n\n return computed(() => {\n const current = entitySignal();\n if (!current) {\n return undefined as EntityPropValue<K>;\n }\n\n if (Object.prototype.hasOwnProperty.call(entityPropMap, key)) {\n const getter = entityPropMap[key as keyof EntityPropMap];\n return getter(current) as EntityPropValue<K>;\n }\n\n if (key.startsWith(\"params.\")) {\n const paramKey = key.slice(\"params.\".length);\n return current._param?.()?.[paramKey] as EntityPropValue<K>;\n }\n\n return undefined as EntityPropValue<K>;\n });\n};\n"],"mappings":";;AAkBA,IAAM,gBAAgB;CACpB,QAAQ,WAA4B,OAAO,QAAQ;CACnD,MAAM,WAA4B,OAAO,MAAM;CAC/C,OAAO,WAA4B,OAAO,OAAO;CACjD,KAAK,WAA4B,OAAO,UAAU;CAClD,KAAK,WAA4B,OAAO,UAAU;CAClD,OAAO,WAA4B,OAAO,MAAM;CAChD,OAAO,WAA4B,OAAO,MAAM;CAChD,IAAI,WAA4B,OAAO,GAAG;CAC1C,IAAI,WAA4B,OAAO,GAAG;CAC1C,IAAI,WAA4B,OAAO,GAAG;CAC1C,OAAO,WAA4B,OAAO,MAAM;CAChD,YAAY,WAA4B,OAAO,WAAW;CAC1D,QAAQ,WAA4B,OAAO,OAAO;CAClD,SAAS,WAA4B,OAAO,QAAQ;CACpD,YAAY,WAA4B,OAAO,eAAe;CAC9D,UAAU,WAA4B,OAAO,SAAS;CACtD,WAAW,WAA4B,OAAO,UAAU;CACxD,QAAQ,WAA4B,OAAO,OAAO;CAClD,aAAa,WAA4B,OAAO,YAAY;CAC5D,SAAS,WAA4B,OAAO,QAAQ;CACpD,SAAS,WAA4B,OAAO,QAAQ;CACpD,UAAU,WAA4B,OAAO,UAAU;CACvD,gBAAgB,WAA4B,OAAO,eAAe;CAClE,mBAAmB,WAA4B,OAAO,kBAAkB;CACxE,mBAAmB,WAA4B,OAAO,kBAAkB;CACxE,iBAAiB,WAA4B,OAAO,gBAAgB;CACpE,kBAAkB,WAA4B,OAAO,iBAAiB;CACvE;AAUD,IAAM,YAAe,UACnB,OAAO,UAAU;AAEnB,IAAM,YAAe,UACnB,SAAY,MAAM,GAAG,QAAQ,eAAe,MAAM;AAEpD,IAAa,iBACX,QACA,QAC+B;CAC/B,MAAM,eAAe,SAAS,OAAO;AAErC,QAAO,eAAe;EACpB,MAAM,UAAU,cAAc;AAC9B,MAAI,CAAC,QACH;AAGF,MAAI,OAAO,UAAU,eAAe,KAAK,eAAe,IAAI,EAAE;GAC5D,MAAM,SAAS,cAAc;AAC7B,UAAO,OAAO,QAAQ;;AAGxB,MAAI,IAAI,WAAW,UAAU,EAAE;GAC7B,MAAM,WAAW,IAAI,MAAM,EAAiB;AAC5C,UAAO,QAAQ,UAAU,GAAG;;GAI9B"}
1
+ {"version":3,"file":"getEntityProp.js","names":[],"sources":["../../src/utils/getEntityProp.ts"],"sourcesContent":["import { computed, Signal } from \"canvasengine\";\nimport { RpgClientObject } from \"../Game/Object\";\nimport { readPropValue } from \"./readPropValue\";\n\nconst BUILTIN_PARAM_KEYS = [\n \"maxHp\",\n \"maxSp\",\n \"atk\",\n \"pdef\",\n \"sdef\",\n \"str\",\n \"agi\",\n \"int\",\n \"dex\",\n] as const;\n\ntype BuiltInParamKey = typeof BUILTIN_PARAM_KEYS[number];\ntype ParamPropKey = `params.${BuiltInParamKey}` | `params.${string}`;\n\nconst entityPropMap = {\n level: (entity: RpgClientObject) => entity._level(),\n exp: (entity: RpgClientObject) => entity._exp(),\n gold: (entity: RpgClientObject) => entity._gold(),\n hp: (entity: RpgClientObject) => entity.hpSignal(),\n sp: (entity: RpgClientObject) => entity.spSignal(),\n name: (entity: RpgClientObject) => entity.name,\n type: (entity: RpgClientObject) => entity.type(),\n x: (entity: RpgClientObject) => entity.x(),\n y: (entity: RpgClientObject) => entity.y(),\n z: (entity: RpgClientObject) => entity.z(),\n tint: (entity: RpgClientObject) => entity.tint(),\n direction: (entity: RpgClientObject) => entity.direction(),\n speed: (entity: RpgClientObject) => entity.speed,\n hitbox: (entity: RpgClientObject) => entity.hitbox(),\n animation: (entity: RpgClientObject) => entity.animationName(),\n canMove: (entity: RpgClientObject) => readPropValue<boolean>((entity as any)._canMove ?? entity.canMove),\n graphics: (entity: RpgClientObject) => entity.graphics(),\n items: (entity: RpgClientObject) => entity.items(),\n equipments: (entity: RpgClientObject) => entity.equipments(),\n states: (entity: RpgClientObject) => entity.states(),\n skills: (entity: RpgClientObject) => entity.skills(),\n effects: (entity: RpgClientObject) => entity._effects(),\n componentsTop: (entity: RpgClientObject) => entity.componentsTop(),\n componentsBottom: (entity: RpgClientObject) => entity.componentsBottom(),\n componentsCenter: (entity: RpgClientObject) => entity.componentsCenter(),\n componentsLeft: (entity: RpgClientObject) => entity.componentsLeft(),\n componentsRight: (entity: RpgClientObject) => entity.componentsRight(),\n} as const;\n\ntype EntityPropMap = typeof entityPropMap;\ntype EntityPropKey = keyof EntityPropMap | ParamPropKey;\ntype EntityPropValue<K extends EntityPropKey> = K extends keyof EntityPropMap\n ? ReturnType<EntityPropMap[K]>\n : K extends `params.${string}`\n ? number | undefined\n : never;\n\nconst isSignal = <T>(value: unknown): value is Signal<T> =>\n typeof value === \"function\";\n\nconst toSignal = <T>(value: Signal<T> | T): Signal<T> =>\n isSignal<T>(value) ? value : computed(() => value);\n\nexport const getEntityProp = <K extends EntityPropKey>(\n entity: Signal<RpgClientObject | undefined> | RpgClientObject | undefined,\n key: K\n): Signal<EntityPropValue<K>> => {\n const entitySignal = toSignal(entity);\n\n return computed(() => {\n const current = entitySignal();\n if (!current) {\n return undefined as EntityPropValue<K>;\n }\n\n if (Object.prototype.hasOwnProperty.call(entityPropMap, key)) {\n const getter = entityPropMap[key as keyof EntityPropMap];\n return getter(current) as EntityPropValue<K>;\n }\n\n if (key.startsWith(\"params.\")) {\n const paramKey = key.slice(\"params.\".length);\n return current._param?.()?.[paramKey] as EntityPropValue<K>;\n }\n\n return undefined as EntityPropValue<K>;\n });\n};\n"],"mappings":";;;AAmBA,IAAM,gBAAgB;CACpB,QAAQ,WAA4B,OAAO,OAAO;CAClD,MAAM,WAA4B,OAAO,KAAK;CAC9C,OAAO,WAA4B,OAAO,MAAM;CAChD,KAAK,WAA4B,OAAO,SAAS;CACjD,KAAK,WAA4B,OAAO,SAAS;CACjD,OAAO,WAA4B,OAAO;CAC1C,OAAO,WAA4B,OAAO,KAAK;CAC/C,IAAI,WAA4B,OAAO,EAAE;CACzC,IAAI,WAA4B,OAAO,EAAE;CACzC,IAAI,WAA4B,OAAO,EAAE;CACzC,OAAO,WAA4B,OAAO,KAAK;CAC/C,YAAY,WAA4B,OAAO,UAAU;CACzD,QAAQ,WAA4B,OAAO;CAC3C,SAAS,WAA4B,OAAO,OAAO;CACnD,YAAY,WAA4B,OAAO,cAAc;CAC7D,UAAU,WAA4B,cAAwB,OAAe,YAAY,OAAO,OAAO;CACvG,WAAW,WAA4B,OAAO,SAAS;CACvD,QAAQ,WAA4B,OAAO,MAAM;CACjD,aAAa,WAA4B,OAAO,WAAW;CAC3D,SAAS,WAA4B,OAAO,OAAO;CACnD,SAAS,WAA4B,OAAO,OAAO;CACnD,UAAU,WAA4B,OAAO,SAAS;CACtD,gBAAgB,WAA4B,OAAO,cAAc;CACjE,mBAAmB,WAA4B,OAAO,iBAAiB;CACvE,mBAAmB,WAA4B,OAAO,iBAAiB;CACvE,iBAAiB,WAA4B,OAAO,eAAe;CACnE,kBAAkB,WAA4B,OAAO,gBAAgB;AACvE;AAUA,IAAM,YAAe,UACnB,OAAO,UAAU;AAEnB,IAAM,YAAe,UACnB,SAAY,KAAK,IAAI,QAAQ,eAAe,KAAK;AAEnD,IAAa,iBACX,QACA,QAC+B;CAC/B,MAAM,eAAe,SAAS,MAAM;CAEpC,OAAO,eAAe;EACpB,MAAM,UAAU,aAAa;EAC7B,IAAI,CAAC,SACH;EAGF,IAAI,OAAO,UAAU,eAAe,KAAK,eAAe,GAAG,GAAG;GAC5D,MAAM,SAAS,cAAc;GAC7B,OAAO,OAAO,OAAO;EACvB;EAEA,IAAI,IAAI,WAAW,SAAS,GAAG;GAC7B,MAAM,WAAW,IAAI,MAAM,CAAgB;GAC3C,OAAO,QAAQ,SAAS,IAAI;EAC9B;CAGF,CAAC;AACH"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare const normalizeRoomMapId: (mapId: string | undefined) => string | undefined;
@@ -0,0 +1,6 @@
1
+ //#region src/utils/mapId.ts
2
+ var normalizeRoomMapId = (mapId) => typeof mapId === "string" ? mapId.replace(/^map-/, "") : void 0;
3
+ //#endregion
4
+ export { normalizeRoomMapId };
5
+
6
+ //# sourceMappingURL=mapId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapId.js","names":[],"sources":["../../src/utils/mapId.ts"],"sourcesContent":["export const normalizeRoomMapId = (mapId: string | undefined): string | undefined =>\n typeof mapId === \"string\" ? mapId.replace(/^map-/, \"\") : undefined;\n"],"mappings":";AAAA,IAAa,sBAAsB,UACjC,OAAO,UAAU,WAAW,MAAM,QAAQ,SAAS,EAAE,IAAI,KAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const readPropValue: <T = unknown>(value: unknown) => T;
2
+ export declare const getCanMoveValue: (entity: any) => boolean;
@@ -0,0 +1,13 @@
1
+ //#region src/utils/readPropValue.ts
2
+ var readPropValue = (value) => {
3
+ if (typeof value === "function") return readPropValue(value());
4
+ if (value && typeof value === "object" && "value" in value) return readPropValue(value.value);
5
+ return value;
6
+ };
7
+ var getCanMoveValue = (entity) => {
8
+ return readPropValue(entity?._canMove ?? entity?.canMove) !== false;
9
+ };
10
+ //#endregion
11
+ export { getCanMoveValue, readPropValue };
12
+
13
+ //# sourceMappingURL=readPropValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readPropValue.js","names":[],"sources":["../../src/utils/readPropValue.ts"],"sourcesContent":["export const readPropValue = <T = unknown>(value: unknown): T => {\n if (typeof value === \"function\") {\n return readPropValue((value as () => unknown)());\n }\n\n if (value && typeof value === \"object\" && \"value\" in value) {\n return readPropValue((value as { value: unknown }).value);\n }\n\n return value as T;\n};\n\nexport const getCanMoveValue = (entity: any): boolean => {\n const value = readPropValue(entity?._canMove ?? entity?.canMove);\n return value !== false;\n};\n"],"mappings":";AAAA,IAAa,iBAA8B,UAAsB;CAC/D,IAAI,OAAO,UAAU,YACnB,OAAO,cAAe,MAAwB,CAAC;CAGjD,IAAI,SAAS,OAAO,UAAU,YAAY,WAAW,OACnD,OAAO,cAAe,MAA6B,KAAK;CAG1D,OAAO;AACT;AAEA,IAAa,mBAAmB,WAAyB;CAEvD,OADc,cAAc,QAAQ,YAAY,QAAQ,OACjD,MAAU;AACnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpgjs/client",
3
- "version": "5.0.0-beta.2",
3
+ "version": "5.0.0-beta.22",
4
4
  "description": "RPGJS is a framework for creating RPG/MMORPG games",
5
5
  "main": "dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,25 +17,25 @@
17
17
  "author": "Samuel Ronce",
18
18
  "license": "MIT",
19
19
  "peerDependencies": {
20
- "@canvasengine/presets": "*",
21
- "canvasengine": "*",
20
+ "@canvasengine/presets": "^2.0.0",
21
+ "canvasengine": "^2.0.1",
22
22
  "pixi.js": "^8.9.2"
23
23
  },
24
24
  "dependencies": {
25
- "@rpgjs/common": "5.0.0-beta.2",
26
- "@rpgjs/server": "5.0.0-beta.2",
27
- "@rpgjs/ui-css": "5.0.0-beta.2",
28
- "@signe/di": "^2.9.0",
29
- "@signe/room": "^2.9.0",
30
- "@signe/sync": "^2.9.0",
25
+ "@rpgjs/common": "5.0.0-beta.21",
26
+ "@rpgjs/server": "5.0.0-beta.22",
27
+ "@rpgjs/ui-css": "5.0.0-beta.21",
28
+ "@signe/di": "3.1.0",
29
+ "@signe/room": "3.1.0",
30
+ "@signe/sync": "3.1.0",
31
31
  "pixi-filters": "^6.1.5",
32
32
  "rxjs": "^7.8.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@canvasengine/compiler": "2.0.0-beta.56",
36
- "vite": "^8.0.3",
37
- "vite-plugin-dts": "^4.5.4",
38
- "vitest": "^4.1.2"
35
+ "@canvasengine/compiler": "2.0.0",
36
+ "vite": "^8.0.16",
37
+ "vite-plugin-dts": "^5.0.2",
38
+ "vitest": "^4.1.9"
39
39
  },
40
40
  "type": "module",
41
41
  "scripts": {
@@ -0,0 +1,30 @@
1
+ import { describe, expect, test, vi } from "vitest";
2
+ import { AnimationManager } from "./AnimationManager";
3
+
4
+ describe("AnimationManager", () => {
5
+ test("resolves displayEffect when the component calls onFinish", async () => {
6
+ const manager = new AnimationManager();
7
+ const done = manager.displayEffect({}, { x: 10, y: 20 });
8
+
9
+ expect(manager.current()).toHaveLength(1);
10
+ manager.current()[0].onFinish();
11
+
12
+ await expect(done).resolves.toBeUndefined();
13
+ expect(manager.current()).toHaveLength(0);
14
+ });
15
+
16
+ test("keeps onFinish idempotent and forwards user callback data", async () => {
17
+ const manager = new AnimationManager();
18
+ const onFinish = vi.fn();
19
+ const done = manager.displayEffect({ onFinish }, { x: 10, y: 20 });
20
+ const finish = manager.current()[0].onFinish;
21
+
22
+ finish({ ok: true });
23
+ finish({ ok: false });
24
+
25
+ await done;
26
+ expect(onFinish).toHaveBeenCalledTimes(1);
27
+ expect(onFinish).toHaveBeenCalledWith({ ok: true });
28
+ expect(manager.current()).toHaveLength(0);
29
+ });
30
+ });
@@ -4,18 +4,34 @@ import { signal } from "canvasengine";
4
4
  export class AnimationManager {
5
5
  current = signal<any[]>([]);
6
6
 
7
- displayEffect(params: any, player: RpgCommonPlayer | { x: number, y: number }) {
7
+ clear(): void {
8
+ this.current.set([]);
9
+ }
10
+
11
+ displayEffect(params: any, player: RpgCommonPlayer | { x: number, y: number }): Promise<void> {
8
12
  const id = generateUID();
9
- this.current().push({
10
- ...params,
11
- id,
12
- x: player.x,
13
- y: player.y,
14
- object: player,
15
- onFinish: () => {
13
+ const effectParams = params ?? {};
14
+ return new Promise<void>((resolve) => {
15
+ let finished = false;
16
+ const finish = (data?: any) => {
17
+ if (finished) return;
18
+ finished = true;
16
19
  const index = this.current().findIndex((value) => value.id === id);
17
- this.current().splice(index, 1);
18
- },
20
+ if (index !== -1) {
21
+ this.current().splice(index, 1);
22
+ }
23
+ effectParams.onFinish?.(data);
24
+ resolve();
25
+ };
26
+
27
+ this.current().push({
28
+ ...effectParams,
29
+ id,
30
+ x: player.x,
31
+ y: player.y,
32
+ object: player,
33
+ onFinish: finish,
34
+ });
19
35
  });
20
36
  }
21
37
  }
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test, vi } from "vitest";
2
+ import { ClientVisualRegistry } from "./ClientVisuals";
3
+
4
+ describe("ClientVisualRegistry", () => {
5
+ test("plays registered visual handlers with resolved objects and helpers", async () => {
6
+ const target = {
7
+ flash: vi.fn(),
8
+ showHit: vi.fn(),
9
+ setAnimation: vi.fn(),
10
+ };
11
+ const componentAnimation = {
12
+ displayEffect: vi.fn(),
13
+ };
14
+ const engine = {
15
+ scene: {},
16
+ getObjectById: vi.fn(() => target),
17
+ getComponentAnimation: vi.fn(() => componentAnimation),
18
+ playSound: vi.fn().mockResolvedValue(undefined),
19
+ mapShakeTrigger: {
20
+ start: vi.fn(),
21
+ },
22
+ } as any;
23
+ const registry = new ClientVisualRegistry();
24
+
25
+ registry.register("hit", ({ target, data }, helpers) => {
26
+ helpers.flash(target, { type: "tint", tint: "red" });
27
+ helpers.showHit(target, `-${data.damage}`);
28
+ helpers.component("hit-spark", target, { scale: 2 });
29
+ helpers.sound("hit");
30
+ helpers.animation(target, "hurt");
31
+ helpers.shake({ intensity: 2 });
32
+ });
33
+
34
+ await registry.play(
35
+ {
36
+ name: "hit",
37
+ data: {
38
+ targetId: "enemy-1",
39
+ damage: 12,
40
+ },
41
+ },
42
+ engine
43
+ );
44
+
45
+ expect(engine.getObjectById).toHaveBeenCalledWith("enemy-1");
46
+ expect(target.flash).toHaveBeenCalledWith({ type: "tint", tint: "red" });
47
+ expect(target.showHit).toHaveBeenCalledWith("-12");
48
+ expect(componentAnimation.displayEffect).toHaveBeenCalledWith(
49
+ { scale: 2 },
50
+ target
51
+ );
52
+ expect(engine.playSound).toHaveBeenCalledWith("hit", undefined);
53
+ expect(target.setAnimation).toHaveBeenCalledWith("hurt", 1);
54
+ expect(engine.mapShakeTrigger.start).toHaveBeenCalledWith({ intensity: 2 });
55
+ });
56
+ });
@@ -0,0 +1,184 @@
1
+ import type { RpgClientEngine } from "../RpgClientEngine";
2
+ import type { RpgClientMap } from "./Map";
3
+
4
+ export type ClientVisualPosition = {
5
+ x: number;
6
+ y: number;
7
+ z?: number;
8
+ };
9
+
10
+ export type ClientVisualPayload = Record<string, any> & {
11
+ source?: string;
12
+ sourceId?: string;
13
+ target?: string;
14
+ targetId?: string;
15
+ object?: string;
16
+ objectId?: string;
17
+ position?: ClientVisualPosition;
18
+ };
19
+
20
+ export type ClientVisualPacket = {
21
+ name: string;
22
+ data?: ClientVisualPayload;
23
+ };
24
+
25
+ export type ClientVisualObjectTarget = string | Record<string, any> | undefined | null;
26
+ export type ClientVisualComponentTarget =
27
+ | ClientVisualObjectTarget
28
+ | ClientVisualPosition;
29
+
30
+ export type ClientVisualContext = {
31
+ name: string;
32
+ data: ClientVisualPayload;
33
+ engine: RpgClientEngine;
34
+ scene: RpgClientMap;
35
+ source?: any;
36
+ target?: any;
37
+ object?: any;
38
+ position?: ClientVisualPosition;
39
+ };
40
+
41
+ export type ClientVisualHelpers = {
42
+ getObject(id?: string | null): any;
43
+ flash(target?: ClientVisualObjectTarget, options?: Record<string, any>): void;
44
+ showHit(target: ClientVisualObjectTarget, text: string): void;
45
+ component(
46
+ id: string,
47
+ target?: ClientVisualComponentTarget,
48
+ params?: Record<string, any>
49
+ ): void;
50
+ sound(id: string, options?: { volume?: number; loop?: boolean }): Promise<void>;
51
+ animation(
52
+ target: ClientVisualObjectTarget,
53
+ animationName: string,
54
+ options?: { graphic?: string | string[]; repeat?: number }
55
+ ): void;
56
+ shake(options?: {
57
+ intensity?: number;
58
+ duration?: number;
59
+ frequency?: number;
60
+ direction?: string;
61
+ }): void;
62
+ };
63
+
64
+ export type ClientVisualHandler = (
65
+ context: ClientVisualContext,
66
+ helpers: ClientVisualHelpers
67
+ ) => void | Promise<void>;
68
+
69
+ export type ClientVisualMap = Record<string, ClientVisualHandler>;
70
+
71
+ const isPosition = (value: any): value is ClientVisualPosition =>
72
+ value &&
73
+ typeof value === "object" &&
74
+ typeof value.x === "number" &&
75
+ typeof value.y === "number";
76
+
77
+ const resolvePosition = (data: ClientVisualPayload): ClientVisualPosition | undefined => {
78
+ if (isPosition(data.position)) return data.position;
79
+ if (typeof data.x === "number" && typeof data.y === "number") {
80
+ return { x: data.x, y: data.y, z: data.z };
81
+ }
82
+ return undefined;
83
+ };
84
+
85
+ const resolveObject = (engine: RpgClientEngine, target: ClientVisualObjectTarget) => {
86
+ if (!target) return undefined;
87
+ if (typeof target === "string") return engine.getObjectById(target);
88
+ return target;
89
+ };
90
+
91
+ const resolvePayloadObject = (
92
+ engine: RpgClientEngine,
93
+ data: ClientVisualPayload,
94
+ keys: string[]
95
+ ) => {
96
+ const id = keys
97
+ .map((key) => data[key])
98
+ .find((value) => typeof value === "string");
99
+ return resolveObject(engine, id);
100
+ };
101
+
102
+ const createClientVisualHelpers = (
103
+ engine: RpgClientEngine
104
+ ): ClientVisualHelpers => ({
105
+ getObject(id) {
106
+ if (!id) return undefined;
107
+ return engine.getObjectById(id);
108
+ },
109
+ flash(target, options = {}) {
110
+ const object = resolveObject(engine, target);
111
+ object?.flash?.(options);
112
+ },
113
+ showHit(target, text) {
114
+ const object = resolveObject(engine, target);
115
+ object?.showHit?.(text);
116
+ },
117
+ component(id, target, params = {}) {
118
+ const object = isPosition(target) ? undefined : resolveObject(engine, target);
119
+ const position = isPosition(target) ? target : undefined;
120
+ const anchor = object ?? position;
121
+ if (!anchor) return;
122
+ engine.getComponentAnimation(id).displayEffect(params, anchor);
123
+ },
124
+ sound(id, options) {
125
+ return engine.playSound(id, options);
126
+ },
127
+ animation(target, animationName, options = {}) {
128
+ const object = resolveObject(engine, target);
129
+ if (!object?.setAnimation) return;
130
+ if (options.graphic !== undefined) {
131
+ object.setAnimation(animationName, options.graphic, options.repeat ?? 1);
132
+ return;
133
+ }
134
+ object.setAnimation(animationName, options.repeat ?? 1);
135
+ },
136
+ shake(options = {}) {
137
+ engine.mapShakeTrigger.start(options);
138
+ },
139
+ });
140
+
141
+ export class ClientVisualRegistry {
142
+ private readonly handlers = new Map<string, ClientVisualHandler>();
143
+
144
+ register(name: string, handler: ClientVisualHandler) {
145
+ this.handlers.set(name, handler);
146
+ return handler;
147
+ }
148
+
149
+ registerMany(visuals: ClientVisualMap) {
150
+ Object.entries(visuals).forEach(([name, handler]) => {
151
+ this.register(name, handler);
152
+ });
153
+ }
154
+
155
+ get(name: string) {
156
+ return this.handlers.get(name);
157
+ }
158
+
159
+ async play(packet: ClientVisualPacket, engine: RpgClientEngine) {
160
+ const handler = this.handlers.get(packet.name);
161
+ if (!handler) {
162
+ console.warn(`Client visual "${packet.name}" is not registered`);
163
+ return;
164
+ }
165
+
166
+ const data = packet.data ?? {};
167
+ const context: ClientVisualContext = {
168
+ name: packet.name,
169
+ data,
170
+ engine,
171
+ scene: engine.scene,
172
+ source: resolvePayloadObject(engine, data, ["sourceId", "source"]),
173
+ target: resolvePayloadObject(engine, data, ["targetId", "target"]),
174
+ object: resolvePayloadObject(engine, data, ["objectId", "object"]),
175
+ position: resolvePosition(data),
176
+ };
177
+
178
+ try {
179
+ await handler(context, createClientVisualHelpers(engine));
180
+ } catch (error) {
181
+ console.error(`Client visual "${packet.name}" failed`, error);
182
+ }
183
+ }
184
+ }
@@ -0,0 +1,84 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { EventComponentResolverRegistry, normalizeEventComponent } from "./EventComponentResolver";
3
+
4
+ describe("EventComponentResolverRegistry", () => {
5
+ test("uses the last resolver returning a custom event component", () => {
6
+ const registry = new EventComponentResolverRegistry();
7
+ const firstComponent = (() => null) as any;
8
+ const secondComponent = (() => null) as any;
9
+ const event = { id: "event-1" } as any;
10
+
11
+ registry.add(() => firstComponent);
12
+ registry.add(() => null);
13
+ registry.add(() => ({ component: secondComponent, props: { variant: "open" } }));
14
+
15
+ expect(registry.resolve(event)).toEqual({
16
+ component: secondComponent,
17
+ props: { variant: "open" }
18
+ });
19
+ });
20
+
21
+ test("returns null when no resolver matches", () => {
22
+ const registry = new EventComponentResolverRegistry();
23
+
24
+ registry.add(() => undefined);
25
+ registry.add(() => null);
26
+
27
+ expect(registry.resolve({ id: "event-1" } as any)).toBeNull();
28
+ });
29
+
30
+ test("can clear registered resolvers", () => {
31
+ const registry = new EventComponentResolverRegistry();
32
+ const component = (() => null) as any;
33
+
34
+ registry.add(() => component);
35
+ registry.clear();
36
+
37
+ expect(registry.resolve({ id: "event-1" } as any)).toBeNull();
38
+ });
39
+
40
+ test("always injects the real sprite prop for direct components", () => {
41
+ const component = (() => null) as any;
42
+ const sprite = { id: "event-1" } as any;
43
+
44
+ expect(normalizeEventComponent(component, sprite)).toEqual({
45
+ component,
46
+ props: { sprite },
47
+ dependencies: [],
48
+ renderGraphic: false
49
+ });
50
+ });
51
+
52
+ test("keeps custom props from replacing the sprite prop", () => {
53
+ const component = (() => null) as any;
54
+ const sprite = { id: "real-event" } as any;
55
+ const spoofedSprite = { id: "spoofed-event" };
56
+
57
+ const normalized = normalizeEventComponent({
58
+ component,
59
+ props: { sprite: spoofedSprite, variant: "wood" },
60
+ dependencies: () => ["ready"],
61
+ renderGraphic: true
62
+ }, sprite);
63
+
64
+ expect(normalized).toEqual({
65
+ component,
66
+ props: { variant: "wood", sprite },
67
+ dependencies: ["ready"],
68
+ renderGraphic: true
69
+ });
70
+ });
71
+
72
+ test("supports dynamic props", () => {
73
+ const component = (() => null) as any;
74
+ const sprite = { id: "event-1", name: "CHEST" } as any;
75
+
76
+ expect(normalizeEventComponent({
77
+ component,
78
+ props: (event) => ({ label: (event as any).name })
79
+ }, sprite)?.props).toEqual({
80
+ label: "CHEST",
81
+ sprite
82
+ });
83
+ });
84
+ });
@@ -0,0 +1,74 @@
1
+ import type { EventComponentConfig, EventComponentSprite } from "../RpgClient";
2
+ import type { RpgClientEvent } from "./Event";
3
+
4
+ export type EventComponentResolver = (event: EventComponentSprite) => EventComponentConfig | null | undefined;
5
+
6
+ export interface NormalizedEventComponentConfig {
7
+ component: any;
8
+ props: Record<string, any>;
9
+ dependencies: any[];
10
+ renderGraphic: boolean;
11
+ }
12
+
13
+ export class EventComponentResolverRegistry {
14
+ private resolvers: EventComponentResolver[] = [];
15
+
16
+ add(resolver: EventComponentResolver) {
17
+ this.resolvers.push(resolver);
18
+ return resolver;
19
+ }
20
+
21
+ resolve(event: RpgClientEvent): EventComponentConfig | null {
22
+ let resolved: EventComponentConfig | null = null;
23
+ this.resolvers.forEach((resolver) => {
24
+ const result = resolver(event as EventComponentSprite);
25
+ if (result !== undefined && result !== null) {
26
+ resolved = result;
27
+ }
28
+ });
29
+ return resolved;
30
+ }
31
+
32
+ clear() {
33
+ this.resolvers = [];
34
+ }
35
+ }
36
+
37
+ function withoutReservedSpriteProp(props: unknown): Record<string, any> {
38
+ if (!props || typeof props !== "object") return {};
39
+ const { sprite: _ignoredSprite, ...safeProps } = props as Record<string, any>;
40
+ return safeProps;
41
+ }
42
+
43
+ export function normalizeEventComponent(
44
+ componentConfig: EventComponentConfig | null | undefined,
45
+ sprite: RpgClientEvent
46
+ ): NormalizedEventComponentConfig | null {
47
+ if (!componentConfig) return null;
48
+
49
+ if (typeof componentConfig === "object" && "component" in componentConfig) {
50
+ const propsValue = componentConfig.props !== undefined
51
+ ? componentConfig.props
52
+ : componentConfig.data;
53
+ const props = typeof propsValue === "function"
54
+ ? propsValue(sprite as EventComponentSprite)
55
+ : propsValue;
56
+
57
+ return {
58
+ component: componentConfig.component,
59
+ props: {
60
+ ...withoutReservedSpriteProp(props),
61
+ sprite
62
+ },
63
+ dependencies: componentConfig.dependencies ? componentConfig.dependencies(sprite as EventComponentSprite) : [],
64
+ renderGraphic: componentConfig.renderGraphic === true
65
+ };
66
+ }
67
+
68
+ return {
69
+ component: componentConfig,
70
+ props: { sprite },
71
+ dependencies: [],
72
+ renderGraphic: false
73
+ };
74
+ }