@rpgjs/server 5.0.0-alpha.21 → 5.0.0-alpha.23

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.
@@ -46,103 +46,10 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
46
46
  return class extends Base {
47
47
  _statesEfficiency = signal<any[]>([]);
48
48
 
49
- /**
50
- * Recovers the player's states defense on inventory. This list is generated from the `statesDefense` property defined on the weapons or armors equipped.
51
- * If several items have the same element, only the highest rate will be taken into account.
52
- *
53
- * Gets the defensive capabilities against various states from equipped items.
54
- * The system automatically consolidates multiple defensive items, keeping only
55
- * the highest protection rate for each state type. This provides comprehensive
56
- * protection against debuffs and negative status effects.
57
- *
58
- * @returns Array of state defense objects with rate and state properties
59
- *
60
- * @example
61
- * ```ts
62
- * import { Armor, State } from '@rpgjs/server'
63
- *
64
- * @State({
65
- * name: 'Paralyze'
66
- * })
67
- * class Paralyze {}
68
- *
69
- * @Armor({
70
- * name: 'Shield',
71
- * statesDefense: [{ rate: 1, state: Paralyze }]
72
- * })
73
- * class Shield {}
74
- *
75
- * @Armor({
76
- * name: 'FireShield',
77
- * statesDefense: [{ rate: 0.5, state: Paralyze }]
78
- * })
79
- * class FireShield {}
80
- *
81
- * player.addItem(Shield)
82
- * player.addItem(FireShield)
83
- * player.equip(Shield)
84
- * player.equip(FireShield)
85
- *
86
- * console.log(player.statesDefense) // [{ rate: 1, state: instance of Paralyze }]
87
- *
88
- * // Check specific state defense
89
- * const paralyzeDefense = player.statesDefense.find(def => def.state instanceof Paralyze);
90
- * if (paralyzeDefense) {
91
- * console.log(`Paralyze defense rate: ${paralyzeDefense.rate}`);
92
- * }
93
- * ```
94
- */
95
49
  get statesDefense(): { rate: number; state: any }[] {
96
50
  return (this as any).getFeature("statesDefense", "state");
97
51
  }
98
52
 
99
- /**
100
- * Set or retrieves all the states where the player is vulnerable or not.
101
- *
102
- * Manages the player's state efficiency modifiers, which determine how
103
- * effective different states are against this player. Values greater than 1
104
- * indicate vulnerability, while values less than 1 indicate resistance.
105
- * This combines both class-based efficiency and player-specific modifiers.
106
- *
107
- * @returns Array of state efficiency objects with rate and state properties
108
- *
109
- * @example
110
- * ```ts
111
- * import { Class, State } from '@rpgjs/server'
112
- *
113
- * @State({
114
- * name: 'Paralyze'
115
- * })
116
- * class Paralyze {}
117
- *
118
- * @State({
119
- * name: 'Sleep'
120
- * })
121
- * class Sleep {}
122
- *
123
- * @Class({
124
- * name: 'Fighter',
125
- * statesEfficiency: [{ rate: 1, state: Paralyze }]
126
- * })
127
- * class Hero {}
128
- *
129
- * player.setClass(Hero)
130
- *
131
- * console.log(player.statesEfficiency) // [{ rate: 1, instance of Paralyze }]
132
- *
133
- * player.statesEfficiency = [{ rate: 2, state: Sleep }]
134
- *
135
- * console.log(player.statesEfficiency) // [{ rate: 1, state: instance of Paralyze }, { rate: 2, state: instance of Sleep }]
136
- *
137
- * // Check for vulnerabilities
138
- * const vulnerabilities = player.statesEfficiency.filter(eff => eff.rate > 1);
139
- * console.log('Vulnerable to states:', vulnerabilities.map(v => v.state.name));
140
- *
141
- * // Check for resistances
142
- * const resistances = player.statesEfficiency.filter(eff => eff.rate < 1);
143
- * console.log('Resistant to states:', resistances.map(r => r.state.name));
144
- * ```
145
- */
146
53
  get statesEfficiency() {
147
54
  return this._statesEfficiency;
148
55
  }
@@ -151,35 +58,6 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
151
58
  this._statesEfficiency = val;
152
59
  }
153
60
 
154
- /**
155
- * Apply states to a player from skill or item effects
156
- *
157
- * Processes state application and removal based on skill or item effects.
158
- * This method handles both adding beneficial states and removing negative ones,
159
- * with proper chance calculation and resistance checks.
160
- *
161
- * @param player - The target player to apply states to
162
- * @param states - Object containing arrays of states to add or remove
163
- *
164
- * @example
165
- * ```ts
166
- * // Apply states from a healing skill
167
- * const healingStates = {
168
- * addStates: [{ state: Regeneration, rate: 0.8 }],
169
- * removeStates: [{ state: Poison, rate: 1.0 }]
170
- * };
171
- * player.applyStates(targetPlayer, healingStates);
172
- *
173
- * // Apply debuff from an enemy attack
174
- * const debuffStates = {
175
- * addStates: [
176
- * { state: Paralyze, rate: 0.3 },
177
- * { state: Slow, rate: 0.5 }
178
- * ]
179
- * };
180
- * player.applyStates(targetPlayer, debuffStates);
181
- * ```
182
- */
183
61
  applyStates(
184
62
  player: RpgPlayer,
185
63
  { addStates, removeStates }
@@ -196,40 +74,6 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
196
74
  }
197
75
  }
198
76
 
199
- /**
200
- * Get a state to the player. Returns `null` if the state is not present on the player
201
- *
202
- * Retrieves a specific state instance from the player's active states.
203
- * This is useful for checking state properties, duration, or performing
204
- * state-specific operations. Returns null if the state is not currently active.
205
- *
206
- * @param stateClass - The state class constructor or state ID to search for
207
- * @returns The state instance if found, null otherwise
208
- *
209
- * @example
210
- * ```ts
211
- * import Paralyze from 'your-database/states/paralyze'
212
- *
213
- * // Check if player has a specific state
214
- * const paralyzeState = player.getState(Paralyze);
215
- * if (paralyzeState) {
216
- * console.log('Player is paralyzed');
217
- * console.log('Remaining duration:', paralyzeState.duration);
218
- * }
219
- *
220
- * // Check using string ID
221
- * const poisonState = player.getState('poison');
222
- * if (poisonState) {
223
- * console.log('Player is poisoned');
224
- * }
225
- *
226
- * // Use in conditional logic
227
- * if (player.getState(Sleep)) {
228
- * console.log('Player cannot act while sleeping');
229
- * return; // Skip player turn
230
- * }
231
- * ```
232
- */
233
77
  getState(stateClass: StateClass | string) {
234
78
  if (isString(stateClass)) stateClass = (this as any).databaseById(stateClass);
235
79
  return this.states().find((state) => {
@@ -240,54 +84,6 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
240
84
  });
241
85
  }
242
86
 
243
- /**
244
- * Adds a state to the player. Set the chance between 0 and 1 that the state can apply
245
- *
246
- * Attempts to apply a state to the player with a specified success chance.
247
- * The method considers state resistance, efficiency modifiers, and random chance
248
- * to determine if the state is successfully applied. If successful, the state
249
- * is added to the player's active states list.
250
- *
251
- * @param stateClass - The state class constructor or state ID to apply
252
- * @param chance - Probability of successful application (0-1, default 1)
253
- * @returns The state instance if successfully applied, null if already present
254
- * @throws StateLog.addFailed if the chance roll fails
255
- *
256
- * @example
257
- * ```ts
258
- * import Paralyze from 'your-database/states/paralyze'
259
- *
260
- * try {
261
- * // Attempt to apply paralyze with 100% chance
262
- * const state = player.addState(Paralyze);
263
- * if (state) {
264
- * console.log('Paralyze applied successfully');
265
- * }
266
- * } catch (err) {
267
- * console.log('Failed to apply paralyze:', err.msg);
268
- * }
269
- *
270
- * // Apply with reduced chance
271
- * try {
272
- * player.addState(Poison, 0.3); // 30% chance
273
- * } catch (err) {
274
- * console.log('Poison application failed');
275
- * }
276
- *
277
- * // Apply multiple states with different chances
278
- * const debuffs = [
279
- * { state: Slow, chance: 0.8 },
280
- * { state: Weak, chance: 0.6 }
281
- * ];
282
- * debuffs.forEach(({ state, chance }) => {
283
- * try {
284
- * player.addState(state, chance);
285
- * } catch (err) {
286
- * // Handle failed applications
287
- * }
288
- * });
289
- * ```
290
- */
291
87
  addState(stateClass: StateClass | string, chance = 1): object | null {
292
88
  const state = this.getState(stateClass);
293
89
  if (isString(stateClass)) {
@@ -306,52 +102,6 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
306
102
  return null;
307
103
  }
308
104
 
309
- /**
310
- * Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
311
- *
312
- * Attempts to remove a state from the player with a specified success chance.
313
- * This is useful for cure spells, items, or time-based state removal.
314
- * The method considers removal resistance and random chance.
315
- *
316
- * @param stateClass - The state class constructor or state ID to remove
317
- * @param chance - Probability of successful removal (0-1, default 1)
318
- * @throws StateLog.removeFailed if the chance roll fails
319
- * @throws StateLog.notApplied if the state is not currently active
320
- *
321
- * @example
322
- * ```ts
323
- * import Paralyze from 'your-database/states/paralyze'
324
- *
325
- * try {
326
- * // Attempt to remove paralyze with 100% chance
327
- * player.removeState(Paralyze);
328
- * console.log('Paralyze removed successfully');
329
- * } catch (err) {
330
- * if (err.id === 'STATE_NOT_APPLIED') {
331
- * console.log('Player was not paralyzed');
332
- * } else {
333
- * console.log('Failed to remove paralyze:', err.msg);
334
- * }
335
- * }
336
- *
337
- * // Remove with reduced chance (for weak cure spells)
338
- * try {
339
- * player.removeState(Poison, 0.7); // 70% chance
340
- * } catch (err) {
341
- * console.log('Cure failed');
342
- * }
343
- *
344
- * // Remove all negative states (cure-all effect)
345
- * const negativeStates = [Poison, Paralyze, Sleep, Slow];
346
- * negativeStates.forEach(state => {
347
- * try {
348
- * player.removeState(state);
349
- * } catch (err) {
350
- * // State wasn't active, continue
351
- * }
352
- * });
353
- * ```
354
- */
355
105
  removeState(stateClass: StateClass | string, chance = 1) {
356
106
  const index = this.states().findIndex((state) => {
357
107
  if (isString(stateClass)) {
@@ -369,12 +119,6 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
369
119
  }
370
120
  }
371
121
 
372
- /**
373
- * Find state efficiency modifier for a specific state class
374
- *
375
- * @param stateClass - The state class to find efficiency for
376
- * @returns The efficiency object if found, undefined otherwise
377
- */
378
122
  findStateEfficiency(stateClass) {
379
123
  return this.statesEfficiency().find((state) =>
380
124
  isInstanceOf(state.state, stateClass)
@@ -384,7 +128,67 @@ export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
384
128
  }
385
129
 
386
130
  /**
387
- * Type helper to extract the interface from the WithStateManager mixin
388
- * This provides the type without duplicating method signatures
131
+ * Interface for State Manager functionality
132
+ *
133
+ * Provides state management capabilities including state defense, efficiency modifiers,
134
+ * and state application/removal. This interface defines the public API of the StateManager mixin.
389
135
  */
390
- export type IStateManager = InstanceType<ReturnType<typeof WithStateManager>>;
136
+ export interface IStateManager {
137
+ /**
138
+ * Gets the defensive capabilities against various states from equipped items
139
+ *
140
+ * @returns Array of state defense objects with rate and state properties
141
+ */
142
+ statesDefense: { rate: number; state: any }[];
143
+
144
+ /**
145
+ * Manages the player's state efficiency modifiers
146
+ *
147
+ * @returns Signal containing array of state efficiency objects
148
+ */
149
+ statesEfficiency: any;
150
+
151
+ /**
152
+ * Apply states to a player from skill or item effects
153
+ *
154
+ * @param player - The target player to apply states to
155
+ * @param states - Object containing arrays of states to add or remove
156
+ */
157
+ applyStates(player: RpgPlayer, states: { addStates?: Array<{ state: any; rate: number }>; removeStates?: Array<{ state: any; rate: number }> }): void;
158
+
159
+ /**
160
+ * Get a state to the player. Returns null if the state is not present
161
+ *
162
+ * @param stateClass - The state class constructor or state ID to search for
163
+ * @returns The state instance if found, null otherwise
164
+ */
165
+ getState(stateClass: StateClass | string): any | null;
166
+
167
+ /**
168
+ * Adds a state to the player
169
+ *
170
+ * @param stateClass - The state class constructor or state ID to apply
171
+ * @param chance - Probability of successful application (0-1, default 1)
172
+ * @returns The state instance if successfully applied, null if already present
173
+ * @throws StateLog.addFailed if the chance roll fails
174
+ */
175
+ addState(stateClass: StateClass | string, chance?: number): object | null;
176
+
177
+ /**
178
+ * Remove a state to the player
179
+ *
180
+ * @param stateClass - The state class constructor or state ID to remove
181
+ * @param chance - Probability of successful removal (0-1, default 1)
182
+ * @throws StateLog.removeFailed if the chance roll fails
183
+ * @throws StateLog.notApplied if the state is not currently active
184
+ */
185
+ removeState(stateClass: StateClass | string, chance?: number): void;
186
+
187
+ /**
188
+ * Find state efficiency modifier for a specific state class
189
+ *
190
+ * @param stateClass - The state class to find efficiency for
191
+ * @returns The efficiency object if found, undefined otherwise
192
+ */
193
+ findStateEfficiency(stateClass: any): any | undefined;
194
+ }
@@ -27,173 +27,26 @@ export function WithVariableManager<TBase extends PlayerCtor>(Base: TBase) {
27
27
  return class extends Base {
28
28
  variables: Map<string, any> = new Map();
29
29
 
30
- /**
31
- * Assign a variable to the player
32
- *
33
- * Stores a key-value pair in the player's variable map. This is useful for
34
- * tracking game state, quest progress, flags, and other player-specific data.
35
- * The variable system provides a flexible way to store any type of data
36
- * associated with the player that persists throughout the game session.
37
- *
38
- * @param key - The variable identifier (string key to reference the variable)
39
- * @param val - The value to store (can be any type: boolean, number, string, object, array)
40
- * @returns void
41
- *
42
- * @example
43
- * ```ts
44
- * // Set different types of variables
45
- * player.setVariable('CHEST_OPENED', true);
46
- * player.setVariable('playerLevel', 5);
47
- * player.setVariable('questProgress', { step: 1, completed: false });
48
- * player.setVariable('inventory', ['sword', 'potion', 'key']);
49
- * player.setVariable('lastSaveTime', new Date().toISOString());
50
- * ```
51
- */
52
30
  setVariable(key: string, val: any): void {
53
31
  this.variables.set(key, val);
54
32
  }
55
33
 
56
- /**
57
- * Get a variable value
58
- *
59
- * Retrieves the value associated with the given key from the player's variables.
60
- * Returns undefined if the variable doesn't exist. This method is type-safe
61
- * and can be used with generic types for better TypeScript support.
62
- *
63
- * @param key - The variable identifier to retrieve
64
- * @returns The stored value or undefined if not found
65
- *
66
- * @example
67
- * ```ts
68
- * // Get variables with type inference
69
- * const hasKey = player.getVariable('CHEST_OPENED'); // boolean | undefined
70
- * const level = player.getVariable('playerLevel'); // number | undefined
71
- * const quest = player.getVariable('questProgress'); // object | undefined
72
- * const missing = player.getVariable('nonexistent'); // undefined
73
- *
74
- * // Use with default values
75
- * const level = player.getVariable('playerLevel') ?? 1;
76
- * const isChestOpened = player.getVariable('CHEST_OPENED') ?? false;
77
- * ```
78
- */
79
34
  getVariable<U = any>(key: string): U | undefined {
80
35
  return this.variables.get(key);
81
36
  }
82
37
 
83
- /**
84
- * Remove a variable
85
- *
86
- * Deletes a variable from the player's variable map. This is useful for
87
- * cleaning up temporary flags, resetting certain game states, or managing
88
- * memory by removing unused variables. The method returns a boolean indicating
89
- * whether the variable existed and was successfully removed.
90
- *
91
- * @param key - The variable identifier to remove
92
- * @returns true if a variable existed and has been removed, false if the variable does not exist
93
- *
94
- * @example
95
- * ```ts
96
- * // Remove variables and check if they existed
97
- * const removed = player.removeVariable('CHEST_OPENED'); // true if existed
98
- * const notFound = player.removeVariable('nonexistent'); // false
99
- *
100
- * // Clean up temporary variables
101
- * player.removeVariable('tempQuestFlag');
102
- * player.removeVariable('battleTempData');
103
- *
104
- * // Conditional removal
105
- * if (player.getVariable('questCompleted')) {
106
- * player.removeVariable('questProgress');
107
- * }
108
- * ```
109
- */
110
38
  removeVariable(key: string): boolean {
111
39
  return this.variables.delete(key);
112
40
  }
113
41
 
114
- /**
115
- * Check if a variable exists
116
- *
117
- * Determines whether a variable with the given key exists in the player's
118
- * variable map, regardless of its value (including falsy values like false, 0, '').
119
- * This is useful when you need to distinguish between a variable that doesn't
120
- * exist and one that has a falsy value.
121
- *
122
- * @param key - The variable identifier to check
123
- * @returns true if the variable exists, false otherwise
124
- *
125
- * @example
126
- * ```ts
127
- * // Check variable existence
128
- * player.setVariable('flag', false);
129
- * player.hasVariable('flag'); // true (even though value is false)
130
- * player.hasVariable('missing'); // false
131
- *
132
- * // Use in conditional logic
133
- * if (player.hasVariable('questStarted')) {
134
- * // Quest has been started, check progress
135
- * const progress = player.getVariable('questProgress');
136
- * } else {
137
- * // Quest not started yet
138
- * player.setVariable('questStarted', true);
139
- * }
140
- * ```
141
- */
142
42
  hasVariable(key: string): boolean {
143
43
  return this.variables.has(key);
144
44
  }
145
45
 
146
- /**
147
- * Get all variable keys
148
- *
149
- * Returns an array of all variable keys currently stored for this player.
150
- * This is useful for debugging, serialization, or iterating over all variables.
151
- * The keys are returned in insertion order.
152
- *
153
- * @returns Array of all variable keys
154
- *
155
- * @example
156
- * ```ts
157
- * // Get all variable keys
158
- * const keys = player.getVariableKeys();
159
- * console.log('Player has variables:', keys);
160
- *
161
- * // Iterate over all variables
162
- * keys.forEach(key => {
163
- * const value = player.getVariable(key);
164
- * console.log(`${key}: ${value}`);
165
- * });
166
- *
167
- * // Filter specific variable types
168
- * const questKeys = keys.filter(key => key.startsWith('quest_'));
169
- * ```
170
- */
171
46
  getVariableKeys(): string[] {
172
47
  return Array.from(this.variables.keys());
173
48
  }
174
49
 
175
- /**
176
- * Clear all variables
177
- *
178
- * Removes all variables from the player's variable map. This is useful for
179
- * resetting the player state, cleaning up before saving, or starting fresh.
180
- * Use with caution as this operation cannot be undone.
181
- *
182
- * @returns void
183
- *
184
- * @example
185
- * ```ts
186
- * // Clear all variables (use with caution)
187
- * player.clearVariables();
188
- *
189
- * // Clear variables conditionally
190
- * if (gameReset) {
191
- * player.clearVariables();
192
- * // Re-initialize essential variables
193
- * player.setVariable('gameStarted', true);
194
- * }
195
- * ```
196
- */
197
50
  clearVariables(): void {
198
51
  this.variables.clear();
199
52
  }
@@ -201,7 +54,57 @@ export function WithVariableManager<TBase extends PlayerCtor>(Base: TBase) {
201
54
  }
202
55
 
203
56
  /**
204
- * Type helper to extract the interface from the WithVariableManager mixin
205
- * This provides the type without duplicating method signatures
57
+ * Interface for Variable Manager functionality
58
+ *
59
+ * Provides variable management capabilities including storing, retrieving, and managing
60
+ * key-value pairs for player-specific data. This interface defines the public API
61
+ * of the VariableManager mixin.
206
62
  */
207
- export type IVariableManager = InstanceType<ReturnType<typeof WithVariableManager>>;
63
+ export interface IVariableManager {
64
+ /** Map storing all player variables */
65
+ variables: Map<string, any>;
66
+
67
+ /**
68
+ * Assign a variable to the player
69
+ *
70
+ * @param key - The variable identifier
71
+ * @param val - The value to store
72
+ */
73
+ setVariable(key: string, val: any): void;
74
+
75
+ /**
76
+ * Get a variable value
77
+ *
78
+ * @param key - The variable identifier to retrieve
79
+ * @returns The stored value or undefined if not found
80
+ */
81
+ getVariable<U = any>(key: string): U | undefined;
82
+
83
+ /**
84
+ * Remove a variable
85
+ *
86
+ * @param key - The variable identifier to remove
87
+ * @returns true if a variable existed and has been removed, false otherwise
88
+ */
89
+ removeVariable(key: string): boolean;
90
+
91
+ /**
92
+ * Check if a variable exists
93
+ *
94
+ * @param key - The variable identifier to check
95
+ * @returns true if the variable exists, false otherwise
96
+ */
97
+ hasVariable(key: string): boolean;
98
+
99
+ /**
100
+ * Get all variable keys
101
+ *
102
+ * @returns Array of all variable keys
103
+ */
104
+ getVariableKeys(): string[];
105
+
106
+ /**
107
+ * Clear all variables
108
+ */
109
+ clearVariables(): void;
110
+ }