@rpgjs/action-battle 5.0.0-beta.2 → 5.0.0-beta.4

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 (55) hide show
  1. package/README.md +137 -0
  2. package/dist/ai.server.d.ts +8 -1
  3. package/dist/client/index.js +19 -31
  4. package/dist/client/index10.js +142 -29
  5. package/dist/client/index11.js +25 -0
  6. package/dist/client/index12.js +1222 -0
  7. package/dist/client/index13.js +46 -0
  8. package/dist/client/index14.js +10 -0
  9. package/dist/client/index15.js +448 -0
  10. package/dist/client/index2.js +93 -46
  11. package/dist/client/index3.js +82 -1329
  12. package/dist/client/index4.js +305 -344
  13. package/dist/client/index5.js +36 -291
  14. package/dist/client/index6.js +99 -95
  15. package/dist/client/index7.js +78 -61
  16. package/dist/client/index8.js +57 -65
  17. package/dist/client/index9.js +97 -62
  18. package/dist/client.d.ts +3 -2
  19. package/dist/core/context.d.ts +5 -0
  20. package/dist/core/defaults.d.ts +81 -0
  21. package/dist/core/hit.d.ts +2 -0
  22. package/dist/enemies/factory.d.ts +7 -0
  23. package/dist/index.d.ts +9 -4
  24. package/dist/server/index.js +18 -31
  25. package/dist/server/index10.js +10 -0
  26. package/dist/server/index2.js +59 -345
  27. package/dist/server/index3.js +92 -1329
  28. package/dist/server/index4.js +141 -67
  29. package/dist/server/index5.js +24 -29
  30. package/dist/server/index6.js +1219 -62
  31. package/dist/server/index7.js +37 -0
  32. package/dist/server/index8.js +46 -0
  33. package/dist/server/index9.js +447 -0
  34. package/dist/server.d.ts +5 -3
  35. package/dist/ui/state.d.ts +20 -3
  36. package/package.json +5 -5
  37. package/src/ai.server.ts +91 -24
  38. package/src/animations.ts +43 -4
  39. package/src/canvas-engine-shim.ts +4 -0
  40. package/src/client.ts +122 -2
  41. package/src/components/action-bar.ce +5 -3
  42. package/src/components/attack-preview.ce +90 -0
  43. package/src/config.ts +30 -0
  44. package/src/core/context.ts +35 -0
  45. package/src/core/contracts.ts +123 -0
  46. package/src/core/defaults.ts +162 -0
  47. package/src/core/hit.spec.ts +58 -0
  48. package/src/core/hit.ts +66 -0
  49. package/src/enemies/factory.ts +25 -0
  50. package/src/index.ts +40 -0
  51. package/src/server.ts +235 -71
  52. package/src/targeting.spec.ts +24 -0
  53. package/src/types/canvas-engine.d.ts +4 -0
  54. package/src/types.ts +46 -1
  55. package/src/ui/state.ts +57 -0
@@ -1,69 +1,143 @@
1
- const DEFAULT_ACTION_BATTLE_OPTIONS = {
2
- ui: {
3
- actionBar: {
4
- enabled: false,
5
- autoOpen: false,
6
- mode: "both"
7
- },
8
- targeting: {
9
- enabled: true,
10
- showGrid: true,
11
- colors: {
12
- area: 3120887,
13
- edge: 1796760,
14
- cursor: 16765286
15
- }
16
- }
17
- },
18
- skills: {
19
- defaultAoeMask: ["#"]
20
- },
21
- targeting: {
22
- affects: "events",
23
- allowEmptyTarget: true
24
- },
25
- animations: {}
1
+ //#region src/core/defaults.ts
2
+ var DEFAULT_CORE_KNOCKBACK = {
3
+ force: 50,
4
+ duration: 300
26
5
  };
27
- let currentActionBattleOptions = DEFAULT_ACTION_BATTLE_OPTIONS;
28
- function normalizeActionBattleOptions(options = {}) {
29
- return {
30
- ui: {
31
- actionBar: {
32
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.actionBar,
33
- ...options.ui?.actionBar
34
- },
35
- targeting: {
36
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting,
37
- ...options.ui?.targeting,
38
- colors: {
39
- ...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting?.colors,
40
- ...options.ui?.targeting?.colors
41
- }
42
- }
43
- },
44
- skills: {
45
- ...DEFAULT_ACTION_BATTLE_OPTIONS.skills,
46
- ...options.skills
47
- },
48
- targeting: {
49
- ...DEFAULT_ACTION_BATTLE_OPTIONS.targeting,
50
- ...options.targeting
51
- },
52
- animations: {
53
- ...DEFAULT_ACTION_BATTLE_OPTIONS.animations,
54
- ...options.animations
55
- }
56
- };
57
- }
58
- function setActionBattleOptions(options) {
59
- currentActionBattleOptions = options;
60
- }
61
- function getActionBattleOptions() {
62
- return currentActionBattleOptions;
63
- }
64
- export {
65
- DEFAULT_ACTION_BATTLE_OPTIONS,
66
- getActionBattleOptions,
67
- normalizeActionBattleOptions,
68
- setActionBattleOptions
6
+ var CoreAttackPattern = {
7
+ Melee: "melee",
8
+ Combo: "combo",
9
+ Charged: "charged",
10
+ Zone: "zone",
11
+ DashAttack: "dashAttack"
69
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 defaultActionBattleSystems = {
139
+ combat: defaultCombatSystem,
140
+ ai: { behaviors: defaultEnemyBehaviors }
141
+ };
142
+ //#endregion
143
+ export { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultActionBattleSystems, defaultCombatSystem, defaultEnemyBehaviors, defaultKnockbackResolver, defaultRpgjsDamageResolver };
@@ -1,30 +1,25 @@
1
- const normalizeMaskRows = (mask) => {
2
- if (!mask) return ["#"];
3
- if (Array.isArray(mask)) return mask;
4
- return mask.trim().split("\n").map((row) => row.replace(/\r/g, ""));
5
- };
6
- const parseAoeMask = (mask) => {
7
- const rows = normalizeMaskRows(mask);
8
- const height = rows.length;
9
- const width = rows.reduce((max, row) => Math.max(max, row.length), 0);
10
- const centerX = Math.floor(width / 2);
11
- const centerY = Math.floor(height / 2);
12
- const cells = [];
13
- rows.forEach((row, y) => {
14
- for (let x = 0; x < row.length; x++) {
15
- const char = row[x];
16
- if (char && char !== "." && char !== " ") {
17
- cells.push({ dx: x - centerX, dy: y - centerY });
18
- }
19
- }
20
- });
21
- if (cells.length === 0) {
22
- cells.push({ dx: 0, dy: 0 });
23
- }
24
- return { width, height, centerX, centerY, cells };
25
- };
26
- const manhattanDistance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
27
- export {
28
- manhattanDistance,
29
- parseAoeMask
1
+ import { defaultActionBattleSystems } from "./index4.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);
30
21
  };
22
+ var getActionBattleSystems = () => currentActionBattleSystems;
23
+ var createActionBattleSystems = mergeSystems;
24
+ //#endregion
25
+ export { createActionBattleSystems, getActionBattleSystems, setActionBattleSystems };