forked from phenom/healer-man
53 lines
3.3 KiB
JavaScript
53 lines
3.3 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { arenaFloorHeight, arenaGeometryLineClear, arenaNavigationPath } from "./arena-geometry.mjs";
|
|
import { ARENA_STAGES } from "./arena-stages.mjs";
|
|
import { ArenaSimulation } from "./arena-simulation.mjs";
|
|
|
|
test("every arena spawn is supported by its shipped navigation surface", () => {
|
|
for (const stage of ARENA_STAGES) for (const spawn of stage.teamSpawns) {
|
|
const floor = arenaFloorHeight(stage.id, spawn[0], spawn[2], spawn[1], 2);
|
|
assert.notEqual(floor, null, `${stage.id} ${spawn}`);
|
|
assert.ok(Math.abs(floor - spawn[1]) < 2, `${stage.id} floor=${floor}, spawn=${spawn[1]}`);
|
|
}
|
|
});
|
|
|
|
test("characters can move away from both starting anchors into each arena", () => {
|
|
for (const stage of ARENA_STAGES) for (const team of [0, 1]) {
|
|
const sim = new ArenaSimulation({ id: "traversal", stage, bracket: "2v2", mode: "practice", ruleset: "wow", startedAt: 1000,
|
|
participants: [{ actorId: "player", name: "Player", team, role: "healer", isBot: false }] });
|
|
sim.phase = "active"; sim.activeStartedAt = 1000;
|
|
const actor = sim.actor("player"), start = [...actor.position], gate = stage.preparationGates[team];
|
|
const dx = gate[0] - start[0], dz = gate[2] - start[2], length = Math.hypot(dx, dz);
|
|
actor.movement = [dx / length, dz / length];
|
|
for (let tick = 0; tick < 50; tick++) sim.moveActor(actor, .05);
|
|
assert.ok(Math.hypot(actor.position[0] - start[0], actor.position[2] - start[2]) > 3, `${stage.id} team ${team}: ${actor.position} from ${start}`);
|
|
assert.ok(actor.position.every(Number.isFinite));
|
|
}
|
|
});
|
|
|
|
test("collision geometry blocks arena walls and preserves clear short sight lines", () => {
|
|
const stage = ARENA_STAGES.find((entry) => entry.id === "nagrand-arena");
|
|
const spawn = stage.teamSpawns[0];
|
|
assert.equal(arenaGeometryLineClear(stage.id, [spawn[0], spawn[1] + 1.2, spawn[2]], [spawn[0] + .05, spawn[1] + 1.2, spawn[2]]), true);
|
|
assert.equal(arenaGeometryLineClear(stage.id, [-60, 14.5, -42], [-35, 14.5, -42]), false);
|
|
});
|
|
|
|
test("bots can traverse each complete arena between both teams without invisible walls", () => {
|
|
for (const stage of ARENA_STAGES) for (const team of [0, 1]) {
|
|
const sim = new ArenaSimulation({ id: "path", stage, bracket: "3v3", mode: "practice", ruleset: "wow", startedAt: 1000,
|
|
participants: [0, 1, 2].map((index) => ({ actorId: `p${index}`, name: "Player", team, role: "damage", isBot: false })) });
|
|
sim.phase = "active"; sim.activeStartedAt = 1000;
|
|
for (const actor of sim.actors.values()) assert.notEqual(arenaFloorHeight(stage.id, actor.position[0], actor.position[2], actor.position[1], 2), null, `${stage.id} team ${team} ${actor.id} spawn`);
|
|
const actor = sim.actor("p0"), destination = stage.teamSpawns[1 - team];
|
|
actor.navigationPath = arenaNavigationPath(stage.id, actor.position, destination);
|
|
assert.ok(actor.navigationPath.length, `${stage.id} has a route`);
|
|
for (let tick = 0; tick < 2400; tick++) {
|
|
sim.tickNumber++;
|
|
sim.followBotPath(actor); sim.moveActor(actor, .05);
|
|
if (Math.hypot(actor.position[0] - destination[0], actor.position[2] - destination[2]) < 2) break;
|
|
}
|
|
assert.ok(Math.hypot(actor.position[0] - destination[0], actor.position[2] - destination[2]) < 2, `${stage.id} team ${team} stuck at ${actor.position}`);
|
|
}
|
|
});
|