Files
2026-05-11 22:07:17 +02:00

61 lines
1.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { computeRangedTarget } from '$lib/engine/ranged';
import { newCharacter } from '$lib/characters/default';
import type { ExtraModifierId } from '$lib/rules/modifiers-ranged';
const fixedId = '00000000-0000-4000-8000-000000000099';
function charWithBogen(taw: number) {
const c = newCharacter({ name: 'Archer', id: fixedId });
const kt = c.kampftalente.find((k) => k.id === 'bogen');
if (kt) kt.taw = taw;
return c;
}
const baseSel = {
range: 'near' as const,
/** Zielgröße „groß“ hat Modifikator 0 in den Tabellen */
targetSize: 'large' as const,
visibility: 'clear' as const,
movement: 'slow' as const,
extras: [] as ExtraModifierId[],
aimTurns: 0,
targetBuild: 'biped' as const
};
describe('ranged', () => {
it('computes FK target with zero modifiers', () => {
const c = charWithBogen(4);
const fkBase = Math.round((11 + 11 + 11) / 4);
const r = computeRangedTarget(c, 'shortbow', { ...baseSel, reloadState: undefined }, 'none');
expect(r.fkBase).toBe(fkBase);
expect(r.baseTarget).toBe(fkBase + 4);
expect(r.finalTarget).toBe(fkBase + 4);
});
it('applies distance modifier (mittel = +4 EW)', () => {
const c = charWithBogen(0);
const r = computeRangedTarget(
c,
'shortbow',
{ ...baseSel, range: 'medium', reloadState: 'regular_shot' },
'none'
);
// +4 Entfernung, +1 normaler Schuss, +0 Zielgröße „groß“
expect(r.totalModifier).toBe(5);
expect(r.finalTarget).toBe(r.baseTarget - 5);
});
it('halves TaW for aimed shot without expertise', () => {
const c = charWithBogen(10);
const r = computeRangedTarget(
c,
'shortbow',
{ ...baseSel, reloadState: 'aimed_shot' },
'none'
);
expect(r.effectiveTaW).toBe(5);
expect(r.baseTarget).toBe(r.fkBase + 5);
});
});