@rpgjs/action-battle 5.0.0-beta.12 → 5.0.0-beta.14
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/CHANGELOG.md +21 -0
- package/dist/client/ai.server.d.ts +12 -0
- package/dist/client/core/defaults.d.ts +1 -1
- package/dist/client/index17.js +11 -1
- package/dist/client/index21.js +2 -1
- package/dist/client/index22.js +2 -1
- package/dist/client/index26.js +316 -74
- package/dist/server/ai.server.d.ts +12 -0
- package/dist/server/core/defaults.d.ts +1 -1
- package/dist/server/index13.js +2 -1
- package/dist/server/index14.js +2 -1
- package/dist/server/index19.js +316 -74
- package/dist/server/index7.js +11 -1
- package/package.json +5 -5
- package/src/ai.server.spec.ts +147 -1
- package/src/ai.server.ts +375 -68
- package/src/core/action-use.ts +2 -1
- package/src/core/defaults.ts +16 -1
- package/src/core/hit.spec.ts +21 -0
- package/src/core/targets.spec.ts +12 -0
- package/src/core/targets.ts +4 -1
- package/src/visual.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpgjs/action-battle",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.14",
|
|
4
4
|
"main": "dist/client/index.js",
|
|
5
5
|
"types": "dist/client/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"description": "RPGJS is a framework for creating RPG/MMORPG games",
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@canvasengine/presets": "^2.0.0-rc.4",
|
|
26
|
-
"@rpgjs/client": "5.0.0-beta.
|
|
27
|
-
"@rpgjs/common": "5.0.0-beta.
|
|
28
|
-
"@rpgjs/server": "5.0.0-beta.
|
|
29
|
-
"@rpgjs/vite": "5.0.0-beta.
|
|
26
|
+
"@rpgjs/client": "5.0.0-beta.14",
|
|
27
|
+
"@rpgjs/common": "5.0.0-beta.14",
|
|
28
|
+
"@rpgjs/server": "5.0.0-beta.14",
|
|
29
|
+
"@rpgjs/vite": "5.0.0-beta.14",
|
|
30
30
|
"canvasengine": "^2.0.0-rc.4"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
package/src/ai.server.spec.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { MAXHP } from "@rpgjs/server";
|
|
2
2
|
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
3
|
-
import { BattleAi } from "./ai.server";
|
|
3
|
+
import { AttackPattern, BattleAi } from "./ai.server";
|
|
4
4
|
import { chase, idle, ifTargetVisible } from "./core/ai-behavior-tree";
|
|
5
5
|
import { setActionBattleSystems } from "./core/context";
|
|
6
|
+
import { ACTION_BATTLE_CLIENT_VISUAL_ID } from "./visual";
|
|
6
7
|
|
|
7
8
|
const createEvent = () => ({
|
|
8
9
|
id: "monster-1",
|
|
@@ -268,6 +269,118 @@ describe("BattleAi behavior tree", () => {
|
|
|
268
269
|
ai.destroy();
|
|
269
270
|
});
|
|
270
271
|
|
|
272
|
+
test("approaches a visible target while alert but not yet in combat range", () => {
|
|
273
|
+
vi.useFakeTimers();
|
|
274
|
+
const event = createEvent();
|
|
275
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
276
|
+
const player = {
|
|
277
|
+
...createPlayer(),
|
|
278
|
+
hp: 10,
|
|
279
|
+
x: vi.fn(() => 120),
|
|
280
|
+
y: vi.fn(() => 0),
|
|
281
|
+
};
|
|
282
|
+
const ai = new BattleAi(event as any, {
|
|
283
|
+
attackRange: 50,
|
|
284
|
+
visionRange: 150,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
ai.onDetectInShape(player as any, {});
|
|
288
|
+
vi.advanceTimersByTime(100);
|
|
289
|
+
|
|
290
|
+
expect(event.moveTo).toHaveBeenCalledWith(player);
|
|
291
|
+
ai.destroy();
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("normalizes position move targets before calling RPGJS moveTo", () => {
|
|
295
|
+
vi.useFakeTimers();
|
|
296
|
+
const event = createEvent();
|
|
297
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
298
|
+
|
|
299
|
+
const ai = new BattleAi(event as any, {
|
|
300
|
+
patrolWaypoints: [{ x: 32, y: 48 }],
|
|
301
|
+
moveToCooldown: 0,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
expect(event.moveTo).toHaveBeenCalledWith({ x: 32, y: 48 });
|
|
305
|
+
ai.destroy();
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test("targets its attacker after taking non-lethal damage", () => {
|
|
309
|
+
vi.useFakeTimers();
|
|
310
|
+
const event = createEvent();
|
|
311
|
+
event.hp = 9;
|
|
312
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
313
|
+
const player = {
|
|
314
|
+
...createPlayer(),
|
|
315
|
+
hp: 10,
|
|
316
|
+
x: vi.fn(() => 120),
|
|
317
|
+
y: vi.fn(() => 0),
|
|
318
|
+
};
|
|
319
|
+
const ai = new BattleAi(event as any, {
|
|
320
|
+
attackRange: 50,
|
|
321
|
+
visionRange: 150,
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
ai.handleDamage(player as any, { damage: 1, defeated: false });
|
|
325
|
+
|
|
326
|
+
expect(ai.getTarget()).toBe(player);
|
|
327
|
+
ai.destroy();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test("waits for damage recovery before chasing its attacker", () => {
|
|
331
|
+
vi.useFakeTimers();
|
|
332
|
+
vi.setSystemTime(1000);
|
|
333
|
+
const event = createEvent();
|
|
334
|
+
event.hp = 9;
|
|
335
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
336
|
+
const player = {
|
|
337
|
+
...createPlayer(),
|
|
338
|
+
hp: 10,
|
|
339
|
+
x: vi.fn(() => 120),
|
|
340
|
+
y: vi.fn(() => 0),
|
|
341
|
+
};
|
|
342
|
+
const ai = new BattleAi(event as any, {
|
|
343
|
+
attackRange: 50,
|
|
344
|
+
visionRange: 150,
|
|
345
|
+
hitstunMs: 100,
|
|
346
|
+
moveToCooldown: 0,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
ai.handleDamage(player as any, { damage: 1, defeated: false });
|
|
350
|
+
vi.advanceTimersByTime(200);
|
|
351
|
+
expect(event.moveTo).not.toHaveBeenCalledWith(player);
|
|
352
|
+
|
|
353
|
+
vi.advanceTimersByTime(100);
|
|
354
|
+
expect(event.moveTo).toHaveBeenCalledWith(player);
|
|
355
|
+
ai.destroy();
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("chases its attacker after hitstun ends", () => {
|
|
359
|
+
vi.useFakeTimers();
|
|
360
|
+
vi.setSystemTime(1000);
|
|
361
|
+
const event = createEvent();
|
|
362
|
+
event.hp = 9;
|
|
363
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
364
|
+
const player = {
|
|
365
|
+
...createPlayer(),
|
|
366
|
+
hp: 10,
|
|
367
|
+
x: vi.fn(() => 120),
|
|
368
|
+
y: vi.fn(() => 0),
|
|
369
|
+
};
|
|
370
|
+
const ai = new BattleAi(event as any, {
|
|
371
|
+
attackRange: 50,
|
|
372
|
+
visionRange: 150,
|
|
373
|
+
hitstunMs: 100,
|
|
374
|
+
moveToCooldown: 0,
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
ai.handleDamage(player as any, { damage: 1, defeated: false });
|
|
378
|
+
vi.advanceTimersByTime(300);
|
|
379
|
+
|
|
380
|
+
expect(event.moveTo).toHaveBeenCalledWith(player);
|
|
381
|
+
ai.destroy();
|
|
382
|
+
});
|
|
383
|
+
|
|
271
384
|
test("behavior tree idle fallback does not block target acquisition", () => {
|
|
272
385
|
vi.useFakeTimers();
|
|
273
386
|
const event = createEvent();
|
|
@@ -350,4 +463,37 @@ describe("BattleAi behavior tree", () => {
|
|
|
350
463
|
expect(ai.getTarget()).toBe(hostile);
|
|
351
464
|
ai.destroy();
|
|
352
465
|
});
|
|
466
|
+
|
|
467
|
+
test("dash attacks emit an attack visual before the dash hit", () => {
|
|
468
|
+
vi.useFakeTimers();
|
|
469
|
+
const clientVisual = vi.fn();
|
|
470
|
+
const event = createEvent();
|
|
471
|
+
event.getCurrentMap.mockReturnValue({ clientVisual });
|
|
472
|
+
event.attachShape.mockReturnValue({ id: "vision_monster-1" });
|
|
473
|
+
const player = {
|
|
474
|
+
...createPlayer(),
|
|
475
|
+
hp: 10,
|
|
476
|
+
x: vi.fn(() => 20),
|
|
477
|
+
y: vi.fn(() => 0),
|
|
478
|
+
};
|
|
479
|
+
const ai = new BattleAi(event as any, {
|
|
480
|
+
attackPatterns: [AttackPattern.DashAttack],
|
|
481
|
+
attackRange: 50,
|
|
482
|
+
moveToCooldown: 0,
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
ai.onDetectInShape(player as any, {});
|
|
486
|
+
(ai as any).performDashAttack();
|
|
487
|
+
|
|
488
|
+
expect(clientVisual).toHaveBeenCalledWith(
|
|
489
|
+
ACTION_BATTLE_CLIENT_VISUAL_ID,
|
|
490
|
+
expect.objectContaining({
|
|
491
|
+
moment: "attack",
|
|
492
|
+
objectId: "monster-1",
|
|
493
|
+
targetId: "player-1",
|
|
494
|
+
pattern: AttackPattern.DashAttack,
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
ai.destroy();
|
|
498
|
+
});
|
|
353
499
|
});
|