Newer
Older
rpg / v2 / packages / engine / src / interaction / __tests__ / interactables.test.ts
import { describe, it, expect } from 'vitest';
import { nearestInteractable, interactablesInRadius, type Interactable } from '../interactables';

const points: Interactable[] = [
    { id: 'npc', pos: [10, 2, 10], radius: 4, label: 'Поговорить', dialogueId: 'guard' },
    { id: 'chest', pos: [20, 2, 20], radius: 2, label: 'Открыть' },
    { id: 'sign', pos: [40, 2, 10], radius: 3, label: 'Осмотреть' },
];

describe('interaction/interactables', () => {
    it('nearestInteractable: в радиусе — ближайшая, вне — null', () => {
        expect(nearestInteractable(points, [12, 2, 11])?.id).toBe('npc');
        expect(nearestInteractable(points, [10, 2, 14])?.id).toBe('npc'); // ровно на границе
        expect(nearestInteractable(points, [10, 2, 15])).toBeNull();
        expect(nearestInteractable(points, [21, 2, 21])?.id).toBe('chest');
        expect(nearestInteractable(points, [0, 0, 0])).toBeNull();
    });

    it('Y не учитывается — только горизонталь x-z', () => {
        expect(nearestInteractable(points, [10, 100, 12])?.id).toBe('npc');
    });

    it('при пересечении радиусов берётся ближайшая, не первая в списке', () => {
        const two: Interactable[] = [
            { id: 'far', pos: [10, 0, 10], radius: 10, label: 'Дальняя' },
            { id: 'near', pos: [11, 0, 10], radius: 10, label: 'Ближняя' },
        ];
        expect(nearestInteractable(two, [11, 0, 10])?.id).toBe('near'); // 1 < 3
    });

    it('interactablesInRadius: сортировка по дистанции', () => {
        const hits = interactablesInRadius(points, [11, 2, 10]);
        expect(hits.map((h) => h.item.id)).toEqual(['npc']);
        const all: Interactable[] = [
            ...points,
            { id: 'well', pos: [14, 2, 10], radius: 10, label: 'Колодец' },
        ];
        const sorted = interactablesInRadius(all, [11, 2, 10]);
        expect(sorted.map((h) => h.item.id)).toEqual(['npc', 'well']); // 1 < 3
        expect(sorted[0].dist).toBe(1);
        expect(sorted[1].dist).toBe(3);
    });
});