import { describe, expect, it } from 'vitest';
import { inInteractRangePos, pickInteract, type InteractCandidate } from '../InteractRouting';
describe('inInteractRangePos — истинная евклидова линейка (юнит = тайл)', () => {
// Центр тайла (5,5) = мир (5.5, 5.5): NPC/объект стоят в центре своего тайла.
it('соседний тайл по оси — в радиусе (дистанция 1.0)', () => {
expect(inInteractRangePos({ x: 6.5, y: 5.5 }, 5, 5)).toBe(true);
});
it('диагональный сосед — в радиусе (дистанция 1.414 < 1.5)', () => {
// findPathToNeighbor может привести героя в диагонального соседа цели.
expect(inInteractRangePos({ x: 6.5, y: 6.5 }, 5, 5)).toBe(true);
});
it('два тайла — вне радиуса (дистанция 2.0): дальний клик не срабатывает', () => {
// Регресс бага: проекционная линейка давала «радиус» в 2-3 тайла.
expect(inInteractRangePos({ x: 7.5, y: 5.5 }, 5, 5)).toBe(false);
});
it('2 тайла вдоль мировой диагонали (проекция была бы «ближе») — вне радиуса', () => {
expect(inInteractRangePos({ x: 6.5, y: 6.5 }, 4, 4)).toBe(false);
});
});
describe('pickInteract — выбор цели кнопки действия', () => {
/** Кандидат-заглушка: тайл задаёт дистанцию (герой в (0,0)). */
function cand(
kind: InteractCandidate['kind'],
tile: { x: number; y: number },
label = 'цель'
): InteractCandidate {
return { kind, tile, dist: Math.hypot(tile.x, tile.y), label };
}
it('ближайший кандидат в радиусе — он', () => {
const c = pickInteract([cand('npc', { x: 2, y: 0 }), cand('interact', { x: 1, y: 0 })]);
expect(c?.label).toBe('цель');
expect(c?.kind).toBe('interact');
expect(c?.tile).toEqual({ x: 1, y: 0 });
});
it('вне радиуса (два тайла и дальше) — не выбирается', () => {
expect(pickInteract([cand('npc', { x: 2, y: 0 })])).toBeNull();
expect(pickInteract([])).toBeNull();
});
it('ничья по дистанции — приоритет NPC выше интерактива', () => {
const c = pickInteract([cand('interact', { x: 1, y: 0 }), cand('npc', { x: 0, y: 1 })]);
expect(c?.kind).toBe('npc');
});
it('почти-ничья (в эпсилоне) — приоритет: переход выше цветка', () => {
const c = pickInteract([cand('flower', { x: 1, y: 1 }), cand('transition', { x: 1.04, y: 0 })]);
expect(c?.kind).toBe('transition');
});
it('заметно ближе — дистанция побеждает приоритет', () => {
const c = pickInteract([cand('npc', { x: 1, y: 0 }), cand('flower', { x: 0.5, y: 0 })]);
expect(c?.kind).toBe('flower');
});
it('заперто — кандидат locked с текстом', () => {
const c: InteractCandidate = {
kind: 'locked',
tile: { x: 1, y: 0 },
dist: 1,
label: 'дверь',
text: 'Заперто.'
};
expect(pickInteract([c])?.text).toBe('Заперто.');
});
});