Back to GRAV / RIFT
SOURCE / PINNED RELEASE

Made of little things.

GRAV / RIFT

Release
288aa261ce07…
Author-recorded commit
c549b5a4e17e…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-8a7361981e8

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

src/game/structures.ts
import type { Body } from './physics.js';
import { WORLD } from './world.js';

export interface Structure { x: number; name: string; parts: Body[]; roots: Body[]; links: [Body,Body][] }
type Spawn = (sprite: number,x: number,y: number,mass: number,scale: number) => Body;

/** Bolted assemblies: load paths keep connected pieces mounted. Removing a
 * support releases every disconnected section into the ordinary simulation. */
export function buildStructures(spawn: Spawn): Structure[] {
  return [850,1690,2590,3420].map((x,index) => {
    const parts: Body[] = [], links: [Body,Body][] = [];
    const add = (dx: number,height: number,scale: number,angle = 0,sprite = 11) => {
      const b = spawn(sprite,x+dx,WORLD.floor-height,2.4*scale,scale);
      b.angle = angle; b.mountAngle = angle; b.attached = true; b.mount = {x:b.x,y:b.y}; b.hp = b.maxHp = 65;
      parts.push(b); return b;
    };
    const left = add(-52,49,1.75,Math.PI/2), right = add(52,49,1.75,Math.PI/2);
    const deck = add(0,105,2.4); links.push([left,deck],[right,deck]);
    const tall = index%2===0;
    if (tall) {
      const a = add(-44,160,1.75,Math.PI/2), b = add(44,160,1.75,Math.PI/2), roof = add(0,215,2.2);
      links.push([deck,a],[deck,b],[a,roof],[b,roof]);
      const crateA = add(-29,252,1,0,12), crateB = add(29,252,1,0,12);
      links.push([roof,crateA],[roof,crateB]);
    } else {
      for(const dx of [-44,0,44]) { const crate = add(dx,140,.85,0,12); links.push([deck,crate]); }
    }
    return {x,name:tall?'BOLTED GANTRY':'SALVAGE RACK',parts,roots:[left,right],links};
  });
}

export function unsupportedParts(structure: Structure): Body[] {
  const live = (b: Body) => b.attached&&!b.dead;
  const connected = new Set(structure.roots.filter(live));
  const queue = [...connected];
  for(let i=0;i<queue.length;i++) for(const [a,b] of structure.links) {
    const next = a===queue[i]?b:b===queue[i]?a:null;
    if(next&&live(next)&&!connected.has(next)) { connected.add(next);queue.push(next); }
  }
  return structure.parts.filter(b=>live(b)&&!connected.has(b));
}