@adatechnology/game-destruction 0.13.2 → 0.14.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.
package/dist/index.js CHANGED
@@ -2796,6 +2796,7 @@ var createDestruction = (options = {}) => {
2796
2796
  const ignitionRules = resolveIgnitionRules(options.ignition);
2797
2797
  const breachBlastFactor = options.breach?.blastFactor ?? BREACH_BLAST_FACTOR;
2798
2798
  const chipEnergy = options.breach?.chipEnergy ?? CHIP_ENERGY;
2799
+ const chainLinkCap = options.chainLinksPerUpdate !== void 0 && options.chainLinksPerUpdate >= 1 ? Math.floor(options.chainLinksPerUpdate) : Infinity;
2799
2800
  const rng = createRng(options.seed ?? 1);
2800
2801
  const rnd = () => rng.next();
2801
2802
  let time = 0;
@@ -3743,7 +3744,7 @@ var createDestruction = (options = {}) => {
3743
3744
  if (disc < 0) return true;
3744
3745
  return -b - Math.sqrt(disc) > maxDist;
3745
3746
  };
3746
- const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false) => {
3747
+ const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false, precise = false) => {
3747
3748
  const d = vec.normalize(dir);
3748
3749
  let best = null;
3749
3750
  for (const o of objects.values()) {
@@ -3758,13 +3759,25 @@ var createDestruction = (options = {}) => {
3758
3759
  }
3759
3760
  }
3760
3761
  for (const im of worldOnly ? [] : impls.values()) {
3762
+ let boxHit = null;
3761
3763
  for (const ps of im.impl.describe().parts) {
3762
3764
  if (ignore?.has(`${im.impl.id}\0${ps.id}`)) continue;
3763
3765
  const ov = im.poses.get(ps.id);
3764
3766
  const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...ps.rotation ?? [0, 0, 0]), origin, d, ov?.pos);
3765
- if (!r || r.t0 < 0 || r.t0 > maxDist) continue;
3766
- 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 };
3767
+ if (!r || r.t1 < 0 || r.t0 > maxDist) continue;
3768
+ if (r.t0 < 0) {
3769
+ if (precise && im.impl.surfaceRay) boxHit = boxHit ?? { object: im.impl.id, part: ps.id, point: origin, normal: r.n, distance: 0, pathLen: r.t1 };
3770
+ continue;
3771
+ }
3772
+ 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 };
3767
3773
  }
3774
+ if (!boxHit) continue;
3775
+ if (precise && im.impl.surfaceRay) {
3776
+ const far = best ? Math.min(maxDist, best.distance) : maxDist;
3777
+ const implId = im.impl.id;
3778
+ const s = im.impl.surfaceRay({ origin, direction: d, maxDistance: far, ...ignore ? { ignored: (part) => ignore.has(`${implId}\0${part}`) } : {} });
3779
+ 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 };
3780
+ } else if (!best || boxHit.distance < best.distance) best = boxHit;
3768
3781
  }
3769
3782
  return best;
3770
3783
  };
@@ -5248,7 +5261,9 @@ var createDestruction = (options = {}) => {
5248
5261
  };
5249
5262
  const detonatePrimed = (until) => {
5250
5263
  const end = time;
5251
- for (let next = nextPrimed(until); next; next = nextPrimed(until)) {
5264
+ let fired = 0;
5265
+ for (let next = nextPrimed(until); next && fired < chainLinkCap; next = nextPrimed(until)) {
5266
+ fired++;
5252
5267
  primed.delete(next.p);
5253
5268
  time = Math.max(0, Math.min(end, next.p.rt.chainDue));
5254
5269
  next.p.rt.chainDue = void 0;
@@ -5318,6 +5333,7 @@ var createDestruction = (options = {}) => {
5318
5333
  updateBound(o);
5319
5334
  },
5320
5335
  remove(id) {
5336
+ impls.get(id)?.impl.dispose?.();
5321
5337
  objects.delete(id);
5322
5338
  impls.delete(id);
5323
5339
  },
@@ -5393,7 +5409,7 @@ var createDestruction = (options = {}) => {
5393
5409
  return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
5394
5410
  },
5395
5411
  raycast(origin, direction, maxDistance = Infinity) {
5396
- const r = raycastInternal(origin, direction, maxDistance);
5412
+ const r = raycastInternal(origin, direction, maxDistance, void 0, false, true);
5397
5413
  return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null;
5398
5414
  },
5399
5415
  sweepBox(box, direction, distance, options2 = {}) {
@@ -5418,11 +5434,11 @@ var createDestruction = (options = {}) => {
5418
5434
  let org = origin;
5419
5435
  let E = energy;
5420
5436
  for (let i = 0; i < 4 && E > 0; i++) {
5421
- const rh = raycastInternal(org, d, Infinity, ignore);
5437
+ const rh = raycastInternal(org, d, Infinity, ignore, false, true);
5422
5438
  if (!rh) break;
5423
5439
  const im = impls.get(rh.object);
5424
5440
  if (im) {
5425
- const r = implHit(im, { type: "ballistic", point: rh.point, direction: d, energy: E, caliber, ...extras, ...source !== void 0 ? { source } : {} });
5441
+ 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 } : {} });
5426
5442
  r.part = rh.part;
5427
5443
  r.point = rh.point;
5428
5444
  r.exitEnergy = r.penetrated ? E * 0.5 : 0;
@@ -5683,6 +5699,9 @@ var createDestruction = (options = {}) => {
5683
5699
  return world;
5684
5700
  };
5685
5701
 
5702
+ // src/assemblies.ts
5703
+ import { applyPatches, mergeById, removeIds } from "@adatechnology/game-contracts";
5704
+
5686
5705
  // src/data/assemblies.json
5687
5706
  var assemblies_default = [
5688
5707
  {
@@ -5748,17 +5767,34 @@ var assemblies_default = [
5748
5767
  ];
5749
5768
 
5750
5769
  // src/assemblies.ts
5770
+ var SHIPPED = structuredClone(assemblies_default);
5751
5771
  var ASSEMBLIES = assemblies_default;
5752
- var registerAssembly = (def) => {
5753
- const at = ASSEMBLIES.findIndex((a) => a.id === def.id);
5754
- if (at >= 0) ASSEMBLIES[at] = def;
5755
- else ASSEMBLIES.push(def);
5772
+ var assembliesOver = (defs) => {
5773
+ const get = (id) => defs.find((a) => a.id === id);
5774
+ return {
5775
+ list: () => defs,
5776
+ get,
5777
+ register(def) {
5778
+ const at = defs.findIndex((a) => a.id === def.id);
5779
+ if (at >= 0) defs[at] = def;
5780
+ else defs.push(def);
5781
+ },
5782
+ part: (assemblyId, options) => buildAssemblyPart(get(assemblyId), assemblyId, options)
5783
+ };
5784
+ };
5785
+ var createAssemblies = (options = {}) => {
5786
+ const entries = mergeById(SHIPPED.map((def) => structuredClone(def)), (options.packs ?? []).flat());
5787
+ applyPatches(entries, options.patch);
5788
+ removeIds(entries, options.remove);
5789
+ return assembliesOver([...entries.values()]);
5756
5790
  };
5757
- var getAssembly = (id) => ASSEMBLIES.find((a) => a.id === id);
5791
+ var defaultSet;
5792
+ var defaultAssemblies = () => defaultSet ?? (defaultSet = assembliesOver(ASSEMBLIES));
5793
+ var registerAssembly = (def) => defaultAssemblies().register(def);
5794
+ var getAssembly = (id) => defaultAssemblies().get(id);
5758
5795
  var faceCount = (layer) => layer.faces === "both" ? 2 : 1;
5759
5796
  var assemblyDepth = (def) => def.depth ?? def.core.thickness + (def.layers ?? []).reduce((sum, l) => sum + l.thickness * faceCount(l), 0);
5760
- var assemblyPart = (assemblyId, options) => {
5761
- const def = getAssembly(assemblyId);
5797
+ var buildAssemblyPart = (def, assemblyId, options) => {
5762
5798
  if (!def) throw new Error(`unknown assembly "${assemblyId}"`);
5763
5799
  const densityOf = (id) => {
5764
5800
  const m = options.materials?.get(id) ?? MATERIALS.find((x) => x.id === id);
@@ -5785,6 +5821,7 @@ var assemblyPart = (assemblyId, options) => {
5785
5821
  ...options.extra
5786
5822
  };
5787
5823
  };
5824
+ var assemblyPart = (assemblyId, options) => defaultAssemblies().part(assemblyId, options);
5788
5825
 
5789
5826
  // src/frame.ts
5790
5827
  var buildFrame = (o = {}) => {
@@ -6224,7 +6261,7 @@ var resolveStrings = (locale) => locales[locale ?? "en"] ?? locales.en;
6224
6261
  import { checkDestructible as check } from "@adatechnology/game-contracts";
6225
6262
  import { IMPACT_CONTRACT, checkHit } from "@adatechnology/game-contracts";
6226
6263
  var checkDestructible = (impl, options = {}) => {
6227
- const contractOptions = { materials: [...MATERIALS.map((m) => m.id), ...options.materials ?? []] };
6264
+ const contractOptions = { materials: [...MATERIALS.map((m) => m.id), ...options.materials ?? []], ...options.cost === void 0 ? {} : { cost: options.cost } };
6228
6265
  return check(impl, contractOptions);
6229
6266
  };
6230
6267
  export {
@@ -6254,9 +6291,11 @@ export {
6254
6291
  checkDestructible,
6255
6292
  checkHit,
6256
6293
  crackingMoment,
6294
+ createAssemblies,
6257
6295
  createDestruction,
6258
6296
  damperAmplification,
6259
6297
  damperTuning,
6298
+ defaultAssemblies,
6260
6299
  elasticEnergy,
6261
6300
  explosivePart,
6262
6301
  exposureOf,