@rpgjs/client 5.0.0-alpha.8 → 5.0.0-beta.1

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 (305) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/Game/AnimationManager.js +26 -0
  3. package/dist/Game/AnimationManager.js.map +1 -0
  4. package/dist/Game/Event.d.ts +1 -1
  5. package/dist/Game/Event.js +12 -0
  6. package/dist/Game/Event.js.map +1 -0
  7. package/dist/Game/Map.d.ts +23 -2
  8. package/dist/Game/Map.js +80 -0
  9. package/dist/Game/Map.js.map +1 -0
  10. package/dist/Game/Object.d.ts +157 -0
  11. package/dist/Game/Object.js +211 -0
  12. package/dist/Game/Object.js.map +1 -0
  13. package/dist/Game/Player.d.ts +1 -1
  14. package/dist/Game/Player.js +12 -0
  15. package/dist/Game/Player.js.map +1 -0
  16. package/dist/Gui/Gui.d.ts +177 -5
  17. package/dist/Gui/Gui.js +445 -0
  18. package/dist/Gui/Gui.js.map +1 -0
  19. package/dist/Gui/NotificationManager.d.ts +23 -0
  20. package/dist/Gui/NotificationManager.js +49 -0
  21. package/dist/Gui/NotificationManager.js.map +1 -0
  22. package/dist/Resource.d.ts +97 -0
  23. package/dist/Resource.js +133 -0
  24. package/dist/Resource.js.map +1 -0
  25. package/dist/RpgClient.d.ts +290 -58
  26. package/dist/RpgClientEngine.d.ts +649 -9
  27. package/dist/RpgClientEngine.js +1334 -0
  28. package/dist/RpgClientEngine.js.map +1 -0
  29. package/dist/Sound.d.ts +199 -0
  30. package/dist/Sound.js +167 -0
  31. package/dist/Sound.js.map +1 -0
  32. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
  33. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
  34. package/dist/components/animations/animation.ce.js +24 -0
  35. package/dist/components/animations/animation.ce.js.map +1 -0
  36. package/dist/components/animations/hit.ce.js +70 -0
  37. package/dist/components/animations/hit.ce.js.map +1 -0
  38. package/dist/components/animations/index.d.ts +4 -0
  39. package/dist/components/animations/index.js +11 -0
  40. package/dist/components/animations/index.js.map +1 -0
  41. package/dist/components/character.ce.js +392 -0
  42. package/dist/components/character.ce.js.map +1 -0
  43. package/dist/components/dynamics/parse-value.d.ts +1 -0
  44. package/dist/components/dynamics/parse-value.js +44 -0
  45. package/dist/components/dynamics/parse-value.js.map +1 -0
  46. package/dist/components/dynamics/text.ce.js +73 -0
  47. package/dist/components/dynamics/text.ce.js.map +1 -0
  48. package/dist/components/gui/box.ce.js +28 -0
  49. package/dist/components/gui/box.ce.js.map +1 -0
  50. package/dist/components/gui/dialogbox/index.ce.js +205 -0
  51. package/dist/components/gui/dialogbox/index.ce.js.map +1 -0
  52. package/dist/components/gui/gameover.ce.js +193 -0
  53. package/dist/components/gui/gameover.ce.js.map +1 -0
  54. package/dist/components/gui/hud/hud.ce.js +92 -0
  55. package/dist/components/gui/hud/hud.ce.js.map +1 -0
  56. package/dist/components/gui/index.d.ts +15 -3
  57. package/dist/components/gui/index.js +14 -0
  58. package/dist/components/gui/menu/equip-menu.ce.js +481 -0
  59. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -0
  60. package/dist/components/gui/menu/exit-menu.ce.js +54 -0
  61. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -0
  62. package/dist/components/gui/menu/items-menu.ce.js +344 -0
  63. package/dist/components/gui/menu/items-menu.ce.js.map +1 -0
  64. package/dist/components/gui/menu/main-menu.ce.js +417 -0
  65. package/dist/components/gui/menu/main-menu.ce.js.map +1 -0
  66. package/dist/components/gui/menu/options-menu.ce.js +48 -0
  67. package/dist/components/gui/menu/options-menu.ce.js.map +1 -0
  68. package/dist/components/gui/menu/skills-menu.ce.js +107 -0
  69. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -0
  70. package/dist/components/gui/mobile/index.d.ts +8 -0
  71. package/dist/components/gui/mobile/index.js +21 -0
  72. package/dist/components/gui/mobile/index.js.map +1 -0
  73. package/dist/components/gui/mobile/mobile.ce.js +78 -0
  74. package/dist/components/gui/mobile/mobile.ce.js.map +1 -0
  75. package/dist/components/gui/notification/notification.ce.js +64 -0
  76. package/dist/components/gui/notification/notification.ce.js.map +1 -0
  77. package/dist/components/gui/save-load.ce.js +389 -0
  78. package/dist/components/gui/save-load.ce.js.map +1 -0
  79. package/dist/components/gui/shop/shop.ce.js +652 -0
  80. package/dist/components/gui/shop/shop.ce.js.map +1 -0
  81. package/dist/components/gui/title-screen.ce.js +190 -0
  82. package/dist/components/gui/title-screen.ce.js.map +1 -0
  83. package/dist/components/index.d.ts +1 -0
  84. package/dist/components/index.js +4 -0
  85. package/dist/components/prebuilt/hp-bar.ce.js +116 -0
  86. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -0
  87. package/dist/components/prebuilt/index.d.ts +19 -0
  88. package/dist/components/prebuilt/index.js +2 -0
  89. package/dist/components/prebuilt/light-halo.ce.js +94 -0
  90. package/dist/components/prebuilt/light-halo.ce.js.map +1 -0
  91. package/dist/components/scenes/canvas.ce.js +60 -0
  92. package/dist/components/scenes/canvas.ce.js.map +1 -0
  93. package/dist/components/scenes/draw-map.ce.js +89 -0
  94. package/dist/components/scenes/draw-map.ce.js.map +1 -0
  95. package/dist/components/scenes/event-layer.ce.js +28 -0
  96. package/dist/components/scenes/event-layer.ce.js.map +1 -0
  97. package/dist/core/inject.js +18 -0
  98. package/dist/core/inject.js.map +1 -0
  99. package/dist/core/setup.js +16 -0
  100. package/dist/core/setup.js.map +1 -0
  101. package/dist/index.d.ts +15 -1
  102. package/dist/index.js +44 -14
  103. package/dist/module.d.ts +43 -4
  104. package/dist/module.js +176 -0
  105. package/dist/module.js.map +1 -0
  106. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js +277 -0
  107. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js.map +1 -0
  108. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js +457 -0
  109. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js.map +1 -0
  110. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js +463 -0
  111. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js.map +1 -0
  112. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js +2191 -0
  113. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js.map +1 -0
  114. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js +10 -0
  115. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +1 -0
  116. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js +91 -0
  117. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js.map +1 -0
  118. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js +325 -0
  119. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js.map +1 -0
  120. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js +14 -0
  121. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +1 -0
  122. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js +115 -0
  123. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +1 -0
  124. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js +401 -0
  125. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +1 -0
  126. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +2 -0
  127. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js +3756 -0
  128. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +1 -0
  129. package/dist/presets/animation.d.ts +31 -0
  130. package/dist/presets/animation.js +39 -0
  131. package/dist/presets/animation.js.map +1 -0
  132. package/dist/presets/faceset.d.ts +30 -0
  133. package/dist/presets/faceset.js +51 -0
  134. package/dist/presets/faceset.js.map +1 -0
  135. package/dist/presets/icon.d.ts +20 -0
  136. package/dist/presets/icon.js +15 -0
  137. package/dist/presets/icon.js.map +1 -0
  138. package/dist/presets/index.d.ts +123 -0
  139. package/dist/presets/index.js +17 -0
  140. package/dist/presets/index.js.map +1 -0
  141. package/dist/presets/lpc.d.ts +89 -0
  142. package/dist/presets/lpc.js +98 -0
  143. package/dist/presets/lpc.js.map +1 -0
  144. package/dist/presets/rmspritesheet.js +42 -0
  145. package/dist/presets/rmspritesheet.js.map +1 -0
  146. package/dist/services/AbstractSocket.d.ts +9 -5
  147. package/dist/services/AbstractSocket.js +11 -0
  148. package/dist/services/AbstractSocket.js.map +1 -0
  149. package/dist/services/keyboardControls.d.ts +15 -0
  150. package/dist/services/keyboardControls.js +23 -0
  151. package/dist/services/keyboardControls.js.map +1 -0
  152. package/dist/services/loadMap.js +123 -0
  153. package/dist/services/loadMap.js.map +1 -0
  154. package/dist/services/mmorpg.d.ts +21 -9
  155. package/dist/services/mmorpg.js +131 -0
  156. package/dist/services/mmorpg.js.map +1 -0
  157. package/dist/services/save.d.ts +19 -0
  158. package/dist/services/save.js +77 -0
  159. package/dist/services/save.js.map +1 -0
  160. package/dist/services/standalone.d.ts +67 -7
  161. package/dist/services/standalone.js +168 -0
  162. package/dist/services/standalone.js.map +1 -0
  163. package/dist/utils/getEntityProp.d.ts +39 -0
  164. package/dist/utils/getEntityProp.js +52 -0
  165. package/dist/utils/getEntityProp.js.map +1 -0
  166. package/package.json +13 -9
  167. package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
  168. package/src/Game/Event.ts +1 -1
  169. package/src/Game/Map.ts +95 -3
  170. package/src/Game/Object.ts +330 -14
  171. package/src/Game/Player.ts +1 -1
  172. package/src/Gui/Gui.ts +506 -18
  173. package/src/Gui/NotificationManager.ts +69 -0
  174. package/src/Resource.ts +150 -0
  175. package/src/RpgClient.ts +300 -58
  176. package/src/RpgClientEngine.ts +1707 -48
  177. package/src/Sound.ts +253 -0
  178. package/src/components/{effects → animations}/animation.ce +3 -6
  179. package/src/components/{effects → animations}/index.ts +1 -1
  180. package/src/components/character.ce +406 -40
  181. package/src/components/dynamics/parse-value.ts +80 -0
  182. package/src/components/dynamics/text.ce +183 -0
  183. package/src/components/gui/box.ce +17 -0
  184. package/src/components/gui/dialogbox/index.ce +204 -187
  185. package/src/components/gui/gameover.ce +158 -0
  186. package/src/components/gui/hud/hud.ce +61 -0
  187. package/src/components/gui/index.ts +30 -4
  188. package/src/components/gui/menu/equip-menu.ce +410 -0
  189. package/src/components/gui/menu/exit-menu.ce +41 -0
  190. package/src/components/gui/menu/items-menu.ce +317 -0
  191. package/src/components/gui/menu/main-menu.ce +294 -0
  192. package/src/components/gui/menu/options-menu.ce +35 -0
  193. package/src/components/gui/menu/skills-menu.ce +83 -0
  194. package/src/components/gui/mobile/index.ts +24 -0
  195. package/src/components/gui/mobile/mobile.ce +80 -0
  196. package/src/components/gui/notification/notification.ce +51 -0
  197. package/src/components/gui/save-load.ce +208 -0
  198. package/src/components/gui/shop/shop.ce +493 -0
  199. package/src/components/gui/title-screen.ce +163 -0
  200. package/src/components/index.ts +3 -0
  201. package/src/components/prebuilt/hp-bar.ce +255 -0
  202. package/src/components/prebuilt/index.ts +24 -0
  203. package/src/components/prebuilt/light-halo.ce +148 -0
  204. package/src/components/scenes/canvas.ce +20 -15
  205. package/src/components/scenes/draw-map.ce +60 -13
  206. package/src/components/scenes/event-layer.ce +9 -2
  207. package/src/components/scenes/transition.ce +60 -0
  208. package/src/index.ts +16 -2
  209. package/src/module.ts +145 -9
  210. package/src/presets/animation.ts +46 -0
  211. package/src/presets/faceset.ts +60 -0
  212. package/src/presets/icon.ts +17 -0
  213. package/src/presets/index.ts +9 -1
  214. package/src/presets/lpc.ts +108 -0
  215. package/src/services/AbstractSocket.ts +10 -2
  216. package/src/services/keyboardControls.ts +20 -0
  217. package/src/services/loadMap.ts +1 -1
  218. package/src/services/mmorpg.ts +100 -12
  219. package/src/services/save.ts +103 -0
  220. package/src/services/standalone.ts +110 -18
  221. package/src/utils/getEntityProp.ts +87 -0
  222. package/tsconfig.json +1 -1
  223. package/vite.config.ts +4 -2
  224. package/dist/Game/EffectManager.d.ts +0 -5
  225. package/dist/components/effects/index.d.ts +0 -4
  226. package/dist/index.js.map +0 -1
  227. package/dist/index10.js +0 -8
  228. package/dist/index10.js.map +0 -1
  229. package/dist/index11.js +0 -10
  230. package/dist/index11.js.map +0 -1
  231. package/dist/index12.js +0 -8
  232. package/dist/index12.js.map +0 -1
  233. package/dist/index13.js +0 -17
  234. package/dist/index13.js.map +0 -1
  235. package/dist/index14.js +0 -91
  236. package/dist/index14.js.map +0 -1
  237. package/dist/index15.js +0 -50
  238. package/dist/index15.js.map +0 -1
  239. package/dist/index16.js +0 -191
  240. package/dist/index16.js.map +0 -1
  241. package/dist/index17.js +0 -9
  242. package/dist/index17.js.map +0 -1
  243. package/dist/index18.js +0 -387
  244. package/dist/index18.js.map +0 -1
  245. package/dist/index19.js +0 -31
  246. package/dist/index19.js.map +0 -1
  247. package/dist/index2.js +0 -112
  248. package/dist/index2.js.map +0 -1
  249. package/dist/index20.js +0 -24
  250. package/dist/index20.js.map +0 -1
  251. package/dist/index21.js +0 -2421
  252. package/dist/index21.js.map +0 -1
  253. package/dist/index22.js +0 -114
  254. package/dist/index22.js.map +0 -1
  255. package/dist/index23.js +0 -109
  256. package/dist/index23.js.map +0 -1
  257. package/dist/index24.js +0 -71
  258. package/dist/index24.js.map +0 -1
  259. package/dist/index25.js +0 -21
  260. package/dist/index25.js.map +0 -1
  261. package/dist/index26.js +0 -41
  262. package/dist/index26.js.map +0 -1
  263. package/dist/index27.js +0 -5
  264. package/dist/index27.js.map +0 -1
  265. package/dist/index28.js +0 -322
  266. package/dist/index28.js.map +0 -1
  267. package/dist/index29.js +0 -27
  268. package/dist/index29.js.map +0 -1
  269. package/dist/index3.js +0 -87
  270. package/dist/index3.js.map +0 -1
  271. package/dist/index30.js +0 -11
  272. package/dist/index30.js.map +0 -1
  273. package/dist/index31.js +0 -11
  274. package/dist/index31.js.map +0 -1
  275. package/dist/index32.js +0 -12
  276. package/dist/index32.js.map +0 -1
  277. package/dist/index33.js +0 -4403
  278. package/dist/index33.js.map +0 -1
  279. package/dist/index34.js +0 -316
  280. package/dist/index34.js.map +0 -1
  281. package/dist/index35.js +0 -174
  282. package/dist/index35.js.map +0 -1
  283. package/dist/index36.js +0 -501
  284. package/dist/index36.js.map +0 -1
  285. package/dist/index37.js +0 -61
  286. package/dist/index37.js.map +0 -1
  287. package/dist/index38.js +0 -20
  288. package/dist/index38.js.map +0 -1
  289. package/dist/index39.js +0 -20
  290. package/dist/index39.js.map +0 -1
  291. package/dist/index4.js +0 -67
  292. package/dist/index4.js.map +0 -1
  293. package/dist/index5.js +0 -16
  294. package/dist/index5.js.map +0 -1
  295. package/dist/index6.js +0 -17
  296. package/dist/index6.js.map +0 -1
  297. package/dist/index7.js +0 -39
  298. package/dist/index7.js.map +0 -1
  299. package/dist/index8.js +0 -90
  300. package/dist/index8.js.map +0 -1
  301. package/dist/index9.js +0 -76
  302. package/dist/index9.js.map +0 -1
  303. package/src/components/gui/dialogbox/itemMenu.ce +0 -23
  304. package/src/components/gui/dialogbox/selection.ce +0 -67
  305. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Gui.js","names":[],"sources":["../../src/Gui/Gui.ts"],"sourcesContent":["import { Context, inject } from \"@signe/di\";\nimport { signal, Signal, WritableSignal } from \"canvasengine\";\nimport { AbstractWebsocket, WebSocketToken } from \"../services/AbstractSocket\";\nimport { DialogboxComponent, ShopComponent, SaveLoadComponent, MainMenuComponent, NotificationComponent, TitleScreenComponent, GameoverComponent } from \"../components/gui\";\nimport { combineLatest, Subscription } from \"rxjs\";\nimport { delay, PrebuiltGui } from \"@rpgjs/common\";\n\ninterface GuiOptions {\n name?: string;\n id?: string;\n component: any;\n display?: boolean;\n data?: any;\n /**\n * Auto display the GUI when added to the system\n * @default false\n */\n autoDisplay?: boolean;\n /**\n * Function that returns an array of Signal dependencies\n * The GUI will only display when all dependencies are resolved (!= undefined)\n * @returns Array of Signal dependencies\n */\n dependencies?: () => Signal[];\n /**\n * Attach the GUI to sprites instead of displaying globally\n * When true, the GUI will be rendered in character.ce for each sprite\n * @default false\n */\n attachToSprite?: boolean;\n}\n\ninterface GuiInstance {\n name: string;\n component: any;\n display: WritableSignal<boolean>;\n data: WritableSignal<any>;\n autoDisplay: boolean;\n dependencies?: () => Signal[];\n subscription?: Subscription;\n attachToSprite?: boolean;\n}\n\ninterface GuiAction {\n guiId: string;\n name: string;\n data: any;\n clientActionId: string;\n}\n\ntype OptimisticReducer = (data: any, action: GuiAction) => any;\n\nconst throwError = (id: string) => {\n throw `The GUI named ${id} is non-existent. Please add the component in the gui property of the decorator @RpgClient`;\n};\n\nconst updateItemQuantity = (items: any[], id: string) => {\n const index = items.findIndex((item) => item?.id === id);\n if (index === -1) return items;\n const item = items[index];\n if (item?.usable === false) return items;\n if (item?.consumable === false) return items;\n const quantity = typeof item?.quantity === \"number\" ? item.quantity : 1;\n const nextQuantity = Math.max(0, quantity - 1);\n if (nextQuantity === quantity) return items;\n if (nextQuantity <= 0) {\n return items.filter((_, idx) => idx !== index);\n }\n const nextItems = items.slice();\n nextItems[index] = { ...item, quantity: nextQuantity };\n return nextItems;\n};\n\nconst updateEquippedFlag = (items: any[], id: string, equip: boolean) => {\n const index = items.findIndex((item) => item?.id === id);\n if (index === -1) return items;\n const item = items[index];\n if (item?.equipped === equip) return items;\n const nextItems = items.slice();\n nextItems[index] = { ...item, equipped: equip };\n return nextItems;\n};\n\nconst mainMenuOptimisticReducer: OptimisticReducer = (data, action) => {\n if (!data || typeof data !== \"object\") return data;\n if (action.name === \"useItem\") {\n if (!Array.isArray(data.items)) return data;\n const id = action.data?.id;\n if (!id) return data;\n const nextItems = updateItemQuantity(data.items, id);\n if (nextItems === data.items) return data;\n return { ...data, items: nextItems };\n }\n if (action.name === \"equipItem\") {\n const id = action.data?.id;\n if (!id || typeof action.data?.equip !== \"boolean\") return data;\n const equip = action.data.equip;\n let nextItems = data.items;\n let nextEquips = data.equips;\n if (Array.isArray(data.items)) {\n nextItems = updateEquippedFlag(data.items, id, equip);\n }\n if (Array.isArray(data.equips)) {\n nextEquips = updateEquippedFlag(data.equips, id, equip);\n }\n if (nextItems === data.items && nextEquips === data.equips) return data;\n return {\n ...data,\n ...(nextItems !== data.items ? { items: nextItems } : {}),\n ...(nextEquips !== data.equips ? { equips: nextEquips } : {})\n };\n }\n return data;\n};\n\nexport class RpgGui {\n private webSocket: AbstractWebsocket;\n gui = signal<Record<string, GuiInstance>>({});\n extraGuis: GuiInstance[] = [];\n private vueGuiInstance: any = null; // Reference to VueGui instance\n private optimisticReducers = new Map<string, OptimisticReducer[]>();\n private pendingActions = new Map<string, GuiAction[]>();\n /**\n * Signal tracking which player IDs should display attached GUIs\n * Key: player ID, Value: boolean (true = show, false = hide)\n */\n attachedGuiDisplayState = signal<Record<string, boolean>>({});\n\n constructor(private context: Context) {\n this.webSocket = inject(context, WebSocketToken);\n this.add({\n name: \"rpg-dialog\",\n component: DialogboxComponent,\n });\n this.add({\n name: PrebuiltGui.MainMenu,\n component: MainMenuComponent,\n });\n this.add({\n name: PrebuiltGui.Shop,\n component: ShopComponent,\n });\n this.add({\n name: PrebuiltGui.Notification,\n component: NotificationComponent,\n autoDisplay: true,\n });\n this.add({\n name: PrebuiltGui.Save,\n component: SaveLoadComponent,\n });\n this.add({\n name: PrebuiltGui.TitleScreen,\n component: TitleScreenComponent,\n });\n this.add({\n name: PrebuiltGui.Gameover,\n component: GameoverComponent,\n });\n\n this.registerOptimisticReducer(PrebuiltGui.MainMenu, mainMenuOptimisticReducer);\n }\n\n async _initialize() {\n this.webSocket.on(\"gui.open\", (data: { guiId: string; data: any }) => {\n this.clearPendingActions(data.guiId);\n this.display(data.guiId, data.data);\n });\n\n this.webSocket.on(\"gui.exit\", (guiId: string) => {\n this.hide(guiId);\n });\n\n this.webSocket.on(\"gui.update\", (payload: { guiId: string; data: any; clientActionId?: string }) => {\n this.applyServerUpdate(payload.guiId, payload.data, payload.clientActionId);\n });\n\n /**\n * Listen for tooltip display state changes from server\n * This is triggered by showAttachedGui/hideAttachedGui on the server\n */\n this.webSocket.on(\"gui.tooltip\", (data: { players: string[]; display: boolean }) => {\n const currentState = { ...this.attachedGuiDisplayState() };\n data.players.forEach((playerId) => {\n currentState[playerId] = data.display;\n });\n this.attachedGuiDisplayState.set(currentState);\n });\n }\n\n /**\n * Set the VueGui instance reference for Vue component management\n * This is called by VueGui when it's initialized\n * \n * @param vueGuiInstance - The VueGui instance\n */\n _setVueGuiInstance(vueGuiInstance: any) {\n this.vueGuiInstance = vueGuiInstance;\n }\n\n /**\n * Notify VueGui about GUI state changes\n * This synchronizes the Vue component display state\n * \n * @param guiId - The GUI component ID\n * @param display - Display state\n * @param data - Component data\n */\n private _notifyVueGui(guiId: string, display: boolean, data: any = {}) {\n if (this.vueGuiInstance && this.vueGuiInstance.vm) {\n // Find the GUI in extraGuis\n const extraGui = this.extraGuis.find(gui => gui.name === guiId);\n if (extraGui) {\n // Update the Vue component's display state and data\n this.vueGuiInstance.vm.gui[guiId] = {\n name: guiId,\n display,\n data,\n attachToSprite: extraGui.attachToSprite || false\n };\n // Trigger Vue reactivity\n this.vueGuiInstance.vm.gui = Object.assign({}, this.vueGuiInstance.vm.gui);\n }\n }\n }\n\n /**\n * Initialize Vue components in the VueGui instance\n * This should be called after VueGui is mounted\n */\n _initializeVueComponents() {\n if (this.vueGuiInstance && this.vueGuiInstance.vm) {\n // Initialize all extraGuis in the Vue instance\n this.extraGuis.forEach(gui => {\n this.vueGuiInstance.vm.gui[gui.name] = {\n name: gui.name,\n display: gui.display(),\n data: gui.data(),\n attachToSprite: gui.attachToSprite || false\n };\n });\n \n // Trigger Vue reactivity\n this.vueGuiInstance.vm.gui = Object.assign({}, this.vueGuiInstance.vm.gui);\n }\n }\n\n guiInteraction(guiId: string, name: string, data: any) {\n const clientActionId = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random()}`;\n const actionData = { ...(data || {}), clientActionId };\n this.applyOptimisticAction({\n guiId,\n name,\n data: actionData,\n clientActionId\n });\n this.webSocket.emit(\"gui.interaction\", {\n guiId,\n name,\n data: actionData,\n });\n }\n\n guiClose(guiId: string, data?: any) {\n this.webSocket.emit(\"gui.exit\", {\n guiId,\n data,\n });\n }\n\n /**\n * Add a GUI component to the system\n * \n * By default, only CanvasEngine components (.ce files) are accepted.\n * Vue components should be handled by the @rpgjs/vue package.\n * \n * @param gui - GUI configuration options\n * @param gui.name - Name or ID of the GUI component\n * @param gui.id - Alternative ID if name is not provided\n * @param gui.component - The component to render (must be a CanvasEngine component)\n * @param gui.display - Initial display state (default: false)\n * @param gui.data - Initial data for the component\n * @param gui.autoDisplay - Auto display when added (default: false)\n * @param gui.dependencies - Function returning Signal dependencies\n * @param gui.attachToSprite - Attach GUI to sprites instead of global display (default: false)\n * \n * @example\n * ```ts\n * gui.add({\n * name: 'inventory',\n * component: InventoryComponent, // Must be a .ce component\n * autoDisplay: true,\n * dependencies: () => [playerSignal, inventorySignal]\n * });\n * \n * // Attach to sprites\n * gui.add({\n * name: 'tooltip',\n * component: TooltipComponent,\n * attachToSprite: true\n * });\n * ```\n */\n add(gui: GuiOptions) {\n const guiId = gui.name || gui.id;\n if (!guiId) {\n throw new Error(\"GUI must have a name or id\");\n }\n const guiInstance: GuiInstance = {\n name: guiId,\n component: gui.component,\n display: signal(gui.display || false),\n data: signal(gui.data || {}),\n autoDisplay: gui.autoDisplay || false,\n dependencies: gui.dependencies ? gui.dependencies() : [],\n attachToSprite: gui.attachToSprite || false,\n };\n\n // Accept both CanvasEngine components (.ce) and Vue components\n // Vue components will be handled by VueGui if available\n if (typeof gui.component !== 'function') {\n guiInstance.component = gui;\n this.extraGuis.push(guiInstance);\n \n // Auto display Vue components if enabled\n if (guiInstance.autoDisplay) {\n this._notifyVueGui(guiId, true, gui.data || {});\n }\n return;\n }\n\n this.gui()[guiId] = guiInstance;\n\n // Auto display if enabled and it's a CanvasEngine component\n if (guiInstance.autoDisplay && typeof gui.component === 'function') {\n this.display(guiId, gui.data);\n }\n }\n\n registerOptimisticReducer(guiId: string, reducer: OptimisticReducer) {\n const existing = this.optimisticReducers.get(guiId) || [];\n this.optimisticReducers.set(guiId, existing.concat(reducer));\n }\n\n /**\n * Get all attached GUI components (attachToSprite: true)\n * \n * Returns all GUI instances that are configured to be attached to sprites.\n * These GUIs should be rendered in character.ce instead of canvas.ce.\n * \n * @returns Array of GUI instances with attachToSprite: true\n * \n * @example\n * ```ts\n * const attachedGuis = gui.getAttachedGuis();\n * // Use in character.ce to render tooltips\n * ```\n */\n getAttachedGuis(): GuiInstance[] {\n const allGuis = this.getAll();\n return Object.values(allGuis).filter(gui => gui.attachToSprite === true);\n }\n\n /**\n * Check if a player should display attached GUIs\n * \n * @param playerId - The player ID to check\n * @returns true if attached GUIs should be displayed for this player\n */\n shouldDisplayAttachedGui(playerId: string): boolean {\n return this.attachedGuiDisplayState()[playerId] === true;\n }\n\n get(id: string): GuiInstance | undefined {\n // Check CanvasEngine GUIs first\n const canvasGui = this.gui()[id];\n if (canvasGui) {\n return canvasGui;\n }\n \n // Check Vue GUIs in extraGuis\n return this.extraGuis.find(gui => gui.name === id);\n }\n\n exists(id: string): boolean {\n return !!this.get(id);\n }\n\n getAll(): Record<string, GuiInstance> {\n const allGuis = { ...this.gui() };\n \n // Add extraGuis to the result\n this.extraGuis.forEach(gui => {\n allGuis[gui.name] = gui;\n });\n \n return allGuis;\n }\n\n /**\n * Display a GUI component\n * \n * Displays the GUI immediately if no dependencies are configured,\n * or waits for all dependencies to be resolved if dependencies are present.\n * Automatically manages subscriptions to prevent memory leaks.\n * Works with both CanvasEngine components and Vue components.\n * \n * @param id - The GUI component ID\n * @param data - Data to pass to the component\n * @param dependencies - Optional runtime dependencies (overrides config dependencies)\n * \n * @example\n * ```ts\n * // Display immediately\n * gui.display('inventory', { items: [] });\n * \n * // Display with runtime dependencies\n * gui.display('shop', { shopId: 1 }, [playerSignal, shopSignal]);\n * ```\n */\n display(id: string, data = {}, dependencies: Signal[] = []) {\n if (!this.exists(id)) {\n throw throwError(id);\n }\n\n const guiInstance = this.get(id)!;\n \n // Check if it's a Vue component (in extraGuis)\n const isVueComponent = this.extraGuis.some(gui => gui.name === id);\n \n if (isVueComponent) {\n // Handle Vue component display\n this._handleVueComponentDisplay(id, data, dependencies, guiInstance);\n } else {\n guiInstance.data.set(data);\n guiInstance.display.set(true);\n }\n }\n\n isDisplaying(id: string): boolean {\n const guiInstance = this.get(id);\n if (!guiInstance) return false;\n return guiInstance.display();\n }\n\n /**\n * Handle Vue component display logic\n * \n * @param id - GUI component ID\n * @param data - Component data\n * @param dependencies - Runtime dependencies\n * @param guiInstance - GUI instance\n */\n private _handleVueComponentDisplay(id: string, data: any, dependencies: Signal[], guiInstance: GuiInstance) {\n // Unsubscribe from previous subscription if exists\n if (guiInstance.subscription) {\n guiInstance.subscription.unsubscribe();\n guiInstance.subscription = undefined;\n }\n\n // Use runtime dependencies or config dependencies\n const deps = dependencies.length > 0 \n ? dependencies \n : (guiInstance.dependencies ? guiInstance.dependencies() : []);\n\n if (deps.length > 0) {\n // Subscribe to dependencies\n guiInstance.subscription = combineLatest(\n deps.map(dependency => dependency.observable)\n ).subscribe((values) => {\n if (values.every(value => value !== undefined)) {\n guiInstance.data.set(data);\n guiInstance.display.set(true);\n this._notifyVueGui(id, true, data);\n }\n });\n return;\n }\n\n // No dependencies, display immediately\n guiInstance.data.set(data);\n guiInstance.display.set(true);\n this._notifyVueGui(id, true, data);\n }\n\n /**\n * Hide a GUI component\n * \n * Hides the GUI and cleans up any active subscriptions.\n * Works with both CanvasEngine components and Vue components.\n * \n * @param id - The GUI component ID\n * \n * @example\n * ```ts\n * gui.hide('inventory');\n * ```\n */\n hide(id: string) {\n if (!this.exists(id)) {\n throw throwError(id);\n }\n\n const guiInstance = this.get(id)!;\n \n // Unsubscribe if there's an active subscription\n if (guiInstance.subscription) {\n guiInstance.subscription.unsubscribe();\n guiInstance.subscription = undefined;\n }\n\n guiInstance.display.set(false)\n \n // Check if it's a Vue component and notify VueGui\n const isVueComponent = this.extraGuis.some(gui => gui.name === id);\n if (isVueComponent) {\n this._notifyVueGui(id, false);\n }\n }\n\n private isVueComponent(id: string) {\n return this.extraGuis.some(gui => gui.name === id);\n }\n\n private clearPendingActions(guiId: string) {\n this.pendingActions.delete(guiId);\n }\n\n private applyReducers(guiId: string, data: any, actions: GuiAction[]) {\n const reducers = this.optimisticReducers.get(guiId);\n if (!reducers || reducers.length === 0) return data;\n let next = data;\n for (const action of actions) {\n for (const reducer of reducers) {\n const updated = reducer(next, action);\n if (updated !== undefined && updated !== null && updated !== next) {\n next = updated;\n }\n }\n }\n return next;\n }\n\n private applyOptimisticAction(action: GuiAction) {\n const guiInstance = this.get(action.guiId);\n if (!guiInstance) return;\n const reducers = this.optimisticReducers.get(action.guiId);\n if (!reducers || reducers.length === 0) return;\n const currentData = guiInstance.data();\n const nextData = this.applyReducers(action.guiId, currentData, [action]);\n if (nextData === currentData) return;\n guiInstance.data.set(nextData);\n const pending = this.pendingActions.get(action.guiId) || [];\n pending.push(action);\n this.pendingActions.set(action.guiId, pending);\n if (this.isVueComponent(action.guiId)) {\n this._notifyVueGui(action.guiId, guiInstance.display(), nextData);\n }\n }\n\n private applyServerUpdate(guiId: string, data: any, clientActionId?: string) {\n const guiInstance = this.get(guiId);\n if (!guiInstance) return;\n let pending = this.pendingActions.get(guiId) || [];\n if (clientActionId) {\n pending = pending.filter(action => action.clientActionId !== clientActionId);\n } else {\n pending = [];\n }\n let nextData = data;\n if (pending.length) {\n nextData = this.applyReducers(guiId, nextData, pending);\n }\n guiInstance.data.set(nextData);\n this.pendingActions.set(guiId, pending);\n if (this.isVueComponent(guiId)) {\n this._notifyVueGui(guiId, guiInstance.display(), nextData);\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export type NotificationType = "info" | "warn" | "error";
2
+ export interface NotificationPayload {
3
+ message: string;
4
+ type?: NotificationType;
5
+ icon?: string;
6
+ time?: number;
7
+ sound?: string;
8
+ }
9
+ export interface NotificationItem extends NotificationPayload {
10
+ id: number;
11
+ opacity: any;
12
+ offset: any;
13
+ layoutY: any;
14
+ removing: boolean;
15
+ }
16
+ export declare class NotificationManager {
17
+ stack: import('canvasengine').WritableArraySignal<NotificationItem[]>;
18
+ private _counter;
19
+ add(payload: NotificationPayload, engine?: {
20
+ playSound?: (id: string) => void;
21
+ }): void;
22
+ remove(id: number): void;
23
+ }
@@ -0,0 +1,49 @@
1
+ import { animatedSignal, signal } from "canvasengine";
2
+ //#region src/Gui/NotificationManager.ts
3
+ var DEFAULT_DURATION = 220;
4
+ var NotificationManager = class {
5
+ constructor() {
6
+ this.stack = signal([]);
7
+ this._counter = 0;
8
+ }
9
+ add(payload, engine) {
10
+ const id = ++this._counter;
11
+ const opacity = animatedSignal(0, { duration: DEFAULT_DURATION });
12
+ const offset = animatedSignal(12, { duration: DEFAULT_DURATION });
13
+ const layoutY = animatedSignal(0, { duration: DEFAULT_DURATION });
14
+ const item = {
15
+ id,
16
+ message: payload.message,
17
+ type: payload.type || "info",
18
+ icon: payload.icon,
19
+ time: payload.time,
20
+ sound: payload.sound,
21
+ opacity,
22
+ offset,
23
+ layoutY,
24
+ removing: false
25
+ };
26
+ this.stack.update((list) => [...list, item]);
27
+ opacity.set(1);
28
+ offset.set(0);
29
+ if (payload.sound && engine?.playSound) engine.playSound(payload.sound);
30
+ const delay = typeof payload.time === "number" ? payload.time : 2e3;
31
+ setTimeout(() => {
32
+ this.remove(id);
33
+ }, delay);
34
+ }
35
+ remove(id) {
36
+ const item = this.stack().find((it) => it.id === id);
37
+ if (!item || item.removing) return;
38
+ item.removing = true;
39
+ item.opacity.set(0);
40
+ item.offset.set(-8);
41
+ setTimeout(() => {
42
+ this.stack.update((items) => items.filter((it) => it.id !== id));
43
+ }, DEFAULT_DURATION);
44
+ }
45
+ };
46
+ //#endregion
47
+ export { NotificationManager };
48
+
49
+ //# sourceMappingURL=NotificationManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationManager.js","names":[],"sources":["../../src/Gui/NotificationManager.ts"],"sourcesContent":["import { signal, animatedSignal } from \"canvasengine\";\n\nexport type NotificationType = \"info\" | \"warn\" | \"error\";\n\nexport interface NotificationPayload {\n message: string;\n type?: NotificationType;\n icon?: string;\n time?: number;\n sound?: string;\n}\n\nexport interface NotificationItem extends NotificationPayload {\n id: number;\n opacity: any;\n offset: any;\n layoutY: any;\n removing: boolean;\n}\n\nconst DEFAULT_DURATION = 220;\n\nexport class NotificationManager {\n stack = signal<NotificationItem[]>([]);\n private _counter = 0;\n\n add(payload: NotificationPayload, engine?: { playSound?: (id: string) => void }) {\n const id = ++this._counter;\n const opacity = animatedSignal(0, { duration: DEFAULT_DURATION });\n const offset = animatedSignal(12, { duration: DEFAULT_DURATION });\n const layoutY = animatedSignal(0, { duration: DEFAULT_DURATION });\n const item: NotificationItem = {\n id,\n message: payload.message,\n type: payload.type || \"info\",\n icon: payload.icon,\n time: payload.time,\n sound: payload.sound,\n opacity,\n offset,\n layoutY,\n removing: false,\n };\n this.stack.update((list) => [...list, item]);\n opacity.set(1);\n offset.set(0);\n\n if (payload.sound && engine?.playSound) {\n engine.playSound(payload.sound);\n }\n\n const delay = typeof payload.time === \"number\" ? payload.time : 2000;\n setTimeout(() => {\n this.remove(id);\n }, delay);\n }\n\n remove(id: number) {\n const list = this.stack();\n const item = list.find((it) => it.id === id);\n if (!item || item.removing) return;\n item.removing = true;\n item.opacity.set(0);\n item.offset.set(-8);\n setTimeout(() => {\n this.stack.update((items) => items.filter((it) => it.id !== id));\n }, DEFAULT_DURATION);\n }\n}\n"],"mappings":";;AAoBA,IAAM,mBAAmB;AAEzB,IAAa,sBAAb,MAAiC;;eACvB,OAA2B,EAAE,CAAC;kBACnB;;CAEnB,IAAI,SAA8B,QAA+C;EAC/E,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,UAAU,eAAe,GAAG,EAAE,UAAU,kBAAkB,CAAC;EACjE,MAAM,SAAS,eAAe,IAAI,EAAE,UAAU,kBAAkB,CAAC;EACjE,MAAM,UAAU,eAAe,GAAG,EAAE,UAAU,kBAAkB,CAAC;EACjE,MAAM,OAAyB;GAC7B;GACA,SAAS,QAAQ;GACjB,MAAM,QAAQ,QAAQ;GACtB,MAAM,QAAQ;GACd,MAAM,QAAQ;GACd,OAAO,QAAQ;GACf;GACA;GACA;GACA,UAAU;GACX;AACD,OAAK,MAAM,QAAQ,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC;AAC5C,UAAQ,IAAI,EAAE;AACd,SAAO,IAAI,EAAE;AAEb,MAAI,QAAQ,SAAS,QAAQ,UAC3B,QAAO,UAAU,QAAQ,MAAM;EAGjC,MAAM,QAAQ,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO;AAChE,mBAAiB;AACf,QAAK,OAAO,GAAG;KACd,MAAM;;CAGX,OAAO,IAAY;EAEjB,MAAM,OADO,KAAK,OAAO,CACP,MAAM,OAAO,GAAG,OAAO,GAAG;AAC5C,MAAI,CAAC,QAAQ,KAAK,SAAU;AAC5B,OAAK,WAAW;AAChB,OAAK,QAAQ,IAAI,EAAE;AACnB,OAAK,OAAO,IAAI,GAAG;AACnB,mBAAiB;AACf,QAAK,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAAO,GAAG,OAAO,GAAG,CAAC;KAC/D,iBAAiB"}
@@ -0,0 +1,97 @@
1
+ import { RpgClientEngine } from './RpgClientEngine';
2
+ /**
3
+ * RpgResource class
4
+ *
5
+ * Provides a unified API to access resource file links (images and sounds) in the game.
6
+ * Resources are stored as Maps of resource IDs to file paths/URLs.
7
+ *
8
+ * ## Design
9
+ *
10
+ * RpgResource acts as a facade over the engine's resource storage, providing
11
+ * easy access to resource file links. It maintains Maps that are synchronized
12
+ * with the engine's internal storage, but only stores the file paths/URLs,
13
+ * not the full resource objects.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { RpgResource } from '@rpgjs/client'
18
+ *
19
+ * // Get spritesheet image link
20
+ * const imageLink = RpgResource.spritesheets.get('hero')
21
+ *
22
+ * // Get sound file link
23
+ * const soundLink = RpgResource.sounds.get('town-music')
24
+ *
25
+ * // Set a new resource link
26
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
27
+ * ```
28
+ */
29
+ export declare class RpgResource {
30
+ private static engine;
31
+ private static _spritesheets;
32
+ private static _sounds;
33
+ /**
34
+ * Initialize RpgResource with the engine instance
35
+ *
36
+ * This is called automatically by the engine during initialization.
37
+ * It synchronizes the resource Maps with the engine's internal storage.
38
+ *
39
+ * @param engine - The RpgClientEngine instance
40
+ */
41
+ static init(engine: RpgClientEngine): void;
42
+ /**
43
+ * Synchronize resource Maps with the engine's internal storage
44
+ *
45
+ * Extracts file links from spritesheets and sounds stored in the engine
46
+ * and updates the Maps accordingly.
47
+ *
48
+ * @private
49
+ */
50
+ private static syncResources;
51
+ /**
52
+ * Get/Set image links for spritesheets
53
+ *
54
+ * Map of spritesheet IDs to their image file paths/URLs.
55
+ * This Map is synchronized with the engine's spritesheet storage.
56
+ *
57
+ * @type {Map<string, string>}
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // Get an image link
62
+ * const imageLink = RpgResource.spritesheets.get('hero')
63
+ *
64
+ * // Set a new image link
65
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
66
+ *
67
+ * // Check if a spritesheet exists
68
+ * if (RpgResource.spritesheets.has('monster')) {
69
+ * const link = RpgResource.spritesheets.get('monster')
70
+ * }
71
+ * ```
72
+ */
73
+ static get spritesheets(): Map<string, string>;
74
+ /**
75
+ * Get/Set sound file links
76
+ *
77
+ * Map of sound IDs to their audio file paths/URLs.
78
+ * This Map is synchronized with the engine's sound storage.
79
+ *
80
+ * @type {Map<string, string>}
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Get a sound link
85
+ * const soundLink = RpgResource.sounds.get('town-music')
86
+ *
87
+ * // Set a new sound link
88
+ * RpgResource.sounds.set('new-sound', './assets/new-sound.ogg')
89
+ *
90
+ * // Iterate over all sounds
91
+ * RpgResource.sounds.forEach((link, id) => {
92
+ * console.log(`Sound ${id}: ${link}`)
93
+ * })
94
+ * ```
95
+ */
96
+ static get sounds(): Map<string, string>;
97
+ }
@@ -0,0 +1,133 @@
1
+ //#region src/Resource.ts
2
+ /**
3
+ * RpgResource class
4
+ *
5
+ * Provides a unified API to access resource file links (images and sounds) in the game.
6
+ * Resources are stored as Maps of resource IDs to file paths/URLs.
7
+ *
8
+ * ## Design
9
+ *
10
+ * RpgResource acts as a facade over the engine's resource storage, providing
11
+ * easy access to resource file links. It maintains Maps that are synchronized
12
+ * with the engine's internal storage, but only stores the file paths/URLs,
13
+ * not the full resource objects.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { RpgResource } from '@rpgjs/client'
18
+ *
19
+ * // Get spritesheet image link
20
+ * const imageLink = RpgResource.spritesheets.get('hero')
21
+ *
22
+ * // Get sound file link
23
+ * const soundLink = RpgResource.sounds.get('town-music')
24
+ *
25
+ * // Set a new resource link
26
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
27
+ * ```
28
+ */
29
+ var RpgResource = class RpgResource {
30
+ static {
31
+ this.engine = null;
32
+ }
33
+ static {
34
+ this._spritesheets = /* @__PURE__ */ new Map();
35
+ }
36
+ static {
37
+ this._sounds = /* @__PURE__ */ new Map();
38
+ }
39
+ /**
40
+ * Initialize RpgResource with the engine instance
41
+ *
42
+ * This is called automatically by the engine during initialization.
43
+ * It synchronizes the resource Maps with the engine's internal storage.
44
+ *
45
+ * @param engine - The RpgClientEngine instance
46
+ */
47
+ static init(engine) {
48
+ RpgResource.engine = engine;
49
+ RpgResource.syncResources();
50
+ }
51
+ /**
52
+ * Synchronize resource Maps with the engine's internal storage
53
+ *
54
+ * Extracts file links from spritesheets and sounds stored in the engine
55
+ * and updates the Maps accordingly.
56
+ *
57
+ * @private
58
+ */
59
+ static syncResources() {
60
+ if (!RpgResource.engine) return;
61
+ RpgResource._spritesheets.clear();
62
+ RpgResource.engine.spritesheets.forEach((spritesheet, id) => {
63
+ const imageLink = spritesheet?.image || spritesheet?.imageSource || void 0;
64
+ if (imageLink) RpgResource._spritesheets.set(id, imageLink);
65
+ });
66
+ RpgResource._sounds.clear();
67
+ RpgResource.engine.sounds.forEach((sound, id) => {
68
+ let soundLink;
69
+ if (sound && typeof sound === "object") {
70
+ if (sound._src && Array.isArray(sound._src) && sound._src.length > 0) soundLink = sound._src[0];
71
+ else if (sound.src && typeof sound.src === "string") soundLink = sound.src;
72
+ else if (sound.src && Array.isArray(sound.src) && sound.src.length > 0) soundLink = sound.src[0];
73
+ }
74
+ if (soundLink) RpgResource._sounds.set(id, soundLink);
75
+ });
76
+ }
77
+ /**
78
+ * Get/Set image links for spritesheets
79
+ *
80
+ * Map of spritesheet IDs to their image file paths/URLs.
81
+ * This Map is synchronized with the engine's spritesheet storage.
82
+ *
83
+ * @type {Map<string, string>}
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * // Get an image link
88
+ * const imageLink = RpgResource.spritesheets.get('hero')
89
+ *
90
+ * // Set a new image link
91
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
92
+ *
93
+ * // Check if a spritesheet exists
94
+ * if (RpgResource.spritesheets.has('monster')) {
95
+ * const link = RpgResource.spritesheets.get('monster')
96
+ * }
97
+ * ```
98
+ */
99
+ static get spritesheets() {
100
+ RpgResource.syncResources();
101
+ return RpgResource._spritesheets;
102
+ }
103
+ /**
104
+ * Get/Set sound file links
105
+ *
106
+ * Map of sound IDs to their audio file paths/URLs.
107
+ * This Map is synchronized with the engine's sound storage.
108
+ *
109
+ * @type {Map<string, string>}
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * // Get a sound link
114
+ * const soundLink = RpgResource.sounds.get('town-music')
115
+ *
116
+ * // Set a new sound link
117
+ * RpgResource.sounds.set('new-sound', './assets/new-sound.ogg')
118
+ *
119
+ * // Iterate over all sounds
120
+ * RpgResource.sounds.forEach((link, id) => {
121
+ * console.log(`Sound ${id}: ${link}`)
122
+ * })
123
+ * ```
124
+ */
125
+ static get sounds() {
126
+ RpgResource.syncResources();
127
+ return RpgResource._sounds;
128
+ }
129
+ };
130
+ //#endregion
131
+ export { RpgResource };
132
+
133
+ //# sourceMappingURL=Resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Resource.js","names":[],"sources":["../src/Resource.ts"],"sourcesContent":["import { RpgClientEngine } from './RpgClientEngine';\n\n/**\n * RpgResource class\n * \n * Provides a unified API to access resource file links (images and sounds) in the game.\n * Resources are stored as Maps of resource IDs to file paths/URLs.\n * \n * ## Design\n * \n * RpgResource acts as a facade over the engine's resource storage, providing\n * easy access to resource file links. It maintains Maps that are synchronized\n * with the engine's internal storage, but only stores the file paths/URLs,\n * not the full resource objects.\n * \n * @example\n * ```ts\n * import { RpgResource } from '@rpgjs/client'\n * \n * // Get spritesheet image link\n * const imageLink = RpgResource.spritesheets.get('hero')\n * \n * // Get sound file link\n * const soundLink = RpgResource.sounds.get('town-music')\n * \n * // Set a new resource link\n * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')\n * ```\n */\nexport class RpgResource {\n private static engine: RpgClientEngine | null = null;\n private static _spritesheets: Map<string, string> = new Map();\n private static _sounds: Map<string, string> = new Map();\n\n /**\n * Initialize RpgResource with the engine instance\n * \n * This is called automatically by the engine during initialization.\n * It synchronizes the resource Maps with the engine's internal storage.\n * \n * @param engine - The RpgClientEngine instance\n */\n static init(engine: RpgClientEngine): void {\n RpgResource.engine = engine;\n RpgResource.syncResources();\n }\n\n /**\n * Synchronize resource Maps with the engine's internal storage\n * \n * Extracts file links from spritesheets and sounds stored in the engine\n * and updates the Maps accordingly.\n * \n * @private\n */\n private static syncResources(): void {\n if (!RpgResource.engine) {\n return;\n }\n\n // Sync spritesheets\n RpgResource._spritesheets.clear();\n RpgResource.engine.spritesheets.forEach((spritesheet, id) => {\n // Extract image path from spritesheet\n const imageLink = spritesheet?.image || spritesheet?.imageSource || undefined;\n if (imageLink) {\n RpgResource._spritesheets.set(id, imageLink);\n }\n });\n\n // Sync sounds\n RpgResource._sounds.clear();\n RpgResource.engine.sounds.forEach((sound, id) => {\n // Extract src path from sound\n let soundLink: string | undefined;\n \n // If it's a Howler instance, try to get src from _src or src property\n if (sound && typeof sound === 'object') {\n if (sound._src && Array.isArray(sound._src) && sound._src.length > 0) {\n soundLink = sound._src[0];\n } else if (sound.src && typeof sound.src === 'string') {\n soundLink = sound.src;\n } else if (sound.src && Array.isArray(sound.src) && sound.src.length > 0) {\n soundLink = sound.src[0];\n }\n }\n \n if (soundLink) {\n RpgResource._sounds.set(id, soundLink);\n }\n });\n }\n\n /**\n * Get/Set image links for spritesheets\n * \n * Map of spritesheet IDs to their image file paths/URLs.\n * This Map is synchronized with the engine's spritesheet storage.\n * \n * @type {Map<string, string>}\n * \n * @example\n * ```ts\n * // Get an image link\n * const imageLink = RpgResource.spritesheets.get('hero')\n * \n * // Set a new image link\n * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')\n * \n * // Check if a spritesheet exists\n * if (RpgResource.spritesheets.has('monster')) {\n * const link = RpgResource.spritesheets.get('monster')\n * }\n * ```\n */\n static get spritesheets(): Map<string, string> {\n // Sync before returning to ensure we have the latest data\n RpgResource.syncResources();\n return RpgResource._spritesheets;\n }\n\n /**\n * Get/Set sound file links\n * \n * Map of sound IDs to their audio file paths/URLs.\n * This Map is synchronized with the engine's sound storage.\n * \n * @type {Map<string, string>}\n * \n * @example\n * ```ts\n * // Get a sound link\n * const soundLink = RpgResource.sounds.get('town-music')\n * \n * // Set a new sound link\n * RpgResource.sounds.set('new-sound', './assets/new-sound.ogg')\n * \n * // Iterate over all sounds\n * RpgResource.sounds.forEach((link, id) => {\n * console.log(`Sound ${id}: ${link}`)\n * })\n * ```\n */\n static get sounds(): Map<string, string> {\n // Sync before returning to ensure we have the latest data\n RpgResource.syncResources();\n return RpgResource._sounds;\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,cAAb,MAAa,YAAY;;gBACyB;;;uCACI,IAAI,KAAK;;;iCACf,IAAI,KAAK;;;;;;;;;;CAUvD,OAAO,KAAK,QAA+B;AACzC,cAAY,SAAS;AACrB,cAAY,eAAe;;;;;;;;;;CAW7B,OAAe,gBAAsB;AACnC,MAAI,CAAC,YAAY,OACf;AAIF,cAAY,cAAc,OAAO;AACjC,cAAY,OAAO,aAAa,SAAS,aAAa,OAAO;GAE3D,MAAM,YAAY,aAAa,SAAS,aAAa,eAAe,KAAA;AACpE,OAAI,UACF,aAAY,cAAc,IAAI,IAAI,UAAU;IAE9C;AAGF,cAAY,QAAQ,OAAO;AAC3B,cAAY,OAAO,OAAO,SAAS,OAAO,OAAO;GAE/C,IAAI;AAGJ,OAAI,SAAS,OAAO,UAAU;QACxB,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,KAAK,SAAS,EACjE,aAAY,MAAM,KAAK;aACd,MAAM,OAAO,OAAO,MAAM,QAAQ,SAC3C,aAAY,MAAM;aACT,MAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,IAAI,SAAS,EACrE,aAAY,MAAM,IAAI;;AAI1B,OAAI,UACF,aAAY,QAAQ,IAAI,IAAI,UAAU;IAExC;;;;;;;;;;;;;;;;;;;;;;;;CAyBJ,WAAW,eAAoC;AAE7C,cAAY,eAAe;AAC3B,SAAO,YAAY;;;;;;;;;;;;;;;;;;;;;;;;CAyBrB,WAAW,SAA8B;AAEvC,cAAY,eAAe;AAC3B,SAAO,YAAY"}