@adatechnology/game-floorplan-structure 2.1.3 → 2.1.5
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 +161 -14
- package/dist/index.global.js.map +1 -1
- package/package.json +6 -6
package/dist/index.global.js
CHANGED
|
@@ -2541,6 +2541,26 @@ var GameFloorplanStructure = (() => {
|
|
|
2541
2541
|
|
|
2542
2542
|
// ../game-contracts/dist/index.js
|
|
2543
2543
|
var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
|
|
2544
|
+
var NEAREST = 0.3;
|
|
2545
|
+
function sideOnImpulse(tnt, distance2) {
|
|
2546
|
+
if (!(tnt > 0)) return 0;
|
|
2547
|
+
const w3 = Math.cbrt(tnt);
|
|
2548
|
+
const z = Math.max(distance2, NEAREST) / w3;
|
|
2549
|
+
const scaled = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
|
|
2550
|
+
return scaled * w3 * 100;
|
|
2551
|
+
}
|
|
2552
|
+
var ATMOSPHERE = 101325;
|
|
2553
|
+
function sideOnOverpressure(tnt, distance2) {
|
|
2554
|
+
if (!(tnt > 0)) return 0;
|
|
2555
|
+
const z = Math.max(distance2, NEAREST) / Math.cbrt(tnt);
|
|
2556
|
+
const ratio = 808 * (1 + (z / 4.5) ** 2) / (Math.sqrt(1 + (z / 0.048) ** 2) * Math.sqrt(1 + (z / 0.32) ** 2) * Math.sqrt(1 + (z / 1.35) ** 2));
|
|
2557
|
+
return ratio * ATMOSPHERE;
|
|
2558
|
+
}
|
|
2559
|
+
function bodyImpulse(tnt, distance2) {
|
|
2560
|
+
if (!(tnt > 0)) return 0;
|
|
2561
|
+
const z = Math.max(distance2, NEAREST) / Math.cbrt(tnt);
|
|
2562
|
+
return sideOnImpulse(tnt, distance2) * (2 + 4 / (1 + z * z));
|
|
2563
|
+
}
|
|
2544
2564
|
var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
|
|
2545
2565
|
var DEFAULT_IGNITION_RULES = {
|
|
2546
2566
|
fillCurve: [
|
|
@@ -5545,9 +5565,15 @@ var GameFloorplanStructure = (() => {
|
|
|
5545
5565
|
var BREACH_AREA = 0.25;
|
|
5546
5566
|
var BREACH_BLAST_REACH = 0.12;
|
|
5547
5567
|
var MEMBER_CUT_REACH = 0.5;
|
|
5568
|
+
var FAR_MEMBER_HP_FLOOR = 0.25;
|
|
5548
5569
|
var BLAST_REFERENCE_RESISTANCE = 200 * 1900 * 0.13;
|
|
5549
5570
|
var BLAST_EDGE_RAGGED = 0.3;
|
|
5550
5571
|
var BLAST_EDGE_LOOSE = 1.35;
|
|
5572
|
+
var PANEL_PRESSURE = 7e4;
|
|
5573
|
+
var PANEL_IMPULSE = 150;
|
|
5574
|
+
var PANEL_PI = 6e6;
|
|
5575
|
+
var PANEL_POINTS = [[0, 0], [-0.3, 0], [0.3, 0], [0, -0.3], [0, 0.3]];
|
|
5576
|
+
var PANEL_POINTS_LOADED = 4;
|
|
5551
5577
|
var BLAST_EDGE_WEAR = 0.6;
|
|
5552
5578
|
var RESIDUAL_CAPACITY = 0.15;
|
|
5553
5579
|
var SEVER_BAND = 0.1;
|
|
@@ -5572,23 +5598,42 @@ var GameFloorplanStructure = (() => {
|
|
|
5572
5598
|
const v = table[mat.penetrationClass ?? mat.id] ?? table[mat.id];
|
|
5573
5599
|
return v === void 0 ? void 0 : v * (mat.penetrationScale ?? 1);
|
|
5574
5600
|
};
|
|
5575
|
-
var
|
|
5601
|
+
var BURIED_BLAST_REACH = 0.5;
|
|
5602
|
+
var GIVE_AT_CUT_HP = 0.5;
|
|
5603
|
+
var capacityScale = (p, borne, through) => {
|
|
5576
5604
|
const residual = p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY;
|
|
5577
5605
|
if (p.st.stripped) return residual;
|
|
5578
|
-
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1,
|
|
5606
|
+
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, sectionKept(p, residual, borne, through));
|
|
5579
5607
|
return Math.max(p.spec.reinforcement ? residual : 0.05, kept);
|
|
5580
5608
|
};
|
|
5581
|
-
var
|
|
5609
|
+
var sectionKept = (p, residual, borne, through) => {
|
|
5610
|
+
let kept = 1;
|
|
5611
|
+
forEachSection(p, borne, (c, along, gone) => {
|
|
5612
|
+
const share = through?.(c.center, along) ?? 1;
|
|
5613
|
+
if (share <= 0) return;
|
|
5614
|
+
kept = Math.min(kept, Math.max(p.spec.reinforcement ? residual : 0, 1 - gone) / share);
|
|
5615
|
+
});
|
|
5616
|
+
return kept;
|
|
5617
|
+
};
|
|
5618
|
+
var sectionLoss = (p, borne) => {
|
|
5619
|
+
let worst = 0;
|
|
5620
|
+
forEachSection(p, borne, (_c, _along, gone) => {
|
|
5621
|
+
worst = Math.max(worst, gone);
|
|
5622
|
+
});
|
|
5623
|
+
return Math.min(1, worst);
|
|
5624
|
+
};
|
|
5625
|
+
var forEachSection = (p, borne, visit) => {
|
|
5582
5626
|
const cells = p.st.chipped;
|
|
5583
|
-
if (!cells?.length) return
|
|
5627
|
+
if (!cells?.length) return;
|
|
5584
5628
|
const [u, v] = planeAxes(p.thin);
|
|
5585
5629
|
const role = p.spec.structure?.role;
|
|
5586
5630
|
const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
|
|
5587
5631
|
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;
|
|
5588
5632
|
const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
|
|
5589
5633
|
const across = along === u ? v : u;
|
|
5590
|
-
|
|
5634
|
+
const lying = along !== upright || upright < 0;
|
|
5591
5635
|
for (const c of cells) {
|
|
5636
|
+
if (lying && borne?.(c.center, along)) continue;
|
|
5592
5637
|
const spans = [];
|
|
5593
5638
|
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]);
|
|
5594
5639
|
spans.sort((a, b) => a[0] - b[0]);
|
|
@@ -5598,9 +5643,8 @@ var GameFloorplanStructure = (() => {
|
|
|
5598
5643
|
gone += b - Math.max(a, end);
|
|
5599
5644
|
end = b;
|
|
5600
5645
|
}
|
|
5601
|
-
|
|
5646
|
+
visit(c, along, Math.min(1, gone / Math.max(p.dims[across], 1e-6)));
|
|
5602
5647
|
}
|
|
5603
|
-
return Math.min(1, worst);
|
|
5604
5648
|
};
|
|
5605
5649
|
var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
|
|
5606
5650
|
var clone = (v) => structuredClone(v);
|
|
@@ -5911,6 +5955,26 @@ var GameFloorplanStructure = (() => {
|
|
|
5911
5955
|
byTouching.set(support, { version: poseVersion, box: box2 });
|
|
5912
5956
|
return box2;
|
|
5913
5957
|
};
|
|
5958
|
+
const throughOf = (p) => {
|
|
5959
|
+
const load = p.st.load ?? 0;
|
|
5960
|
+
if (load <= 0) return void 0;
|
|
5961
|
+
const above = Math.max(0, load - p.st.mass);
|
|
5962
|
+
const up = rotateVec(p.q, [0, 1, 0]);
|
|
5963
|
+
return (local, along) => {
|
|
5964
|
+
const axis = [0, 0, 0];
|
|
5965
|
+
axis[along] = 1;
|
|
5966
|
+
const sign = Math.sign(rotateVec(p.q, axis)[1]);
|
|
5967
|
+
if (Math.abs(up[1]) < 0.7 && Math.abs(rotateVec(p.q, axis)[1]) < 0.7) return 1;
|
|
5968
|
+
const half = p.dims[along] / 2;
|
|
5969
|
+
const share = clamp22((half - sign * local[along]) / Math.max(p.dims[along], 1e-6), 0, 1);
|
|
5970
|
+
return (above + p.st.mass * share) / load;
|
|
5971
|
+
};
|
|
5972
|
+
};
|
|
5973
|
+
const borneOn = (p, supports) => {
|
|
5974
|
+
if (supports.length === 0) return void 0;
|
|
5975
|
+
const boxes = supports.map((support) => contactBox(p, support));
|
|
5976
|
+
return (local, along) => boxes.some(([lo, hi]) => local[along] >= lo[along] - SUPPORT_TOLERANCE && local[along] <= hi[along] + SUPPORT_TOLERANCE);
|
|
5977
|
+
};
|
|
5914
5978
|
const measureContact = (p, support) => {
|
|
5915
5979
|
const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
|
|
5916
5980
|
const lo = [0, 0, 0], hi = [0, 0, 0];
|
|
@@ -6118,7 +6182,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6118
6182
|
o.unsup[i] = o.anyAnchor && !isLost(p) && !p.orphan;
|
|
6119
6183
|
continue;
|
|
6120
6184
|
}
|
|
6121
|
-
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p));
|
|
6185
|
+
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p, borneOn(p, (lowerOf.get(i) ?? []).map((k) => parts[k])), throughOf(p)));
|
|
6122
6186
|
if (p.bend) {
|
|
6123
6187
|
p.bendLoad = p.st.mass + bending[i];
|
|
6124
6188
|
const bent = restFlexure(o, p, lowerOf.get(i) ?? []);
|
|
@@ -7103,7 +7167,7 @@ var GameFloorplanStructure = (() => {
|
|
|
7103
7167
|
return BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3) * clamp22(Math.cbrt(BLAST_REFERENCE_RESISTANCE / resistance), 0.3, 2);
|
|
7104
7168
|
};
|
|
7105
7169
|
const blastUnits = (o, p, wp, energy, dist, src) => {
|
|
7106
|
-
var _a
|
|
7170
|
+
var _a;
|
|
7107
7171
|
if (!p.staged || p.st.stripped || isLost(p) || chipEnergy <= 0) return false;
|
|
7108
7172
|
const reach = blastReachOf(p, energy);
|
|
7109
7173
|
if (dist >= reach) return false;
|
|
@@ -7133,6 +7197,62 @@ var GameFloorplanStructure = (() => {
|
|
|
7133
7197
|
}
|
|
7134
7198
|
}
|
|
7135
7199
|
if (out.length === 0) return false;
|
|
7200
|
+
return knockOutUnits(o, p, wp, energy, out, src);
|
|
7201
|
+
};
|
|
7202
|
+
const blastPanel = (o, p, point, energy, src) => {
|
|
7203
|
+
var _a;
|
|
7204
|
+
if (!p.staged || p.st.stripped || isLost(p) || !p.spec.units || p.spec.units.mortar === p.spec.material || p.spec.reinforcement) return false;
|
|
7205
|
+
const [u, v] = planeAxes(p.thin);
|
|
7206
|
+
const lp = toLocal(p.pos, p.q, objLocal(o, point));
|
|
7207
|
+
const half = p.dims[u] / 2;
|
|
7208
|
+
const posts = [];
|
|
7209
|
+
for (const m of o.parts) {
|
|
7210
|
+
if (m === p || !m.spec.reinforcement || isLost(m) || m.spec.shape.kind !== "box") continue;
|
|
7211
|
+
const mp = toLocal(p.pos, p.q, m.pos);
|
|
7212
|
+
if (Math.abs(mp[p.thin]) > p.dims[p.thin] + 0.15 || Math.abs(mp[u]) > half + 0.15 || m.dims[v] < p.dims[v] * 0.5) continue;
|
|
7213
|
+
posts.push(mp[u]);
|
|
7214
|
+
}
|
|
7215
|
+
let from = -half, to = half;
|
|
7216
|
+
for (const x of posts) {
|
|
7217
|
+
if (x <= lp[u] && x > from) from = x;
|
|
7218
|
+
if (x >= lp[u] && x < to) to = x;
|
|
7219
|
+
}
|
|
7220
|
+
if (to - from < 0.2) return false;
|
|
7221
|
+
const tnt = energy * DEFAULT_BLAST_IMPULSE.tntPerJoule;
|
|
7222
|
+
const centre2 = objLocal(o, point);
|
|
7223
|
+
const span = to - from, height = p.dims[v];
|
|
7224
|
+
let loaded = 0;
|
|
7225
|
+
for (const [fu, fv] of PANEL_POINTS) {
|
|
7226
|
+
const at2 = [0, 0, 0];
|
|
7227
|
+
at2[u] = (from + to) / 2 + fu * span;
|
|
7228
|
+
at2[v] = fv * height;
|
|
7229
|
+
at2[p.thin] = Math.sign(lp[p.thin]) * p.dims[p.thin] / 2;
|
|
7230
|
+
const r = vec.distance(toWorld(p.pos, p.q, at2), centre2);
|
|
7231
|
+
const side = sideOnOverpressure(tnt, r);
|
|
7232
|
+
const reflected = 2 * side + 6 * side * side / (side + 7 * 101325);
|
|
7233
|
+
const impulse = bodyImpulse(tnt, r);
|
|
7234
|
+
if (reflected > PANEL_PRESSURE && impulse > PANEL_IMPULSE && (reflected - PANEL_PRESSURE) * (impulse - PANEL_IMPULSE) >= PANEL_PI) loaded++;
|
|
7235
|
+
}
|
|
7236
|
+
if (loaded < PANEL_POINTS_LOADED) return false;
|
|
7237
|
+
const grid = gridOf(p);
|
|
7238
|
+
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
7239
|
+
const out = [];
|
|
7240
|
+
for (let i = 0; i < grid.length; i++) {
|
|
7241
|
+
const cell = grid[i];
|
|
7242
|
+
if (worn[i] === -1) continue;
|
|
7243
|
+
if (cell.center[u] - cell.size[u] / 2 >= from - 1e-6 && cell.center[u] + cell.size[u] / 2 <= to + 1e-6) out.push(i);
|
|
7244
|
+
}
|
|
7245
|
+
if (out.length === 0) return false;
|
|
7246
|
+
for (const i of out) worn[i] = -1;
|
|
7247
|
+
return knockOutUnits(o, p, point, energy, out, src);
|
|
7248
|
+
};
|
|
7249
|
+
const knockOutUnits = (o, p, wp, energy, out, src) => {
|
|
7250
|
+
var _a, _b;
|
|
7251
|
+
const [u, v] = planeAxes(p.thin);
|
|
7252
|
+
const op = p.st.opening ? toLocal(p.pos, p.q, p.st.opening.center) : null;
|
|
7253
|
+
const grid = gridOf(p);
|
|
7254
|
+
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
7255
|
+
for (const i of out) worn[i] = -1;
|
|
7136
7256
|
const loose = unsupportedCells(grid, p.thin, p.dims, (i) => worn[i] !== -1 && !(op && p.st.opening && Math.hypot(grid[i].center[u] - op[u], grid[i].center[v] - op[v]) <= p.st.opening.radius));
|
|
7137
7257
|
for (const i of loose) worn[i] = -1;
|
|
7138
7258
|
const blown = out.map((i) => grid[i]), fallen = loose.map((i) => grid[i]);
|
|
@@ -7208,6 +7328,27 @@ var GameFloorplanStructure = (() => {
|
|
|
7208
7328
|
debris(o, p, p.mat.breakDebris, center, [0, -1, 0], 6, 1, src);
|
|
7209
7329
|
return loose.length;
|
|
7210
7330
|
};
|
|
7331
|
+
const giveAtCut = (o, p, src) => {
|
|
7332
|
+
if (!p.spec.reinforcement || !p.spec.units || !p.st.chipped?.length || sectionLoss(p) <= 0) return false;
|
|
7333
|
+
const opened = [];
|
|
7334
|
+
for (const j of o.byPart.get(p.spec.id) ?? []) {
|
|
7335
|
+
if (j.st.open) continue;
|
|
7336
|
+
const onIt = j.bears === "a_on_b" && j.spec.b === p.spec.id || j.bears === "b_on_a" && j.spec.a === p.spec.id;
|
|
7337
|
+
if (!onIt) continue;
|
|
7338
|
+
j.st.open = true;
|
|
7339
|
+
j.st.openedBy = "break";
|
|
7340
|
+
opened.push(j);
|
|
7341
|
+
}
|
|
7342
|
+
if (opened.length === 0) return false;
|
|
7343
|
+
p.st.hp = Math.max(p.st.hp, p.st.maxHp * GIVE_AT_CUT_HP);
|
|
7344
|
+
markDamaged(p);
|
|
7345
|
+
solveStructure(o);
|
|
7346
|
+
recomputeGroups(o);
|
|
7347
|
+
detachEvents(o, opened, "break", src);
|
|
7348
|
+
exposeRebar(o, p, src);
|
|
7349
|
+
collapseCheck(o, src);
|
|
7350
|
+
return true;
|
|
7351
|
+
};
|
|
7211
7352
|
const stripPart = (o, p, reinforcement, src) => {
|
|
7212
7353
|
const bars = rebarBars(p.dims, p.thin, reinforcement.spacing);
|
|
7213
7354
|
p.st.stripped = true;
|
|
@@ -7265,6 +7406,7 @@ var GameFloorplanStructure = (() => {
|
|
|
7265
7406
|
hingeDrop(o, p, src);
|
|
7266
7407
|
return;
|
|
7267
7408
|
}
|
|
7409
|
+
if (!force && giveAtCut(o, p, src)) return;
|
|
7268
7410
|
const ex = p.spec.explodes;
|
|
7269
7411
|
const style = force ?? (p.snap ? "snap" : p.mat.fracture === "none" ? "snap" : p.mat.fracture);
|
|
7270
7412
|
const { c, q } = partXf(o, p);
|
|
@@ -7593,12 +7735,15 @@ var GameFloorplanStructure = (() => {
|
|
|
7593
7735
|
return reach;
|
|
7594
7736
|
}
|
|
7595
7737
|
if (Ein > 20 && p.layers.length > 0) spallOuter(o, p, wp, faceOf(o, p, wn), wn, clamp22(0.05 + Math.sqrt(Ein) * 2e-3, 0.05, 0.4), src);
|
|
7596
|
-
const
|
|
7738
|
+
const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
|
|
7739
|
+
const farMember = Boolean(p.spec.reinforcement && p.spec.units) && dist > MEMBER_CUT_REACH * breachReach;
|
|
7740
|
+
const dealt = farMember ? applyDamage(o, p, Math.min(amount, Math.max(0, p.st.hp - p.st.maxHp * FAR_MEMBER_HP_FLOOR)), "explosive", null, null, Ein * 0.3, 40, src) : applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
|
|
7597
7741
|
res.damage += dealt;
|
|
7598
7742
|
if (p.bend && flexure.enabled) bendByBlast(o, p, point, energy, radius, reach, src);
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7743
|
+
if (p.spec.units && p.spec.units.mortar !== p.spec.material) {
|
|
7744
|
+
blastPanel(o, p, point, energy, src);
|
|
7745
|
+
if (!isLost(p)) blastUnits(o, p, wp, energy, dist, src);
|
|
7746
|
+
} else if (farMember) blastUnits(o, p, wp, energy, dist, src);
|
|
7602
7747
|
else if (dist <= breachReach) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
|
|
7603
7748
|
return reach;
|
|
7604
7749
|
};
|
|
@@ -7611,7 +7756,9 @@ var GameFloorplanStructure = (() => {
|
|
|
7611
7756
|
const dx = local[0] - p.pos[0];
|
|
7612
7757
|
const dy = local[1] - p.pos[1];
|
|
7613
7758
|
const dz = local[2] - p.pos[2];
|
|
7614
|
-
if (dx * dx + dy * dy + dz * dz
|
|
7759
|
+
if (dx * dx + dy * dy + dz * dz >= reach * reach) continue;
|
|
7760
|
+
if (p.spec.anchored && p.spec.structure?.role === "foundation" && distToPart(o, p, point) > BURIED_BLAST_REACH) continue;
|
|
7761
|
+
near.push(p);
|
|
7615
7762
|
}
|
|
7616
7763
|
blastProbe.partsTested += o.parts.length;
|
|
7617
7764
|
blastProbe.partsNear += near.length;
|