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

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 +57 -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 +3 -2
  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 +203 -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 +70 -0
  25. package/dist/client/index22.js +226 -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 +1949 -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 +57 -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 +3 -2
  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 +67 -11
  56. package/dist/server/index14.js +207 -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 +1949 -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 +208 -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 +380 -1
  79. package/src/ai.server.ts +963 -137
  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 +387 -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 +72 -1
  96. package/src/core/equipment.ts +9 -5
  97. package/src/core/hit.spec.ts +21 -0
  98. package/src/core/targets.spec.ts +124 -0
  99. package/src/core/targets.ts +150 -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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @rpgjs/action-battle
2
2
 
3
+ ## 5.0.0-beta.13
4
+
5
+ ### Patch Changes
6
+
7
+ - Release the next RPGJS beta with client interactions, i18n support, movement and physics improvements, Studio fixes, action battle updates, playground migration, and related runtime documentation.
8
+ - Updated dependencies
9
+ - @rpgjs/client@5.0.0-beta.13
10
+ - @rpgjs/common@5.0.0-beta.13
11
+ - @rpgjs/server@5.0.0-beta.13
12
+ - @rpgjs/vite@5.0.0-beta.13
13
+
14
+ ## 5.0.0-beta.12
15
+
16
+ ### Patch Changes
17
+
18
+ - Prepare beta.12 with action battle AI, area queries, client visuals, event component resolvers, projectile handling, and related Vite/runtime updates.
19
+ - Updated dependencies
20
+ - @rpgjs/client@5.0.0-beta.12
21
+ - @rpgjs/common@5.0.0-beta.12
22
+ - @rpgjs/server@5.0.0-beta.12
23
+ - @rpgjs/vite@5.0.0-beta.12
24
+
3
25
  ## 5.0.0-beta.11
4
26
 
5
27
  ### Patch Changes
@@ -1,6 +1,7 @@
1
1
  import { RpgEvent, RpgPlayer } from '@rpgjs/server';
2
2
  import { ActionBattleEnemyAttackProfileMap } from './core/enemy-attack-profiles';
3
- import { ActionBattleDamageResult } from './core/contracts';
3
+ import { ActionBattleAiSimpleBehavior, ActionBattleAiTreeInput } from './core/ai-behavior-tree';
4
+ import { ActionBattleAiPreset, ActionBattleDamageResult, ActionBattleEntity, ActionBattleTargetSelector } from './core/contracts';
4
5
  import { NormalizedActionBattleHitReactionProfile, ActionBattleAnimationOptions } from './types';
5
6
  type RpgEventWithBattleAi = RpgEvent & {
6
7
  battleAi?: BattleAi;
@@ -23,13 +24,16 @@ export interface BattleAiDefeatReward {
23
24
  }
24
25
  export interface BattleAiDefeatedContext {
25
26
  event: RpgEvent;
26
- attacker?: RpgPlayer;
27
+ attacker?: ActionBattleEntity;
27
28
  reward: BattleAiDefeatReward;
28
29
  remove: () => void;
29
30
  }
30
31
  export type BattleAiDefeatedCallback = (context: BattleAiDefeatedContext) => void;
31
- export type BattleAiLegacyDefeatedCallback = (event: RpgEvent, attacker?: RpgPlayer) => void;
32
+ export type BattleAiLegacyDefeatedCallback = (event: RpgEvent, attacker?: ActionBattleEntity) => void;
32
33
  export interface BattleAiBaseOptions {
34
+ preset?: string | ActionBattleAiPreset;
35
+ faction?: string;
36
+ targets?: ActionBattleTargetSelector;
33
37
  enemyType?: EnemyType;
34
38
  attackCooldown?: number;
35
39
  visionRange?: number;
@@ -58,6 +62,9 @@ export interface BattleAiBaseOptions {
58
62
  retreatThreshold?: number;
59
63
  };
60
64
  behaviorKey?: string;
65
+ tree?: ActionBattleAiTreeInput;
66
+ behaviorTree?: ActionBattleAiTreeInput;
67
+ simpleBehavior?: ActionBattleAiSimpleBehavior;
61
68
  animations?: ActionBattleAnimationOptions;
62
69
  rewards?: BattleAiRewards;
63
70
  autoAwardRewards?: boolean;
@@ -276,10 +283,15 @@ export declare class BattleAi {
276
283
  * Log AI debug message for this event
277
284
  */
278
285
  private debugLog;
286
+ private traceLog;
287
+ private lockActionUntil;
288
+ private lockForAttack;
279
289
  private state;
280
290
  private stateStartTime;
281
291
  private stunnedUntil;
282
292
  private enemyType;
293
+ private faction?;
294
+ private targets;
283
295
  private attackCooldown;
284
296
  private visionRange;
285
297
  private attackRange;
@@ -320,11 +332,23 @@ export declare class BattleAi {
320
332
  private lastMoveToTime;
321
333
  private retreatCooldown;
322
334
  private lastRetreatTime;
335
+ private actionLockedUntil;
336
+ private lastActionLockTraceTime;
337
+ private lastMoveToCooldownTraceTime;
338
+ private lastMoveToCooldownTraceSignature;
339
+ private lastTargetMovementSkipTraceTime;
323
340
  private timers;
324
341
  private behaviorKey?;
342
+ private behaviorTree?;
343
+ private aiMemory;
325
344
  private poise;
326
345
  private hitstunMs;
327
346
  private invincibilityMs;
347
+ private visionShape?;
348
+ private visionSetupRetries;
349
+ private maxVisionSetupRetries;
350
+ private destroyed;
351
+ private lastNoTargetTraceTime;
328
352
  /**
329
353
  * Create a new Battle AI Controller
330
354
  *
@@ -362,6 +386,7 @@ export declare class BattleAi {
362
386
  * Setup vision detection
363
387
  */
364
388
  private setupVision;
389
+ private scheduleVisionSetup;
365
390
  /**
366
391
  * Start the AI behavior loop
367
392
  */
@@ -412,6 +437,9 @@ export declare class BattleAi {
412
437
  * Perform basic hitbox attack when no skill is set
413
438
  */
414
439
  private performBasicHitbox;
440
+ private resolveBasicHitboxes;
441
+ private queryHitboxCandidates;
442
+ private processHitboxHits;
415
443
  /**
416
444
  * Apply hit to target using RPGJS damage system with knockback
417
445
  *
@@ -476,6 +504,7 @@ export declare class BattleAi {
476
504
  */
477
505
  private performDashAttack;
478
506
  private getAttackProfile;
507
+ private playAttackVisual;
479
508
  private telegraphAttack;
480
509
  private scheduleAttackStartup;
481
510
  /**
@@ -524,19 +553,20 @@ export declare class BattleAi {
524
553
  /**
525
554
  * Handle player entering vision
526
555
  */
527
- onDetectInShape(player: InstanceType<typeof RpgPlayer>, shape: any): void;
556
+ onDetectInShape(target: ActionBattleEntity, shape: any): void;
557
+ private engageTarget;
528
558
  /**
529
559
  * Handle player leaving vision
530
560
  */
531
- onDetectOutShape(player: InstanceType<typeof RpgPlayer>, shape: any): void;
561
+ onDetectOutShape(target: ActionBattleEntity, shape: any): void;
532
562
  /**
533
563
  * Handle taking damage (called from server.ts)
534
564
  *
535
565
  * This triggers state changes like stun and flee check.
536
566
  * The actual damage is applied externally via RPGJS API.
537
567
  */
538
- takeDamage(attacker: RpgPlayer): boolean;
539
- handleDamage(attacker: RpgPlayer, damageResult: ActionBattleDamageResult & {
568
+ takeDamage(attacker: ActionBattleEntity): boolean;
569
+ handleDamage(attacker: ActionBattleEntity, damageResult: ActionBattleDamageResult & {
540
570
  reaction?: NormalizedActionBattleHitReactionProfile;
541
571
  }): boolean;
542
572
  /**
@@ -550,16 +580,35 @@ export declare class BattleAi {
550
580
  * Get distance between entities
551
581
  */
552
582
  private getDistance;
583
+ private resolveUsable;
584
+ private getCurrentActionRange;
585
+ private canTarget;
586
+ private findNearestTarget;
587
+ private isTargetDefeated;
588
+ private clearTarget;
553
589
  private updateBehavior;
554
590
  private applyCustomBehavior;
591
+ private applyAiDecision;
592
+ private createAiTreeContext;
593
+ private executeAiIntents;
594
+ private executeAiIntent;
595
+ private executeKeepDistance;
596
+ private executeRequestedAttack;
597
+ private executeRequestedSkill;
555
598
  private handleTacticalMovement;
556
599
  private handleAssaultMovement;
600
+ private resolveMoveTarget;
557
601
  private requestMoveTo;
602
+ private requestTargetMovement;
558
603
  private schedule;
559
604
  getHealth(): number;
560
605
  getMaxHealth(): number;
561
- getTarget(): InstanceType<typeof RpgPlayer> | null;
606
+ getTarget(): ActionBattleEntity | null;
562
607
  getState(): AiState;
608
+ getFaction(): string | undefined;
609
+ setFaction(faction: string | undefined): void;
610
+ getTargets(): ActionBattleTargetSelector;
611
+ setTargets(targets: ActionBattleTargetSelector): void;
563
612
  getEnemyType(): EnemyType;
564
613
  /**
565
614
  * Clean up
@@ -0,0 +1,3 @@
1
+ export type ActionBattleResolvedDirection = "up" | "down" | "left" | "right";
2
+ export declare const resolveActionBattleAttackDirection: (entity: any, input?: any) => ActionBattleResolvedDirection;
3
+ export declare const applyActionBattleAttackDirection: (entity: any, direction: ActionBattleResolvedDirection) => void;
@@ -0,0 +1,18 @@
1
+ import { ActionBattleActionConfig, ActionBattleActionTarget, ActionBattleEntity, ActionBattleTargetOptions, ActionBattleProjectileImpactContext } from './contracts';
2
+ import { NormalizedActionBattleAttackProfile } from '../types';
3
+ export declare const getActionBattleActionConfig: (usable: any) => ActionBattleActionConfig | undefined;
4
+ export declare const getActionBattleActionRange: (usable: any) => number | undefined;
5
+ export declare const canActionBattleUseTarget: (attacker: ActionBattleEntity, target: ActionBattleEntity, actionTarget?: ActionBattleActionTarget, options?: ActionBattleTargetOptions) => boolean;
6
+ export declare const shouldUseActionBattleUsable: (usable: any, explicitSkill?: any) => boolean;
7
+ export declare const executeActionBattleUse: (input: {
8
+ attacker: ActionBattleEntity;
9
+ target?: ActionBattleEntity | ActionBattleEntity[] | null;
10
+ usable: any;
11
+ skill?: any;
12
+ weapon?: any;
13
+ pattern?: string;
14
+ profile?: NormalizedActionBattleAttackProfile;
15
+ playVisual?: boolean;
16
+ }) => boolean;
17
+ export declare const handleActionBattleProjectileImpact: (context: ActionBattleProjectileImpactContext) => void;
18
+ export declare const handleActionBattleProjectileDestroy: (projectileId: string) => void;
@@ -0,0 +1,99 @@
1
+ import { RpgEvent, RpgPlayer } from '@rpgjs/server';
2
+ import { AiState, AttackPattern, EnemyType } from '../ai.server';
3
+ import { ActionBattleAiContext, ActionBattleAiDecision } from './contracts';
4
+ export type ActionBattleAiTreeStatus = "success" | "failure" | "running";
5
+ export type ActionBattleAiMemory = Record<string, any>;
6
+ export interface ActionBattleAiIntentBase {
7
+ consume?: boolean;
8
+ metadata?: Record<string, any>;
9
+ }
10
+ export type ActionBattleAiIntent = (ActionBattleAiIntentBase & {
11
+ type: "idle";
12
+ }) | (ActionBattleAiIntentBase & {
13
+ type: "patrol";
14
+ }) | (ActionBattleAiIntentBase & {
15
+ type: "faceTarget";
16
+ }) | (ActionBattleAiIntentBase & {
17
+ type: "moveToTarget";
18
+ }) | (ActionBattleAiIntentBase & {
19
+ type: "fleeFromTarget";
20
+ }) | (ActionBattleAiIntentBase & {
21
+ type: "keepDistance";
22
+ distance: number;
23
+ tolerance?: number;
24
+ }) | (ActionBattleAiIntentBase & {
25
+ type: "useAttack";
26
+ pattern?: AttackPattern | string;
27
+ }) | (ActionBattleAiIntentBase & {
28
+ type: "useSkill";
29
+ skill: any;
30
+ }) | (ActionBattleAiIntentBase & {
31
+ type: "setMode";
32
+ mode: NonNullable<ActionBattleAiDecision["mode"]>;
33
+ });
34
+ export interface ActionBattleAiSnapshotSelf {
35
+ event: RpgEvent;
36
+ state: AiState;
37
+ enemyType: EnemyType;
38
+ hpPercent: number | null;
39
+ attackRange: number;
40
+ }
41
+ export interface ActionBattleAiSnapshotTarget {
42
+ entity: RpgPlayer;
43
+ distance: number;
44
+ inAttackRange: boolean;
45
+ visible: boolean;
46
+ }
47
+ export interface ActionBattleAiTreeContext extends ActionBattleAiContext {
48
+ self: ActionBattleAiSnapshotSelf;
49
+ targetInfo: ActionBattleAiSnapshotTarget | null;
50
+ memory: ActionBattleAiMemory;
51
+ }
52
+ export interface ActionBattleAiTreeResult {
53
+ status: ActionBattleAiTreeStatus;
54
+ decision?: ActionBattleAiDecision;
55
+ intent?: ActionBattleAiIntent | ActionBattleAiIntent[];
56
+ }
57
+ export interface ActionBattleAiTreeNode {
58
+ tick(context: ActionBattleAiTreeContext): ActionBattleAiTreeResult;
59
+ }
60
+ export type ActionBattleAiTreeInput = ActionBattleAiTreeNode | ((context: ActionBattleAiTreeContext) => ActionBattleAiTreeResult | void);
61
+ export type ActionBattleAiCondition = (context: ActionBattleAiTreeContext) => boolean;
62
+ export type ActionBattleAiIntentInput = ActionBattleAiIntent | ActionBattleAiIntent[] | ActionBattleAiTreeNode | ((context: ActionBattleAiTreeContext) => ActionBattleAiIntent | ActionBattleAiIntent[]);
63
+ export interface ActionBattleAiRule {
64
+ condition: ActionBattleAiCondition;
65
+ then: ActionBattleAiIntentInput;
66
+ }
67
+ export interface ActionBattleAiSimpleBehavior {
68
+ when?: ActionBattleAiRule[];
69
+ otherwise?: ActionBattleAiIntentInput;
70
+ }
71
+ export declare const defineAiTree: (input: ActionBattleAiTreeInput) => ActionBattleAiTreeNode;
72
+ export declare const selector: (children: ActionBattleAiTreeInput[]) => ActionBattleAiTreeNode;
73
+ export declare const sequence: (children: ActionBattleAiTreeInput[]) => ActionBattleAiTreeNode;
74
+ export declare const condition: (predicate: ActionBattleAiCondition) => ActionBattleAiTreeNode;
75
+ export declare const action: (input: ActionBattleAiIntentInput, status?: ActionBattleAiTreeStatus) => ActionBattleAiTreeNode;
76
+ export declare const decision: (resolve: ActionBattleAiDecision | ((context: ActionBattleAiTreeContext) => ActionBattleAiDecision)) => ActionBattleAiTreeNode;
77
+ export declare const rule: (predicate: ActionBattleAiCondition, then: ActionBattleAiIntentInput) => ActionBattleAiRule;
78
+ export declare const defineAiBehavior: (behavior: ActionBattleAiSimpleBehavior) => ActionBattleAiTreeNode;
79
+ export declare const hpBelow: (ratio: number) => ActionBattleAiCondition;
80
+ export declare const targetVisible: () => ActionBattleAiCondition;
81
+ export declare const targetInRange: (range?: number) => ActionBattleAiCondition;
82
+ export declare const distanceLessThan: (distance: number) => ActionBattleAiCondition;
83
+ export declare const inState: (state: AiState) => ActionBattleAiCondition;
84
+ export declare const isEnemyType: (enemyType: EnemyType) => ActionBattleAiCondition;
85
+ export declare const idle: () => ActionBattleAiIntent;
86
+ export declare const patrol: () => ActionBattleAiIntent;
87
+ export declare const faceTarget: () => ActionBattleAiIntent;
88
+ export declare const chase: () => ActionBattleAiIntent;
89
+ export declare const moveToTarget: () => ActionBattleAiIntent;
90
+ export declare const flee: () => ActionBattleAiIntent;
91
+ export declare const fleeFromTarget: () => ActionBattleAiIntent;
92
+ export declare const keepDistance: (distance: number, tolerance?: number) => ActionBattleAiIntent;
93
+ export declare const useAttack: (pattern?: AttackPattern | string) => ActionBattleAiIntent;
94
+ export declare const useSkill: (skill: any) => ActionBattleAiIntent;
95
+ export declare const setMode: (mode: NonNullable<ActionBattleAiDecision["mode"]>) => ActionBattleAiIntent;
96
+ export declare const ifHpBelow: (ratio: number, then: ActionBattleAiIntentInput) => ActionBattleAiRule;
97
+ export declare const ifTargetVisible: (then: ActionBattleAiIntentInput) => ActionBattleAiRule;
98
+ export declare const ifTargetInRange: (then: ActionBattleAiIntentInput, range?: number) => ActionBattleAiRule;
99
+ export declare const ifDistanceLessThan: (distance: number, then: ActionBattleAiIntentInput) => ActionBattleAiRule;
@@ -1,8 +1,10 @@
1
1
  import { ActionBattleAttackHitPolicy, ActionBattleOptions, NormalizedActionBattleAttackProfile } from '../types';
2
+ import { ActionBattleHitbox } from './contracts';
2
3
  export declare const ACTION_BATTLE_HITBOX_FRAME_MS = 16;
3
4
  export declare function getNormalizedActionBattleAttackProfile(options?: ActionBattleOptions): NormalizedActionBattleAttackProfile;
4
5
  export declare function resolveActionBattleHitboxSpeed(profile: NormalizedActionBattleAttackProfile, hitboxCount: number): number;
5
6
  export declare function scheduleActionBattleStartup(profile: NormalizedActionBattleAttackProfile, callback: () => void, scheduler?: (callback: () => void, delayMs: number) => unknown): unknown;
7
+ export declare function runActionBattleActiveHitbox(profile: NormalizedActionBattleAttackProfile, resolveHitboxes: () => ActionBattleHitbox[], onHitboxes: (hitboxes: ActionBattleHitbox[]) => void, scheduler?: (callback: () => void, delayMs: number) => unknown): unknown;
6
8
  export declare function createActionBattleAttackId(attackerId: string | number | undefined, profileId: string): string;
7
9
  export declare class ActionBattleHitTracker {
8
10
  private readonly hitPolicy;
@@ -1,5 +1,5 @@
1
1
  import { RpgPlayer } from '@rpgjs/server';
2
- import { ActionBattleAiBehavior, ActionBattleAttackContext, ActionBattleCombatSystem, ActionBattleDamageContext, ActionBattleKnockbackContext, ActionBattleKnockbackResult, ActionBattleSystems } from './contracts';
2
+ import { ActionBattleAiBehavior, ActionBattleAiPreset, ActionBattleAttackContext, ActionBattleCombatSystem, ActionBattleDamageContext, ActionBattleKnockbackContext, ActionBattleKnockbackResult, ActionBattleSystems } from './contracts';
3
3
  export declare const DEFAULT_ZELDA_PLAYER_HITBOXES: {
4
4
  up: {
5
5
  offsetX: number;
@@ -70,12 +70,13 @@ export declare const createDefaultPlayerHitboxResolver: (hitboxes?: {
70
70
  height: number;
71
71
  }[];
72
72
  export declare const defaultRpgjsDamageResolver: (context: ActionBattleDamageContext) => {
73
- damage: any;
73
+ damage: number;
74
74
  defeated: boolean;
75
75
  raw: any;
76
76
  };
77
77
  export declare const defaultKnockbackResolver: (context: ActionBattleKnockbackContext) => ActionBattleKnockbackResult;
78
78
  export declare const defaultCombatSystem: ActionBattleCombatSystem;
79
79
  export declare const defaultEnemyBehaviors: Record<string, ActionBattleAiBehavior>;
80
+ export declare const defaultEnemyPresets: Record<string, ActionBattleAiPreset>;
80
81
  export declare const defaultActionBattleSystems: ActionBattleSystems;
81
82
  export declare const getEntityWeaponKnockbackForce: (entity: RpgPlayer) => number;
@@ -1,2 +1,3 @@
1
1
  import { ActionBattleAttackProfile } from '../types';
2
+ export declare function resolveActionBattleWeapon(entity: any): any | null;
2
3
  export declare function resolveActionBattleWeaponAttackProfile(entity: any): ActionBattleAttackProfile | null;
@@ -0,0 +1,15 @@
1
+ import { ActionBattleEntity, ActionBattleTargetContext, ActionBattleTargetOptions, ActionBattleTargetSelector } from './contracts';
2
+ export declare const ACTION_BATTLE_PLAYER_FACTION = "players";
3
+ export declare const ACTION_BATTLE_ENEMY_FACTION = "enemies";
4
+ type EntityKind = "player" | "event";
5
+ export declare const getActionBattleEntityKind: (entity: ActionBattleEntity) => EntityKind;
6
+ export declare const isActionBattlePlayer: (entity: ActionBattleEntity) => boolean;
7
+ export declare const isActionBattleEvent: (entity: ActionBattleEntity) => boolean;
8
+ export declare const isActionBattleCombatEntity: (entity: ActionBattleEntity | undefined | null) => entity is ActionBattleEntity;
9
+ export declare const getActionBattleFaction: (entity: ActionBattleEntity, options?: ActionBattleTargetOptions) => string | undefined;
10
+ export declare const getActionBattleTargets: (entity: ActionBattleEntity, fallback: ActionBattleTargetSelector) => ActionBattleTargetSelector;
11
+ export declare const isActionBattleTargetDefeated: (target: ActionBattleEntity | null | undefined) => boolean;
12
+ export declare const matchesActionBattleTargetSelector: (selector: ActionBattleTargetSelector | undefined, context: ActionBattleTargetContext) => boolean;
13
+ export declare const canActionBattleTarget: (attacker: ActionBattleEntity, target: ActionBattleEntity, selector: ActionBattleTargetSelector | undefined, options?: ActionBattleTargetOptions) => boolean;
14
+ export declare const getActionBattleEntitiesInRange: (attacker: ActionBattleEntity, radius: number, selector: ActionBattleTargetSelector | undefined, options?: ActionBattleTargetOptions) => ActionBattleEntity[];
15
+ export {};
@@ -4,4 +4,6 @@ export interface ActionBattleEnemyPreset extends BattleAiOptions {
4
4
  stats?: (event: RpgEvent) => void;
5
5
  }
6
6
  export type ActionBattleEnemyPresetMap = Record<string, ActionBattleEnemyPreset>;
7
+ export declare const defineActionBattleEnemy: <T extends ActionBattleEnemyPreset>(preset: T) => T;
8
+ export declare const defineActionBattleAiPreset: <T extends BattleAiOptions>(preset: T) => T;
7
9
  export declare const createActionEnemy: (event: RpgEvent, presetOrOptions: string | BattleAiOptions, presets?: ActionBattleEnemyPresetMap) => BattleAi;
@@ -1,18 +1,23 @@
1
1
  import { ActionBattleOptions } from './types';
2
2
  export { BattleAi, AiState, EnemyType, AttackPattern, AiDebug, DEFAULT_KNOCKBACK } from './ai.server';
3
3
  export type { HitResult, ApplyHitHooks, BattleAiOptions, BattleAiDefeatedCallback, BattleAiDefeatedContext, BattleAiDefeatReward, BattleAiLegacyDefeatedCallback, BattleAiLegacyOptions, BattleAiRewardItem, BattleAiRewards, } from './ai.server';
4
- export type { ActionBattleAnimationContext, ActionBattleAnimationEntity, ActionBattleAnimationKey, ActionBattleAnimationOptions, ActionBattleAnimationResolver, ActionBattleAnimationResult, ActionBattleOptions, ActionBattleActionBarData, ActionBattleActionBarItem, ActionBattleActionBarSkill, ActionBattleSkillTargeting, ActionBattleSkillTargetingResolver, ActionBattleAttackOptions, ActionBattleUiOptions, ActionBattleUiActionBarOptions, ActionBattleUiTargetingOptions, ActionBattleAttackDirection, ActionBattleAttackHitboxConfig, ActionBattleAttackHitboxMap, ActionBattleAttackHitPolicy, ActionBattleAttackProfile, ActionBattleDebugOptions, ActionBattleHitReactionProfile, NormalizedActionBattleHitReactionProfile, NormalizedActionBattleAttackProfile, ActionBattleCombatOptions, ActionBattleSystemOptions, ActionBattleAiSystemOptions, } from './types';
5
- export type { ActionBattleAiBehavior, ActionBattleAiContext, ActionBattleAiDecision, ActionBattleAttackContext, ActionBattleCombatSystem, ActionBattleDamageContext, ActionBattleDamageResult, ActionBattleDirection, ActionBattleEntity, ActionBattleHitContext, ActionBattleHitHooks, ActionBattleHitResult, ActionBattleHitbox, ActionBattleKnockbackContext, ActionBattleKnockbackResult, ActionBattleSystems, } from './core/contracts';
4
+ export type { ActionBattleAnimationContext, ActionBattleAnimationEntity, ActionBattleAnimationKey, ActionBattleAnimationOptions, ActionBattleAnimationResolver, ActionBattleAnimationResult, ActionBattleAiOptions, ActionBattleOptions, ActionBattleActionBarData, ActionBattleActionBarItem, ActionBattleActionBarSkill, ActionBattleSkillTargeting, ActionBattleSkillTargetingResolver, ActionBattleAttackOptions, ActionBattleUiOptions, ActionBattleUiActionBarOptions, ActionBattleUiAttackPreviewOptions, ActionBattleUiGuiEntry, ActionBattleUiTargetingOptions, ActionBattleAttackDirection, ActionBattleAttackHitboxConfig, ActionBattleAttackHitboxMap, ActionBattleAttackHitPolicy, ActionBattleAttackProfile, ActionBattleHitReactionProfile, NormalizedActionBattleHitReactionProfile, NormalizedActionBattleAttackProfile, ActionBattleCombatOptions, ActionBattleSystemOptions, ActionBattleAiSystemOptions, ActionBattleVisualComposer, ActionBattleVisualContext, ActionBattleVisualHelpers, ActionBattleVisualInput, ActionBattleVisualMoment, ActionBattleVisualPart, ActionBattleVisualPreset, } from './types';
5
+ export type { ActionBattleAiBehavior, ActionBattleAiContext, ActionBattleAiDecision, ActionBattleAiPreset, ActionBattleAttackContext, ActionBattleCombatSystem, ActionBattleDamageContext, ActionBattleDamageResult, ActionBattleDirection, ActionBattleEntity, ActionBattleActionConfig, ActionBattleActionMode, ActionBattleActionTarget, ActionBattleTargetContext, ActionBattleTargetOptions, ActionBattleTargetSelector, ActionBattleProjectileImpactContext, ActionBattleProjectileOptions, ActionBattleUsable, ActionBattleUseContext, ActionBattleHitContext, ActionBattleHitHooks, ActionBattleHitResult, ActionBattleHitbox, ActionBattleKnockbackContext, ActionBattleKnockbackResult, ActionBattleSystems, } from './core/contracts';
6
+ export { action, chase, condition, decision, defineAiBehavior, defineAiTree, distanceLessThan, faceTarget, flee, fleeFromTarget, hpBelow, idle, ifDistanceLessThan, ifHpBelow, ifTargetInRange, ifTargetVisible, inState, isEnemyType, keepDistance, moveToTarget, patrol, rule, selector, sequence, setMode, targetInRange, targetVisible, useAttack, useSkill, type ActionBattleAiCondition, type ActionBattleAiIntent, type ActionBattleAiIntentInput, type ActionBattleAiMemory, type ActionBattleAiRule, type ActionBattleAiSimpleBehavior, type ActionBattleAiSnapshotSelf, type ActionBattleAiSnapshotTarget, type ActionBattleAiTreeContext, type ActionBattleAiTreeInput, type ActionBattleAiTreeNode, type ActionBattleAiTreeResult, type ActionBattleAiTreeStatus, } from './core/ai-behavior-tree';
6
7
  export { DEFAULT_ACTION_BATTLE_ATTACK_PROFILE, normalizeActionBattleAttackProfile, type ActionBattleAttackProfileFallbacks, } from './core/attack-profile';
7
- export { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, scheduleActionBattleStartup, } from './core/attack-runtime';
8
+ export { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, runActionBattleActiveHitbox, scheduleActionBattleStartup, } from './core/attack-runtime';
9
+ export { canActionBattleUseTarget, executeActionBattleUse, getActionBattleActionConfig, getActionBattleActionRange, handleActionBattleProjectileDestroy, handleActionBattleProjectileImpact, shouldUseActionBattleUsable, } from './core/action-use';
8
10
  export { DEFAULT_ACTION_BATTLE_HIT_REACTION, isActionBattleEntityInvincible, normalizeActionBattleHitReaction, setActionBattleInvincibility, } from './core/hit-reaction';
9
11
  export { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles, type ActionBattleEnemyAttackProfileKey, type ActionBattleEnemyAttackProfileMap, type NormalizedActionBattleEnemyAttackProfileMap, } from './core/enemy-attack-profiles';
10
- export { resolveActionBattleWeaponAttackProfile } from './core/equipment';
11
- export { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultCombatSystem, defaultEnemyBehaviors, defaultKnockbackResolver, defaultRpgjsDamageResolver, } from './core/defaults';
12
+ export { resolveActionBattleWeapon, resolveActionBattleWeaponAttackProfile, } from './core/equipment';
13
+ export { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultCombatSystem, defaultEnemyBehaviors, defaultEnemyPresets, defaultKnockbackResolver, defaultRpgjsDamageResolver, } from './core/defaults';
14
+ export { ACTION_BATTLE_ENEMY_FACTION, ACTION_BATTLE_PLAYER_FACTION, canActionBattleTarget, getActionBattleFaction, getActionBattleTargets, isActionBattleCombatEntity, isActionBattleEvent, isActionBattlePlayer, matchesActionBattleTargetSelector, } from './core/targets';
12
15
  export { createActionBattleSystems, getActionBattleSystems, } from './core/context';
13
16
  export { applyActionBattleHit } from './core/hit';
14
- export { createActionEnemy, type ActionBattleEnemyPreset, type ActionBattleEnemyPresetMap, } from './enemies/factory';
15
- export { DEFAULT_PLAYER_ATTACK_HITBOXES, getPlayerWeaponKnockbackForce, applyPlayerHitToEvent, ACTION_BATTLE_ACTION_BAR_GUI_ID, openActionBattleActionBar, updateActionBattleActionBar, createActionBattleServer, } from './server';
17
+ export { ACTION_BATTLE_CLIENT_VISUAL_ID, ACTION_BATTLE_HIT_FX_COMPONENT_ID, createActionBattleClientVisuals, createActionBattleVisual, createClassicActionBattleVisual, createFxActionBattleVisual, emitActionBattleClientVisual, playActionBattleVisual, setActionBattlePreviewStarter, } from './visual';
18
+ export { ActionBattleUi, createActionBattleUi, resolveActionBattleUi, type ResolvedActionBattleUi, } from './ui';
19
+ export { createActionEnemy, defineActionBattleAiPreset, defineActionBattleEnemy, type ActionBattleEnemyPreset, type ActionBattleEnemyPresetMap, } from './enemies/factory';
20
+ export { DEFAULT_PLAYER_ATTACK_HITBOXES, getPlayerWeaponKnockbackForce, applyActionBattleEntityHit, applyPlayerHitToEvent, ACTION_BATTLE_ACTION_BAR_GUI_ID, openActionBattleActionBar, updateActionBattleActionBar, createActionBattleServer, } from './server';
16
21
  export declare function provideActionBattle(options?: ActionBattleOptions): any[];
17
22
  declare const _default: {
18
23
  server: import('@rpgjs/server').RpgServer;
@@ -1,15 +1,20 @@
1
1
  import { DEFAULT_ACTION_BATTLE_HIT_REACTION, isActionBattleEntityInvincible, normalizeActionBattleHitReaction, setActionBattleInvincibility } from "./index2.js";
2
2
  import { DEFAULT_ACTION_BATTLE_ATTACK_PROFILE, normalizeActionBattleAttackProfile } from "./index3.js";
3
- import { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, scheduleActionBattleStartup } from "./index11.js";
4
- import client_default, { createActionBattleClient } from "./index12.js";
5
- import { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultCombatSystem, defaultEnemyBehaviors, defaultKnockbackResolver, defaultRpgjsDamageResolver } from "./index13.js";
6
- import { createActionBattleSystems, getActionBattleSystems } from "./index14.js";
7
- import { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles } from "./index15.js";
8
- import { AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_KNOCKBACK, EnemyType } from "./index16.js";
9
- import { resolveActionBattleWeaponAttackProfile } from "./index17.js";
10
- import { applyActionBattleHit } from "./index18.js";
11
- import { createActionEnemy } from "./index19.js";
12
- import { ACTION_BATTLE_ACTION_BAR_GUI_ID, DEFAULT_PLAYER_ATTACK_HITBOXES, applyPlayerHitToEvent, createActionBattleServer, getPlayerWeaponKnockbackForce, openActionBattleActionBar, updateActionBattleActionBar } from "./index20.js";
3
+ import { ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, createActionBattleAttackId, getNormalizedActionBattleAttackProfile, resolveActionBattleHitboxSpeed, runActionBattleActiveHitbox, scheduleActionBattleStartup } from "./index6.js";
4
+ import { ActionBattleUi, createActionBattleUi, resolveActionBattleUi } from "./index13.js";
5
+ import { ACTION_BATTLE_CLIENT_VISUAL_ID, ACTION_BATTLE_HIT_FX_COMPONENT_ID, createActionBattleClientVisuals, createActionBattleVisual, createClassicActionBattleVisual, createFxActionBattleVisual, emitActionBattleClientVisual, playActionBattleVisual, setActionBattlePreviewStarter } from "./index15.js";
6
+ import client_default, { createActionBattleClient } from "./index16.js";
7
+ import { DEFAULT_ZELDA_PLAYER_HITBOXES, createDefaultPlayerHitboxResolver, defaultCombatSystem, defaultEnemyBehaviors, defaultEnemyPresets, defaultKnockbackResolver, defaultRpgjsDamageResolver } from "./index17.js";
8
+ import { createActionBattleSystems, getActionBattleSystems } from "./index18.js";
9
+ import { DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, normalizeActionBattleEnemyAttackProfiles } from "./index19.js";
10
+ import { applyActionBattleHit } from "./index20.js";
11
+ import { ACTION_BATTLE_ENEMY_FACTION, ACTION_BATTLE_PLAYER_FACTION, canActionBattleTarget, getActionBattleFaction, getActionBattleTargets, isActionBattleCombatEntity, isActionBattleEvent, isActionBattlePlayer, matchesActionBattleTargetSelector } from "./index21.js";
12
+ import { canActionBattleUseTarget, executeActionBattleUse, getActionBattleActionConfig, getActionBattleActionRange, handleActionBattleProjectileDestroy, handleActionBattleProjectileImpact, shouldUseActionBattleUsable } from "./index22.js";
13
+ import { resolveActionBattleWeapon, resolveActionBattleWeaponAttackProfile } from "./index23.js";
14
+ import { action, chase, condition, decision, defineAiBehavior, defineAiTree, distanceLessThan, faceTarget, flee, fleeFromTarget, hpBelow, idle, ifDistanceLessThan, ifHpBelow, ifTargetInRange, ifTargetVisible, inState, isEnemyType, keepDistance, moveToTarget, patrol, rule, selector, sequence, setMode, targetInRange, targetVisible, useAttack, useSkill } from "./index25.js";
15
+ import { AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_KNOCKBACK, EnemyType } from "./index26.js";
16
+ import { createActionEnemy, defineActionBattleAiPreset, defineActionBattleEnemy } from "./index27.js";
17
+ import { ACTION_BATTLE_ACTION_BAR_GUI_ID, DEFAULT_PLAYER_ATTACK_HITBOXES, applyActionBattleEntityHit, applyPlayerHitToEvent, createActionBattleServer, getPlayerWeaponKnockbackForce, openActionBattleActionBar, updateActionBattleActionBar } from "./index28.js";
13
18
  import { createModule } from "@rpgjs/common";
14
19
  //#region src/index.ts
15
20
  var server = null;
@@ -25,4 +30,4 @@ var src_default = {
25
30
  client: client_default
26
31
  };
27
32
  //#endregion
28
- export { ACTION_BATTLE_ACTION_BAR_GUI_ID, ACTION_BATTLE_HITBOX_FRAME_MS, ActionBattleHitTracker, AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_ACTION_BATTLE_ATTACK_PROFILE, DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, DEFAULT_ACTION_BATTLE_HIT_REACTION, DEFAULT_KNOCKBACK, DEFAULT_PLAYER_ATTACK_HITBOXES, DEFAULT_ZELDA_PLAYER_HITBOXES, EnemyType, applyActionBattleHit, applyPlayerHitToEvent, createActionBattleAttackId, createActionBattleServer, createActionBattleSystems, createActionEnemy, createDefaultPlayerHitboxResolver, src_default as default, defaultCombatSystem, defaultEnemyBehaviors, defaultKnockbackResolver, defaultRpgjsDamageResolver, getActionBattleSystems, getNormalizedActionBattleAttackProfile, getPlayerWeaponKnockbackForce, isActionBattleEntityInvincible, normalizeActionBattleAttackProfile, normalizeActionBattleEnemyAttackProfiles, normalizeActionBattleHitReaction, openActionBattleActionBar, provideActionBattle, resolveActionBattleHitboxSpeed, resolveActionBattleWeaponAttackProfile, scheduleActionBattleStartup, setActionBattleInvincibility, updateActionBattleActionBar };
33
+ export { ACTION_BATTLE_ACTION_BAR_GUI_ID, ACTION_BATTLE_CLIENT_VISUAL_ID, ACTION_BATTLE_ENEMY_FACTION, ACTION_BATTLE_HITBOX_FRAME_MS, ACTION_BATTLE_HIT_FX_COMPONENT_ID, ACTION_BATTLE_PLAYER_FACTION, ActionBattleHitTracker, ActionBattleUi, AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_ACTION_BATTLE_ATTACK_PROFILE, DEFAULT_ACTION_BATTLE_ENEMY_ATTACK_PROFILES, DEFAULT_ACTION_BATTLE_HIT_REACTION, DEFAULT_KNOCKBACK, DEFAULT_PLAYER_ATTACK_HITBOXES, DEFAULT_ZELDA_PLAYER_HITBOXES, EnemyType, action, applyActionBattleEntityHit, applyActionBattleHit, applyPlayerHitToEvent, canActionBattleTarget, canActionBattleUseTarget, chase, condition, createActionBattleAttackId, createActionBattleClientVisuals, createActionBattleServer, createActionBattleSystems, createActionBattleUi, createActionBattleVisual, createActionEnemy, createClassicActionBattleVisual, createDefaultPlayerHitboxResolver, createFxActionBattleVisual, decision, src_default as default, defaultCombatSystem, defaultEnemyBehaviors, defaultEnemyPresets, defaultKnockbackResolver, defaultRpgjsDamageResolver, defineActionBattleAiPreset, defineActionBattleEnemy, defineAiBehavior, defineAiTree, distanceLessThan, emitActionBattleClientVisual, executeActionBattleUse, faceTarget, flee, fleeFromTarget, getActionBattleActionConfig, getActionBattleActionRange, getActionBattleFaction, getActionBattleSystems, getActionBattleTargets, getNormalizedActionBattleAttackProfile, getPlayerWeaponKnockbackForce, handleActionBattleProjectileDestroy, handleActionBattleProjectileImpact, hpBelow, idle, ifDistanceLessThan, ifHpBelow, ifTargetInRange, ifTargetVisible, inState, isActionBattleCombatEntity, isActionBattleEntityInvincible, isActionBattleEvent, isActionBattlePlayer, isEnemyType, keepDistance, matchesActionBattleTargetSelector, moveToTarget, normalizeActionBattleAttackProfile, normalizeActionBattleEnemyAttackProfiles, normalizeActionBattleHitReaction, openActionBattleActionBar, patrol, playActionBattleVisual, provideActionBattle, resolveActionBattleHitboxSpeed, resolveActionBattleUi, resolveActionBattleWeapon, resolveActionBattleWeaponAttackProfile, rule, runActionBattleActiveHitbox, scheduleActionBattleStartup, selector, sequence, setActionBattleInvincibility, setActionBattlePreviewStarter, setMode, shouldUseActionBattleUsable, targetInRange, targetVisible, updateActionBattleActionBar, useAttack, useSkill };
@@ -1,61 +1,37 @@
1
- var DEFAULT_ANIMATION_BY_KEY = {
2
- attack: "attack",
3
- hurt: "hurt",
4
- die: "die",
5
- castSkill: "skill",
6
- castSpell: "skill"
1
+ //#region src/targeting.ts
2
+ var normalizeMaskRows = (mask) => {
3
+ if (!mask) return ["#"];
4
+ if (Array.isArray(mask)) return mask;
5
+ return mask.trim().split("\n").map((row) => row.replace(/\r/g, ""));
7
6
  };
8
- var getConfiguredAnimation = (key, animations) => {
9
- if (!animations) return {
10
- hasConfiguredAnimation: false,
11
- configured: void 0
12
- };
13
- const hasConfiguredAnimation = Object.prototype.hasOwnProperty.call(animations, key);
14
- if (hasConfiguredAnimation) return {
15
- hasConfiguredAnimation,
16
- configured: animations[key]
17
- };
18
- if (key === "castSkill") return {
19
- hasConfiguredAnimation: Object.prototype.hasOwnProperty.call(animations, "castSpell"),
20
- configured: animations.castSpell
21
- };
7
+ var parseAoeMask = (mask) => {
8
+ const rows = normalizeMaskRows(mask);
9
+ const height = rows.length;
10
+ const width = rows.reduce((max, row) => Math.max(max, row.length), 0);
11
+ const centerX = Math.floor(width / 2);
12
+ const centerY = Math.floor(height / 2);
13
+ const cells = [];
14
+ rows.forEach((row, y) => {
15
+ for (let x = 0; x < row.length; x++) {
16
+ const char = row[x];
17
+ if (char && char !== "." && char !== " ") cells.push({
18
+ dx: x - centerX,
19
+ dy: y - centerY
20
+ });
21
+ }
22
+ });
23
+ if (cells.length === 0) cells.push({
24
+ dx: 0,
25
+ dy: 0
26
+ });
22
27
  return {
23
- hasConfiguredAnimation: false,
24
- configured: void 0
28
+ width,
29
+ height,
30
+ centerX,
31
+ centerY,
32
+ cells
25
33
  };
26
34
  };
27
- function resolveActionBattleAnimation(key, entity, animations, context, defaults = {}) {
28
- const defaultAnimationName = defaults.animationName ?? DEFAULT_ANIMATION_BY_KEY[key];
29
- const defaultRepeat = defaults.repeat ?? 1;
30
- const { hasConfiguredAnimation, configured: configuredAnimation } = getConfiguredAnimation(key, animations);
31
- if (!hasConfiguredAnimation && key !== "attack") return null;
32
- const configured = hasConfiguredAnimation ? configuredAnimation : defaultAnimationName;
33
- const result = typeof configured === "function" ? configured(entity, context) : configured;
34
- if (result == null) return null;
35
- if (typeof result === "string") return {
36
- animationName: result,
37
- repeat: defaultRepeat,
38
- waitEnd: false
39
- };
40
- return {
41
- animationName: result.animationName ?? defaultAnimationName,
42
- graphic: result.graphic,
43
- repeat: result.repeat ?? defaultRepeat,
44
- waitEnd: result.waitEnd ?? false,
45
- delayMs: result.delayMs
46
- };
47
- }
48
- function playActionBattleAnimation(key, entity, animations, context, defaults = {}) {
49
- const animation = resolveActionBattleAnimation(key, entity, animations, context, defaults);
50
- if (!animation) return null;
51
- if (animation.graphic !== void 0) entity.setGraphicAnimation(animation.animationName, animation.graphic, animation.repeat);
52
- else entity.setGraphicAnimation(animation.animationName, animation.repeat);
53
- return animation;
54
- }
55
- function getActionBattleAnimationRemovalDelay(animation) {
56
- if (!animation) return 0;
57
- if (animation.delayMs !== void 0) return animation.delayMs;
58
- return animation.waitEnd ? 500 : 0;
59
- }
35
+ var manhattanDistance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
60
36
  //#endregion
61
- export { getActionBattleAnimationRemovalDelay, playActionBattleAnimation, resolveActionBattleAnimation };
37
+ export { manhattanDistance, parseAoeMask };