quill/val Public Public: anyone can read this; nobody can change it.
forked from benjivers/val
workbenchthis machine
Files d7211248ad6d576d3c93536129a0d746e3c90526
| 1 | import { expect, test } from "bun:test"; |
| 2 | import { fade, firedNow, gunFire, gunSnapshot, gunTick, hitMarked, makeGun } from "../../static/engine/gun.js"; |
| 3 | |
| 4 | const snap = (over: Record<string, unknown> = {}, shots: unknown[] = []) => ({ |
| 5 | me: { x: 100, y: 100, ammo: 25, reloading: false, alive: true, ...over }, |
| 6 | shots, |
| 7 | }); |
| 8 | |
| 9 | test("the magazine going down is a shot; a reload is not", () => { |
| 10 | expect(firedNow(25, 24, false)).toBe(true); |
| 11 | expect(firedNow(25, 25, false)).toBe(false); |
| 12 | expect(firedNow(1, 25, true)).toBe(false); |
| 13 | expect(firedNow(null, 25, false)).toBe(false); |
| 14 | }); |
| 15 | |
| 16 | test("a hit marker comes from a shot of mine the server says landed", () => { |
| 17 | const mine = [{ x1: 102, y1: 99, x2: 400, y2: 100, hit: true }]; |
| 18 | expect(hitMarked(mine, { x: 100, y: 100 })).toBe(true); |
| 19 | const missed = [{ x1: 102, y1: 99, x2: 400, y2: 100, hit: false }]; |
| 20 | expect(hitMarked(missed, { x: 100, y: 100 })).toBe(false); |
| 21 | const somebody_else = [{ x1: 900, y1: 900, x2: 400, y2: 100, hit: true }]; |
| 22 | expect(hitMarked(somebody_else, { x: 100, y: 100 })).toBe(false); |
| 23 | }); |
| 24 | |
| 25 | test("a snapshot with a shot in it kicks the gun, and the kick fades", () => { |
| 26 | const gun = makeGun(); |
| 27 | gunSnapshot(gun, snap()); |
| 28 | expect(gun.kick).toBe(0); |
| 29 | gunSnapshot(gun, snap({ ammo: 24 })); |
| 30 | expect(gun.kick).toBe(1); |
| 31 | gunTick(gun, 0.06); |
| 32 | expect(gun.kick).toBeLessThan(1); |
| 33 | gunTick(gun, 1); |
| 34 | expect(gun.kick).toBe(0); |
| 35 | }); |
| 36 | |
| 37 | test("a landed shot marks, and the mark fades on its own clock", () => { |
| 38 | const gun = makeGun(); |
| 39 | gunSnapshot(gun, snap({ ammo: 24 }, [{ x1: 100, y1: 100, x2: 300, y2: 100, hit: true }])); |
| 40 | expect(gun.mark).toBe(1); |
| 41 | gunTick(gun, 0.2); |
| 42 | expect(gun.mark).toBeGreaterThan(0); |
| 43 | gunTick(gun, 0.2); |
| 44 | expect(gun.mark).toBe(0); |
| 45 | }); |
| 46 | |
| 47 | test("pulling the trigger kicks the gun now, and the snapshot's word is not a second kick", () => { |
| 48 | const gun = makeGun(); |
| 49 | gunSnapshot(gun, snap()); |
| 50 | expect(gunFire(gun, snap())).toBe(true); |
| 51 | expect(gun.kick).toBe(1); |
| 52 | // The kick is well under way when the server's word arrives: no restart. |
| 53 | gunTick(gun, 0.08); |
| 54 | const shown = gun.kick; |
| 55 | gunSnapshot(gun, snap({ ammo: 24 })); |
| 56 | expect(gun.kick).toBe(shown); |
| 57 | // A second shot the server fired on its own (a held trigger) still kicks. |
| 58 | gunSnapshot(gun, snap({ ammo: 23 })); |
| 59 | expect(gun.kick).toBe(1); |
| 60 | // No kick with nothing to fire: dead, reloading, or empty. |
| 61 | expect(gunFire(makeGun(), snap({ alive: false }))).toBe(false); |
| 62 | expect(gunFire(makeGun(), snap({ reloading: true }))).toBe(false); |
| 63 | expect(gunFire(makeGun(), snap({ ammo: 0 }))).toBe(false); |
| 64 | // A kick the server never answered is forgotten once it has faded. |
| 65 | const refused = makeGun(); |
| 66 | gunFire(refused, snap()); |
| 67 | gunTick(refused, 1); |
| 68 | gunSnapshot(refused, snap()); |
| 69 | expect(refused.owed).toBe(0); |
| 70 | }); |
| 71 | |
| 72 | test("fade never goes below nothing", () => { |
| 73 | expect(fade(0.1, 10, 0.2)).toBe(0); |
| 74 | }); |