@adatechnology/game-destruction 0.18.2 → 0.19.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.global.js +71 -9
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +71 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.global.js
CHANGED
|
@@ -3416,23 +3416,42 @@ var GameDestruction = (() => {
|
|
|
3416
3416
|
const v = table[mat.penetrationClass ?? mat.id] ?? table[mat.id];
|
|
3417
3417
|
return v === void 0 ? void 0 : v * (mat.penetrationScale ?? 1);
|
|
3418
3418
|
};
|
|
3419
|
-
var
|
|
3419
|
+
var BURIED_BLAST_REACH = 0.5;
|
|
3420
|
+
var GIVE_AT_CUT_HP = 0.5;
|
|
3421
|
+
var capacityScale = (p, borne, through) => {
|
|
3420
3422
|
const residual = p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY;
|
|
3421
3423
|
if (p.st.stripped) return residual;
|
|
3422
|
-
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1,
|
|
3424
|
+
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, sectionKept(p, residual, borne, through));
|
|
3423
3425
|
return Math.max(p.spec.reinforcement ? residual : 0.05, kept);
|
|
3424
3426
|
};
|
|
3425
|
-
var
|
|
3427
|
+
var sectionKept = (p, residual, borne, through) => {
|
|
3428
|
+
let kept = 1;
|
|
3429
|
+
forEachSection(p, borne, (c, along, gone) => {
|
|
3430
|
+
const share = through?.(c.center, along) ?? 1;
|
|
3431
|
+
if (share <= 0) return;
|
|
3432
|
+
kept = Math.min(kept, Math.max(p.spec.reinforcement ? residual : 0, 1 - gone) / share);
|
|
3433
|
+
});
|
|
3434
|
+
return kept;
|
|
3435
|
+
};
|
|
3436
|
+
var sectionLoss = (p, borne) => {
|
|
3437
|
+
let worst = 0;
|
|
3438
|
+
forEachSection(p, borne, (_c, _along, gone) => {
|
|
3439
|
+
worst = Math.max(worst, gone);
|
|
3440
|
+
});
|
|
3441
|
+
return Math.min(1, worst);
|
|
3442
|
+
};
|
|
3443
|
+
var forEachSection = (p, borne, visit) => {
|
|
3426
3444
|
const cells = p.st.chipped;
|
|
3427
|
-
if (!cells?.length) return
|
|
3445
|
+
if (!cells?.length) return;
|
|
3428
3446
|
const [u, v] = planeAxes(p.thin);
|
|
3429
3447
|
const role = p.spec.structure?.role;
|
|
3430
3448
|
const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
|
|
3431
3449
|
const upright = Math.abs(up[1]) > 0.7 ? v : Math.abs(rotateVec(p.q, [0, 0, 0].map((_, k) => k === u ? 1 : 0))[1]) > 0.7 ? u : -1;
|
|
3432
3450
|
const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
|
|
3433
3451
|
const across = along === u ? v : u;
|
|
3434
|
-
|
|
3452
|
+
const lying = along !== upright || upright < 0;
|
|
3435
3453
|
for (const c of cells) {
|
|
3454
|
+
if (lying && borne?.(c.center, along)) continue;
|
|
3436
3455
|
const spans = [];
|
|
3437
3456
|
for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) spans.push([d.center[across] - d.size[across] / 2, d.center[across] + d.size[across] / 2]);
|
|
3438
3457
|
spans.sort((a, b) => a[0] - b[0]);
|
|
@@ -3442,9 +3461,8 @@ var GameDestruction = (() => {
|
|
|
3442
3461
|
gone += b - Math.max(a, end);
|
|
3443
3462
|
end = b;
|
|
3444
3463
|
}
|
|
3445
|
-
|
|
3464
|
+
visit(c, along, Math.min(1, gone / Math.max(p.dims[across], 1e-6)));
|
|
3446
3465
|
}
|
|
3447
|
-
return Math.min(1, worst);
|
|
3448
3466
|
};
|
|
3449
3467
|
var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
|
|
3450
3468
|
var clone = (v) => structuredClone(v);
|
|
@@ -3755,6 +3773,26 @@ var GameDestruction = (() => {
|
|
|
3755
3773
|
byTouching.set(support, { version: poseVersion, box });
|
|
3756
3774
|
return box;
|
|
3757
3775
|
};
|
|
3776
|
+
const throughOf = (p) => {
|
|
3777
|
+
const load = p.st.load ?? 0;
|
|
3778
|
+
if (load <= 0) return void 0;
|
|
3779
|
+
const above = Math.max(0, load - p.st.mass);
|
|
3780
|
+
const up = rotateVec(p.q, [0, 1, 0]);
|
|
3781
|
+
return (local, along) => {
|
|
3782
|
+
const axis = [0, 0, 0];
|
|
3783
|
+
axis[along] = 1;
|
|
3784
|
+
const sign = Math.sign(rotateVec(p.q, axis)[1]);
|
|
3785
|
+
if (Math.abs(up[1]) < 0.7 && Math.abs(rotateVec(p.q, axis)[1]) < 0.7) return 1;
|
|
3786
|
+
const half = p.dims[along] / 2;
|
|
3787
|
+
const share = clamp2((half - sign * local[along]) / Math.max(p.dims[along], 1e-6), 0, 1);
|
|
3788
|
+
return (above + p.st.mass * share) / load;
|
|
3789
|
+
};
|
|
3790
|
+
};
|
|
3791
|
+
const borneOn = (p, supports) => {
|
|
3792
|
+
if (supports.length === 0) return void 0;
|
|
3793
|
+
const boxes = supports.map((support) => contactBox(p, support));
|
|
3794
|
+
return (local, along) => boxes.some(([lo, hi]) => local[along] >= lo[along] - SUPPORT_TOLERANCE && local[along] <= hi[along] + SUPPORT_TOLERANCE);
|
|
3795
|
+
};
|
|
3758
3796
|
const measureContact = (p, support) => {
|
|
3759
3797
|
const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
|
|
3760
3798
|
const lo = [0, 0, 0], hi = [0, 0, 0];
|
|
@@ -3962,7 +4000,7 @@ var GameDestruction = (() => {
|
|
|
3962
4000
|
o.unsup[i] = o.anyAnchor && !isLost(p) && !p.orphan;
|
|
3963
4001
|
continue;
|
|
3964
4002
|
}
|
|
3965
|
-
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p));
|
|
4003
|
+
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p, borneOn(p, (lowerOf.get(i) ?? []).map((k) => parts[k])), throughOf(p)));
|
|
3966
4004
|
if (p.bend) {
|
|
3967
4005
|
p.bendLoad = p.st.mass + bending[i];
|
|
3968
4006
|
const bent = restFlexure(o, p, lowerOf.get(i) ?? []);
|
|
@@ -5052,6 +5090,27 @@ var GameDestruction = (() => {
|
|
|
5052
5090
|
debris(o, p, p.mat.breakDebris, center, [0, -1, 0], 6, 1, src);
|
|
5053
5091
|
return loose.length;
|
|
5054
5092
|
};
|
|
5093
|
+
const giveAtCut = (o, p, src) => {
|
|
5094
|
+
if (!p.spec.reinforcement || !p.spec.units || !p.st.chipped?.length || sectionLoss(p) <= 0) return false;
|
|
5095
|
+
const opened = [];
|
|
5096
|
+
for (const j of o.byPart.get(p.spec.id) ?? []) {
|
|
5097
|
+
if (j.st.open) continue;
|
|
5098
|
+
const onIt = j.bears === "a_on_b" && j.spec.b === p.spec.id || j.bears === "b_on_a" && j.spec.a === p.spec.id;
|
|
5099
|
+
if (!onIt) continue;
|
|
5100
|
+
j.st.open = true;
|
|
5101
|
+
j.st.openedBy = "break";
|
|
5102
|
+
opened.push(j);
|
|
5103
|
+
}
|
|
5104
|
+
if (opened.length === 0) return false;
|
|
5105
|
+
p.st.hp = Math.max(p.st.hp, p.st.maxHp * GIVE_AT_CUT_HP);
|
|
5106
|
+
markDamaged(p);
|
|
5107
|
+
solveStructure(o);
|
|
5108
|
+
recomputeGroups(o);
|
|
5109
|
+
detachEvents(o, opened, "break", src);
|
|
5110
|
+
exposeRebar(o, p, src);
|
|
5111
|
+
collapseCheck(o, src);
|
|
5112
|
+
return true;
|
|
5113
|
+
};
|
|
5055
5114
|
const stripPart = (o, p, reinforcement, src) => {
|
|
5056
5115
|
const bars = rebarBars(p.dims, p.thin, reinforcement.spacing);
|
|
5057
5116
|
p.st.stripped = true;
|
|
@@ -5109,6 +5168,7 @@ var GameDestruction = (() => {
|
|
|
5109
5168
|
hingeDrop(o, p, src);
|
|
5110
5169
|
return;
|
|
5111
5170
|
}
|
|
5171
|
+
if (!force && giveAtCut(o, p, src)) return;
|
|
5112
5172
|
const ex = p.spec.explodes;
|
|
5113
5173
|
const style = force ?? (p.snap ? "snap" : p.mat.fracture === "none" ? "snap" : p.mat.fracture);
|
|
5114
5174
|
const { c, q } = partXf(o, p);
|
|
@@ -5455,7 +5515,9 @@ var GameDestruction = (() => {
|
|
|
5455
5515
|
const dx = local[0] - p.pos[0];
|
|
5456
5516
|
const dy = local[1] - p.pos[1];
|
|
5457
5517
|
const dz = local[2] - p.pos[2];
|
|
5458
|
-
if (dx * dx + dy * dy + dz * dz
|
|
5518
|
+
if (dx * dx + dy * dy + dz * dz >= reach * reach) continue;
|
|
5519
|
+
if (p.spec.anchored && p.spec.structure?.role === "foundation" && distToPart(o, p, point) > BURIED_BLAST_REACH) continue;
|
|
5520
|
+
near.push(p);
|
|
5459
5521
|
}
|
|
5460
5522
|
blastProbe.partsTested += o.parts.length;
|
|
5461
5523
|
blastProbe.partsNear += near.length;
|