@adatechnology/game-destruction 0.14.0 → 0.15.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.d.ts +11 -1
- package/dist/index.global.js +62 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +62 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Vec3, Quat, MaterialId, FractureStyle, DamageType, DebrisKind, DestructionEvent, StructureRole, SoilProfile, WindExposure, IgnitionRules, BlastOptions, DestructibleSpec, ObjectState, DestructibleImpl, Hit, HitResult, RayHit, BallisticExtras, ToolKind, JointState, PartState, DestructionEventType, ConfinementOptions, FragmentHitOptions,
|
|
1
|
+
import { Vec3, Quat, MaterialId, FractureStyle, DamageType, DebrisKind, DestructionEvent, StructureRole, SoilProfile, WindExposure, IgnitionRules, BlastOptions, DestructibleSpec, ObjectState, DestructibleImpl, Hit, HitResult, ShelterOptions, RayHit, BallisticExtras, ToolKind, JointState, PartState, DestructionEventType, ConfinementOptions, FragmentHitOptions, ExplosionChain, PartSpec, JointKind, JointSpec, PartShape, SurfaceLayer, PartUnits, Reinforcement, PartBreach, DeepPartial, PileSpec, PartStatus, CostOptions } from '@adatechnology/game-contracts';
|
|
2
2
|
export { BallisticExtras, BlastOptions, BlastReport, ChainDelay, ConfinementOptions, Crack, DamageStage, DamageType, DebrisKind, Dent, DestructibleImpl, DestructibleSpec, DestructionEvent, DestructionEventType, ExplosionChain, FluidKind, FractureStyle, Fragment, FragmentHitOptions, FragmentMark, Hit, HitIgnition, HitResult, Hole, IMPACT_CONTRACT, ImpactContract, JointKind, JointSpec, JointState, MaterialId, ObjectState, PartBreach, PartShape, PartSpec, PartState, PartStatus, PartUnits, PileSpec, Quat, RayHit, Reinforcement, ShelterOptions, SoilLayer, SoilProfile, SoilState, StructureRole, SurfaceLayer, TensionRebar, ToolKind, TunedMassDamper, Vec3, WindExposure, WindState, checkHit } from '@adatechnology/game-contracts';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -457,6 +457,16 @@ interface DestructionWorld {
|
|
|
457
457
|
* that target, and a `blast` event sums it up.
|
|
458
458
|
*/
|
|
459
459
|
explode(point: Vec3, energy: number, radius: number, source?: string, options?: BlastOptions): HitResult[];
|
|
460
|
+
/**
|
|
461
|
+
* The share (0..1) of a blast at `point` that reaches `target` through what stands between them: every part the straight line crosses lets
|
|
462
|
+
* `exp(-r / k)` through (`ShelterOptions`; `r` the hit points of the slab per square metre), a broken part or a hole lets it all by. Always on, whatever
|
|
463
|
+
* `BlastOptions.shelter` says: the shove of a blast (people, the player, loose things) is blocked by cover in every room. `ignore` lists objects that never
|
|
464
|
+
* block (the explosive itself, the body being shoved).
|
|
465
|
+
*/
|
|
466
|
+
blastReach(point: Vec3, target: Vec3, options?: {
|
|
467
|
+
readonly ignore?: readonly string[];
|
|
468
|
+
readonly shelter?: ShelterOptions;
|
|
469
|
+
}): number;
|
|
460
470
|
/** Cost of the last `explode`: parts in range of the broad phase (`partsTested`) and those whose bounding sphere the blast reached (`partsNear`). */
|
|
461
471
|
blastProbe(): {
|
|
462
472
|
partsTested: number;
|
package/dist/index.global.js
CHANGED
|
@@ -3210,7 +3210,13 @@ var GameDestruction = (() => {
|
|
|
3210
3210
|
const typed = listeners.get(e.type);
|
|
3211
3211
|
if (typed) for (const fn of [...typed]) fn(e);
|
|
3212
3212
|
};
|
|
3213
|
-
|
|
3213
|
+
let blow;
|
|
3214
|
+
const base = (o, source) => ({
|
|
3215
|
+
object: o.id,
|
|
3216
|
+
time,
|
|
3217
|
+
...source === void 0 ? {} : { source },
|
|
3218
|
+
...blow === void 0 ? {} : { blow }
|
|
3219
|
+
});
|
|
3214
3220
|
const pendingCollapse = /* @__PURE__ */ new Map();
|
|
3215
3221
|
let runDepth = 0;
|
|
3216
3222
|
const drainBlasts = () => {
|
|
@@ -5355,7 +5361,17 @@ var GameDestruction = (() => {
|
|
|
5355
5361
|
res.events = cur.slice(start);
|
|
5356
5362
|
return res;
|
|
5357
5363
|
};
|
|
5358
|
-
const
|
|
5364
|
+
const withBlow = (type, fn) => () => {
|
|
5365
|
+
const outer = blow;
|
|
5366
|
+
blow = type;
|
|
5367
|
+
try {
|
|
5368
|
+
return fn();
|
|
5369
|
+
} finally {
|
|
5370
|
+
blow = outer;
|
|
5371
|
+
}
|
|
5372
|
+
};
|
|
5373
|
+
const doHit = (o, hit, only) => withBlow(hit.type, () => resolveHit(o, hit, only))();
|
|
5374
|
+
const resolveHit = (o, hit, only) => {
|
|
5359
5375
|
let point = hit.point;
|
|
5360
5376
|
let dir = hit.direction;
|
|
5361
5377
|
if (hit.space === "local") {
|
|
@@ -5794,6 +5810,44 @@ var GameDestruction = (() => {
|
|
|
5794
5810
|
blastProbe() {
|
|
5795
5811
|
return { ...blastProbe };
|
|
5796
5812
|
},
|
|
5813
|
+
blastReach(point, target, options2 = {}) {
|
|
5814
|
+
const L = vec.distance(point, target);
|
|
5815
|
+
if (L < 1e-4) return 1;
|
|
5816
|
+
const shelter = { ...SHELTER_DEFAULTS, ...options2.shelter };
|
|
5817
|
+
const ignore = new Set(options2.ignore ?? []);
|
|
5818
|
+
const d = vec.scale(vec.sub(target, point), 1 / L);
|
|
5819
|
+
let t = 1;
|
|
5820
|
+
for (const o of objects.values()) {
|
|
5821
|
+
if (ignore.has(o.id) || raySphereMiss(point, d, toWorld(o.st.position, o.st.rotation, o.bc), o.br, L)) continue;
|
|
5822
|
+
for (const p of o.parts) {
|
|
5823
|
+
if (isLost(p) || p.st.stripped) continue;
|
|
5824
|
+
const r = rayPart(o, p, point, d);
|
|
5825
|
+
if (!r) continue;
|
|
5826
|
+
const t0 = Math.max(r.t0, 0);
|
|
5827
|
+
const path = Math.min(r.t1, L) - t0;
|
|
5828
|
+
if (path < shelter.minPath) continue;
|
|
5829
|
+
if (p.st.opening && insideOpening(o, p, toLocal(o.st.position, o.st.rotation, vec.madd(point, d, t0 + path / 2)))) continue;
|
|
5830
|
+
t *= Math.exp(-(p.mat.hpPerKg * p.mat.density * path * (p.mat.damageScale?.shelter ?? 1)) / shelter.k);
|
|
5831
|
+
if (t < 1e-4) return 0;
|
|
5832
|
+
}
|
|
5833
|
+
}
|
|
5834
|
+
for (const im of impls.values()) {
|
|
5835
|
+
if (ignore.has(im.impl.id)) continue;
|
|
5836
|
+
for (const ps of im.impl.describe().parts) {
|
|
5837
|
+
const mat = materials.get(ps.material);
|
|
5838
|
+
if (!mat) continue;
|
|
5839
|
+
const ov = im.poses.get(ps.id);
|
|
5840
|
+
const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...ps.rotation ?? [0, 0, 0]), point, d, ov?.pos);
|
|
5841
|
+
if (!r || r.t1 < 0 || r.t0 > L) continue;
|
|
5842
|
+
let path = Math.min(r.t1, L) - Math.max(r.t0, 0);
|
|
5843
|
+
if (ps.thickness !== void 0 && ps.thickness > 0) path = Math.min(path, 2 * ps.thickness);
|
|
5844
|
+
else if (path < shelter.minPath) continue;
|
|
5845
|
+
t *= Math.exp(-(mat.hpPerKg * mat.density * path * (mat.damageScale?.shelter ?? 1)) / shelter.k);
|
|
5846
|
+
if (t < 1e-4) return 0;
|
|
5847
|
+
}
|
|
5848
|
+
}
|
|
5849
|
+
return t;
|
|
5850
|
+
},
|
|
5797
5851
|
explode(point, energy, radius, source, blast) {
|
|
5798
5852
|
blastProbe.partsTested = 0;
|
|
5799
5853
|
blastProbe.partsNear = 0;
|
|
@@ -5818,7 +5872,7 @@ var GameDestruction = (() => {
|
|
|
5818
5872
|
},
|
|
5819
5873
|
shoot(origin, direction, energy, caliber, source, round) {
|
|
5820
5874
|
const extras = typeof round === "number" ? { piercing: round } : round ?? {};
|
|
5821
|
-
return withCollapses(run(() => {
|
|
5875
|
+
return withCollapses(run(withBlow("ballistic", () => {
|
|
5822
5876
|
const results = [];
|
|
5823
5877
|
const d = vec.normalize(direction);
|
|
5824
5878
|
const ignore = /* @__PURE__ */ new Set();
|
|
@@ -5829,10 +5883,12 @@ var GameDestruction = (() => {
|
|
|
5829
5883
|
if (!rh) break;
|
|
5830
5884
|
const im = impls.get(rh.object);
|
|
5831
5885
|
if (im) {
|
|
5832
|
-
const
|
|
5886
|
+
const scaled = extras.penetration && E < energy ? { ...extras, penetration: Object.fromEntries(Object.entries(extras.penetration).map(([k, mm]) => [k, mm * (E / energy)])) } : extras;
|
|
5887
|
+
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 } : {} });
|
|
5833
5888
|
r.part = rh.part;
|
|
5834
5889
|
r.point = rh.point;
|
|
5835
|
-
|
|
5890
|
+
const left = r.events.find((e) => e.type === "hole" && e.energyLeft !== void 0);
|
|
5891
|
+
r.exitEnergy = r.penetrated ? left?.energyLeft ?? E * 0.5 : 0;
|
|
5836
5892
|
results.push(r);
|
|
5837
5893
|
ignore.add(`${im.impl.id}\0${rh.part}`);
|
|
5838
5894
|
if (!r.penetrated) break;
|
|
@@ -5851,7 +5907,7 @@ var GameDestruction = (() => {
|
|
|
5851
5907
|
E = out.exitEnergy;
|
|
5852
5908
|
}
|
|
5853
5909
|
return results;
|
|
5854
|
-
}));
|
|
5910
|
+
})));
|
|
5855
5911
|
},
|
|
5856
5912
|
disassemble(objectId, jointId, tool, dt) {
|
|
5857
5913
|
const im = impls.get(objectId);
|