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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/Game/Map.d.ts +7 -1
  3. package/dist/Gui/Gui.d.ts +128 -5
  4. package/dist/RpgClient.d.ts +217 -59
  5. package/dist/RpgClientEngine.d.ts +345 -6
  6. package/dist/Sound.d.ts +199 -0
  7. package/dist/components/animations/index.d.ts +4 -0
  8. package/dist/components/dynamics/parse-value.d.ts +1 -0
  9. package/dist/components/gui/index.d.ts +3 -3
  10. package/dist/components/index.d.ts +3 -1
  11. package/dist/components/prebuilt/index.d.ts +18 -0
  12. package/dist/index.d.ts +4 -1
  13. package/dist/index.js +9 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/index10.js +149 -4
  16. package/dist/index10.js.map +1 -1
  17. package/dist/index11.js +21 -7
  18. package/dist/index11.js.map +1 -1
  19. package/dist/index12.js +6 -4
  20. package/dist/index12.js.map +1 -1
  21. package/dist/index13.js +11 -14
  22. package/dist/index13.js.map +1 -1
  23. package/dist/index14.js +8 -40
  24. package/dist/index14.js.map +1 -1
  25. package/dist/index15.js +187 -180
  26. package/dist/index15.js.map +1 -1
  27. package/dist/index16.js +104 -7
  28. package/dist/index16.js.map +1 -1
  29. package/dist/index17.js +82 -372
  30. package/dist/index17.js.map +1 -1
  31. package/dist/index18.js +361 -26
  32. package/dist/index18.js.map +1 -1
  33. package/dist/index19.js +46 -20
  34. package/dist/index19.js.map +1 -1
  35. package/dist/index2.js +683 -32
  36. package/dist/index2.js.map +1 -1
  37. package/dist/index20.js +5 -2417
  38. package/dist/index20.js.map +1 -1
  39. package/dist/index21.js +383 -97
  40. package/dist/index21.js.map +1 -1
  41. package/dist/index22.js +41 -104
  42. package/dist/index22.js.map +1 -1
  43. package/dist/index23.js +21 -67
  44. package/dist/index23.js.map +1 -1
  45. package/dist/index24.js +2632 -20
  46. package/dist/index24.js.map +1 -1
  47. package/dist/index25.js +107 -34
  48. package/dist/index25.js.map +1 -1
  49. package/dist/index26.js +69 -3
  50. package/dist/index26.js.map +1 -1
  51. package/dist/index27.js +17 -318
  52. package/dist/index27.js.map +1 -1
  53. package/dist/index28.js +24 -22
  54. package/dist/index28.js.map +1 -1
  55. package/dist/index29.js +92 -8
  56. package/dist/index29.js.map +1 -1
  57. package/dist/index3.js +68 -8
  58. package/dist/index3.js.map +1 -1
  59. package/dist/index30.js +37 -7
  60. package/dist/index30.js.map +1 -1
  61. package/dist/index31.js +18 -168
  62. package/dist/index31.js.map +1 -1
  63. package/dist/index32.js +3 -499
  64. package/dist/index32.js.map +1 -1
  65. package/dist/index33.js +332 -9
  66. package/dist/index33.js.map +1 -1
  67. package/dist/index34.js +24 -4400
  68. package/dist/index34.js.map +1 -1
  69. package/dist/index35.js +6 -311
  70. package/dist/index35.js.map +1 -1
  71. package/dist/index36.js +8 -88
  72. package/dist/index36.js.map +1 -1
  73. package/dist/index37.js +182 -56
  74. package/dist/index37.js.map +1 -1
  75. package/dist/index38.js +500 -16
  76. package/dist/index38.js.map +1 -1
  77. package/dist/index39.js +10 -18
  78. package/dist/index39.js.map +1 -1
  79. package/dist/index4.js +23 -5
  80. package/dist/index4.js.map +1 -1
  81. package/dist/index40.js +7 -0
  82. package/dist/index40.js.map +1 -0
  83. package/dist/index41.js +3690 -0
  84. package/dist/index41.js.map +1 -0
  85. package/dist/index42.js +77 -0
  86. package/dist/index42.js.map +1 -0
  87. package/dist/index43.js +6 -0
  88. package/dist/index43.js.map +1 -0
  89. package/dist/index44.js +20 -0
  90. package/dist/index44.js.map +1 -0
  91. package/dist/index45.js +146 -0
  92. package/dist/index45.js.map +1 -0
  93. package/dist/index46.js +12 -0
  94. package/dist/index46.js.map +1 -0
  95. package/dist/index47.js +113 -0
  96. package/dist/index47.js.map +1 -0
  97. package/dist/index48.js +136 -0
  98. package/dist/index48.js.map +1 -0
  99. package/dist/index49.js +137 -0
  100. package/dist/index49.js.map +1 -0
  101. package/dist/index5.js +2 -1
  102. package/dist/index5.js.map +1 -1
  103. package/dist/index50.js +112 -0
  104. package/dist/index50.js.map +1 -0
  105. package/dist/index51.js +141 -0
  106. package/dist/index51.js.map +1 -0
  107. package/dist/index52.js +9 -0
  108. package/dist/index52.js.map +1 -0
  109. package/dist/index53.js +54 -0
  110. package/dist/index53.js.map +1 -0
  111. package/dist/index6.js +1 -1
  112. package/dist/index6.js.map +1 -1
  113. package/dist/index7.js +11 -3
  114. package/dist/index7.js.map +1 -1
  115. package/dist/index8.js +68 -7
  116. package/dist/index8.js.map +1 -1
  117. package/dist/index9.js +230 -15
  118. package/dist/index9.js.map +1 -1
  119. package/dist/presets/animation.d.ts +31 -0
  120. package/dist/presets/faceset.d.ts +30 -0
  121. package/dist/presets/index.d.ts +103 -0
  122. package/dist/presets/lpc.d.ts +89 -0
  123. package/dist/services/loadMap.d.ts +123 -2
  124. package/dist/services/mmorpg.d.ts +9 -4
  125. package/dist/services/standalone.d.ts +51 -2
  126. package/package.json +22 -18
  127. package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
  128. package/src/Game/Map.ts +20 -2
  129. package/src/Game/Object.ts +163 -9
  130. package/src/Gui/Gui.ts +300 -17
  131. package/src/RpgClient.ts +222 -58
  132. package/src/RpgClientEngine.ts +804 -36
  133. package/src/Sound.ts +253 -0
  134. package/src/components/{effects → animations}/animation.ce +3 -6
  135. package/src/components/{effects → animations}/index.ts +1 -1
  136. package/src/components/character.ce +165 -37
  137. package/src/components/dynamics/parse-value.ts +80 -0
  138. package/src/components/dynamics/text.ce +183 -0
  139. package/src/components/gui/box.ce +17 -0
  140. package/src/components/gui/dialogbox/index.ce +73 -35
  141. package/src/components/gui/dialogbox/selection.ce +16 -1
  142. package/src/components/gui/index.ts +3 -4
  143. package/src/components/index.ts +5 -1
  144. package/src/components/prebuilt/hp-bar.ce +255 -0
  145. package/src/components/prebuilt/index.ts +21 -0
  146. package/src/components/scenes/draw-map.ce +6 -23
  147. package/src/components/scenes/event-layer.ce +9 -3
  148. package/src/core/setup.ts +2 -0
  149. package/src/index.ts +5 -2
  150. package/src/module.ts +72 -6
  151. package/src/presets/animation.ts +46 -0
  152. package/src/presets/faceset.ts +60 -0
  153. package/src/presets/index.ts +7 -1
  154. package/src/presets/lpc.ts +108 -0
  155. package/src/services/loadMap.ts +132 -3
  156. package/src/services/mmorpg.ts +27 -5
  157. package/src/services/standalone.ts +68 -6
  158. package/tsconfig.json +1 -1
  159. package/vite.config.ts +1 -1
  160. package/dist/Game/EffectManager.d.ts +0 -5
  161. package/dist/components/effects/index.d.ts +0 -4
  162. package/src/components/scenes/element-map.ce +0 -23
  163. /package/src/components/{effects → animations}/hit.ce +0 -0
package/src/Gui/Gui.ts CHANGED
@@ -1,13 +1,36 @@
1
1
  import { Context, inject } from "@signe/di";
2
- import { signal } from "canvasengine";
2
+ import { signal, Signal, WritableSignal } from "canvasengine";
3
3
  import { AbstractWebsocket, WebSocketToken } from "../services/AbstractSocket";
4
- import { PrebuiltGui } from "../components/gui";
4
+ import { DialogboxComponent } from "../components/gui";
5
+ import { combineLatest, Subscription } from "rxjs";
5
6
 
6
7
  interface GuiOptions {
7
- name: string;
8
+ name?: string;
9
+ id?: string;
8
10
  component: any;
9
11
  display?: boolean;
10
12
  data?: any;
13
+ /**
14
+ * Auto display the GUI when added to the system
15
+ * @default false
16
+ */
17
+ autoDisplay?: boolean;
18
+ /**
19
+ * Function that returns an array of Signal dependencies
20
+ * The GUI will only display when all dependencies are resolved (!= undefined)
21
+ * @returns Array of Signal dependencies
22
+ */
23
+ dependencies?: () => Signal[];
24
+ }
25
+
26
+ interface GuiInstance {
27
+ name: string;
28
+ component: any;
29
+ display: WritableSignal<boolean>;
30
+ data: WritableSignal<any>;
31
+ autoDisplay: boolean;
32
+ dependencies?: () => Signal[];
33
+ subscription?: Subscription;
11
34
  }
12
35
 
13
36
  const throwError = (id: string) => {
@@ -16,13 +39,15 @@ const throwError = (id: string) => {
16
39
 
17
40
  export class RpgGui {
18
41
  private webSocket: AbstractWebsocket;
19
- gui = signal<any>({});
42
+ gui = signal<Record<string, GuiInstance>>({});
43
+ extraGuis: GuiInstance[] = [];
44
+ private vueGuiInstance: any = null; // Reference to VueGui instance
20
45
 
21
46
  constructor(private context: Context) {
22
47
  this.webSocket = inject(context, WebSocketToken);
23
48
  this.add({
24
49
  name: "rpg-dialog",
25
- component: PrebuiltGui.Dialogbox,
50
+ component: DialogboxComponent,
26
51
  });
27
52
  }
28
53
 
@@ -36,6 +61,63 @@ export class RpgGui {
36
61
  });
37
62
  }
38
63
 
64
+ /**
65
+ * Set the VueGui instance reference for Vue component management
66
+ * This is called by VueGui when it's initialized
67
+ *
68
+ * @param vueGuiInstance - The VueGui instance
69
+ */
70
+ _setVueGuiInstance(vueGuiInstance: any) {
71
+ this.vueGuiInstance = vueGuiInstance;
72
+ }
73
+
74
+ /**
75
+ * Notify VueGui about GUI state changes
76
+ * This synchronizes the Vue component display state
77
+ *
78
+ * @param guiId - The GUI component ID
79
+ * @param display - Display state
80
+ * @param data - Component data
81
+ */
82
+ private _notifyVueGui(guiId: string, display: boolean, data: any = {}) {
83
+ if (this.vueGuiInstance && this.vueGuiInstance.vm) {
84
+ // Find the GUI in extraGuis
85
+ const extraGui = this.extraGuis.find(gui => gui.name === guiId);
86
+ if (extraGui) {
87
+ // Update the Vue component's display state and data
88
+ this.vueGuiInstance.vm.gui[guiId] = {
89
+ name: guiId,
90
+ display,
91
+ data,
92
+ attachToSprite: false // Default value, could be configurable
93
+ };
94
+ // Trigger Vue reactivity
95
+ this.vueGuiInstance.vm.gui = Object.assign({}, this.vueGuiInstance.vm.gui);
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Initialize Vue components in the VueGui instance
102
+ * This should be called after VueGui is mounted
103
+ */
104
+ _initializeVueComponents() {
105
+ if (this.vueGuiInstance && this.vueGuiInstance.vm) {
106
+ // Initialize all extraGuis in the Vue instance
107
+ this.extraGuis.forEach(gui => {
108
+ this.vueGuiInstance.vm.gui[gui.name] = {
109
+ name: gui.name,
110
+ display: gui.display(),
111
+ data: gui.data(),
112
+ attachToSprite: false
113
+ };
114
+ });
115
+
116
+ // Trigger Vue reactivity
117
+ this.vueGuiInstance.vm.gui = Object.assign({}, this.vueGuiInstance.vm.gui);
118
+ }
119
+ }
120
+
39
121
  guiInteraction(guiId: string, name: string, data: any) {
40
122
  this.webSocket.emit("gui.interaction", {
41
123
  guiId,
@@ -51,42 +133,243 @@ export class RpgGui {
51
133
  });
52
134
  }
53
135
 
136
+ /**
137
+ * Add a GUI component to the system
138
+ *
139
+ * By default, only CanvasEngine components (.ce files) are accepted.
140
+ * Vue components should be handled by the @rpgjs/vue package.
141
+ *
142
+ * @param gui - GUI configuration options
143
+ * @param gui.name - Name or ID of the GUI component
144
+ * @param gui.id - Alternative ID if name is not provided
145
+ * @param gui.component - The component to render (must be a CanvasEngine component)
146
+ * @param gui.display - Initial display state (default: false)
147
+ * @param gui.data - Initial data for the component
148
+ * @param gui.autoDisplay - Auto display when added (default: false)
149
+ * @param gui.dependencies - Function returning Signal dependencies
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * gui.add({
154
+ * name: 'inventory',
155
+ * component: InventoryComponent, // Must be a .ce component
156
+ * autoDisplay: true,
157
+ * dependencies: () => [playerSignal, inventorySignal]
158
+ * });
159
+ * ```
160
+ */
54
161
  add(gui: GuiOptions) {
55
- this.gui()[gui.name] = {
56
- name: gui.name,
162
+ const guiId = gui.name || gui.id;
163
+ if (!guiId) {
164
+ throw new Error("GUI must have a name or id");
165
+ }
166
+
167
+ const guiInstance: GuiInstance = {
168
+ name: guiId,
57
169
  component: gui.component,
58
170
  display: signal(gui.display || false),
59
171
  data: signal(gui.data || {}),
172
+ autoDisplay: gui.autoDisplay || false,
173
+ dependencies: gui.dependencies,
60
174
  };
175
+
176
+ // Accept both CanvasEngine components (.ce) and Vue components
177
+ // Vue components will be handled by VueGui if available
178
+ if (typeof gui.component !== 'function') {
179
+ guiInstance.component = gui;
180
+ this.extraGuis.push(guiInstance);
181
+
182
+ // Auto display Vue components if enabled
183
+ if (guiInstance.autoDisplay) {
184
+ this._notifyVueGui(guiId, true, gui.data || {});
185
+ }
186
+ return;
187
+ }
188
+
189
+ this.gui()[guiId] = guiInstance;
190
+
191
+ // Auto display if enabled and it's a CanvasEngine component
192
+ if (guiInstance.autoDisplay && typeof gui.component === 'function') {
193
+ this.display(guiId);
194
+ }
61
195
  }
62
196
 
63
- get(id: string | GuiOptions) {
64
- if (typeof id != "string") {
65
- id = id.name;
197
+ get(id: string): GuiInstance | undefined {
198
+ // Check CanvasEngine GUIs first
199
+ const canvasGui = this.gui()[id];
200
+ if (canvasGui) {
201
+ return canvasGui;
66
202
  }
67
- return this.gui()[id];
203
+
204
+ // Check Vue GUIs in extraGuis
205
+ return this.extraGuis.find(gui => gui.name === id);
68
206
  }
69
207
 
70
208
  exists(id: string): boolean {
71
209
  return !!this.get(id);
72
210
  }
73
211
 
74
- getAll() {
75
- return this.gui();
212
+ getAll(): Record<string, GuiInstance> {
213
+ const allGuis = { ...this.gui() };
214
+
215
+ // Add extraGuis to the result
216
+ this.extraGuis.forEach(gui => {
217
+ allGuis[gui.name] = gui;
218
+ });
219
+
220
+ return allGuis;
76
221
  }
77
222
 
78
- display(id: string, data = {}) {
223
+ /**
224
+ * Display a GUI component
225
+ *
226
+ * Displays the GUI immediately if no dependencies are configured,
227
+ * or waits for all dependencies to be resolved if dependencies are present.
228
+ * Automatically manages subscriptions to prevent memory leaks.
229
+ * Works with both CanvasEngine components and Vue components.
230
+ *
231
+ * @param id - The GUI component ID
232
+ * @param data - Data to pass to the component
233
+ * @param dependencies - Optional runtime dependencies (overrides config dependencies)
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * // Display immediately
238
+ * gui.display('inventory', { items: [] });
239
+ *
240
+ * // Display with runtime dependencies
241
+ * gui.display('shop', { shopId: 1 }, [playerSignal, shopSignal]);
242
+ * ```
243
+ */
244
+ display(id: string, data = {}, dependencies: Signal[] = []) {
79
245
  if (!this.exists(id)) {
80
246
  throw throwError(id);
81
247
  }
82
- this.get(id).data.set(data);
83
- this.get(id).display.set(true);
248
+
249
+ const guiInstance = this.get(id)!;
250
+
251
+ // Check if it's a Vue component (in extraGuis)
252
+ const isVueComponent = this.extraGuis.some(gui => gui.name === id);
253
+
254
+ if (isVueComponent) {
255
+ // Handle Vue component display
256
+ this._handleVueComponentDisplay(id, data, dependencies, guiInstance);
257
+ } else {
258
+ // Handle CanvasEngine component display
259
+ this._handleCanvasComponentDisplay(id, data, dependencies, guiInstance);
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Handle Vue component display logic
265
+ *
266
+ * @param id - GUI component ID
267
+ * @param data - Component data
268
+ * @param dependencies - Runtime dependencies
269
+ * @param guiInstance - GUI instance
270
+ */
271
+ private _handleVueComponentDisplay(id: string, data: any, dependencies: Signal[], guiInstance: GuiInstance) {
272
+ // Unsubscribe from previous subscription if exists
273
+ if (guiInstance.subscription) {
274
+ guiInstance.subscription.unsubscribe();
275
+ guiInstance.subscription = undefined;
276
+ }
277
+
278
+ // Use runtime dependencies or config dependencies
279
+ const deps = dependencies.length > 0
280
+ ? dependencies
281
+ : (guiInstance.dependencies ? guiInstance.dependencies() : []);
282
+
283
+ if (deps.length > 0) {
284
+ // Subscribe to dependencies
285
+ guiInstance.subscription = combineLatest(
286
+ deps.map(dependency => dependency.observable)
287
+ ).subscribe((values) => {
288
+ if (values.every(value => value !== undefined)) {
289
+ guiInstance.data.set(data);
290
+ guiInstance.display.set(true);
291
+ this._notifyVueGui(id, true, data);
292
+ }
293
+ });
294
+ return;
295
+ }
296
+
297
+ // No dependencies, display immediately
298
+ guiInstance.data.set(data);
299
+ guiInstance.display.set(true);
300
+ this._notifyVueGui(id, true, data);
301
+ }
302
+
303
+ /**
304
+ * Handle CanvasEngine component display logic
305
+ *
306
+ * @param id - GUI component ID
307
+ * @param data - Component data
308
+ * @param dependencies - Runtime dependencies
309
+ * @param guiInstance - GUI instance
310
+ */
311
+ private _handleCanvasComponentDisplay(id: string, data: any, dependencies: Signal[], guiInstance: GuiInstance) {
312
+ // Unsubscribe from previous subscription if exists
313
+ if (guiInstance.subscription) {
314
+ guiInstance.subscription.unsubscribe();
315
+ guiInstance.subscription = undefined;
316
+ }
317
+
318
+ // Use runtime dependencies or config dependencies
319
+ const deps = dependencies.length > 0
320
+ ? dependencies
321
+ : (guiInstance.dependencies ? guiInstance.dependencies() : []);
322
+
323
+ if (deps.length > 0) {
324
+ // Subscribe to dependencies
325
+ guiInstance.subscription = combineLatest(
326
+ deps.map(dependency => dependency.observable)
327
+ ).subscribe((values) => {
328
+ if (values.every(value => value !== undefined)) {
329
+ guiInstance.data.set(data);
330
+ guiInstance.display.set(true);
331
+ }
332
+ });
333
+ return;
334
+ }
335
+
336
+ // No dependencies, display immediately
337
+ guiInstance.data.set(data);
338
+ guiInstance.display.set(true);
84
339
  }
85
340
 
341
+ /**
342
+ * Hide a GUI component
343
+ *
344
+ * Hides the GUI and cleans up any active subscriptions.
345
+ * Works with both CanvasEngine components and Vue components.
346
+ *
347
+ * @param id - The GUI component ID
348
+ *
349
+ * @example
350
+ * ```ts
351
+ * gui.hide('inventory');
352
+ * ```
353
+ */
86
354
  hide(id: string) {
87
355
  if (!this.exists(id)) {
88
356
  throw throwError(id);
89
357
  }
90
- this.get(id).display.set(false);
358
+
359
+ const guiInstance = this.get(id)!;
360
+
361
+ // Unsubscribe if there's an active subscription
362
+ if (guiInstance.subscription) {
363
+ guiInstance.subscription.unsubscribe();
364
+ guiInstance.subscription = undefined;
365
+ }
366
+
367
+ guiInstance.display.set(false);
368
+
369
+ // Check if it's a Vue component and notify VueGui
370
+ const isVueComponent = this.extraGuis.some(gui => gui.name === id);
371
+ if (isVueComponent) {
372
+ this._notifyVueGui(id, false);
373
+ }
91
374
  }
92
375
  }