@rpgjs/client 5.0.0-alpha.9 → 5.0.0-beta.10

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 (347) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +19 -0
  3. package/dist/Game/AnimationManager.d.ts +8 -0
  4. package/dist/Game/AnimationManager.js +35 -0
  5. package/dist/Game/AnimationManager.js.map +1 -0
  6. package/dist/Game/AnimationManager.spec.d.ts +1 -0
  7. package/dist/Game/Event.d.ts +1 -1
  8. package/dist/Game/Event.js +12 -0
  9. package/dist/Game/Event.js.map +1 -0
  10. package/dist/Game/Map.d.ts +31 -2
  11. package/dist/Game/Map.js +138 -0
  12. package/dist/Game/Map.js.map +1 -0
  13. package/dist/Game/Object.d.ts +189 -0
  14. package/dist/Game/Object.js +255 -0
  15. package/dist/Game/Object.js.map +1 -0
  16. package/dist/Game/Player.d.ts +1 -1
  17. package/dist/Game/Player.js +12 -0
  18. package/dist/Game/Player.js.map +1 -0
  19. package/dist/Gui/Gui.d.ts +192 -7
  20. package/dist/Gui/Gui.js +475 -0
  21. package/dist/Gui/Gui.js.map +1 -0
  22. package/dist/Gui/Gui.spec.d.ts +1 -0
  23. package/dist/Gui/NotificationManager.d.ts +23 -0
  24. package/dist/Gui/NotificationManager.js +49 -0
  25. package/dist/Gui/NotificationManager.js.map +1 -0
  26. package/dist/Resource.d.ts +97 -0
  27. package/dist/Resource.js +133 -0
  28. package/dist/Resource.js.map +1 -0
  29. package/dist/RpgClient.d.ts +295 -13
  30. package/dist/RpgClientEngine.d.ts +671 -15
  31. package/dist/RpgClientEngine.js +1442 -0
  32. package/dist/RpgClientEngine.js.map +1 -0
  33. package/dist/Sound.d.ts +199 -0
  34. package/dist/Sound.js +167 -0
  35. package/dist/Sound.js.map +1 -0
  36. package/dist/_virtual/_@oxc-project_runtime@0.130.0/helpers/decorate.js +9 -0
  37. package/dist/_virtual/_@oxc-project_runtime@0.130.0/helpers/decorateMetadata.js +6 -0
  38. package/dist/components/animations/animation.ce.js +23 -0
  39. package/dist/components/animations/animation.ce.js.map +1 -0
  40. package/dist/components/animations/hit.ce.js +64 -0
  41. package/dist/components/animations/hit.ce.js.map +1 -0
  42. package/dist/components/animations/index.d.ts +4 -0
  43. package/dist/components/animations/index.js +11 -0
  44. package/dist/components/animations/index.js.map +1 -0
  45. package/dist/components/character.ce.js +572 -0
  46. package/dist/components/character.ce.js.map +1 -0
  47. package/dist/components/dynamics/bar.ce.js +96 -0
  48. package/dist/components/dynamics/bar.ce.js.map +1 -0
  49. package/dist/components/dynamics/image.ce.js +23 -0
  50. package/dist/components/dynamics/image.ce.js.map +1 -0
  51. package/dist/components/dynamics/parse-value.d.ts +4 -0
  52. package/dist/components/dynamics/parse-value.js +63 -0
  53. package/dist/components/dynamics/parse-value.js.map +1 -0
  54. package/dist/components/dynamics/parse-value.spec.d.ts +1 -0
  55. package/dist/components/dynamics/shape-utils.d.ts +16 -0
  56. package/dist/components/dynamics/shape-utils.js +73 -0
  57. package/dist/components/dynamics/shape-utils.js.map +1 -0
  58. package/dist/components/dynamics/shape-utils.spec.d.ts +1 -0
  59. package/dist/components/dynamics/shape.ce.js +83 -0
  60. package/dist/components/dynamics/shape.ce.js.map +1 -0
  61. package/dist/components/dynamics/text.ce.js +50 -0
  62. package/dist/components/dynamics/text.ce.js.map +1 -0
  63. package/dist/components/gui/box.ce.js +26 -0
  64. package/dist/components/gui/box.ce.js.map +1 -0
  65. package/dist/components/gui/dialogbox/index.ce.js +198 -0
  66. package/dist/components/gui/dialogbox/index.ce.js.map +1 -0
  67. package/dist/components/gui/gameover.ce.js +169 -0
  68. package/dist/components/gui/gameover.ce.js.map +1 -0
  69. package/dist/components/gui/hud/hud.ce.js +83 -0
  70. package/dist/components/gui/hud/hud.ce.js.map +1 -0
  71. package/dist/components/gui/index.d.ts +15 -3
  72. package/dist/components/gui/index.js +14 -0
  73. package/dist/components/gui/menu/equip-menu.ce.js +427 -0
  74. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -0
  75. package/dist/components/gui/menu/exit-menu.ce.js +55 -0
  76. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -0
  77. package/dist/components/gui/menu/items-menu.ce.js +326 -0
  78. package/dist/components/gui/menu/items-menu.ce.js.map +1 -0
  79. package/dist/components/gui/menu/main-menu.ce.js +399 -0
  80. package/dist/components/gui/menu/main-menu.ce.js.map +1 -0
  81. package/dist/components/gui/menu/options-menu.ce.js +49 -0
  82. package/dist/components/gui/menu/options-menu.ce.js.map +1 -0
  83. package/dist/components/gui/menu/skills-menu.ce.js +102 -0
  84. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -0
  85. package/dist/components/gui/mobile/index.d.ts +8 -0
  86. package/dist/components/gui/mobile/index.js +21 -0
  87. package/dist/components/gui/mobile/index.js.map +1 -0
  88. package/dist/components/gui/mobile/mobile.ce.js +79 -0
  89. package/dist/components/gui/mobile/mobile.ce.js.map +1 -0
  90. package/dist/components/gui/notification/notification.ce.js +62 -0
  91. package/dist/components/gui/notification/notification.ce.js.map +1 -0
  92. package/dist/components/gui/save-load.ce.js +211 -0
  93. package/dist/components/gui/save-load.ce.js.map +1 -0
  94. package/dist/components/gui/shop/shop.ce.js +614 -0
  95. package/dist/components/gui/shop/shop.ce.js.map +1 -0
  96. package/dist/components/gui/title-screen.ce.js +164 -0
  97. package/dist/components/gui/title-screen.ce.js.map +1 -0
  98. package/dist/components/index.d.ts +1 -0
  99. package/dist/components/index.js +4 -0
  100. package/dist/components/player-components-utils.d.ts +67 -0
  101. package/dist/components/player-components-utils.js +162 -0
  102. package/dist/components/player-components-utils.js.map +1 -0
  103. package/dist/components/player-components-utils.spec.d.ts +1 -0
  104. package/dist/components/player-components.ce.js +188 -0
  105. package/dist/components/player-components.ce.js.map +1 -0
  106. package/dist/components/prebuilt/hp-bar.ce.js +113 -0
  107. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -0
  108. package/dist/components/prebuilt/index.d.ts +19 -0
  109. package/dist/components/prebuilt/index.js +2 -0
  110. package/dist/components/prebuilt/light-halo.ce.js +70 -0
  111. package/dist/components/prebuilt/light-halo.ce.js.map +1 -0
  112. package/dist/components/scenes/canvas.ce.js +196 -0
  113. package/dist/components/scenes/canvas.ce.js.map +1 -0
  114. package/dist/components/scenes/draw-map.ce.js +79 -0
  115. package/dist/components/scenes/draw-map.ce.js.map +1 -0
  116. package/dist/components/scenes/event-layer.ce.js +29 -0
  117. package/dist/components/scenes/event-layer.ce.js.map +1 -0
  118. package/dist/core/inject.js +18 -0
  119. package/dist/core/inject.js.map +1 -0
  120. package/dist/core/setup.js +16 -0
  121. package/dist/core/setup.js.map +1 -0
  122. package/dist/decorators/spritesheet.d.ts +1 -0
  123. package/dist/decorators/spritesheet.js +11 -0
  124. package/dist/decorators/spritesheet.js.map +1 -0
  125. package/dist/index.d.ts +16 -1
  126. package/dist/index.js +45 -14
  127. package/dist/module.d.ts +43 -4
  128. package/dist/module.js +179 -0
  129. package/dist/module.js.map +1 -0
  130. package/dist/node_modules/.pnpm/@signe_di@3.0.1/node_modules/@signe/di/dist/index.js +167 -0
  131. package/dist/node_modules/.pnpm/@signe_di@3.0.1/node_modules/@signe/di/dist/index.js.map +1 -0
  132. package/dist/node_modules/.pnpm/@signe_reactive@3.0.1/node_modules/@signe/reactive/dist/index.js +239 -0
  133. package/dist/node_modules/.pnpm/@signe_reactive@3.0.1/node_modules/@signe/reactive/dist/index.js.map +1 -0
  134. package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/chunk-EUXUH3YW.js +13 -0
  135. package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/chunk-EUXUH3YW.js.map +1 -0
  136. package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/index.js +696 -0
  137. package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/index.js.map +1 -0
  138. package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/client/index.js +44 -0
  139. package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/client/index.js.map +1 -0
  140. package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/index.js +241 -0
  141. package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/index.js.map +1 -0
  142. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js +115 -0
  143. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +1 -0
  144. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js +401 -0
  145. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +1 -0
  146. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +2 -0
  147. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js +3756 -0
  148. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +1 -0
  149. package/dist/presets/animation.d.ts +31 -0
  150. package/dist/presets/animation.js +39 -0
  151. package/dist/presets/animation.js.map +1 -0
  152. package/dist/presets/faceset.d.ts +30 -0
  153. package/dist/presets/faceset.js +51 -0
  154. package/dist/presets/faceset.js.map +1 -0
  155. package/dist/presets/icon.d.ts +20 -0
  156. package/dist/presets/icon.js +15 -0
  157. package/dist/presets/icon.js.map +1 -0
  158. package/dist/presets/index.d.ts +123 -0
  159. package/dist/presets/index.js +17 -0
  160. package/dist/presets/index.js.map +1 -0
  161. package/dist/presets/lpc.d.ts +89 -0
  162. package/dist/presets/lpc.js +98 -0
  163. package/dist/presets/lpc.js.map +1 -0
  164. package/dist/presets/rmspritesheet.js +42 -0
  165. package/dist/presets/rmspritesheet.js.map +1 -0
  166. package/dist/services/AbstractSocket.d.ts +9 -5
  167. package/dist/services/AbstractSocket.js +11 -0
  168. package/dist/services/AbstractSocket.js.map +1 -0
  169. package/dist/services/keyboardControls.d.ts +15 -0
  170. package/dist/services/keyboardControls.js +23 -0
  171. package/dist/services/keyboardControls.js.map +1 -0
  172. package/dist/services/loadMap.d.ts +6 -0
  173. package/dist/services/loadMap.js +123 -0
  174. package/dist/services/loadMap.js.map +1 -0
  175. package/dist/services/mmorpg.d.ts +21 -9
  176. package/dist/services/mmorpg.js +136 -0
  177. package/dist/services/mmorpg.js.map +1 -0
  178. package/dist/services/save.d.ts +19 -0
  179. package/dist/services/save.js +77 -0
  180. package/dist/services/save.js.map +1 -0
  181. package/dist/services/save.spec.d.ts +1 -0
  182. package/dist/services/standalone.d.ts +67 -7
  183. package/dist/services/standalone.js +168 -0
  184. package/dist/services/standalone.js.map +1 -0
  185. package/dist/utils/getEntityProp.d.ts +39 -0
  186. package/dist/utils/getEntityProp.js +53 -0
  187. package/dist/utils/getEntityProp.js.map +1 -0
  188. package/dist/utils/getEntityProp.spec.d.ts +1 -0
  189. package/dist/utils/readPropValue.d.ts +2 -0
  190. package/dist/utils/readPropValue.js +13 -0
  191. package/dist/utils/readPropValue.js.map +1 -0
  192. package/package.json +14 -11
  193. package/src/Game/AnimationManager.spec.ts +30 -0
  194. package/src/Game/AnimationManager.ts +33 -0
  195. package/src/Game/Event.ts +1 -1
  196. package/src/Game/Map.ts +184 -3
  197. package/src/Game/Object.ts +409 -14
  198. package/src/Game/Player.ts +1 -1
  199. package/src/Gui/Gui.spec.ts +273 -0
  200. package/src/Gui/Gui.ts +566 -23
  201. package/src/Gui/NotificationManager.ts +69 -0
  202. package/src/Resource.ts +149 -0
  203. package/src/RpgClient.ts +309 -14
  204. package/src/RpgClientEngine.ts +1790 -63
  205. package/src/Sound.ts +253 -0
  206. package/src/components/{effects → animations}/animation.ce +3 -6
  207. package/src/components/{effects → animations}/index.ts +1 -1
  208. package/src/components/character.ce +801 -59
  209. package/src/components/dynamics/bar.ce +87 -0
  210. package/src/components/dynamics/image.ce +20 -0
  211. package/src/components/dynamics/parse-value.spec.ts +83 -0
  212. package/src/components/dynamics/parse-value.ts +154 -0
  213. package/src/components/dynamics/shape-utils.spec.ts +46 -0
  214. package/src/components/dynamics/shape-utils.ts +61 -0
  215. package/src/components/dynamics/shape.ce +89 -0
  216. package/src/components/dynamics/text.ce +68 -0
  217. package/src/components/gui/box.ce +17 -0
  218. package/src/components/gui/dialogbox/index.ce +213 -187
  219. package/src/components/gui/gameover.ce +158 -0
  220. package/src/components/gui/hud/hud.ce +61 -0
  221. package/src/components/gui/index.ts +30 -4
  222. package/src/components/gui/menu/equip-menu.ce +410 -0
  223. package/src/components/gui/menu/exit-menu.ce +41 -0
  224. package/src/components/gui/menu/items-menu.ce +317 -0
  225. package/src/components/gui/menu/main-menu.ce +294 -0
  226. package/src/components/gui/menu/options-menu.ce +35 -0
  227. package/src/components/gui/menu/skills-menu.ce +83 -0
  228. package/src/components/gui/mobile/index.ts +24 -0
  229. package/src/components/gui/mobile/mobile.ce +80 -0
  230. package/src/components/gui/notification/notification.ce +51 -0
  231. package/src/components/gui/save-load.ce +208 -0
  232. package/src/components/gui/shop/shop.ce +493 -0
  233. package/src/components/gui/title-screen.ce +163 -0
  234. package/src/components/index.ts +3 -0
  235. package/src/components/player-components-utils.spec.ts +109 -0
  236. package/src/components/player-components-utils.ts +205 -0
  237. package/src/components/player-components.ce +221 -0
  238. package/src/components/prebuilt/hp-bar.ce +255 -0
  239. package/src/components/prebuilt/index.ts +24 -0
  240. package/src/components/prebuilt/light-halo.ce +148 -0
  241. package/src/components/scenes/canvas.ce +185 -21
  242. package/src/components/scenes/draw-map.ce +55 -21
  243. package/src/components/scenes/event-layer.ce +8 -2
  244. package/src/components/scenes/transition.ce +60 -0
  245. package/src/core/setup.ts +2 -2
  246. package/src/decorators/spritesheet.ts +8 -0
  247. package/src/index.ts +17 -2
  248. package/src/module.ts +132 -10
  249. package/src/presets/animation.ts +46 -0
  250. package/src/presets/faceset.ts +60 -0
  251. package/src/presets/icon.ts +17 -0
  252. package/src/presets/index.ts +9 -1
  253. package/src/presets/lpc.ts +108 -0
  254. package/src/services/AbstractSocket.ts +10 -2
  255. package/src/services/keyboardControls.ts +20 -0
  256. package/src/services/loadMap.ts +3 -1
  257. package/src/services/mmorpg.ts +106 -12
  258. package/src/services/save.spec.ts +127 -0
  259. package/src/services/save.ts +103 -0
  260. package/src/services/standalone.ts +110 -18
  261. package/src/utils/getEntityProp.spec.ts +96 -0
  262. package/src/utils/getEntityProp.ts +88 -0
  263. package/src/utils/readPropValue.ts +16 -0
  264. package/vite.config.ts +4 -2
  265. package/dist/Game/EffectManager.d.ts +0 -5
  266. package/dist/components/effects/index.d.ts +0 -4
  267. package/dist/index.js.map +0 -1
  268. package/dist/index10.js +0 -8
  269. package/dist/index10.js.map +0 -1
  270. package/dist/index11.js +0 -10
  271. package/dist/index11.js.map +0 -1
  272. package/dist/index12.js +0 -8
  273. package/dist/index12.js.map +0 -1
  274. package/dist/index13.js +0 -17
  275. package/dist/index13.js.map +0 -1
  276. package/dist/index14.js +0 -107
  277. package/dist/index14.js.map +0 -1
  278. package/dist/index15.js +0 -50
  279. package/dist/index15.js.map +0 -1
  280. package/dist/index16.js +0 -191
  281. package/dist/index16.js.map +0 -1
  282. package/dist/index17.js +0 -9
  283. package/dist/index17.js.map +0 -1
  284. package/dist/index18.js +0 -387
  285. package/dist/index18.js.map +0 -1
  286. package/dist/index19.js +0 -31
  287. package/dist/index19.js.map +0 -1
  288. package/dist/index2.js +0 -181
  289. package/dist/index2.js.map +0 -1
  290. package/dist/index20.js +0 -24
  291. package/dist/index20.js.map +0 -1
  292. package/dist/index21.js +0 -2421
  293. package/dist/index21.js.map +0 -1
  294. package/dist/index22.js +0 -114
  295. package/dist/index22.js.map +0 -1
  296. package/dist/index23.js +0 -109
  297. package/dist/index23.js.map +0 -1
  298. package/dist/index24.js +0 -71
  299. package/dist/index24.js.map +0 -1
  300. package/dist/index25.js +0 -21
  301. package/dist/index25.js.map +0 -1
  302. package/dist/index26.js +0 -41
  303. package/dist/index26.js.map +0 -1
  304. package/dist/index27.js +0 -5
  305. package/dist/index27.js.map +0 -1
  306. package/dist/index28.js +0 -322
  307. package/dist/index28.js.map +0 -1
  308. package/dist/index29.js +0 -27
  309. package/dist/index29.js.map +0 -1
  310. package/dist/index3.js +0 -87
  311. package/dist/index3.js.map +0 -1
  312. package/dist/index30.js +0 -11
  313. package/dist/index30.js.map +0 -1
  314. package/dist/index31.js +0 -11
  315. package/dist/index31.js.map +0 -1
  316. package/dist/index32.js +0 -174
  317. package/dist/index32.js.map +0 -1
  318. package/dist/index33.js +0 -501
  319. package/dist/index33.js.map +0 -1
  320. package/dist/index34.js +0 -12
  321. package/dist/index34.js.map +0 -1
  322. package/dist/index35.js +0 -4403
  323. package/dist/index35.js.map +0 -1
  324. package/dist/index36.js +0 -316
  325. package/dist/index36.js.map +0 -1
  326. package/dist/index37.js +0 -61
  327. package/dist/index37.js.map +0 -1
  328. package/dist/index38.js +0 -20
  329. package/dist/index38.js.map +0 -1
  330. package/dist/index39.js +0 -20
  331. package/dist/index39.js.map +0 -1
  332. package/dist/index4.js +0 -67
  333. package/dist/index4.js.map +0 -1
  334. package/dist/index5.js +0 -16
  335. package/dist/index5.js.map +0 -1
  336. package/dist/index6.js +0 -17
  337. package/dist/index6.js.map +0 -1
  338. package/dist/index7.js +0 -39
  339. package/dist/index7.js.map +0 -1
  340. package/dist/index8.js +0 -108
  341. package/dist/index8.js.map +0 -1
  342. package/dist/index9.js +0 -76
  343. package/dist/index9.js.map +0 -1
  344. package/src/Game/EffectManager.ts +0 -20
  345. package/src/components/gui/dialogbox/itemMenu.ce +0 -23
  346. package/src/components/gui/dialogbox/selection.ce +0 -67
  347. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -0,0 +1,410 @@
1
+ <DOMContainer width="100%" height="100%">
2
+ <div class="rpg-ui-menu-panel rpg-ui-panel">
3
+ <div class="rpg-ui-menu-panel-header">Equip</div>
4
+ <div class="rpg-ui-menu-panel-body rpg-ui-menu-panel-body-stacked">
5
+ <div>
6
+ <div class="rpg-ui-menu-panel-details rpg-ui-panel">
7
+ <div class="rpg-ui-menu-panel-hero">
8
+ <div class="rpg-ui-menu-panel-hero-icon">
9
+ <DOMSprite
10
+ sheet={iconSheet(detailsItem()?.icon)}
11
+ playing="default"
12
+ width="48px"
13
+ height="48px"
14
+ objectFit="contain"
15
+ />
16
+ </div>
17
+ <div>
18
+ <div class="rpg-ui-menu-panel-details-title">
19
+ {detailsItem()?.name || currentSlot()?.label || "Equip"}
20
+ </div>
21
+ <div class="rpg-ui-menu-panel-details-desc">
22
+ {detailsItem()?.description || ""}
23
+ </div>
24
+ @if (displayStats().length > 0) {
25
+ <div class="rpg-ui-equip-stats">
26
+ @for ((stat,index) of displayStats) {
27
+ <div class="rpg-ui-equip-stat" class={{positive: stat.delta > 0, negative: stat.delta < 0}}>
28
+ <div class="rpg-ui-equip-stat-key">{stat.label}</div>
29
+ <div class="rpg-ui-equip-stat-value">
30
+ {stat.delta > 0 ? "+" : ""}{stat.delta}
31
+ </div>
32
+ @if (stat.current) {
33
+ <div class="rpg-ui-equip-stat-current">{stat.current} -> {stat.next}</div>
34
+ }
35
+ </div>
36
+ }
37
+ </div>
38
+ }
39
+ <div class="rpg-ui-menu-panel-details-meta">
40
+ <span>{equippedText()}</span>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="rpg-ui-menu-panel-list rpg-ui-menu rpg-ui-menu-panel-list-full">
48
+ <div class="rpg-ui-menu-tabs">
49
+ @for ((tab,tabIndex) of slotList) {
50
+ <div
51
+ class="rpg-ui-menu-tab"
52
+ class={{active: selectedTab() === tabIndex}}
53
+ tabindex={tabIndex}
54
+ click={selectTab(tabIndex)}
55
+ >{tab.label}</div>
56
+ }
57
+ </div>
58
+ <Navigation tabindex={selectedItem} controls={controls}>
59
+ @for ((entry,index) of listEntries) {
60
+ <div
61
+ class="rpg-ui-menu-item rpg-ui-menu-row"
62
+ data-selected={selectedItem() === index ? "true" : "false"}
63
+ tabindex={index}
64
+ click={selectItem(index)}
65
+ >
66
+ <div class="rpg-ui-menu-row-main">
67
+ <div class="rpg-ui-menu-row-icon">
68
+ @if (entry?.icon) {
69
+ <DOMSprite
70
+ sheet={iconSheet(entry.icon)}
71
+ playing="default"
72
+ width="28px"
73
+ height="28px"
74
+ objectFit="contain"
75
+ />
76
+ }
77
+ </div>
78
+ <span>{entry.name}</span>
79
+ </div>
80
+ <span class="rpg-ui-menu-row-end">{entry.tag || ""}</span>
81
+ </div>
82
+ }
83
+ </Navigation>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </DOMContainer>
88
+
89
+ <script>
90
+ import { signal, computed, createTabindexNavigator, effect } from "canvasengine";
91
+ import { inject } from "../../../core/inject";
92
+ import { RpgClientEngine } from "../../../RpgClientEngine";
93
+
94
+ const engine = inject(RpgClientEngine);
95
+ const keyboardControls = engine.globalConfig.keyboardControls;
96
+ const currentPlayer = engine.scene.currentPlayer;
97
+
98
+ const selectedTab = signal(0);
99
+ const selectedItem = signal(0);
100
+ const { data, onInteraction, onBack } = defineProps();
101
+
102
+ const equips = computed(() => data().equips ?? data().items);
103
+ const slots = computed(() => data().slots);
104
+
105
+ const defaultSlots = [
106
+ { id: "weapon", label: "Weapon", types: ["weapon"] },
107
+ { id: "armor", label: "Armor", types: ["armor"] }
108
+ ];
109
+ const resolveProp = (value) => typeof value === "function" ? value() : value;
110
+ const safeEquips = computed(() => {
111
+ const list = resolveProp(equips);
112
+ return Array.isArray(list) ? list : [];
113
+ });
114
+ const slotList = computed(() => {
115
+ const list = resolveProp(slots);
116
+ if (Array.isArray(list) && list.length) return list;
117
+ return defaultSlots;
118
+ });
119
+
120
+ const currentSlot = computed(() => slotList()[selectedTab()]);
121
+
122
+ const equippedIds = computed(() => {
123
+ const equipped = currentPlayer().equipments?.() || [];
124
+ return new Set(equipped.map((it) => it?.id?.() ?? it?.id ?? it?.name));
125
+ });
126
+ const equippedOverrides = signal({});
127
+
128
+ effect(() => {
129
+ const next = {};
130
+ safeEquips().forEach((item) => {
131
+ if (item?.id && typeof item.equipped === "boolean") {
132
+ next[item.id] = item.equipped;
133
+ }
134
+ });
135
+ equippedOverrides.set(next);
136
+ });
137
+
138
+ const itemEquipped = (item) => {
139
+ if (!item) return false;
140
+ const overrides = equippedOverrides();
141
+ if (Object.prototype.hasOwnProperty.call(overrides, item.id)) {
142
+ return overrides[item.id];
143
+ }
144
+ if (typeof item.equipped === "boolean") return item.equipped;
145
+ return equippedIds().has(item.id);
146
+ };
147
+
148
+ const slotTypes = (slot) => {
149
+ if (!slot) return [];
150
+ if (Array.isArray(slot.types)) return slot.types;
151
+ if (slot.type) return [slot.type];
152
+ if (slot.id) return [slot.id];
153
+ return [];
154
+ };
155
+
156
+ const slotItems = computed(() => {
157
+ const slot = currentSlot();
158
+ if (!slot) return [];
159
+ const types = new Set(slotTypes(slot));
160
+ return safeEquips().filter((item) => item && types.has(item.type));
161
+ });
162
+
163
+ const currentEquippedItem = computed(() => {
164
+ const list = slotItems();
165
+ return list.find((item) => itemEquipped(item)) || null;
166
+ });
167
+
168
+ const listEntries = computed(() => {
169
+ const items = slotItems().map((item) => ({
170
+ ...item,
171
+ kind: "item",
172
+ tag: itemEquipped(item) ? "Equipped" : ""
173
+ }));
174
+ const equipped = currentEquippedItem();
175
+ if (!equipped) return items;
176
+ return [
177
+ {
178
+ id: "__unequip__",
179
+ name: "Unequip",
180
+ description: "Remove the current equipment",
181
+ kind: "unequip",
182
+ tag: ""
183
+ },
184
+ ...items
185
+ ];
186
+ });
187
+
188
+ const currentEntry = computed(() => listEntries()[selectedItem()]);
189
+ const detailsItem = computed(() => {
190
+ const entry = currentEntry();
191
+ if (entry?.kind === "item") return entry;
192
+ return currentEquippedItem();
193
+ });
194
+
195
+ const equippedText = computed(() => {
196
+ const slot = currentSlot();
197
+ if (!slot) return "";
198
+ const equipped = currentEquippedItem();
199
+ return equipped ? `${slot.label}: ${equipped.name}` : `${slot.label}: Empty`;
200
+ });
201
+ const listEmpty = computed(() => listEntries().length === 0);
202
+
203
+ const nav = createTabindexNavigator(selectedItem, { count: () => listEntries().length }, "wrap");
204
+
205
+ const playerParams = computed(() => {
206
+ const menuData = data();
207
+ if (menuData?.playerStats) return menuData.playerStats;
208
+ if (menuData?.playerParams) return menuData.playerParams;
209
+ return currentPlayer()?._param?.() || {};
210
+ });
211
+ const statOrder = ["atk", "def", "pdef", "sdef", "str", "dex", "int", "agi", "maxHp", "maxSp"];
212
+ const statLabels = {
213
+ atk: "ATK",
214
+ def: "DEF",
215
+ pdef: "PDEF",
216
+ sdef: "SDEF",
217
+ str: "STR",
218
+ dex: "DEX",
219
+ int: "INT",
220
+ agi: "AGI",
221
+ maxHp: "MAX HP",
222
+ maxSp: "MAX SP"
223
+ };
224
+
225
+ const getItemStats = (item) => {
226
+ if (!item) return {};
227
+ const stats = item.stats || item.params || {};
228
+ if (Object.keys(stats).length) return stats;
229
+ const keys = ["atk", "def", "pdef", "sdef", "str", "dex", "int", "agi", "maxHp", "maxSp"];
230
+ const direct = {};
231
+ keys.forEach((key) => {
232
+ if (item[key] !== undefined) direct[key] = item[key];
233
+ });
234
+ return direct;
235
+ };
236
+
237
+ const buildStatsList = (deltaStats) => {
238
+ const params = playerParams() || {};
239
+ const orderedKeys = statOrder.filter((key) => deltaStats[key] !== undefined);
240
+ const extraKeys = Object.keys(deltaStats).filter((key) => !statOrder.includes(key));
241
+ const keys = orderedKeys.concat(extraKeys);
242
+ const list = [];
243
+ for (const key of keys) {
244
+ const delta = deltaStats[key];
245
+ if (delta === undefined || delta === 0) continue;
246
+ let current = params[key];
247
+ if (current === undefined && key === "def") current = params.pdef;
248
+ const next = current !== undefined ? current + delta : undefined;
249
+ list.push({
250
+ key,
251
+ label: statLabels[key] || key.toUpperCase(),
252
+ delta,
253
+ current,
254
+ next
255
+ });
256
+ }
257
+ return list;
258
+ };
259
+
260
+ const displayStats = computed(() => {
261
+ const entry = currentEntry();
262
+ const equipped = currentEquippedItem();
263
+ if (!entry) return [];
264
+ if (entry.kind === "unequip") {
265
+
266
+ if (!equipped) return [];
267
+ const stats = getItemStats(equipped);
268
+ const delta = {};
269
+ Object.keys(stats).forEach((key) => {
270
+ delta[key] = -stats[key];
271
+ });
272
+ return buildStatsList(delta);
273
+ }
274
+ if (entry.kind === "item") {
275
+ const equippedStats = getItemStats(equipped);
276
+ const nextStats = getItemStats(entry);
277
+ const delta = {};
278
+ const keys = new Set([...Object.keys(nextStats), ...Object.keys(equippedStats)]);
279
+ keys.forEach((key) => {
280
+ delta[key] = (nextStats[key] || 0) - (equippedStats[key] || 0);
281
+ });
282
+ return buildStatsList(delta);
283
+ }
284
+ return [];
285
+ });
286
+
287
+ const applyEquipState = (slot, itemId, equip) => {
288
+ const types = slotTypes(slot);
289
+ const next = { ...equippedOverrides() };
290
+ if (types.length) {
291
+ safeEquips().forEach((item) => {
292
+ if (!item) return;
293
+ if (types.includes(item.type)) {
294
+ next[item.id] = false;
295
+ }
296
+ });
297
+ }
298
+ if (itemId) {
299
+ next[itemId] = equip;
300
+ }
301
+ equippedOverrides.set(next);
302
+ };
303
+
304
+ const commitSelection = (index) => {
305
+ const entry = listEntries()[index];
306
+ if (!entry) return;
307
+ if (entry.kind === "unequip") {
308
+ const equipped = currentEquippedItem();
309
+ if (equipped && onInteraction) {
310
+ onInteraction("equipItem", { id: equipped.id, equip: false });
311
+ }
312
+ applyEquipState(currentSlot(), equipped?.id, false);
313
+ return;
314
+ }
315
+ if (entry.kind === "item" && onInteraction) {
316
+ if (!itemEquipped(entry)) {
317
+ onInteraction("equipItem", { id: entry.id, equip: true });
318
+ }
319
+ applyEquipState(currentSlot(), entry.id, true);
320
+ }
321
+ };
322
+
323
+ function selectTab(index) {
324
+ return function() {
325
+ selectedTab.set(index);
326
+ selectedItem.set(0);
327
+ }
328
+ }
329
+
330
+ function selectItem(index) {
331
+ return function() {
332
+ selectedItem.set(index);
333
+ commitSelection(index);
334
+ }
335
+ }
336
+
337
+ const iconSheet = (iconId) => ({
338
+ definition: engine.getSpriteSheet(iconId)
339
+ });
340
+
341
+ const controls = signal({
342
+ up: {
343
+ repeat: true,
344
+ bind: keyboardControls.up,
345
+ throttle: 150,
346
+ keyDown() {
347
+ if (!listEntries().length) return;
348
+ nav.next(-1);
349
+ }
350
+ },
351
+ left: {
352
+ repeat: true,
353
+ bind: keyboardControls.left,
354
+ throttle: 150,
355
+ keyDown() {
356
+ const tabs = slotList();
357
+ if (!tabs.length) return;
358
+ selectedTab.update((value) => (value - 1 + tabs.length) % tabs.length);
359
+ selectedItem.set(0);
360
+ }
361
+ },
362
+ right: {
363
+ repeat: true,
364
+ bind: keyboardControls.right,
365
+ throttle: 150,
366
+ keyDown() {
367
+ const tabs = slotList();
368
+ if (!tabs.length) return;
369
+ selectedTab.update((value) => (value + 1) % tabs.length);
370
+ selectedItem.set(0);
371
+ }
372
+ },
373
+ down: {
374
+ repeat: true,
375
+ bind: keyboardControls.down,
376
+ throttle: 150,
377
+ keyDown() {
378
+ if (!listEntries().length) return;
379
+ nav.next(1);
380
+ }
381
+ },
382
+ action: {
383
+ bind: keyboardControls.action,
384
+ keyDown() {
385
+ if (!listEntries().length) return;
386
+ commitSelection(selectedItem());
387
+ }
388
+ },
389
+ escape: {
390
+ bind: keyboardControls.escape,
391
+ keyDown() {
392
+ if (onBack) onBack();
393
+ }
394
+ },
395
+ gamepad: {
396
+ enabled: true
397
+ }
398
+ });
399
+
400
+ effect(() => {
401
+ const count = listEntries().length;
402
+ if (!count) {
403
+ selectedItem.set(0);
404
+ return;
405
+ }
406
+ if (selectedItem() >= count) {
407
+ selectedItem.set(count - 1);
408
+ }
409
+ });
410
+ </script>
@@ -0,0 +1,41 @@
1
+ <DOMContainer width="100%" height="100%" controls={controls}>
2
+ <div class="rpg-ui-menu-panel rpg-ui-panel">
3
+ <div class="rpg-ui-menu-panel-header">Exit</div>
4
+ <div class="rpg-ui-menu-panel-body">
5
+ <div class="rpg-ui-menu-panel-details">
6
+ <div class="rpg-ui-menu-panel-details-title">Leave the game?</div>
7
+ <div class="rpg-ui-menu-panel-details-desc">
8
+ Press Action to confirm or Escape to go back.
9
+ </div>
10
+ </div>
11
+ </div>
12
+ </div>
13
+ </DOMContainer>
14
+
15
+ <script>
16
+ import { signal } from "canvasengine";
17
+ import { inject } from "../../../core/inject";
18
+ import { RpgClientEngine } from "../../../RpgClientEngine";
19
+
20
+ const engine = inject(RpgClientEngine);
21
+ const keyboardControls = engine.globalConfig.keyboardControls;
22
+ const { onConfirm, onBack } = defineProps();
23
+
24
+ const controls = signal({
25
+ action: {
26
+ bind: keyboardControls.action,
27
+ keyDown() {
28
+ if (onConfirm) onConfirm();
29
+ }
30
+ },
31
+ escape: {
32
+ bind: keyboardControls.escape,
33
+ keyDown() {
34
+ if (onBack) onBack();
35
+ }
36
+ },
37
+ gamepad: {
38
+ enabled: true
39
+ }
40
+ });
41
+ </script>