@rpgjs/server 5.0.0-alpha.3 → 5.0.0-alpha.31

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 (99) hide show
  1. package/dist/Gui/DialogGui.d.ts +5 -0
  2. package/dist/Gui/GameoverGui.d.ts +23 -0
  3. package/dist/Gui/Gui.d.ts +6 -0
  4. package/dist/Gui/MenuGui.d.ts +22 -3
  5. package/dist/Gui/NotificationGui.d.ts +1 -2
  6. package/dist/Gui/SaveLoadGui.d.ts +13 -0
  7. package/dist/Gui/ShopGui.d.ts +24 -3
  8. package/dist/Gui/TitleGui.d.ts +23 -0
  9. package/dist/Gui/index.d.ts +10 -1
  10. package/dist/Player/BattleManager.d.ts +34 -12
  11. package/dist/Player/ClassManager.d.ts +46 -13
  12. package/dist/Player/ComponentManager.d.ts +123 -0
  13. package/dist/Player/Components.d.ts +345 -0
  14. package/dist/Player/EffectManager.d.ts +86 -0
  15. package/dist/Player/ElementManager.d.ts +104 -0
  16. package/dist/Player/GoldManager.d.ts +22 -0
  17. package/dist/Player/GuiManager.d.ts +259 -0
  18. package/dist/Player/ItemFixture.d.ts +6 -0
  19. package/dist/Player/ItemManager.d.ts +451 -9
  20. package/dist/Player/MoveManager.d.ts +324 -69
  21. package/dist/Player/ParameterManager.d.ts +344 -14
  22. package/dist/Player/Player.d.ts +460 -8
  23. package/dist/Player/SkillManager.d.ts +197 -15
  24. package/dist/Player/StateManager.d.ts +89 -25
  25. package/dist/Player/VariableManager.d.ts +74 -0
  26. package/dist/RpgServer.d.ts +462 -62
  27. package/dist/RpgServerEngine.d.ts +2 -1
  28. package/dist/decorators/event.d.ts +46 -0
  29. package/dist/decorators/map.d.ts +265 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.js +21056 -20733
  32. package/dist/index.js.map +1 -1
  33. package/dist/module.d.ts +43 -1
  34. package/dist/presets/index.d.ts +0 -9
  35. package/dist/rooms/BaseRoom.d.ts +132 -0
  36. package/dist/rooms/lobby.d.ts +10 -2
  37. package/dist/rooms/map.d.ts +1163 -14
  38. package/dist/services/save.d.ts +43 -0
  39. package/dist/storage/index.d.ts +1 -0
  40. package/dist/storage/localStorage.d.ts +23 -0
  41. package/package.json +19 -15
  42. package/src/Gui/DialogGui.ts +19 -4
  43. package/src/Gui/GameoverGui.ts +39 -0
  44. package/src/Gui/Gui.ts +23 -1
  45. package/src/Gui/MenuGui.ts +155 -6
  46. package/src/Gui/NotificationGui.ts +1 -2
  47. package/src/Gui/SaveLoadGui.ts +60 -0
  48. package/src/Gui/ShopGui.ts +145 -16
  49. package/src/Gui/TitleGui.ts +39 -0
  50. package/src/Gui/index.ts +15 -2
  51. package/src/Player/BattleManager.ts +91 -49
  52. package/src/Player/ClassManager.ts +113 -48
  53. package/src/Player/ComponentManager.ts +425 -19
  54. package/src/Player/Components.ts +380 -0
  55. package/src/Player/EffectManager.ts +81 -44
  56. package/src/Player/ElementManager.ts +109 -86
  57. package/src/Player/GoldManager.ts +32 -35
  58. package/src/Player/GuiManager.ts +308 -150
  59. package/src/Player/ItemFixture.ts +4 -5
  60. package/src/Player/ItemManager.ts +768 -352
  61. package/src/Player/MoveManager.ts +1482 -772
  62. package/src/Player/ParameterManager.ts +514 -104
  63. package/src/Player/Player.ts +1138 -88
  64. package/src/Player/SkillManager.ts +520 -195
  65. package/src/Player/StateManager.ts +170 -182
  66. package/src/Player/VariableManager.ts +101 -63
  67. package/src/RpgServer.ts +481 -61
  68. package/src/core/context.ts +1 -0
  69. package/src/decorators/event.ts +61 -0
  70. package/src/decorators/map.ts +302 -0
  71. package/src/index.ts +11 -1
  72. package/src/module.ts +118 -2
  73. package/src/presets/index.ts +1 -10
  74. package/src/rooms/BaseRoom.ts +232 -0
  75. package/src/rooms/lobby.ts +25 -7
  76. package/src/rooms/map.ts +1848 -73
  77. package/src/services/save.ts +147 -0
  78. package/src/storage/index.ts +1 -0
  79. package/src/storage/localStorage.ts +76 -0
  80. package/tests/battle.spec.ts +375 -0
  81. package/tests/change-map.spec.ts +72 -0
  82. package/tests/class.spec.ts +274 -0
  83. package/tests/effect.spec.ts +219 -0
  84. package/tests/element.spec.ts +221 -0
  85. package/tests/event.spec.ts +80 -0
  86. package/tests/gold.spec.ts +99 -0
  87. package/tests/item.spec.ts +591 -0
  88. package/tests/module.spec.ts +38 -0
  89. package/tests/move.spec.ts +601 -0
  90. package/tests/player-param.spec.ts +28 -0
  91. package/tests/random-move.spec.ts +65 -0
  92. package/tests/skill.spec.ts +658 -0
  93. package/tests/state.spec.ts +467 -0
  94. package/tests/variable.spec.ts +185 -0
  95. package/tests/world-maps.spec.ts +814 -0
  96. package/vite.config.ts +16 -0
  97. package/CHANGELOG.md +0 -9
  98. package/dist/Player/Event.d.ts +0 -0
  99. package/src/Player/Event.ts +0 -0
@@ -1,59 +1,511 @@
1
- import { Constructor, isString, RpgCommonPlayer } from "@rpgjs/common";
2
- import { MAXHP, MAXSP } from "../presets";
3
-
4
- export interface IWithParameterManager {
5
- parameters: Map<string, any>
6
- hp: number
7
- sp: number
8
- exp: number
9
- level: number
10
- expForNextlevel: number
11
- param: { [key: string]: number }
12
- paramsModifier: { [key: string]: { value?: number, rate?: number } }
13
- }
1
+ import { isString, PlayerCtor } from "@rpgjs/common";
2
+ import { signal, computed, WritableSignal, ComputedSignal } from "@signe/reactive";
3
+ import { MAXHP, MAXSP } from "@rpgjs/common";
4
+ import { type } from "@signe/sync";
5
+
6
+ export type ExpCurve = {
7
+ basis: number;
8
+ extra: number;
9
+ accelerationA: number;
10
+ accelerationB: number;
11
+ };
12
+
13
+ /**
14
+ * Interface for Parameter Manager functionality
15
+ *
16
+ * Provides comprehensive parameter management including health points (HP), skill points (SP),
17
+ * experience and level progression, custom parameters, and parameter modifiers.
18
+ */
19
+ export interface IParameterManager {
20
+ /**
21
+ * ```ts
22
+ * player.initialLevel = 5
23
+ * ```
24
+ *
25
+ * @title Set initial level
26
+ * @prop {number} player.initialLevel
27
+ * @default 1
28
+ * @memberof ParameterManager
29
+ * */
30
+ initialLevel: number;
31
+
32
+ /**
33
+ * ```ts
34
+ * player.finalLevel = 50
35
+ * ```
36
+ *
37
+ * @title Set final level
38
+ * @prop {number} player.finalLevel
39
+ * @default 99
40
+ * @memberof ParameterManager
41
+ * */
42
+ finalLevel: number;
43
+
44
+ /**
45
+ * With Object-based syntax, you can use following options:
46
+ * - `basis: number`
47
+ * - `extra: number`
48
+ * - `accelerationA: number`
49
+ * - `accelerationB: number`
50
+ * @title Change Experience Curve
51
+ * @prop {object} player.expCurve
52
+ * @default
53
+ * ```ts
54
+ * {
55
+ * basis: 30,
56
+ * extra: 20,
57
+ * accelerationA: 30,
58
+ * accelerationB: 30
59
+ * }
60
+ * ```
61
+ * @memberof ParameterManager
62
+ * */
63
+ expCurve: ExpCurve;
64
+
65
+ /**
66
+ * Changes the health points
67
+ * - Cannot exceed the MaxHP parameter
68
+ * - Cannot have a negative value
69
+ * - If the value is 0, a hook named `onDead()` is called in the RpgPlayer class.
70
+ *
71
+ * ```ts
72
+ * player.hp = 100
73
+ * ```
74
+ * @title Change HP
75
+ * @prop {number} player.hp
76
+ * @default MaxHPValue
77
+ * @memberof ParameterManager
78
+ * */
79
+ hp: number;
80
+
81
+ /**
82
+ * Changes the skill points
83
+ * - Cannot exceed the MaxSP parameter
84
+ * - Cannot have a negative value
85
+ *
86
+ * ```ts
87
+ * player.sp = 200
88
+ * ```
89
+ * @title Change SP
90
+ * @prop {number} player.sp
91
+ * @default MaxSPValue
92
+ * @memberof ParameterManager
93
+ * */
94
+ sp: number;
95
+
96
+ /**
97
+ * Changing the player's experience.
98
+ * ```ts
99
+ * player.exp += 100
100
+ * ```
101
+ *
102
+ * Levels are based on the experience curve.
103
+ *
104
+ * ```ts
105
+ * console.log(player.level) // 1
106
+ * console.log(player.expForNextlevel) // 150
107
+ * player.exp += 160
108
+ * console.log(player.level) // 2
109
+ * ```
110
+ *
111
+ * @title Change Experience
112
+ * @prop {number} player.exp
113
+ * @default 0
114
+ * @memberof ParameterManager
115
+ * */
116
+ exp: number;
117
+
118
+ /**
119
+ * Changing the player's level.
120
+ *
121
+ * ```ts
122
+ * player.level += 1
123
+ * ```
124
+ *
125
+ * The level will be between the initial level given by the `initialLevel` and final level given by `finalLevel`
126
+ *
127
+ * ```ts
128
+ * player.finalLevel = 50
129
+ * player.level = 60
130
+ * console.log(player.level) // 50
131
+ * ```
132
+ *
133
+ * @title Change Level
134
+ * @prop {number} player.level
135
+ * @default 1
136
+ * @memberof ParameterManager
137
+ * */
138
+ level: number;
139
+
140
+ /**
141
+ * ```ts
142
+ * console.log(player.expForNextlevel) // 150
143
+ * ```
144
+ * @title Experience for next level ?
145
+ * @prop {number} player.expForNextlevel
146
+ * @readonly
147
+ * @memberof ParameterManager
148
+ * */
149
+ readonly expForNextlevel: number;
150
+
151
+ /**
152
+ * Read the value of a parameter. Put the name of the parameter.
153
+ *
154
+ * ```ts
155
+ * import { Presets } from '@rpgjs/server'
156
+ *
157
+ * const { MAXHP } = Presets
158
+ *
159
+ * console.log(player.param[MAXHP])
160
+ * ```
161
+ *
162
+ * > Possible to use the `player.getParamValue(name)` method instead
163
+ * @title Get Param Value
164
+ * @prop {object} player.param
165
+ * @readonly
166
+ * @memberof ParameterManager
167
+ * */
168
+ readonly param: { [key: string]: number };
169
+
170
+ /**
171
+ * Direct parameter modifiers (reactive signal)
172
+ *
173
+ * > It is important that these parameters have been created beforehand with the `addParameter()` method.
174
+ * > By default, the following settings have been created:
175
+ * - maxhp
176
+ * - maxsp
177
+ * - str
178
+ * - int
179
+ * - dex
180
+ * - agi
181
+ *
182
+ * **Object Key**
183
+ *
184
+ * The key of the object is the name of the parameter
185
+ *
186
+ * > The good practice is to retrieve the name coming from a constant
187
+ *
188
+ * **Object Value**
189
+ *
190
+ * The value of the key is an object containing:
191
+ * ```
192
+ * {
193
+ * value: number,
194
+ * rate: number
195
+ * }
196
+ * ```
197
+ *
198
+ * - value: Adds a number to the parameter
199
+ * - rate: Adds a rate to the parameter
200
+ *
201
+ * > Note that you can put both (value and rate)
202
+ *
203
+ * This property uses reactive signals - changes automatically trigger parameter recalculation.
204
+ * The final parameter values in `param` include aggregated modifiers from equipment, states, etc.
205
+ *
206
+ * @prop {Object} [paramsModifier]
207
+ * @example
208
+ *
209
+ * ```ts
210
+ * import { Presets } from '@rpgjs/server'
211
+ *
212
+ * const { MAXHP } = Presets
213
+ *
214
+ * // Set direct modifiers (reactive)
215
+ * player.paramsModifier = {
216
+ * [MAXHP]: {
217
+ * value: 100
218
+ * }
219
+ * }
220
+ *
221
+ * // Parameters automatically recalculate
222
+ * console.log(player.param[MAXHP]); // Updated value
223
+ * ```
224
+ *
225
+ * @title Set Parameters Modifier
226
+ * @prop {object} paramsModifier
227
+ * @memberof ParameterManager
228
+ * */
229
+ paramsModifier: {
230
+ [key: string]: {
231
+ value?: number,
232
+ rate?: number
233
+ }
234
+ };
14
235
 
15
- interface PlayerWithMixins extends RpgCommonPlayer {
16
- databaseById?(id: string): any;
236
+ /**
237
+ * Get or set the parameters object
238
+ *
239
+ * @prop {object} parameters
240
+ * @memberof ParameterManager
241
+ */
242
+ parameters: { [key: string]: { start: number, end: number } };
243
+
244
+ /**
245
+ * Get the value of a specific parameter by name
246
+ *
247
+ * @deprecated Use `player.param[name]` instead for better reactivity
248
+ * @param name - The name of the parameter to get
249
+ * @returns The calculated parameter value
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * import { Presets } from '@rpgjs/server'
254
+ *
255
+ * const { MAXHP } = Presets
256
+ *
257
+ * // Preferred way (reactive)
258
+ * const maxHp = player.param[MAXHP];
259
+ *
260
+ * // Legacy way (still works)
261
+ * const maxHp = player.getParamValue(MAXHP);
262
+ * ```
263
+ */
264
+ getParamValue(name: string): number;
265
+
266
+ /**
267
+ * Give a new parameter. Give a start value and an end value.
268
+ * The start value will be set to the level set at `player.initialLevel` and the end value will be linked to the level set at `player.finalLevel`.
269
+ *
270
+ * ```ts
271
+ * const SPEED = 'speed'
272
+ *
273
+ * player.addParameter(SPEED, {
274
+ * start: 10,
275
+ * end: 100
276
+ * })
277
+ *
278
+ * player.param[SPEED] // 10
279
+ * player.level += 5
280
+ * player.param[SPEED] // 14
281
+ * ```
282
+ *
283
+ * @title Add custom parameters
284
+ * @method player.addParameter(name,curve)
285
+ * @param {string} name - The name of the parameter
286
+ * @param {object} curve - Scheme of the object: { start: number, end: number }
287
+ * @returns {void}
288
+ * @memberof ParameterManager
289
+ * */
290
+ addParameter(name: string, curve: { start: number, end: number }): void;
291
+
292
+ /**
293
+ * Gives back in percentage of health points to skill points
294
+ *
295
+ * ```ts
296
+ * import { Presets } from '@rpgjs/server'
297
+ *
298
+ * const { MAXHP } = Presets
299
+ *
300
+ * console.log(player.param[MAXHP]) // 800
301
+ * player.hp = 100
302
+ * player.recovery({ hp: 0.5 }) // = 800 * 0.5
303
+ * console.log(player.hp) // 400
304
+ * ```
305
+ *
306
+ * @title Recovery HP and/or SP
307
+ * @method player.recovery(params)
308
+ * @param {object} params - Scheme of the object: { hp: number, sp: number }. The values of the numbers must be in 0 and 1
309
+ * @returns {void}
310
+ * @memberof ParameterManager
311
+ * */
312
+ recovery(params: { hp?: number, sp?: number }): void;
313
+
314
+ /**
315
+ * restores all HP and SP
316
+ *
317
+ * ```ts
318
+ * import { Presets } from '@rpgjs/server'
319
+ *
320
+ * const { MAXHP, MAXSP } = Presets
321
+ *
322
+ * console.log(player.param[MAXHP], player.param[MAXSP]) // 800, 230
323
+ * player.hp = 100
324
+ * player.sp = 0
325
+ * player.allRecovery()
326
+ * console.log(player.hp, player.sp) // 800, 230
327
+ * ```
328
+ *
329
+ * @title All Recovery
330
+ * @method player.allRecovery()
331
+ * @returns {void}
332
+ * @memberof ParameterManager
333
+ * */
334
+ allRecovery(): void;
17
335
  }
18
336
 
19
337
  /**
20
- * Mixin that adds parameter management functionality to a player class.
338
+ * Parameter Manager Mixin with Reactive Signals
21
339
  *
22
- * This mixin provides comprehensive parameter management including:
23
- * - Health Points (HP) and Skill Points (SP) management
24
- * - Experience and level progression system
25
- * - Custom parameter creation and modification
26
- * - Parameter modifiers for temporary stat changes
340
+ * Provides comprehensive parameter management functionality using reactive signals from `@signe/reactive`.
341
+ * This mixin handles health points (HP), skill points (SP), experience and level progression,
342
+ * custom parameters, and parameter modifiers with automatic reactivity.
343
+ *
344
+ * **Key Features:**
345
+ * - ✨ **Reactive Parameters**: All parameters automatically recalculate when level or modifiers change
346
+ * - 🚀 **Performance Optimized**: Uses computed signals to avoid unnecessary recalculations
347
+ * - 🔄 **Real-time Updates**: Changes propagate automatically throughout the system
348
+ * - 🎯 **Type Safe**: Full TypeScript support with proper type inference
27
349
  *
28
350
  * @template TBase - The base class constructor type
29
- * @param Base - The base class to extend
30
- * @returns A new class that extends the base with parameter management capabilities
351
+ * @param Base - The base class to extend with parameter management
352
+ * @returns Extended class with reactive parameter management methods
31
353
  *
32
354
  * @example
33
355
  * ```ts
34
356
  * class MyPlayer extends WithParameterManager(BasePlayer) {
35
357
  * constructor() {
36
358
  * super();
359
+ *
360
+ * // Add custom parameters
37
361
  * this.addParameter('strength', { start: 10, end: 100 });
362
+ * this.addParameter('magic', { start: 5, end: 80 });
38
363
  * }
39
364
  * }
365
+ *
366
+ * const player = new MyPlayer();
367
+ *
368
+ * // Reactive parameter updates
369
+ * player.level = 5;
370
+ * console.log(player.param.strength); // Automatically calculated for level 5
371
+ *
372
+ * // Reactive modifiers
373
+ * player.paramsModifier = {
374
+ * [MAXHP]: { value: 100, rate: 1.2 }
375
+ * };
376
+ * console.log(player.param[MAXHP]); // Automatically includes modifiers
40
377
  * ```
41
378
  */
42
- export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>(
43
- Base: TBase
44
- ): TBase & Constructor<IWithParameterManager> {
45
- return class extends Base implements IWithParameterManager {
46
- private _paramsModifier: {
379
+ export function WithParameterManager<TBase extends PlayerCtor>(Base: TBase) {
380
+ return class extends Base {
381
+ /**
382
+ * Signal for parameter modifiers - allows reactive updates when modifiers change
383
+ *
384
+ * This signal tracks temporary parameter modifications from equipment, states, etc.
385
+ * When updated, it automatically triggers recalculation of all computed parameters.
386
+ *
387
+ * @example
388
+ * ```ts
389
+ * // Set modifier that adds 100 to MaxHP
390
+ * player.paramsModifier = {
391
+ * [MAXHP]: { value: 100 }
392
+ * };
393
+ *
394
+ * // Parameters automatically recalculate
395
+ * console.log(player.param[MAXHP]); // Updated value
396
+ * ```
397
+ */
398
+ private _paramsModifierSignal = type(signal<{
47
399
  [key: string]: {
48
400
  value?: number,
49
401
  rate?: number
50
402
  }
51
- } = {}
403
+ }>({}) as any, '_paramsModifierSignal', { persist: true }, this as any)
52
404
 
53
- private _parameters: Map<string, {
54
- start: number,
55
- end: number
56
- }> = new Map()
405
+ /**
406
+ * Signal for base parameters configuration
407
+ *
408
+ * Stores the start and end values for each parameter's level curve.
409
+ * Changes to this signal trigger recalculation of all parameter values.
410
+ */
411
+ private _parametersSignal = type(signal<{
412
+ [key: string]: {
413
+ start: number,
414
+ end: number
415
+ }
416
+ }>({}) as any, '_parametersSignal', { persist: true }, this as any)
417
+
418
+ /**
419
+ * Computed signal for all parameter values
420
+ *
421
+ * Automatically recalculates all parameter values when level or modifiers change.
422
+ * This provides reactive parameter updates throughout the system.
423
+ *
424
+ * @example
425
+ * ```ts
426
+ * // Access reactive parameters
427
+ * const maxHp = player.param[MAXHP]; // Always current value
428
+ *
429
+ * // Parameters update automatically when level changes
430
+ * player.level = 10;
431
+ * console.log(player.param[MAXHP]); // New calculated value
432
+ * ```
433
+ */
434
+ _param = type(computed(() => {
435
+ const obj = {}
436
+ const parameters = this._parametersSignal()
437
+ const level = this._level()
438
+
439
+ for (const [name, paramConfig] of Object.entries(parameters)) {
440
+ let curveVal = Math.floor((paramConfig.end - paramConfig.start) * ((level - 1) / (this.finalLevel - this.initialLevel))) + paramConfig.start
441
+
442
+ // Apply modifiers from equipment, states, etc.
443
+ const allModifiers = this._getAggregatedModifiers()
444
+ const modifier = allModifiers[name]
445
+ if (modifier) {
446
+ if (modifier.rate) curveVal *= modifier.rate
447
+ if (modifier.value) curveVal += modifier.value
448
+ }
449
+
450
+ obj[name] = curveVal
451
+ }
452
+
453
+ return obj
454
+ }) as any, '_param', {}, this as any)
455
+
456
+ /**
457
+ * Aggregates parameter modifiers from all sources (direct modifiers, states, equipment)
458
+ *
459
+ * This method combines modifiers from multiple sources and calculates the final
460
+ * modifier values for each parameter. It handles both value and rate modifiers.
461
+ *
462
+ * @returns Aggregated parameter modifiers
463
+ *
464
+ * @example
465
+ * ```ts
466
+ * // Internal usage - gets modifiers from all sources
467
+ * const modifiers = this._getAggregatedModifiers();
468
+ * console.log(modifiers[MAXHP]); // { value: 100, rate: 1.2 }
469
+ * ```
470
+ */
471
+ private _getAggregatedModifiers(): { [key: string]: { value?: number, rate?: number } } {
472
+ const params = {}
473
+ const paramsAvg = {}
474
+
475
+ const changeParam = (paramsModifier) => {
476
+ for (let key in paramsModifier) {
477
+ const { rate, value } = paramsModifier[key]
478
+ if (!params[key]) params[key] = { rate: 0, value: 0 }
479
+ if (!paramsAvg[key]) paramsAvg[key] = 0
480
+ if (value) params[key].value += value
481
+ if (rate !== undefined) params[key].rate += rate
482
+ paramsAvg[key]++
483
+ }
484
+ }
485
+
486
+ const getModifier = (prop) => {
487
+ if (!isString(prop)) {
488
+ changeParam(prop)
489
+ return
490
+ }
491
+ for (let el of this[prop]()) {
492
+ if (!el.paramsModifier) continue
493
+ changeParam(el.paramsModifier)
494
+ }
495
+ }
496
+
497
+ // Aggregate modifiers from all sources
498
+ getModifier(this._paramsModifierSignal())
499
+ getModifier('states')
500
+ getModifier('equipments')
501
+
502
+ // Average the rates
503
+ for (let key in params) {
504
+ params[key].rate /= paramsAvg[key]
505
+ }
506
+
507
+ return params
508
+ }
57
509
 
58
510
  /**
59
511
  * ```ts
@@ -98,11 +550,14 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
98
550
  * ```
99
551
  * @memberof ParameterManager
100
552
  * */
101
- public expCurve: {
102
- basis: number,
103
- extra: number,
104
- accelerationA: number
105
- accelerationB: number
553
+ public _expCurveSignal = type(signal<string>('') as any, '_expCurveSignal', { persist: true }, this as any)
554
+
555
+ get expCurve(): ExpCurve {
556
+ return JSON.parse(this._expCurveSignal())
557
+ }
558
+
559
+ set expCurve(val: ExpCurve) {
560
+ this._expCurveSignal.set(JSON.stringify(val))
106
561
  }
107
562
 
108
563
  /**
@@ -127,11 +582,11 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
127
582
  this['execMethod']('onDead')
128
583
  val = 0
129
584
  }
130
- this._hp.set(val)
585
+ this.hpSignal.set(val)
131
586
  }
132
587
 
133
588
  get hp(): number {
134
- return this._hp()
589
+ return this.hpSignal()
135
590
  }
136
591
 
137
592
  /**
@@ -151,12 +606,12 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
151
606
  if (val > this.param[MAXSP]) {
152
607
  val = this.param[MAXSP]
153
608
  }
154
- this._sp.set(val)
609
+ this.spSignal.set(val)
155
610
  }
156
611
 
157
612
  get sp(): number {
158
- return this._sp()
159
- }
613
+ return this.spSignal()
614
+ }
160
615
 
161
616
  /**
162
617
  * Changing the player's experience.
@@ -268,43 +723,11 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
268
723
  * @memberof ParameterManager
269
724
  * */
270
725
  get param() {
271
- const obj = {}
272
- this._parameters.forEach((val, name) => {
273
- obj[name] = this.getParamValue(name)
274
- })
275
- return obj
726
+ return this._param()
276
727
  }
277
728
 
278
729
  get paramsModifier() {
279
- const params = {}
280
- const paramsAvg = {}
281
- const changeParam = (paramsModifier) => {
282
- for (let key in paramsModifier) {
283
- const { rate, value } = paramsModifier[key]
284
- if (!params[key]) params[key] = { rate: 0, value: 0 }
285
- if (!paramsAvg[key]) paramsAvg[key] = 0
286
- if (value) params[key].value += value
287
- if (rate !== undefined) params[key].rate += rate
288
- paramsAvg[key]++
289
- }
290
- }
291
- const getModifier = (prop) => {
292
- if (!isString(prop)) {
293
- changeParam(prop)
294
- return
295
- }
296
- for (let el of this[prop]()) {
297
- if (!el.paramsModifier) continue
298
- changeParam(el.paramsModifier)
299
- }
300
- }
301
- getModifier(this._paramsModifier)
302
- getModifier('states')
303
- getModifier('equipments')
304
- for (let key in params) {
305
- params[key].rate /= paramsAvg[key]
306
- }
307
- return params
730
+ return this._paramsModifierSignal()
308
731
  }
309
732
 
310
733
  /**
@@ -370,15 +793,15 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
370
793
  rate?: number
371
794
  }
372
795
  }) {
373
- this._paramsModifier = val
796
+ this._paramsModifierSignal.set(val)
374
797
  }
375
798
 
376
799
  get parameters() {
377
- return this._parameters
800
+ return this._parametersSignal()
378
801
  }
379
802
 
380
803
  set parameters(val) {
381
- this._parameters = val
804
+ this._parametersSignal.set(val)
382
805
  }
383
806
 
384
807
  private _expForLevel(level: number): number {
@@ -391,23 +814,8 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
391
814
  return Math.round(basis * (Math.pow(level - 1, 0.9 + accelerationA / 250)) * level * (level + 1) / (6 + Math.pow(level, 2) / 50 / accelerationB) + (level - 1) * extra)
392
815
  }
393
816
 
394
- private getParam(name: string) {
395
- const features = this._parameters.get(name)
396
- if (!features) {
397
- throw `Parameter ${name} not exists. Please use addParameter() before`
398
- }
399
- return features
400
- }
401
-
402
817
  getParamValue(name: string): number | never {
403
- const features = this.getParam(name)
404
- let curveVal = Math.floor((features.end - features.start) * ((this.level-1) / (this.finalLevel - this.initialLevel))) + features.start
405
- const modifier = this.paramsModifier[name]
406
- if (modifier) {
407
- if (modifier.rate) curveVal *= modifier.rate
408
- if (modifier.value) curveVal += modifier.value
409
- }
410
- return curveVal
818
+ return this.param[name]
411
819
  }
412
820
 
413
821
  /**
@@ -429,15 +837,17 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
429
837
  *
430
838
  * @title Add custom parameters
431
839
  * @method player.addParameter(name,curve)
432
- * @param {name} name
433
- * @param {object} curve Scheme of the object: { start: number, end: number }
840
+ * @param {string} name - The name of the parameter
841
+ * @param {object} curve - Scheme of the object: { start: number, end: number }
434
842
  * @returns {void}
435
843
  * @memberof ParameterManager
436
844
  * */
437
845
  addParameter(name: string, { start, end }: { start: number, end: number }): void {
438
- this._parameters.set(name, {
439
- start,
440
- end
846
+ this._parametersSignal.mutate(parameters => {
847
+ parameters[name] = {
848
+ start,
849
+ end
850
+ }
441
851
  })
442
852
  const maxHp = this.param[MAXHP]
443
853
  const maxSp = this.param[MAXSP]
@@ -465,7 +875,7 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
465
875
  *
466
876
  * @title Recovery HP and/or SP
467
877
  * @method player.recovery(params)
468
- * @param {object} params Scheme of the object: { hp: number, sp: number }. The values of the numbers must be in 0 and 1
878
+ * @param {object} params - Scheme of the object: { hp: number, sp: number }. The values of the numbers must be in 0 and 1
469
879
  * @returns {void}
470
880
  * @memberof ParameterManager
471
881
  * */
@@ -497,5 +907,5 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
497
907
  allRecovery(): void {
498
908
  this.recovery({ hp: 1, sp: 1 })
499
909
  }
500
- }
501
- }
910
+ } as unknown as TBase;
911
+ }