Back to Pursuit PIT
SOURCE / PINNED RELEASE

Made of little things.

Pursuit PIT

Release
565f4981bdc3…
Author-recorded commit
197afdbed44b…
License
LICENSE
Author’s source reference
nostr://npub12lm3rxsva8kfempyjkxupt09e02n3fezurkyadyqfejdc5e0r2kscqty6r/wss%3A%2F%2Fgit.napplet.soy%2F/n-951414e7fd7

Archive hash verified: 3b0485589942fd5c…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/game/parts.ts
// Body panels that can be knocked off a car. Shared by the sim (which decides what breaks)
// and the renderer (which draws and drops them). Local axes: lat is right, lon is forward,
// y is height of the panel's centre; w, l, h are its size across, along and up.

export interface Part {
  name: string;
  lat: number;
  lon: number;
  y: number;
  w: number;
  l: number;
  h: number;
}

export function partsFor(len: number, wid: number): Part[] {
  const side = wid / 2 - 0.05;
  return [
    { name: 'front bumper', lat: 0, lon: len / 2 - 0.15, y: 0.45, w: wid, l: 0.3, h: 0.3 },
    { name: 'rear bumper', lat: 0, lon: -(len / 2 - 0.15), y: 0.45, w: wid, l: 0.3, h: 0.3 },
    { name: 'hood', lat: 0, lon: len * 0.3, y: 0.89, w: wid * 0.92, l: len * 0.3, h: 0.07 },
    { name: 'trunk', lat: 0, lon: -len * 0.34, y: 0.89, w: wid * 0.92, l: len * 0.22, h: 0.07 },
    { name: 'left front fender', lat: -side, lon: len * 0.29, y: 0.62, w: 0.1, l: len * 0.26, h: 0.5 },
    { name: 'right front fender', lat: side, lon: len * 0.29, y: 0.62, w: 0.1, l: len * 0.26, h: 0.5 },
    { name: 'left door', lat: -side, lon: 0, y: 0.62, w: 0.1, l: len * 0.32, h: 0.5 },
    { name: 'right door', lat: side, lon: 0, y: 0.62, w: 0.1, l: len * 0.32, h: 0.5 },
    { name: 'left rear quarter', lat: -side, lon: -len * 0.29, y: 0.62, w: 0.1, l: len * 0.26, h: 0.5 },
    { name: 'right rear quarter', lat: side, lon: -len * 0.29, y: 0.62, w: 0.1, l: len * 0.26, h: 0.5 },
  ];
}

export const ALL_PARTS = (1 << 10) - 1;

/** The attached panel nearest a contact point given in the car's local frame, or -1. */
export function nearestPart(len: number, wid: number, lost: number, lat: number, lon: number): number {
  let best = -1;
  let bestD = Infinity;
  partsFor(len, wid).forEach((p, i) => {
    if (lost & (1 << i)) return;
    // Hood and trunk only come off from the ends, not side swipes.
    const d = Math.hypot(p.lat - lat, p.lon - lon) + (p.h < 0.1 ? 0.6 : 0);
    if (d < bestD) {
      bestD = d;
      best = i;
    }
  });
  return best;
}