@rpgjs/server 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (53) hide show
  1. package/dist/Gui/DialogGui.d.ts +4 -0
  2. package/dist/Gui/index.d.ts +1 -0
  3. package/dist/Player/BattleManager.d.ts +32 -22
  4. package/dist/Player/ClassManager.d.ts +31 -18
  5. package/dist/Player/ComponentManager.d.ts +123 -0
  6. package/dist/Player/Components.d.ts +345 -0
  7. package/dist/Player/EffectManager.d.ts +40 -0
  8. package/dist/Player/ElementManager.d.ts +31 -0
  9. package/dist/Player/GoldManager.d.ts +22 -0
  10. package/dist/Player/GuiManager.d.ts +176 -0
  11. package/dist/Player/ItemFixture.d.ts +6 -0
  12. package/dist/Player/ItemManager.d.ts +164 -10
  13. package/dist/Player/MoveManager.d.ts +32 -44
  14. package/dist/Player/ParameterManager.d.ts +343 -14
  15. package/dist/Player/Player.d.ts +266 -8
  16. package/dist/Player/SkillManager.d.ts +27 -19
  17. package/dist/Player/StateManager.d.ts +28 -35
  18. package/dist/Player/VariableManager.d.ts +30 -0
  19. package/dist/RpgServer.d.ts +227 -1
  20. package/dist/decorators/event.d.ts +46 -0
  21. package/dist/decorators/map.d.ts +177 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +17436 -18167
  24. package/dist/index.js.map +1 -1
  25. package/dist/rooms/map.d.ts +486 -8
  26. package/package.json +17 -15
  27. package/src/Gui/DialogGui.ts +7 -2
  28. package/src/Gui/index.ts +3 -1
  29. package/src/Player/BattleManager.ts +97 -38
  30. package/src/Player/ClassManager.ts +95 -35
  31. package/src/Player/ComponentManager.ts +425 -19
  32. package/src/Player/Components.ts +380 -0
  33. package/src/Player/EffectManager.ts +110 -27
  34. package/src/Player/ElementManager.ts +126 -25
  35. package/src/Player/GoldManager.ts +32 -35
  36. package/src/Player/GuiManager.ts +187 -140
  37. package/src/Player/ItemFixture.ts +4 -5
  38. package/src/Player/ItemManager.ts +363 -48
  39. package/src/Player/MoveManager.ts +323 -308
  40. package/src/Player/ParameterManager.ts +499 -99
  41. package/src/Player/Player.ts +719 -80
  42. package/src/Player/SkillManager.ts +44 -23
  43. package/src/Player/StateManager.ts +210 -95
  44. package/src/Player/VariableManager.ts +180 -48
  45. package/src/RpgServer.ts +236 -1
  46. package/src/core/context.ts +1 -0
  47. package/src/decorators/event.ts +61 -0
  48. package/src/decorators/map.ts +198 -0
  49. package/src/index.ts +5 -1
  50. package/src/module.ts +24 -0
  51. package/src/rooms/map.ts +1054 -54
  52. package/dist/Player/Event.d.ts +0 -0
  53. package/src/Player/Event.ts +0 -0
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Component definitions for player UI elements
3
+ *
4
+ * This module provides factory functions to create component definitions
5
+ * that can be displayed above or below player graphics. Components are
6
+ * synchronized from server to client and rendered using CanvasEngine.
7
+ *
8
+ * ## Design
9
+ *
10
+ * Components are defined as data structures that describe UI elements
11
+ * (text, bars, shapes) with their properties and layout options. The
12
+ * server creates these definitions and they are automatically synchronized
13
+ * to all clients on the map.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { Components } from '@rpgjs/server';
18
+ *
19
+ * // Create a text component
20
+ * const nameComponent = Components.text('{name}');
21
+ *
22
+ * // Create an HP bar
23
+ * const hpBar = Components.hpBar();
24
+ *
25
+ * // Set components on player
26
+ * player.setComponentsTop([nameComponent, hpBar]);
27
+ * ```
28
+ */
29
+
30
+ export interface ComponentLayout {
31
+ /** Width of the component block in pixels */
32
+ width?: number;
33
+ /** Height of the component block in pixels */
34
+ height?: number;
35
+ /** Margin from the top of the player in pixels */
36
+ marginTop?: number;
37
+ /** Margin from the bottom of the player in pixels */
38
+ marginBottom?: number;
39
+ /** Margin from the left of the player in pixels */
40
+ marginLeft?: number;
41
+ /** Margin from the right of the player in pixels */
42
+ marginRight?: number;
43
+ }
44
+
45
+ export interface TextComponentOptions {
46
+ /** Text color in hexadecimal format (e.g., '#000000') */
47
+ fill?: string;
48
+ /** Font size in pixels */
49
+ fontSize?: number;
50
+ /** Font family */
51
+ fontFamily?: string;
52
+ /** Font style: 'normal', 'italic', 'oblique' */
53
+ fontStyle?: 'normal' | 'italic' | 'oblique';
54
+ /** Font weight: 'normal', 'bold', 'bolder', 'lighter', or numeric values */
55
+ fontWeight?: 'normal' | 'bold' | 'bolder' | 'lighter' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;
56
+ /** Stroke color in hexadecimal format */
57
+ stroke?: string;
58
+ /** Opacity between 0 and 1 */
59
+ opacity?: number;
60
+ /** Word wrap */
61
+ wordWrap?: boolean;
62
+ /** Text alignment */
63
+ align?: 'left' | 'center' | 'right' | 'justify';
64
+ }
65
+
66
+ export interface BarComponentOptions {
67
+ /** Background color in hexadecimal format */
68
+ bgColor?: string;
69
+ /** Fill color in hexadecimal format */
70
+ fillColor?: string;
71
+ /** Border color in hexadecimal format */
72
+ borderColor?: string;
73
+ /** Border width */
74
+ borderWidth?: number;
75
+ /** Height of the bar in pixels */
76
+ height?: number;
77
+ /** Width of the bar in pixels */
78
+ width?: number;
79
+ /** Border radius */
80
+ borderRadius?: number;
81
+ /** Opacity between 0 and 1 */
82
+ opacity?: number;
83
+ }
84
+
85
+ export interface ShapeComponentOptions {
86
+ /** Fill color in hexadecimal format */
87
+ fill: string;
88
+ /** Type of shape */
89
+ type: 'circle' | 'rectangle' | 'ellipse' | 'polygon' | 'line' | 'rounded-rectangle';
90
+ /** Radius (for circle) */
91
+ radius?: number | string;
92
+ /** Width (for rectangle, ellipse) */
93
+ width?: number | string;
94
+ /** Height (for rectangle, ellipse) */
95
+ height?: number | string;
96
+ /** X1 position (for line) */
97
+ x1?: number | string;
98
+ /** Y1 position (for line) */
99
+ y1?: number | string;
100
+ /** X2 position (for line) */
101
+ x2?: number | string;
102
+ /** Y2 position (for line) */
103
+ y2?: number | string;
104
+ /** Points array (for polygon) */
105
+ points?: number[];
106
+ /** Opacity between 0 and 1 */
107
+ opacity?: number | string;
108
+ /** Line/border style */
109
+ line?: {
110
+ color?: string;
111
+ width?: number;
112
+ alpha?: number;
113
+ };
114
+ }
115
+
116
+ export type ComponentDefinition =
117
+ | { type: 'text'; value: string; style?: TextComponentOptions }
118
+ | { type: 'hpBar'; style?: BarComponentOptions; text?: string | null }
119
+ | { type: 'spBar'; style?: BarComponentOptions; text?: string | null }
120
+ | { type: 'bar'; current: string; max: string; style?: BarComponentOptions; text?: string | null }
121
+ | { type: 'shape'; value: ShapeComponentOptions }
122
+ | { type: 'image'; value: string }
123
+ | { type: 'tile'; value: number | string };
124
+
125
+ export type ComponentInput = ComponentDefinition | ComponentDefinition[] | ComponentDefinition[][];
126
+
127
+ /**
128
+ * Components factory for creating component definitions
129
+ *
130
+ * Provides factory methods to create various UI components that can be
131
+ * displayed above or below player graphics. Components support template
132
+ * strings with placeholders like {name}, {hp}, etc. that are replaced
133
+ * with actual player property values on the client.
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * // Create a text component
138
+ * Components.text('Player: {name}');
139
+ *
140
+ * // Create an HP bar with custom text
141
+ * Components.hpBar({}, '{$percent}%');
142
+ *
143
+ * // Create a custom bar
144
+ * Components.bar('wood', 'param.maxWood');
145
+ * ```
146
+ */
147
+ export const Components = {
148
+ /**
149
+ * Create a text component
150
+ *
151
+ * Creates a text component that displays text with optional styling.
152
+ * Supports template strings with placeholders like {name}, {hp}, etc.
153
+ * that are replaced with actual player property values.
154
+ *
155
+ * ## Design
156
+ *
157
+ * Text components use template strings to allow dynamic content without
158
+ * resending the entire component structure when values change. Only the
159
+ * property values are synchronized, reducing bandwidth usage.
160
+ *
161
+ * @param text - Text to display, can include placeholders like {name}, {hp}
162
+ * @param options - Text styling options
163
+ * @returns Component definition for text
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * // Simple text
168
+ * Components.text('Player Name');
169
+ *
170
+ * // Text with placeholder
171
+ * Components.text('{name}');
172
+ *
173
+ * // Text with styling
174
+ * Components.text('{name}', {
175
+ * fill: '#000000',
176
+ * fontSize: 20
177
+ * });
178
+ * ```
179
+ */
180
+ text(value: string, style?: TextComponentOptions): ComponentDefinition {
181
+ return {
182
+ type: 'text',
183
+ value,
184
+ style
185
+ };
186
+ },
187
+
188
+ /**
189
+ * Create an HP bar component
190
+ *
191
+ * Creates a health point bar that automatically displays the player's
192
+ * current HP relative to their maximum HP. The bar updates automatically
193
+ * as HP changes.
194
+ *
195
+ * ## Design
196
+ *
197
+ * HP bars read from the player's hp and param.maxHp properties. The
198
+ * bar can optionally display text above it showing current, max, or
199
+ * percentage values.
200
+ *
201
+ * @param options - Bar styling options
202
+ * @param text - Optional text to display above the bar. Can use placeholders:
203
+ * - {$current} - Current HP value
204
+ * - {$max} - Maximum HP value
205
+ * - {$percent} - Percentage value
206
+ * Set to null to hide text
207
+ * @returns Component definition for HP bar
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * // Simple HP bar
212
+ * Components.hpBar();
213
+ *
214
+ * // HP bar with percentage text
215
+ * Components.hpBar({}, '{$percent}%');
216
+ *
217
+ * // HP bar with custom styling
218
+ * Components.hpBar({
219
+ * fillColor: '#ff0000',
220
+ * height: 8
221
+ * });
222
+ * ```
223
+ */
224
+ hpBar(style?: BarComponentOptions, text?: string | null): ComponentDefinition {
225
+ return {
226
+ type: 'hpBar',
227
+ style,
228
+ text: text ?? undefined
229
+ };
230
+ },
231
+
232
+ /**
233
+ * Create an SP bar component
234
+ *
235
+ * Creates a skill point bar that automatically displays the player's
236
+ * current SP relative to their maximum SP. The bar updates automatically
237
+ * as SP changes.
238
+ *
239
+ * @param style - Bar styling options
240
+ * @param text - Optional text to display above the bar. Can use placeholders:
241
+ * - {$current} - Current SP value
242
+ * - {$max} - Maximum SP value
243
+ * - {$percent} - Percentage value
244
+ * Set to null to hide text
245
+ * @returns Component definition for SP bar
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * // Simple SP bar
250
+ * Components.spBar();
251
+ *
252
+ * // SP bar with text
253
+ * Components.spBar({}, 'SP: {$current}/{$max}');
254
+ * ```
255
+ */
256
+ spBar(style?: BarComponentOptions, text?: string | null): ComponentDefinition {
257
+ return {
258
+ type: 'spBar',
259
+ style,
260
+ text: text ?? undefined
261
+ };
262
+ },
263
+
264
+ /**
265
+ * Create a custom bar component
266
+ *
267
+ * Creates a bar that displays a custom property value relative to a maximum.
268
+ * Useful for displaying custom resources like wood, mana, energy, etc.
269
+ *
270
+ * @param current - Property path for current value (e.g., 'wood', 'mana')
271
+ * @param max - Property path for maximum value (e.g., 'param.maxWood', 'param.maxMana')
272
+ * @param style - Bar styling options
273
+ * @param text - Optional text to display above the bar. Can use placeholders:
274
+ * - {$current} - Current value
275
+ * - {$max} - Maximum value
276
+ * - {$percent} - Percentage value
277
+ * Set to null to hide text
278
+ * @returns Component definition for custom bar
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * // Bar for custom property
283
+ * Components.bar('wood', 'param.maxWood');
284
+ *
285
+ * // Bar with text
286
+ * Components.bar('mana', 'param.maxMana', {}, 'Mana: {$current}/{$max}');
287
+ * ```
288
+ */
289
+ bar(current: string, max: string, style?: BarComponentOptions, text?: string | null): ComponentDefinition {
290
+ return {
291
+ type: 'bar',
292
+ current,
293
+ max,
294
+ style,
295
+ text: text ?? undefined
296
+ };
297
+ },
298
+
299
+ /**
300
+ * Create a shape component
301
+ *
302
+ * Creates a geometric shape that can be displayed above or below the player.
303
+ * Useful for visual indicators, backgrounds, or decorative elements.
304
+ *
305
+ * @param value - Shape configuration options
306
+ * @returns Component definition for shape
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * // Circle shape
311
+ * Components.shape({
312
+ * fill: '#ffffff',
313
+ * type: 'circle',
314
+ * radius: 10
315
+ * });
316
+ *
317
+ * // Rectangle shape
318
+ * Components.shape({
319
+ * fill: '#ff0000',
320
+ * type: 'rectangle',
321
+ * width: 32,
322
+ * height: 32
323
+ * });
324
+ *
325
+ * // Using parameters
326
+ * Components.shape({
327
+ * fill: '#ffffff',
328
+ * type: 'circle',
329
+ * radius: 'hp' // radius will be the same as hp value
330
+ * });
331
+ * ```
332
+ */
333
+ shape(value: ShapeComponentOptions): ComponentDefinition {
334
+ return {
335
+ type: 'shape',
336
+ value
337
+ };
338
+ },
339
+
340
+ /**
341
+ * Create an image component
342
+ *
343
+ * Displays an image from a URL or spritesheet identifier.
344
+ *
345
+ * @param value - Image source URL or spritesheet identifier
346
+ * @returns Component definition for image
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * Components.image('mygraphic.png');
351
+ * ```
352
+ */
353
+ image(value: string): ComponentDefinition {
354
+ return {
355
+ type: 'image',
356
+ value
357
+ };
358
+ },
359
+
360
+ /**
361
+ * Create a tile component
362
+ *
363
+ * Displays a tile from a tileset by ID.
364
+ *
365
+ * @param value - Tile ID in the tileset
366
+ * @returns Component definition for tile
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * Components.tile(3); // Use tile #3
371
+ * ```
372
+ */
373
+ tile(value: number | string): ComponentDefinition {
374
+ return {
375
+ type: 'tile',
376
+ value
377
+ };
378
+ }
379
+ };
380
+
@@ -2,13 +2,10 @@ import {
2
2
  arrayFlat,
3
3
  arrayUniq,
4
4
  Constructor,
5
+ PlayerCtor,
5
6
  RpgCommonPlayer,
6
7
  } from "@rpgjs/common";
7
8
 
8
- export interface IWithEffectManager {
9
- effects: any[];
10
- }
11
-
12
9
  export enum Effect {
13
10
  CAN_NOT_SKILL = 'CAN_NOT_SKILL',
14
11
  CAN_NOT_ITEM = 'CAN_NOT_ITEM',
@@ -19,23 +16,64 @@ export enum Effect {
19
16
  SUPER_GUARD = 'SUPER_GUARD'
20
17
  }
21
18
 
22
- export function WithEffectManager<TBase extends Constructor<RpgCommonPlayer>>(
23
- Base: TBase
24
- ) {
25
- return class extends Base implements IWithEffectManager {
19
+ /**
20
+ * Effect Manager Mixin
21
+ *
22
+ * Provides effect management capabilities to any class. This mixin handles
23
+ * player effects including restrictions, buffs, and debuffs. Effects can come
24
+ * from various sources like states, equipment, and temporary conditions.
25
+ *
26
+ * @param Base - The base class to extend with effect management
27
+ * @returns Extended class with effect management methods
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * class MyPlayer extends WithEffectManager(BasePlayer) {
32
+ * constructor() {
33
+ * super();
34
+ * // Effect system is automatically initialized
35
+ * }
36
+ * }
37
+ *
38
+ * const player = new MyPlayer();
39
+ * player.effects = [Effect.GUARD];
40
+ * console.log(player.hasEffect(Effect.GUARD)); // true
41
+ * ```
42
+ */
43
+ export function WithEffectManager<TBase extends PlayerCtor>(Base: TBase) {
44
+ return class extends Base {
26
45
  /**
46
+ * Check if the player has a specific effect
47
+ *
48
+ * Determines whether the player currently has the specified effect active.
49
+ * This includes effects from states, equipment, and temporary conditions.
50
+ * The effect system provides a flexible way to apply various gameplay
51
+ * restrictions and enhancements to the player.
52
+ *
53
+ * @param effect - The effect identifier to check for
54
+ * @returns true if the player has the effect, false otherwise
55
+ *
56
+ * @example
27
57
  * ```ts
28
58
  * import { Effect } from '@rpgjs/database'
29
59
  *
30
- * const bool = player.hasEffect(Effect.CAN_NOT_SKILL)
60
+ * // Check for skill restriction
61
+ * const cannotUseSkills = player.hasEffect(Effect.CAN_NOT_SKILL);
62
+ * if (cannotUseSkills) {
63
+ * console.log('Player cannot use skills right now');
64
+ * }
65
+ *
66
+ * // Check for guard effect
67
+ * const isGuarding = player.hasEffect(Effect.GUARD);
68
+ * if (isGuarding) {
69
+ * console.log('Player is in guard stance');
70
+ * }
71
+ *
72
+ * // Check for cost reduction
73
+ * const halfCost = player.hasEffect(Effect.HALF_SP_COST);
74
+ * const actualCost = skillCost / (halfCost ? 2 : 1);
31
75
  * ```
32
- *
33
- * @title Has Effect
34
- * @method player.hasEffect(effect)
35
- * @param {string} effect
36
- * @returns {boolean}
37
- * @memberof EffectManager
38
- * */
76
+ */
39
77
  hasEffect(effect: string): boolean {
40
78
  return this.effects.includes(effect);
41
79
  }
@@ -43,13 +81,31 @@ export function WithEffectManager<TBase extends Constructor<RpgCommonPlayer>>(
43
81
  /**
44
82
  * Retrieves a array of effects assigned to the player, state effects and effects of weapons and armors equipped with the player's own weapons.
45
83
  *
84
+ * Gets all currently active effects on the player from multiple sources:
85
+ * - Direct effects assigned to the player
86
+ * - Effects from active states (buffs/debuffs)
87
+ * - Effects from equipped weapons and armor
88
+ * The returned array contains unique effects without duplicates.
89
+ *
90
+ * @returns Array of all active effects on the player
91
+ *
92
+ * @example
46
93
  * ```ts
47
- * console.log(player.effects)
94
+ * // Get all active effects
95
+ * console.log(player.effects); // ['GUARD', 'HALF_SP_COST', ...]
96
+ *
97
+ * // Check multiple effects
98
+ * const effects = player.effects;
99
+ * const hasRestrictions = effects.some(effect =>
100
+ * effect.startsWith('CAN_NOT_')
101
+ * );
102
+ *
103
+ * // Count beneficial effects
104
+ * const beneficialEffects = effects.filter(effect =>
105
+ * ['GUARD', 'SUPER_GUARD', 'HALF_SP_COST'].includes(effect)
106
+ * );
48
107
  * ```
49
- * @title Get Effects
50
- * @prop {Array<Effect>} player.effects
51
- * @memberof EffectManager
52
- * */
108
+ */
53
109
  get effects(): any[] {
54
110
  const getEffects = (prop) => {
55
111
  return arrayFlat(this[prop]().map((el) => el.effects || []));
@@ -64,17 +120,44 @@ export function WithEffectManager<TBase extends Constructor<RpgCommonPlayer>>(
64
120
  /**
65
121
  * Assigns effects to the player. If you give a array, it does not change the effects of the player's states and armor/weapons equipped.
66
122
  *
123
+ * Sets the direct effects on the player. This only affects the player's own effects
124
+ * and does not modify effects from states or equipment. The total effects will be
125
+ * the combination of these direct effects plus any effects from states and equipment.
126
+ *
127
+ * @param val - Array of effect identifiers to assign to the player
128
+ *
129
+ * @example
67
130
  * ```ts
68
131
  * import { Effect } from '@rpgjs/database'
69
132
  *
70
- * player.effects = [Effect.CAN_NOT_SKILL]
133
+ * // Set direct player effects
134
+ * player.effects = [Effect.CAN_NOT_SKILL];
135
+ *
136
+ * // Add multiple effects
137
+ * player.effects = [
138
+ * Effect.GUARD,
139
+ * Effect.HALF_SP_COST,
140
+ * Effect.CAN_NOT_ITEM
141
+ * ];
142
+ *
143
+ * // Clear direct effects (equipment/state effects remain)
144
+ * player.effects = [];
145
+ *
146
+ * // Temporary effect application
147
+ * const originalEffects = player.effects;
148
+ * player.effects = [...originalEffects, Effect.SUPER_GUARD];
149
+ * // Later restore
150
+ * player.effects = originalEffects;
71
151
  * ```
72
- * @title Set Effects
73
- * @prop {Array<Effect>} player.effects
74
- * @memberof EffectManager
75
- * */
152
+ */
76
153
  set effects(val) {
77
154
  this._effects.set(val);
78
155
  }
79
- };
156
+ } as unknown as TBase;
80
157
  }
158
+
159
+ /**
160
+ * Type helper to extract the interface from the WithEffectManager mixin
161
+ * This provides the type without duplicating method signatures
162
+ */
163
+ export type IEffectManager = InstanceType<ReturnType<typeof WithEffectManager>>;