@rpgjs/action-battle 5.0.0-alpha.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +784 -0
- package/dist/ai.server.d.ts +482 -0
- package/dist/client/index.js +25 -0
- package/dist/client/index2.js +13 -0
- package/dist/client/index3.js +1129 -0
- package/dist/client/index4.js +137 -0
- package/dist/client.d.ts +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/server/index.js +25 -0
- package/dist/server/index2.js +138 -0
- package/dist/server/index3.js +1128 -0
- package/dist/server.d.ts +93 -0
- package/package.json +45 -0
- package/src/ai.server.ts +1430 -0
- package/src/client.ts +11 -0
- package/src/index.ts +21 -0
- package/src/server.ts +227 -0
- package/vite.config.ts +3 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
import { RpgEvent, RpgPlayer } from '@rpgjs/server';
|
|
2
|
+
type RpgEventWithBattleAi = RpgEvent & {
|
|
3
|
+
battleAi: BattleAi;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Hit result data returned after applying damage
|
|
7
|
+
*
|
|
8
|
+
* Contains information about the hit including damage dealt,
|
|
9
|
+
* knockback parameters, and whether the target was defeated.
|
|
10
|
+
* Used by hooks to customize hit behavior.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const hitResult: HitResult = {
|
|
15
|
+
* damage: 25,
|
|
16
|
+
* knockbackForce: 50,
|
|
17
|
+
* knockbackDuration: 300,
|
|
18
|
+
* defeated: false,
|
|
19
|
+
* attacker: this.event,
|
|
20
|
+
* target: player
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export interface HitResult {
|
|
25
|
+
/** Damage dealt to the target */
|
|
26
|
+
damage: number;
|
|
27
|
+
/** Knockback force applied (from weapon or default) */
|
|
28
|
+
knockbackForce: number;
|
|
29
|
+
/** Knockback duration in milliseconds */
|
|
30
|
+
knockbackDuration: number;
|
|
31
|
+
/** Whether the target was defeated */
|
|
32
|
+
defeated: boolean;
|
|
33
|
+
/** The entity that attacked */
|
|
34
|
+
attacker: RpgEvent | RpgPlayer;
|
|
35
|
+
/** The entity that was hit */
|
|
36
|
+
target: RpgPlayer | RpgEvent;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Hook options for customizing hit behavior
|
|
40
|
+
*
|
|
41
|
+
* Allows overriding knockback parameters and adding custom effects
|
|
42
|
+
* when a hit is applied.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* const hooks: ApplyHitHooks = {
|
|
47
|
+
* onBeforeHit(result) {
|
|
48
|
+
* // Reduce knockback for armored enemies
|
|
49
|
+
* if (result.target.hasState('armored')) {
|
|
50
|
+
* result.knockbackForce *= 0.5;
|
|
51
|
+
* }
|
|
52
|
+
* return result;
|
|
53
|
+
* },
|
|
54
|
+
* onAfterHit(result) {
|
|
55
|
+
* // Add poison effect on hit
|
|
56
|
+
* if (Math.random() < 0.3) {
|
|
57
|
+
* result.target.addState('poison');
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* };
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export interface ApplyHitHooks {
|
|
64
|
+
/**
|
|
65
|
+
* Called before the hit is applied
|
|
66
|
+
* Can modify the hit result before damage and knockback
|
|
67
|
+
*
|
|
68
|
+
* @param result - The hit result data
|
|
69
|
+
* @returns Modified hit result or void to use original
|
|
70
|
+
*/
|
|
71
|
+
onBeforeHit?: (result: HitResult) => HitResult | void;
|
|
72
|
+
/**
|
|
73
|
+
* Called after the hit is applied
|
|
74
|
+
* Used for side effects like adding states, playing sounds, etc.
|
|
75
|
+
*
|
|
76
|
+
* @param result - The final hit result data
|
|
77
|
+
*/
|
|
78
|
+
onAfterHit?: (result: HitResult) => void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* AI Debug Logger
|
|
82
|
+
*
|
|
83
|
+
* Conditional logging utility for AI behavior debugging.
|
|
84
|
+
* Enable by setting `AiDebug.enabled = true` or via environment variable `RPGJS_DEBUG_AI=1`
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // Enable debug logging
|
|
89
|
+
* AiDebug.enabled = true;
|
|
90
|
+
*
|
|
91
|
+
* // Or filter by event ID
|
|
92
|
+
* AiDebug.filterEventId = 'goblin-1';
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare const AiDebug: {
|
|
96
|
+
/** Enable/disable all AI debug logs */
|
|
97
|
+
enabled: boolean;
|
|
98
|
+
/** Filter logs to a specific event ID (null = all events) */
|
|
99
|
+
filterEventId: string | null;
|
|
100
|
+
/** Log categories to enable (empty = all) */
|
|
101
|
+
categories: string[];
|
|
102
|
+
/**
|
|
103
|
+
* Log an AI debug message
|
|
104
|
+
*
|
|
105
|
+
* @param category - Log category (e.g., 'state', 'attack', 'movement', 'damage')
|
|
106
|
+
* @param eventId - Event ID for filtering
|
|
107
|
+
* @param message - Log message
|
|
108
|
+
* @param data - Optional additional data
|
|
109
|
+
*/
|
|
110
|
+
log(category: string, eventId: string | undefined, message: string, data?: any): void;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* AI State enumeration
|
|
114
|
+
*
|
|
115
|
+
* Defines the different states an AI can be in, each with its own behavior.
|
|
116
|
+
*/
|
|
117
|
+
export declare enum AiState {
|
|
118
|
+
Idle = "idle",
|
|
119
|
+
Alert = "alert",
|
|
120
|
+
Combat = "combat",
|
|
121
|
+
Flee = "flee",
|
|
122
|
+
Stunned = "stunned"
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Enemy Type enumeration
|
|
126
|
+
*
|
|
127
|
+
* Defines different enemy archetypes with unique behaviors.
|
|
128
|
+
* Stats (HP, ATK, etc.) should be set on the event itself via onInit.
|
|
129
|
+
*/
|
|
130
|
+
export declare enum EnemyType {
|
|
131
|
+
Aggressive = "aggressive",
|
|
132
|
+
Defensive = "defensive",
|
|
133
|
+
Ranged = "ranged",
|
|
134
|
+
Tank = "tank",
|
|
135
|
+
Berserker = "berserker"
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Attack Pattern enumeration
|
|
139
|
+
*
|
|
140
|
+
* Different attack patterns the AI can use.
|
|
141
|
+
*/
|
|
142
|
+
export declare enum AttackPattern {
|
|
143
|
+
Melee = "melee",
|
|
144
|
+
Combo = "combo",
|
|
145
|
+
Charged = "charged",
|
|
146
|
+
Zone = "zone",
|
|
147
|
+
DashAttack = "dashAttack"
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Default knockback configuration
|
|
151
|
+
*
|
|
152
|
+
* Used when no weapon is equipped or weapon doesn't specify knockback.
|
|
153
|
+
*/
|
|
154
|
+
export declare const DEFAULT_KNOCKBACK: {
|
|
155
|
+
/** Default knockback force */
|
|
156
|
+
force: number;
|
|
157
|
+
/** Default knockback duration in milliseconds */
|
|
158
|
+
duration: number;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Advanced Battle AI Controller for events
|
|
162
|
+
*
|
|
163
|
+
* This class provides intelligent combat behavior control for events.
|
|
164
|
+
* It uses the existing RPGJS API for stats, skills, items, etc.
|
|
165
|
+
* The AI only manages behavior - the event's stats should be configured
|
|
166
|
+
* in onInit using standard RPGJS methods.
|
|
167
|
+
*
|
|
168
|
+
* ## Usage with RPGJS API
|
|
169
|
+
*
|
|
170
|
+
* Configure the event stats using standard RPGJS methods:
|
|
171
|
+
* - `this.hp = 100` - Set health
|
|
172
|
+
* - `this.learnSkill(FireBall)` - Learn a skill
|
|
173
|
+
* - `this.addItem(Potion, 3)` - Add items
|
|
174
|
+
* - `this.equip(Sword)` - Equip items
|
|
175
|
+
* - `this.setClass(WarriorClass)` - Set class
|
|
176
|
+
* - `this.param[ATK] = 20` - Set parameters
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* function GoblinEnemy() {
|
|
181
|
+
* return {
|
|
182
|
+
* name: "Goblin",
|
|
183
|
+
* onInit() {
|
|
184
|
+
* this.setGraphic("goblin");
|
|
185
|
+
*
|
|
186
|
+
* // Configure stats using RPGJS API
|
|
187
|
+
* this.hp = 80;
|
|
188
|
+
* this.param[ATK] = 15;
|
|
189
|
+
* this.param[PDEF] = 5;
|
|
190
|
+
* this.learnSkill(Slash);
|
|
191
|
+
*
|
|
192
|
+
* // Apply AI behavior
|
|
193
|
+
* new BattleAi(this, {
|
|
194
|
+
* enemyType: EnemyType.Aggressive,
|
|
195
|
+
* attackSkill: Slash
|
|
196
|
+
* });
|
|
197
|
+
* }
|
|
198
|
+
* };
|
|
199
|
+
* }
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export declare class BattleAi {
|
|
203
|
+
private event;
|
|
204
|
+
private target;
|
|
205
|
+
private lastAttackTime;
|
|
206
|
+
private updateInterval?;
|
|
207
|
+
/**
|
|
208
|
+
* Log AI debug message for this event
|
|
209
|
+
*/
|
|
210
|
+
private debugLog;
|
|
211
|
+
private state;
|
|
212
|
+
private stateStartTime;
|
|
213
|
+
private stunnedUntil;
|
|
214
|
+
private enemyType;
|
|
215
|
+
private attackCooldown;
|
|
216
|
+
private visionRange;
|
|
217
|
+
private attackRange;
|
|
218
|
+
private dodgeChance;
|
|
219
|
+
private dodgeCooldown;
|
|
220
|
+
private lastDodgeTime;
|
|
221
|
+
private fleeThreshold;
|
|
222
|
+
private attackSkill;
|
|
223
|
+
private attackPatterns;
|
|
224
|
+
private comboCount;
|
|
225
|
+
private comboMax;
|
|
226
|
+
private chargingAttack;
|
|
227
|
+
private groupBehavior;
|
|
228
|
+
private nearbyEnemies;
|
|
229
|
+
private groupUpdateInterval;
|
|
230
|
+
private patrolWaypoints;
|
|
231
|
+
private currentPatrolIndex;
|
|
232
|
+
private lastHpCheck;
|
|
233
|
+
private recentDamageTaken;
|
|
234
|
+
private damageCheckInterval;
|
|
235
|
+
private isMovingToTarget;
|
|
236
|
+
private onDefeatedCallback?;
|
|
237
|
+
private lastFacingDirection;
|
|
238
|
+
/**
|
|
239
|
+
* Create a new Battle AI Controller
|
|
240
|
+
*
|
|
241
|
+
* The AI controls behavior only. Stats should be set on the event
|
|
242
|
+
* using standard RPGJS methods (hp, param, learnSkill, etc.)
|
|
243
|
+
*
|
|
244
|
+
* @param event - The event to control
|
|
245
|
+
* @param options - AI behavior configuration
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```ts
|
|
249
|
+
* // In your event's onInit
|
|
250
|
+
* this.hp = 100;
|
|
251
|
+
* this.param[ATK] = 20;
|
|
252
|
+
* this.learnSkill(FireBall);
|
|
253
|
+
*
|
|
254
|
+
* new BattleAi(this, {
|
|
255
|
+
* enemyType: EnemyType.Ranged,
|
|
256
|
+
* attackSkill: FireBall,
|
|
257
|
+
* visionRange: 200,
|
|
258
|
+
* fleeThreshold: 0.2
|
|
259
|
+
* });
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
constructor(event: RpgEventWithBattleAi, options?: {
|
|
263
|
+
enemyType?: EnemyType;
|
|
264
|
+
attackCooldown?: number;
|
|
265
|
+
visionRange?: number;
|
|
266
|
+
attackRange?: number;
|
|
267
|
+
dodgeChance?: number;
|
|
268
|
+
dodgeCooldown?: number;
|
|
269
|
+
fleeThreshold?: number;
|
|
270
|
+
attackSkill?: any;
|
|
271
|
+
attackPatterns?: AttackPattern[];
|
|
272
|
+
patrolWaypoints?: Array<{
|
|
273
|
+
x: number;
|
|
274
|
+
y: number;
|
|
275
|
+
}>;
|
|
276
|
+
groupBehavior?: boolean;
|
|
277
|
+
/** Callback called when the AI is defeated */
|
|
278
|
+
onDefeated?: (event: RpgEvent) => void;
|
|
279
|
+
});
|
|
280
|
+
/**
|
|
281
|
+
* Apply enemy type-specific behavior modifiers
|
|
282
|
+
*
|
|
283
|
+
* This only affects AI behavior (cooldowns, ranges, dodge).
|
|
284
|
+
* Stats should be set on the event itself.
|
|
285
|
+
*/
|
|
286
|
+
private applyEnemyTypeBehavior;
|
|
287
|
+
/**
|
|
288
|
+
* Setup vision detection
|
|
289
|
+
*/
|
|
290
|
+
private setupVision;
|
|
291
|
+
/**
|
|
292
|
+
* Start the AI behavior loop
|
|
293
|
+
*/
|
|
294
|
+
private startAiBehaviorLoop;
|
|
295
|
+
/**
|
|
296
|
+
* Change AI state with validated transitions
|
|
297
|
+
*/
|
|
298
|
+
private changeState;
|
|
299
|
+
/**
|
|
300
|
+
* Main AI behavior update loop
|
|
301
|
+
*/
|
|
302
|
+
private updateAiBehavior;
|
|
303
|
+
/**
|
|
304
|
+
* Update idle behavior (patrolling)
|
|
305
|
+
*/
|
|
306
|
+
private updateIdleBehavior;
|
|
307
|
+
/**
|
|
308
|
+
* Update alert behavior
|
|
309
|
+
*/
|
|
310
|
+
private updateAlertBehavior;
|
|
311
|
+
/**
|
|
312
|
+
* Update combat behavior
|
|
313
|
+
*/
|
|
314
|
+
private updateCombatBehavior;
|
|
315
|
+
/**
|
|
316
|
+
* Update flee behavior
|
|
317
|
+
*/
|
|
318
|
+
private updateFleeBehavior;
|
|
319
|
+
/**
|
|
320
|
+
* Select and perform an attack pattern
|
|
321
|
+
*/
|
|
322
|
+
private selectAndPerformAttack;
|
|
323
|
+
/**
|
|
324
|
+
* Select attack pattern with weighted probability
|
|
325
|
+
*/
|
|
326
|
+
private selectAttackPattern;
|
|
327
|
+
/**
|
|
328
|
+
* Perform attack pattern
|
|
329
|
+
*/
|
|
330
|
+
private performAttackPattern;
|
|
331
|
+
/**
|
|
332
|
+
* Perform melee attack
|
|
333
|
+
* Uses skill if configured, otherwise creates hitbox
|
|
334
|
+
*/
|
|
335
|
+
private performMeleeAttack;
|
|
336
|
+
/**
|
|
337
|
+
* Perform basic hitbox attack when no skill is set
|
|
338
|
+
*/
|
|
339
|
+
private performBasicHitbox;
|
|
340
|
+
/**
|
|
341
|
+
* Apply hit to target using RPGJS damage system with knockback
|
|
342
|
+
*
|
|
343
|
+
* Calculates damage using RPGJS formula, applies knockback based on
|
|
344
|
+
* equipped weapon's knockbackForce property, and triggers visual effects.
|
|
345
|
+
* Supports hooks for customizing behavior.
|
|
346
|
+
*
|
|
347
|
+
* @param target - The player or entity being hit
|
|
348
|
+
* @param hooks - Optional hooks for customizing hit behavior
|
|
349
|
+
* @returns The hit result containing damage and knockback info
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```ts
|
|
353
|
+
* // Basic hit
|
|
354
|
+
* this.applyHit(player);
|
|
355
|
+
*
|
|
356
|
+
* // With custom hooks
|
|
357
|
+
* this.applyHit(player, {
|
|
358
|
+
* onBeforeHit(result) {
|
|
359
|
+
* result.knockbackForce *= 1.5; // Increase knockback
|
|
360
|
+
* return result;
|
|
361
|
+
* },
|
|
362
|
+
* onAfterHit(result) {
|
|
363
|
+
* console.log(`Dealt ${result.damage} damage!`);
|
|
364
|
+
* }
|
|
365
|
+
* });
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
private applyHit;
|
|
369
|
+
/**
|
|
370
|
+
* Get knockback force from equipped weapon
|
|
371
|
+
*
|
|
372
|
+
* Retrieves the knockbackForce property from the event's equipped weapon.
|
|
373
|
+
* Falls back to DEFAULT_KNOCKBACK.force if no weapon or property is set.
|
|
374
|
+
*
|
|
375
|
+
* @returns Knockback force value
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* // Weapon with knockbackForce: 80
|
|
380
|
+
* const force = this.getWeaponKnockbackForce(); // 80
|
|
381
|
+
*
|
|
382
|
+
* // No weapon equipped
|
|
383
|
+
* const force = this.getWeaponKnockbackForce(); // 50 (default)
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
private getWeaponKnockbackForce;
|
|
387
|
+
/**
|
|
388
|
+
* Perform combo attack
|
|
389
|
+
*/
|
|
390
|
+
private performComboAttack;
|
|
391
|
+
/**
|
|
392
|
+
* Perform charged attack
|
|
393
|
+
*/
|
|
394
|
+
private performChargedAttack;
|
|
395
|
+
/**
|
|
396
|
+
* Perform zone attack (360 degrees)
|
|
397
|
+
*/
|
|
398
|
+
private performZoneAttack;
|
|
399
|
+
/**
|
|
400
|
+
* Perform dash attack
|
|
401
|
+
*/
|
|
402
|
+
private performDashAttack;
|
|
403
|
+
/**
|
|
404
|
+
* Face the current target with hysteresis to prevent animation flickering
|
|
405
|
+
*
|
|
406
|
+
* Uses multiple strategies to prevent flickering:
|
|
407
|
+
* 1. When very close to target (collision), keep current direction
|
|
408
|
+
* 2. When near diagonal, require significant difference to change
|
|
409
|
+
* 3. Only change if direction is clearly wrong (opposite)
|
|
410
|
+
*/
|
|
411
|
+
private faceTarget;
|
|
412
|
+
/**
|
|
413
|
+
* Try to dodge
|
|
414
|
+
*/
|
|
415
|
+
private tryDodge;
|
|
416
|
+
private canDodge;
|
|
417
|
+
private shouldDodge;
|
|
418
|
+
/**
|
|
419
|
+
* Flee from target
|
|
420
|
+
*/
|
|
421
|
+
private fleeFromTarget;
|
|
422
|
+
/**
|
|
423
|
+
* Retreat from target (temporary)
|
|
424
|
+
*/
|
|
425
|
+
private retreatFromTarget;
|
|
426
|
+
/**
|
|
427
|
+
* Check damage taken for retreat decision
|
|
428
|
+
*/
|
|
429
|
+
private checkDamageTaken;
|
|
430
|
+
/**
|
|
431
|
+
* Start patrol
|
|
432
|
+
*/
|
|
433
|
+
private startPatrol;
|
|
434
|
+
/**
|
|
435
|
+
* Update group behavior
|
|
436
|
+
*/
|
|
437
|
+
private updateGroupBehavior;
|
|
438
|
+
/**
|
|
439
|
+
* Find nearby enemies
|
|
440
|
+
*/
|
|
441
|
+
private findNearbyEnemies;
|
|
442
|
+
/**
|
|
443
|
+
* Apply formation around target
|
|
444
|
+
*/
|
|
445
|
+
private applyFormation;
|
|
446
|
+
/**
|
|
447
|
+
* Handle player entering vision
|
|
448
|
+
*/
|
|
449
|
+
onDetectInShape(player: InstanceType<typeof RpgPlayer>, shape: any): void;
|
|
450
|
+
/**
|
|
451
|
+
* Handle player leaving vision
|
|
452
|
+
*/
|
|
453
|
+
onDetectOutShape(player: InstanceType<typeof RpgPlayer>, shape: any): void;
|
|
454
|
+
/**
|
|
455
|
+
* Handle taking damage (called from server.ts)
|
|
456
|
+
*
|
|
457
|
+
* This triggers state changes like stun and flee check.
|
|
458
|
+
* The actual damage is applied externally via RPGJS API.
|
|
459
|
+
*/
|
|
460
|
+
takeDamage(attacker: RpgPlayer): boolean;
|
|
461
|
+
/**
|
|
462
|
+
* Kill this AI
|
|
463
|
+
*
|
|
464
|
+
* Stops all movements, cleans up resources, calls the onDefeated hook,
|
|
465
|
+
* and removes the event from the map.
|
|
466
|
+
*/
|
|
467
|
+
private kill;
|
|
468
|
+
/**
|
|
469
|
+
* Get distance between entities
|
|
470
|
+
*/
|
|
471
|
+
private getDistance;
|
|
472
|
+
getHealth(): number;
|
|
473
|
+
getMaxHealth(): number;
|
|
474
|
+
getTarget(): InstanceType<typeof RpgPlayer> | null;
|
|
475
|
+
getState(): AiState;
|
|
476
|
+
getEnemyType(): EnemyType;
|
|
477
|
+
/**
|
|
478
|
+
* Clean up
|
|
479
|
+
*/
|
|
480
|
+
destroy(): void;
|
|
481
|
+
}
|
|
482
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import client from "./index2.js";
|
|
2
|
+
import { createModule } from "@rpgjs/common";
|
|
3
|
+
import { AiDebug, AiState, AttackPattern, BattleAi, DEFAULT_KNOCKBACK, EnemyType } from "./index3.js";
|
|
4
|
+
import { DEFAULT_PLAYER_ATTACK_HITBOXES, applyPlayerHitToEvent, getPlayerWeaponKnockbackForce } from "./index4.js";
|
|
5
|
+
const server = null;
|
|
6
|
+
function provideActionBattle() {
|
|
7
|
+
return createModule("ActionBattle", [
|
|
8
|
+
{
|
|
9
|
+
server,
|
|
10
|
+
client
|
|
11
|
+
}
|
|
12
|
+
]);
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
AiDebug,
|
|
16
|
+
AiState,
|
|
17
|
+
AttackPattern,
|
|
18
|
+
BattleAi,
|
|
19
|
+
DEFAULT_KNOCKBACK,
|
|
20
|
+
DEFAULT_PLAYER_ATTACK_HITBOXES,
|
|
21
|
+
EnemyType,
|
|
22
|
+
applyPlayerHitToEvent,
|
|
23
|
+
getPlayerWeaponKnockbackForce,
|
|
24
|
+
provideActionBattle
|
|
25
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PrebuiltComponentAnimations } from "@rpgjs/client";
|
|
2
|
+
import { defineModule } from "@rpgjs/common";
|
|
3
|
+
const client = defineModule({
|
|
4
|
+
componentAnimations: [
|
|
5
|
+
{
|
|
6
|
+
id: "hit",
|
|
7
|
+
component: PrebuiltComponentAnimations.Hit
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
});
|
|
11
|
+
export {
|
|
12
|
+
client as default
|
|
13
|
+
};
|