@rpgjs/action-battle 5.0.0-beta.11 → 5.0.0-beta.12

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 (110) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/client/ai.server.d.ts +45 -8
  3. package/dist/client/attack-input.d.ts +3 -0
  4. package/dist/client/core/action-use.d.ts +18 -0
  5. package/dist/client/core/ai-behavior-tree.d.ts +99 -0
  6. package/dist/client/core/attack-runtime.d.ts +2 -0
  7. package/dist/client/core/defaults.d.ts +2 -1
  8. package/dist/client/core/equipment.d.ts +1 -0
  9. package/dist/client/core/targets.d.ts +15 -0
  10. package/dist/client/enemies/factory.d.ts +2 -0
  11. package/dist/client/index.d.ts +12 -7
  12. package/dist/client/index.js +16 -11
  13. package/dist/client/index10.js +32 -56
  14. package/dist/client/index11.js +99 -52
  15. package/dist/client/index12.js +76 -103
  16. package/dist/client/index13.js +72 -135
  17. package/dist/client/index14.js +67 -23
  18. package/dist/client/index15.js +197 -63
  19. package/dist/client/index16.js +112 -1337
  20. package/dist/client/index17.js +193 -7
  21. package/dist/client/index18.js +32 -58
  22. package/dist/client/index19.js +70 -8
  23. package/dist/client/index20.js +57 -501
  24. package/dist/client/index21.js +69 -0
  25. package/dist/client/index22.js +225 -0
  26. package/dist/client/index23.js +16 -0
  27. package/dist/client/index24.js +25 -0
  28. package/dist/client/index25.js +107 -0
  29. package/dist/client/index26.js +1707 -0
  30. package/dist/client/index27.js +12 -0
  31. package/dist/client/index28.js +589 -0
  32. package/dist/client/index4.js +79 -38
  33. package/dist/client/index6.js +65 -306
  34. package/dist/client/index7.js +33 -33
  35. package/dist/client/index8.js +24 -100
  36. package/dist/client/index9.js +293 -61
  37. package/dist/client/locomotion.d.ts +16 -0
  38. package/dist/client/movement.d.ts +14 -0
  39. package/dist/client/server.d.ts +7 -3
  40. package/dist/client/ui.d.ts +22 -0
  41. package/dist/client/visual.d.ts +15 -0
  42. package/dist/server/ai.server.d.ts +45 -8
  43. package/dist/server/attack-input.d.ts +3 -0
  44. package/dist/server/core/action-use.d.ts +18 -0
  45. package/dist/server/core/ai-behavior-tree.d.ts +99 -0
  46. package/dist/server/core/attack-runtime.d.ts +2 -0
  47. package/dist/server/core/defaults.d.ts +2 -1
  48. package/dist/server/core/equipment.d.ts +1 -0
  49. package/dist/server/core/targets.d.ts +15 -0
  50. package/dist/server/enemies/factory.d.ts +2 -0
  51. package/dist/server/index.d.ts +12 -7
  52. package/dist/server/index.js +14 -9
  53. package/dist/server/index10.js +64 -1336
  54. package/dist/server/index11.js +33 -33
  55. package/dist/server/index13.js +66 -11
  56. package/dist/server/index14.js +206 -484
  57. package/dist/server/index15.js +15 -9
  58. package/dist/server/index16.js +26 -0
  59. package/dist/server/index17.js +25 -0
  60. package/dist/server/index18.js +107 -0
  61. package/dist/server/index19.js +1707 -0
  62. package/dist/server/index2.js +10 -2
  63. package/dist/server/index20.js +37 -0
  64. package/dist/server/index21.js +588 -0
  65. package/dist/server/index22.js +78 -0
  66. package/dist/server/index23.js +12 -0
  67. package/dist/server/index5.js +79 -38
  68. package/dist/server/index6.js +192 -129
  69. package/dist/server/index7.js +198 -24
  70. package/dist/server/index8.js +28 -66
  71. package/dist/server/index9.js +68 -51
  72. package/dist/server/locomotion.d.ts +16 -0
  73. package/dist/server/movement.d.ts +14 -0
  74. package/dist/server/server.d.ts +7 -3
  75. package/dist/server/ui.d.ts +22 -0
  76. package/dist/server/visual.d.ts +15 -0
  77. package/package.json +5 -5
  78. package/src/ai.server.spec.ts +233 -0
  79. package/src/ai.server.ts +627 -108
  80. package/src/animations.spec.ts +40 -0
  81. package/src/animations.ts +31 -9
  82. package/src/attack-input.spec.ts +51 -0
  83. package/src/attack-input.ts +59 -0
  84. package/src/client.ts +75 -62
  85. package/src/config.ts +84 -37
  86. package/src/core/action-use.spec.ts +317 -0
  87. package/src/core/action-use.ts +386 -0
  88. package/src/core/ai-behavior-tree.spec.ts +116 -0
  89. package/src/core/ai-behavior-tree.ts +272 -0
  90. package/src/core/attack-profile.spec.ts +46 -0
  91. package/src/core/attack-runtime.spec.ts +35 -0
  92. package/src/core/attack-runtime.ts +32 -0
  93. package/src/core/context.ts +9 -0
  94. package/src/core/contracts.ts +146 -1
  95. package/src/core/defaults.ts +56 -0
  96. package/src/core/equipment.ts +9 -5
  97. package/src/core/targets.spec.ts +112 -0
  98. package/src/core/targets.ts +147 -0
  99. package/src/enemies/factory.ts +8 -0
  100. package/src/index.ts +111 -2
  101. package/src/locomotion.spec.ts +51 -0
  102. package/src/locomotion.ts +48 -0
  103. package/src/movement.spec.ts +78 -0
  104. package/src/movement.ts +46 -0
  105. package/src/server.ts +242 -66
  106. package/src/types.ts +105 -35
  107. package/src/ui.ts +113 -0
  108. package/src/visual.spec.ts +166 -0
  109. package/src/visual.ts +285 -0
  110. package/README.md +0 -1242
@@ -1,25 +1,199 @@
1
- import { defaultActionBattleSystems } from "./index6.js";
2
- //#region src/core/context.ts
3
- var mergeSystems = (options = {}) => ({
4
- combat: {
5
- ...defaultActionBattleSystems.combat,
6
- resolveDamage: options.systems?.combat?.damage ?? defaultActionBattleSystems.combat.resolveDamage,
7
- resolveKnockback: options.systems?.combat?.knockback ?? defaultActionBattleSystems.combat.resolveKnockback,
8
- hooks: {
9
- ...defaultActionBattleSystems.combat.hooks,
10
- ...options.systems?.combat?.hooks
11
- }
12
- },
13
- ai: { behaviors: {
14
- ...defaultActionBattleSystems.ai.behaviors,
15
- ...options.systems?.ai?.behaviors
16
- } }
17
- });
18
- var currentActionBattleSystems = mergeSystems();
19
- var setActionBattleSystems = (options = {}) => {
20
- currentActionBattleSystems = mergeSystems(options);
21
- };
22
- var getActionBattleSystems = () => currentActionBattleSystems;
23
- var createActionBattleSystems = mergeSystems;
1
+ //#region src/core/defaults.ts
2
+ var DEFAULT_CORE_KNOCKBACK = {
3
+ force: 50,
4
+ duration: 300
5
+ };
6
+ var CoreAttackPattern = {
7
+ Melee: "melee",
8
+ Combo: "combo",
9
+ Charged: "charged",
10
+ Zone: "zone",
11
+ DashAttack: "dashAttack"
12
+ };
13
+ var CoreEnemyType = {
14
+ Aggressive: "aggressive",
15
+ Defensive: "defensive",
16
+ Ranged: "ranged",
17
+ Tank: "tank",
18
+ Berserker: "berserker"
19
+ };
20
+ var DEFAULT_ZELDA_PLAYER_HITBOXES = {
21
+ up: {
22
+ offsetX: -16,
23
+ offsetY: -48,
24
+ width: 32,
25
+ height: 32
26
+ },
27
+ down: {
28
+ offsetX: -16,
29
+ offsetY: 16,
30
+ width: 32,
31
+ height: 32
32
+ },
33
+ left: {
34
+ offsetX: -48,
35
+ offsetY: -16,
36
+ width: 32,
37
+ height: 32
38
+ },
39
+ right: {
40
+ offsetX: 16,
41
+ offsetY: -16,
42
+ width: 32,
43
+ height: 32
44
+ },
45
+ default: {
46
+ offsetX: 0,
47
+ offsetY: -32,
48
+ width: 32,
49
+ height: 32
50
+ }
51
+ };
52
+ var resolveEquippedWeapon = (entity) => {
53
+ const equipments = entity?.equipments?.() || [];
54
+ for (const item of equipments) {
55
+ const itemId = item?.id?.() ?? item?.id;
56
+ const itemData = entity?.databaseById?.(itemId);
57
+ if (itemData?._type === "weapon") return itemData;
58
+ }
59
+ return null;
60
+ };
61
+ var resolveDirection = (attacker, target) => {
62
+ const dx = target.x() - attacker.x();
63
+ const dy = target.y() - attacker.y();
64
+ const distance = Math.sqrt(dx * dx + dy * dy);
65
+ if (distance <= 0) return void 0;
66
+ return {
67
+ x: dx / distance,
68
+ y: dy / distance
69
+ };
70
+ };
71
+ var createDefaultPlayerHitboxResolver = (hitboxes = DEFAULT_ZELDA_PLAYER_HITBOXES) => (context) => {
72
+ const attacker = context.attacker;
73
+ const config = hitboxes[context.direction ?? (typeof attacker.getDirection === "function" ? attacker.getDirection() : "default")] || hitboxes.default;
74
+ return [{
75
+ x: attacker.x() + config.offsetX,
76
+ y: attacker.y() + config.offsetY,
77
+ width: config.width,
78
+ height: config.height
79
+ }];
80
+ };
81
+ var defaultRpgjsDamageResolver = (context) => {
82
+ const target = context.target;
83
+ const raw = target.applyDamage(context.attacker, context.skill);
84
+ return {
85
+ damage: raw?.damage ?? 0,
86
+ defeated: target.hp <= 0,
87
+ raw
88
+ };
89
+ };
90
+ var defaultKnockbackResolver = (context) => {
91
+ const weapon = context.weapon ?? resolveEquippedWeapon(context.attacker);
92
+ return {
93
+ force: weapon?.knockbackForce ?? DEFAULT_CORE_KNOCKBACK.force,
94
+ duration: weapon?.knockbackDuration ?? DEFAULT_CORE_KNOCKBACK.duration,
95
+ direction: resolveDirection(context.attacker, context.target)
96
+ };
97
+ };
98
+ var defaultCombatSystem = {
99
+ resolveHitboxes: createDefaultPlayerHitboxResolver(),
100
+ resolveDamage: defaultRpgjsDamageResolver,
101
+ resolveKnockback: defaultKnockbackResolver
102
+ };
103
+ var defaultEnemyBehaviors = {
104
+ [CoreEnemyType.Aggressive]: ({ hpPercent }) => ({
105
+ mode: hpPercent !== null && hpPercent < .15 ? "retreat" : "assault",
106
+ attackPatterns: [
107
+ CoreAttackPattern.Melee,
108
+ CoreAttackPattern.Combo,
109
+ CoreAttackPattern.DashAttack
110
+ ]
111
+ }),
112
+ [CoreEnemyType.Defensive]: ({ hpPercent }) => ({
113
+ mode: hpPercent !== null && hpPercent < .3 ? "retreat" : "tactical",
114
+ attackPatterns: [CoreAttackPattern.Melee, CoreAttackPattern.Charged]
115
+ }),
116
+ [CoreEnemyType.Ranged]: ({ distance }) => ({
117
+ mode: distance !== null && distance < 80 ? "retreat" : "tactical",
118
+ attackPatterns: [CoreAttackPattern.Melee, CoreAttackPattern.Zone]
119
+ }),
120
+ [CoreEnemyType.Tank]: () => ({
121
+ mode: "assault",
122
+ attackPatterns: [
123
+ CoreAttackPattern.Melee,
124
+ CoreAttackPattern.Charged,
125
+ CoreAttackPattern.Zone
126
+ ]
127
+ }),
128
+ [CoreEnemyType.Berserker]: ({ hpPercent }) => ({
129
+ mode: "assault",
130
+ attackCooldown: hpPercent === null ? void 0 : Math.max(250, 800 * Math.max(.3, hpPercent)),
131
+ attackPatterns: [
132
+ CoreAttackPattern.Melee,
133
+ CoreAttackPattern.Combo,
134
+ CoreAttackPattern.DashAttack
135
+ ]
136
+ })
137
+ };
138
+ var defaultEnemyPresets = {
139
+ [CoreEnemyType.Aggressive]: {
140
+ enemyType: CoreEnemyType.Aggressive,
141
+ attackCooldown: 600,
142
+ visionRange: 150,
143
+ attackRange: 50,
144
+ dodgeChance: .1,
145
+ dodgeCooldown: 3e3,
146
+ fleeThreshold: .15,
147
+ behaviorKey: CoreEnemyType.Aggressive
148
+ },
149
+ [CoreEnemyType.Defensive]: {
150
+ enemyType: CoreEnemyType.Defensive,
151
+ attackCooldown: 1500,
152
+ visionRange: 120,
153
+ attackRange: 60,
154
+ dodgeChance: .5,
155
+ dodgeCooldown: 1500,
156
+ fleeThreshold: .3,
157
+ behaviorKey: CoreEnemyType.Defensive
158
+ },
159
+ [CoreEnemyType.Ranged]: {
160
+ enemyType: CoreEnemyType.Ranged,
161
+ attackCooldown: 1200,
162
+ visionRange: 200,
163
+ attackRange: 120,
164
+ dodgeChance: .4,
165
+ dodgeCooldown: 2e3,
166
+ fleeThreshold: .25,
167
+ behaviorKey: CoreEnemyType.Ranged
168
+ },
169
+ [CoreEnemyType.Tank]: {
170
+ enemyType: CoreEnemyType.Tank,
171
+ attackCooldown: 2e3,
172
+ visionRange: 100,
173
+ attackRange: 50,
174
+ dodgeChance: 0,
175
+ dodgeCooldown: 5e3,
176
+ fleeThreshold: .1,
177
+ poise: 2,
178
+ behaviorKey: CoreEnemyType.Tank
179
+ },
180
+ [CoreEnemyType.Berserker]: {
181
+ enemyType: CoreEnemyType.Berserker,
182
+ attackCooldown: 800,
183
+ visionRange: 180,
184
+ attackRange: 55,
185
+ dodgeChance: .15,
186
+ dodgeCooldown: 2500,
187
+ fleeThreshold: .05,
188
+ behaviorKey: CoreEnemyType.Berserker
189
+ }
190
+ };
191
+ var defaultActionBattleSystems = {
192
+ combat: defaultCombatSystem,
193
+ ai: {
194
+ behaviors: defaultEnemyBehaviors,
195
+ presets: defaultEnemyPresets
196
+ }
197
+ };
24
198
  //#endregion
25
- export { createActionBattleSystems, getActionBattleSystems, setActionBattleSystems };
199
+ export { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultActionBattleSystems, defaultCombatSystem, defaultEnemyBehaviors, defaultEnemyPresets, defaultKnockbackResolver, defaultRpgjsDamageResolver };
@@ -1,72 +1,34 @@
1
- import { normalizeActionBattleAttackProfile } from "./index4.js";
2
- //#region src/core/enemy-attack-profiles.ts
3
- var DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES = {
4
- melee: {
5
- id: "enemy-melee",
6
- startupMs: 120,
7
- activeMs: 100,
8
- recoveryMs: 220,
9
- cooldownMs: 440,
10
- reaction: {
11
- invincibilityMs: 250,
12
- hitstunMs: 120,
13
- staggerPower: 1
1
+ import { defaultActionBattleSystems } from "./index7.js";
2
+ //#region src/core/context.ts
3
+ var mergeSystems = (options = {}) => ({
4
+ combat: {
5
+ ...defaultActionBattleSystems.combat,
6
+ resolveDamage: options.combat?.damage ?? options.systems?.combat?.damage ?? defaultActionBattleSystems.combat.resolveDamage,
7
+ resolveKnockback: options.combat?.knockback ?? options.systems?.combat?.knockback ?? defaultActionBattleSystems.combat.resolveKnockback,
8
+ hooks: {
9
+ ...defaultActionBattleSystems.combat.hooks,
10
+ ...options.systems?.combat?.hooks,
11
+ ...options.combat?.hooks
14
12
  }
15
13
  },
16
- combo: {
17
- id: "enemy-combo",
18
- startupMs: 80,
19
- activeMs: 80,
20
- recoveryMs: 140,
21
- cooldownMs: 300,
22
- reaction: {
23
- invincibilityMs: 180,
24
- hitstunMs: 90,
25
- staggerPower: .75
26
- }
27
- },
28
- charged: {
29
- id: "enemy-charged",
30
- startupMs: 800,
31
- activeMs: 140,
32
- recoveryMs: 320,
33
- cooldownMs: 1260,
34
- reaction: {
35
- invincibilityMs: 350,
36
- hitstunMs: 220,
37
- staggerPower: 2
38
- }
39
- },
40
- zone: {
41
- id: "enemy-zone",
42
- startupMs: 450,
43
- activeMs: 180,
44
- recoveryMs: 320,
45
- cooldownMs: 950,
46
- reaction: {
47
- invincibilityMs: 300,
48
- hitstunMs: 160,
49
- staggerPower: 1.25
50
- }
51
- },
52
- dashAttack: {
53
- id: "enemy-dash",
54
- startupMs: 180,
55
- activeMs: 120,
56
- recoveryMs: 260,
57
- cooldownMs: 560,
58
- reaction: {
59
- invincibilityMs: 280,
60
- hitstunMs: 150,
61
- staggerPower: 1.2
14
+ ai: {
15
+ behaviors: {
16
+ ...defaultActionBattleSystems.ai.behaviors,
17
+ ...options.systems?.ai?.behaviors,
18
+ ...options.ai?.behaviors
19
+ },
20
+ presets: {
21
+ ...defaultActionBattleSystems.ai.presets,
22
+ ...options.systems?.ai?.presets,
23
+ ...options.ai?.presets
62
24
  }
63
25
  }
26
+ });
27
+ var currentActionBattleSystems = mergeSystems();
28
+ var setActionBattleSystems = (options = {}) => {
29
+ currentActionBattleSystems = mergeSystems(options);
64
30
  };
65
- function normalizeActionBattleEnemyAttackProfiles(overrides = {}) {
66
- return Object.fromEntries(Object.entries(DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES).map(([key, defaultProfile]) => [key, normalizeActionBattleAttackProfile({
67
- ...defaultProfile,
68
- ...overrides[key]
69
- })]));
70
- }
31
+ var getActionBattleSystems = () => currentActionBattleSystems;
32
+ var createActionBattleSystems = mergeSystems;
71
33
  //#endregion
72
- export { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles };
34
+ export { createActionBattleSystems, getActionBattleSystems, setActionBattleSystems };
@@ -1,55 +1,72 @@
1
1
  import { normalizeActionBattleAttackProfile } from "./index4.js";
2
- //#region src/core/attack-runtime.ts
3
- var ACTION_BATTLE_HITBOX_FRAME_MS = 16;
4
- function getNormalizedActionBattleAttackProfile(options = {}) {
5
- const attack = options.attack ?? {};
6
- return normalizeActionBattleAttackProfile(attack.profile, {
7
- lockMovement: attack.lockMovement,
8
- lockDurationMs: attack.lockDurationMs,
9
- hitboxes: attack.hitboxes
10
- });
11
- }
12
- function resolveActionBattleHitboxSpeed(profile, hitboxCount) {
13
- const positions = Math.max(1, Math.floor(hitboxCount));
14
- const activeFrames = Math.max(1, Math.ceil(profile.activeMs / 16));
15
- return Math.max(1, Math.ceil(activeFrames / positions));
16
- }
17
- function scheduleActionBattleStartup(profile, callback, scheduler = setTimeout) {
18
- if (profile.startupMs <= 0) {
19
- callback();
20
- return null;
21
- }
22
- return scheduler(callback, profile.startupMs);
23
- }
24
- var attackIdCounter = 0;
25
- function createActionBattleAttackId(attackerId, profileId) {
26
- attackIdCounter++;
27
- return `${attackerId ?? "unknown"}:${profileId}:${Date.now()}:${attackIdCounter}`;
28
- }
29
- var getTargetKey = (target) => {
30
- if (!target || target.id === void 0 || target.id === null) return null;
31
- return String(target.id);
32
- };
33
- var ActionBattleHitTracker = class {
34
- hitPolicy;
35
- hitTargets = /* @__PURE__ */ new Set();
36
- constructor(hitPolicy) {
37
- this.hitPolicy = hitPolicy;
38
- }
39
- canHit(target) {
40
- if (this.hitPolicy === "allowRepeatHits") return true;
41
- const key = getTargetKey(target);
42
- return !key || !this.hitTargets.has(key);
43
- }
44
- recordHit(target) {
45
- const key = getTargetKey(target);
46
- if (key) this.hitTargets.add(key);
47
- }
48
- tryHit(target) {
49
- if (!this.canHit(target)) return false;
50
- this.recordHit(target);
51
- return true;
2
+ //#region src/core/enemy-attack-profiles.ts
3
+ var DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES = {
4
+ melee: {
5
+ id: "enemy-melee",
6
+ startupMs: 120,
7
+ activeMs: 100,
8
+ recoveryMs: 220,
9
+ cooldownMs: 440,
10
+ reaction: {
11
+ invincibilityMs: 250,
12
+ hitstunMs: 120,
13
+ staggerPower: 1
14
+ }
15
+ },
16
+ combo: {
17
+ id: "enemy-combo",
18
+ startupMs: 80,
19
+ activeMs: 80,
20
+ recoveryMs: 140,
21
+ cooldownMs: 300,
22
+ reaction: {
23
+ invincibilityMs: 180,
24
+ hitstunMs: 90,
25
+ staggerPower: .75
26
+ }
27
+ },
28
+ charged: {
29
+ id: "enemy-charged",
30
+ startupMs: 800,
31
+ activeMs: 140,
32
+ recoveryMs: 320,
33
+ cooldownMs: 1260,
34
+ reaction: {
35
+ invincibilityMs: 350,
36
+ hitstunMs: 220,
37
+ staggerPower: 2
38
+ }
39
+ },
40
+ zone: {
41
+ id: "enemy-zone",
42
+ startupMs: 450,
43
+ activeMs: 180,
44
+ recoveryMs: 320,
45
+ cooldownMs: 950,
46
+ reaction: {
47
+ invincibilityMs: 300,
48
+ hitstunMs: 160,
49
+ staggerPower: 1.25
50
+ }
51
+ },
52
+ dashAttack: {
53
+ id: "enemy-dash",
54
+ startupMs: 180,
55
+ activeMs: 120,
56
+ recoveryMs: 260,
57
+ cooldownMs: 560,
58
+ reaction: {
59
+ invincibilityMs: 280,
60
+ hitstunMs: 150,
61
+ staggerPower: 1.2
62
+ }
52
63
  }
53
64
  };
65
+ function normalizeActionBattleEnemyAttackProfiles(overrides = {}) {
66
+ return Object.fromEntries(Object.entries(DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES).map(([key, defaultProfile]) => [key, normalizeActionBattleAttackProfile({
67
+ ...defaultProfile,
68
+ ...overrides[key]
69
+ })]));
70
+ }
54
71
  //#endregion
55
- export { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, scheduleActionBattleStartup };
72
+ export { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles };
@@ -0,0 +1,16 @@
1
+ type LocomotionEntity = {
2
+ animationFixed?: boolean;
3
+ setGraphicAnimation?: (...args: any[]) => unknown;
4
+ animationName?: {
5
+ set?: (animationName: string) => unknown;
6
+ };
7
+ resetAnimationState?: () => unknown;
8
+ };
9
+ export declare const withActionBattleAnimationUnlocked: <T>(entity: LocomotionEntity | undefined, callback: () => T) => T;
10
+ /**
11
+ * Force a locomotion animation even when an action lock temporarily froze
12
+ * animation changes. This keeps server state and local rendering coherent
13
+ * after attack recovery interrupts movement.
14
+ */
15
+ export declare const forceActionBattleLocomotionAnimation: (entity: LocomotionEntity | undefined, animationName: "stand" | "walk") => void;
16
+ export {};
@@ -0,0 +1,14 @@
1
+ export type ActionBattleDashEntity = {
2
+ id?: string;
3
+ getCurrentMap?: () => any;
4
+ dash?: (direction: {
5
+ x: number;
6
+ y: number;
7
+ }, additionalSpeed?: number, duration?: number) => unknown;
8
+ };
9
+ export declare const isActionBattleMovementResolutionError: (error: unknown) => boolean;
10
+ export declare const hasActionBattlePhysicsBody: (entity: ActionBattleDashEntity | null | undefined) => boolean;
11
+ export declare const safeActionBattleDash: (entity: ActionBattleDashEntity | null | undefined, direction: {
12
+ x: number;
13
+ y: number;
14
+ }, additionalSpeed?: number, duration?: number) => boolean;
@@ -91,16 +91,20 @@ export declare function getPlayerWeaponKnockbackForce(player: RpgPlayer): number
91
91
  * ```
92
92
  */
93
93
  export declare function applyPlayerHitToEvent(player: RpgPlayer, target: RpgEvent, hooks?: ApplyHitHooks, metadata?: Record<string, any>): HitResult | undefined;
94
+ export declare function applyActionBattleEntityHit(attacker: RpgPlayer | RpgEvent, target: RpgPlayer | RpgEvent, hooks?: ApplyHitHooks, metadata?: Record<string, any>): HitResult | undefined;
94
95
  export declare const openActionBattleActionBar: (player: RpgPlayer, rawOptions?: ActionBattleOptions) => void;
95
96
  export declare const updateActionBattleActionBar: (player: RpgPlayer, rawOptions?: ActionBattleOptions) => void;
96
97
  export declare const createActionBattleServer: (rawOptions?: ActionBattleOptions) => RpgServer;
97
98
  declare const _default: RpgServer;
98
99
  export default _default;
99
- export { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, scheduleActionBattleStartup, } from './core/attack-runtime';
100
+ export { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, runActionBattleActiveHitbox, scheduleActionBattleStartup, } from './core/attack-runtime';
100
101
  export { DEFAULT_ACTION_BATTLE_ATTACK_PROFILE, normalizeActionBattleAttackProfile, type ActionBattleAttackProfileFallbacks, } from './core/attack-profile';
101
- export type { ActionBattleAttackDirection, ActionBattleAttackHitboxConfig, ActionBattleAttackHitboxMap, ActionBattleAttackHitPolicy, ActionBattleAttackProfile, ActionBattleDebugOptions, ActionBattleHitReactionProfile, NormalizedActionBattleHitReactionProfile, NormalizedActionBattleAttackProfile, } from './types';
102
+ export type { ActionBattleAttackDirection, ActionBattleAttackHitboxConfig, ActionBattleAttackHitboxMap, ActionBattleAttackHitPolicy, ActionBattleAttackProfile, ActionBattleHitReactionProfile, NormalizedActionBattleHitReactionProfile, NormalizedActionBattleAttackProfile, } from './types';
103
+ export type { ActionBattleActionConfig, ActionBattleActionMode, ActionBattleActionTarget, ActionBattleProjectileImpactContext, ActionBattleProjectileOptions, ActionBattleTargetContext, ActionBattleTargetOptions, ActionBattleTargetSelector, ActionBattleUsable, ActionBattleUseContext, } from './core/contracts';
104
+ export { canActionBattleUseTarget, executeActionBattleUse, getActionBattleActionConfig, getActionBattleActionRange, handleActionBattleProjectileDestroy, handleActionBattleProjectileImpact, shouldUseActionBattleUsable, } from './core/action-use';
102
105
  export { DEFAULT_ACTION_BATTLE_HIT_REACTION, isActionBattleEntityInvincible, normalizeActionBattleHitReaction, setActionBattleInvincibility, } from './core/hit-reaction';
103
106
  export { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles, type ActionBattleEnemyAttackProfileKey, type ActionBattleEnemyAttackProfileMap, type NormalizedActionBattleEnemyAttackProfileMap, } from './core/enemy-attack-profiles';
104
- export { resolveActionBattleWeaponAttackProfile } from './core/equipment';
107
+ export { resolveActionBattleWeapon, resolveActionBattleWeaponAttackProfile, } from './core/equipment';
108
+ export { ACTION_BATTLE_ENEMY_FACTION, ACTION_BATTLE_PLAYER_FACTION, canActionBattleTarget, getActionBattleFaction, getActionBattleTargets, isActionBattleCombatEntity, isActionBattleEvent, isActionBattlePlayer, matchesActionBattleTargetSelector, } from './core/targets';
105
109
  export { AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_KNOCKBACK, EnemyType, } from './ai.server';
106
110
  export type { ApplyHitHooks, BattleAiDefeatedCallback, BattleAiDefeatedContext, BattleAiDefeatReward, BattleAiLegacyDefeatedCallback, BattleAiLegacyOptions, BattleAiOptions, BattleAiRewardItem, BattleAiRewards, HitResult, } from './ai.server';
@@ -0,0 +1,22 @@
1
+ import { ActionBattleUiActionBarOptions, ActionBattleUiAttackPreviewOptions, ActionBattleUiOptions, ActionBattleUiTargetingOptions } from './types';
2
+ export declare const ActionBattleUi: {
3
+ ActionBar: any;
4
+ TargetingOverlay: any;
5
+ AttackPreview: any;
6
+ };
7
+ export interface ResolvedActionBattleUi {
8
+ gui: Array<{
9
+ id: string;
10
+ component: any;
11
+ dependencies?: Function;
12
+ }>;
13
+ sprite: {
14
+ componentsInFront: any[];
15
+ componentsBehind: any[];
16
+ };
17
+ actionBar: ActionBattleUiActionBarOptions;
18
+ targeting: ActionBattleUiTargetingOptions;
19
+ attackPreview: ActionBattleUiAttackPreviewOptions;
20
+ }
21
+ export declare function createActionBattleUi(input?: "classic" | ActionBattleUiOptions): ActionBattleUiOptions;
22
+ export declare function resolveActionBattleUi(options?: ActionBattleUiOptions): ResolvedActionBattleUi;
@@ -0,0 +1,15 @@
1
+ import { ActionBattleVisualComposer, ActionBattleVisualContext, ActionBattleVisualInput } from './types';
2
+ export declare const ACTION_BATTLE_CLIENT_VISUAL_ID = "action-battle.visual";
3
+ export declare const ACTION_BATTLE_HIT_FX_COMPONENT_ID = "action-battle-hit-fx";
4
+ type PreviewStarter = (entity: any, options?: Record<string, any>) => void;
5
+ export declare function setActionBattlePreviewStarter(starter?: PreviewStarter): void;
6
+ export declare function emitActionBattleClientVisual(context: ActionBattleVisualContext): void;
7
+ export declare function createActionBattleClientVisuals(options?: import('./types').ActionBattleOptions): {
8
+ "action-battle.visual": (context: any) => void;
9
+ };
10
+ export declare function createActionBattleVisual(input?: ActionBattleVisualInput): ActionBattleVisualComposer;
11
+ export declare const createClassicActionBattleVisual: () => ActionBattleVisualComposer;
12
+ export declare const createFxActionBattleVisual: () => ActionBattleVisualComposer;
13
+ export declare function playActionBattleVisual(visual: ActionBattleVisualInput | ActionBattleVisualComposer | undefined, context: ActionBattleVisualContext): void;
14
+ export declare function usesActionBattleFxVisual(visual: ActionBattleVisualInput | undefined): boolean;
15
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpgjs/action-battle",
3
- "version": "5.0.0-beta.11",
3
+ "version": "5.0.0-beta.12",
4
4
  "main": "dist/client/index.js",
5
5
  "types": "dist/client/index.d.ts",
6
6
  "exports": {
@@ -23,10 +23,10 @@
23
23
  "description": "RPGJS is a framework for creating RPG/MMORPG games",
24
24
  "peerDependencies": {
25
25
  "@canvasengine/presets": "^2.0.0-rc.4",
26
- "@rpgjs/client": "5.0.0-beta.11",
27
- "@rpgjs/common": "5.0.0-beta.11",
28
- "@rpgjs/server": "5.0.0-beta.11",
29
- "@rpgjs/vite": "5.0.0-beta.11",
26
+ "@rpgjs/client": "5.0.0-beta.12",
27
+ "@rpgjs/common": "5.0.0-beta.12",
28
+ "@rpgjs/server": "5.0.0-beta.12",
29
+ "@rpgjs/vite": "5.0.0-beta.12",
30
30
  "canvasengine": "^2.0.0-rc.4"
31
31
  },
32
32
  "publishConfig": {