34 lines
1.3 KiB
TypeScript
34 lines
1.3 KiB
TypeScript
import { afterEach, describe, expect, it } from "vitest";
|
|
import {
|
|
combatHasLineOfSight,
|
|
isPositionInFacingArc,
|
|
isSourceBehindTarget,
|
|
projectCombatGroundPoint,
|
|
registerCombatSpatialProvider,
|
|
resetCombatSpatialProvider,
|
|
} from "./combatSpatial";
|
|
|
|
describe("renderer-independent combat spatial queries", () => {
|
|
afterEach(resetCombatSpatialProvider);
|
|
|
|
it("validates facing and behind arcs", () => {
|
|
const actor = { id: "actor", position: [0, 0, 0] as const, yaw: 0 };
|
|
expect(isPositionInFacingArc(actor, [0, 0, 5])).toBe(true);
|
|
expect(isPositionInFacingArc(actor, [0, 0, -5])).toBe(false);
|
|
expect(isSourceBehindTarget([0, 0, -2], actor)).toBe(true);
|
|
expect(isSourceBehindTarget([0, 0, 2], actor)).toBe(false);
|
|
});
|
|
|
|
it("delegates line of sight and collision-safe ground projection", () => {
|
|
registerCombatSpatialProvider({
|
|
actor: () => null,
|
|
hasLineOfSight: (_source, target) => target[0] >= 0,
|
|
projectGroundPoint: (requested) => requested[1] > 5 ? null : [requested[0], 0, requested[2]],
|
|
});
|
|
expect(combatHasLineOfSight([0, 0, 0], [2, 0, 0])).toBe(true);
|
|
expect(combatHasLineOfSight([0, 0, 0], [-2, 0, 0])).toBe(false);
|
|
expect(projectCombatGroundPoint([2, 3, 4], 10)).toEqual([2, 0, 4]);
|
|
expect(projectCombatGroundPoint([2, 8, 4], 10)).toBeNull();
|
|
});
|
|
});
|