@rpgjs/client 5.0.0-beta.2 → 5.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/CHANGELOG.md +123 -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 +96 -54
  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 +176 -11
  36. package/dist/RpgClientEngine.js +669 -68
  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 +606 -248
  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.js +2 -2
  90. package/dist/components/gui/mobile/index.js.map +1 -1
  91. package/dist/components/gui/mobile/mobile.ce.js +7 -5
  92. package/dist/components/gui/mobile/mobile.ce.js.map +1 -1
  93. package/dist/components/gui/notification/notification.ce.js +28 -26
  94. package/dist/components/gui/notification/notification.ce.js.map +1 -1
  95. package/dist/components/gui/save-load.ce.js +81 -256
  96. package/dist/components/gui/save-load.ce.js.map +1 -1
  97. package/dist/components/gui/shop/shop.ce.js +107 -142
  98. package/dist/components/gui/shop/shop.ce.js.map +1 -1
  99. package/dist/components/gui/title-screen.ce.js +50 -73
  100. package/dist/components/gui/title-screen.ce.js.map +1 -1
  101. package/dist/components/index.d.ts +2 -1
  102. package/dist/components/index.js +1 -0
  103. package/dist/components/interaction-components.ce.js +22 -0
  104. package/dist/components/interaction-components.ce.js.map +1 -0
  105. package/dist/components/player-components-utils.d.ts +67 -0
  106. package/dist/components/player-components-utils.js +162 -0
  107. package/dist/components/player-components-utils.js.map +1 -0
  108. package/dist/components/player-components-utils.spec.d.ts +1 -0
  109. package/dist/components/player-components.ce.js +191 -0
  110. package/dist/components/player-components.ce.js.map +1 -0
  111. package/dist/components/prebuilt/hp-bar.ce.js +45 -45
  112. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -1
  113. package/dist/components/prebuilt/light-halo.ce.js +39 -60
  114. package/dist/components/prebuilt/light-halo.ce.js.map +1 -1
  115. package/dist/components/scenes/canvas.ce.js +205 -27
  116. package/dist/components/scenes/canvas.ce.js.map +1 -1
  117. package/dist/components/scenes/draw-map.ce.js +39 -39
  118. package/dist/components/scenes/draw-map.ce.js.map +1 -1
  119. package/dist/components/scenes/event-layer.ce.js +51 -10
  120. package/dist/components/scenes/event-layer.ce.js.map +1 -1
  121. package/dist/core/inject.js +1 -1
  122. package/dist/core/inject.js.map +1 -1
  123. package/dist/core/setup.js +1 -1
  124. package/dist/core/setup.js.map +1 -1
  125. package/dist/decorators/spritesheet.d.ts +1 -0
  126. package/dist/decorators/spritesheet.js +11 -0
  127. package/dist/decorators/spritesheet.js.map +1 -0
  128. package/dist/i18n.d.ts +55 -0
  129. package/dist/i18n.js +60 -0
  130. package/dist/i18n.js.map +1 -0
  131. package/dist/i18n.spec.d.ts +1 -0
  132. package/dist/index.d.ts +7 -0
  133. package/dist/index.js +29 -21
  134. package/dist/module.js +45 -4
  135. package/dist/module.js.map +1 -1
  136. package/dist/node_modules/.pnpm/{@signe_di@2.9.0 → @signe_di@3.1.0}/node_modules/@signe/di/dist/index.js +7 -117
  137. package/dist/node_modules/.pnpm/@signe_di@3.1.0/node_modules/@signe/di/dist/index.js.map +1 -0
  138. package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js +239 -0
  139. package/dist/node_modules/.pnpm/@signe_reactive@3.1.0/node_modules/@signe/reactive/dist/index.js.map +1 -0
  140. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/chunk-EUXUH3YW.js +13 -0
  141. 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
  142. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js +698 -0
  143. package/dist/node_modules/.pnpm/@signe_room@3.1.0_react@19.2.7/node_modules/@signe/room/dist/index.js.map +1 -0
  144. package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/client/index.js +43 -0
  145. 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
  146. 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
  147. package/dist/node_modules/.pnpm/@signe_sync@3.1.0_react@19.2.7/node_modules/@signe/sync/dist/index.js.map +1 -0
  148. 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
  149. package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/index.js.map +1 -0
  150. 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
  151. package/dist/node_modules/.pnpm/partysocket@1.2.0_react@19.2.7/node_modules/partysocket/dist/ws.js.map +1 -0
  152. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js +13 -0
  153. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js.map +1 -0
  154. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +106 -0
  155. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js.map +1 -0
  156. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +13 -0
  157. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js.map +1 -0
  158. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js +121 -0
  159. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js.map +1 -0
  160. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js +10 -0
  161. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
  162. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +110 -0
  163. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
  164. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +99 -0
  165. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js.map +1 -0
  166. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +82 -0
  167. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js.map +1 -0
  168. 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
  169. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js.map +1 -0
  170. package/dist/presets/animation.js.map +1 -1
  171. package/dist/presets/faceset.js.map +1 -1
  172. package/dist/presets/icon.js.map +1 -1
  173. package/dist/presets/index.js.map +1 -1
  174. package/dist/presets/lpc.js.map +1 -1
  175. package/dist/presets/rmspritesheet.js.map +1 -1
  176. package/dist/services/AbstractSocket.d.ts +2 -0
  177. package/dist/services/AbstractSocket.js.map +1 -1
  178. package/dist/services/actionInput.d.ts +14 -0
  179. package/dist/services/actionInput.js +59 -0
  180. package/dist/services/actionInput.js.map +1 -0
  181. package/dist/services/actionInput.spec.d.ts +1 -0
  182. package/dist/services/interactions.d.ts +159 -0
  183. package/dist/services/interactions.js +460 -0
  184. package/dist/services/interactions.js.map +1 -0
  185. package/dist/services/interactions.spec.d.ts +1 -0
  186. package/dist/services/keyboardControls.d.ts +1 -0
  187. package/dist/services/keyboardControls.js +1 -0
  188. package/dist/services/keyboardControls.js.map +1 -1
  189. package/dist/services/loadMap.d.ts +9 -0
  190. package/dist/services/loadMap.js +1 -1
  191. package/dist/services/loadMap.js.map +1 -1
  192. package/dist/services/mmorpg-connection.d.ts +5 -0
  193. package/dist/services/mmorpg-connection.js +50 -0
  194. package/dist/services/mmorpg-connection.js.map +1 -0
  195. package/dist/services/mmorpg-connection.spec.d.ts +1 -0
  196. package/dist/services/mmorpg.d.ts +11 -4
  197. package/dist/services/mmorpg.js +57 -33
  198. package/dist/services/mmorpg.js.map +1 -1
  199. package/dist/services/pointerContext.d.ts +11 -0
  200. package/dist/services/pointerContext.js +48 -0
  201. package/dist/services/pointerContext.js.map +1 -0
  202. package/dist/services/pointerContext.spec.d.ts +1 -0
  203. package/dist/services/save.js.map +1 -1
  204. package/dist/services/save.spec.d.ts +1 -0
  205. package/dist/services/standalone-message.d.ts +1 -0
  206. package/dist/services/standalone-message.js +9 -0
  207. package/dist/services/standalone-message.js.map +1 -0
  208. package/dist/services/standalone.d.ts +4 -1
  209. package/dist/services/standalone.js +36 -16
  210. package/dist/services/standalone.js.map +1 -1
  211. package/dist/services/standalone.spec.d.ts +1 -0
  212. package/dist/utils/getEntityProp.js +4 -3
  213. package/dist/utils/getEntityProp.js.map +1 -1
  214. package/dist/utils/getEntityProp.spec.d.ts +1 -0
  215. package/dist/utils/mapId.d.ts +1 -0
  216. package/dist/utils/mapId.js +6 -0
  217. package/dist/utils/mapId.js.map +1 -0
  218. package/dist/utils/readPropValue.d.ts +2 -0
  219. package/dist/utils/readPropValue.js +13 -0
  220. package/dist/utils/readPropValue.js.map +1 -0
  221. package/package.json +13 -13
  222. package/src/Game/AnimationManager.spec.ts +30 -0
  223. package/src/Game/AnimationManager.ts +26 -10
  224. package/src/Game/ClientVisuals.spec.ts +56 -0
  225. package/src/Game/ClientVisuals.ts +184 -0
  226. package/src/Game/EventComponentResolver.spec.ts +84 -0
  227. package/src/Game/EventComponentResolver.ts +74 -0
  228. package/src/Game/Map.ts +134 -2
  229. package/src/Game/Object.spec.ts +59 -0
  230. package/src/Game/Object.ts +181 -77
  231. package/src/Game/ProjectileManager.spec.ts +449 -0
  232. package/src/Game/ProjectileManager.ts +346 -0
  233. package/src/Gui/Gui.spec.ts +340 -0
  234. package/src/Gui/Gui.ts +129 -57
  235. package/src/Resource.ts +1 -2
  236. package/src/RpgClient.ts +220 -17
  237. package/src/RpgClientEngine.ts +959 -116
  238. package/src/components/animations/fx.ce +101 -0
  239. package/src/components/animations/index.ts +4 -2
  240. package/src/components/character.ce +681 -45
  241. package/src/components/dynamics/bar.ce +88 -0
  242. package/src/components/dynamics/image.ce +21 -0
  243. package/src/components/dynamics/parse-value.spec.ts +83 -0
  244. package/src/components/dynamics/parse-value.ts +111 -37
  245. package/src/components/dynamics/shape-utils.spec.ts +46 -0
  246. package/src/components/dynamics/shape-utils.ts +61 -0
  247. package/src/components/dynamics/shape.ce +90 -0
  248. package/src/components/dynamics/text.ce +35 -149
  249. package/src/components/gui/dialogbox/index.ce +52 -21
  250. package/src/components/gui/gameover.ce +6 -4
  251. package/src/components/gui/menu/equip-menu.ce +11 -9
  252. package/src/components/gui/menu/exit-menu.ce +6 -4
  253. package/src/components/gui/menu/items-menu.ce +11 -9
  254. package/src/components/gui/menu/main-menu.ce +14 -12
  255. package/src/components/gui/menu/options-menu.ce +4 -3
  256. package/src/components/gui/menu/skills-menu.ce +2 -1
  257. package/src/components/gui/notification/notification.ce +7 -1
  258. package/src/components/gui/save-load.ce +13 -11
  259. package/src/components/gui/shop/shop.ce +20 -18
  260. package/src/components/gui/title-screen.ce +6 -4
  261. package/src/components/index.ts +2 -1
  262. package/src/components/interaction-components.ce +23 -0
  263. package/src/components/player-components-utils.spec.ts +109 -0
  264. package/src/components/player-components-utils.ts +205 -0
  265. package/src/components/player-components.ce +222 -0
  266. package/src/components/prebuilt/hp-bar.ce +4 -3
  267. package/src/components/prebuilt/light-halo.ce +2 -2
  268. package/src/components/scenes/canvas.ce +219 -15
  269. package/src/components/scenes/draw-map.ce +34 -22
  270. package/src/components/scenes/event-layer.ce +55 -4
  271. package/src/core/setup.ts +2 -2
  272. package/src/decorators/spritesheet.ts +8 -0
  273. package/src/i18n.spec.ts +39 -0
  274. package/src/i18n.ts +59 -0
  275. package/src/index.ts +7 -0
  276. package/src/module.ts +61 -11
  277. package/src/services/AbstractSocket.ts +3 -0
  278. package/src/services/actionInput.spec.ts +155 -0
  279. package/src/services/actionInput.ts +120 -0
  280. package/src/services/interactions.spec.ts +175 -0
  281. package/src/services/interactions.ts +722 -0
  282. package/src/services/keyboardControls.ts +2 -1
  283. package/src/services/loadMap.ts +5 -1
  284. package/src/services/mmorpg-connection.spec.ts +99 -0
  285. package/src/services/mmorpg-connection.ts +69 -0
  286. package/src/services/mmorpg.ts +70 -36
  287. package/src/services/pointerContext.spec.ts +36 -0
  288. package/src/services/pointerContext.ts +84 -0
  289. package/src/services/save.spec.ts +127 -0
  290. package/src/services/standalone-message.ts +7 -0
  291. package/src/services/standalone.spec.ts +54 -0
  292. package/src/services/standalone.ts +44 -12
  293. package/src/utils/getEntityProp.spec.ts +96 -0
  294. package/src/utils/getEntityProp.ts +4 -3
  295. package/src/utils/mapId.ts +2 -0
  296. package/src/utils/readPropValue.ts +16 -0
  297. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js.map +0 -1
  298. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js +0 -457
  299. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js.map +0 -1
  300. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js +0 -463
  301. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js.map +0 -1
  302. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js +0 -2191
  303. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js.map +0 -1
  304. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js +0 -10
  305. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +0 -1
  306. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js +0 -91
  307. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js.map +0 -1
  308. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js.map +0 -1
  309. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js +0 -14
  310. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +0 -1
  311. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +0 -1
  312. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +0 -1
  313. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +0 -2
  314. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +0 -1
@@ -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
+ }
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 isTest = (typeof process !== 'undefined' && process.env?.TEST === 'true')
33
- || (typeof window !== 'undefined' && (window as any).__RPGJS_TEST__ === true);
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
+ });