@rpgjs/server 3.3.2 → 4.0.0-beta.10

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 (154) hide show
  1. package/LICENSE +19 -0
  2. package/lib/Game/Map.d.ts +58 -5
  3. package/lib/Game/Map.js +185 -80
  4. package/lib/Game/Map.js.map +1 -1
  5. package/lib/Game/WorldMaps.d.ts +3 -2
  6. package/lib/Game/WorldMaps.js +6 -11
  7. package/lib/Game/WorldMaps.js.map +1 -1
  8. package/lib/Gui/DialogGui.d.ts +1 -1
  9. package/lib/Gui/DialogGui.js +12 -13
  10. package/lib/Gui/DialogGui.js.map +1 -1
  11. package/lib/Gui/Gui.js +2 -6
  12. package/lib/Gui/Gui.js.map +1 -1
  13. package/lib/Gui/MenuGui.js +4 -8
  14. package/lib/Gui/MenuGui.js.map +1 -1
  15. package/lib/Gui/NotificationGui.js +4 -8
  16. package/lib/Gui/NotificationGui.js.map +1 -1
  17. package/lib/Gui/ShopGui.js +4 -8
  18. package/lib/Gui/ShopGui.js.map +1 -1
  19. package/lib/Gui/index.js +6 -13
  20. package/lib/Gui/index.js.map +1 -1
  21. package/lib/Interfaces/Gui.js +1 -2
  22. package/lib/Interfaces/StateStore.js +1 -2
  23. package/lib/MatchMaker.js +28 -46
  24. package/lib/MatchMaker.js.map +1 -1
  25. package/lib/Monitor/index.js +3 -5
  26. package/lib/Monitor/index.js.map +1 -1
  27. package/lib/Player/BattleManager.js +17 -16
  28. package/lib/Player/BattleManager.js.map +1 -1
  29. package/lib/Player/ClassManager.js +6 -10
  30. package/lib/Player/ClassManager.js.map +1 -1
  31. package/lib/Player/ComponentManager.d.ts +4 -4
  32. package/lib/Player/ComponentManager.js +37 -24
  33. package/lib/Player/ComponentManager.js.map +1 -1
  34. package/lib/Player/EffectManager.js +8 -12
  35. package/lib/Player/EffectManager.js.map +1 -1
  36. package/lib/Player/ElementManager.js +5 -9
  37. package/lib/Player/ElementManager.js.map +1 -1
  38. package/lib/Player/GoldManager.js +1 -5
  39. package/lib/Player/GoldManager.js.map +1 -1
  40. package/lib/Player/GuiManager.js +17 -15
  41. package/lib/Player/GuiManager.js.map +1 -1
  42. package/lib/Player/ItemFixture.js +1 -5
  43. package/lib/Player/ItemFixture.js.map +1 -1
  44. package/lib/Player/ItemManager.d.ts +3 -3
  45. package/lib/Player/ItemManager.js +29 -31
  46. package/lib/Player/ItemManager.js.map +1 -1
  47. package/lib/Player/MoveManager.d.ts +7 -6
  48. package/lib/Player/MoveManager.js +67 -74
  49. package/lib/Player/MoveManager.js.map +1 -1
  50. package/lib/Player/ParameterManager.js +10 -14
  51. package/lib/Player/ParameterManager.js.map +1 -1
  52. package/lib/Player/Player.d.ts +7 -1
  53. package/lib/Player/Player.js +193 -191
  54. package/lib/Player/Player.js.map +1 -1
  55. package/lib/Player/SkillManager.js +18 -22
  56. package/lib/Player/SkillManager.js.map +1 -1
  57. package/lib/Player/StateManager.js +9 -13
  58. package/lib/Player/StateManager.js.map +1 -1
  59. package/lib/Player/VariableManager.js +1 -5
  60. package/lib/Player/VariableManager.js.map +1 -1
  61. package/lib/Query.d.ts +2 -1
  62. package/lib/Query.js +19 -15
  63. package/lib/Query.js.map +1 -1
  64. package/lib/RpgServer.d.ts +11 -3
  65. package/lib/RpgServer.js +1 -2
  66. package/lib/Scenes/Map.d.ts +27 -4
  67. package/lib/Scenes/Map.js +117 -122
  68. package/lib/Scenes/Map.js.map +1 -1
  69. package/lib/decorators/event.js +4 -7
  70. package/lib/decorators/event.js.map +1 -1
  71. package/lib/decorators/map.d.ts +1 -1
  72. package/lib/decorators/map.js +5 -9
  73. package/lib/decorators/map.js.map +1 -1
  74. package/lib/entry-point.d.ts +1 -0
  75. package/lib/entry-point.js +59 -65
  76. package/lib/entry-point.js.map +1 -1
  77. package/lib/express/api.d.ts +3 -0
  78. package/lib/express/api.js +105 -0
  79. package/lib/express/api.js.map +1 -0
  80. package/lib/express/errors/NotAuthorized.d.ts +4 -0
  81. package/lib/express/errors/NotAuthorized.js +7 -0
  82. package/lib/express/errors/NotAuthorized.js.map +1 -0
  83. package/lib/express/errors/NotFound.d.ts +4 -0
  84. package/lib/express/errors/NotFound.js +7 -0
  85. package/lib/express/errors/NotFound.js.map +1 -0
  86. package/lib/express/server.d.ts +1 -0
  87. package/lib/express/server.js +22 -6
  88. package/lib/express/server.js.map +1 -1
  89. package/lib/index.js +15 -68
  90. package/lib/index.js.map +1 -1
  91. package/lib/logs/index.js +5 -11
  92. package/lib/logs/index.js.map +1 -1
  93. package/lib/logs/item.js +11 -15
  94. package/lib/logs/item.js.map +1 -1
  95. package/lib/logs/log.js +1 -5
  96. package/lib/logs/log.js.map +1 -1
  97. package/lib/logs/skill.js +6 -10
  98. package/lib/logs/skill.js.map +1 -1
  99. package/lib/logs/state.js +5 -9
  100. package/lib/logs/state.js.map +1 -1
  101. package/lib/models/Item.js +1 -2
  102. package/lib/presets/index.js +28 -36
  103. package/lib/presets/index.js.map +1 -1
  104. package/lib/server.d.ts +24 -2
  105. package/lib/server.js +229 -134
  106. package/lib/server.js.map +1 -1
  107. package/package.json +30 -15
  108. package/src/Game/Map.ts +513 -0
  109. package/src/Game/WorldMaps.ts +45 -0
  110. package/src/Gui/DialogGui.ts +67 -0
  111. package/src/Gui/Gui.ts +45 -0
  112. package/src/Gui/MenuGui.ts +26 -0
  113. package/src/Gui/NotificationGui.ts +10 -0
  114. package/src/Gui/ShopGui.ts +43 -0
  115. package/src/Gui/index.ts +13 -0
  116. package/src/Interfaces/Gui.ts +4 -0
  117. package/src/Interfaces/StateStore.ts +5 -0
  118. package/src/MatchMaker.ts +63 -0
  119. package/src/Monitor/index.ts +78 -0
  120. package/src/Player/BattleManager.ts +123 -0
  121. package/src/Player/ClassManager.ts +72 -0
  122. package/src/Player/ComponentManager.ts +538 -0
  123. package/src/Player/EffectManager.ts +94 -0
  124. package/src/Player/ElementManager.ts +142 -0
  125. package/src/Player/GoldManager.ts +26 -0
  126. package/src/Player/GuiManager.ts +308 -0
  127. package/src/Player/ItemFixture.ts +24 -0
  128. package/src/Player/ItemManager.ts +474 -0
  129. package/src/Player/MoveManager.ts +635 -0
  130. package/src/Player/ParameterManager.ts +468 -0
  131. package/src/Player/Player.ts +931 -0
  132. package/src/Player/SkillManager.ts +229 -0
  133. package/src/Player/StateManager.ts +230 -0
  134. package/src/Player/VariableManager.ts +55 -0
  135. package/src/Query.ts +172 -0
  136. package/src/RpgServer.ts +429 -0
  137. package/src/Scenes/Map.ts +302 -0
  138. package/src/decorators/event.ts +57 -0
  139. package/src/decorators/map.ts +223 -0
  140. package/src/entry-point.ts +104 -0
  141. package/src/express/api.ts +118 -0
  142. package/src/express/errors/NotAuthorized.ts +6 -0
  143. package/src/express/errors/NotFound.ts +6 -0
  144. package/src/express/server.ts +95 -0
  145. package/src/index.ts +28 -0
  146. package/src/logs/index.ts +11 -0
  147. package/src/logs/item.ts +31 -0
  148. package/src/logs/log.ts +3 -0
  149. package/src/logs/skill.ts +16 -0
  150. package/src/logs/state.ts +13 -0
  151. package/src/models/Item.ts +11 -0
  152. package/src/presets/index.ts +71 -0
  153. package/src/server.ts +396 -0
  154. package/tsconfig.json +27 -0
@@ -0,0 +1,635 @@
1
+ import { Direction, LiteralDirection, RpgShape, Vector2d } from '@rpgjs/common'
2
+ import { Utils } from '@rpgjs/common'
3
+ import { Behavior, ClientMode, MoveMode, MoveTo, PositionXY, SocketEvents, SocketMethods, Tick } from '@rpgjs/types'
4
+ import { Observable, Subscription, takeUntil, Subject } from 'rxjs'
5
+ import { RpgServerEngine } from '../server'
6
+ import { RpgEvent, RpgPlayer } from './Player'
7
+
8
+ const {
9
+ arrayFlat,
10
+ random,
11
+ isFunction,
12
+ capitalize
13
+ } = Utils
14
+
15
+ function wait(sec: number) {
16
+ return new Promise((resolve) => {
17
+ setTimeout(resolve, sec * 1000)
18
+ })
19
+ }
20
+
21
+ type CallbackTileMove = (player: RpgPlayer, map) => Direction[]
22
+ type CallbackTurnMove = (player: RpgPlayer, map) => string
23
+ type Routes = (string | Promise<any> | Direction | Direction[] | Function)[]
24
+
25
+ export enum Frequency {
26
+ Lowest = 600,
27
+ Lower = 400,
28
+ Low = 200,
29
+ High = 100,
30
+ Higher = 50,
31
+ Highest = 25,
32
+ None = 0
33
+ }
34
+
35
+ export enum Speed {
36
+ Slowest = 0.2,
37
+ Slower = 0.5,
38
+ Slow = 1,
39
+ Normal = 3,
40
+ Fast = 5,
41
+ Faster = 7,
42
+ Fastest = 10
43
+ }
44
+
45
+ /**
46
+ * @title Move
47
+ * @enum {Object}
48
+ *
49
+ * Move.right(repeat=1) | Movement of a number of pixels on the right
50
+ * Move.left(repeat=1) | Movement of a number of pixels on the left
51
+ * Move.up(repeat=1) | Movement of a number of pixels on the up
52
+ * Move.down(repeat=1) | Movement of a number of pixels on the down
53
+ * Move.random(repeat=1) | Movement of a number of pixels in a random direction
54
+ * Move.towardPlayer(player, repeat=1) | Moves a number of pixels in the direction of the designated player
55
+ * Move.awayFromPlayer(player, repeat=1) | Moves a number of pixels in the opposite direction of the designated player
56
+ * Move.tileRight(repeat=1) | Movement of a number of tiles on the right
57
+ * Move.tileLeft(repeat=1) | Movement of a number of tiles on the left
58
+ * Move.tileUp(repeat=1) | Movement of a number of tiles on the up
59
+ * Move.tileDown(repeat=1) | Movement of a number of tiles on the down
60
+ * Move.tileRandom(repeat=1) | Movement of a number of tiles in a random direction
61
+ * Move.tileTowardPlayer(player, repeat=1) | Moves a number of tiles in the direction of the designated player
62
+ * Move.tileAwayFromPlayer(player, repeat=1) | Moves a number of tiles in the opposite direction of the designated player
63
+ * Move.turnRight() | Turn to the right
64
+ * Move.turnLeft() | Turn to the left
65
+ * Move.turnUp() | Turn to the up
66
+ * Move.turnDown() | Turn to the down
67
+ * Move.turnRandom() | Turn to random direction
68
+ * Move.turnAwayFromPlayer(player) | Turns in the opposite direction of the designated player
69
+ * Move.turnTowardPlayer(player) | Turns in the direction of the designated player
70
+ * @memberof Move
71
+ * */
72
+ class MoveList {
73
+
74
+ repeatMove(direction: Direction, repeat: number): Direction[] {
75
+ return new Array(repeat).fill(direction)
76
+ }
77
+
78
+ private repeatTileMove(direction: string, repeat: number, propMap: string): CallbackTileMove {
79
+ return (player: RpgPlayer, map): Direction[] => {
80
+ const repeatTile = Math.floor(map[propMap] / player.speed) * repeat
81
+ return this[direction](repeatTile)
82
+ }
83
+ }
84
+
85
+ right(repeat: number = 1): Direction[] {
86
+ return this.repeatMove(Direction.Right, repeat)
87
+ }
88
+
89
+ left(repeat: number = 1): Direction[] {
90
+ return this.repeatMove(Direction.Left, repeat)
91
+ }
92
+
93
+ up(repeat: number = 1): Direction[] {
94
+ return this.repeatMove(Direction.Up, repeat)
95
+ }
96
+
97
+ down(repeat: number = 1): Direction[] {
98
+ return this.repeatMove(Direction.Down, repeat)
99
+ }
100
+
101
+ wait(sec: number): Promise<unknown> {
102
+ return wait(sec)
103
+ }
104
+
105
+ random(repeat: number = 1): Direction[] {
106
+ return new Array(repeat).fill(null).map(() => [
107
+ Direction.Right,
108
+ Direction.Left,
109
+ Direction.Up,
110
+ Direction.Down
111
+ ][random(0, 3)])
112
+ }
113
+
114
+ tileRight(repeat: number = 1): CallbackTileMove {
115
+ return this.repeatTileMove('right', repeat, 'tileWidth')
116
+ }
117
+
118
+ tileLeft(repeat: number = 1): CallbackTileMove {
119
+ return this.repeatTileMove('left', repeat, 'tileWidth')
120
+ }
121
+
122
+ tileUp(repeat: number = 1): CallbackTileMove {
123
+ return this.repeatTileMove('up', repeat, 'tileHeight')
124
+ }
125
+
126
+ tileDown(repeat: number = 1): CallbackTileMove {
127
+ return this.repeatTileMove('down', repeat, 'tileHeight')
128
+ }
129
+
130
+ tileRandom(repeat: number = 1): CallbackTileMove {
131
+ return (player: RpgPlayer, map): Direction[] => {
132
+ let directions: Direction[] = []
133
+ for (let i = 0; i < repeat; i++) {
134
+ const randFn: CallbackTileMove = [
135
+ this.tileRight(),
136
+ this.tileLeft(),
137
+ this.tileUp(),
138
+ this.tileDown()
139
+ ][random(0, 3)]
140
+ directions = [
141
+ ...directions,
142
+ ...randFn(player, map)
143
+ ]
144
+ }
145
+ return directions
146
+ }
147
+ }
148
+
149
+ private _awayFromPlayerDirection(player: RpgPlayer, otherPlayer: RpgPlayer): number {
150
+ const directionOtherPlayer = otherPlayer.getDirection()
151
+ let newDirection = 0
152
+ switch (directionOtherPlayer) {
153
+ case Direction.Left:
154
+ case Direction.Right:
155
+ if (otherPlayer.position.x > player.position.x) {
156
+ newDirection = Direction.Left
157
+ }
158
+ else {
159
+ newDirection = Direction.Right
160
+ }
161
+ break
162
+ case Direction.Up:
163
+ case Direction.Down:
164
+ if (otherPlayer.position.y > player.position.y) {
165
+ newDirection = Direction.Up
166
+ }
167
+ else {
168
+ newDirection = Direction.Down
169
+ }
170
+ break
171
+ }
172
+ return newDirection
173
+ }
174
+
175
+ private _towardPlayerDirection(player: RpgPlayer, otherPlayer: RpgPlayer): number {
176
+ const directionOtherPlayer = otherPlayer.getDirection()
177
+ let newDirection = 0
178
+ switch (directionOtherPlayer) {
179
+ case Direction.Left:
180
+ case Direction.Right:
181
+ if (otherPlayer.position.x > player.position.x) {
182
+ newDirection = Direction.Right
183
+ }
184
+ else {
185
+ newDirection = Direction.Left
186
+ }
187
+ break
188
+ case Direction.Up:
189
+ case Direction.Down:
190
+ if (otherPlayer.position.y > player.position.y) {
191
+ newDirection = Direction.Down
192
+ }
193
+ else {
194
+ newDirection = Direction.Up
195
+ }
196
+ break
197
+ }
198
+ return newDirection
199
+ }
200
+
201
+ private _awayFromPlayer({ isTile, typeMov }: { isTile: boolean, typeMov: string }, otherPlayer: RpgPlayer, repeat: number = 1) {
202
+ const method = (dir: number) => {
203
+ const direction: string = LiteralDirection[dir]
204
+ return this[isTile ? 'tile' + capitalize(direction) : direction](repeat)
205
+ }
206
+ return (player: RpgPlayer, map) => {
207
+ let newDirection = 0
208
+ switch (typeMov) {
209
+ case 'away':
210
+ newDirection = this._awayFromPlayerDirection(player, otherPlayer)
211
+ break;
212
+ case 'toward':
213
+ newDirection = this._towardPlayerDirection(player, otherPlayer)
214
+ break
215
+ }
216
+ let direction: any = method(newDirection)
217
+ if (isFunction(direction)) {
218
+ direction = direction(player, map)
219
+ }
220
+ return direction
221
+ }
222
+ }
223
+
224
+ towardPlayer(player: RpgPlayer, repeat: number = 1) {
225
+ return this._awayFromPlayer({ isTile: false, typeMov: 'toward' }, player, repeat)
226
+ }
227
+
228
+ tileTowardPlayer(player: RpgPlayer, repeat: number = 1) {
229
+ return this._awayFromPlayer({ isTile: true, typeMov: 'toward' }, player, repeat)
230
+ }
231
+
232
+ awayFromPlayer(player: RpgPlayer, repeat: number = 1): CallbackTileMove {
233
+ return this._awayFromPlayer({ isTile: false, typeMov: 'away' }, player, repeat)
234
+ }
235
+
236
+ tileAwayFromPlayer(player: RpgPlayer, repeat: number = 1): CallbackTileMove {
237
+ return this._awayFromPlayer({ isTile: true, typeMov: 'away' }, player, repeat)
238
+ }
239
+
240
+ turnLeft(): string {
241
+ return 'turn-' + Direction.Left
242
+ }
243
+
244
+ turnRight(): string {
245
+ return 'turn-' + Direction.Right
246
+ }
247
+
248
+ turnUp(): string {
249
+ return 'turn-' + Direction.Up
250
+ }
251
+
252
+ turnDown(): string {
253
+ return 'turn-' + Direction.Down
254
+ }
255
+
256
+ turnRandom(): string {
257
+ return [
258
+ this.turnRight(),
259
+ this.turnLeft(),
260
+ this.turnUp(),
261
+ this.turnDown()
262
+ ][random(0, 3)]
263
+ }
264
+
265
+ turnAwayFromPlayer(otherPlayer: RpgPlayer): CallbackTurnMove {
266
+ return (player: RpgPlayer) => {
267
+ const direction = this._awayFromPlayerDirection(player, otherPlayer)
268
+ return 'turn-' + direction
269
+ }
270
+ }
271
+
272
+ turnTowardPlayer(otherPlayer: RpgPlayer): CallbackTurnMove {
273
+ return (player: RpgPlayer) => {
274
+ const direction = this._towardPlayerDirection(player, otherPlayer)
275
+ return 'turn-' + direction
276
+ }
277
+ }
278
+ }
279
+
280
+ export const Move = new MoveList()
281
+
282
+ export class MoveManager {
283
+ private movingSubscription: Subscription
284
+ private _infiniteRoutes: Routes
285
+ private _finishRoute: Function
286
+
287
+ /**
288
+ * Changes the player's speed
289
+ *
290
+ * ```ts
291
+ * player.speed = 1
292
+ * ```
293
+ *
294
+ * You can use Speed enum
295
+ *
296
+ * ```ts
297
+ * import { Speed } from '@rpgjs/server'
298
+ * player.speed = Speed.Slow
299
+ * ```
300
+ *
301
+ * @title Change Speed
302
+ * @prop {number} player.speed
303
+ * @enum {number}
304
+ *
305
+ * Speed.Slowest | 0.2
306
+ * Speed.Slower | 0.5
307
+ * Speed.Slow | 1
308
+ * Speed.Normal | 3
309
+ * Speed.Fast | 5
310
+ * Speed.Faster | 7
311
+ * Speed.Fastest | 10
312
+ * @default 3
313
+ * @memberof MoveManager
314
+ * */
315
+ speed: number
316
+
317
+ /**
318
+ * Blocks the movement. The player will not be able to move even if he presses the direction keys on the keyboard.
319
+ *
320
+ * ```ts
321
+ * player.canMove = false
322
+ * ```
323
+ *
324
+ * @title Block movement
325
+ * @prop {boolean} player.canMove
326
+ * @default true
327
+ * @memberof MoveManager
328
+ * */
329
+ canMove: boolean
330
+
331
+ /**
332
+ * The player passes through the other players (or vice versa). But the player does not go through the events.
333
+ *
334
+ * ```ts
335
+ * player.throughOtherPlayer = true
336
+ * ```
337
+ *
338
+ * @title Go through to other player
339
+ * @prop {boolean} player.throughOtherPlayer
340
+ * @default true
341
+ * @memberof MoveManager
342
+ * */
343
+ throughOtherPlayer: boolean
344
+
345
+ /**
346
+ * The player goes through the event or the other players (or vice versa)
347
+ *
348
+ * ```ts
349
+ * player.through = true
350
+ * ```
351
+ *
352
+ * @title Go through the player
353
+ * @prop {boolean} player.through
354
+ * @default false
355
+ * @memberof MoveManager
356
+ * */
357
+ through: boolean
358
+
359
+ /**
360
+ * The frequency allows to put a stop time between each movement in the array of the moveRoutes() method.
361
+ * The value represents a dwell time in milliseconds. The higher the value, the slower the frequency.
362
+ *
363
+ * ```ts
364
+ * player.frequency = 400
365
+ * ```
366
+ *
367
+ * You can use Frequency enum
368
+ *
369
+ * ```ts
370
+ * import { Frequency } from '@rpgjs/server'
371
+ * player.frequency = Frequency.Low
372
+ * ```
373
+ *
374
+ * @title Change Frequency
375
+ * @prop {number} player.speed
376
+ * @enum {number}
377
+ *
378
+ * Frequency.Lowest | 600
379
+ * Frequency.Lower | 400
380
+ * Frequency.Low | 200
381
+ * Frequency.High | 100
382
+ * Frequency.Higher | 50
383
+ * Frequency.Highest | 25
384
+ * Frequency.None | 0
385
+ * @default 0
386
+ * @memberof MoveManager
387
+ * */
388
+ frequency: number
389
+
390
+ /**
391
+ * Gives an itinerary.
392
+ *
393
+ * You can create your own motion function:
394
+ *
395
+ * ```ts
396
+ * import { Direction } from '@rpgjs/server'
397
+ *
398
+ * const customMove = () => {
399
+ * return [Direction.Left, Direction.Up]
400
+ * }
401
+ *
402
+ * player.moveRoutes([ customMove() ])
403
+ * ```
404
+ *
405
+ * Your function can also return a function:
406
+ *
407
+ * ```ts
408
+ * import { Direction, RpgPlayer } from '@rpgjs/server'
409
+ *
410
+ * // This function can be found in another file. By returning a function, you have access to the player who is making a move.
411
+ * const customMove = (otherPlayer: RpgPlayer) => {
412
+ * return (player: RpgPlayer, map) => {
413
+ * return otherPlayer.position.x > player.position.x ? Direction.Left : Direction.Right
414
+ * }
415
+ * }
416
+ *
417
+ * player.moveRoutes([ customMove(otherPlayer) ])
418
+ * ```
419
+ *
420
+ * the function contains two parameters:
421
+ *
422
+ * - `player`: the player concerned by the movement
423
+ * - `map`: The information of the current map
424
+ *
425
+ * @title Give an itinerary
426
+ * @method player.moveRoutes(routes)
427
+ * @param {Array<Move>} routes
428
+ * @returns {Promise}
429
+ * @memberof MoveManager
430
+ * @example
431
+ *
432
+ * ```ts
433
+ * import { Move } from '@rpgjs/server'
434
+ *
435
+ * await player.moveRoutes([ Move.tileLeft(), Move.tileDown(2) ])
436
+ * // The path is over when the promise is resolved
437
+ * ```
438
+ */
439
+ moveRoutes(routes: Routes): Promise<boolean> {
440
+ let count = 0
441
+ let frequence = 0
442
+ this.breakRoutes() // break previous route
443
+ return new Promise(async (resolve) => {
444
+ this._finishRoute = resolve
445
+ routes = routes.map((route: any) => {
446
+ if (isFunction(route)) {
447
+ return route(this, this.getCurrentMap())
448
+ }
449
+ return route
450
+ })
451
+ routes = arrayFlat(routes)
452
+ const move = () => {
453
+ // If movement continues while the player no longer exists or is no longer on the map
454
+ if (!this) {
455
+ return
456
+ }
457
+ if (count >= this['nbPixelInTile']) {
458
+ if (frequence < this.frequency) {
459
+ frequence++
460
+ return
461
+ }
462
+ }
463
+
464
+ frequence = 0
465
+ count++
466
+
467
+ const [route] = routes
468
+
469
+ if (route === undefined) {
470
+ this.breakRoutes()
471
+ return
472
+ }
473
+
474
+ switch (route) {
475
+ case Direction.Left:
476
+ case Direction.Down:
477
+ case Direction.Right:
478
+ case Direction.Up:
479
+ this.moveByDirection(route, 1)
480
+ break
481
+ case 'turn-' + Direction.Left:
482
+ this.changeDirection(Direction.Left)
483
+ break
484
+ case 'turn-' + Direction.Right:
485
+ this.changeDirection(Direction.Right)
486
+ break
487
+ case 'turn-' + Direction.Up:
488
+ this.changeDirection(Direction.Up)
489
+ break
490
+ case 'turn-' + Direction.Down:
491
+ this.changeDirection(Direction.Down)
492
+ break
493
+ }
494
+
495
+ routes.shift()
496
+ }
497
+ this.movingSubscription = this.server.tick
498
+ .pipe(
499
+ takeUntil(this._destroy$)
500
+ )
501
+ .subscribe(move)
502
+ })
503
+ }
504
+
505
+ /**
506
+ * Giving a path that repeats itself in a loop to a character
507
+ *
508
+ * You can stop the movement at any time with `breakRoutes()` and replay it with `replayRoutes()`.
509
+ *
510
+ * @title Infinite Move Routes
511
+ * @method player.infiniteMoveRoute(routes)
512
+ * @param {Array<Move>} routes
513
+ * @returns {void}
514
+ * @memberof MoveManager
515
+ * @example
516
+ *
517
+ * ```ts
518
+ * import { Move } from '@rpgjs/server'
519
+ *
520
+ * player.infiniteMoveRoute([ Move.tileRandom() ])
521
+ * ```
522
+ */
523
+ infiniteMoveRoute(routes: Routes): void {
524
+ this._infiniteRoutes = routes
525
+
526
+ const move = (isBreaking: boolean) => {
527
+ if (isBreaking) return
528
+ this.moveRoutes(routes).then(move)
529
+ }
530
+
531
+ move(false)
532
+ }
533
+
534
+ /**
535
+ * Works only for infinite movements. You must first use the method `infiniteMoveRoute()`
536
+ *
537
+ * @title Stop an infinite movement
538
+ * @method player.breakRoutes(force=false)
539
+ * @param {boolean} [force] Forces the stop of the infinite movement
540
+ * @returns {void}
541
+ * @memberof MoveManager
542
+ * @example
543
+ *
544
+ * ```ts
545
+ * import { Move } from '@rpgjs/server'
546
+ *
547
+ * player.infiniteMoveRoute([ Move.tileRandom() ])
548
+ * player.breakRoutes(true)
549
+ * ```
550
+ */
551
+ breakRoutes(force: boolean = false): void {
552
+ if (this._finishRoute) {
553
+ this.movingSubscription.unsubscribe()
554
+ this._finishRoute(force)
555
+ }
556
+ }
557
+
558
+ /**
559
+ * Works only for infinite movements. You must first use the method `infiniteMoveRoute()`
560
+ * If the road was stopped with `breakRoutes()`, you can restart it with this method
561
+ *
562
+ * @title Replay an infinite movement
563
+ * @method player.replayRoutes()
564
+ * @returns {void}
565
+ * @memberof MoveManager
566
+ * @example
567
+ *
568
+ * ```ts
569
+ * import { Move } from '@rpgjs/server'
570
+ *
571
+ * player.infiniteMoveRoute([ Move.tileRandom() ])
572
+ * player.breakRoutes(true)
573
+ * player.replayRoutes()
574
+ * ```
575
+ */
576
+ replayRoutes(): void {
577
+ if (this._infiniteRoutes) this.infiniteMoveRoute(this._infiniteRoutes)
578
+ }
579
+
580
+ /**
581
+ * Move the event to another event, a player, a shape or a specific position.
582
+ * The event will avoid obstacles, but you can tell if it is stuck or has completed its path
583
+ *
584
+ * @title Move To
585
+ * @method player.moveTo()
586
+ * @param {RpgPlayer|RpgEvent|RpgShape|Position} target the target
587
+ * @param {object} [options] - animate. Set a boolean to use default parameters
588
+ * @param {boolean} [options.infinite=false] - moves infinitely towards the target, you have to stop its movement manually with the method `stopMoveTo()`
589
+ * @param {() => void} [options.onComplete] - Callback when the event arrives at the destination
590
+ * @param {(duration:number) => void} [options.onStuck] - callback when the event is blocked against a wall. Duration gives you the duration (in frames) of the blocking time
591
+ * @returns {Observable<void>}
592
+ * @since 3.2.0
593
+ * @memberof MoveManager
594
+ * @example
595
+ *
596
+ * ```ts
597
+ * import { Move } from '@rpgjs/server'
598
+ *
599
+ * player.moveTo(otherPlayer).subscribe()
600
+ * ```
601
+ */
602
+ moveTo(event: RpgEvent, options?: MoveTo): Observable<void>
603
+ moveTo(player: RpgPlayer, options?: MoveTo): Observable<void>
604
+ moveTo(position: PositionXY, options?: MoveTo): Observable<void>
605
+ moveTo(shape: RpgShape, options?: MoveTo): Observable<void>
606
+ moveTo(position: RpgPlayer | RpgShape | PositionXY, options?: MoveTo): Observable<void> {
607
+ return this['_moveTo'](this.server.tick, position, options)
608
+ }
609
+
610
+ // TODO
611
+ setMoveMode(mode: MoveMode): void {
612
+ if (mode.checkCollision) this.checkCollision = mode.checkCollision
613
+ if (mode.clientMode) this.clientModeMove = mode.clientMode
614
+ if (mode.behavior) this.behavior = mode.behavior
615
+ this.emit(SocketEvents.CallMethod, {
616
+ objectId: this.id,
617
+ name: SocketMethods.ModeMove,
618
+ params: [mode]
619
+ })
620
+ }
621
+ }
622
+
623
+ export interface MoveManager {
624
+ moveByDirection: (direction: Direction, deltaTimeInt: number) => Promise<boolean>
625
+ changeDirection: (direction: Direction) => boolean
626
+ getCurrentMap: any
627
+ checkCollision: boolean
628
+ clientModeMove: ClientMode
629
+ behavior: Behavior
630
+ emit(name: SocketEvents, params: any)
631
+ id: string
632
+ server: RpgServerEngine
633
+ position: Vector2d
634
+ _destroy$: Subject<void>
635
+ }