@rpgjs/action-battle 5.0.0-beta.10 → 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 (111) hide show
  1. package/CHANGELOG.md +22 -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 +10 -10
  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/components/action-bar.ce +2 -2
  86. package/src/config.ts +84 -37
  87. package/src/core/action-use.spec.ts +317 -0
  88. package/src/core/action-use.ts +386 -0
  89. package/src/core/ai-behavior-tree.spec.ts +116 -0
  90. package/src/core/ai-behavior-tree.ts +272 -0
  91. package/src/core/attack-profile.spec.ts +46 -0
  92. package/src/core/attack-runtime.spec.ts +35 -0
  93. package/src/core/attack-runtime.ts +32 -0
  94. package/src/core/context.ts +9 -0
  95. package/src/core/contracts.ts +146 -1
  96. package/src/core/defaults.ts +56 -0
  97. package/src/core/equipment.ts +9 -5
  98. package/src/core/targets.spec.ts +112 -0
  99. package/src/core/targets.ts +147 -0
  100. package/src/enemies/factory.ts +8 -0
  101. package/src/index.ts +111 -2
  102. package/src/locomotion.spec.ts +51 -0
  103. package/src/locomotion.ts +48 -0
  104. package/src/movement.spec.ts +78 -0
  105. package/src/movement.ts +46 -0
  106. package/src/server.ts +242 -66
  107. package/src/types.ts +105 -35
  108. package/src/ui.ts +113 -0
  109. package/src/visual.spec.ts +166 -0
  110. package/src/visual.ts +285 -0
  111. package/README.md +0 -1242
@@ -0,0 +1,78 @@
1
+ //#region src/ui.ts
2
+ var inject = null;
3
+ var RpgClientEngine = null;
4
+ var ActionBattleUi = {
5
+ ActionBar: null,
6
+ TargetingOverlay: null,
7
+ AttackPreview: null
8
+ };
9
+ var normalizeToggle = (value, defaults) => {
10
+ if (value === false) return {
11
+ ...defaults,
12
+ enabled: false
13
+ };
14
+ if (value === true) return {
15
+ ...defaults,
16
+ enabled: true
17
+ };
18
+ if (value === void 0) return { ...defaults };
19
+ return {
20
+ ...defaults,
21
+ ...value,
22
+ enabled: value.enabled ?? defaults.enabled
23
+ };
24
+ };
25
+ function createActionBattleUi(input = "classic") {
26
+ if (input === "classic") return {};
27
+ return input;
28
+ }
29
+ function resolveActionBattleUi(options = {}) {
30
+ const actionBar = normalizeToggle(options.actionBar, {
31
+ enabled: false,
32
+ autoOpen: false,
33
+ mode: "both",
34
+ component: ActionBattleUi.ActionBar
35
+ });
36
+ const targeting = normalizeToggle(options.targeting, {
37
+ enabled: true,
38
+ showGrid: true,
39
+ component: ActionBattleUi.TargetingOverlay,
40
+ colors: {
41
+ area: 3120887,
42
+ edge: 1796760,
43
+ cursor: 16765286
44
+ }
45
+ });
46
+ const attackPreview = normalizeToggle(options.attackPreview, {
47
+ enabled: true,
48
+ component: ActionBattleUi.AttackPreview
49
+ });
50
+ const gui = [...options.gui ?? []];
51
+ if (actionBar.enabled && actionBar.component) gui.unshift({
52
+ id: "action-battle-action-bar",
53
+ component: actionBar.component,
54
+ dependencies: () => {
55
+ return [inject(RpgClientEngine).scene.currentPlayer];
56
+ }
57
+ });
58
+ const configuredSpriteComponents = Array.isArray(options.spriteComponents) ? {
59
+ front: options.spriteComponents,
60
+ back: []
61
+ } : options.spriteComponents ?? {};
62
+ return {
63
+ gui,
64
+ sprite: {
65
+ componentsInFront: [
66
+ ...targeting.enabled && targeting.component ? [targeting.component] : [],
67
+ ...attackPreview.enabled && attackPreview.component ? [attackPreview.component] : [],
68
+ ...configuredSpriteComponents.front ?? []
69
+ ],
70
+ componentsBehind: configuredSpriteComponents.back ?? []
71
+ },
72
+ actionBar,
73
+ targeting,
74
+ attackPreview
75
+ };
76
+ }
77
+ //#endregion
78
+ export { ActionBattleUi, createActionBattleUi, resolveActionBattleUi };
@@ -0,0 +1,12 @@
1
+ import { BattleAi } from "./index19.js";
2
+ //#region src/enemies/factory.ts
3
+ var defineActionBattleEnemy = (preset) => preset;
4
+ var defineActionBattleAiPreset = (preset) => preset;
5
+ var createActionEnemy = (event, presetOrOptions, presets = {}) => {
6
+ const options = typeof presetOrOptions === "string" ? presets[presetOrOptions] : presetOrOptions;
7
+ if (!options) throw new Error(`Action battle enemy preset not found: ${presetOrOptions}`);
8
+ options.stats?.(event);
9
+ return new BattleAi(event, options);
10
+ };
11
+ //#endregion
12
+ export { createActionEnemy, defineActionBattleAiPreset, defineActionBattleEnemy };
@@ -34,67 +34,108 @@ var DEFAULT_ACTION_BATTLE_OPTIONS = {
34
34
  };
35
35
  var currentActionBattleOptions = DEFAULT_ACTION_BATTLE_OPTIONS;
36
36
  function normalizeActionBattleOptions(options = {}) {
37
+ const combat = {
38
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat,
39
+ ...options.systems?.combat,
40
+ ...options.combat,
41
+ hooks: {
42
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat?.hooks,
43
+ ...options.systems?.combat?.hooks,
44
+ ...options.combat?.hooks
45
+ }
46
+ };
37
47
  const attack = {
38
48
  ...DEFAULT_ACTION_BATTLE_OPTIONS.attack,
39
- ...options.attack
49
+ ...options.attack,
50
+ ...combat.attack
40
51
  };
41
52
  const attackProfile = normalizeActionBattleAttackProfile(attack.profile, {
42
53
  lockMovement: attack.lockMovement,
43
54
  lockDurationMs: attack.lockDurationMs,
44
55
  hitboxes: attack.hitboxes
45
56
  });
57
+ const normalizedAttack = {
58
+ ...attack,
59
+ profile: attackProfile
60
+ };
61
+ const skills = {
62
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.skills,
63
+ ...options.skills
64
+ };
65
+ skills.targeting = skills.targeting ?? skills.getTargeting;
66
+ skills.getTargeting = skills.getTargeting ?? skills.targeting;
67
+ const defaultActionBar = DEFAULT_ACTION_BATTLE_OPTIONS.ui?.actionBar;
68
+ const defaultTargeting = DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting;
69
+ const optionActionBar = options.ui?.actionBar;
70
+ const optionTargeting = options.ui?.targeting;
71
+ const optionAttackPreview = options.ui?.attackPreview;
72
+ const actionBar = options.ui?.actionBar === false ? {
73
+ ...defaultActionBar,
74
+ enabled: false
75
+ } : {
76
+ ...defaultActionBar,
77
+ ...options.ui?.actionBar === true ? { enabled: true } : optionActionBar
78
+ };
79
+ const legacyPreviewEnabled = normalizedAttack.showPreview !== false;
80
+ const attackPreview = options.ui?.attackPreview === false ? { enabled: false } : {
81
+ enabled: options.ui?.attackPreview === true ? true : legacyPreviewEnabled,
82
+ ...options.ui?.attackPreview === true ? {} : optionAttackPreview
83
+ };
84
+ const targeting = options.ui?.targeting === false ? {
85
+ ...defaultTargeting,
86
+ enabled: false
87
+ } : {
88
+ ...defaultTargeting,
89
+ ...options.ui?.targeting === true ? { enabled: true } : optionTargeting,
90
+ colors: {
91
+ ...defaultTargeting?.colors,
92
+ ...typeof options.ui?.targeting === "object" ? optionTargeting?.colors : void 0
93
+ }
94
+ };
95
+ const ai = {
96
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai,
97
+ ...options.systems?.ai,
98
+ ...options.ai,
99
+ behaviors: {
100
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai?.behaviors,
101
+ ...options.systems?.ai?.behaviors,
102
+ ...options.ai?.behaviors
103
+ },
104
+ presets: {
105
+ ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai?.presets,
106
+ ...options.systems?.ai?.presets,
107
+ ...options.ai?.presets
108
+ }
109
+ };
46
110
  return {
47
111
  ui: {
48
- actionBar: {
49
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.actionBar,
50
- ...options.ui?.actionBar
51
- },
52
- targeting: {
53
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting,
54
- ...options.ui?.targeting,
55
- colors: {
56
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting?.colors,
57
- ...options.ui?.targeting?.colors
58
- }
59
- }
60
- },
61
- skills: {
62
- ...DEFAULT_ACTION_BATTLE_OPTIONS.skills,
63
- ...options.skills
112
+ ...options.ui,
113
+ actionBar,
114
+ targeting,
115
+ attackPreview
64
116
  },
117
+ skills,
65
118
  targeting: {
66
119
  ...DEFAULT_ACTION_BATTLE_OPTIONS.targeting,
67
120
  ...options.targeting
68
121
  },
69
- debug: {
70
- ...DEFAULT_ACTION_BATTLE_OPTIONS.debug,
71
- ...options.debug
72
- },
73
- attack: {
74
- ...attack,
75
- profile: attackProfile
122
+ attack: normalizedAttack,
123
+ combat: {
124
+ ...combat,
125
+ attack: normalizedAttack
76
126
  },
127
+ ai,
128
+ visual: options.visual,
77
129
  animations: {
78
130
  ...DEFAULT_ACTION_BATTLE_OPTIONS.animations,
79
131
  ...options.animations
80
132
  },
81
133
  systems: {
82
134
  combat: {
83
- ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat,
84
- ...options.systems?.combat,
85
- hooks: {
86
- ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat?.hooks,
87
- ...options.systems?.combat?.hooks
88
- }
135
+ ...combat,
136
+ attack: normalizedAttack
89
137
  },
90
- ai: {
91
- ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai,
92
- ...options.systems?.ai,
93
- behaviors: {
94
- ...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai?.behaviors,
95
- ...options.systems?.ai?.behaviors
96
- }
97
- }
138
+ ai
98
139
  }
99
140
  };
100
141
  }
@@ -1,143 +1,206 @@
1
- //#region src/core/defaults.ts
2
- var DEFAULT_CORE_KNOCKBACK = {
3
- force: 50,
4
- duration: 300
1
+ import { playActionBattleAnimation } from "./index2.js";
2
+ import { getActionBattleOptions } from "./index5.js";
3
+ //#region src/visual.ts
4
+ var ACTION_BATTLE_CLIENT_VISUAL_ID = "action-battle.visual";
5
+ var ACTION_BATTLE_HIT_FX_COMPONENT_ID = "action-battle-hit-fx";
6
+ var previewStarter;
7
+ function setActionBattlePreviewStarter(starter) {
8
+ previewStarter = starter;
9
+ }
10
+ var entityId = (entity) => typeof entity?.id === "string" ? entity.id : void 0;
11
+ var serializeSkill = (skill) => {
12
+ const id = skill?.id;
13
+ if (typeof id === "string") return { id };
14
+ if (typeof id === "function") {
15
+ const value = id.call(skill);
16
+ if (typeof value === "string") return { id: value };
17
+ }
5
18
  };
6
- var CoreAttackPattern = {
7
- Melee: "melee",
8
- Combo: "combo",
9
- Charged: "charged",
10
- Zone: "zone",
11
- DashAttack: "dashAttack"
19
+ var serializeResult = (result) => {
20
+ if (!result) return void 0;
21
+ return {
22
+ damage: result.damage,
23
+ knockbackForce: result.knockbackForce,
24
+ knockbackDuration: result.knockbackDuration,
25
+ defeated: result.defeated,
26
+ attackerId: entityId(result.attacker),
27
+ targetId: entityId(result.target),
28
+ rawDamage: result.rawDamage,
29
+ reaction: result.reaction,
30
+ cancelled: result.cancelled,
31
+ metadata: result.metadata
32
+ };
12
33
  };
13
- var CoreEnemyType = {
14
- Aggressive: "aggressive",
15
- Defensive: "defensive",
16
- Ranged: "ranged",
17
- Tank: "tank",
18
- Berserker: "berserker"
34
+ var serializeActionBattleVisualContext = (context) => ({
35
+ moment: context.moment,
36
+ objectId: entityId(context.entity),
37
+ sourceId: entityId(context.attacker ?? context.entity),
38
+ targetId: entityId(context.target),
39
+ damage: context.damage,
40
+ defeated: context.defeated,
41
+ result: serializeResult(context.result),
42
+ skill: serializeSkill(context.skill),
43
+ pattern: context.pattern,
44
+ animations: context.animations,
45
+ animationDefaults: context.animationDefaults
46
+ });
47
+ function emitActionBattleClientVisual(context) {
48
+ if (getActionBattleOptions().visual === "none") return;
49
+ const map = (context.entity ?? context.target ?? context.attacker)?.getCurrentMap?.();
50
+ if (!map?.clientVisual) return;
51
+ map.clientVisual(ACTION_BATTLE_CLIENT_VISUAL_ID, serializeActionBattleVisualContext(context));
52
+ }
53
+ function createActionBattleClientVisuals(options = getActionBattleOptions()) {
54
+ return { [ACTION_BATTLE_CLIENT_VISUAL_ID]: (context) => {
55
+ const data = context.data ?? {};
56
+ playActionBattleVisual(options.visual, {
57
+ moment: data.moment,
58
+ entity: context.object ?? context.source ?? context.target,
59
+ target: context.target,
60
+ attacker: context.source,
61
+ damage: data.damage,
62
+ defeated: data.defeated,
63
+ result: data.result,
64
+ skill: data.skill,
65
+ pattern: data.pattern,
66
+ animations: data.animations ?? options.animations,
67
+ animationDefaults: data.animationDefaults
68
+ });
69
+ } };
70
+ }
71
+ var callGraphic = (entity, keyOrOptions, context) => {
72
+ if (!entity || keyOrOptions == null) return;
73
+ if (typeof keyOrOptions === "string") {
74
+ playActionBattleAnimation(keyOrOptions, entity, context?.animations ?? getActionBattleOptions().animations, {
75
+ attacker: context?.attacker,
76
+ target: context?.target,
77
+ skill: context?.skill
78
+ }, context?.animationDefaults);
79
+ return;
80
+ }
81
+ const animationName = keyOrOptions.animationName;
82
+ if (!animationName) return;
83
+ const repeat = keyOrOptions.repeat ?? 1;
84
+ const graphic = keyOrOptions.graphic;
85
+ if (typeof entity.setGraphicAnimation === "function") {
86
+ if (graphic !== void 0) entity.setGraphicAnimation(animationName, graphic, repeat);
87
+ else entity.setGraphicAnimation(animationName, repeat);
88
+ return;
89
+ }
90
+ if (typeof entity.setAnimation === "function") if (graphic !== void 0) entity.setAnimation(animationName, graphic, repeat);
91
+ else entity.setAnimation(animationName, repeat);
19
92
  };
20
- var DEFAULT_ZELDA_PLAYER_HITBOXES = {
21
- up: {
22
- offsetX: -16,
23
- offsetY: -48,
24
- width: 32,
25
- height: 32
93
+ var createHelpers = (context) => ({
94
+ graphic(entity, keyOrOptions) {
95
+ callGraphic(entity, keyOrOptions, context);
26
96
  },
27
- down: {
28
- offsetX: -16,
29
- offsetY: 16,
30
- width: 32,
31
- height: 32
97
+ flash(entity, options = {}) {
98
+ entity?.flash?.({
99
+ type: "tint",
100
+ tint: "red",
101
+ duration: 200,
102
+ cycles: 1,
103
+ ...options
104
+ });
32
105
  },
33
- left: {
34
- offsetX: -48,
35
- offsetY: -16,
36
- width: 32,
37
- height: 32
106
+ damageText(entity, damageOrText) {
107
+ if (typeof damageOrText === "string") {
108
+ if (entity?.showHit) {
109
+ entity.showHit(damageOrText);
110
+ return;
111
+ }
112
+ entity?.showComponentAnimation?.("hit", {
113
+ text: damageOrText,
114
+ direction: entity?.direction?.() ?? entity?.direction
115
+ });
116
+ return;
117
+ }
118
+ const damage = damageOrText ?? context.damage ?? context.result?.damage;
119
+ if (damage === void 0) return;
120
+ const text = `-${damage}`;
121
+ if (entity?.showHit) {
122
+ entity.showHit(text);
123
+ return;
124
+ }
125
+ entity?.showComponentAnimation?.("hit", {
126
+ text,
127
+ direction: entity?.direction?.() ?? entity?.direction
128
+ });
38
129
  },
39
- right: {
40
- offsetX: 16,
41
- offsetY: -16,
42
- width: 32,
43
- height: 32
130
+ component(entity, id, params = {}) {
131
+ entity?.showComponentAnimation?.(id, params);
44
132
  },
45
- default: {
46
- offsetX: 0,
47
- offsetY: -32,
48
- width: 32,
49
- height: 32
133
+ preview(entity, options = {}) {
134
+ previewStarter?.(entity, options);
50
135
  }
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;
136
+ });
137
+ var classicParts = {
138
+ attack({ entity }, fx) {
139
+ fx.graphic(entity, "attack");
140
+ },
141
+ castSkill({ entity }, fx) {
142
+ fx.graphic(entity, "castSkill");
143
+ },
144
+ preview({ entity }, fx) {
145
+ fx.preview(entity);
146
+ },
147
+ hit({ target, damage }, fx) {
148
+ fx.flash(target);
149
+ fx.damageText(target, damage);
150
+ },
151
+ hurt({ entity, target }, fx) {
152
+ const hurtTarget = target ?? entity;
153
+ fx.flash(hurtTarget);
154
+ fx.damageText(hurtTarget);
155
+ fx.graphic(hurtTarget, "hurt");
156
+ },
157
+ defeat({ entity, target }, fx) {
158
+ fx.graphic(target ?? entity, "die");
58
159
  }
59
- return null;
60
160
  };
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
- };
161
+ var fxParts = {
162
+ ...classicParts,
163
+ hit(context, fx) {
164
+ classicParts.hit?.(context, fx);
165
+ fx.component(context.target, ACTION_BATTLE_HIT_FX_COMPONENT_ID, {
166
+ name: "hitSpark",
167
+ scale: .8,
168
+ zIndex: 1e3
169
+ });
170
+ },
171
+ hurt(context, fx) {
172
+ classicParts.hurt?.(context, fx);
173
+ fx.component(context.target ?? context.entity, ACTION_BATTLE_HIT_FX_COMPONENT_ID, {
174
+ name: "hitSpark",
175
+ scale: .8,
176
+ zIndex: 1e3
177
+ });
178
+ }
70
179
  };
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
- }];
180
+ var resolveParts = (input) => {
181
+ const visual = input ?? "classic";
182
+ if (visual === "none") return null;
183
+ if (visual === "classic") return classicParts;
184
+ if (visual === "fx") return fxParts;
185
+ if (typeof visual === "function") return null;
186
+ return visual;
80
187
  };
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
188
+ function createActionBattleVisual(input = "classic") {
189
+ if (typeof input === "function") return input;
190
+ const parts = resolveParts(input);
191
+ const composer = (context) => {
192
+ if (!parts) return;
193
+ const part = parts[context.moment];
194
+ if (!part) return;
195
+ part(context, createHelpers(context));
88
196
  };
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 defaultActionBattleSystems = {
139
- combat: defaultCombatSystem,
140
- ai: { behaviors: defaultEnemyBehaviors }
141
- };
197
+ composer.__actionBattleUsesFx = input === "fx";
198
+ return composer;
199
+ }
200
+ var createClassicActionBattleVisual = () => createActionBattleVisual("classic");
201
+ var createFxActionBattleVisual = () => createActionBattleVisual("fx");
202
+ function playActionBattleVisual(visual, context) {
203
+ (typeof visual === "function" ? visual : createActionBattleVisual(visual))(context);
204
+ }
142
205
  //#endregion
143
- export { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultActionBattleSystems, defaultCombatSystem, defaultEnemyBehaviors, defaultKnockbackResolver, defaultRpgjsDamageResolver };
206
+ export { ACTION_BATTLE_CLIENT_VISUAL_ID, ACTION_BATTLE_HIT_FX_COMPONENT_ID, createActionBattleClientVisuals, createActionBattleVisual, createClassicActionBattleVisual, createFxActionBattleVisual, emitActionBattleClientVisual, playActionBattleVisual, setActionBattlePreviewStarter };