@adatechnology/game-floorplan-structure 1.3.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2383,6 +2383,7 @@ var GameFloorplanStructure = (() => {
2383
2383
  }
2384
2384
 
2385
2385
  // ../game-contracts/dist/index.js
2386
+ var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
2386
2387
  var DEFAULT_IGNITION_RULES = {
2387
2388
  fillCurve: [
2388
2389
  [0, 0.6],
@@ -2426,6 +2427,54 @@ var GameFloorplanStructure = (() => {
2426
2427
  const flame = flameBase * (1 - rules.flameFillInfluence * (1 - k));
2427
2428
  return 1 - (1 - Math.min(1, Math.max(0, spark))) * (1 - Math.min(1, Math.max(0, flame)));
2428
2429
  };
2430
+ var DEFERRED_QUEUE_ID = {
2431
+ DESTRUCTION_EVENTS: "destruction.events",
2432
+ BREACH_PAINT: "floorplan.breach-paint",
2433
+ AUDIO_VOICES: "audio.voices",
2434
+ VEHICLE_CREASE: "vehicles.crease"
2435
+ };
2436
+ var DEFERRED_PRIORITY = {
2437
+ [DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS]: { priority: 300, phase: "present" },
2438
+ [DEFERRED_QUEUE_ID.BREACH_PAINT]: { priority: 250, phase: "present" },
2439
+ [DEFERRED_QUEUE_ID.AUDIO_VOICES]: { priority: 200, phase: "idle", reserveMs: 1 },
2440
+ [DEFERRED_QUEUE_ID.VEHICLE_CREASE]: { priority: 100, phase: "idle" }
2441
+ };
2442
+ var SURFACE_IDS = ["concrete", "asphalt", "wood", "tile", "dirt", "grass", "gravel", "sand", "metal", "water", "glass", "carpet"];
2443
+ var GAIT_IDS = ["walk", "run"];
2444
+ var LANDING_IDS = ["light", "heavy"];
2445
+ var BODY_SOUND_IDS = [
2446
+ "jump",
2447
+ "cloth_rustle",
2448
+ "body_fall",
2449
+ "fall_damage",
2450
+ "player_hurt",
2451
+ "player_breath_run",
2452
+ "player_death",
2453
+ "bite",
2454
+ "grab",
2455
+ "punch_swing",
2456
+ "punch_hit_body",
2457
+ "punch_hit_face",
2458
+ "punch_hit_object",
2459
+ "kick_swing",
2460
+ "kick_hit",
2461
+ "kick_hit_object",
2462
+ "shove_two_hands",
2463
+ "knife_swing",
2464
+ "knife_stab",
2465
+ "knife_slash",
2466
+ "knife_hit_object",
2467
+ "blunt_swing",
2468
+ "blunt_hit",
2469
+ "blunt_hit_object",
2470
+ "axe_swing",
2471
+ "axe_chop",
2472
+ "axe_hit_object"
2473
+ ];
2474
+ var footstepSoundId = (surface, gait) => `footstep_${surface}_${gait}`;
2475
+ var FOOTSTEP_SOUND_IDS = SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstepSoundId(surface, gait)));
2476
+ var LAND_SOUND_IDS = SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((landing) => `land_${surface}_${landing}`));
2477
+ var BODY_FOLEY_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
2429
2478
 
2430
2479
  // ../game-destruction/dist/index.js
2431
2480
  var FIRE_PRIME_C = 300;
@@ -5064,6 +5113,7 @@ var GameFloorplanStructure = (() => {
5064
5113
  var CHIP_ENERGY = 200;
5065
5114
  var CHIP_SPLASH = 0.5;
5066
5115
  var CRATER_SPENT = 0.6;
5116
+ var EDGE_REACH = 1.5;
5067
5117
  var BAR_BOW = 0.08;
5068
5118
  var BULLET_JOINT_SPAN = 0.3;
5069
5119
  var CUT_SLICE = 1;
@@ -5136,6 +5186,7 @@ var GameFloorplanStructure = (() => {
5136
5186
  const ignitionRules = resolveIgnitionRules(options.ignition);
5137
5187
  const breachBlastFactor = options.breach?.blastFactor ?? BREACH_BLAST_FACTOR;
5138
5188
  const chipEnergy = options.breach?.chipEnergy ?? CHIP_ENERGY;
5189
+ const chainLinkCap = options.chainLinksPerUpdate !== void 0 && options.chainLinksPerUpdate >= 1 ? Math.floor(options.chainLinksPerUpdate) : Infinity;
5139
5190
  const rng = createRng(options.seed ?? 1);
5140
5191
  const rnd = () => rng.next();
5141
5192
  let time = 0;
@@ -6083,7 +6134,7 @@ var GameFloorplanStructure = (() => {
6083
6134
  if (disc < 0) return true;
6084
6135
  return -b - Math.sqrt(disc) > maxDist;
6085
6136
  };
6086
- const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false) => {
6137
+ const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false, precise = false) => {
6087
6138
  const d = vec.normalize(dir);
6088
6139
  let best = null;
6089
6140
  for (const o of objects.values()) {
@@ -6098,13 +6149,25 @@ var GameFloorplanStructure = (() => {
6098
6149
  }
6099
6150
  }
6100
6151
  for (const im of worldOnly ? [] : impls.values()) {
6152
+ let boxHit = null;
6101
6153
  for (const ps of im.impl.describe().parts) {
6102
6154
  if (ignore?.has(`${im.impl.id}\0${ps.id}`)) continue;
6103
6155
  const ov = im.poses.get(ps.id);
6104
6156
  const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...ps.rotation ?? [0, 0, 0]), origin, d, ov?.pos);
6105
- if (!r || r.t0 < 0 || r.t0 > maxDist) continue;
6106
- if (!best || r.t0 < best.distance) best = { object: im.impl.id, part: ps.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 };
6157
+ if (!r || r.t1 < 0 || r.t0 > maxDist) continue;
6158
+ if (r.t0 < 0) {
6159
+ if (precise && im.impl.surfaceRay) boxHit = boxHit ?? { object: im.impl.id, part: ps.id, point: origin, normal: r.n, distance: 0, pathLen: r.t1 };
6160
+ continue;
6161
+ }
6162
+ if (!boxHit || r.t0 < boxHit.distance) boxHit = { object: im.impl.id, part: ps.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 };
6107
6163
  }
6164
+ if (!boxHit) continue;
6165
+ if (precise && im.impl.surfaceRay) {
6166
+ const far = best ? Math.min(maxDist, best.distance) : maxDist;
6167
+ const implId = im.impl.id;
6168
+ const s = im.impl.surfaceRay({ origin, direction: d, maxDistance: far, ...ignore ? { ignored: (part) => ignore.has(`${implId}\0${part}`) } : {} });
6169
+ if (s && (!best || s.distance < best.distance)) best = { object: implId, part: s.part, point: s.point, normal: s.normal, distance: s.distance, pathLen: s.pathLen };
6170
+ } else if (!best || boxHit.distance < best.distance) best = boxHit;
6108
6171
  }
6109
6172
  return best;
6110
6173
  };
@@ -6437,6 +6500,9 @@ var GameFloorplanStructure = (() => {
6437
6500
  const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
6438
6501
  size[a] = w;
6439
6502
  center[a] = clamp22(lp[a], lo, hi);
6503
+ const [from, to] = tornToEdge({ p, cell, a, b: a === u ? v : u, at: lp[a], crater: [center[a] - w / 2, center[a] + w / 2], reach: w * EDGE_REACH, gone: (k) => worn[k] === -1 });
6504
+ size[a] = to - from;
6505
+ center[a] = (from + to) / 2;
6440
6506
  }
6441
6507
  const taken2 = (cut[i] ?? 0) + size[u] * size[v];
6442
6508
  if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
@@ -6474,6 +6540,19 @@ var GameFloorplanStructure = (() => {
6474
6540
  collapseCheck(o, src);
6475
6541
  }
6476
6542
  };
6543
+ const tornToEdge = (o) => {
6544
+ const { p, cell, a, b, at: at2, crater: crater2, reach, gone } = o;
6545
+ const half = p.dims[a] / 2;
6546
+ const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
6547
+ const free = (side, sign) => {
6548
+ if (sign > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign > 0 || a !== planeAxes(p.thin)[1];
6549
+ const probe = side + sign * 1e-3;
6550
+ return gridOf(p).some((c, k) => gone(k) && Math.abs(probe - c.center[a]) <= c.size[a] / 2 && Math.abs(cell.center[b] - c.center[b]) <= c.size[b] / 2);
6551
+ };
6552
+ if (at2 - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
6553
+ if (hi - at2 <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
6554
+ return crater2;
6555
+ };
6477
6556
  const craterAcross = (energy) => clamp22(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
6478
6557
  const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
6479
6558
  const { c, q } = partXf(o, p);
@@ -7572,7 +7651,9 @@ var GameFloorplanStructure = (() => {
7572
7651
  };
7573
7652
  const detonatePrimed = (until) => {
7574
7653
  const end = time;
7575
- for (let next = nextPrimed(until); next; next = nextPrimed(until)) {
7654
+ let fired = 0;
7655
+ for (let next = nextPrimed(until); next && fired < chainLinkCap; next = nextPrimed(until)) {
7656
+ fired++;
7576
7657
  primed.delete(next.p);
7577
7658
  time = Math.max(0, Math.min(end, next.p.rt.chainDue));
7578
7659
  next.p.rt.chainDue = void 0;
@@ -7642,6 +7723,7 @@ var GameFloorplanStructure = (() => {
7642
7723
  updateBound(o);
7643
7724
  },
7644
7725
  remove(id) {
7726
+ impls.get(id)?.impl.dispose?.();
7645
7727
  objects.delete(id);
7646
7728
  impls.delete(id);
7647
7729
  },
@@ -7717,7 +7799,7 @@ var GameFloorplanStructure = (() => {
7717
7799
  return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
7718
7800
  },
7719
7801
  raycast(origin, direction, maxDistance = Infinity) {
7720
- const r = raycastInternal(origin, direction, maxDistance);
7802
+ const r = raycastInternal(origin, direction, maxDistance, void 0, false, true);
7721
7803
  return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null;
7722
7804
  },
7723
7805
  sweepBox(box2, direction, distance2, options2 = {}) {
@@ -7742,11 +7824,11 @@ var GameFloorplanStructure = (() => {
7742
7824
  let org = origin;
7743
7825
  let E = energy;
7744
7826
  for (let i = 0; i < 4 && E > 0; i++) {
7745
- const rh = raycastInternal(org, d, Infinity, ignore);
7827
+ const rh = raycastInternal(org, d, Infinity, ignore, false, true);
7746
7828
  if (!rh) break;
7747
7829
  const im = impls.get(rh.object);
7748
7830
  if (im) {
7749
- const r = implHit(im, { type: "ballistic", point: rh.point, direction: d, energy: E, caliber, ...extras, ...source !== void 0 ? { source } : {} });
7831
+ const r = implHit(im, { type: "ballistic", point: rh.point, part: rh.part, normal: rh.normal, direction: d, energy: E, caliber, ...extras, ...source !== void 0 ? { source } : {} });
7750
7832
  r.part = rh.part;
7751
7833
  r.point = rh.point;
7752
7834
  r.exitEnergy = r.penetrated ? E * 0.5 : 0;
@@ -8068,12 +8150,27 @@ var GameFloorplanStructure = (() => {
8068
8150
  breach: { area: 0.1 }
8069
8151
  }
8070
8152
  ];
8153
+ var SHIPPED = structuredClone(assemblies_default);
8071
8154
  var ASSEMBLIES = assemblies_default;
8072
- var getAssembly = (id) => ASSEMBLIES.find((a) => a.id === id);
8155
+ var assembliesOver = (defs) => {
8156
+ const get = (id) => defs.find((a) => a.id === id);
8157
+ return {
8158
+ list: () => defs,
8159
+ get,
8160
+ register(def) {
8161
+ const at2 = defs.findIndex((a) => a.id === def.id);
8162
+ if (at2 >= 0) defs[at2] = def;
8163
+ else defs.push(def);
8164
+ },
8165
+ part: (assemblyId, options) => buildAssemblyPart(get(assemblyId), assemblyId, options)
8166
+ };
8167
+ };
8168
+ var defaultSet;
8169
+ var defaultAssemblies = () => defaultSet ?? (defaultSet = assembliesOver(ASSEMBLIES));
8170
+ var getAssembly = (id) => defaultAssemblies().get(id);
8073
8171
  var faceCount = (layer) => layer.faces === "both" ? 2 : 1;
8074
8172
  var assemblyDepth = (def) => def.depth ?? def.core.thickness + (def.layers ?? []).reduce((sum, l) => sum + l.thickness * faceCount(l), 0);
8075
- var assemblyPart = (assemblyId, options) => {
8076
- const def = getAssembly(assemblyId);
8173
+ var buildAssemblyPart = (def, assemblyId, options) => {
8077
8174
  if (!def) throw new Error(`unknown assembly "${assemblyId}"`);
8078
8175
  const densityOf2 = (id) => {
8079
8176
  const m = options.materials?.get(id) ?? MATERIALS.find((x) => x.id === id);
@@ -8100,6 +8197,7 @@ var GameFloorplanStructure = (() => {
8100
8197
  ...options.extra
8101
8198
  };
8102
8199
  };
8200
+ var assemblyPart = (assemblyId, options) => defaultAssemblies().part(assemblyId, options);
8103
8201
  var buildFrame = (o = {}) => {
8104
8202
  const spanX = o.spanX ?? 8, spanZ = o.spanZ ?? 8;
8105
8203
  const nx = Math.max(2, o.columnsX ?? 3), nz = Math.max(2, o.columnsZ ?? 3);