@rpgjs/client 5.0.0-alpha.9 → 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 (304) 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 +238 -11
  26. package/dist/RpgClientEngine.d.ts +615 -14
  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 +246 -12
  176. package/src/RpgClientEngine.ts +1641 -62
  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 +387 -52
  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 +7 -0
  207. package/src/components/scenes/transition.ce +60 -0
  208. package/src/index.ts +16 -2
  209. package/src/module.ts +127 -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/vite.config.ts +4 -2
  223. package/dist/Game/EffectManager.d.ts +0 -5
  224. package/dist/components/effects/index.d.ts +0 -4
  225. package/dist/index.js.map +0 -1
  226. package/dist/index10.js +0 -8
  227. package/dist/index10.js.map +0 -1
  228. package/dist/index11.js +0 -10
  229. package/dist/index11.js.map +0 -1
  230. package/dist/index12.js +0 -8
  231. package/dist/index12.js.map +0 -1
  232. package/dist/index13.js +0 -17
  233. package/dist/index13.js.map +0 -1
  234. package/dist/index14.js +0 -107
  235. package/dist/index14.js.map +0 -1
  236. package/dist/index15.js +0 -50
  237. package/dist/index15.js.map +0 -1
  238. package/dist/index16.js +0 -191
  239. package/dist/index16.js.map +0 -1
  240. package/dist/index17.js +0 -9
  241. package/dist/index17.js.map +0 -1
  242. package/dist/index18.js +0 -387
  243. package/dist/index18.js.map +0 -1
  244. package/dist/index19.js +0 -31
  245. package/dist/index19.js.map +0 -1
  246. package/dist/index2.js +0 -181
  247. package/dist/index2.js.map +0 -1
  248. package/dist/index20.js +0 -24
  249. package/dist/index20.js.map +0 -1
  250. package/dist/index21.js +0 -2421
  251. package/dist/index21.js.map +0 -1
  252. package/dist/index22.js +0 -114
  253. package/dist/index22.js.map +0 -1
  254. package/dist/index23.js +0 -109
  255. package/dist/index23.js.map +0 -1
  256. package/dist/index24.js +0 -71
  257. package/dist/index24.js.map +0 -1
  258. package/dist/index25.js +0 -21
  259. package/dist/index25.js.map +0 -1
  260. package/dist/index26.js +0 -41
  261. package/dist/index26.js.map +0 -1
  262. package/dist/index27.js +0 -5
  263. package/dist/index27.js.map +0 -1
  264. package/dist/index28.js +0 -322
  265. package/dist/index28.js.map +0 -1
  266. package/dist/index29.js +0 -27
  267. package/dist/index29.js.map +0 -1
  268. package/dist/index3.js +0 -87
  269. package/dist/index3.js.map +0 -1
  270. package/dist/index30.js +0 -11
  271. package/dist/index30.js.map +0 -1
  272. package/dist/index31.js +0 -11
  273. package/dist/index31.js.map +0 -1
  274. package/dist/index32.js +0 -174
  275. package/dist/index32.js.map +0 -1
  276. package/dist/index33.js +0 -501
  277. package/dist/index33.js.map +0 -1
  278. package/dist/index34.js +0 -12
  279. package/dist/index34.js.map +0 -1
  280. package/dist/index35.js +0 -4403
  281. package/dist/index35.js.map +0 -1
  282. package/dist/index36.js +0 -316
  283. package/dist/index36.js.map +0 -1
  284. package/dist/index37.js +0 -61
  285. package/dist/index37.js.map +0 -1
  286. package/dist/index38.js +0 -20
  287. package/dist/index38.js.map +0 -1
  288. package/dist/index39.js +0 -20
  289. package/dist/index39.js.map +0 -1
  290. package/dist/index4.js +0 -67
  291. package/dist/index4.js.map +0 -1
  292. package/dist/index5.js +0 -16
  293. package/dist/index5.js.map +0 -1
  294. package/dist/index6.js +0 -17
  295. package/dist/index6.js.map +0 -1
  296. package/dist/index7.js +0 -39
  297. package/dist/index7.js.map +0 -1
  298. package/dist/index8.js +0 -108
  299. package/dist/index8.js.map +0 -1
  300. package/dist/index9.js +0 -76
  301. package/dist/index9.js.map +0 -1
  302. package/src/components/gui/dialogbox/itemMenu.ce +0 -23
  303. package/src/components/gui/dialogbox/selection.ce +0 -67
  304. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -0,0 +1,183 @@
1
+ <Text text={parseDynamicValue(component.value, object)} ...getComponentStyle(component) />
2
+
3
+ <script>
4
+ import { computed } from "canvasengine";
5
+ import { parseDynamicValue } from "./parse-value";
6
+
7
+ const { object } = defineProps();
8
+ const component = object._component;
9
+
10
+ /**
11
+ * Parses a numeric style value that can be a number or a string
12
+ *
13
+ * If the value is a string, it may contain dynamic references like {hp}
14
+ * which need to be parsed using parseDynamicValue. If it's a number,
15
+ * it's returned as-is wrapped in a computed.
16
+ *
17
+ * @param value - Numeric value (number or string)
18
+ * @param object - Object to resolve dynamic references from
19
+ * @returns Computed signal with the numeric value
20
+ */
21
+ const parseNumericStyleValue = (value, object) => {
22
+ if (value === undefined || value === null) {
23
+ return undefined;
24
+ }
25
+
26
+ if (typeof value === 'number') {
27
+ return value;
28
+ }
29
+
30
+ if (typeof value === 'string') {
31
+ // Check if it contains dynamic references
32
+ if (value.includes('{')) {
33
+ // Parse dynamic value and convert to number
34
+ const parsed = parseDynamicValue(value, object);
35
+ return computed(() => {
36
+ const str = parsed();
37
+ const num = parseFloat(str);
38
+ return isNaN(num) ? 0 : num;
39
+ });
40
+ } else {
41
+ // Simple string number, convert directly
42
+ const num = parseFloat(value);
43
+ return isNaN(num) ? undefined : num;
44
+ }
45
+ }
46
+
47
+ return value;
48
+ };
49
+
50
+ /**
51
+ * Maps component style properties to Canvas Engine Text component props
52
+ *
53
+ * Converts TextComponentOptions from the server to the format expected
54
+ * by the Canvas Engine Text component. Supports all text styling properties
55
+ * including fill, fontSize, fontFamily, fontStyle, fontWeight, stroke,
56
+ * opacity, wordWrap, and align. Also supports dynamic values (number | string)
57
+ * for numeric properties like fontSize and opacity.
58
+ *
59
+ * @param component - Component definition with style property
60
+ * @returns Object with Text component props
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // Component with style
65
+ * const component = {
66
+ * style: {
67
+ * fill: '#000000',
68
+ * fontSize: 20,
69
+ * fontFamily: 'Arial',
70
+ * fontWeight: 'bold'
71
+ * }
72
+ * };
73
+ *
74
+ * const props = getComponentStyle(component);
75
+ * // Returns: { color: '#000000', size: 20, fontFamily: 'Arial', style: { fontWeight: 'bold' } }
76
+ *
77
+ * // Component with dynamic fontSize
78
+ * const component2 = {
79
+ * style: {
80
+ * fill: '#000000',
81
+ * fontSize: '{hp}', // Will be resolved from object.hp
82
+ * opacity: '0.8'
83
+ * }
84
+ * };
85
+ * ```
86
+ */
87
+ const getComponentStyle = (component) => {
88
+ if (!component.style) {
89
+ return {};
90
+ }
91
+
92
+ const style = component.style;
93
+ const result = {};
94
+
95
+ // Map fill to color (shortcut property)
96
+ // fill can be a string (hex color) or a dynamic string
97
+ if (style.fill !== undefined) {
98
+ if (typeof style.fill === 'string' && style.fill.includes('{')) {
99
+ result.color = parseDynamicValue(style.fill, object);
100
+ } else {
101
+ result.color = style.fill;
102
+ }
103
+ }
104
+
105
+ // Map fontSize to size (shortcut property)
106
+ // fontSize can be number or string (with dynamic references)
107
+ if (style.fontSize !== undefined) {
108
+ const fontSizeValue = parseNumericStyleValue(style.fontSize, object);
109
+ if (fontSizeValue !== undefined) {
110
+ result.size = fontSizeValue;
111
+ }
112
+ }
113
+
114
+ // Map fontFamily (shortcut property)
115
+ if (style.fontFamily !== undefined) {
116
+ if (typeof style.fontFamily === 'string' && style.fontFamily.includes('{')) {
117
+ result.fontFamily = parseDynamicValue(style.fontFamily, object);
118
+ } else {
119
+ result.fontFamily = style.fontFamily;
120
+ }
121
+ }
122
+
123
+ // Build style object for PixiJS Text properties
124
+ const textStyle = {};
125
+
126
+ // Font style properties
127
+ if (style.fontStyle !== undefined) {
128
+ if (typeof style.fontStyle === 'string' && style.fontStyle.includes('{')) {
129
+ textStyle.fontStyle = parseDynamicValue(style.fontStyle, object);
130
+ } else {
131
+ textStyle.fontStyle = style.fontStyle;
132
+ }
133
+ }
134
+
135
+ if (style.fontWeight !== undefined) {
136
+ if (typeof style.fontWeight === 'string' && style.fontWeight.includes('{')) {
137
+ textStyle.fontWeight = parseDynamicValue(style.fontWeight, object);
138
+ } else if (typeof style.fontWeight === 'number') {
139
+ textStyle.fontWeight = style.fontWeight;
140
+ } else {
141
+ textStyle.fontWeight = style.fontWeight;
142
+ }
143
+ }
144
+
145
+ // Stroke properties
146
+ if (style.stroke !== undefined) {
147
+ if (typeof style.stroke === 'string' && style.stroke.includes('{')) {
148
+ textStyle.stroke = parseDynamicValue(style.stroke, object);
149
+ } else {
150
+ textStyle.stroke = style.stroke;
151
+ }
152
+ }
153
+
154
+ // Opacity (can be number or string)
155
+ if (style.opacity !== undefined) {
156
+ const opacityValue = parseNumericStyleValue(style.opacity, object);
157
+ if (opacityValue !== undefined) {
158
+ textStyle.opacity = opacityValue;
159
+ }
160
+ }
161
+
162
+ // Word wrap
163
+ if (style.wordWrap !== undefined) {
164
+ textStyle.wordWrap = style.wordWrap;
165
+ }
166
+
167
+ // Text alignment
168
+ if (style.align !== undefined) {
169
+ if (typeof style.align === 'string' && style.align.includes('{')) {
170
+ textStyle.align = parseDynamicValue(style.align, object);
171
+ } else {
172
+ textStyle.align = style.align;
173
+ }
174
+ }
175
+
176
+ // Only add style prop if there are style properties
177
+ if (Object.keys(textStyle).length > 0) {
178
+ result.style = textStyle;
179
+ }
180
+
181
+ return result;
182
+ }
183
+ </script>
@@ -0,0 +1,17 @@
1
+ <Container positionType="absolute" top={top} left={left}>
2
+ <Container
3
+ anchor={[0.5, 0.5]}
4
+ >
5
+ <Rect width height color={_color} />
6
+ <Container attach={child}></Container>
7
+ </Container>
8
+ </Container>
9
+
10
+ <script>
11
+ import { RpgClientEngine, inject } from "../../index";
12
+
13
+ const { width, height, children, color, top, left } = defineProps();
14
+ const engine = inject(RpgClientEngine)
15
+ const child = children[0]
16
+ const _color = computed(() => engine.globalConfig.gui?.windowColor || color?.() || "#1a1a2e")
17
+ </script>
@@ -1,194 +1,211 @@
1
- <Container justifyContent="center" alignItems="center" width="100%" height="100%">
2
- <Container
3
- ref="dialogbox"
4
- scale={{ x: scaleX }}
5
- anchor={[0.5, 0.5]}
6
- width={700}
7
- height
8
- controls
9
- positionType="absolute"
10
- bottom={10}
11
- >
12
- <Rect width={700} height={250} color="#1a1a2e" />
13
- <Rect
14
- x={0}
15
- y={0}
16
- width={700}
17
- height
18
- color="#1a1a2e"
19
- alpha={0.9}
20
- borderRadius={10}
21
- border
22
- shadow
23
- />
24
- <Container
25
- flexDirection="row"
26
- width={700}
27
- height
28
- alpha={contentOpacity}
29
- >
30
- <Container flexDirection="column">
31
- <Text
32
- text
33
- color="#fff"
34
- fontSize={18}
35
- margin={40}
36
- typewriter
37
- style={textStyle}
38
- />
39
- @if (visibleSelection) {
40
- <Selection selectedIndex={0} items={choices} onSelect />
41
- }
42
- </Container>
43
- </Container>
44
- </Container>
45
-
46
-
47
- </Container>
1
+ <DOMContainer width="100%" height="100%" controls={dialogControls}>
2
+ <div
3
+ class="rpg-ui-dialog-container"
4
+ data-position={dialogPosition()}
5
+ data-full-width={isFullWidth() ? "true" : "false"}
6
+ data-has-face={hasFace() ? "true" : "false"}
7
+ >
8
+ <div class="rpg-ui-dialog rpg-anim-fade-in">
9
+ <div class="rpg-ui-dialog-body">
10
+ <div>
11
+ @if (speakerName()) {
12
+ <div class="rpg-ui-dialog-speaker">{speakerName()}</div>
13
+ }
14
+ <div class="rpg-ui-dialog-content">
15
+ {displayMessage()}
16
+ </div>
17
+ @if (hasChoices()) {
18
+ <Navigation tabindex={selectedItem} controls={controls}>
19
+ <div class="rpg-ui-dialog-choices">
20
+ @for ((choice,index) of choices) {
21
+ <div
22
+ class="rpg-ui-dialog-choice"
23
+ class={{active: selectedItem() === index}}
24
+ tabindex={index}
25
+ data-choice-index={index}
26
+ click={selectChoice(index)}
27
+ >{{ choice.text }}</div>
28
+ }
29
+ </div>
30
+ </Navigation>
31
+ }
32
+ </div>
33
+ @if (hasFace()) {
34
+ <div class="rpg-ui-dialog-face">
35
+ <DOMSprite sheet={faceSheet(face.id, face.expression)} />
36
+ </div>
37
+ }
38
+ </div>
39
+ @if (showIndicator) {
40
+ <div class="rpg-ui-dialog-indicator"></div>
41
+ }
42
+ </div>
43
+ </div>
44
+ </DOMContainer>
45
+
48
46
  <script>
49
- import Selection from './selection.ce'
50
-
51
- import {
52
- animatedSignal,
53
- computed,
54
- effect,
55
- signal,
56
- trigger,
57
- mount
58
- } from "canvasengine";
59
-
60
- import { inject } from "../../../core/inject";
61
- import { RpgClientEngine } from "../../../RpgClientEngine";
62
-
63
- const {
64
- message,
65
- choices: _choices,
66
- onFinish,
67
- onInteraction
68
- } = defineProps();
69
-
70
- const client = inject(RpgClientEngine);
71
- const keyboardControls = client.globalConfig.keyboardControls;
72
-
73
- client.stopProcessingInput = true;
74
- let isDestroyed = false;
75
-
76
- const texts = [message()]
77
- const height = signal(250);
78
- const isTextCompleted = signal(false);
79
-
80
- const drawSpeaker = (g) => {
81
- g.beginFill(0xffa500); // Orange color
82
- g.lineStyle(2, 0x000000); // Black border
83
- g.moveTo(0, 0);
84
- g.lineTo(70, 0);
85
- g.lineTo(80, 15);
86
- g.lineTo(70, 30);
87
- g.lineTo(0, 30);
88
- g.lineTo(0, 0);
89
- g.endFill();
90
- };
91
-
92
- const border = signal({ width: 5, color: "#595971" });
93
- const shadow = signal({ color: "#000", blur: 10, offsetX: 10, offsetY: 10 });
94
-
95
- const contentOpacity = animatedSignal(0, {
96
- duration: 1000,
97
- });
98
-
99
- const scaleX = animatedSignal(0, {
100
- duration: 500,
101
- });
102
-
103
- scaleX.set(1);
104
- contentOpacity.set(1);
105
-
106
- const currentTextIndex = signal(0);
107
- const currentText = computed(() => texts?.[currentTextIndex()] ?? '');
108
- const isChoiceDisplayed = signal(false);
109
-
110
- const text = computed(() => {
111
- const current = currentText();
112
- return typeof current === "string" ? current : current.text;
113
- });
114
-
115
- const choices = computed(() => {
116
- //const current = currentText();
117
- //return typeof current === "string" ? null : current.choices;
118
- return _choices;
119
- });
120
-
121
- const visibleSelection = computed(() => isChoiceDisplayed() && choices().length != 0)
122
-
123
- const triggerSkip = trigger();
124
-
125
- const typewriter = {
126
- speed: 0.3,
127
- skip: triggerSkip,
128
- onComplete: () => {
129
- isTextCompleted.set(true);
130
- }
131
- }
132
-
133
- const textStyle = {
134
- wordWrap: true,
135
- wordWrapWidth: 700 - 256 - 80
136
- }
137
-
138
- const face = signal({ x: 0, y: 0, width: 256, height: 256 });
139
-
140
- mount((element) => {
141
- const [dialogbox] = element.props.children
142
- return () => {
143
- dialogbox.directives.controls.onDestroy()
144
- isDestroyed = true;
145
- // Wait destroy is finished before start processing input
146
- setTimeout(() => {
147
- client.stopProcessingInput = false;
148
- }, 500)
149
- }
150
- })
151
-
152
- const controls = signal({
153
- next: {
154
- bind: keyboardControls.action,
155
- keyDown(e) {
156
- if (isDestroyed) return;
157
- if (isChoiceDisplayed()) {
158
- // If choices are displayed, do nothing (wait for selection)
159
- return;
47
+ import { effect, signal, computed, createTabindexNavigator, mount } from "canvasengine";
48
+ import { inject } from "../../../core/inject";
49
+ import { RpgClientEngine } from "../../../RpgClientEngine";
50
+ import { delay } from "@rpgjs/common";
51
+
52
+ const engine = inject(RpgClientEngine);
53
+ const currentPlayer = engine.scene.currentPlayer
54
+ const keyboardControls = engine.globalConfig.keyboardControls;
55
+
56
+ engine.stopProcessingInput = true;
57
+
58
+ const selectedItem = signal(0)
59
+ let isDestroyed = false;
60
+
61
+ const {
62
+ data,
63
+ onFinish,
64
+ onInteraction
65
+ } = defineProps();
66
+
67
+ const { message, choices, face, speaker, position, typewriterEffect, autoClose } = data();
68
+ const fullWidth = computed(() => data().fullWidth || false);
69
+
70
+ const resolveProp = (value) => typeof value === "function" ? value() : value;
71
+
72
+ const speakerName = computed(() => {
73
+ const value = resolveProp(speaker);
74
+ return value ? String(value) : "";
75
+ });
76
+
77
+ const dialogPosition = computed(() => resolveProp(position) || "bottom");
78
+ const isFullWidth = computed(() => resolveProp(fullWidth) !== false);
79
+ const hasFace = computed(() => !!resolveProp(face));
80
+
81
+ const displayMessage = signal("");
82
+ const fullMessage = signal("");
83
+ const isTyping = signal(false);
84
+ let typewriterTimer = null;
85
+ let rootElement = null;
86
+
87
+ mount((element) => {
88
+ rootElement = element;
89
+ });
90
+
91
+ const startTypewriter = (text) => {
92
+ if (typewriterTimer) clearInterval(typewriterTimer);
93
+ displayMessage.set("");
94
+ if (!text) return;
95
+ let index = 0;
96
+ isTyping.set(true);
97
+ typewriterTimer = setInterval(() => {
98
+ index += 1;
99
+ displayMessage.set(text.slice(0, index));
100
+ if (index >= text.length) {
101
+ clearInterval(typewriterTimer);
102
+ typewriterTimer = null;
103
+ isTyping.set(false);
104
+ }
105
+ }, 20);
106
+ };
107
+
108
+ const finishTyping = () => {
109
+ if (typewriterTimer) clearInterval(typewriterTimer);
110
+ typewriterTimer = null;
111
+ displayMessage.set(fullMessage());
112
+ isTyping.set(false);
113
+ };
114
+
115
+ effect(() => {
116
+ const text = resolveProp(message) || "";
117
+ fullMessage.set(text);
118
+ const useTypewriter = resolveProp(typewriterEffect) !== false;
119
+ if (!useTypewriter) {
120
+ finishTyping();
121
+ return;
160
122
  }
123
+ startTypewriter(text);
124
+ });
125
+
161
126
 
162
- // If text is still typing, just skip (fast forward) the animation
163
- if (!isTextCompleted()) {
164
- triggerSkip.start();
165
- isTextCompleted.set(true);
127
+ const hasChoices = computed(() => choices.length > 0);
128
+ const showIndicator = computed(() => !hasChoices() && !isTyping());
129
+ const nav = createTabindexNavigator(selectedItem, { count: () => choices.length }, 'wrap');
130
+
131
+ function selectChoice(index) {
132
+ return function() {
133
+ selectedItem.set(index);
134
+ onSelect(index);
166
135
  }
167
- else {
168
- const isFinished = currentTextIndex() === texts.length - 1;
169
- currentTextIndex.update((index) => {
170
- if (index < texts.length - 1) {
171
- return index + 1;
136
+ }
137
+
138
+ function _onFinish(value) {
139
+ if (onFinish) onFinish(value);
140
+ }
141
+
142
+ const onSelect = (index) => {
143
+ _onFinish(index);
144
+ };
145
+
146
+ const controls = signal({
147
+ up: {
148
+ repeat: true,
149
+ bind: keyboardControls.up,
150
+ throttle: 150,
151
+ keyDown() {
152
+ if (!hasChoices()) return;
153
+ nav.next(-1);
154
+ }
155
+ },
156
+ down: {
157
+ repeat: true,
158
+ bind: keyboardControls.down,
159
+ throttle: 150,
160
+ keyDown() {
161
+ if (!hasChoices()) return;
162
+ nav.next(1);
163
+ }
164
+ },
165
+ action: {
166
+ bind: keyboardControls.action,
167
+ keyDown() {
168
+ if (isTyping()) {
169
+ finishTyping();
170
+ return;
171
+ }
172
+ if (!hasChoices()) return;
173
+ onSelect(selectedItem());
172
174
  }
173
- return index;
174
- });
175
- isChoiceDisplayed.set(false);
176
- isTextCompleted.set(false);
177
- if (isFinished && onFinish) {
178
- onFinish();
179
- }
175
+ },
176
+ gamepad: {
177
+ enabled: true
180
178
  }
181
- },
182
- },
183
- });
184
-
185
- const onSelect = (index) => {
186
- onFinish(index);
187
- }
188
-
189
- effect(() => {
190
- if (choices().length != 0) {
191
- isChoiceDisplayed.set(true);
179
+ });
180
+
181
+ const dialogControls = signal({
182
+ action: {
183
+ bind: keyboardControls.action,
184
+ keyDown() {
185
+ if (isTyping()) {
186
+ finishTyping();
187
+ return;
188
+ }
189
+ if (hasChoices()) return;
190
+ _onFinish();
191
+ }
192
+ },
193
+ })
194
+
195
+ const faceSheet = (graphicId, animationName) => {
196
+ return {
197
+ definition: engine.getSpriteSheet(graphicId),
198
+ playing: animationName,
199
+ };
192
200
  }
193
- });
194
- </script>
201
+
202
+ mount((element) => {
203
+ return () => {
204
+ isDestroyed = true;
205
+ // Wait destroy is finished before start processing input
206
+ delay(() => {
207
+ engine.stopProcessingInput = false;
208
+ })
209
+ }
210
+ })
211
+ </script>