@rpgjs/server 5.0.0-alpha.1 → 5.0.0-alpha.10

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 (40) hide show
  1. package/dist/Player/BattleManager.d.ts +32 -22
  2. package/dist/Player/ClassManager.d.ts +31 -18
  3. package/dist/Player/ComponentManager.d.ts +60 -0
  4. package/dist/Player/EffectManager.d.ts +40 -0
  5. package/dist/Player/ElementManager.d.ts +31 -0
  6. package/dist/Player/GoldManager.d.ts +22 -0
  7. package/dist/Player/GuiManager.d.ts +176 -0
  8. package/dist/Player/ItemFixture.d.ts +6 -0
  9. package/dist/Player/ItemManager.d.ts +27 -13
  10. package/dist/Player/MoveManager.d.ts +31 -43
  11. package/dist/Player/ParameterManager.d.ts +27 -19
  12. package/dist/Player/Player.d.ts +123 -8
  13. package/dist/Player/SkillManager.d.ts +27 -19
  14. package/dist/Player/StateManager.d.ts +28 -35
  15. package/dist/Player/VariableManager.d.ts +30 -0
  16. package/dist/RpgServer.d.ts +224 -1
  17. package/dist/index.js +1097 -636
  18. package/dist/index.js.map +1 -1
  19. package/dist/rooms/map.d.ts +70 -1
  20. package/package.json +8 -8
  21. package/src/Player/BattleManager.ts +97 -38
  22. package/src/Player/ClassManager.ts +95 -35
  23. package/src/Player/ComponentManager.ts +64 -20
  24. package/src/Player/EffectManager.ts +110 -27
  25. package/src/Player/ElementManager.ts +126 -25
  26. package/src/Player/GoldManager.ts +32 -35
  27. package/src/Player/GuiManager.ts +187 -140
  28. package/src/Player/ItemFixture.ts +4 -5
  29. package/src/Player/ItemManager.ts +39 -26
  30. package/src/Player/MoveManager.ts +40 -31
  31. package/src/Player/ParameterManager.ts +35 -25
  32. package/src/Player/Player.ts +184 -39
  33. package/src/Player/SkillManager.ts +44 -23
  34. package/src/Player/StateManager.ts +210 -95
  35. package/src/Player/VariableManager.ts +180 -48
  36. package/src/RpgServer.ts +232 -1
  37. package/src/core/context.ts +1 -0
  38. package/src/rooms/map.ts +76 -8
  39. package/dist/Player/Event.d.ts +0 -0
  40. package/src/Player/Event.ts +0 -0
@@ -1,20 +1,6 @@
1
- import { Constructor, isString, RpgCommonPlayer } from "@rpgjs/common";
1
+ import { isString, PlayerCtor } from "@rpgjs/common";
2
2
  import { MAXHP, MAXSP } from "../presets";
3
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
- }
14
-
15
- interface PlayerWithMixins extends RpgCommonPlayer {
16
- databaseById?(id: string): any;
17
- }
18
4
 
19
5
  /**
20
6
  * Mixin that adds parameter management functionality to a player class.
@@ -39,18 +25,40 @@ interface PlayerWithMixins extends RpgCommonPlayer {
39
25
  * }
40
26
  * ```
41
27
  */
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: {
28
+ /**
29
+ * Parameter Manager Mixin
30
+ *
31
+ * Provides comprehensive parameter management functionality to any class. This mixin handles
32
+ * health points (HP), skill points (SP), experience and level progression, custom parameters,
33
+ * and parameter modifiers for temporary stat changes.
34
+ *
35
+ * @param Base - The base class to extend with parameter management
36
+ * @returns Extended class with parameter management methods
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * class MyPlayer extends WithParameterManager(BasePlayer) {
41
+ * constructor() {
42
+ * super();
43
+ * this.addParameter('strength', { start: 10, end: 100 });
44
+ * }
45
+ * }
46
+ *
47
+ * const player = new MyPlayer();
48
+ * player.hp = 100;
49
+ * player.level = 5;
50
+ * ```
51
+ */
52
+ export function WithParameterManager<TBase extends PlayerCtor>(Base: TBase) {
53
+ return class extends Base {
54
+ _paramsModifier: {
47
55
  [key: string]: {
48
56
  value?: number,
49
57
  rate?: number
50
58
  }
51
59
  } = {}
52
60
 
53
- private _parameters: Map<string, {
61
+ _parameters: Map<string, {
54
62
  start: number,
55
63
  end: number
56
64
  }> = new Map()
@@ -127,11 +135,11 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
127
135
  this['execMethod']('onDead')
128
136
  val = 0
129
137
  }
130
- this._hp.set(val)
138
+ (this as any)._hp.set(val)
131
139
  }
132
140
 
133
141
  get hp(): number {
134
- return this._hp()
142
+ return (this as any)._hp()
135
143
  }
136
144
 
137
145
  /**
@@ -497,5 +505,7 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
497
505
  allRecovery(): void {
498
506
  this.recovery({ hp: 1, sp: 1 })
499
507
  }
500
- }
501
- }
508
+ } as unknown as TBase;
509
+ }
510
+
511
+ export type IParameterManager = InstanceType<ReturnType<typeof WithParameterManager>>;
@@ -5,33 +5,42 @@ import {
5
5
  RpgCommonPlayer,
6
6
  ShowAnimationParams,
7
7
  Constructor,
8
- ZoneOptions,
9
8
  } from "@rpgjs/common";
10
- import { WithComponentManager, IComponentManager } from "./ComponentManager";
9
+ import { IComponentManager, WithComponentManager } from "./ComponentManager";
11
10
  import { RpgMap } from "../rooms/map";
12
11
  import { Context, inject } from "@signe/di";
13
12
  import { IGuiManager, WithGuiManager } from "./GuiManager";
14
13
  import { MockConnection } from "@signe/room";
15
14
  import { IMoveManager, WithMoveManager } from "./MoveManager";
16
15
  import { IGoldManager, WithGoldManager } from "./GoldManager";
17
- import { IWithVariableManager, WithVariableManager } from "./VariableManager";
16
+ import { WithVariableManager, type IVariableManager } from "./VariableManager";
18
17
  import { sync } from "@signe/sync";
19
18
  import { signal } from "@signe/reactive";
20
19
  import {
21
- IWithParameterManager,
20
+ IParameterManager,
22
21
  WithParameterManager,
23
22
  } from "./ParameterManager";
24
23
  import { WithItemFixture } from "./ItemFixture";
25
- import { WithStateManager } from "./StateManager";
26
- import { WithItemManager } from "./ItemManager";
24
+ import { IItemManager, WithItemManager } from "./ItemManager";
27
25
  import { lastValueFrom } from "rxjs";
28
- import { WithBattleManager } from "./BattleManager";
29
- import { WithEffectManager } from "./EffectManager";
30
- import { WithSkillManager, IWithSkillManager } from "./SkillManager";
26
+ import { IEffectManager, WithEffectManager } from "./EffectManager";
31
27
  import { AGI, AGI_CURVE, DEX, DEX_CURVE, INT, INT_CURVE, MAXHP, MAXHP_CURVE, MAXSP, MAXSP_CURVE, STR, STR_CURVE } from "../presets";
32
- import { WithClassManager } from "./ClassManager";
33
- import { WithElementManager } from "./ElementManager";
28
+ import { IElementManager, WithElementManager } from "./ElementManager";
29
+ import { ISkillManager, WithSkillManager } from "./SkillManager";
30
+ import { IBattleManager, WithBattleManager } from "./BattleManager";
31
+ import { IClassManager, WithClassManager } from "./ClassManager";
32
+ import { IStateManager, WithStateManager } from "./StateManager";
34
33
 
34
+ // Local interface for ZoneOptions to avoid import issues
35
+ interface ZoneOptions {
36
+ x?: number;
37
+ y?: number;
38
+ radius: number;
39
+ angle?: number;
40
+ direction?: any;
41
+ linkedTo?: string;
42
+ limitedByWalls?: boolean;
43
+ }
35
44
 
36
45
  /**
37
46
  * Combines multiple RpgCommonPlayer mixins into one
@@ -46,27 +55,44 @@ function combinePlayerMixins<T extends Constructor<RpgCommonPlayer>>(
46
55
  mixins.reduce((ExtendedClass, mixin) => mixin(ExtendedClass), Base);
47
56
  }
48
57
 
49
- const PlayerMixins = combinePlayerMixins([
58
+ // Start with basic mixins that work
59
+ const BasicPlayerMixins = combinePlayerMixins([
50
60
  WithComponentManager,
51
61
  WithEffectManager,
52
62
  WithGuiManager,
53
63
  WithMoveManager,
54
64
  WithGoldManager,
55
- WithVariableManager,
56
65
  WithParameterManager,
57
66
  WithItemFixture,
58
- WithStateManager,
59
67
  WithItemManager,
60
- WithSkillManager,
68
+ WithElementManager,
69
+ WithVariableManager,
70
+ WithStateManager,
61
71
  WithClassManager,
72
+ WithSkillManager,
62
73
  WithBattleManager,
63
- WithElementManager,
64
74
  ]);
65
75
 
66
76
  /**
67
77
  * RPG Player class with component management capabilities
78
+ *
79
+ * Combines all player mixins to provide a complete player implementation
80
+ * with graphics, movement, inventory, skills, and battle capabilities.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Create a new player
85
+ * const player = new RpgPlayer();
86
+ *
87
+ * // Set player graphics
88
+ * player.setGraphic("hero");
89
+ *
90
+ * // Add parameters and items
91
+ * player.addParameter("strength", { start: 10, end: 100 });
92
+ * player.addItem(sword);
93
+ * ```
68
94
  */
69
- export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
95
+ export class RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
70
96
  map: RpgMap | null = null;
71
97
  context?: Context;
72
98
  conn: MockConnection | null = null;
@@ -75,20 +101,21 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
75
101
 
76
102
  constructor() {
77
103
  super();
78
- this.expCurve = {
104
+ // Use type assertion to access mixin properties
105
+ (this as any).expCurve = {
79
106
  basis: 30,
80
107
  extra: 20,
81
108
  accelerationA: 30,
82
109
  accelerationB: 30
83
- }
110
+ };
84
111
 
85
- this.addParameter(MAXHP, MAXHP_CURVE)
86
- this.addParameter(MAXSP, MAXSP_CURVE)
87
- this.addParameter(STR, STR_CURVE)
88
- this.addParameter(INT, INT_CURVE)
89
- this.addParameter(DEX, DEX_CURVE)
90
- this.addParameter(AGI, AGI_CURVE)
91
- this.allRecovery()
112
+ (this as any).addParameter(MAXHP, MAXHP_CURVE);
113
+ (this as any).addParameter(MAXSP, MAXSP_CURVE);
114
+ (this as any).addParameter(STR, STR_CURVE);
115
+ (this as any).addParameter(INT, INT_CURVE);
116
+ (this as any).addParameter(DEX, DEX_CURVE);
117
+ (this as any).addParameter(AGI, AGI_CURVE);
118
+ (this as any).allRecovery();
92
119
  }
93
120
 
94
121
  async execMethod(method: string, methodData: any[] = [], target?: any) {
@@ -151,7 +178,50 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
151
178
  });
152
179
  }
153
180
 
154
- showAnimation(params: ShowAnimationParams) {}
181
+ /**
182
+ * Set the current animation of the player's sprite
183
+ *
184
+ * This method changes the animation state of the player's current sprite.
185
+ * It's used to trigger character animations like attack, skill, or custom movements.
186
+ * When `nbTimes` is set to a finite number, the animation will play that many times
187
+ * before returning to the previous animation state.
188
+ *
189
+ * @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk')
190
+ * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * // Set continuous walk animation
195
+ * player.setAnimation('walk');
196
+ *
197
+ * // Play attack animation 3 times then return to previous state
198
+ * player.setAnimation('attack', 3);
199
+ *
200
+ * // Play skill animation once
201
+ * player.setAnimation('skill', 1);
202
+ *
203
+ * // Set idle/stand animation
204
+ * player.setAnimation('stand');
205
+ * ```
206
+ */
207
+ setAnimation(animationName: string, nbTimes: number = Infinity) {
208
+ const map = this.getCurrentMap();
209
+ if (!map) return;
210
+ if (nbTimes === Infinity) {
211
+ this.animationName.set(animationName);
212
+ }
213
+ else {
214
+ map.$broadcast({
215
+ type: "setAnimation",
216
+ value: {
217
+ animationName,
218
+ nbTimes,
219
+ object: this.id,
220
+ },
221
+ });
222
+ }
223
+ }
224
+
155
225
 
156
226
  /**
157
227
  * Run the change detection cycle. Normally, as soon as a hook is called in a class, the cycle is started. But you can start it manually
@@ -228,11 +298,35 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
228
298
  );
229
299
  }
230
300
 
231
- broadcastEffect(id: string, params: any) {
301
+ /**
302
+ * Show a temporary component animation on this player
303
+ *
304
+ * This method broadcasts a component animation to all clients, allowing
305
+ * temporary visual effects like hit indicators, spell effects, or status animations
306
+ * to be displayed on the player.
307
+ *
308
+ * @param id - The ID of the component animation to display
309
+ * @param params - Parameters to pass to the component animation
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * // Show a hit animation with damage text
314
+ * player.showComponentAnimation("hit", {
315
+ * text: "150",
316
+ * color: "red"
317
+ * });
318
+ *
319
+ * // Show a heal animation
320
+ * player.showComponentAnimation("heal", {
321
+ * amount: 50
322
+ * });
323
+ * ```
324
+ */
325
+ showComponentAnimation(id: string, params: any) {
232
326
  const map = this.getCurrentMap();
233
327
  if (!map) return;
234
328
  map.$broadcast({
235
- type: "showEffect",
329
+ type: "showComponentAnimation",
236
330
  value: {
237
331
  id,
238
332
  params,
@@ -241,8 +335,46 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
241
335
  });
242
336
  }
243
337
 
338
+ /**
339
+ * Display a spritesheet animation on the player
340
+ *
341
+ * This method displays a temporary visual animation using a spritesheet.
342
+ * The animation can either be displayed as an overlay on the player or replace
343
+ * the player's current graphic temporarily. This is useful for spell effects,
344
+ * transformations, or other visual feedback that uses predefined spritesheets.
345
+ *
346
+ * @param graphic - The ID of the spritesheet to use for the animation
347
+ * @param animationName - The name of the animation within the spritesheet (default: 'default')
348
+ * @param replaceGraphic - Whether to replace the player's sprite with the animation (default: false)
349
+ *
350
+ * @example
351
+ * ```ts
352
+ * // Show explosion animation as overlay on player
353
+ * player.showAnimation("explosion");
354
+ *
355
+ * // Show specific spell effect animation
356
+ * player.showAnimation("spell-effects", "fireball");
357
+ *
358
+ * // Transform player graphic temporarily with animation
359
+ * player.showAnimation("transformation", "werewolf", true);
360
+ *
361
+ * // Show healing effect on player
362
+ * player.showAnimation("healing-effects", "holy-light");
363
+ * ```
364
+ */
365
+ showAnimation(graphic: string, animationName: string = 'default', replaceGraphic: boolean = false) {
366
+ if (replaceGraphic) {
367
+ this.setAnimation(animationName, 1);
368
+ return
369
+ }
370
+ this.showComponentAnimation("animation", {
371
+ graphic,
372
+ animationName,
373
+ });
374
+ }
375
+
244
376
  showHit(text: string) {
245
- this.broadcastEffect("hit", {
377
+ this.showComponentAnimation("hit", {
246
378
  text,
247
379
  direction: this.direction(),
248
380
  });
@@ -268,12 +400,25 @@ export class RpgEvent extends RpgPlayer {
268
400
  }
269
401
  }
270
402
 
271
- export interface RpgPlayer
272
- extends RpgCommonPlayer,
273
- IComponentManager,
274
- IGuiManager,
275
- IMoveManager,
276
- IGoldManager,
277
- IWithVariableManager,
278
- IWithParameterManager,
279
- IWithSkillManager {}
403
+
404
+ /**
405
+ * Interface extension for RpgPlayer
406
+ *
407
+ * Extends the RpgPlayer class with additional interfaces from mixins.
408
+ * This provides proper TypeScript support for all mixin methods and properties.
409
+ */
410
+ export interface RpgPlayer extends
411
+ IVariableManager,
412
+ IMoveManager,
413
+ IGoldManager,
414
+ IComponentManager,
415
+ IGuiManager,
416
+ IItemManager,
417
+ IEffectManager,
418
+ IParameterManager,
419
+ IElementManager,
420
+ ISkillManager,
421
+ IBattleManager,
422
+ IClassManager,
423
+ IStateManager
424
+ {}
@@ -3,6 +3,7 @@ import {
3
3
  isArray,
4
4
  isInstanceOf,
5
5
  isString,
6
+ PlayerCtor,
6
7
  RpgCommonPlayer,
7
8
  } from "@rpgjs/common";
8
9
  import { SkillLog } from "../logs";
@@ -20,22 +21,36 @@ interface SkillManagerDependencies {
20
21
  applyStates(player: RpgPlayer, skill: any): void;
21
22
  }
22
23
 
24
+
25
+
23
26
  /**
24
- * Interface defining what SkillManager adds to a class
27
+ * Skill Manager Mixin
28
+ *
29
+ * Provides skill management capabilities to any class. This mixin handles
30
+ * learning, forgetting, and using skills, including SP cost management,
31
+ * hit rate calculations, and skill effects application.
32
+ *
33
+ * @param Base - The base class to extend with skill management
34
+ * @returns Extended class with skill management methods
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * class MyPlayer extends WithSkillManager(BasePlayer) {
39
+ * constructor() {
40
+ * super();
41
+ * // Skill system is automatically initialized
42
+ * }
43
+ * }
44
+ *
45
+ * const player = new MyPlayer();
46
+ * player.learnSkill(Fire);
47
+ * player.useSkill(Fire, targetPlayer);
48
+ * ```
25
49
  */
26
- export interface IWithSkillManager {
27
- getSkill(skillClass: any | string): any;
28
- learnSkill(skillId: any | string): any;
29
- forgetSkill(skillId: any | string): any;
30
- useSkill(skillId: any | string, otherPlayer?: RpgPlayer | RpgPlayer[]): any;
31
- }
32
-
33
- export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & SkillManagerDependencies>>(
34
- Base: TBase
35
- ): Constructor<IWithSkillManager> & TBase {
36
- return class extends Base implements IWithSkillManager {
37
- private _getSkillIndex(skillClass: any | string) {
38
- return this.skills().findIndex((skill) => {
50
+ export function WithSkillManager<TBase extends PlayerCtor>(Base: TBase) {
51
+ return class extends Base {
52
+ _getSkillIndex(skillClass: any | string) {
53
+ return (this as any).skills().findIndex((skill) => {
39
54
  if (isString(skill)) {
40
55
  return skill.id == skillClass;
41
56
  }
@@ -94,7 +109,7 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
94
109
  if (this.getSkill(skillId)) {
95
110
  throw SkillLog.alreadyLearned(skillId);
96
111
  }
97
- const instance = this.databaseById(skillId);
112
+ const instance = (this as any).databaseById(skillId);
98
113
  this.skills().push(instance);
99
114
  this["execMethod"]("onLearn", [this], instance);
100
115
  return instance;
@@ -131,7 +146,7 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
131
146
  * @memberof SkillManager
132
147
  */
133
148
  forgetSkill(skillId: any | string) {
134
- if (isString(skillId)) skillId = this.databaseById(skillId);
149
+ if (isString(skillId)) skillId = (this as any).databaseById(skillId);
135
150
  const index = this._getSkillIndex(skillId);
136
151
  if (index == -1) {
137
152
  throw SkillLog.notLearned(skillId);
@@ -219,16 +234,16 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
219
234
  */
220
235
  useSkill(skillId: any | string, otherPlayer?: RpgPlayer | RpgPlayer[]) {
221
236
  const skill = this.getSkill(skillId);
222
- if (this.hasEffect(Effect.CAN_NOT_SKILL)) {
237
+ if ((this as any).hasEffect(Effect.CAN_NOT_SKILL)) {
223
238
  throw SkillLog.restriction(skillId);
224
239
  }
225
240
  if (!skill) {
226
241
  throw SkillLog.notLearned(skillId);
227
242
  }
228
- if (skill.spCost > this.sp) {
229
- throw SkillLog.notEnoughSp(skillId, skill.spCost, this.sp);
243
+ if (skill.spCost > (this as any).sp) {
244
+ throw SkillLog.notEnoughSp(skillId, skill.spCost, (this as any).sp);
230
245
  }
231
- this.sp -= skill.spCost / (this.hasEffect(Effect.HALF_SP_COST) ? 2 : 1);
246
+ (this as any).sp -= skill.spCost / ((this as any).hasEffect(Effect.HALF_SP_COST) ? 2 : 1);
232
247
  const hitRate = skill.hitRate ?? 1;
233
248
  if (Math.random() > hitRate) {
234
249
  this["execMethod"]("onUseFailed", [this, otherPlayer], skill);
@@ -240,12 +255,18 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
240
255
  players = [otherPlayer];
241
256
  }
242
257
  for (let player of players) {
243
- this.applyStates(player, skill);
244
- player.applyDamage(this, skill);
258
+ (this as any).applyStates(player, skill);
259
+ (player as any).applyDamage(this, skill);
245
260
  }
246
261
  }
247
262
  this["execMethod"]("onUse", [this, otherPlayer], skill);
248
263
  return skill;
249
264
  }
250
- };
265
+ } as unknown as TBase;
251
266
  }
267
+
268
+ /**
269
+ * Type helper to extract the interface from the WithSkillManager mixin
270
+ * This provides the type without duplicating method signatures
271
+ */
272
+ export type ISkillManager = InstanceType<ReturnType<typeof WithSkillManager>>;