import { describe, expect, it } from "vitest"; import { stepFearedMobAway } from "./mobMotion"; describe("feared mob steering", () => { it("moves away from the player without changing floor height or crossing the leash", () => { const current: [number, number, number] = [2, 7, 0]; const threat = [0, 4, 0] as const; const home = [0, 7, 0] as const; const moved = stepFearedMobAway(current, threat, home, 2, 3, current); const awayFromThreat = [current[0] - threat[0], current[2] - threat[2]]; const originalAway = [2 - threat[0], 0 - threat[2]]; const directionDot = awayFromThreat[0] * originalAway[0] + awayFromThreat[1] * originalAway[1]; expect(moved).toBeCloseTo(1); expect(directionDot).toBeGreaterThan(0); expect(current[1]).toBe(7); expect(Math.hypot(current[0] - home[0], current[2] - home[2])).toBeCloseTo(3); }); it("uses a deterministic direction when the mob and player overlap", () => { const out: [number, number, number] = [0, 0, 0]; stepFearedMobAway([0, 2, 0], [0, 2, 0], [0, 2, 0], 0.5, 5, out); expect(out).toEqual([0.5, 2, 0]); }); it("keeps malformed or zero-step input stationary and finite", () => { const out: [number, number, number] = [9, 9, 9]; expect(stepFearedMobAway([1, 2, 3], [0, 0, 0], [0, 0, 0], Number.NaN, 4, out)).toBe(0); expect(out).toEqual([1, 2, 3]); expect(Object.values(out).every(Number.isFinite)).toBe(true); }); });