@rpgjs/client 5.0.0-alpha.3 → 5.0.0-alpha.30

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 (275) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/{index19.js → Game/AnimationManager.js} +4 -3
  3. package/dist/Game/AnimationManager.js.map +1 -0
  4. package/dist/{index30.js → Game/Event.js} +2 -2
  5. package/dist/Game/Event.js.map +1 -0
  6. package/dist/Game/Map.d.ts +8 -1
  7. package/dist/Game/Map.js +54 -0
  8. package/dist/Game/Map.js.map +1 -0
  9. package/dist/Game/Object.d.ts +129 -0
  10. package/dist/Game/Object.js +218 -0
  11. package/dist/Game/Object.js.map +1 -0
  12. package/dist/{index29.js → Game/Player.js} +2 -2
  13. package/dist/Game/Player.js.map +1 -0
  14. package/dist/Gui/Gui.d.ts +177 -5
  15. package/dist/Gui/Gui.js +478 -0
  16. package/dist/Gui/Gui.js.map +1 -0
  17. package/dist/Gui/NotificationManager.d.ts +23 -0
  18. package/dist/Gui/NotificationManager.js +51 -0
  19. package/dist/Gui/NotificationManager.js.map +1 -0
  20. package/dist/Resource.d.ts +97 -0
  21. package/dist/Resource.js +114 -0
  22. package/dist/Resource.js.map +1 -0
  23. package/dist/RpgClient.d.ts +259 -59
  24. package/dist/RpgClientEngine.d.ts +632 -9
  25. package/dist/RpgClientEngine.js +1262 -0
  26. package/dist/RpgClientEngine.js.map +1 -0
  27. package/dist/Sound.d.ts +199 -0
  28. package/dist/Sound.js +97 -0
  29. package/dist/Sound.js.map +1 -0
  30. package/dist/components/animations/animation.ce.js +21 -0
  31. package/dist/components/animations/animation.ce.js.map +1 -0
  32. package/dist/{index23.js → components/animations/hit.ce.js} +3 -3
  33. package/dist/components/animations/hit.ce.js.map +1 -0
  34. package/dist/components/animations/index.d.ts +4 -0
  35. package/dist/components/animations/index.js +10 -0
  36. package/dist/components/animations/index.js.map +1 -0
  37. package/dist/components/character.ce.js +316 -0
  38. package/dist/components/character.ce.js.map +1 -0
  39. package/dist/components/dynamics/parse-value.d.ts +1 -0
  40. package/dist/components/dynamics/parse-value.js +54 -0
  41. package/dist/components/dynamics/parse-value.js.map +1 -0
  42. package/dist/components/dynamics/text.ce.js +141 -0
  43. package/dist/components/dynamics/text.ce.js.map +1 -0
  44. package/dist/components/gui/box.ce.js +27 -0
  45. package/dist/components/gui/box.ce.js.map +1 -0
  46. package/dist/components/gui/dialogbox/index.ce.js +152 -0
  47. package/dist/components/gui/dialogbox/index.ce.js.map +1 -0
  48. package/dist/components/gui/gameover.ce.js +141 -0
  49. package/dist/components/gui/gameover.ce.js.map +1 -0
  50. package/dist/components/gui/hud/hud.ce.js +35 -0
  51. package/dist/components/gui/hud/hud.ce.js.map +1 -0
  52. package/dist/components/gui/index.d.ts +15 -3
  53. package/dist/components/gui/menu/equip-menu.ce.js +349 -0
  54. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -0
  55. package/dist/components/gui/menu/exit-menu.ce.js +35 -0
  56. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -0
  57. package/dist/components/gui/menu/items-menu.ce.js +229 -0
  58. package/dist/components/gui/menu/items-menu.ce.js.map +1 -0
  59. package/dist/components/gui/menu/main-menu.ce.js +205 -0
  60. package/dist/components/gui/menu/main-menu.ce.js.map +1 -0
  61. package/dist/components/gui/menu/options-menu.ce.js +28 -0
  62. package/dist/components/gui/menu/options-menu.ce.js.map +1 -0
  63. package/dist/components/gui/menu/skills-menu.ce.js +53 -0
  64. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -0
  65. package/dist/components/gui/mobile/index.d.ts +8 -0
  66. package/dist/components/gui/mobile/index.js +24 -0
  67. package/dist/components/gui/mobile/index.js.map +1 -0
  68. package/dist/components/gui/mobile/mobile.ce.js +17 -0
  69. package/dist/components/gui/mobile/mobile.ce.js.map +1 -0
  70. package/dist/components/gui/notification/notification.ce.js +38 -0
  71. package/dist/components/gui/notification/notification.ce.js.map +1 -0
  72. package/dist/components/gui/save-load.ce.js +242 -0
  73. package/dist/components/gui/save-load.ce.js.map +1 -0
  74. package/dist/components/gui/shop/shop.ce.js +322 -0
  75. package/dist/components/gui/shop/shop.ce.js.map +1 -0
  76. package/dist/components/gui/title-screen.ce.js +148 -0
  77. package/dist/components/gui/title-screen.ce.js.map +1 -0
  78. package/dist/components/index.d.ts +3 -1
  79. package/dist/components/prebuilt/hp-bar.ce.js +106 -0
  80. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -0
  81. package/dist/components/prebuilt/index.d.ts +19 -0
  82. package/dist/components/prebuilt/light-halo.ce.js +76 -0
  83. package/dist/components/prebuilt/light-halo.ce.js.map +1 -0
  84. package/dist/components/scenes/canvas.ce.js +44 -0
  85. package/dist/components/scenes/canvas.ce.js.map +1 -0
  86. package/dist/components/scenes/draw-map.ce.js +34 -0
  87. package/dist/components/scenes/draw-map.ce.js.map +1 -0
  88. package/dist/{index13.js → components/scenes/event-layer.ce.js} +7 -6
  89. package/dist/components/scenes/event-layer.ce.js.map +1 -0
  90. package/dist/{index6.js → core/inject.js} +2 -2
  91. package/dist/core/inject.js.map +1 -0
  92. package/dist/core/setup.js +16 -0
  93. package/dist/core/setup.js.map +1 -0
  94. package/dist/index.d.ts +15 -1
  95. package/dist/index.js +40 -12
  96. package/dist/index.js.map +1 -1
  97. package/dist/module.d.ts +43 -4
  98. package/dist/module.js +175 -0
  99. package/dist/module.js.map +1 -0
  100. package/dist/node_modules/.pnpm/@signe_di@2.8.2/node_modules/@signe/di/dist/index.js +366 -0
  101. package/dist/node_modules/.pnpm/@signe_di@2.8.2/node_modules/@signe/di/dist/index.js.map +1 -0
  102. package/dist/{index27.js → node_modules/.pnpm/@signe_reactive@2.8.2/node_modules/@signe/reactive/dist/index.js} +229 -11
  103. package/dist/node_modules/.pnpm/@signe_reactive@2.8.2/node_modules/@signe/reactive/dist/index.js.map +1 -0
  104. package/dist/{index20.js → node_modules/.pnpm/@signe_room@2.8.2/node_modules/@signe/room/dist/index.js} +308 -40
  105. package/dist/node_modules/.pnpm/@signe_room@2.8.2/node_modules/@signe/room/dist/index.js.map +1 -0
  106. package/dist/{index26.js → node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/chunk-7QVYU63E.js} +1 -1
  107. package/dist/node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +1 -0
  108. package/dist/{index21.js → node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/client/index.js} +5 -5
  109. package/dist/node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/client/index.js.map +1 -0
  110. package/dist/{index17.js → node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/index.js} +89 -12
  111. package/dist/node_modules/.pnpm/@signe_sync@2.8.2/node_modules/@signe/sync/dist/index.js.map +1 -0
  112. package/dist/{index33.js → node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js} +1 -1
  113. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +1 -0
  114. package/dist/{index31.js → node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js} +2 -2
  115. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +1 -0
  116. package/dist/{index32.js → node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js} +1 -1
  117. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +1 -0
  118. package/dist/{index34.js → node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js} +1 -1
  119. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +1 -0
  120. package/dist/presets/animation.d.ts +31 -0
  121. package/dist/presets/animation.js +27 -0
  122. package/dist/presets/animation.js.map +1 -0
  123. package/dist/presets/faceset.d.ts +30 -0
  124. package/dist/presets/faceset.js +24 -0
  125. package/dist/presets/faceset.js.map +1 -0
  126. package/dist/presets/icon.d.ts +20 -0
  127. package/dist/presets/icon.js +15 -0
  128. package/dist/presets/icon.js.map +1 -0
  129. package/dist/presets/index.d.ts +123 -0
  130. package/dist/presets/index.js +16 -0
  131. package/dist/presets/index.js.map +1 -0
  132. package/dist/presets/lpc.d.ts +89 -0
  133. package/dist/presets/lpc.js +95 -0
  134. package/dist/presets/lpc.js.map +1 -0
  135. package/dist/{index25.js → presets/rmspritesheet.js} +1 -1
  136. package/dist/presets/rmspritesheet.js.map +1 -0
  137. package/dist/{index16.js → services/AbstractSocket.js} +1 -1
  138. package/dist/services/AbstractSocket.js.map +1 -0
  139. package/dist/services/keyboardControls.d.ts +15 -0
  140. package/dist/services/keyboardControls.js +21 -0
  141. package/dist/services/keyboardControls.js.map +1 -0
  142. package/dist/services/loadMap.d.ts +123 -2
  143. package/dist/{index7.js → services/loadMap.js} +12 -4
  144. package/dist/services/loadMap.js.map +1 -0
  145. package/dist/services/mmorpg.d.ts +16 -4
  146. package/dist/services/mmorpg.js +84 -0
  147. package/dist/services/mmorpg.js.map +1 -0
  148. package/dist/services/save.d.ts +19 -0
  149. package/dist/services/save.js +69 -0
  150. package/dist/services/save.js.map +1 -0
  151. package/dist/services/standalone.d.ts +65 -3
  152. package/dist/services/standalone.js +170 -0
  153. package/dist/services/standalone.js.map +1 -0
  154. package/dist/utils/getEntityProp.d.ts +39 -0
  155. package/dist/utils/getEntityProp.js +54 -0
  156. package/dist/utils/getEntityProp.js.map +1 -0
  157. package/package.json +24 -18
  158. package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
  159. package/src/Game/Map.ts +37 -2
  160. package/src/Game/Object.ts +296 -11
  161. package/src/Gui/Gui.ts +506 -18
  162. package/src/Gui/NotificationManager.ts +69 -0
  163. package/src/Resource.ts +150 -0
  164. package/src/RpgClient.ts +264 -58
  165. package/src/RpgClientEngine.ts +1421 -44
  166. package/src/Sound.ts +253 -0
  167. package/src/components/{effects → animations}/animation.ce +3 -6
  168. package/src/components/{effects → animations}/index.ts +1 -1
  169. package/src/components/character.ce +406 -40
  170. package/src/components/dynamics/parse-value.ts +80 -0
  171. package/src/components/dynamics/text.ce +183 -0
  172. package/src/components/gui/box.ce +17 -0
  173. package/src/components/gui/dialogbox/index.ce +204 -187
  174. package/src/components/gui/gameover.ce +158 -0
  175. package/src/components/gui/hud/hud.ce +56 -0
  176. package/src/components/gui/index.ts +30 -4
  177. package/src/components/gui/menu/equip-menu.ce +410 -0
  178. package/src/components/gui/menu/exit-menu.ce +41 -0
  179. package/src/components/gui/menu/items-menu.ce +317 -0
  180. package/src/components/gui/menu/main-menu.ce +291 -0
  181. package/src/components/gui/menu/options-menu.ce +35 -0
  182. package/src/components/gui/menu/skills-menu.ce +83 -0
  183. package/src/components/gui/mobile/index.ts +24 -0
  184. package/src/components/gui/mobile/mobile.ce +80 -0
  185. package/src/components/gui/notification/notification.ce +51 -0
  186. package/src/components/gui/save-load.ce +208 -0
  187. package/src/components/gui/shop/shop.ce +493 -0
  188. package/src/components/gui/title-screen.ce +163 -0
  189. package/src/components/index.ts +5 -1
  190. package/src/components/prebuilt/hp-bar.ce +255 -0
  191. package/src/components/prebuilt/index.ts +24 -0
  192. package/src/components/prebuilt/light-halo.ce +148 -0
  193. package/src/components/scenes/canvas.ce +19 -14
  194. package/src/components/scenes/draw-map.ce +21 -29
  195. package/src/components/scenes/event-layer.ce +10 -3
  196. package/src/components/scenes/transition.ce +60 -0
  197. package/src/core/setup.ts +2 -0
  198. package/src/index.ts +16 -2
  199. package/src/module.ts +145 -9
  200. package/src/presets/animation.ts +46 -0
  201. package/src/presets/faceset.ts +60 -0
  202. package/src/presets/icon.ts +17 -0
  203. package/src/presets/index.ts +9 -1
  204. package/src/presets/lpc.ts +108 -0
  205. package/src/services/keyboardControls.ts +20 -0
  206. package/src/services/loadMap.ts +132 -3
  207. package/src/services/mmorpg.ts +39 -5
  208. package/src/services/save.ts +103 -0
  209. package/src/services/standalone.ts +107 -15
  210. package/src/utils/getEntityProp.ts +87 -0
  211. package/tsconfig.json +1 -1
  212. package/vite.config.ts +5 -3
  213. package/CHANGELOG.md +0 -9
  214. package/dist/Game/EffectManager.d.ts +0 -5
  215. package/dist/components/effects/index.d.ts +0 -4
  216. package/dist/index10.js +0 -8
  217. package/dist/index10.js.map +0 -1
  218. package/dist/index11.js +0 -10
  219. package/dist/index11.js.map +0 -1
  220. package/dist/index12.js +0 -8
  221. package/dist/index12.js.map +0 -1
  222. package/dist/index13.js.map +0 -1
  223. package/dist/index14.js +0 -50
  224. package/dist/index14.js.map +0 -1
  225. package/dist/index15.js +0 -191
  226. package/dist/index15.js.map +0 -1
  227. package/dist/index16.js.map +0 -1
  228. package/dist/index17.js.map +0 -1
  229. package/dist/index18.js +0 -31
  230. package/dist/index18.js.map +0 -1
  231. package/dist/index19.js.map +0 -1
  232. package/dist/index2.js +0 -112
  233. package/dist/index2.js.map +0 -1
  234. package/dist/index20.js.map +0 -1
  235. package/dist/index21.js.map +0 -1
  236. package/dist/index22.js +0 -109
  237. package/dist/index22.js.map +0 -1
  238. package/dist/index23.js.map +0 -1
  239. package/dist/index24.js +0 -21
  240. package/dist/index24.js.map +0 -1
  241. package/dist/index25.js.map +0 -1
  242. package/dist/index26.js.map +0 -1
  243. package/dist/index27.js.map +0 -1
  244. package/dist/index28.js +0 -25
  245. package/dist/index28.js.map +0 -1
  246. package/dist/index29.js.map +0 -1
  247. package/dist/index3.js +0 -87
  248. package/dist/index3.js.map +0 -1
  249. package/dist/index30.js.map +0 -1
  250. package/dist/index31.js.map +0 -1
  251. package/dist/index32.js.map +0 -1
  252. package/dist/index33.js.map +0 -1
  253. package/dist/index34.js.map +0 -1
  254. package/dist/index35.js +0 -91
  255. package/dist/index35.js.map +0 -1
  256. package/dist/index36.js +0 -61
  257. package/dist/index36.js.map +0 -1
  258. package/dist/index37.js +0 -20
  259. package/dist/index37.js.map +0 -1
  260. package/dist/index38.js +0 -20
  261. package/dist/index38.js.map +0 -1
  262. package/dist/index4.js +0 -54
  263. package/dist/index4.js.map +0 -1
  264. package/dist/index5.js +0 -15
  265. package/dist/index5.js.map +0 -1
  266. package/dist/index6.js.map +0 -1
  267. package/dist/index7.js.map +0 -1
  268. package/dist/index8.js +0 -90
  269. package/dist/index8.js.map +0 -1
  270. package/dist/index9.js +0 -76
  271. package/dist/index9.js.map +0 -1
  272. package/src/components/gui/dialogbox/itemMenu.ce +0 -23
  273. package/src/components/gui/dialogbox/selection.ce +0 -67
  274. package/src/components/scenes/element-map.ce +0 -23
  275. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -1,16 +1,301 @@
1
- import { RpgCommonPlayer } from "@rpgjs/common";
2
- import { trigger, signal } from "canvasengine";
1
+ import { Hooks, ModulesToken, RpgCommonPlayer } from "@rpgjs/common";
2
+ import { trigger, signal, effect } from "canvasengine";
3
+ import { filter, from, map, Subscription, switchMap } from "rxjs";
4
+ import { inject } from "../core/inject";
5
+ import { RpgClientEngine } from "../RpgClientEngine";
6
+ import TextComponent from "../components/dynamics/text.ce";
7
+
8
+ const DYNAMIC_COMPONENTS = {
9
+ text: TextComponent,
10
+ }
3
11
 
4
12
  export abstract class RpgClientObject extends RpgCommonPlayer {
5
13
  abstract type: string;
6
- emitParticleTrigger = trigger()
7
- particleName = signal('')
14
+ emitParticleTrigger = trigger();
15
+ particleName = signal("");
16
+ animationCurrentIndex = signal(0);
17
+ animationIsPlaying = signal(false);
18
+ _param = signal({});
19
+ frames: { x: number; y: number; ts: number }[] = [];
20
+ graphicsSignals = signal<any[]>([]);
21
+ _component = {} // temporary component memory
22
+ flashTrigger = trigger();
23
+
24
+ constructor() {
25
+ super();
26
+ this.hooks.callHooks("client-sprite-onInit", this).subscribe();
27
+
28
+ this._frames.observable.subscribe(({ items }) => {
29
+ if (!this.id) return;
30
+ //if (this.id == this.engine.playerIdSignal()!) return;
31
+ this.frames = [...this.frames, ...items];
32
+ });
33
+
34
+ this.graphics.observable
35
+ .pipe(
36
+ map(({ items }) => items),
37
+ filter(graphics => graphics.length > 0),
38
+ switchMap(graphics => from(Promise.all(graphics.map(graphic => this.engine.getSpriteSheet(graphic)))))
39
+ )
40
+ .subscribe((sheets) => {
41
+ this.graphicsSignals.set(sheets);
42
+ });
43
+
44
+ this.componentsTop.observable
45
+ .pipe(
46
+ filter(value => value !== null && value !== undefined),
47
+ map((value) => typeof value === 'string' ? JSON.parse(value) : value),
48
+ )
49
+ .subscribe(({components}) => {
50
+ for (const component of components) {
51
+ for (const [key, value] of Object.entries(component)) {
52
+ this._component = value as any; // temporary component memory
53
+ console.log(value)
54
+ const type = (value as any).type as keyof typeof DYNAMIC_COMPONENTS;
55
+ if (DYNAMIC_COMPONENTS[type]) {
56
+ this.engine.addSpriteComponentInFront(DYNAMIC_COMPONENTS[type]);
57
+ }
58
+ }
59
+ }
60
+ });
61
+
62
+ this.engine.tick
63
+ .pipe
64
+ //throttleTime(10)
65
+ ()
66
+ .subscribe(() => {
67
+ const frame = this.frames.shift();
68
+ if (frame) {
69
+ if (!frame.x || !frame.y) return;
70
+ this.engine.scene.setBodyPosition(
71
+ this.id,
72
+ frame.x,
73
+ frame.y,
74
+ "top-left"
75
+ );
76
+ }
77
+ });
78
+ }
79
+
80
+ get hooks() {
81
+ return inject<Hooks>(ModulesToken);
82
+ }
83
+
84
+ get engine() {
85
+ return inject(RpgClientEngine);
86
+ }
87
+
88
+ private animationSubscription?: Subscription;
89
+
90
+ /**
91
+ * Trigger a flash animation on this sprite
92
+ *
93
+ * This method triggers a flash effect using CanvasEngine's flash directive.
94
+ * The flash can be configured with various options including type (alpha, tint, or both),
95
+ * duration, cycles, and color.
96
+ *
97
+ * ## Design
98
+ *
99
+ * The flash uses a trigger system that is connected to the flash directive in the
100
+ * character component. This allows for flexible configuration and can be triggered
101
+ * from both server events and client-side code.
102
+ *
103
+ * @param options - Flash configuration options
104
+ * @param options.type - Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both' (default: 'alpha')
105
+ * @param options.duration - Duration of the flash animation in milliseconds (default: 300)
106
+ * @param options.cycles - Number of flash cycles (flash on/off) (default: 1)
107
+ * @param options.alpha - Alpha value when flashing, from 0 to 1 (default: 0.3)
108
+ * @param options.tint - Tint color when flashing as hex value or color name (default: 0xffffff - white)
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * // Simple flash with default settings (alpha flash)
113
+ * player.flash();
114
+ *
115
+ * // Flash with red tint
116
+ * player.flash({ type: 'tint', tint: 0xff0000 });
117
+ *
118
+ * // Flash with both alpha and tint
119
+ * player.flash({
120
+ * type: 'both',
121
+ * alpha: 0.5,
122
+ * tint: 0xff0000,
123
+ * duration: 200,
124
+ * cycles: 2
125
+ * });
126
+ *
127
+ * // Quick damage flash
128
+ * player.flash({
129
+ * type: 'tint',
130
+ * tint: 0xff0000,
131
+ * duration: 150,
132
+ * cycles: 1
133
+ * });
134
+ * ```
135
+ */
136
+ flash(options?: {
137
+ type?: 'alpha' | 'tint' | 'both';
138
+ duration?: number;
139
+ cycles?: number;
140
+ alpha?: number;
141
+ tint?: number | string;
142
+ }): void {
143
+ const flashOptions = {
144
+ type: options?.type || 'alpha',
145
+ duration: options?.duration ?? 300,
146
+ cycles: options?.cycles ?? 1,
147
+ alpha: options?.alpha ?? 0.3,
148
+ tint: options?.tint ?? 0xffffff,
149
+ };
150
+
151
+ // Convert color name to hex if needed
152
+ let tintValue = flashOptions.tint;
153
+ if (typeof tintValue === 'string') {
154
+ // Common color name to hex mapping
155
+ const colorMap: Record<string, number> = {
156
+ 'white': 0xffffff,
157
+ 'red': 0xff0000,
158
+ 'green': 0x00ff00,
159
+ 'blue': 0x0000ff,
160
+ 'yellow': 0xffff00,
161
+ 'cyan': 0x00ffff,
162
+ 'magenta': 0xff00ff,
163
+ 'black': 0x000000,
164
+ };
165
+ tintValue = colorMap[tintValue.toLowerCase()] ?? 0xffffff;
166
+ }
167
+
168
+ this.flashTrigger.start({
169
+ ...flashOptions,
170
+ tint: tintValue,
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Reset animation state when animation changes externally
176
+ *
177
+ * This method should be called when the animation changes due to movement
178
+ * or other external factors to ensure the animation system doesn't get stuck
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * // Reset when player starts moving
183
+ * player.resetAnimationState();
184
+ * ```
185
+ */
186
+ resetAnimationState() {
187
+ this.animationIsPlaying.set(false);
188
+ this.animationCurrentIndex.set(0);
189
+ if (this.animationSubscription) {
190
+ this.animationSubscription.unsubscribe();
191
+ this.animationSubscription = undefined;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Set a custom animation for a specific number of times
197
+ *
198
+ * Plays a custom animation for the specified number of repetitions.
199
+ * The animation system prevents overlapping animations and automatically
200
+ * returns to the previous animation when complete.
201
+ *
202
+ * @param animationName - Name of the animation to play
203
+ * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * // Play attack animation 3 times
208
+ * player.setAnimation('attack', 3);
209
+ *
210
+ * // Play continuous spell animation
211
+ * player.setAnimation('spell');
212
+ * ```
213
+ */
214
+ setAnimation(animationName: string, nbTimes?: number): void;
215
+ /**
216
+ * Set a custom animation with temporary graphic change
217
+ *
218
+ * Plays a custom animation for the specified number of repetitions and temporarily
219
+ * changes the player's graphic (sprite sheet) during the animation. The graphic
220
+ * is automatically reset when the animation finishes.
221
+ *
222
+ * @param animationName - Name of the animation to play
223
+ * @param graphic - The graphic(s) to temporarily use during the animation
224
+ * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
225
+ *
226
+ * @example
227
+ * ```ts
228
+ * // Play attack animation with temporary graphic change
229
+ * player.setAnimation('attack', 'hero_attack', 3);
230
+ * ```
231
+ */
232
+ setAnimation(animationName: string, graphic?: string | string[], nbTimes?: number): void;
233
+ setAnimation(animationName: string, graphicOrNbTimes?: string | string[] | number, nbTimes?: number): void {
234
+ if (this.animationIsPlaying()) return;
235
+ this.animationIsPlaying.set(true);
236
+ const previousAnimationName = this.animationName();
237
+ const previousGraphics = this.graphics();
238
+ this.animationCurrentIndex.set(0);
239
+
240
+ let graphic: string | string[] | undefined;
241
+ let finalNbTimes: number = Infinity;
242
+
243
+ // Handle overloads
244
+ if (typeof graphicOrNbTimes === 'number') {
245
+ // setAnimation(animationName, nbTimes)
246
+ finalNbTimes = graphicOrNbTimes;
247
+ } else if (graphicOrNbTimes !== undefined) {
248
+ // setAnimation(animationName, graphic, nbTimes)
249
+ graphic = graphicOrNbTimes;
250
+ finalNbTimes = nbTimes ?? Infinity;
251
+ } else {
252
+ // setAnimation(animationName) - nbTimes remains Infinity
253
+ finalNbTimes = Infinity;
254
+ }
255
+
256
+ // Temporarily change graphic if provided
257
+ if (graphic !== undefined) {
258
+ if (Array.isArray(graphic)) {
259
+ this.graphics.set(graphic);
260
+ } else {
261
+ this.graphics.set([graphic]);
262
+ }
263
+ }
264
+
265
+ // Clean up any existing subscription
266
+ if (this.animationSubscription) {
267
+ this.animationSubscription.unsubscribe();
268
+ }
269
+
270
+ this.animationSubscription =
271
+ this.animationCurrentIndex.observable.subscribe((index) => {
272
+ if (index >= finalNbTimes) {
273
+ this.animationCurrentIndex.set(0);
274
+ this.animationName.set(previousAnimationName);
275
+ // Reset graphic to previous value if it was changed
276
+ if (graphic !== undefined) {
277
+ this.graphics.set(previousGraphics);
278
+ }
279
+ this.animationIsPlaying.set(false);
280
+ if (this.animationSubscription) {
281
+ this.animationSubscription.unsubscribe();
282
+ this.animationSubscription = undefined;
283
+ }
284
+ }
285
+ });
286
+ this.animationName.set(animationName);
287
+ }
288
+
289
+ showComponentAnimation(id: string, params: any) {
290
+ const engine = inject(RpgClientEngine);
291
+ engine.getComponentAnimation(id).displayEffect(params, this);
292
+ }
293
+
294
+ isEvent(): boolean {
295
+ return this.type === 'event';
296
+ }
8
297
 
9
- flash(color: string, duration: number = 100) {
10
- const lastTint = this.tint()
11
- this.tint.set(color);
12
- setTimeout(() => {
13
- this.tint.set(lastTint)
14
- }, duration)
298
+ isPlayer(): boolean {
299
+ return this.type === 'player';
15
300
  }
16
- }
301
+ }