@rpgjs/action-battle 5.0.0-beta.1 → 5.0.0-beta.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/LICENSE +19 -0
- package/README.md +94 -0
- package/dist/ai.server.d.ts +31 -27
- package/dist/animations.d.ts +16 -0
- package/dist/client/index.js +15 -31
- package/dist/client/index10.js +376 -0
- package/dist/client/index2.js +63 -46
- package/dist/client/index3.js +50 -1287
- package/dist/client/index4.js +301 -331
- package/dist/client/index5.js +36 -291
- package/dist/client/index6.js +99 -95
- package/dist/client/index7.js +33 -60
- package/dist/client/index8.js +39 -53
- package/dist/client/index9.js +1167 -27
- package/dist/client.d.ts +3 -2
- package/dist/config.d.ts +2 -0
- package/dist/index.d.ts +5 -5
- package/dist/server/index.js +14 -31
- package/dist/server/index2.js +39 -332
- package/dist/server/index3.js +62 -1287
- package/dist/server/index4.js +1167 -53
- package/dist/server/index5.js +35 -28
- package/dist/server/index6.js +376 -0
- package/dist/server.d.ts +3 -3
- package/dist/ui/state.d.ts +3 -3
- package/package.json +5 -5
- package/src/ai.server.ts +79 -28
- package/src/animations.ts +110 -0
- package/src/config.ts +16 -0
- package/src/index.ts +7 -1
- package/src/server.ts +16 -3
- package/src/types.ts +47 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActionBattleAnimationContext,
|
|
3
|
+
ActionBattleAnimationEntity,
|
|
4
|
+
ActionBattleAnimationKey,
|
|
5
|
+
ActionBattleAnimationOptions,
|
|
6
|
+
} from "./types";
|
|
7
|
+
|
|
8
|
+
export const DEFAULT_DIE_ANIMATION_DELAY_MS = 500;
|
|
9
|
+
|
|
10
|
+
export interface ResolvedActionBattleAnimation {
|
|
11
|
+
animationName: string;
|
|
12
|
+
graphic?: string | string[];
|
|
13
|
+
repeat: number;
|
|
14
|
+
waitEnd: boolean;
|
|
15
|
+
delayMs?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ActionBattleAnimationDefaults {
|
|
19
|
+
animationName?: string;
|
|
20
|
+
repeat?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const DEFAULT_ANIMATION_BY_KEY: Record<ActionBattleAnimationKey, string> = {
|
|
24
|
+
attack: "attack",
|
|
25
|
+
hurt: "hurt",
|
|
26
|
+
die: "die",
|
|
27
|
+
castSkill: "skill",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function resolveActionBattleAnimation(
|
|
31
|
+
key: ActionBattleAnimationKey,
|
|
32
|
+
entity: ActionBattleAnimationEntity,
|
|
33
|
+
animations?: ActionBattleAnimationOptions,
|
|
34
|
+
context?: ActionBattleAnimationContext,
|
|
35
|
+
defaults: ActionBattleAnimationDefaults = {}
|
|
36
|
+
): ResolvedActionBattleAnimation | null {
|
|
37
|
+
const defaultAnimationName =
|
|
38
|
+
defaults.animationName ?? DEFAULT_ANIMATION_BY_KEY[key];
|
|
39
|
+
const defaultRepeat = defaults.repeat ?? 1;
|
|
40
|
+
const hasConfiguredAnimation = animations
|
|
41
|
+
? Object.prototype.hasOwnProperty.call(animations, key)
|
|
42
|
+
: false;
|
|
43
|
+
if (!hasConfiguredAnimation && key !== "attack") {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const configured = hasConfiguredAnimation
|
|
48
|
+
? animations?.[key]
|
|
49
|
+
: defaultAnimationName;
|
|
50
|
+
const result =
|
|
51
|
+
typeof configured === "function"
|
|
52
|
+
? configured(entity, context)
|
|
53
|
+
: configured;
|
|
54
|
+
|
|
55
|
+
if (result == null) return null;
|
|
56
|
+
|
|
57
|
+
if (typeof result === "string") {
|
|
58
|
+
return {
|
|
59
|
+
animationName: result,
|
|
60
|
+
repeat: defaultRepeat,
|
|
61
|
+
waitEnd: false,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const animationName = result.animationName ?? defaultAnimationName;
|
|
66
|
+
return {
|
|
67
|
+
animationName,
|
|
68
|
+
graphic: result.graphic,
|
|
69
|
+
repeat: result.repeat ?? defaultRepeat,
|
|
70
|
+
waitEnd: result.waitEnd ?? false,
|
|
71
|
+
delayMs: result.delayMs,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function playActionBattleAnimation(
|
|
76
|
+
key: ActionBattleAnimationKey,
|
|
77
|
+
entity: ActionBattleAnimationEntity,
|
|
78
|
+
animations?: ActionBattleAnimationOptions,
|
|
79
|
+
context?: ActionBattleAnimationContext,
|
|
80
|
+
defaults: ActionBattleAnimationDefaults = {}
|
|
81
|
+
): ResolvedActionBattleAnimation | null {
|
|
82
|
+
const animation = resolveActionBattleAnimation(
|
|
83
|
+
key,
|
|
84
|
+
entity,
|
|
85
|
+
animations,
|
|
86
|
+
context,
|
|
87
|
+
defaults
|
|
88
|
+
);
|
|
89
|
+
if (!animation) return null;
|
|
90
|
+
|
|
91
|
+
if (animation.graphic !== undefined) {
|
|
92
|
+
entity.setGraphicAnimation(
|
|
93
|
+
animation.animationName,
|
|
94
|
+
animation.graphic,
|
|
95
|
+
animation.repeat
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
entity.setGraphicAnimation(animation.animationName, animation.repeat);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return animation;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function getActionBattleAnimationRemovalDelay(
|
|
105
|
+
animation: ResolvedActionBattleAnimation | null
|
|
106
|
+
): number {
|
|
107
|
+
if (!animation) return 0;
|
|
108
|
+
if (animation.delayMs !== undefined) return animation.delayMs;
|
|
109
|
+
return animation.waitEnd ? DEFAULT_DIE_ANIMATION_DELAY_MS : 0;
|
|
110
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -24,8 +24,12 @@ export const DEFAULT_ACTION_BATTLE_OPTIONS: ActionBattleOptions = {
|
|
|
24
24
|
affects: "events",
|
|
25
25
|
allowEmptyTarget: true,
|
|
26
26
|
},
|
|
27
|
+
animations: {},
|
|
27
28
|
};
|
|
28
29
|
|
|
30
|
+
let currentActionBattleOptions: ActionBattleOptions =
|
|
31
|
+
DEFAULT_ACTION_BATTLE_OPTIONS;
|
|
32
|
+
|
|
29
33
|
export function normalizeActionBattleOptions(
|
|
30
34
|
options: ActionBattleOptions = {}
|
|
31
35
|
): ActionBattleOptions {
|
|
@@ -52,5 +56,17 @@ export function normalizeActionBattleOptions(
|
|
|
52
56
|
...DEFAULT_ACTION_BATTLE_OPTIONS.targeting,
|
|
53
57
|
...options.targeting,
|
|
54
58
|
},
|
|
59
|
+
animations: {
|
|
60
|
+
...DEFAULT_ACTION_BATTLE_OPTIONS.animations,
|
|
61
|
+
...options.animations,
|
|
62
|
+
},
|
|
55
63
|
};
|
|
56
64
|
}
|
|
65
|
+
|
|
66
|
+
export function setActionBattleOptions(options: ActionBattleOptions) {
|
|
67
|
+
currentActionBattleOptions = options;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getActionBattleOptions(): ActionBattleOptions {
|
|
71
|
+
return currentActionBattleOptions;
|
|
72
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -7,8 +7,14 @@ import type { ActionBattleOptions } from "./types";
|
|
|
7
7
|
export { BattleAi, AiState, EnemyType, AttackPattern, AiDebug, DEFAULT_KNOCKBACK } from "./ai.server";
|
|
8
8
|
|
|
9
9
|
// Types exports
|
|
10
|
-
export type { HitResult, ApplyHitHooks } from "./ai.server";
|
|
10
|
+
export type { HitResult, ApplyHitHooks, BattleAiOptions } from "./ai.server";
|
|
11
11
|
export type {
|
|
12
|
+
ActionBattleAnimationContext,
|
|
13
|
+
ActionBattleAnimationEntity,
|
|
14
|
+
ActionBattleAnimationKey,
|
|
15
|
+
ActionBattleAnimationOptions,
|
|
16
|
+
ActionBattleAnimationResolver,
|
|
17
|
+
ActionBattleAnimationResult,
|
|
12
18
|
ActionBattleOptions,
|
|
13
19
|
ActionBattleActionBarData,
|
|
14
20
|
ActionBattleActionBarItem,
|
package/src/server.ts
CHANGED
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
ActionBattleActionBarSkill,
|
|
7
7
|
ActionBattleOptions,
|
|
8
8
|
} from "./types";
|
|
9
|
-
import { normalizeActionBattleOptions } from "./config";
|
|
9
|
+
import { normalizeActionBattleOptions, setActionBattleOptions } from "./config";
|
|
10
10
|
import { manhattanDistance, parseAoeMask } from "./targeting";
|
|
11
|
+
import { playActionBattleAnimation } from "./animations";
|
|
11
12
|
|
|
12
13
|
export const ACTION_BATTLE_ACTION_BAR_GUI_ID = "action-battle-action-bar";
|
|
13
14
|
|
|
@@ -330,13 +331,21 @@ const handleActionBattleSkillUse = (
|
|
|
330
331
|
target: { x: number; y: number } | undefined,
|
|
331
332
|
options: ActionBattleOptions
|
|
332
333
|
) => {
|
|
334
|
+
const skillData = resolveSkillData(player, skillId);
|
|
335
|
+
|
|
333
336
|
const map = player.getCurrentMap();
|
|
334
337
|
if (!map) {
|
|
338
|
+
playActionBattleAnimation("castSkill", player, options.animations, {
|
|
339
|
+
skill: skillData,
|
|
340
|
+
});
|
|
335
341
|
player.useSkill(skillId);
|
|
336
342
|
return;
|
|
337
343
|
}
|
|
338
344
|
const targeting = resolveSkillTargeting(player, skillId, options);
|
|
339
345
|
if (!targeting || !target) {
|
|
346
|
+
playActionBattleAnimation("castSkill", player, options.animations, {
|
|
347
|
+
skill: skillData,
|
|
348
|
+
});
|
|
340
349
|
player.useSkill(skillId);
|
|
341
350
|
return;
|
|
342
351
|
}
|
|
@@ -383,6 +392,10 @@ const handleActionBattleSkillUse = (
|
|
|
383
392
|
return;
|
|
384
393
|
}
|
|
385
394
|
|
|
395
|
+
playActionBattleAnimation("castSkill", player, options.animations, {
|
|
396
|
+
skill: skillData,
|
|
397
|
+
target: targets[0],
|
|
398
|
+
});
|
|
386
399
|
player.useSkill(skillId, targets as any);
|
|
387
400
|
};
|
|
388
401
|
|
|
@@ -390,6 +403,7 @@ export const createActionBattleServer = (
|
|
|
390
403
|
rawOptions: ActionBattleOptions = {}
|
|
391
404
|
) => {
|
|
392
405
|
const options = normalizeActionBattleOptions(rawOptions);
|
|
406
|
+
setActionBattleOptions(options);
|
|
393
407
|
return defineModule<RpgServer>({
|
|
394
408
|
player: {
|
|
395
409
|
/**
|
|
@@ -405,8 +419,7 @@ export const createActionBattleServer = (
|
|
|
405
419
|
*/
|
|
406
420
|
onInput(player: RpgPlayer, input: any) {
|
|
407
421
|
if (input.action == Control.Action) {
|
|
408
|
-
|
|
409
|
-
player.setGraphicAnimation("attack", 1);
|
|
422
|
+
playActionBattleAnimation("attack", player, options.animations);
|
|
410
423
|
|
|
411
424
|
// Get player position
|
|
412
425
|
const playerX = player.x();
|
package/src/types.ts
CHANGED
|
@@ -4,6 +4,52 @@ export type ActionBattleActionBarMode = "items" | "skills" | "both";
|
|
|
4
4
|
|
|
5
5
|
export type ActionBattleTargetingAffects = "events" | "players" | "both";
|
|
6
6
|
|
|
7
|
+
export type ActionBattleAnimationKey =
|
|
8
|
+
| "attack"
|
|
9
|
+
| "hurt"
|
|
10
|
+
| "die"
|
|
11
|
+
| "castSkill";
|
|
12
|
+
|
|
13
|
+
export type ActionBattleAnimationResult =
|
|
14
|
+
| string
|
|
15
|
+
| {
|
|
16
|
+
animationName?: string;
|
|
17
|
+
graphic?: string | string[];
|
|
18
|
+
repeat?: number;
|
|
19
|
+
waitEnd?: boolean;
|
|
20
|
+
delayMs?: number;
|
|
21
|
+
}
|
|
22
|
+
| null
|
|
23
|
+
| undefined;
|
|
24
|
+
|
|
25
|
+
export type ActionBattleAnimationEntity = {
|
|
26
|
+
setGraphicAnimation(animationName: string, repeat: number): void;
|
|
27
|
+
setGraphicAnimation(
|
|
28
|
+
animationName: string,
|
|
29
|
+
graphic: string | string[],
|
|
30
|
+
repeat: number
|
|
31
|
+
): void;
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export interface ActionBattleAnimationContext {
|
|
36
|
+
skill?: any;
|
|
37
|
+
attacker?: ActionBattleAnimationEntity;
|
|
38
|
+
target?: ActionBattleAnimationEntity;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type ActionBattleAnimationResolver = (
|
|
42
|
+
entity: ActionBattleAnimationEntity,
|
|
43
|
+
context?: ActionBattleAnimationContext
|
|
44
|
+
) => ActionBattleAnimationResult;
|
|
45
|
+
|
|
46
|
+
export type ActionBattleAnimationOptions = Partial<
|
|
47
|
+
Record<
|
|
48
|
+
ActionBattleAnimationKey,
|
|
49
|
+
ActionBattleAnimationResult | ActionBattleAnimationResolver
|
|
50
|
+
>
|
|
51
|
+
>;
|
|
52
|
+
|
|
7
53
|
export interface ActionBattleSkillTargeting {
|
|
8
54
|
range: number;
|
|
9
55
|
aoeMask?: ActionBattleAoeMask;
|
|
@@ -49,6 +95,7 @@ export interface ActionBattleOptions {
|
|
|
49
95
|
ui?: ActionBattleUiOptions;
|
|
50
96
|
skills?: ActionBattleSkillOptions;
|
|
51
97
|
targeting?: ActionBattleTargetingOptions;
|
|
98
|
+
animations?: ActionBattleAnimationOptions;
|
|
52
99
|
}
|
|
53
100
|
|
|
54
101
|
export interface ActionBattleActionBarItem {
|