@rpgjs/server 5.0.0-alpha.25 → 5.0.0-alpha.27

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.
@@ -3,6 +3,51 @@ import { RpgPlayer } from './Player';
3
3
  type CallbackTileMove = (player: RpgPlayer, map: any) => Direction[];
4
4
  type CallbackTurnMove = (player: RpgPlayer, map: any) => string;
5
5
  type Routes = (string | Promise<any> | Direction | Direction[] | Function)[];
6
+ /**
7
+ * Options for moveRoutes method
8
+ */
9
+ export interface MoveRoutesOptions {
10
+ /**
11
+ * Callback function called when the player gets stuck (cannot move towards target)
12
+ *
13
+ * This callback is triggered when the player is trying to move but cannot make progress
14
+ * towards the target position, typically due to obstacles or collisions.
15
+ *
16
+ * @param player - The player instance that is stuck
17
+ * @param target - The target position the player was trying to reach
18
+ * @param currentPosition - The current position of the player
19
+ * @returns If true, the route will continue; if false, the route will be cancelled
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * await player.moveRoutes([Move.right()], {
24
+ * onStuck: (player, target, currentPos) => {
25
+ * console.log('Player is stuck!');
26
+ * return false; // Cancel the route
27
+ * }
28
+ * });
29
+ * ```
30
+ */
31
+ onStuck?: (player: RpgPlayer, target: {
32
+ x: number;
33
+ y: number;
34
+ }, currentPosition: {
35
+ x: number;
36
+ y: number;
37
+ }) => boolean | void;
38
+ /**
39
+ * Time in milliseconds to wait before considering the player stuck (default: 500ms)
40
+ *
41
+ * The player must be unable to make progress for this duration before onStuck is called.
42
+ */
43
+ stuckTimeout?: number;
44
+ /**
45
+ * Minimum distance change in pixels to consider movement progress (default: 1 pixel)
46
+ *
47
+ * If the player moves less than this distance over the stuckTimeout period, they are considered stuck.
48
+ */
49
+ stuckThreshold?: number;
50
+ }
6
51
  export declare enum Frequency {
7
52
  Lowest = 600,
8
53
  Lower = 400,
@@ -49,6 +94,21 @@ export declare enum Speed {
49
94
  * @memberof Move
50
95
  * */
51
96
  declare class MoveList {
97
+ private static perlinNoise;
98
+ private static randomCounter;
99
+ private static callCounter;
100
+ /**
101
+ * Gets a random direction index (0-3) using a hybrid approach for balanced randomness
102
+ *
103
+ * Uses a combination of hash-based pseudo-randomness and Perlin noise to ensure
104
+ * fair distribution of directions while maintaining smooth, natural-looking movement patterns.
105
+ * The hash function guarantees uniform distribution, while Perlin noise adds spatial/temporal coherence.
106
+ *
107
+ * @param player - Optional player instance for coordinate-based noise
108
+ * @param index - Optional index for array-based calls to ensure variation
109
+ * @returns Direction index (0-3) corresponding to Right, Left, Up, Down
110
+ */
111
+ private getRandomDirectionIndex;
52
112
  repeatMove(direction: Direction, repeat: number): Direction[];
53
113
  private repeatTileMove;
54
114
  right(repeat?: number): Direction[];
@@ -283,9 +343,10 @@ export interface IMoveManager {
283
343
  * Give an itinerary to follow using movement strategies
284
344
  *
285
345
  * @param routes - Array of movement instructions to execute
346
+ * @param options - Optional configuration including onStuck callback
286
347
  * @returns Promise that resolves when all routes are completed
287
348
  */
288
- moveRoutes(routes: Routes): Promise<boolean>;
349
+ moveRoutes(routes: Routes, options?: MoveRoutesOptions): Promise<boolean>;
289
350
  /**
290
351
  * Give a path that repeats itself in a loop to a character
291
352
  *
@@ -1,4 +1,5 @@
1
1
  import { Hooks, RpgCommonPlayer, Constructor, Direction, AttachShapeOptions, RpgShape } from '../../../common/src';
2
+ import { Vector2 } from '../../../physic/src';
2
3
  import { IComponentManager } from './ComponentManager';
3
4
  import { RpgMap } from '../rooms/map';
4
5
  import { Context } from '@signe/di';
@@ -40,6 +41,34 @@ export declare class RpgPlayer extends RpgPlayer_base {
40
41
  context?: Context;
41
42
  conn: MockConnection | null;
42
43
  touchSide: boolean;
44
+ /**
45
+ * Computed signal for world X position
46
+ *
47
+ * Calculates the absolute world X position from the map's world position
48
+ * plus the player's local X position. Returns 0 if no map is assigned.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const worldX = player.worldX();
53
+ * console.log(`Player is at world X: ${worldX}`);
54
+ * ```
55
+ */
56
+ get worldPositionX(): any;
57
+ /**
58
+ * Computed signal for world Y position
59
+ *
60
+ * Calculates the absolute world Y position from the map's world position
61
+ * plus the player's local Y position. Returns 0 if no map is assigned.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const worldY = player.worldY();
66
+ * console.log(`Player is at world Y: ${worldY}`);
67
+ * ```
68
+ */
69
+ get worldPositionY(): any;
70
+ private _worldPositionSignals;
71
+ private _getComputedWorldPosition;
43
72
  /** Internal: Shapes attached to this player */
44
73
  private _attachedShapes;
45
74
  /** Internal: Shapes where this player is currently located */
@@ -66,6 +95,7 @@ export declare class RpgPlayer extends RpgPlayer_base {
66
95
  _onInit(): void;
67
96
  get hooks(): Hooks;
68
97
  get server(): RpgMap | null;
98
+ setMap(map: RpgMap): void;
69
99
  applyFrames(): void;
70
100
  execMethod(method: string, methodData?: any[], target?: any): Promise<any>;
71
101
  /**
@@ -89,28 +119,7 @@ export declare class RpgPlayer extends RpgPlayer_base {
89
119
  y: number;
90
120
  z?: number;
91
121
  } | string): Promise<any | null | boolean>;
92
- /**
93
- * Auto change map when player touches map borders
94
- *
95
- * This method checks if the player touches the current map borders
96
- * and automatically performs a change to the adjacent map if it exists.
97
- *
98
- * @param nextPosition - The next position of the player
99
- * @returns Promise<boolean> - true if a map change occurred
100
- *
101
- * @example
102
- * ```ts
103
- * // Called automatically by the movement system
104
- * const changed = await player.autoChangeMap({ x: newX, y: newY });
105
- * if (changed) {
106
- * console.log('Player changed map automatically');
107
- * }
108
- * ```
109
- */
110
- autoChangeMap(nextPosition: {
111
- x: number;
112
- y: number;
113
- }, forcedDirection?: any): Promise<boolean>;
122
+ autoChangeMap(nextPosition: Vector2): Promise<boolean>;
114
123
  teleport(positions: {
115
124
  x: number;
116
125
  y: number;
@@ -450,10 +459,12 @@ export declare class RpgPlayer extends RpgPlayer_base {
450
459
  * @param schema - The schema to set
451
460
  */
452
461
  setSync(schema: any): void;
462
+ isEvent(): boolean;
453
463
  }
454
464
  export declare class RpgEvent extends RpgPlayer {
455
465
  execMethod(methodName: string, methodData?: any[], instance?: this): Promise<any>;
456
466
  remove(): void;
467
+ isEvent(): boolean;
457
468
  }
458
469
  /**
459
470
  * Interface extension for RpgPlayer
package/dist/index.d.ts CHANGED
@@ -13,3 +13,4 @@ export * from './Gui';
13
13
  export { RpgShape, RpgModule } from '../../common/src';
14
14
  export * from './decorators/event';
15
15
  export * from './decorators/map';
16
+ export * from './Player/MoveManager';