@rpgjs/server 5.0.0-alpha.0 → 5.0.0-alpha.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.
- package/dist/Player/BattleManager.d.ts +32 -22
- package/dist/Player/ClassManager.d.ts +31 -18
- package/dist/Player/ComponentManager.d.ts +60 -0
- package/dist/Player/EffectManager.d.ts +40 -0
- package/dist/Player/ElementManager.d.ts +31 -0
- package/dist/Player/GoldManager.d.ts +22 -0
- package/dist/Player/GuiManager.d.ts +176 -0
- package/dist/Player/ItemFixture.d.ts +6 -0
- package/dist/Player/ItemManager.d.ts +27 -13
- package/dist/Player/MoveManager.d.ts +31 -43
- package/dist/Player/ParameterManager.d.ts +27 -19
- package/dist/Player/Player.d.ts +123 -8
- package/dist/Player/SkillManager.d.ts +27 -19
- package/dist/Player/StateManager.d.ts +28 -35
- package/dist/Player/VariableManager.d.ts +30 -0
- package/dist/RpgServer.d.ts +224 -1
- package/dist/index.js +1097 -636
- package/dist/index.js.map +1 -1
- package/dist/rooms/map.d.ts +70 -1
- package/package.json +8 -8
- package/src/Player/BattleManager.ts +97 -38
- package/src/Player/ClassManager.ts +95 -35
- package/src/Player/ComponentManager.ts +64 -20
- package/src/Player/EffectManager.ts +110 -27
- package/src/Player/ElementManager.ts +126 -25
- package/src/Player/GoldManager.ts +32 -35
- package/src/Player/GuiManager.ts +187 -140
- package/src/Player/ItemFixture.ts +4 -5
- package/src/Player/ItemManager.ts +39 -26
- package/src/Player/MoveManager.ts +40 -31
- package/src/Player/ParameterManager.ts +35 -25
- package/src/Player/Player.ts +184 -39
- package/src/Player/SkillManager.ts +44 -23
- package/src/Player/StateManager.ts +210 -95
- package/src/Player/VariableManager.ts +180 -48
- package/src/RpgServer.ts +232 -1
- package/src/core/context.ts +1 -0
- package/src/rooms/map.ts +76 -8
- package/dist/Player/Event.d.ts +0 -0
- package/src/Player/Event.ts +0 -0
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isString, PlayerCtor } from "@rpgjs/common";
|
|
2
2
|
import { MAXHP, MAXSP } from "../presets";
|
|
3
3
|
|
|
4
|
-
export interface IWithParameterManager {
|
|
5
|
-
parameters: Map<string, any>
|
|
6
|
-
hp: number
|
|
7
|
-
sp: number
|
|
8
|
-
exp: number
|
|
9
|
-
level: number
|
|
10
|
-
expForNextlevel: number
|
|
11
|
-
param: { [key: string]: number }
|
|
12
|
-
paramsModifier: { [key: string]: { value?: number, rate?: number } }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface PlayerWithMixins extends RpgCommonPlayer {
|
|
16
|
-
databaseById?(id: string): any;
|
|
17
|
-
}
|
|
18
4
|
|
|
19
5
|
/**
|
|
20
6
|
* Mixin that adds parameter management functionality to a player class.
|
|
@@ -39,18 +25,40 @@ interface PlayerWithMixins extends RpgCommonPlayer {
|
|
|
39
25
|
* }
|
|
40
26
|
* ```
|
|
41
27
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Parameter Manager Mixin
|
|
30
|
+
*
|
|
31
|
+
* Provides comprehensive parameter management functionality to any class. This mixin handles
|
|
32
|
+
* health points (HP), skill points (SP), experience and level progression, custom parameters,
|
|
33
|
+
* and parameter modifiers for temporary stat changes.
|
|
34
|
+
*
|
|
35
|
+
* @param Base - The base class to extend with parameter management
|
|
36
|
+
* @returns Extended class with parameter management methods
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* class MyPlayer extends WithParameterManager(BasePlayer) {
|
|
41
|
+
* constructor() {
|
|
42
|
+
* super();
|
|
43
|
+
* this.addParameter('strength', { start: 10, end: 100 });
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* const player = new MyPlayer();
|
|
48
|
+
* player.hp = 100;
|
|
49
|
+
* player.level = 5;
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function WithParameterManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
53
|
+
return class extends Base {
|
|
54
|
+
_paramsModifier: {
|
|
47
55
|
[key: string]: {
|
|
48
56
|
value?: number,
|
|
49
57
|
rate?: number
|
|
50
58
|
}
|
|
51
59
|
} = {}
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
_parameters: Map<string, {
|
|
54
62
|
start: number,
|
|
55
63
|
end: number
|
|
56
64
|
}> = new Map()
|
|
@@ -127,11 +135,11 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
|
|
|
127
135
|
this['execMethod']('onDead')
|
|
128
136
|
val = 0
|
|
129
137
|
}
|
|
130
|
-
this._hp.set(val)
|
|
138
|
+
(this as any)._hp.set(val)
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
get hp(): number {
|
|
134
|
-
return this._hp()
|
|
142
|
+
return (this as any)._hp()
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
/**
|
|
@@ -497,5 +505,7 @@ export function WithParameterManager<TBase extends Constructor<RpgCommonPlayer>>
|
|
|
497
505
|
allRecovery(): void {
|
|
498
506
|
this.recovery({ hp: 1, sp: 1 })
|
|
499
507
|
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
508
|
+
} as unknown as TBase;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export type IParameterManager = InstanceType<ReturnType<typeof WithParameterManager>>;
|
package/src/Player/Player.ts
CHANGED
|
@@ -5,33 +5,42 @@ import {
|
|
|
5
5
|
RpgCommonPlayer,
|
|
6
6
|
ShowAnimationParams,
|
|
7
7
|
Constructor,
|
|
8
|
-
ZoneOptions,
|
|
9
8
|
} from "@rpgjs/common";
|
|
10
|
-
import {
|
|
9
|
+
import { IComponentManager, WithComponentManager } from "./ComponentManager";
|
|
11
10
|
import { RpgMap } from "../rooms/map";
|
|
12
11
|
import { Context, inject } from "@signe/di";
|
|
13
12
|
import { IGuiManager, WithGuiManager } from "./GuiManager";
|
|
14
13
|
import { MockConnection } from "@signe/room";
|
|
15
14
|
import { IMoveManager, WithMoveManager } from "./MoveManager";
|
|
16
15
|
import { IGoldManager, WithGoldManager } from "./GoldManager";
|
|
17
|
-
import {
|
|
16
|
+
import { WithVariableManager, type IVariableManager } from "./VariableManager";
|
|
18
17
|
import { sync } from "@signe/sync";
|
|
19
18
|
import { signal } from "@signe/reactive";
|
|
20
19
|
import {
|
|
21
|
-
|
|
20
|
+
IParameterManager,
|
|
22
21
|
WithParameterManager,
|
|
23
22
|
} from "./ParameterManager";
|
|
24
23
|
import { WithItemFixture } from "./ItemFixture";
|
|
25
|
-
import {
|
|
26
|
-
import { WithItemManager } from "./ItemManager";
|
|
24
|
+
import { IItemManager, WithItemManager } from "./ItemManager";
|
|
27
25
|
import { lastValueFrom } from "rxjs";
|
|
28
|
-
import {
|
|
29
|
-
import { WithEffectManager } from "./EffectManager";
|
|
30
|
-
import { WithSkillManager, IWithSkillManager } from "./SkillManager";
|
|
26
|
+
import { IEffectManager, WithEffectManager } from "./EffectManager";
|
|
31
27
|
import { AGI, AGI_CURVE, DEX, DEX_CURVE, INT, INT_CURVE, MAXHP, MAXHP_CURVE, MAXSP, MAXSP_CURVE, STR, STR_CURVE } from "../presets";
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
28
|
+
import { IElementManager, WithElementManager } from "./ElementManager";
|
|
29
|
+
import { ISkillManager, WithSkillManager } from "./SkillManager";
|
|
30
|
+
import { IBattleManager, WithBattleManager } from "./BattleManager";
|
|
31
|
+
import { IClassManager, WithClassManager } from "./ClassManager";
|
|
32
|
+
import { IStateManager, WithStateManager } from "./StateManager";
|
|
34
33
|
|
|
34
|
+
// Local interface for ZoneOptions to avoid import issues
|
|
35
|
+
interface ZoneOptions {
|
|
36
|
+
x?: number;
|
|
37
|
+
y?: number;
|
|
38
|
+
radius: number;
|
|
39
|
+
angle?: number;
|
|
40
|
+
direction?: any;
|
|
41
|
+
linkedTo?: string;
|
|
42
|
+
limitedByWalls?: boolean;
|
|
43
|
+
}
|
|
35
44
|
|
|
36
45
|
/**
|
|
37
46
|
* Combines multiple RpgCommonPlayer mixins into one
|
|
@@ -46,27 +55,44 @@ function combinePlayerMixins<T extends Constructor<RpgCommonPlayer>>(
|
|
|
46
55
|
mixins.reduce((ExtendedClass, mixin) => mixin(ExtendedClass), Base);
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
// Start with basic mixins that work
|
|
59
|
+
const BasicPlayerMixins = combinePlayerMixins([
|
|
50
60
|
WithComponentManager,
|
|
51
61
|
WithEffectManager,
|
|
52
62
|
WithGuiManager,
|
|
53
63
|
WithMoveManager,
|
|
54
64
|
WithGoldManager,
|
|
55
|
-
WithVariableManager,
|
|
56
65
|
WithParameterManager,
|
|
57
66
|
WithItemFixture,
|
|
58
|
-
WithStateManager,
|
|
59
67
|
WithItemManager,
|
|
60
|
-
|
|
68
|
+
WithElementManager,
|
|
69
|
+
WithVariableManager,
|
|
70
|
+
WithStateManager,
|
|
61
71
|
WithClassManager,
|
|
72
|
+
WithSkillManager,
|
|
62
73
|
WithBattleManager,
|
|
63
|
-
WithElementManager,
|
|
64
74
|
]);
|
|
65
75
|
|
|
66
76
|
/**
|
|
67
77
|
* RPG Player class with component management capabilities
|
|
78
|
+
*
|
|
79
|
+
* Combines all player mixins to provide a complete player implementation
|
|
80
|
+
* with graphics, movement, inventory, skills, and battle capabilities.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* // Create a new player
|
|
85
|
+
* const player = new RpgPlayer();
|
|
86
|
+
*
|
|
87
|
+
* // Set player graphics
|
|
88
|
+
* player.setGraphic("hero");
|
|
89
|
+
*
|
|
90
|
+
* // Add parameters and items
|
|
91
|
+
* player.addParameter("strength", { start: 10, end: 100 });
|
|
92
|
+
* player.addItem(sword);
|
|
93
|
+
* ```
|
|
68
94
|
*/
|
|
69
|
-
export class RpgPlayer extends
|
|
95
|
+
export class RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
|
|
70
96
|
map: RpgMap | null = null;
|
|
71
97
|
context?: Context;
|
|
72
98
|
conn: MockConnection | null = null;
|
|
@@ -75,20 +101,21 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
75
101
|
|
|
76
102
|
constructor() {
|
|
77
103
|
super();
|
|
78
|
-
|
|
104
|
+
// Use type assertion to access mixin properties
|
|
105
|
+
(this as any).expCurve = {
|
|
79
106
|
basis: 30,
|
|
80
107
|
extra: 20,
|
|
81
108
|
accelerationA: 30,
|
|
82
109
|
accelerationB: 30
|
|
83
|
-
}
|
|
110
|
+
};
|
|
84
111
|
|
|
85
|
-
this.addParameter(MAXHP, MAXHP_CURVE)
|
|
86
|
-
this.addParameter(MAXSP, MAXSP_CURVE)
|
|
87
|
-
this.addParameter(STR, STR_CURVE)
|
|
88
|
-
this.addParameter(INT, INT_CURVE)
|
|
89
|
-
this.addParameter(DEX, DEX_CURVE)
|
|
90
|
-
this.addParameter(AGI, AGI_CURVE)
|
|
91
|
-
this.allRecovery()
|
|
112
|
+
(this as any).addParameter(MAXHP, MAXHP_CURVE);
|
|
113
|
+
(this as any).addParameter(MAXSP, MAXSP_CURVE);
|
|
114
|
+
(this as any).addParameter(STR, STR_CURVE);
|
|
115
|
+
(this as any).addParameter(INT, INT_CURVE);
|
|
116
|
+
(this as any).addParameter(DEX, DEX_CURVE);
|
|
117
|
+
(this as any).addParameter(AGI, AGI_CURVE);
|
|
118
|
+
(this as any).allRecovery();
|
|
92
119
|
}
|
|
93
120
|
|
|
94
121
|
async execMethod(method: string, methodData: any[] = [], target?: any) {
|
|
@@ -151,7 +178,50 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
151
178
|
});
|
|
152
179
|
}
|
|
153
180
|
|
|
154
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Set the current animation of the player's sprite
|
|
183
|
+
*
|
|
184
|
+
* This method changes the animation state of the player's current sprite.
|
|
185
|
+
* It's used to trigger character animations like attack, skill, or custom movements.
|
|
186
|
+
* When `nbTimes` is set to a finite number, the animation will play that many times
|
|
187
|
+
* before returning to the previous animation state.
|
|
188
|
+
*
|
|
189
|
+
* @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk')
|
|
190
|
+
* @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* // Set continuous walk animation
|
|
195
|
+
* player.setAnimation('walk');
|
|
196
|
+
*
|
|
197
|
+
* // Play attack animation 3 times then return to previous state
|
|
198
|
+
* player.setAnimation('attack', 3);
|
|
199
|
+
*
|
|
200
|
+
* // Play skill animation once
|
|
201
|
+
* player.setAnimation('skill', 1);
|
|
202
|
+
*
|
|
203
|
+
* // Set idle/stand animation
|
|
204
|
+
* player.setAnimation('stand');
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
setAnimation(animationName: string, nbTimes: number = Infinity) {
|
|
208
|
+
const map = this.getCurrentMap();
|
|
209
|
+
if (!map) return;
|
|
210
|
+
if (nbTimes === Infinity) {
|
|
211
|
+
this.animationName.set(animationName);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
map.$broadcast({
|
|
215
|
+
type: "setAnimation",
|
|
216
|
+
value: {
|
|
217
|
+
animationName,
|
|
218
|
+
nbTimes,
|
|
219
|
+
object: this.id,
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
155
225
|
|
|
156
226
|
/**
|
|
157
227
|
* Run the change detection cycle. Normally, as soon as a hook is called in a class, the cycle is started. But you can start it manually
|
|
@@ -228,11 +298,35 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
228
298
|
);
|
|
229
299
|
}
|
|
230
300
|
|
|
231
|
-
|
|
301
|
+
/**
|
|
302
|
+
* Show a temporary component animation on this player
|
|
303
|
+
*
|
|
304
|
+
* This method broadcasts a component animation to all clients, allowing
|
|
305
|
+
* temporary visual effects like hit indicators, spell effects, or status animations
|
|
306
|
+
* to be displayed on the player.
|
|
307
|
+
*
|
|
308
|
+
* @param id - The ID of the component animation to display
|
|
309
|
+
* @param params - Parameters to pass to the component animation
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```ts
|
|
313
|
+
* // Show a hit animation with damage text
|
|
314
|
+
* player.showComponentAnimation("hit", {
|
|
315
|
+
* text: "150",
|
|
316
|
+
* color: "red"
|
|
317
|
+
* });
|
|
318
|
+
*
|
|
319
|
+
* // Show a heal animation
|
|
320
|
+
* player.showComponentAnimation("heal", {
|
|
321
|
+
* amount: 50
|
|
322
|
+
* });
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
showComponentAnimation(id: string, params: any) {
|
|
232
326
|
const map = this.getCurrentMap();
|
|
233
327
|
if (!map) return;
|
|
234
328
|
map.$broadcast({
|
|
235
|
-
type: "
|
|
329
|
+
type: "showComponentAnimation",
|
|
236
330
|
value: {
|
|
237
331
|
id,
|
|
238
332
|
params,
|
|
@@ -241,8 +335,46 @@ export class RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
241
335
|
});
|
|
242
336
|
}
|
|
243
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Display a spritesheet animation on the player
|
|
340
|
+
*
|
|
341
|
+
* This method displays a temporary visual animation using a spritesheet.
|
|
342
|
+
* The animation can either be displayed as an overlay on the player or replace
|
|
343
|
+
* the player's current graphic temporarily. This is useful for spell effects,
|
|
344
|
+
* transformations, or other visual feedback that uses predefined spritesheets.
|
|
345
|
+
*
|
|
346
|
+
* @param graphic - The ID of the spritesheet to use for the animation
|
|
347
|
+
* @param animationName - The name of the animation within the spritesheet (default: 'default')
|
|
348
|
+
* @param replaceGraphic - Whether to replace the player's sprite with the animation (default: false)
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```ts
|
|
352
|
+
* // Show explosion animation as overlay on player
|
|
353
|
+
* player.showAnimation("explosion");
|
|
354
|
+
*
|
|
355
|
+
* // Show specific spell effect animation
|
|
356
|
+
* player.showAnimation("spell-effects", "fireball");
|
|
357
|
+
*
|
|
358
|
+
* // Transform player graphic temporarily with animation
|
|
359
|
+
* player.showAnimation("transformation", "werewolf", true);
|
|
360
|
+
*
|
|
361
|
+
* // Show healing effect on player
|
|
362
|
+
* player.showAnimation("healing-effects", "holy-light");
|
|
363
|
+
* ```
|
|
364
|
+
*/
|
|
365
|
+
showAnimation(graphic: string, animationName: string = 'default', replaceGraphic: boolean = false) {
|
|
366
|
+
if (replaceGraphic) {
|
|
367
|
+
this.setAnimation(animationName, 1);
|
|
368
|
+
return
|
|
369
|
+
}
|
|
370
|
+
this.showComponentAnimation("animation", {
|
|
371
|
+
graphic,
|
|
372
|
+
animationName,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
244
376
|
showHit(text: string) {
|
|
245
|
-
this.
|
|
377
|
+
this.showComponentAnimation("hit", {
|
|
246
378
|
text,
|
|
247
379
|
direction: this.direction(),
|
|
248
380
|
});
|
|
@@ -268,12 +400,25 @@ export class RpgEvent extends RpgPlayer {
|
|
|
268
400
|
}
|
|
269
401
|
}
|
|
270
402
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Interface extension for RpgPlayer
|
|
406
|
+
*
|
|
407
|
+
* Extends the RpgPlayer class with additional interfaces from mixins.
|
|
408
|
+
* This provides proper TypeScript support for all mixin methods and properties.
|
|
409
|
+
*/
|
|
410
|
+
export interface RpgPlayer extends
|
|
411
|
+
IVariableManager,
|
|
412
|
+
IMoveManager,
|
|
413
|
+
IGoldManager,
|
|
414
|
+
IComponentManager,
|
|
415
|
+
IGuiManager,
|
|
416
|
+
IItemManager,
|
|
417
|
+
IEffectManager,
|
|
418
|
+
IParameterManager,
|
|
419
|
+
IElementManager,
|
|
420
|
+
ISkillManager,
|
|
421
|
+
IBattleManager,
|
|
422
|
+
IClassManager,
|
|
423
|
+
IStateManager
|
|
424
|
+
{}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
isArray,
|
|
4
4
|
isInstanceOf,
|
|
5
5
|
isString,
|
|
6
|
+
PlayerCtor,
|
|
6
7
|
RpgCommonPlayer,
|
|
7
8
|
} from "@rpgjs/common";
|
|
8
9
|
import { SkillLog } from "../logs";
|
|
@@ -20,22 +21,36 @@ interface SkillManagerDependencies {
|
|
|
20
21
|
applyStates(player: RpgPlayer, skill: any): void;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
|
|
25
|
+
|
|
23
26
|
/**
|
|
24
|
-
*
|
|
27
|
+
* Skill Manager Mixin
|
|
28
|
+
*
|
|
29
|
+
* Provides skill management capabilities to any class. This mixin handles
|
|
30
|
+
* learning, forgetting, and using skills, including SP cost management,
|
|
31
|
+
* hit rate calculations, and skill effects application.
|
|
32
|
+
*
|
|
33
|
+
* @param Base - The base class to extend with skill management
|
|
34
|
+
* @returns Extended class with skill management methods
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* class MyPlayer extends WithSkillManager(BasePlayer) {
|
|
39
|
+
* constructor() {
|
|
40
|
+
* super();
|
|
41
|
+
* // Skill system is automatically initialized
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* const player = new MyPlayer();
|
|
46
|
+
* player.learnSkill(Fire);
|
|
47
|
+
* player.useSkill(Fire, targetPlayer);
|
|
48
|
+
* ```
|
|
25
49
|
*/
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
useSkill(skillId: any | string, otherPlayer?: RpgPlayer | RpgPlayer[]): any;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & SkillManagerDependencies>>(
|
|
34
|
-
Base: TBase
|
|
35
|
-
): Constructor<IWithSkillManager> & TBase {
|
|
36
|
-
return class extends Base implements IWithSkillManager {
|
|
37
|
-
private _getSkillIndex(skillClass: any | string) {
|
|
38
|
-
return this.skills().findIndex((skill) => {
|
|
50
|
+
export function WithSkillManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
51
|
+
return class extends Base {
|
|
52
|
+
_getSkillIndex(skillClass: any | string) {
|
|
53
|
+
return (this as any).skills().findIndex((skill) => {
|
|
39
54
|
if (isString(skill)) {
|
|
40
55
|
return skill.id == skillClass;
|
|
41
56
|
}
|
|
@@ -94,7 +109,7 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
|
|
|
94
109
|
if (this.getSkill(skillId)) {
|
|
95
110
|
throw SkillLog.alreadyLearned(skillId);
|
|
96
111
|
}
|
|
97
|
-
const instance = this.databaseById(skillId);
|
|
112
|
+
const instance = (this as any).databaseById(skillId);
|
|
98
113
|
this.skills().push(instance);
|
|
99
114
|
this["execMethod"]("onLearn", [this], instance);
|
|
100
115
|
return instance;
|
|
@@ -131,7 +146,7 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
|
|
|
131
146
|
* @memberof SkillManager
|
|
132
147
|
*/
|
|
133
148
|
forgetSkill(skillId: any | string) {
|
|
134
|
-
if (isString(skillId)) skillId = this.databaseById(skillId);
|
|
149
|
+
if (isString(skillId)) skillId = (this as any).databaseById(skillId);
|
|
135
150
|
const index = this._getSkillIndex(skillId);
|
|
136
151
|
if (index == -1) {
|
|
137
152
|
throw SkillLog.notLearned(skillId);
|
|
@@ -219,16 +234,16 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
|
|
|
219
234
|
*/
|
|
220
235
|
useSkill(skillId: any | string, otherPlayer?: RpgPlayer | RpgPlayer[]) {
|
|
221
236
|
const skill = this.getSkill(skillId);
|
|
222
|
-
if (this.hasEffect(Effect.CAN_NOT_SKILL)) {
|
|
237
|
+
if ((this as any).hasEffect(Effect.CAN_NOT_SKILL)) {
|
|
223
238
|
throw SkillLog.restriction(skillId);
|
|
224
239
|
}
|
|
225
240
|
if (!skill) {
|
|
226
241
|
throw SkillLog.notLearned(skillId);
|
|
227
242
|
}
|
|
228
|
-
if (skill.spCost > this.sp) {
|
|
229
|
-
throw SkillLog.notEnoughSp(skillId, skill.spCost, this.sp);
|
|
243
|
+
if (skill.spCost > (this as any).sp) {
|
|
244
|
+
throw SkillLog.notEnoughSp(skillId, skill.spCost, (this as any).sp);
|
|
230
245
|
}
|
|
231
|
-
this.sp -= skill.spCost / (this.hasEffect(Effect.HALF_SP_COST) ? 2 : 1);
|
|
246
|
+
(this as any).sp -= skill.spCost / ((this as any).hasEffect(Effect.HALF_SP_COST) ? 2 : 1);
|
|
232
247
|
const hitRate = skill.hitRate ?? 1;
|
|
233
248
|
if (Math.random() > hitRate) {
|
|
234
249
|
this["execMethod"]("onUseFailed", [this, otherPlayer], skill);
|
|
@@ -240,12 +255,18 @@ export function WithSkillManager<TBase extends Constructor<RpgCommonPlayer & Ski
|
|
|
240
255
|
players = [otherPlayer];
|
|
241
256
|
}
|
|
242
257
|
for (let player of players) {
|
|
243
|
-
this.applyStates(player, skill);
|
|
244
|
-
player.applyDamage(this, skill);
|
|
258
|
+
(this as any).applyStates(player, skill);
|
|
259
|
+
(player as any).applyDamage(this, skill);
|
|
245
260
|
}
|
|
246
261
|
}
|
|
247
262
|
this["execMethod"]("onUse", [this, otherPlayer], skill);
|
|
248
263
|
return skill;
|
|
249
264
|
}
|
|
250
|
-
};
|
|
265
|
+
} as unknown as TBase;
|
|
251
266
|
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Type helper to extract the interface from the WithSkillManager mixin
|
|
270
|
+
* This provides the type without duplicating method signatures
|
|
271
|
+
*/
|
|
272
|
+
export type ISkillManager = InstanceType<ReturnType<typeof WithSkillManager>>;
|