@adatechnology/game-destruction 0.14.0 → 0.16.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
@@ -2819,7 +2819,13 @@ var createDestruction = (options = {}) => {
2819
2819
  const typed = listeners.get(e.type);
2820
2820
  if (typed) for (const fn of [...typed]) fn(e);
2821
2821
  };
2822
- const base = (o, source) => source === void 0 ? { object: o.id, time } : { object: o.id, time, source };
2822
+ let blow;
2823
+ const base = (o, source) => ({
2824
+ object: o.id,
2825
+ time,
2826
+ ...source === void 0 ? {} : { source },
2827
+ ...blow === void 0 ? {} : { blow }
2828
+ });
2823
2829
  const pendingCollapse = /* @__PURE__ */ new Map();
2824
2830
  let runDepth = 0;
2825
2831
  const drainBlasts = () => {
@@ -4370,7 +4376,7 @@ var createDestruction = (options = {}) => {
4370
4376
  return;
4371
4377
  }
4372
4378
  if (ex) {
4373
- emit({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
4379
+ emit({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.tnt !== void 0 ? { tnt: ex.tnt } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
4374
4380
  blasts.push({ point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, source: src });
4375
4381
  }
4376
4382
  partLost(o, p, src);
@@ -4964,7 +4970,17 @@ var createDestruction = (options = {}) => {
4964
4970
  res.events = cur.slice(start);
4965
4971
  return res;
4966
4972
  };
4967
- const doHit = (o, hit, only) => {
4973
+ const withBlow = (type, fn) => () => {
4974
+ const outer = blow;
4975
+ blow = type;
4976
+ try {
4977
+ return fn();
4978
+ } finally {
4979
+ blow = outer;
4980
+ }
4981
+ };
4982
+ const doHit = (o, hit, only) => withBlow(hit.type, () => resolveHit(o, hit, only))();
4983
+ const resolveHit = (o, hit, only) => {
4968
4984
  let point = hit.point;
4969
4985
  let dir = hit.direction;
4970
4986
  if (hit.space === "local") {
@@ -5403,6 +5419,44 @@ var createDestruction = (options = {}) => {
5403
5419
  blastProbe() {
5404
5420
  return { ...blastProbe };
5405
5421
  },
5422
+ blastReach(point, target, options2 = {}) {
5423
+ const L = vec.distance(point, target);
5424
+ if (L < 1e-4) return 1;
5425
+ const shelter = { ...SHELTER_DEFAULTS, ...options2.shelter };
5426
+ const ignore = new Set(options2.ignore ?? []);
5427
+ const d = vec.scale(vec.sub(target, point), 1 / L);
5428
+ let t = 1;
5429
+ for (const o of objects.values()) {
5430
+ if (ignore.has(o.id) || raySphereMiss(point, d, toWorld(o.st.position, o.st.rotation, o.bc), o.br, L)) continue;
5431
+ for (const p of o.parts) {
5432
+ if (isLost(p) || p.st.stripped) continue;
5433
+ const r = rayPart(o, p, point, d);
5434
+ if (!r) continue;
5435
+ const t0 = Math.max(r.t0, 0);
5436
+ const path = Math.min(r.t1, L) - t0;
5437
+ if (path < shelter.minPath) continue;
5438
+ if (p.st.opening && insideOpening(o, p, toLocal(o.st.position, o.st.rotation, vec.madd(point, d, t0 + path / 2)))) continue;
5439
+ t *= Math.exp(-(p.mat.hpPerKg * p.mat.density * path * (p.mat.damageScale?.shelter ?? 1)) / shelter.k);
5440
+ if (t < 1e-4) return 0;
5441
+ }
5442
+ }
5443
+ for (const im of impls.values()) {
5444
+ if (ignore.has(im.impl.id)) continue;
5445
+ for (const ps of im.impl.describe().parts) {
5446
+ const mat = materials.get(ps.material);
5447
+ if (!mat) continue;
5448
+ const ov = im.poses.get(ps.id);
5449
+ const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...ps.rotation ?? [0, 0, 0]), point, d, ov?.pos);
5450
+ if (!r || r.t1 < 0 || r.t0 > L) continue;
5451
+ let path = Math.min(r.t1, L) - Math.max(r.t0, 0);
5452
+ if (ps.thickness !== void 0 && ps.thickness > 0) path = Math.min(path, 2 * ps.thickness);
5453
+ else if (path < shelter.minPath) continue;
5454
+ t *= Math.exp(-(mat.hpPerKg * mat.density * path * (mat.damageScale?.shelter ?? 1)) / shelter.k);
5455
+ if (t < 1e-4) return 0;
5456
+ }
5457
+ }
5458
+ return t;
5459
+ },
5406
5460
  explode(point, energy, radius, source, blast) {
5407
5461
  blastProbe.partsTested = 0;
5408
5462
  blastProbe.partsNear = 0;
@@ -5427,7 +5481,7 @@ var createDestruction = (options = {}) => {
5427
5481
  },
5428
5482
  shoot(origin, direction, energy, caliber, source, round) {
5429
5483
  const extras = typeof round === "number" ? { piercing: round } : round ?? {};
5430
- return withCollapses(run(() => {
5484
+ return withCollapses(run(withBlow("ballistic", () => {
5431
5485
  const results = [];
5432
5486
  const d = vec.normalize(direction);
5433
5487
  const ignore = /* @__PURE__ */ new Set();
@@ -5438,10 +5492,12 @@ var createDestruction = (options = {}) => {
5438
5492
  if (!rh) break;
5439
5493
  const im = impls.get(rh.object);
5440
5494
  if (im) {
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 } : {} });
5495
+ const scaled = extras.penetration && E < energy ? { ...extras, penetration: Object.fromEntries(Object.entries(extras.penetration).map(([k, mm]) => [k, mm * (E / energy)])) } : extras;
5496
+ const r = implHit(im, { type: "ballistic", point: rh.point, part: rh.part, normal: rh.normal, direction: d, energy: E, caliber, ...scaled, ...source !== void 0 ? { source } : {} });
5442
5497
  r.part = rh.part;
5443
5498
  r.point = rh.point;
5444
- r.exitEnergy = r.penetrated ? E * 0.5 : 0;
5499
+ const left = r.events.find((e) => e.type === "hole" && e.energyLeft !== void 0);
5500
+ r.exitEnergy = r.penetrated ? left?.energyLeft ?? E * 0.5 : 0;
5445
5501
  results.push(r);
5446
5502
  ignore.add(`${im.impl.id}\0${rh.part}`);
5447
5503
  if (!r.penetrated) break;
@@ -5460,7 +5516,7 @@ var createDestruction = (options = {}) => {
5460
5516
  E = out.exitEnergy;
5461
5517
  }
5462
5518
  return results;
5463
- }));
5519
+ })));
5464
5520
  },
5465
5521
  disassemble(objectId, jointId, tool, dt) {
5466
5522
  const im = impls.get(objectId);