@rpgjs/server 5.0.0-alpha.4 → 5.0.0-alpha.41

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 (101) 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 +28 -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 +450 -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 +502 -64
  27. package/dist/RpgServerEngine.d.ts +2 -1
  28. package/dist/decorators/event.d.ts +46 -0
  29. package/dist/decorators/map.d.ts +287 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.js +21653 -20900
  32. package/dist/index.js.map +1 -1
  33. package/dist/logs/log.d.ts +2 -3
  34. package/dist/module.d.ts +43 -1
  35. package/dist/presets/index.d.ts +0 -9
  36. package/dist/rooms/BaseRoom.d.ts +132 -0
  37. package/dist/rooms/lobby.d.ts +10 -2
  38. package/dist/rooms/map.d.ts +1236 -17
  39. package/dist/services/save.d.ts +43 -0
  40. package/dist/storage/index.d.ts +1 -0
  41. package/dist/storage/localStorage.d.ts +23 -0
  42. package/package.json +14 -10
  43. package/src/Gui/DialogGui.ts +19 -4
  44. package/src/Gui/GameoverGui.ts +39 -0
  45. package/src/Gui/Gui.ts +23 -1
  46. package/src/Gui/MenuGui.ts +155 -6
  47. package/src/Gui/NotificationGui.ts +1 -2
  48. package/src/Gui/SaveLoadGui.ts +60 -0
  49. package/src/Gui/ShopGui.ts +146 -16
  50. package/src/Gui/TitleGui.ts +39 -0
  51. package/src/Gui/index.ts +15 -2
  52. package/src/Player/BattleManager.ts +91 -49
  53. package/src/Player/ClassManager.ts +118 -50
  54. package/src/Player/ComponentManager.ts +425 -19
  55. package/src/Player/Components.ts +380 -0
  56. package/src/Player/EffectManager.ts +81 -44
  57. package/src/Player/ElementManager.ts +109 -86
  58. package/src/Player/GoldManager.ts +32 -35
  59. package/src/Player/GuiManager.ts +308 -150
  60. package/src/Player/ItemFixture.ts +4 -5
  61. package/src/Player/ItemManager.ts +774 -355
  62. package/src/Player/MoveManager.ts +1544 -774
  63. package/src/Player/ParameterManager.ts +546 -104
  64. package/src/Player/Player.ts +1163 -88
  65. package/src/Player/SkillManager.ts +520 -195
  66. package/src/Player/StateManager.ts +170 -182
  67. package/src/Player/VariableManager.ts +101 -63
  68. package/src/RpgServer.ts +525 -63
  69. package/src/core/context.ts +1 -0
  70. package/src/decorators/event.ts +61 -0
  71. package/src/decorators/map.ts +327 -0
  72. package/src/index.ts +11 -1
  73. package/src/logs/log.ts +10 -3
  74. package/src/module.ts +126 -3
  75. package/src/presets/index.ts +1 -10
  76. package/src/rooms/BaseRoom.ts +232 -0
  77. package/src/rooms/lobby.ts +25 -7
  78. package/src/rooms/map.ts +2502 -194
  79. package/src/services/save.ts +147 -0
  80. package/src/storage/index.ts +1 -0
  81. package/src/storage/localStorage.ts +76 -0
  82. package/tests/battle.spec.ts +375 -0
  83. package/tests/change-map.spec.ts +72 -0
  84. package/tests/class.spec.ts +274 -0
  85. package/tests/effect.spec.ts +219 -0
  86. package/tests/element.spec.ts +221 -0
  87. package/tests/event.spec.ts +80 -0
  88. package/tests/gold.spec.ts +99 -0
  89. package/tests/item.spec.ts +609 -0
  90. package/tests/module.spec.ts +38 -0
  91. package/tests/move.spec.ts +601 -0
  92. package/tests/player-param.spec.ts +28 -0
  93. package/tests/prediction-reconciliation.spec.ts +182 -0
  94. package/tests/random-move.spec.ts +65 -0
  95. package/tests/skill.spec.ts +658 -0
  96. package/tests/state.spec.ts +467 -0
  97. package/tests/variable.spec.ts +185 -0
  98. package/tests/world-maps.spec.ts +896 -0
  99. package/vite.config.ts +16 -0
  100. package/dist/Player/Event.d.ts +0 -0
  101. package/src/Player/Event.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { isInstanceOf, isString, type Constructor } from "@rpgjs/common";
1
+ import { isInstanceOf, isString, PlayerCtor, type Constructor } from "@rpgjs/common";
2
2
  import { RpgCommonPlayer, Matter, SeekAvoid } from "@rpgjs/common";
3
3
  import { signal, type WritableArraySignal } from "@signe/reactive";
4
4
  import { ATK, PDEF, SDEF } from "../presets";
@@ -13,111 +13,112 @@ interface StateManagerDependencies {
13
13
  removeState(stateClass: StateClass | string, chance?: number): void;
14
14
  }
15
15
 
16
- /**
17
- * Interface defining what MoveManager adds to a class
18
- */
19
- export interface IStateManager {
20
- statesDefense: { rate: number; state: any }[];
21
- statesEfficiency: WritableArraySignal<any[]>;
22
- applyStates(
23
- player: RpgPlayer,
24
- states: { addStates?: any[]; removeStates?: any[] }
25
- ): void;
26
- getState(stateClass: StateClass | string): any;
27
- addState(stateClass: StateClass | string, chance?: number): object | null;
28
- removeState(stateClass: StateClass | string, chance?: number): void;
29
- }
16
+
30
17
 
31
18
  type StateClass = { new (...args: any[]) };
32
19
 
33
20
  /**
34
- * Move Manager mixin
35
- *
36
- * Adds methods to manage player movement
37
- *
38
- * @param Base - The base class to extend
39
- * @returns A new class with move management capabilities
21
+ * State Manager Mixin
22
+ *
23
+ * Provides state management capabilities to any class. This mixin handles
24
+ * player states (buffs/debuffs), state defense from equipment, and state
25
+ * efficiency modifiers. It manages the complete state system including
26
+ * application, removal, and resistance mechanics.
27
+ *
28
+ * @param Base - The base class to extend with state management
29
+ * @returns Extended class with state management methods
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * class MyPlayer extends WithStateManager(BasePlayer) {
34
+ * constructor() {
35
+ * super();
36
+ * // State system is automatically initialized
37
+ * }
38
+ * }
39
+ *
40
+ * const player = new MyPlayer();
41
+ * player.addState(Paralyze);
42
+ * console.log(player.getState(Paralyze));
43
+ * ```
40
44
  */
41
- export function WithStateManager<
42
- TBase extends Constructor<RpgCommonPlayer & StateManagerDependencies>
43
- >(Base: TBase): Constructor<IStateManager> & TBase {
44
- return class extends Base implements IStateManager {
45
+ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
46
+ return class extends Base {
45
47
  _statesEfficiency = signal<any[]>([]);
46
48
 
49
+ private _getStateMap(required: boolean = true) {
50
+ // Use this.map directly to support both RpgMap and LobbyRoom
51
+ const map = (this as any).getCurrentMap?.() || (this as any).map;
52
+ if (required && (!map || !map.database)) {
53
+ throw new Error('Player must be on a map to resolve states');
54
+ }
55
+ return map;
56
+ }
57
+
58
+ private _resolveStateInput(
59
+ stateInput: StateClass | string,
60
+ databaseByIdOverride?: (id: string) => any
61
+ ) {
62
+ if (isString(stateInput)) {
63
+ return databaseByIdOverride
64
+ ? databaseByIdOverride(stateInput)
65
+ : (this as any).databaseById(stateInput);
66
+ }
67
+ return stateInput;
68
+ }
69
+
70
+ private _createStateInstance(stateClass: StateClass) {
71
+ return new (stateClass as StateClass)();
72
+ }
73
+
47
74
  /**
48
- * Recovers the player's states defense on inventory. This list is generated from the `statesDefense` property defined on the weapons or armors equipped.
49
- * If several items have the same element, only the highest rate will be taken into account.
50
- *
51
- * ```ts
52
- * import { Armor, State } from '@rpgjs/server'
53
- *
54
- * @State({
55
- * name: 'Paralyze'
56
- * })
57
- * class Paralyze {}
58
- *
59
- * @Armor({
60
- * name: 'Shield',
61
- * statesDefense: [{ rate: 1, state: Paralyze }]
62
- * })
63
- * class Shield {}
64
- *
65
- * @Armor({
66
- * name: 'FireShield',
67
- * statesDefense: [{ rate: 0.5, state: Paralyze }]
68
- * })
69
- * class FireShield {}
70
- *
71
- * player.addItem(Shield)
72
- * player.addItem(FireShield)
73
- * player.equip(Shield)
74
- * player.equip(FireShield)
75
- *
76
- * console.log(player.statesDefense) // [{ rate: 1, state: instance of Paralyze }]
77
- * ```
78
- * @title Get States Defense
79
- * @prop {Array<{ rate: number, state: StateClass}>} player.statesDefense
80
- * @readonly
81
- * @memberof StateManager
82
- * */
83
- get statesDefense(): { rate: number; state: any }[] {
84
- return this.getFeature("statesDefense", "state");
75
+ * Create a state instance without side effects.
76
+ */
77
+ createStateInstance(stateInput: StateClass | string) {
78
+ const stateClass = this._resolveStateInput(stateInput);
79
+ const instance = this._createStateInstance(stateClass as StateClass);
80
+ return { stateClass, instance };
85
81
  }
86
82
 
87
83
  /**
88
- * Set or retrieves all the states where the player is vulnerable or not.
89
- *
90
- * ```ts
91
- * import { Class, State } from '@rpgjs/server'
92
- *
93
- * @State({
94
- * name: 'Paralyze'
95
- * })
96
- * class Paralyze {}
97
- *
98
- * @State({
99
- * name: 'Sleep'
100
- * })
101
- * class Sleep {}
102
- *
103
- * @Class({
104
- * name: 'Fighter',
105
- * statesEfficiency: [{ rate: 1, state: Paralyze }]
106
- * })
107
- * class Hero {}
108
- *
109
- * player.setClass(Hero)
110
- *
111
- * console.log(player.statesEfficiency) // [{ rate: 1, instance of Paralyze }]
112
- *
113
- * player.statesEfficiency = [{ rate: 2, state: Sleep }]
114
- *
115
- * console.log(player.statesEfficiency) // [{ rate: 1, state: instance of Paralyze }, { rate: 2, state: instance of Sleep }]
116
- * ```
117
- * @title Set/Get States Efficiency
118
- * @prop {Array<{ rate: number, state: StateClass}>} player.statesEfficiency
119
- * @memberof StateManager
120
- * */
84
+ * Resolve state snapshot entries into state instances without side effects.
85
+ */
86
+ resolveStatesSnapshot(snapshot: { states?: any[] }, mapOverride?: any) {
87
+ if (!snapshot || !Array.isArray(snapshot.states)) {
88
+ return snapshot;
89
+ }
90
+
91
+ const map = mapOverride ?? this._getStateMap(false);
92
+ if (!map || !map.database) {
93
+ return snapshot;
94
+ }
95
+
96
+ const databaseByIdOverride = (id: string) => {
97
+ const data = map.database()[id];
98
+ if (!data) {
99
+ throw new Error(
100
+ `The ID=${id} data is not found in the database. Add the data in the property "database"`
101
+ );
102
+ }
103
+ return data;
104
+ };
105
+
106
+ const states = snapshot.states.map((entry: any) => {
107
+ const stateId = isString(entry) ? entry : entry?.id;
108
+ if (!stateId) {
109
+ return entry;
110
+ }
111
+ const stateClass = this._resolveStateInput(stateId, databaseByIdOverride);
112
+ return this._createStateInstance(stateClass as StateClass);
113
+ });
114
+
115
+ return { ...snapshot, states };
116
+ }
117
+
118
+ get statesDefense(): { rate: number; state: any }[] {
119
+ return (this as any).getFeature("statesDefense", "state");
120
+ }
121
+
121
122
  get statesEfficiency() {
122
123
  return this._statesEfficiency;
123
124
  }
@@ -127,37 +128,23 @@ export function WithStateManager<
127
128
  }
128
129
 
129
130
  applyStates(
130
- player: RpgPlayer & IStateManager,
131
+ player: RpgPlayer,
131
132
  { addStates, removeStates }
132
133
  ) {
133
134
  if (addStates) {
134
135
  for (let { state, rate } of addStates) {
135
- player.addState(state, rate);
136
+ (player as any).addState(state, rate);
136
137
  }
137
138
  }
138
139
  if (removeStates) {
139
140
  for (let { state, rate } of removeStates) {
140
- player.removeState(state, rate);
141
+ (player as any).removeState(state, rate);
141
142
  }
142
143
  }
143
144
  }
144
145
 
145
- /**
146
- * Get a state to the player. Returns `null` if the state is not present on the player
147
- * ```ts
148
- * import Paralyze from 'your-database/states/paralyze'
149
- *
150
- * player.getState(Paralyze)
151
- * ```
152
- *
153
- * @title Get State
154
- * @method player.getState(stateClass)
155
- * @param {StateClass | string} stateClass or state id
156
- * @returns {instance of StateClass | null}
157
- * @memberof StateManager
158
- */
159
146
  getState(stateClass: StateClass | string) {
160
- if (isString(stateClass)) stateClass = this.databaseById(stateClass);
147
+ if (isString(stateClass)) stateClass = (this as any).databaseById(stateClass);
161
148
  return this.states().find((state) => {
162
149
  if (isString(stateClass)) {
163
150
  return state.id == stateClass;
@@ -166,46 +153,17 @@ export function WithStateManager<
166
153
  });
167
154
  }
168
155
 
169
- /**
170
- * Adds a state to the player. Set the chance between 0 and 1 that the state can apply
171
- * ```ts
172
- * import Paralyze from 'your-database/states/paralyze'
173
- *
174
- * try {
175
- * player.addState(Paralyze)
176
- * }
177
- * catch (err) {
178
- * console.log(err)
179
- * }
180
- * ```
181
- *
182
- * @title Add State
183
- * @method player.addState(stateClass,chance=1)
184
- * @param {StateClass | string} stateClass state class or state id
185
- * @param {number} [chance] 1 by default
186
- * @throws {StateLog} addFailed
187
- * If the chance to add the state has failed (defined with the `chance` param)
188
- * ```
189
- * {
190
- * id: ADD_STATE_FAILED,
191
- * msg: '...'
192
- * }
193
- * ```
194
- * @returns {instance of StateClass}
195
- * @memberof StateManager
196
- * @todo
197
- */
198
156
  addState(stateClass: StateClass | string, chance = 1): object | null {
199
157
  const state = this.getState(stateClass);
200
158
  if (isString(stateClass)) {
201
- stateClass = this.databaseById(stateClass);
159
+ stateClass = (this as any).databaseById(stateClass);
202
160
  }
203
161
  if (!state) {
204
162
  if (Math.random() > chance) {
205
163
  throw StateLog.addFailed(stateClass);
206
164
  }
207
165
  //const efficiency = this.findStateEfficiency(stateClass)
208
- const instance = new (stateClass as StateClass)();
166
+ const instance = this._createStateInstance(stateClass as StateClass);
209
167
  this.states().push(instance);
210
168
  this.applyStates(<any>this, instance);
211
169
  return instance;
@@ -213,42 +171,6 @@ export function WithStateManager<
213
171
  return null;
214
172
  }
215
173
 
216
- /**
217
- * Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
218
- * ```ts
219
- * import Paralyze from 'your-database/states/paralyze'
220
- *
221
- * try {
222
- * player.removeState(Paralyze)
223
- * }
224
- * catch (err) {
225
- * console.log(err)
226
- * }
227
- * ```
228
- *
229
- * @title Remove State
230
- * @method player.removeState(stateClass,chance=1)
231
- * @param {StateClass|string} stateClass class state or state id
232
- * @param {number} [chance] 1 by default
233
- * @throws {StateLog} removeFailed
234
- * If the chance to remove the state has failed (defined with the `chance` param)
235
- * ```
236
- * {
237
- * id: REMOVE_STATE_FAILED,
238
- * msg: '...'
239
- * }
240
- * ```
241
- * @throws {StateLog} notApplied
242
- * If the status does not exist
243
- * ```
244
- * {
245
- * id: STATE_NOT_APPLIED,
246
- * msg: '...'
247
- * }
248
- * ```
249
- * @returns {instance of StateClass}
250
- * @memberof StateManager
251
- */
252
174
  removeState(stateClass: StateClass | string, chance = 1) {
253
175
  const index = this.states().findIndex((state) => {
254
176
  if (isString(stateClass)) {
@@ -266,10 +188,76 @@ export function WithStateManager<
266
188
  }
267
189
  }
268
190
 
269
- private findStateEfficiency(stateClass) {
191
+ findStateEfficiency(stateClass) {
270
192
  return this.statesEfficiency().find((state) =>
271
193
  isInstanceOf(state.state, stateClass)
272
194
  );
273
195
  }
274
- };
196
+ } as unknown as TBase;
197
+ }
198
+
199
+ /**
200
+ * Interface for State Manager functionality
201
+ *
202
+ * Provides state management capabilities including state defense, efficiency modifiers,
203
+ * and state application/removal. This interface defines the public API of the StateManager mixin.
204
+ */
205
+ export interface IStateManager {
206
+ /**
207
+ * Gets the defensive capabilities against various states from equipped items
208
+ *
209
+ * @returns Array of state defense objects with rate and state properties
210
+ */
211
+ statesDefense: { rate: number; state: any }[];
212
+
213
+ /**
214
+ * Manages the player's state efficiency modifiers
215
+ *
216
+ * @returns Signal containing array of state efficiency objects
217
+ */
218
+ statesEfficiency: any;
219
+
220
+ /**
221
+ * Apply states to a player from skill or item effects
222
+ *
223
+ * @param player - The target player to apply states to
224
+ * @param states - Object containing arrays of states to add or remove
225
+ */
226
+ applyStates(player: RpgPlayer, states: { addStates?: Array<{ state: any; rate: number }>; removeStates?: Array<{ state: any; rate: number }> }): void;
227
+
228
+ /**
229
+ * Get a state to the player. Returns null if the state is not present
230
+ *
231
+ * @param stateClass - The state class constructor or state ID to search for
232
+ * @returns The state instance if found, null otherwise
233
+ */
234
+ getState(stateClass: StateClass | string): any | null;
235
+
236
+ /**
237
+ * Adds a state to the player
238
+ *
239
+ * @param stateClass - The state class constructor or state ID to apply
240
+ * @param chance - Probability of successful application (0-1, default 1)
241
+ * @returns The state instance if successfully applied, null if already present
242
+ * @throws StateLog.addFailed if the chance roll fails
243
+ */
244
+ addState(stateClass: StateClass | string, chance?: number): object | null;
245
+
246
+ /**
247
+ * Remove a state to the player
248
+ *
249
+ * @param stateClass - The state class constructor or state ID to remove
250
+ * @param chance - Probability of successful removal (0-1, default 1)
251
+ * @throws StateLog.removeFailed if the chance roll fails
252
+ * @throws StateLog.notApplied if the state is not currently active
253
+ */
254
+ removeState(stateClass: StateClass | string, chance?: number): void;
255
+
256
+ /**
257
+ * Find state efficiency modifier for a specific state class
258
+ *
259
+ * @param stateClass - The state class to find efficiency for
260
+ * @returns The efficiency object if found, undefined otherwise
261
+ */
262
+ findStateEfficiency(stateClass: any): any | undefined;
275
263
  }
@@ -1,75 +1,113 @@
1
- import { type Constructor } from "@rpgjs/common";
2
- import { RpgCommonPlayer } from "@rpgjs/common";
1
+ import { Constructor, PlayerCtor } from "@rpgjs/common";
2
+ import { signal } from "@signe/reactive";
3
+ import { type } from "@signe/sync";
3
4
 
4
5
  /**
5
- * Interface defining what MoveManager adds to a class
6
- */
7
- export interface IWithVariableManager {
8
- variables: Map<string, any>
9
- }
10
-
11
- /**
12
- * Move Manager mixin
6
+ * Variable Manager Mixin
7
+ *
8
+ * Provides variable management capabilities to any class. Variables are key-value
9
+ * pairs that can store any type of data associated with the player, such as
10
+ * quest progress, game flags, inventory state, and custom game data.
11
+ *
12
+ * @param Base - The base class to extend with variable management
13
+ * @returns Extended class with variable management methods
13
14
  *
14
- * Adds methods to manage player movement
15
+ * @example
16
+ * ```ts
17
+ * class MyPlayer extends WithVariableManager(BasePlayer) {
18
+ * constructor() {
19
+ * super();
20
+ * // Variables are automatically initialized
21
+ * }
22
+ * }
15
23
  *
16
- * @param Base - The base class to extend
17
- * @returns A new class with move management capabilities
24
+ * const player = new MyPlayer();
25
+ * player.setVariable('questCompleted', true);
26
+ * ```
18
27
  */
19
- export function WithVariableManager<TBase extends Constructor<RpgCommonPlayer>>(Base: TBase) {
20
- return class extends Base implements IWithVariableManager {
21
- variables: Map<string, any> = new Map()
28
+ export function WithVariableManager<TBase extends PlayerCtor>(Base: TBase) {
29
+ return class extends Base {
30
+ variables = type(signal<Record<string, any>>({}) as any, 'variables', { persist: true }, this as any);
31
+
32
+ setVariable(key: string, val: any): void {
33
+ this.variables()[key] = val;
34
+ }
35
+
36
+ getVariable<U = any>(key: string): U | undefined {
37
+ return this.variables()[key];
38
+ }
39
+
40
+ removeVariable(key: string): boolean {
41
+ delete this.variables()[key];
42
+ return true;
43
+ }
22
44
 
23
- /**
24
- * Assign a variable to the player
25
- *
26
- * ```ts
27
- * player.setVariable('OPEN_CHEST', true)
28
- * ```
29
- *
30
- * @title Set variable
31
- * @method player.setVariable(key,val)
32
- * @param {string} key
33
- * @param {any} val
34
- * @returns {void}
35
- * @memberof VariableManager
36
- * */
37
- setVariable(key: string, val) {
38
- this.variables.set(key, val)
45
+ hasVariable(key: string): boolean {
46
+ return key in this.variables();
39
47
  }
40
48
 
41
- /**
42
- * Get a variable
43
- *
44
- * ```ts
45
- * const val = player.getVariable('OPEN_CHEST')
46
- * ```
47
- *
48
- * @title Get variable
49
- * @method player.setVariable(key,val)
50
- * @param {string} key
51
- * @returns {any}
52
- * @memberof VariableManager
53
- * */
54
- getVariable(key: string) {
55
- return this.variables.get(key)
49
+ getVariableKeys(): string[] {
50
+ return Object.keys(this.variables());
56
51
  }
57
52
 
58
- /**
59
- * Remove a variable
60
- *
61
- * ```ts
62
- * player.removeVariable('OPEN_CHEST')
63
- * ```
64
- *
65
- * @title Remove variable
66
- * @method player.removeVariable(key)
67
- * @param {string} key
68
- * @returns {boolean} true if a variable existed and has been removed, or false if the variable does not exist.
69
- * @memberof VariableManager
70
- * */
71
- removeVariable(key: string) {
72
- return this.variables.delete(key)
53
+ clearVariables(): void {
54
+ this.variables.set({});
73
55
  }
74
- };
56
+ } as unknown as TBase;
75
57
  }
58
+
59
+ /**
60
+ * Interface for Variable Manager functionality
61
+ *
62
+ * Provides variable management capabilities including storing, retrieving, and managing
63
+ * key-value pairs for player-specific data. This interface defines the public API
64
+ * of the VariableManager mixin.
65
+ */
66
+ export interface IVariableManager {
67
+ /** Map storing all player variables */
68
+ variables: Map<string, any>;
69
+
70
+ /**
71
+ * Assign a variable to the player
72
+ *
73
+ * @param key - The variable identifier
74
+ * @param val - The value to store
75
+ */
76
+ setVariable(key: string, val: any): void;
77
+
78
+ /**
79
+ * Get a variable value
80
+ *
81
+ * @param key - The variable identifier to retrieve
82
+ * @returns The stored value or undefined if not found
83
+ */
84
+ getVariable<U = any>(key: string): U | undefined;
85
+
86
+ /**
87
+ * Remove a variable
88
+ *
89
+ * @param key - The variable identifier to remove
90
+ * @returns true if a variable existed and has been removed, false otherwise
91
+ */
92
+ removeVariable(key: string): boolean;
93
+
94
+ /**
95
+ * Check if a variable exists
96
+ *
97
+ * @param key - The variable identifier to check
98
+ * @returns true if the variable exists, false otherwise
99
+ */
100
+ hasVariable(key: string): boolean;
101
+
102
+ /**
103
+ * Get all variable keys
104
+ *
105
+ * @returns Array of all variable keys
106
+ */
107
+ getVariableKeys(): string[];
108
+
109
+ /**
110
+ * Clear all variables
111
+ */
112
+ clearVariables(): void;
113
+ }