@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.
- package/dist/Player/BattleManager.d.ts +43 -31
- package/dist/Player/ClassManager.d.ts +23 -3
- package/dist/Player/EffectManager.d.ts +49 -3
- package/dist/Player/ElementManager.d.ts +76 -3
- package/dist/Player/ItemManager.d.ts +292 -4
- package/dist/Player/MoveManager.d.ts +145 -4
- package/dist/Player/Player.d.ts +135 -0
- package/dist/Player/SkillManager.d.ts +42 -3
- package/dist/Player/StateManager.d.ts +74 -3
- package/dist/Player/VariableManager.d.ts +47 -3
- package/dist/RpgServer.d.ts +228 -61
- package/dist/decorators/map.d.ts +89 -1
- package/dist/index.js +804 -1703
- package/dist/index.js.map +1 -1
- package/dist/module.d.ts +43 -1
- package/dist/rooms/map.d.ts +676 -12
- package/package.json +8 -8
- package/src/Player/BattleManager.ts +38 -55
- package/src/Player/ClassManager.ts +21 -71
- package/src/Player/EffectManager.ts +50 -96
- package/src/Player/ElementManager.ts +74 -152
- package/src/Player/ItemManager.ts +302 -359
- package/src/Player/MoveManager.ts +141 -438
- package/src/Player/Player.ts +217 -0
- package/src/Player/SkillManager.ts +44 -147
- package/src/Player/StateManager.ts +63 -259
- package/src/Player/VariableManager.ts +53 -150
- package/src/RpgServer.ts +237 -60
- package/src/decorators/map.ts +105 -1
- package/src/module.ts +81 -2
- package/src/rooms/map.ts +757 -23
package/dist/rooms/map.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { MockConnection, RoomOnJoin } from '@signe/room';
|
|
|
2
2
|
import { Hooks, RpgCommonMap, RpgShape, WorldMapsManager, WorldMapConfig } from '@rpgjs/common';
|
|
3
3
|
import { RpgPlayer, RpgEvent } from '../Player/Player';
|
|
4
4
|
import { BehaviorSubject } from 'rxjs';
|
|
5
|
+
import { MapOptions } from '../decorators/map';
|
|
5
6
|
/**
|
|
6
7
|
* Interface for input controls configuration
|
|
7
8
|
*
|
|
@@ -35,7 +36,9 @@ export interface EventHooks {
|
|
|
35
36
|
onInShape?: (zone: RpgShape, player: RpgPlayer) => void;
|
|
36
37
|
/** Called when a player exits a shape */
|
|
37
38
|
onOutShape?: (zone: RpgShape, player: RpgPlayer) => void;
|
|
39
|
+
/** Called when a player is detected entering a shape */
|
|
38
40
|
onDetectInShape?: (player: RpgPlayer, shape: RpgShape) => void;
|
|
41
|
+
/** Called when a player is detected exiting a shape */
|
|
39
42
|
onDetectOutShape?: (player: RpgPlayer, shape: RpgShape) => void;
|
|
40
43
|
}
|
|
41
44
|
/** Type for event class constructor */
|
|
@@ -56,12 +59,104 @@ export type EventPosOption = {
|
|
|
56
59
|
event: EventConstructor | (EventHooks & Record<string, any>);
|
|
57
60
|
};
|
|
58
61
|
export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoin {
|
|
62
|
+
/**
|
|
63
|
+
* Synchronized signal containing all players currently on the map
|
|
64
|
+
*
|
|
65
|
+
* This signal is automatically synchronized with clients using @signe/sync.
|
|
66
|
+
* Players are indexed by their unique ID.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* // Get all players
|
|
71
|
+
* const allPlayers = map.players();
|
|
72
|
+
*
|
|
73
|
+
* // Get a specific player
|
|
74
|
+
* const player = map.players()['player-id'];
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
59
77
|
players: import('@signe/reactive').WritableObjectSignal<{}>;
|
|
78
|
+
/**
|
|
79
|
+
* Synchronized signal containing all events (NPCs, objects) on the map
|
|
80
|
+
*
|
|
81
|
+
* This signal is automatically synchronized with clients using @signe/sync.
|
|
82
|
+
* Events are indexed by their unique ID.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // Get all events
|
|
87
|
+
* const allEvents = map.events();
|
|
88
|
+
*
|
|
89
|
+
* // Get a specific event
|
|
90
|
+
* const event = map.events()['event-id'];
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
60
93
|
events: import('@signe/reactive').WritableObjectSignal<{}>;
|
|
94
|
+
/**
|
|
95
|
+
* Signal containing the map's database of items, classes, and other game data
|
|
96
|
+
*
|
|
97
|
+
* This database can be dynamically populated using `addInDatabase()` and
|
|
98
|
+
* `removeInDatabase()` methods. It's used to store game entities like items,
|
|
99
|
+
* classes, skills, etc. that are specific to this map.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* // Add data to database
|
|
104
|
+
* map.addInDatabase('Potion', PotionClass);
|
|
105
|
+
*
|
|
106
|
+
* // Access database
|
|
107
|
+
* const potion = map.database()['Potion'];
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
61
110
|
database: import('@signe/reactive').WritableObjectSignal<{}>;
|
|
62
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Array of map configurations - can contain MapOptions objects or instances of map classes
|
|
113
|
+
*
|
|
114
|
+
* This array stores the configuration for this map and any related maps.
|
|
115
|
+
* It's populated when the map is loaded via `updateMap()`.
|
|
116
|
+
*/
|
|
117
|
+
maps: (MapOptions | any)[];
|
|
118
|
+
/**
|
|
119
|
+
* Array of sound IDs to play when players join the map
|
|
120
|
+
*
|
|
121
|
+
* These sounds are automatically played for each player when they join the map.
|
|
122
|
+
* Sounds must be defined on the client side.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* // Set sounds for the map
|
|
127
|
+
* map.sounds = ['background-music', 'ambient-forest'];
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
sounds: string[];
|
|
131
|
+
/**
|
|
132
|
+
* BehaviorSubject that completes when the map data is ready
|
|
133
|
+
*
|
|
134
|
+
* This subject is used to signal when the map has finished loading all its data.
|
|
135
|
+
* Players wait for this to complete before the map is fully initialized.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* // Wait for map data to be ready
|
|
140
|
+
* map.dataIsReady$.subscribe(() => {
|
|
141
|
+
* console.log('Map is ready!');
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
63
145
|
dataIsReady$: BehaviorSubject<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Global configuration object for the map
|
|
148
|
+
*
|
|
149
|
+
* This object contains configuration settings that apply to the entire map.
|
|
150
|
+
* It's populated from the map data when `updateMap()` is called.
|
|
151
|
+
*/
|
|
64
152
|
globalConfig: any;
|
|
153
|
+
/**
|
|
154
|
+
* Damage formulas configuration for the map
|
|
155
|
+
*
|
|
156
|
+
* Contains formulas for calculating damage from skills, physical attacks,
|
|
157
|
+
* critical hits, and element coefficients. Default formulas are merged
|
|
158
|
+
* with custom formulas when the map is loaded.
|
|
159
|
+
*/
|
|
65
160
|
damageFormulas: any;
|
|
66
161
|
/** Internal: Map of shapes by name */
|
|
67
162
|
private _shapes;
|
|
@@ -108,32 +203,301 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
108
203
|
* ```
|
|
109
204
|
*/
|
|
110
205
|
private setupCollisionDetection;
|
|
206
|
+
/**
|
|
207
|
+
* Intercepts and modifies packets before they are sent to clients
|
|
208
|
+
*
|
|
209
|
+
* This method is automatically called by @signe/room for each packet sent to clients.
|
|
210
|
+
* It adds timestamp and acknowledgment information to sync packets for client-side
|
|
211
|
+
* prediction reconciliation. This helps with network synchronization and reduces
|
|
212
|
+
* perceived latency.
|
|
213
|
+
*
|
|
214
|
+
* ## Architecture
|
|
215
|
+
*
|
|
216
|
+
* Adds metadata to packets:
|
|
217
|
+
* - `timestamp`: Current server time for client-side prediction
|
|
218
|
+
* - `ack`: Acknowledgment info with last processed frame and authoritative position
|
|
219
|
+
*
|
|
220
|
+
* @param player - The player receiving the packet
|
|
221
|
+
* @param packet - The packet data to intercept
|
|
222
|
+
* @param conn - The connection object
|
|
223
|
+
* @returns Modified packet with timestamp and ack info, or null if player is invalid
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* // This method is called automatically by the framework
|
|
228
|
+
* // You typically don't call it directly
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
111
231
|
interceptorPacket(player: RpgPlayer, packet: any, conn: MockConnection): any;
|
|
232
|
+
/**
|
|
233
|
+
* Called when a player joins the map
|
|
234
|
+
*
|
|
235
|
+
* This method is automatically called by @signe/room when a player connects to the map.
|
|
236
|
+
* It initializes the player's connection, sets up the map context, and waits for
|
|
237
|
+
* the map data to be ready before playing sounds and triggering hooks.
|
|
238
|
+
*
|
|
239
|
+
* ## Architecture
|
|
240
|
+
*
|
|
241
|
+
* 1. Sets player's map reference and context
|
|
242
|
+
* 2. Initializes the player
|
|
243
|
+
* 3. Waits for map data to be ready
|
|
244
|
+
* 4. Plays map sounds for the player
|
|
245
|
+
* 5. Triggers `server-player-onJoinMap` hook
|
|
246
|
+
*
|
|
247
|
+
* @param player - The player joining the map
|
|
248
|
+
* @param conn - The connection object for the player
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* // This method is called automatically by the framework
|
|
253
|
+
* // You can listen to the hook to perform custom logic
|
|
254
|
+
* server.addHook('server-player-onJoinMap', (player, map) => {
|
|
255
|
+
* console.log(`Player ${player.id} joined map ${map.id}`);
|
|
256
|
+
* });
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
112
259
|
onJoin(player: RpgPlayer, conn: MockConnection): void;
|
|
113
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Called when a player leaves the map
|
|
262
|
+
*
|
|
263
|
+
* This method is automatically called by @signe/room when a player disconnects from the map.
|
|
264
|
+
* It cleans up the player's pending inputs and triggers the appropriate hooks.
|
|
265
|
+
*
|
|
266
|
+
* ## Architecture
|
|
267
|
+
*
|
|
268
|
+
* 1. Triggers `server-player-onLeaveMap` hook
|
|
269
|
+
* 2. Clears pending inputs to prevent processing after disconnection
|
|
270
|
+
*
|
|
271
|
+
* @param player - The player leaving the map
|
|
272
|
+
* @param conn - The connection object for the player
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* // This method is called automatically by the framework
|
|
277
|
+
* // You can listen to the hook to perform custom cleanup
|
|
278
|
+
* server.addHook('server-player-onLeaveMap', (player, map) => {
|
|
279
|
+
* console.log(`Player ${player.id} left map ${map.id}`);
|
|
280
|
+
* });
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
onLeave(player: RpgPlayer, conn: MockConnection): Promise<void>;
|
|
284
|
+
/**
|
|
285
|
+
* Get the hooks system for this map
|
|
286
|
+
*
|
|
287
|
+
* Returns the dependency-injected Hooks instance that allows you to trigger
|
|
288
|
+
* and listen to various game events.
|
|
289
|
+
*
|
|
290
|
+
* @returns The Hooks instance for this map
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```ts
|
|
294
|
+
* // Trigger a custom hook
|
|
295
|
+
* map.hooks.callHooks('custom-event', data).subscribe();
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
114
298
|
get hooks(): Hooks;
|
|
299
|
+
/**
|
|
300
|
+
* Get the width of the map in pixels
|
|
301
|
+
*
|
|
302
|
+
* @returns The width of the map in pixels, or 0 if not loaded
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* const width = map.widthPx;
|
|
307
|
+
* console.log(`Map width: ${width}px`);
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
115
310
|
get widthPx(): number;
|
|
311
|
+
/**
|
|
312
|
+
* Get the height of the map in pixels
|
|
313
|
+
*
|
|
314
|
+
* @returns The height of the map in pixels, or 0 if not loaded
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* const height = map.heightPx;
|
|
319
|
+
* console.log(`Map height: ${height}px`);
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
116
322
|
get heightPx(): number;
|
|
323
|
+
/**
|
|
324
|
+
* Get the unique identifier of the map
|
|
325
|
+
*
|
|
326
|
+
* @returns The map ID, or empty string if not loaded
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* const mapId = map.id;
|
|
331
|
+
* console.log(`Current map: ${mapId}`);
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
117
334
|
get id(): string;
|
|
335
|
+
/**
|
|
336
|
+
* Get the X position of this map in the world coordinate system
|
|
337
|
+
*
|
|
338
|
+
* This is used when maps are part of a larger world map. The world position
|
|
339
|
+
* indicates where this map is located relative to other maps.
|
|
340
|
+
*
|
|
341
|
+
* @returns The X position in world coordinates, or 0 if not in a world
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```ts
|
|
345
|
+
* const worldX = map.worldX;
|
|
346
|
+
* console.log(`Map is at world position (${worldX}, ${map.worldY})`);
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
118
349
|
get worldX(): number;
|
|
350
|
+
/**
|
|
351
|
+
* Get the Y position of this map in the world coordinate system
|
|
352
|
+
*
|
|
353
|
+
* This is used when maps are part of a larger world map. The world position
|
|
354
|
+
* indicates where this map is located relative to other maps.
|
|
355
|
+
*
|
|
356
|
+
* @returns The Y position in world coordinates, or 0 if not in a world
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* const worldY = map.worldY;
|
|
361
|
+
* console.log(`Map is at world position (${map.worldX}, ${worldY})`);
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
119
364
|
get worldY(): number;
|
|
365
|
+
/**
|
|
366
|
+
* Handle GUI interaction from a player
|
|
367
|
+
*
|
|
368
|
+
* This method is called when a player interacts with a GUI element.
|
|
369
|
+
* It synchronizes the player's changes to ensure the client state is up to date.
|
|
370
|
+
*
|
|
371
|
+
* @param player - The player performing the interaction
|
|
372
|
+
* @param value - The interaction data from the client
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```ts
|
|
376
|
+
* // This method is called automatically when a player interacts with a GUI
|
|
377
|
+
* // The interaction data is sent from the client
|
|
378
|
+
* ```
|
|
379
|
+
*/
|
|
120
380
|
guiInteraction(player: RpgPlayer, value: any): void;
|
|
381
|
+
/**
|
|
382
|
+
* Handle GUI exit from a player
|
|
383
|
+
*
|
|
384
|
+
* This method is called when a player closes or exits a GUI.
|
|
385
|
+
* It removes the GUI from the player's active GUIs.
|
|
386
|
+
*
|
|
387
|
+
* @param player - The player exiting the GUI
|
|
388
|
+
* @param guiId - The ID of the GUI being exited
|
|
389
|
+
* @param data - Optional data associated with the GUI exit
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```ts
|
|
393
|
+
* // This method is called automatically when a player closes a GUI
|
|
394
|
+
* // The GUI is removed from the player's active GUIs
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
121
397
|
guiExit(player: RpgPlayer, { guiId, data }: {
|
|
122
398
|
guiId: any;
|
|
123
399
|
data: any;
|
|
124
400
|
}): void;
|
|
401
|
+
/**
|
|
402
|
+
* Handle action input from a player
|
|
403
|
+
*
|
|
404
|
+
* This method is called when a player performs an action (like pressing a button).
|
|
405
|
+
* It checks for collisions with events and triggers the appropriate hooks.
|
|
406
|
+
*
|
|
407
|
+
* ## Architecture
|
|
408
|
+
*
|
|
409
|
+
* 1. Gets all entities colliding with the player
|
|
410
|
+
* 2. Triggers `onAction` hook on colliding events
|
|
411
|
+
* 3. Triggers `onInput` hook on the player
|
|
412
|
+
*
|
|
413
|
+
* @param player - The player performing the action
|
|
414
|
+
* @param action - The action data (button pressed, etc.)
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```ts
|
|
418
|
+
* // This method is called automatically when a player presses an action button
|
|
419
|
+
* // Events near the player will have their onAction hook triggered
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
125
422
|
onAction(player: RpgPlayer, action: any): void;
|
|
423
|
+
/**
|
|
424
|
+
* Handle movement input from a player
|
|
425
|
+
*
|
|
426
|
+
* This method is called when a player sends movement input from the client.
|
|
427
|
+
* It queues the input for processing by the game loop. Inputs are processed
|
|
428
|
+
* with frame numbers to ensure proper ordering and client-side prediction.
|
|
429
|
+
*
|
|
430
|
+
* ## Architecture
|
|
431
|
+
*
|
|
432
|
+
* - Inputs are queued in `player.pendingInputs`
|
|
433
|
+
* - Duplicate frames are skipped to prevent processing the same input twice
|
|
434
|
+
* - Inputs are processed asynchronously by the game loop
|
|
435
|
+
*
|
|
436
|
+
* @param player - The player sending the movement input
|
|
437
|
+
* @param input - The input data containing frame number, input direction, and timestamp
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```ts
|
|
441
|
+
* // This method is called automatically when a player moves
|
|
442
|
+
* // The input is queued and processed by processInput()
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
126
445
|
onInput(player: RpgPlayer, input: any): Promise<void>;
|
|
446
|
+
/**
|
|
447
|
+
* Update the map configuration and data
|
|
448
|
+
*
|
|
449
|
+
* This endpoint receives map data from the client and initializes the map.
|
|
450
|
+
* It loads the map configuration, damage formulas, events, and physics.
|
|
451
|
+
*
|
|
452
|
+
* ## Architecture
|
|
453
|
+
*
|
|
454
|
+
* 1. Validates the request body using MapUpdateSchema
|
|
455
|
+
* 2. Updates map data, global config, and damage formulas
|
|
456
|
+
* 3. Merges events and sounds from map configuration
|
|
457
|
+
* 4. Triggers hooks for map loading
|
|
458
|
+
* 5. Loads physics engine
|
|
459
|
+
* 6. Creates all events on the map
|
|
460
|
+
* 7. Completes the dataIsReady$ subject
|
|
461
|
+
*
|
|
462
|
+
* @param request - HTTP request containing map data
|
|
463
|
+
* @returns Promise that resolves when the map is fully loaded
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```ts
|
|
467
|
+
* // This endpoint is called automatically when a map is loaded
|
|
468
|
+
* // POST /map/update
|
|
469
|
+
* // Body: { id: string, width: number, height: number, config?: any, damageFormulas?: any }
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
127
472
|
updateMap(request: Request): Promise<void>;
|
|
128
473
|
/**
|
|
129
474
|
* Update (or create) a world configuration and propagate to all maps in that world
|
|
130
475
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
476
|
+
* This endpoint receives world map configuration data (typically from Tiled world import)
|
|
477
|
+
* and creates or updates the world manager. The world ID is extracted from the URL path.
|
|
478
|
+
*
|
|
479
|
+
* ## Architecture
|
|
480
|
+
*
|
|
481
|
+
* 1. Extracts world ID from URL path parameter
|
|
482
|
+
* 2. Normalizes input to array of WorldMapConfig
|
|
483
|
+
* 3. Ensures all required map properties are present (width, height, tile sizes)
|
|
484
|
+
* 4. Creates or updates the world manager
|
|
133
485
|
*
|
|
134
486
|
* Expected payload examples:
|
|
135
|
-
* - { id: string, maps: WorldMapConfig[] }
|
|
136
|
-
* - WorldMapConfig[]
|
|
487
|
+
* - `{ id: string, maps: WorldMapConfig[] }`
|
|
488
|
+
* - `WorldMapConfig[]`
|
|
489
|
+
*
|
|
490
|
+
* @param request - HTTP request containing world configuration
|
|
491
|
+
* @returns Promise resolving to `{ ok: true }` when complete
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```ts
|
|
495
|
+
* // POST /world/my-world/update
|
|
496
|
+
* // Body: [{ id: 'map1', worldX: 0, worldY: 0, width: 800, height: 600 }]
|
|
497
|
+
*
|
|
498
|
+
* // Or with nested structure
|
|
499
|
+
* // Body: { id: 'my-world', maps: [{ id: 'map1', ... }] }
|
|
500
|
+
* ```
|
|
137
501
|
*/
|
|
138
502
|
updateWorld(request: Request): Promise<any>;
|
|
139
503
|
/**
|
|
@@ -176,17 +540,85 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
176
540
|
player: RpgPlayer;
|
|
177
541
|
inputs: string[];
|
|
178
542
|
}>;
|
|
543
|
+
/**
|
|
544
|
+
* Main game loop that processes player inputs
|
|
545
|
+
*
|
|
546
|
+
* This private method runs continuously every 50ms to process pending inputs
|
|
547
|
+
* for all players on the map. It ensures inputs are processed in order and
|
|
548
|
+
* prevents concurrent processing for the same player.
|
|
549
|
+
*
|
|
550
|
+
* ## Architecture
|
|
551
|
+
*
|
|
552
|
+
* - Runs every 50ms for responsive input processing
|
|
553
|
+
* - Processes inputs for each player with pending inputs
|
|
554
|
+
* - Uses a flag to prevent concurrent processing for the same player
|
|
555
|
+
* - Calls `processInput()` to handle anti-cheat validation and movement
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```ts
|
|
559
|
+
* // This method is called automatically in the constructor
|
|
560
|
+
* // You typically don't call it directly
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
179
563
|
private loop;
|
|
180
564
|
/**
|
|
181
|
-
* Get a world manager by id
|
|
565
|
+
* Get a world manager by id
|
|
566
|
+
*
|
|
567
|
+
* Returns the world maps manager for the given world ID. Currently, only
|
|
568
|
+
* one world manager is supported per map instance.
|
|
569
|
+
*
|
|
570
|
+
* @param id - The world ID (currently unused, returns the single manager)
|
|
571
|
+
* @returns The WorldMapsManager instance, or null if not initialized
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```ts
|
|
575
|
+
* const worldManager = map.getWorldMaps('my-world');
|
|
576
|
+
* if (worldManager) {
|
|
577
|
+
* const mapInfo = worldManager.getMapInfo('map1');
|
|
578
|
+
* }
|
|
579
|
+
* ```
|
|
182
580
|
*/
|
|
183
581
|
getWorldMaps(id: string): WorldMapsManager | null;
|
|
184
582
|
/**
|
|
185
583
|
* Delete a world manager by id
|
|
584
|
+
*
|
|
585
|
+
* Removes the world maps manager from this map instance. Currently, only
|
|
586
|
+
* one world manager is supported, so this clears the single manager.
|
|
587
|
+
*
|
|
588
|
+
* @param id - The world ID (currently unused)
|
|
589
|
+
* @returns true if the manager was deleted, false if it didn't exist
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* ```ts
|
|
593
|
+
* const deleted = map.deleteWorldMaps('my-world');
|
|
594
|
+
* if (deleted) {
|
|
595
|
+
* console.log('World manager removed');
|
|
596
|
+
* }
|
|
597
|
+
* ```
|
|
186
598
|
*/
|
|
187
599
|
deleteWorldMaps(id: string): boolean;
|
|
188
600
|
/**
|
|
189
601
|
* Create a world manager dynamically
|
|
602
|
+
*
|
|
603
|
+
* Creates a new WorldMapsManager instance and configures it with the provided
|
|
604
|
+
* map configurations. This is used when loading world data from Tiled or
|
|
605
|
+
* other map editors.
|
|
606
|
+
*
|
|
607
|
+
* @param world - World configuration object
|
|
608
|
+
* @param world.id - Optional world identifier
|
|
609
|
+
* @param world.maps - Array of map configurations for the world
|
|
610
|
+
* @returns The newly created WorldMapsManager instance
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* const manager = map.createDynamicWorldMaps({
|
|
615
|
+
* id: 'my-world',
|
|
616
|
+
* maps: [
|
|
617
|
+
* { id: 'map1', worldX: 0, worldY: 0, width: 800, height: 600 },
|
|
618
|
+
* { id: 'map2', worldX: 800, worldY: 0, width: 800, height: 600 }
|
|
619
|
+
* ]
|
|
620
|
+
* });
|
|
621
|
+
* ```
|
|
190
622
|
*/
|
|
191
623
|
createDynamicWorldMaps(world: {
|
|
192
624
|
id?: string;
|
|
@@ -194,6 +626,22 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
194
626
|
}): WorldMapsManager;
|
|
195
627
|
/**
|
|
196
628
|
* Update world maps by id. Auto-create when missing.
|
|
629
|
+
*
|
|
630
|
+
* Updates the world maps configuration. If the world manager doesn't exist,
|
|
631
|
+
* it is automatically created. This is useful for dynamically loading world
|
|
632
|
+
* data or updating map positions.
|
|
633
|
+
*
|
|
634
|
+
* @param id - The world ID
|
|
635
|
+
* @param maps - Array of map configurations to update
|
|
636
|
+
* @returns Promise that resolves when the update is complete
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* ```ts
|
|
640
|
+
* await map.updateWorldMaps('my-world', [
|
|
641
|
+
* { id: 'map1', worldX: 0, worldY: 0, width: 800, height: 600 },
|
|
642
|
+
* { id: 'map2', worldX: 800, worldY: 0, width: 800, height: 600 }
|
|
643
|
+
* ]);
|
|
644
|
+
* ```
|
|
197
645
|
*/
|
|
198
646
|
updateWorldMaps(id: string, maps: WorldMapConfig[]): Promise<void>;
|
|
199
647
|
/**
|
|
@@ -286,12 +734,147 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
286
734
|
* });
|
|
287
735
|
*/
|
|
288
736
|
createDynamicEvent(eventObj: EventPosOption): Promise<void>;
|
|
737
|
+
/**
|
|
738
|
+
* Get an event by its ID
|
|
739
|
+
*
|
|
740
|
+
* Returns the event with the specified ID, or undefined if not found.
|
|
741
|
+
* The return type can be narrowed using TypeScript generics.
|
|
742
|
+
*
|
|
743
|
+
* @param eventId - The unique identifier of the event
|
|
744
|
+
* @returns The event instance, or undefined if not found
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* // Get any event
|
|
749
|
+
* const event = map.getEvent('npc-1');
|
|
750
|
+
*
|
|
751
|
+
* // Get event with type narrowing
|
|
752
|
+
* const npc = map.getEvent<MyNPC>('npc-1');
|
|
753
|
+
* if (npc) {
|
|
754
|
+
* npc.speak('Hello!');
|
|
755
|
+
* }
|
|
756
|
+
* ```
|
|
757
|
+
*/
|
|
289
758
|
getEvent<T extends RpgPlayer>(eventId: string): T | undefined;
|
|
759
|
+
/**
|
|
760
|
+
* Get a player by their ID
|
|
761
|
+
*
|
|
762
|
+
* Returns the player with the specified ID, or undefined if not found.
|
|
763
|
+
*
|
|
764
|
+
* @param playerId - The unique identifier of the player
|
|
765
|
+
* @returns The player instance, or undefined if not found
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* ```ts
|
|
769
|
+
* const player = map.getPlayer('player-123');
|
|
770
|
+
* if (player) {
|
|
771
|
+
* console.log(`Player ${player.name} is on the map`);
|
|
772
|
+
* }
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
290
775
|
getPlayer(playerId: string): RpgPlayer | undefined;
|
|
776
|
+
/**
|
|
777
|
+
* Get all players currently on the map
|
|
778
|
+
*
|
|
779
|
+
* Returns an array of all players that are currently connected to this map.
|
|
780
|
+
*
|
|
781
|
+
* @returns Array of all RpgPlayer instances on the map
|
|
782
|
+
*
|
|
783
|
+
* @example
|
|
784
|
+
* ```ts
|
|
785
|
+
* const players = map.getPlayers();
|
|
786
|
+
* console.log(`There are ${players.length} players on the map`);
|
|
787
|
+
*
|
|
788
|
+
* players.forEach(player => {
|
|
789
|
+
* console.log(`- ${player.name}`);
|
|
790
|
+
* });
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
291
793
|
getPlayers(): RpgPlayer[];
|
|
794
|
+
/**
|
|
795
|
+
* Get all events on the map
|
|
796
|
+
*
|
|
797
|
+
* Returns an array of all events (NPCs, objects, etc.) that are currently
|
|
798
|
+
* on this map.
|
|
799
|
+
*
|
|
800
|
+
* @returns Array of all RpgEvent instances on the map
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```ts
|
|
804
|
+
* const events = map.getEvents();
|
|
805
|
+
* console.log(`There are ${events.length} events on the map`);
|
|
806
|
+
*
|
|
807
|
+
* events.forEach(event => {
|
|
808
|
+
* console.log(`- ${event.name} at (${event.x}, ${event.y})`);
|
|
809
|
+
* });
|
|
810
|
+
* ```
|
|
811
|
+
*/
|
|
292
812
|
getEvents(): RpgEvent[];
|
|
813
|
+
/**
|
|
814
|
+
* Get the first event that matches a condition
|
|
815
|
+
*
|
|
816
|
+
* Searches through all events on the map and returns the first one that
|
|
817
|
+
* matches the provided callback function.
|
|
818
|
+
*
|
|
819
|
+
* @param cb - Callback function that returns true for the desired event
|
|
820
|
+
* @returns The first matching event, or undefined if none found
|
|
821
|
+
*
|
|
822
|
+
* @example
|
|
823
|
+
* ```ts
|
|
824
|
+
* // Find an event by name
|
|
825
|
+
* const npc = map.getEventBy(event => event.name === 'Merchant');
|
|
826
|
+
*
|
|
827
|
+
* // Find an event at a specific position
|
|
828
|
+
* const chest = map.getEventBy(event =>
|
|
829
|
+
* event.x === 100 && event.y === 200
|
|
830
|
+
* );
|
|
831
|
+
* ```
|
|
832
|
+
*/
|
|
293
833
|
getEventBy(cb: (event: RpgEvent) => boolean): RpgEvent | undefined;
|
|
834
|
+
/**
|
|
835
|
+
* Get all events that match a condition
|
|
836
|
+
*
|
|
837
|
+
* Searches through all events on the map and returns all events that
|
|
838
|
+
* match the provided callback function.
|
|
839
|
+
*
|
|
840
|
+
* @param cb - Callback function that returns true for desired events
|
|
841
|
+
* @returns Array of all matching events
|
|
842
|
+
*
|
|
843
|
+
* @example
|
|
844
|
+
* ```ts
|
|
845
|
+
* // Find all NPCs
|
|
846
|
+
* const npcs = map.getEventsBy(event => event.name.startsWith('NPC-'));
|
|
847
|
+
*
|
|
848
|
+
* // Find all events in a specific area
|
|
849
|
+
* const nearbyEvents = map.getEventsBy(event =>
|
|
850
|
+
* event.x >= 0 && event.x <= 100 &&
|
|
851
|
+
* event.y >= 0 && event.y <= 100
|
|
852
|
+
* );
|
|
853
|
+
* ```
|
|
854
|
+
*/
|
|
294
855
|
getEventsBy(cb: (event: RpgEvent) => boolean): RpgEvent[];
|
|
856
|
+
/**
|
|
857
|
+
* Remove an event from the map
|
|
858
|
+
*
|
|
859
|
+
* Removes the event with the specified ID from the map. The event will
|
|
860
|
+
* be removed from the synchronized events signal, causing it to disappear
|
|
861
|
+
* on all clients.
|
|
862
|
+
*
|
|
863
|
+
* @param eventId - The unique identifier of the event to remove
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```ts
|
|
867
|
+
* // Remove an event
|
|
868
|
+
* map.removeEvent('npc-1');
|
|
869
|
+
*
|
|
870
|
+
* // Remove event after interaction
|
|
871
|
+
* const chest = map.getEvent('chest-1');
|
|
872
|
+
* if (chest) {
|
|
873
|
+
* // ... do something with chest ...
|
|
874
|
+
* map.removeEvent('chest-1');
|
|
875
|
+
* }
|
|
876
|
+
* ```
|
|
877
|
+
*/
|
|
295
878
|
removeEvent(eventId: string): void;
|
|
296
879
|
/**
|
|
297
880
|
* Display a component animation at a specific position on the map
|
|
@@ -363,16 +946,44 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
363
946
|
x: number;
|
|
364
947
|
y: number;
|
|
365
948
|
}, graphic: string, animationName?: string): void;
|
|
366
|
-
/**
|
|
367
|
-
* Set the sync schema for the map
|
|
368
|
-
* @param schema - The schema to set
|
|
369
|
-
*/
|
|
370
949
|
/**
|
|
371
950
|
* Configure runtime synchronized properties on the map
|
|
372
951
|
*
|
|
373
|
-
*
|
|
952
|
+
* This method allows you to dynamically add synchronized properties to the map
|
|
953
|
+
* that will be automatically synced with clients. The schema follows the same
|
|
954
|
+
* structure as module properties with `$initial`, `$syncWithClient`, and `$permanent` options.
|
|
955
|
+
*
|
|
956
|
+
* ## Architecture
|
|
957
|
+
*
|
|
374
958
|
* - Reads a schema object shaped like module props
|
|
375
959
|
* - Creates typed sync signals with @signe/sync
|
|
960
|
+
* - Properties are accessible as `map.propertyName`
|
|
961
|
+
*
|
|
962
|
+
* @param schema - Schema object defining the properties to sync
|
|
963
|
+
* @param schema[key].$initial - Initial value for the property
|
|
964
|
+
* @param schema[key].$syncWithClient - Whether to sync this property to clients
|
|
965
|
+
* @param schema[key].$permanent - Whether to persist this property
|
|
966
|
+
*
|
|
967
|
+
* @example
|
|
968
|
+
* ```ts
|
|
969
|
+
* // Add synchronized properties to the map
|
|
970
|
+
* map.setSync({
|
|
971
|
+
* weather: {
|
|
972
|
+
* $initial: 'sunny',
|
|
973
|
+
* $syncWithClient: true,
|
|
974
|
+
* $permanent: false
|
|
975
|
+
* },
|
|
976
|
+
* timeOfDay: {
|
|
977
|
+
* $initial: 12,
|
|
978
|
+
* $syncWithClient: true,
|
|
979
|
+
* $permanent: false
|
|
980
|
+
* }
|
|
981
|
+
* });
|
|
982
|
+
*
|
|
983
|
+
* // Use the properties
|
|
984
|
+
* map.weather.set('rainy');
|
|
985
|
+
* const currentWeather = map.weather();
|
|
986
|
+
* ```
|
|
376
987
|
*/
|
|
377
988
|
setSync(schema: Record<string, any>): void;
|
|
378
989
|
/**
|
|
@@ -580,6 +1191,59 @@ export declare class RpgMap extends RpgCommonMap<RpgPlayer> implements RoomOnJoi
|
|
|
580
1191
|
* ```
|
|
581
1192
|
*/
|
|
582
1193
|
stopSound(soundId: string): void;
|
|
1194
|
+
/**
|
|
1195
|
+
* Shake the map for all players
|
|
1196
|
+
*
|
|
1197
|
+
* This method triggers a shake animation on the map for all players currently on the map.
|
|
1198
|
+
* The shake effect creates a visual feedback that can be used for earthquakes, explosions,
|
|
1199
|
+
* impacts, or any dramatic event that should affect the entire map visually.
|
|
1200
|
+
*
|
|
1201
|
+
* ## Architecture
|
|
1202
|
+
*
|
|
1203
|
+
* Broadcasts a shake event to all clients connected to the map. Each client receives
|
|
1204
|
+
* the shake configuration and triggers the shake animation on the map container using
|
|
1205
|
+
* Canvas Engine's shake directive.
|
|
1206
|
+
*
|
|
1207
|
+
* @param options - Optional shake configuration
|
|
1208
|
+
* @param options.intensity - Shake intensity in pixels (default: 10)
|
|
1209
|
+
* @param options.duration - Duration of the shake animation in milliseconds (default: 500)
|
|
1210
|
+
* @param options.frequency - Number of shake oscillations during the animation (default: 10)
|
|
1211
|
+
* @param options.direction - Direction of the shake - 'x', 'y', or 'both' (default: 'both')
|
|
1212
|
+
*
|
|
1213
|
+
* @example
|
|
1214
|
+
* ```ts
|
|
1215
|
+
* // Basic shake with default settings
|
|
1216
|
+
* map.shakeMap();
|
|
1217
|
+
*
|
|
1218
|
+
* // Intense earthquake effect
|
|
1219
|
+
* map.shakeMap({
|
|
1220
|
+
* intensity: 25,
|
|
1221
|
+
* duration: 1000,
|
|
1222
|
+
* frequency: 15,
|
|
1223
|
+
* direction: 'both'
|
|
1224
|
+
* });
|
|
1225
|
+
*
|
|
1226
|
+
* // Horizontal shake for side impact
|
|
1227
|
+
* map.shakeMap({
|
|
1228
|
+
* intensity: 15,
|
|
1229
|
+
* duration: 400,
|
|
1230
|
+
* direction: 'x'
|
|
1231
|
+
* });
|
|
1232
|
+
*
|
|
1233
|
+
* // Vertical shake for ground impact
|
|
1234
|
+
* map.shakeMap({
|
|
1235
|
+
* intensity: 20,
|
|
1236
|
+
* duration: 600,
|
|
1237
|
+
* direction: 'y'
|
|
1238
|
+
* });
|
|
1239
|
+
* ```
|
|
1240
|
+
*/
|
|
1241
|
+
shakeMap(options?: {
|
|
1242
|
+
intensity?: number;
|
|
1243
|
+
duration?: number;
|
|
1244
|
+
frequency?: number;
|
|
1245
|
+
direction?: 'x' | 'y' | 'both';
|
|
1246
|
+
}): void;
|
|
583
1247
|
}
|
|
584
1248
|
export interface RpgMap {
|
|
585
1249
|
$send: (conn: MockConnection, data: any) => void;
|