@rpgjs/server 5.0.0-alpha.10 → 5.0.0-alpha.3
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/CHANGELOG.md +9 -0
- package/dist/Player/BattleManager.d.ts +22 -32
- package/dist/Player/ClassManager.d.ts +18 -31
- package/dist/Player/Event.d.ts +0 -0
- package/dist/Player/ItemManager.d.ts +13 -27
- package/dist/Player/MoveManager.d.ts +43 -31
- package/dist/Player/ParameterManager.d.ts +19 -27
- package/dist/Player/Player.d.ts +8 -123
- package/dist/Player/SkillManager.d.ts +19 -27
- package/dist/Player/StateManager.d.ts +35 -28
- package/dist/RpgServer.d.ts +1 -224
- package/dist/index.js +647 -1108
- package/dist/index.js.map +1 -1
- package/dist/rooms/map.d.ts +1 -70
- package/package.json +8 -8
- package/src/Player/BattleManager.ts +38 -97
- package/src/Player/ClassManager.ts +35 -95
- package/src/Player/ComponentManager.ts +20 -64
- package/src/Player/EffectManager.ts +27 -110
- package/src/Player/ElementManager.ts +25 -126
- package/src/Player/Event.ts +0 -0
- package/src/Player/GoldManager.ts +35 -32
- package/src/Player/GuiManager.ts +140 -187
- package/src/Player/ItemFixture.ts +5 -4
- package/src/Player/ItemManager.ts +26 -39
- package/src/Player/MoveManager.ts +31 -40
- package/src/Player/ParameterManager.ts +25 -35
- package/src/Player/Player.ts +39 -184
- package/src/Player/SkillManager.ts +23 -44
- package/src/Player/StateManager.ts +95 -210
- package/src/Player/VariableManager.ts +48 -180
- package/src/RpgServer.ts +1 -232
- package/src/core/context.ts +0 -1
- package/src/rooms/map.ts +8 -76
- package/dist/Player/ComponentManager.d.ts +0 -60
- package/dist/Player/EffectManager.d.ts +0 -40
- package/dist/Player/ElementManager.d.ts +0 -31
- package/dist/Player/GoldManager.d.ts +0 -22
- package/dist/Player/GuiManager.d.ts +0 -176
- package/dist/Player/ItemFixture.d.ts +0 -6
- package/dist/Player/VariableManager.d.ts +0 -30
package/src/Player/GuiManager.ts
CHANGED
|
@@ -1,45 +1,132 @@
|
|
|
1
1
|
import { RpgPlayer } from "./Player";
|
|
2
2
|
import { Gui, DialogGui, MenuGui, ShopGui, NotificationGui } from "../Gui";
|
|
3
3
|
import { DialogOptions, Choice } from "../Gui/DialogGui";
|
|
4
|
-
import { Constructor,
|
|
4
|
+
import { Constructor, RpgCommonPlayer } from "@rpgjs/common";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* @param Base - The base class to extend with GUI management
|
|
14
|
-
* @returns Extended class with GUI management methods
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* class MyPlayer extends WithGuiManager(BasePlayer) {
|
|
19
|
-
* constructor() {
|
|
20
|
-
* super();
|
|
21
|
-
* // GUI system is automatically initialized
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
*
|
|
25
|
-
* const player = new MyPlayer();
|
|
26
|
-
* await player.showText('Hello World!');
|
|
27
|
-
* player.callMainMenu();
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export function WithGuiManager<TBase extends PlayerCtor>(
|
|
6
|
+
export interface IGuiManager {
|
|
7
|
+
emit: any;
|
|
8
|
+
removeGui: (guiId: string, data?: any) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function WithGuiManager<TBase extends Constructor<RpgCommonPlayer>>(
|
|
31
12
|
Base: TBase
|
|
32
|
-
)
|
|
33
|
-
IGuiManager {
|
|
34
|
-
class GuiManagerMixin extends Base {
|
|
13
|
+
) {
|
|
14
|
+
return class extends Base implements IGuiManager {
|
|
35
15
|
_gui: { [id: string]: Gui } = {};
|
|
36
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Show a text. This is a graphical interface already built. Opens the GUI named `rpg-dialog`
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* player.showText('Hello World')
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The method returns a promise. It is resolved when the dialog box is closed.
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* await player.showText('Hello World')
|
|
28
|
+
* // dialog box is closed, then ...
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* **Option: position**
|
|
32
|
+
*
|
|
33
|
+
* You can define how the dialog box is displayed:
|
|
34
|
+
* - top
|
|
35
|
+
* - middle
|
|
36
|
+
* - bottom
|
|
37
|
+
*
|
|
38
|
+
* (bottom by default)
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* player.showText('Hello World', {
|
|
42
|
+
* position: 'top'
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* **Option: fullWidth**
|
|
47
|
+
*
|
|
48
|
+
* `boolean` (true by default)
|
|
49
|
+
*
|
|
50
|
+
* Indicate that the dialog box will take the full width of the screen.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* player.showText('Hello World', {
|
|
54
|
+
* fullWidth: true
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* **Option: autoClose**
|
|
59
|
+
*
|
|
60
|
+
* `boolean` (false by default)
|
|
61
|
+
*
|
|
62
|
+
* If false, the user will have to press Enter to close the dialog box.
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* player.showText('Hello World', {
|
|
66
|
+
* autoClose: true
|
|
67
|
+
* })
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* **Option: typewriterEffect**
|
|
71
|
+
*
|
|
72
|
+
* `boolean` (true by default)
|
|
73
|
+
*
|
|
74
|
+
* Performs a typewriter effect
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* player.showText('Hello World', {
|
|
78
|
+
* typewriterEffect: false
|
|
79
|
+
* })
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* **Option: talkWith**
|
|
83
|
+
*
|
|
84
|
+
* `RpgPlayer` (nothing by default)
|
|
85
|
+
*
|
|
86
|
+
* If you specify the event or another player, the other player will stop his or her movement and look in the player's direction.
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* // Code in an event
|
|
90
|
+
* player.showText('Hello World', {
|
|
91
|
+
* talkWith: this
|
|
92
|
+
* })
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @title Show Text
|
|
96
|
+
* @method player.showText(text,options)
|
|
97
|
+
* @param {string} text
|
|
98
|
+
* @param {object} [options] the different options, see usage below
|
|
99
|
+
* @returns {Promise}
|
|
100
|
+
* @memberof GuiManager
|
|
101
|
+
*/
|
|
37
102
|
showText(msg: string, options: DialogOptions = {}): Promise<any> {
|
|
38
103
|
const gui = new DialogGui(<any>this);
|
|
39
104
|
this._gui[gui.id] = gui;
|
|
40
105
|
return gui.openDialog(msg, options);
|
|
41
106
|
}
|
|
42
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Shows a dialog box with a choice. Opens the GUI named `rpg-dialog`
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* const choice = await player.showChoices('What color do you prefer?', [
|
|
113
|
+
* { text: 'Black', value: 'black' },
|
|
114
|
+
* { text: 'Rather the blue', value: 'blue' },
|
|
115
|
+
* { text: 'I don\'t have a preference!', value: 'none' }
|
|
116
|
+
* ])
|
|
117
|
+
*
|
|
118
|
+
* // If the player selects the first
|
|
119
|
+
* console.log(choice) // { text: 'Black', value: 'black' }
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @title Show Choices
|
|
123
|
+
* @method player.showChoices(text,choices)
|
|
124
|
+
* @param {string} text
|
|
125
|
+
* @param {Array<{ text: string, value: any }>} choices
|
|
126
|
+
* @param {object} [options] Same options as the openDialog method
|
|
127
|
+
* @returns {Promise<Choice | null>}
|
|
128
|
+
* @memberof GuiManager
|
|
129
|
+
*/
|
|
43
130
|
showChoices(
|
|
44
131
|
msg: string,
|
|
45
132
|
choices: Choice[],
|
|
@@ -54,6 +141,19 @@ export function WithGuiManager<TBase extends PlayerCtor>(
|
|
|
54
141
|
});
|
|
55
142
|
}
|
|
56
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Displays a notification . Opens the GUI named `rpg-notification`
|
|
146
|
+
*
|
|
147
|
+
* @title Displays a notification
|
|
148
|
+
* @method player.showNotification()
|
|
149
|
+
* @param {string} message - The message to display in the notification
|
|
150
|
+
* @param {object} options - An object containing options for the notification
|
|
151
|
+
* @param {number} options.time - The time to display the notification for (in ms). Default: 2000ms
|
|
152
|
+
* @param {string} options.icon - The icon to display in the notification. Put the identifier of the spritesheet (defined on the client side)
|
|
153
|
+
* @param {string} options.sound - The sound to play when the notification is shown. Set the sound ID (defined on the client side)
|
|
154
|
+
* @returns {void}
|
|
155
|
+
* @memberof GuiManager
|
|
156
|
+
*/
|
|
57
157
|
showNotification(
|
|
58
158
|
message: string,
|
|
59
159
|
options: { time?: number; icon?: string; sound?: string } = {}
|
|
@@ -67,6 +167,14 @@ export function WithGuiManager<TBase extends PlayerCtor>(
|
|
|
67
167
|
return gui.open(data);
|
|
68
168
|
}
|
|
69
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Calls main menu. Opens the GUI named `rpg-main-menu`
|
|
172
|
+
*
|
|
173
|
+
* @title Call Main Menu
|
|
174
|
+
* @method player.callMainMenu()
|
|
175
|
+
* @returns {void}
|
|
176
|
+
* @memberof GuiManager
|
|
177
|
+
*/
|
|
70
178
|
callMainMenu() {
|
|
71
179
|
const gui = new MenuGui(<any>this);
|
|
72
180
|
this._gui[gui.id] = gui;
|
|
@@ -145,11 +253,11 @@ export function WithGuiManager<TBase extends PlayerCtor>(
|
|
|
145
253
|
}
|
|
146
254
|
}
|
|
147
255
|
|
|
148
|
-
_attachedGui(players: RpgPlayer[] | RpgPlayer, display: boolean) {
|
|
256
|
+
private _attachedGui(players: RpgPlayer[] | RpgPlayer, display: boolean) {
|
|
149
257
|
if (!Array.isArray(players)) {
|
|
150
258
|
players = [players] as RpgPlayer[];
|
|
151
259
|
}
|
|
152
|
-
|
|
260
|
+
this.emit("gui.tooltip", {
|
|
153
261
|
players: (players as RpgPlayer[]).map((player) => player.id),
|
|
154
262
|
display,
|
|
155
263
|
});
|
|
@@ -205,160 +313,5 @@ export function WithGuiManager<TBase extends PlayerCtor>(
|
|
|
205
313
|
const _players = players || this;
|
|
206
314
|
this._attachedGui(_players as RpgPlayer[], false);
|
|
207
315
|
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return GuiManagerMixin as unknown as any;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Interface for GUI management capabilities
|
|
215
|
-
* Defines the methods that will be available on the player
|
|
216
|
-
*/
|
|
217
|
-
export interface IGuiManager {
|
|
218
|
-
/**
|
|
219
|
-
* Show a text. This is a graphical interface already built. Opens the GUI named `rpg-dialog`
|
|
220
|
-
*
|
|
221
|
-
* ```ts
|
|
222
|
-
* player.showText('Hello World')
|
|
223
|
-
* ```
|
|
224
|
-
*
|
|
225
|
-
* The method returns a promise. It is resolved when the dialog box is closed.
|
|
226
|
-
*
|
|
227
|
-
* ```ts
|
|
228
|
-
* await player.showText('Hello World')
|
|
229
|
-
* // dialog box is closed, then ...
|
|
230
|
-
* ```
|
|
231
|
-
*
|
|
232
|
-
* **Option: position**
|
|
233
|
-
*
|
|
234
|
-
* You can define how the dialog box is displayed:
|
|
235
|
-
* - top
|
|
236
|
-
* - middle
|
|
237
|
-
* - bottom
|
|
238
|
-
*
|
|
239
|
-
* (bottom by default)
|
|
240
|
-
*
|
|
241
|
-
* ```ts
|
|
242
|
-
* player.showText('Hello World', {
|
|
243
|
-
* position: 'top'
|
|
244
|
-
* })
|
|
245
|
-
* ```
|
|
246
|
-
*
|
|
247
|
-
* **Option: fullWidth**
|
|
248
|
-
*
|
|
249
|
-
* `boolean` (true by default)
|
|
250
|
-
*
|
|
251
|
-
* Indicate that the dialog box will take the full width of the screen.
|
|
252
|
-
*
|
|
253
|
-
* ```ts
|
|
254
|
-
* player.showText('Hello World', {
|
|
255
|
-
* fullWidth: true
|
|
256
|
-
* })
|
|
257
|
-
* ```
|
|
258
|
-
*
|
|
259
|
-
* **Option: autoClose**
|
|
260
|
-
*
|
|
261
|
-
* `boolean` (false by default)
|
|
262
|
-
*
|
|
263
|
-
* If false, the user will have to press Enter to close the dialog box.
|
|
264
|
-
*
|
|
265
|
-
* ```ts
|
|
266
|
-
* player.showText('Hello World', {
|
|
267
|
-
* autoClose: true
|
|
268
|
-
* })
|
|
269
|
-
* ```
|
|
270
|
-
*
|
|
271
|
-
* **Option: typewriterEffect**
|
|
272
|
-
*
|
|
273
|
-
* `boolean` (true by default)
|
|
274
|
-
*
|
|
275
|
-
* Performs a typewriter effect
|
|
276
|
-
*
|
|
277
|
-
* ```ts
|
|
278
|
-
* player.showText('Hello World', {
|
|
279
|
-
* typewriterEffect: false
|
|
280
|
-
* })
|
|
281
|
-
* ```
|
|
282
|
-
*
|
|
283
|
-
* **Option: talkWith**
|
|
284
|
-
*
|
|
285
|
-
* `RpgPlayer` (nothing by default)
|
|
286
|
-
*
|
|
287
|
-
* If you specify the event or another player, the other player will stop his or her movement and look in the player's direction.
|
|
288
|
-
*
|
|
289
|
-
* ```ts
|
|
290
|
-
* // Code in an event
|
|
291
|
-
* player.showText('Hello World', {
|
|
292
|
-
* talkWith: this
|
|
293
|
-
* })
|
|
294
|
-
* ```
|
|
295
|
-
*
|
|
296
|
-
* @title Show Text
|
|
297
|
-
* @method player.showText(text,options)
|
|
298
|
-
* @param {string} text
|
|
299
|
-
* @param {object} [options] the different options, see usage below
|
|
300
|
-
* @returns {Promise}
|
|
301
|
-
* @memberof GuiManager
|
|
302
|
-
*/
|
|
303
|
-
showText(msg: string, options?: DialogOptions): Promise<any>;
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Shows a dialog box with a choice. Opens the GUI named `rpg-dialog`
|
|
307
|
-
*
|
|
308
|
-
* ```ts
|
|
309
|
-
* const choice = await player.showChoices('What color do you prefer?', [
|
|
310
|
-
* { text: 'Black', value: 'black' },
|
|
311
|
-
* { text: 'Rather the blue', value: 'blue' },
|
|
312
|
-
* { text: 'I don\'t have a preference!', value: 'none' }
|
|
313
|
-
* ])
|
|
314
|
-
*
|
|
315
|
-
* // If the player selects the first
|
|
316
|
-
* console.log(choice) // { text: 'Black', value: 'black' }
|
|
317
|
-
* ```
|
|
318
|
-
*
|
|
319
|
-
* @title Show Choices
|
|
320
|
-
* @method player.showChoices(text,choices)
|
|
321
|
-
* @param {string} text
|
|
322
|
-
* @param {Array<{ text: string, value: any }>} choices
|
|
323
|
-
* @param {object} [options] Same options as the openDialog method
|
|
324
|
-
* @returns {Promise<Choice | null>}
|
|
325
|
-
* @memberof GuiManager
|
|
326
|
-
*/
|
|
327
|
-
showChoices(
|
|
328
|
-
msg: string,
|
|
329
|
-
choices: Choice[],
|
|
330
|
-
options?: DialogOptions
|
|
331
|
-
): Promise<Choice | null>;
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Displays a notification . Opens the GUI named `rpg-notification`
|
|
335
|
-
*
|
|
336
|
-
* @title Displays a notification
|
|
337
|
-
* @method player.showNotification()
|
|
338
|
-
* @param {string} message - The message to display in the notification
|
|
339
|
-
* @param {object} options - An object containing options for the notification
|
|
340
|
-
* @param {number} options.time - The time to display the notification for (in ms). Default: 2000ms
|
|
341
|
-
* @param {string} options.icon - The icon to display in the notification. Put the identifier of the spritesheet (defined on the client side)
|
|
342
|
-
* @param {string} options.sound - The sound to play when the notification is shown. Set the sound ID (defined on the client side)
|
|
343
|
-
* @returns {void}
|
|
344
|
-
* @memberof GuiManager
|
|
345
|
-
*/
|
|
346
|
-
showNotification(
|
|
347
|
-
message: string,
|
|
348
|
-
options?: { time?: number; icon?: string; sound?: string }
|
|
349
|
-
): Promise<any>;
|
|
350
|
-
/**
|
|
351
|
-
* Calls main menu. Opens the GUI named `rpg-main-menu`
|
|
352
|
-
*
|
|
353
|
-
* @title Call Main Menu
|
|
354
|
-
* @method player.callMainMenu()
|
|
355
|
-
* @returns {void}
|
|
356
|
-
* @memberof GuiManager
|
|
357
|
-
*/
|
|
358
|
-
callMainMenu(): void;
|
|
359
|
-
callShop(items: any[]): void;
|
|
360
|
-
gui(guiId: string): Gui;
|
|
361
|
-
removeGui(guiId: string, data?: any): void;
|
|
362
|
-
showAttachedGui(players?: RpgPlayer[] | RpgPlayer): void;
|
|
363
|
-
hideAttachedGui(players?: RpgPlayer[] | RpgPlayer): void;
|
|
316
|
+
};
|
|
364
317
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ItemInstance } from "@rpgjs/database";
|
|
2
|
-
import {
|
|
2
|
+
import { RpgCommonPlayer, type Constructor } from "@rpgjs/common";
|
|
3
|
+
export class ItemFixture {}
|
|
3
4
|
|
|
4
|
-
export function WithItemFixture<TBase extends
|
|
5
|
+
export function WithItemFixture<TBase extends Constructor<RpgCommonPlayer>>(
|
|
5
6
|
Base: TBase
|
|
6
7
|
) {
|
|
7
|
-
return class extends Base {
|
|
8
|
+
return class extends Base implements IItemFixture {
|
|
8
9
|
protected getFeature(name, prop): any {
|
|
9
10
|
const array = {};
|
|
10
11
|
for (let item of this.equipments()) {
|
|
@@ -20,7 +21,7 @@ export function WithItemFixture<TBase extends PlayerCtor>(
|
|
|
20
21
|
}
|
|
21
22
|
return Object.values(array);
|
|
22
23
|
}
|
|
23
|
-
}
|
|
24
|
+
};
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export interface ItemFixture {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isInstanceOf, isString, Item,
|
|
1
|
+
import { isInstanceOf, isString, Item, type Constructor } from "@rpgjs/common";
|
|
2
2
|
import { RpgCommonPlayer, Matter } from "@rpgjs/common";
|
|
3
3
|
import { ATK, PDEF, SDEF } from "../presets";
|
|
4
4
|
import { ItemLog } from "../logs";
|
|
@@ -13,34 +13,27 @@ enum ClassHooks {
|
|
|
13
13
|
canEquip = 'canEquip'
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Interface defining what MoveManager adds to a class
|
|
18
|
+
*/
|
|
19
|
+
export interface IItemManager {
|
|
20
|
+
databaseById(id: string): ItemClass;
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
type Inventory = { nb: number; item: ItemInstance };
|
|
17
24
|
|
|
18
25
|
/**
|
|
19
|
-
*
|
|
26
|
+
* Move Manager mixin
|
|
20
27
|
*
|
|
21
|
-
*
|
|
22
|
-
* inventory management, item usage, equipment, buying/selling, and item effects.
|
|
23
|
-
* It manages the complete item system including restrictions, transactions, and equipment.
|
|
28
|
+
* Adds methods to manage player movement
|
|
24
29
|
*
|
|
25
|
-
* @param Base - The base class to extend
|
|
26
|
-
* @returns
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* class MyPlayer extends WithItemManager(BasePlayer) {
|
|
31
|
-
* constructor() {
|
|
32
|
-
* super();
|
|
33
|
-
* // Item system is automatically initialized
|
|
34
|
-
* }
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* const player = new MyPlayer();
|
|
38
|
-
* player.addItem('potion', 5);
|
|
39
|
-
* player.useItem('potion');
|
|
40
|
-
* ```
|
|
30
|
+
* @param Base - The base class to extend
|
|
31
|
+
* @returns A new class with move management capabilities
|
|
41
32
|
*/
|
|
42
|
-
export function WithItemManager<TBase extends
|
|
43
|
-
|
|
33
|
+
export function WithItemManager<TBase extends Constructor<RpgCommonPlayer>>(
|
|
34
|
+
Base: TBase
|
|
35
|
+
): Constructor<IItemManager> & TBase {
|
|
36
|
+
return class extends Base implements IItemManager {
|
|
44
37
|
|
|
45
38
|
/**
|
|
46
39
|
* Retrieves the information of an object: the number and the instance
|
|
@@ -61,7 +54,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
61
54
|
*/
|
|
62
55
|
getItem(itemClass: ItemClass | string): Item {
|
|
63
56
|
const index: number = this._getItemIndex(itemClass);
|
|
64
|
-
return
|
|
57
|
+
return this.items()[index];
|
|
65
58
|
}
|
|
66
59
|
|
|
67
60
|
/**
|
|
@@ -84,7 +77,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
84
77
|
}
|
|
85
78
|
|
|
86
79
|
_getItemIndex(itemClass: ItemClass | string): number {
|
|
87
|
-
return
|
|
80
|
+
return this.items().findIndex((it: Item): boolean => {
|
|
88
81
|
if (isString(itemClass)) {
|
|
89
82
|
return it.id() == itemClass;
|
|
90
83
|
}
|
|
@@ -110,8 +103,8 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
110
103
|
* ```
|
|
111
104
|
*/
|
|
112
105
|
addItem(itemId: string, nb: number = 1): Item {
|
|
113
|
-
const data =
|
|
114
|
-
const item =
|
|
106
|
+
const data = this.databaseById(itemId);
|
|
107
|
+
const item = this.items().find((it) => it.id() == itemId);
|
|
115
108
|
let instance: Item;
|
|
116
109
|
if (item) {
|
|
117
110
|
instance = item;
|
|
@@ -119,9 +112,9 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
119
112
|
} else {
|
|
120
113
|
instance = new Item(data);
|
|
121
114
|
instance.id.set(itemId);
|
|
122
|
-
|
|
115
|
+
this.items().push(instance);
|
|
123
116
|
}
|
|
124
|
-
|
|
117
|
+
this["execMethod"]("onAdd", [this], instance);
|
|
125
118
|
return instance;
|
|
126
119
|
}
|
|
127
120
|
|
|
@@ -217,7 +210,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
217
210
|
* ```
|
|
218
211
|
*/
|
|
219
212
|
buyItem(itemId: string, nb = 1): Item {
|
|
220
|
-
const data =
|
|
213
|
+
const data = this.databaseById(itemId);
|
|
221
214
|
if (!data.price) {
|
|
222
215
|
throw ItemLog.haveNotPrice(itemId);
|
|
223
216
|
}
|
|
@@ -279,7 +272,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
279
272
|
* ```
|
|
280
273
|
*/
|
|
281
274
|
sellItem(itemId: string, nbToSell = 1): Item {
|
|
282
|
-
const data =
|
|
275
|
+
const data = this.databaseById(itemId);
|
|
283
276
|
const inventory = this.getItem(itemId);
|
|
284
277
|
if (!inventory) {
|
|
285
278
|
throw ItemLog.notInInventory(itemId);
|
|
@@ -485,7 +478,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
485
478
|
if (!inventory) {
|
|
486
479
|
throw ItemLog.notInInventory(itemId);
|
|
487
480
|
}
|
|
488
|
-
const data =
|
|
481
|
+
const data = this.databaseById(itemId);
|
|
489
482
|
if (data._type == "item") {
|
|
490
483
|
throw ItemLog.invalidToEquiped(itemId);
|
|
491
484
|
}
|
|
@@ -515,11 +508,5 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
515
508
|
}
|
|
516
509
|
this["execMethod"]("onEquip", [this, equip], item);
|
|
517
510
|
}
|
|
518
|
-
}
|
|
511
|
+
};
|
|
519
512
|
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Type helper to extract the interface from the WithItemManager mixin
|
|
523
|
-
* This provides the type without duplicating method signatures
|
|
524
|
-
*/
|
|
525
|
-
export type IItemManager = InstanceType<ReturnType<typeof WithItemManager>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type Constructor } from "@rpgjs/common";
|
|
2
2
|
import { RpgCommonPlayer, Matter, Direction } from "@rpgjs/common";
|
|
3
3
|
import {
|
|
4
4
|
MovementManager,
|
|
@@ -34,7 +34,26 @@ interface PlayerWithMixins extends RpgCommonPlayer {
|
|
|
34
34
|
changeDirection: (direction: Direction) => boolean;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
export interface IMoveManager {
|
|
38
|
+
addMovement(strategy: MovementStrategy): void;
|
|
39
|
+
removeMovement(strategy: MovementStrategy): boolean;
|
|
40
|
+
clearMovements(): void;
|
|
41
|
+
hasActiveMovements(): boolean;
|
|
42
|
+
getActiveMovements(): MovementStrategy[];
|
|
43
|
+
|
|
44
|
+
moveTo(target: RpgCommonPlayer | { x: number, y: number }): void;
|
|
45
|
+
stopMoveTo(): void;
|
|
46
|
+
dash(direction: { x: number, y: number }, speed?: number, duration?: number): void;
|
|
47
|
+
knockback(direction: { x: number, y: number }, force?: number, duration?: number): void;
|
|
48
|
+
followPath(waypoints: Array<{ x: number, y: number }>, speed?: number, loop?: boolean): void;
|
|
49
|
+
oscillate(direction: { x: number, y: number }, amplitude?: number, period?: number): void;
|
|
50
|
+
applyIceMovement(direction: { x: number, y: number }, maxSpeed?: number): void;
|
|
51
|
+
shootProjectile(type: ProjectileType, direction: { x: number, y: number }, speed?: number): void;
|
|
52
|
+
moveRoutes(routes: Routes): Promise<boolean>;
|
|
53
|
+
infiniteMoveRoute(routes: Routes): void;
|
|
54
|
+
breakRoutes(force?: boolean): void;
|
|
55
|
+
replayRoutes(): void;
|
|
56
|
+
}
|
|
38
57
|
|
|
39
58
|
|
|
40
59
|
function wait(sec: number) {
|
|
@@ -456,37 +475,15 @@ export const Move = new MoveList();
|
|
|
456
475
|
* }
|
|
457
476
|
* ```
|
|
458
477
|
*/
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
* various types of movement including pathfinding, physics-based movement, route following,
|
|
464
|
-
* and advanced movement strategies like dashing, knockback, and projectile movement.
|
|
465
|
-
*
|
|
466
|
-
* @param Base - The base class to extend with movement management
|
|
467
|
-
* @returns Extended class with movement management methods
|
|
468
|
-
*
|
|
469
|
-
* @example
|
|
470
|
-
* ```ts
|
|
471
|
-
* class MyPlayer extends WithMoveManager(BasePlayer) {
|
|
472
|
-
* constructor() {
|
|
473
|
-
* super();
|
|
474
|
-
* this.frequency = Frequency.High;
|
|
475
|
-
* }
|
|
476
|
-
* }
|
|
477
|
-
*
|
|
478
|
-
* const player = new MyPlayer();
|
|
479
|
-
* player.moveTo({ x: 100, y: 100 });
|
|
480
|
-
* player.dash({ x: 1, y: 0 }, 8, 200);
|
|
481
|
-
* ```
|
|
482
|
-
*/
|
|
483
|
-
export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
484
|
-
return class extends Base {
|
|
478
|
+
export function WithMoveManager<TBase extends Constructor<RpgCommonPlayer>>(
|
|
479
|
+
Base: TBase
|
|
480
|
+
): Constructor<IMoveManager> & TBase {
|
|
481
|
+
return class extends Base implements IMoveManager {
|
|
485
482
|
|
|
486
|
-
//
|
|
487
|
-
_infiniteRoutes: Routes | null = null;
|
|
488
|
-
_finishRoute: ((value: boolean) => void) | null = null;
|
|
489
|
-
_isInfiniteRouteActive: boolean = false;
|
|
483
|
+
// Private properties for infinite route management
|
|
484
|
+
private _infiniteRoutes: Routes | null = null;
|
|
485
|
+
private _finishRoute: ((value: boolean) => void) | null = null;
|
|
486
|
+
private _isInfiniteRouteActive: boolean = false;
|
|
490
487
|
|
|
491
488
|
/**
|
|
492
489
|
* The player passes through the other players (or vice versa). But the player does not go through the events.
|
|
@@ -1100,7 +1097,7 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1100
1097
|
* @param routes - Routes array that may contain nested arrays
|
|
1101
1098
|
* @returns Flattened array of routes
|
|
1102
1099
|
*/
|
|
1103
|
-
flattenRoutes(routes: any[]): any[] {
|
|
1100
|
+
private flattenRoutes(routes: any[]): any[] {
|
|
1104
1101
|
const result: any[] = [];
|
|
1105
1102
|
|
|
1106
1103
|
for (const route of routes) {
|
|
@@ -1244,11 +1241,5 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1244
1241
|
this.infiniteMoveRoute(this._infiniteRoutes);
|
|
1245
1242
|
}
|
|
1246
1243
|
}
|
|
1247
|
-
}
|
|
1244
|
+
};
|
|
1248
1245
|
}
|
|
1249
|
-
|
|
1250
|
-
/**
|
|
1251
|
-
* Type helper to extract the interface from the WithMoveManager mixin
|
|
1252
|
-
* This provides the type without duplicating method signatures
|
|
1253
|
-
*/
|
|
1254
|
-
export type IMoveManager = InstanceType<ReturnType<typeof WithMoveManager>>;
|