90 lines
3.9 KiB
TypeScript
90 lines
3.9 KiB
TypeScript
import { beforeEach, describe, expect, it } from "vitest";
|
|
import {
|
|
clearPartyRuntimeRegistry,
|
|
clearPartyRuntimeAttackCorridor,
|
|
getPartyRuntimePosition,
|
|
partyRuntimeDistanceSquared,
|
|
partyRuntimeCenter,
|
|
partyRuntimeTargetVisible,
|
|
partyRuntimePositionAlongAttackCorridor,
|
|
registerPartyRuntimePosition,
|
|
updatePartyRuntimeTargetVisibility,
|
|
updatePartyRuntimeAttackCorridor,
|
|
updatePartyRuntimePosition,
|
|
beginPartyRuntimeRejoin,
|
|
consumePartyRuntimeRejoin,
|
|
partyRuntimeIsRejoining,
|
|
finishPartyRuntimeRejoin,
|
|
} from "./partyRuntimeRegistry";
|
|
|
|
describe("party runtime position registry", () => {
|
|
beforeEach(clearPartyRuntimeRegistry);
|
|
|
|
it("consumes a copied relocation once and keeps the individual return task until completed", () => {
|
|
const origin: [number, number, number] = [1, 2, 3];
|
|
beginPartyRuntimeRejoin("tank", origin);
|
|
origin[0] = 999;
|
|
const result = consumePartyRuntimeRejoin("tank")! as [number, number, number];
|
|
expect(result).toEqual([1, 2, 3]);
|
|
result[0] = 888;
|
|
expect(getPartyRuntimePosition("tank")).toEqual([1, 2, 3]);
|
|
expect(consumePartyRuntimeRejoin("tank")).toBeNull();
|
|
expect(partyRuntimeIsRejoining("tank")).toBe(true);
|
|
expect(partyRuntimeIsRejoining("healer")).toBe(false);
|
|
finishPartyRuntimeRejoin("tank");
|
|
expect(partyRuntimeIsRejoining("tank")).toBe(false);
|
|
});
|
|
|
|
it("clears pending resurrection tasks on actor unmount and dungeon switch", () => {
|
|
const unregister = registerPartyRuntimePosition("tank", [0, 0, 0]);
|
|
beginPartyRuntimeRejoin("tank", [1, 0, 0]);
|
|
unregister();
|
|
expect(partyRuntimeIsRejoining("tank")).toBe(false);
|
|
beginPartyRuntimeRejoin("tank", [1, 0, 0]);
|
|
clearPartyRuntimeRegistry();
|
|
expect(consumePartyRuntimeRejoin("tank")).toBeNull();
|
|
expect(partyRuntimeIsRejoining("tank")).toBe(false);
|
|
});
|
|
|
|
it("tracks world actors without exposing mutable registry storage", () => {
|
|
const unregister = registerPartyRuntimePosition("tank", [1, 2, 3]);
|
|
updatePartyRuntimePosition("tank", 4, 5, 6);
|
|
const snapshot = getPartyRuntimePosition("tank")! as [number, number, number];
|
|
snapshot[0] = 999;
|
|
expect(getPartyRuntimePosition("tank")).toEqual([4, 5, 6]);
|
|
unregister();
|
|
expect(getPartyRuntimePosition("tank")).toBeNull();
|
|
});
|
|
|
|
it("computes a party center and uses a finite fallback before actors mount", () => {
|
|
registerPartyRuntimePosition("a", [0, 2, 4]);
|
|
registerPartyRuntimePosition("b", [2, 4, 6]);
|
|
expect(partyRuntimeCenter(["a", "b"], [9, 9, 9])).toEqual([1, 3, 5]);
|
|
expect(partyRuntimeCenter(["missing"], [9, 8, 7])).toEqual([9, 8, 7]);
|
|
});
|
|
|
|
it("measures distance to registered members and rejects missing positions", () => {
|
|
registerPartyRuntimePosition("party-a", [3, 4, 0]);
|
|
expect(partyRuntimeDistanceSquared("party-a", [0, 0, 0])).toBe(25);
|
|
expect(partyRuntimeDistanceSquared("missing", [0, 0, 0])).toBe(Number.POSITIVE_INFINITY);
|
|
});
|
|
|
|
it("scopes collision-checked target visibility to the current target", () => {
|
|
registerPartyRuntimePosition("party-a", [0, 0, 0]);
|
|
updatePartyRuntimeTargetVisibility("party-a", "mob-a", true);
|
|
expect(partyRuntimeTargetVisible("party-a", "mob-a")).toBe(true);
|
|
expect(partyRuntimeTargetVisible("party-a", "mob-b")).toBe(false);
|
|
updatePartyRuntimeTargetVisibility("party-a", "mob-a", false);
|
|
expect(partyRuntimeTargetVisible("party-a", "mob-a")).toBe(false);
|
|
});
|
|
|
|
it("keeps idle add acquisition on the remaining route and current floor", () => {
|
|
updatePartyRuntimeAttackCorridor([0, 0, 0], [[10, 0, 0], [10, 0, 10]], 0);
|
|
expect(partyRuntimePositionAlongAttackCorridor([6, 0, 4], 5)).toBe(true);
|
|
expect(partyRuntimePositionAlongAttackCorridor([6, 8, 4], 5)).toBe(false);
|
|
expect(partyRuntimePositionAlongAttackCorridor([-8, 0, 0], 5)).toBe(false);
|
|
clearPartyRuntimeAttackCorridor();
|
|
expect(partyRuntimePositionAlongAttackCorridor([6, 0, 4], 5)).toBe(false);
|
|
});
|
|
});
|