@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/RpgClient.ts CHANGED
@@ -1,9 +1,11 @@
1
+ import { ComponentFunction, Signal } from 'canvasengine'
1
2
  import { RpgClientEngine } from './RpgClientEngine'
2
- import { Loader } from 'pixi.js'
3
+ import { Loader, Container } from 'pixi.js'
4
+ import { RpgClientObject } from './Game/Object'
3
5
 
4
6
  type RpgClass<T = any> = new (...args: any[]) => T
5
- type RpgComponent = any
6
- type SceneMap = any
7
+ type RpgComponent = RpgClientObject
8
+ type SceneMap = Container
7
9
 
8
10
  export interface RpgClientEngineHooks {
9
11
  /**
@@ -12,7 +14,7 @@ export interface RpgClientEngineHooks {
12
14
  * @prop { (engine: RpgClientEngine) => boolean | any } [onStart]
13
15
  * @memberof RpgEngineHooks
14
16
  */
15
- onStart?: (engine: RpgClientEngine) => boolean | void
17
+ onStart?: (engine: RpgClientEngine) => boolean | void | Promise<boolean | void>
16
18
 
17
19
  /**
18
20
  * Each frame
@@ -65,6 +67,36 @@ export interface RpgClientEngineHooks {
65
67
  }
66
68
 
67
69
  export interface RpgSpriteHooks {
70
+ /**
71
+ * Array of components to render behind the sprite
72
+ * These components will be displayed with a lower z-index than the sprite itself
73
+ *
74
+ * @prop { ComponentFunction[] } [componentsBehind]
75
+ * @memberof RpgSpriteHooks
76
+ * @example
77
+ * ```ts
78
+ * const sprite: RpgSpriteHooks = {
79
+ * componentsBehind: [ShadowComponent, AuraComponent]
80
+ * }
81
+ * ```
82
+ */
83
+ componentsBehind?: ComponentFunction[]
84
+
85
+ /**
86
+ * Array of components to render in front of the sprite
87
+ * These components will be displayed with a higher z-index than the sprite itself
88
+ *
89
+ * @prop { ComponentFunction[] } [componentsInFront]
90
+ * @memberof RpgSpriteHooks
91
+ * @example
92
+ * ```ts
93
+ * const sprite: RpgSpriteHooks = {
94
+ * componentsInFront: [HealthBarComponent, StatusEffectComponent]
95
+ * }
96
+ * ```
97
+ */
98
+ componentsInFront?: ComponentFunction[]
99
+
68
100
  /**
69
101
  * As soon as the sprite is initialized
70
102
  *
@@ -178,14 +210,13 @@ export interface RpgClient {
178
210
  * @example
179
211
  *
180
212
  * ```ts
181
- * import { RpgClient, RpgModule } from '@rpgjs/client'
213
+ * import { RpgClient, defineModule } from '@rpgjs/client'
182
214
  *
183
- * @RpgModule<RpgClient>({
215
+ * defineModule<RpgClient>({
184
216
  * hooks: {
185
217
  * player: ['onAuth']
186
218
  * }
187
219
  * })
188
- * class RpgClientEngine { }
189
220
  * ```
190
221
  *
191
222
  * Emit the hook:
@@ -224,7 +255,7 @@ export interface RpgClient {
224
255
  * Object containing the hooks concerning the engine
225
256
  *
226
257
  * ```ts
227
- * import { RpgClientEngine, RpgClientEngineHooks, RpgModule, RpgClient } from '@rpgjs/client'
258
+ * import { RpgClientEngine, RpgClientEngineHooks, defineModule, RpgClient } from '@rpgjs/client'
228
259
  *
229
260
  * const engine: RpgClientEngineHooks = {
230
261
  * onConnected(engine: RpgClientEngine) {
@@ -232,10 +263,9 @@ export interface RpgClient {
232
263
  * }
233
264
  * }
234
265
  *
235
- * @RpgModule<RpgClient>({
266
+ * defineModule<RpgClient>({
236
267
  * engine
237
268
  * })
238
- * class RpgClientModule {}
239
269
  * ```
240
270
  *
241
271
  * @prop {RpgClientEngineHooks} [engine]
@@ -245,102 +275,209 @@ export interface RpgClient {
245
275
 
246
276
  /**
247
277
  * Array containing the list of spritesheets
248
- * An element contains a class with the `@Spritesheet` decorator
278
+ * Each element is a simple object containing spritesheet definitions
249
279
  *
250
280
  * ```ts
251
- * import { Spritesheet, Animation, Direction, RpgClient, RpgModule } from '@rpgjs/client'
252
- *
253
- * @Spritesheet({
254
- * id: 'chest',
255
- * image: require('./assets/chest.png'),
256
- * // other options
257
- * })
258
- * class Chest { }
281
+ * import { defineModule, RpgClient } from '@rpgjs/client'
259
282
  *
260
- * @RpgModule<RpgClient>({
283
+ * defineModule<RpgClient>({
261
284
  * spritesheets: [
262
- * Chest
285
+ * {
286
+ * id: 'chest',
287
+ * image: require('./assets/chest.png'),
288
+ * framesWidth: 32,
289
+ * framesHeight: 32,
290
+ * animations: {
291
+ * default: {
292
+ * frames: [0, 1, 2],
293
+ * duration: 1000
294
+ * }
295
+ * }
296
+ * }
263
297
  * ]
264
298
  * })
265
- * class RpgClientEngine {}
266
299
  * ```
267
300
  *
268
301
  * [Guide: Create Sprite](/guide/create-sprite.html)
269
302
  *
270
- * @prop {Array<Class>} [spritesheets]
303
+ * @prop {Array<Object>} [spritesheets]
271
304
  * @memberof RpgClient
272
305
  * */
273
306
  spritesheets?: any[],
274
307
 
275
308
  /**
276
- * Array containing the list of VueJS components
309
+ * Resolver function for dynamically creating spritesheets
310
+ *
311
+ * This function is called when a spritesheet is requested but not found in the cache.
312
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
313
+ * The resolved spritesheet is automatically cached for future use.
277
314
  *
278
315
  * ```ts
279
- * import { RpgClient, RpgModule } from '@rpgjs/client'
280
- *
281
- * const component = {
282
- * name: 'my-gui',
283
- * template: `
284
- * <div>
285
- * Component
286
- * </div>
287
- * `
288
- * }
316
+ * import { defineModule, RpgClient } from '@rpgjs/client'
317
+ *
318
+ * defineModule<RpgClient>({
319
+ * spritesheetResolver: (id: string) => {
320
+ * // Synchronous resolver
321
+ * if (id === 'dynamic-sprite') {
322
+ * return {
323
+ * id: 'dynamic-sprite',
324
+ * image: 'path/to/image.png',
325
+ * framesWidth: 32,
326
+ * framesHeight: 32
327
+ * };
328
+ * }
329
+ * return undefined;
330
+ * }
331
+ * })
332
+ *
333
+ * // Or asynchronous resolver
334
+ * defineModule<RpgClient>({
335
+ * spritesheetResolver: async (id: string) => {
336
+ * const response = await fetch(`/api/spritesheets/${id}`);
337
+ * const data = await response.json();
338
+ * return data;
339
+ * }
340
+ * })
341
+ * ```
342
+ *
343
+ * @prop {(id: string) => any | Promise<any>} [spritesheetResolver]
344
+ * @memberof RpgClient
345
+ * */
346
+ spritesheetResolver?: (id: string) => any | Promise<any>,
347
+
348
+ /**
349
+ * Resolver function for dynamically loading sounds
350
+ *
351
+ * The resolver is called when a sound is requested but not found in the cache.
352
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
353
+ * The resolved sound is automatically cached for future use.
354
+ *
355
+ * ```ts
356
+ * import { defineModule, RpgClient } from '@rpgjs/client'
357
+ *
358
+ * defineModule<RpgClient>({
359
+ * soundResolver: (id: string) => {
360
+ * if (id === 'dynamic-sound') {
361
+ * return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
362
+ * }
363
+ * return undefined;
364
+ * }
365
+ * })
366
+ * ```
367
+ *
368
+ * @prop {(id: string) => any | Promise<any>} [soundResolver]
369
+ * @memberof RpgClient
370
+ * */
371
+ soundResolver?: (id: string) => any | Promise<any>,
372
+
373
+ /**
374
+ * Array containing the list of GUI components
375
+ *
376
+ * ```ts
377
+ * import { defineModule, RpgClient } from '@rpgjs/client'
378
+ * import InventoryComponent from './inventory.ce'
289
379
  *
290
- * @RpgModule<RpgClient>({
380
+ * defineModule<RpgClient>({
291
381
  * gui: [
292
- * component
382
+ * {
383
+ * id: 'inventory',
384
+ * component: InventoryComponent,
385
+ * autoDisplay: true,
386
+ * dependencies: () => [playerSignal, inventorySignal]
387
+ * }
293
388
  * ]
294
389
  * })
295
- * class RpgClientEngine {}
296
390
  * ```
297
391
  *
298
392
  * [Guide: Create GUI](/guide/create-gui.html)
299
393
  *
300
- * @prop {Array<Component of VueJS>} [gui]
394
+ * @prop {Array<GuiOptions>} [gui]
301
395
  * @memberof RpgClient
302
396
  * */
303
- gui?: any[],
397
+ gui?: ({
398
+ id: string,
399
+ component: ComponentFunction,
400
+ /**
401
+ * Auto display the GUI when added to the system
402
+ * @default false
403
+ */
404
+ autoDisplay?: boolean,
405
+ /**
406
+ * Function that returns an array of Signal dependencies
407
+ * The GUI will only display when all dependencies are resolved (!= undefined)
408
+ */
409
+ dependencies?: () => Signal[]
410
+ } | any)[],
304
411
 
305
412
  /**
306
413
  * Array containing the list of sounds
307
- * An element contains a class with the `@Sound` decorator
414
+ * Each element can be:
415
+ * - A simple object containing sound definitions
416
+ * - A class decorated with @Sound
308
417
  *
309
418
  * ```ts
310
- * import { Sound, RpgModule, RpgClient } from '@rpgjs/client'
419
+ * import { defineModule, RpgClient, Sound } from '@rpgjs/client'
420
+ *
421
+ * // Using simple objects
422
+ * defineModule<RpgClient>({
423
+ * sounds: [
424
+ * {
425
+ * id: 'typewriter',
426
+ * src: 'typewriter.wav'
427
+ * },
428
+ * {
429
+ * id: 'cursor',
430
+ * src: 'cursor.wav'
431
+ * }
432
+ * ]
433
+ * })
311
434
  *
435
+ * // Using @Sound decorator
312
436
  * @Sound({
313
- * sounds: {
314
- * town: require('./assets/Town_Theme.ogg')
315
- * }
437
+ * id: 'town-music',
438
+ * sound: require('./sound/town.ogg'),
439
+ * loop: true,
440
+ * volume: 0.5
441
+ * })
442
+ * export class TownMusic {}
443
+ *
444
+ * defineModule<RpgClient>({
445
+ * sounds: [TownMusic]
446
+ * })
447
+ *
448
+ * // Multiple sounds in one class
449
+ * @Sound({
450
+ * sounds: {
451
+ * hero: require('./assets/hero.ogg'),
452
+ * monster: require('./assets/monster.ogg')
453
+ * },
454
+ * loop: true
316
455
  * })
317
- * class Sounds {}
456
+ * export class CharacterSounds {}
318
457
  *
319
- * @RpgModule<RpgClient>({
320
- * sounds: [ Sounds ]
458
+ * defineModule<RpgClient>({
459
+ * sounds: [CharacterSounds]
321
460
  * })
322
- * class RpgClientEngine {}
323
461
  * ```
324
462
  *
325
- * @prop {Array<Class>} [sounds]
463
+ * @prop {Array<Object | Class>} [sounds]
326
464
  * @memberof RpgClient
327
465
  * */
328
- sounds?: RpgClass[],
466
+ sounds?: any[],
329
467
 
330
468
  /**
331
469
  * Give the `RpgSprite` class. A Sprite represents a player or an event
332
470
  *
333
471
  * ```ts
334
- * import { RpgSprite, RpgSpriteHooks, RpgClient, RpgModule } from '@rpgjs/client'
472
+ * import { RpgSprite, RpgSpriteHooks, RpgClient, defineModule } from '@rpgjs/client'
335
473
  *
336
474
  * export const sprite: RpgSpriteHooks = {
337
475
  * onInit(sprite: RpgSprite) {}
338
476
  * }
339
477
  *
340
- * @RpgModule<RpgClient>({
478
+ * defineModule<RpgClient>({
341
479
  * sprite
342
480
  * })
343
- * class RpgClientEngine {}
344
481
  * ```
345
482
  *
346
483
  * @prop {RpgSpriteHooks} [sprite]
@@ -352,19 +489,18 @@ export interface RpgClient {
352
489
  * Reference the scenes of the game. Here you can put your own class that inherits RpgSceneMap
353
490
  *
354
491
  * ```ts
355
- * import { RpgSceneMapHooks, RpgClient, RpgModule } from '@rpgjs/client'
492
+ * import { RpgSceneMapHooks, RpgClient, defineModule } from '@rpgjs/client'
356
493
  *
357
494
  * export const sceneMap: RpgSceneMapHooks = {
358
495
  *
359
496
  * }
360
497
  *
361
- * @RpgModule<RpgClient>({
498
+ * defineModule<RpgClient>({
362
499
  * scenes: {
363
500
  * // If you put the RpgSceneMap scene, Thhe key is called mandatory `map`
364
501
  * map: sceneMap
365
502
  * }
366
503
  * })
367
- * class RpgClientEngine {}
368
504
  * ```
369
505
  *
370
506
  * @prop { [sceneName: string]: RpgSceneMapHooks } [scenes]
@@ -374,8 +510,36 @@ export interface RpgClient {
374
510
  map: RpgSceneMapHooks
375
511
  }
376
512
 
377
- effects?: {
513
+ sceneMap?: RpgSceneMapHooks
514
+
515
+ /**
516
+ * Array containing the list of component animations
517
+ * Each element defines a temporary component to display for animations like hits, effects, etc.
518
+ *
519
+ * ```ts
520
+ * import { defineModule, RpgClient } from '@rpgjs/client'
521
+ * import HitComponent from './hit.ce'
522
+ * import ExplosionComponent from './explosion.ce'
523
+ *
524
+ * defineModule<RpgClient>({
525
+ * componentAnimations: [
526
+ * {
527
+ * id: 'hit',
528
+ * component: HitComponent
529
+ * },
530
+ * {
531
+ * id: 'explosion',
532
+ * component: ExplosionComponent
533
+ * }
534
+ * ]
535
+ * })
536
+ * ```
537
+ *
538
+ * @prop {Array<{id: string, component: ComponentFunction}>} [componentAnimations]
539
+ * @memberof RpgClient
540
+ * */
541
+ componentAnimations?: {
378
542
  id: string,
379
- component: any
543
+ component: ComponentFunction
380
544
  }[]
381
545
  }