@adatechnology/game-floorplan-structure 1.3.1 → 1.3.3
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 +160 -18
- package/dist/index.global.js.map +1 -1
- package/package.json +6 -7
package/dist/index.global.js
CHANGED
|
@@ -5047,6 +5047,7 @@ var GameFloorplanStructure = (() => {
|
|
|
5047
5047
|
var FLAMMABLE_FLUIDS = ["gas", "fuel"];
|
|
5048
5048
|
var VENT_DIAMETER = 8e-3;
|
|
5049
5049
|
var FLAME_LIGHTS_LEAK_C = 470;
|
|
5050
|
+
var RESTING_HOLD_COS = Math.cos(Math.PI / 6);
|
|
5050
5051
|
var BREACH_RADIUS = 0.55;
|
|
5051
5052
|
var BREACH_BLAST_FACTOR = 6;
|
|
5052
5053
|
var BREACH_AREA = 0.25;
|
|
@@ -5062,6 +5063,8 @@ var GameFloorplanStructure = (() => {
|
|
|
5062
5063
|
var BREACH_GRID_CAP = 4096;
|
|
5063
5064
|
var CHIP_ENERGY = 200;
|
|
5064
5065
|
var CHIP_SPLASH = 0.5;
|
|
5066
|
+
var CRATER_SPENT = 0.6;
|
|
5067
|
+
var EDGE_REACH = 1.5;
|
|
5065
5068
|
var BAR_BOW = 0.08;
|
|
5066
5069
|
var BULLET_JOINT_SPAN = 0.3;
|
|
5067
5070
|
var CUT_SLICE = 1;
|
|
@@ -5082,12 +5085,22 @@ var GameFloorplanStructure = (() => {
|
|
|
5082
5085
|
const cells = p.st.chipped;
|
|
5083
5086
|
if (!cells?.length) return 0;
|
|
5084
5087
|
const [u, v] = planeAxes(p.thin);
|
|
5085
|
-
const
|
|
5088
|
+
const role = p.spec.structure?.role;
|
|
5089
|
+
const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
|
|
5090
|
+
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;
|
|
5091
|
+
const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
|
|
5086
5092
|
const across = along === u ? v : u;
|
|
5087
5093
|
let worst = 0;
|
|
5088
5094
|
for (const c of cells) {
|
|
5089
|
-
|
|
5090
|
-
for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6)
|
|
5095
|
+
const spans = [];
|
|
5096
|
+
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]);
|
|
5097
|
+
spans.sort((a, b) => a[0] - b[0]);
|
|
5098
|
+
let gone = 0, end = -Infinity;
|
|
5099
|
+
for (const [a, b] of spans) {
|
|
5100
|
+
if (b <= end) continue;
|
|
5101
|
+
gone += b - Math.max(a, end);
|
|
5102
|
+
end = b;
|
|
5103
|
+
}
|
|
5091
5104
|
worst = Math.max(worst, gone / Math.max(p.dims[across], 1e-6));
|
|
5092
5105
|
}
|
|
5093
5106
|
return Math.min(1, worst);
|
|
@@ -5383,7 +5396,18 @@ var GameFloorplanStructure = (() => {
|
|
|
5383
5396
|
if (k < 0 || j.spec.kind !== "tie") return k;
|
|
5384
5397
|
return partXf(o, o.parts[k]).c[1] > partXf(o, o.parts[r]).c[1] + 1e-6 ? k : -1;
|
|
5385
5398
|
};
|
|
5399
|
+
let poseVersion = 0;
|
|
5400
|
+
const contactMemo = /* @__PURE__ */ new WeakMap();
|
|
5386
5401
|
const contactBox = (p, support) => {
|
|
5402
|
+
let byTouching = contactMemo.get(p);
|
|
5403
|
+
if (!byTouching) contactMemo.set(p, byTouching = /* @__PURE__ */ new Map());
|
|
5404
|
+
const known = byTouching.get(support);
|
|
5405
|
+
if (known && known.version === poseVersion) return known.box;
|
|
5406
|
+
const box2 = measureContact(p, support);
|
|
5407
|
+
byTouching.set(support, { version: poseVersion, box: box2 });
|
|
5408
|
+
return box2;
|
|
5409
|
+
};
|
|
5410
|
+
const measureContact = (p, support) => {
|
|
5387
5411
|
const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
|
|
5388
5412
|
const lo = [0, 0, 0], hi = [0, 0, 0];
|
|
5389
5413
|
for (let k = 0; k < 3; k++) {
|
|
@@ -6178,7 +6202,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6178
6202
|
p.st.holes.push(hole);
|
|
6179
6203
|
if (p.st.holes.length > maxHoles) p.st.holes.shift();
|
|
6180
6204
|
markDamaged(p);
|
|
6181
|
-
emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {} });
|
|
6205
|
+
emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {}, ...p.spec.powder ? { powder: { ...p.spec.powder } } : {} });
|
|
6182
6206
|
setStage(o, p, 1, {}, src);
|
|
6183
6207
|
return hole;
|
|
6184
6208
|
};
|
|
@@ -6195,6 +6219,22 @@ var GameFloorplanStructure = (() => {
|
|
|
6195
6219
|
const detachEvents = (o, opened, by, src) => {
|
|
6196
6220
|
for (const j of opened) emit({ ...base(o, src), type: "detach", joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) });
|
|
6197
6221
|
};
|
|
6222
|
+
const slideOffResting = (o, rotation) => {
|
|
6223
|
+
const upY = 1 - 2 * (rotation[0] * rotation[0] + rotation[2] * rotation[2]);
|
|
6224
|
+
if (upY >= RESTING_HOLD_COS) return;
|
|
6225
|
+
const opened = o.joints.filter((j) => j.spec.kind === "resting" && !j.st.open);
|
|
6226
|
+
if (opened.length === 0) return;
|
|
6227
|
+
run(() => {
|
|
6228
|
+
for (const j of opened) {
|
|
6229
|
+
j.st.open = true;
|
|
6230
|
+
j.st.openedBy = "break";
|
|
6231
|
+
}
|
|
6232
|
+
solveStructure(o);
|
|
6233
|
+
recomputeGroups(o);
|
|
6234
|
+
detachEvents(o, opened, "break");
|
|
6235
|
+
collapseCheck(o);
|
|
6236
|
+
});
|
|
6237
|
+
};
|
|
6198
6238
|
const checkDestroyed = (o, src) => {
|
|
6199
6239
|
if (!o.st.destroyed && o.parts.length > 0 && o.parts.every(isLost)) {
|
|
6200
6240
|
o.st.destroyed = true;
|
|
@@ -6295,7 +6335,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6295
6335
|
const localHolesOf = (p) => p.st.holes.map((h) => ({ point: toLocal(p.pos, p.q, h.point), normal: rotateVec(quat.conjugate(p.q), h.normal), diameter: h.diameter }));
|
|
6296
6336
|
const unitsOf2 = (p) => p.spec.units ?? { size: [p.mat.fragmentSize?.[1] ?? 0.2, p.mat.fragmentSize?.[1] ?? 0.2, p.thickness], bond: "stack" };
|
|
6297
6337
|
const FRAGMENT_SHAPE = { shatter: "shard", splinter: "splinter", tear: "scrap" };
|
|
6298
|
-
const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag) => {
|
|
6338
|
+
const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag, inner2 = false) => {
|
|
6299
6339
|
const { c, q } = partXf(o, p);
|
|
6300
6340
|
const holes = p.st.holes.length > 0 ? localHolesOf(p) : [];
|
|
6301
6341
|
const [u, v] = planeAxes(p.thin);
|
|
@@ -6319,7 +6359,8 @@ var GameFloorplanStructure = (() => {
|
|
|
6319
6359
|
velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k],
|
|
6320
6360
|
angularVelocity: [(rnd() - 0.5) * 8, (rnd() - 0.5) * 8, (rnd() - 0.5) * 8],
|
|
6321
6361
|
mass: mass * faceArea(cell) / total,
|
|
6322
|
-
...marks.length > 0 ? { marks } : {}
|
|
6362
|
+
...marks.length > 0 ? { marks } : {},
|
|
6363
|
+
...inner2 ? { inner: inner2 } : {}
|
|
6323
6364
|
};
|
|
6324
6365
|
});
|
|
6325
6366
|
};
|
|
@@ -6360,7 +6401,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6360
6401
|
return cells.some((c) => Math.abs(lp[u] - c.center[u]) <= c.size[u] / 2 && Math.abs(lp[v] - c.center[v]) <= c.size[v] / 2);
|
|
6361
6402
|
};
|
|
6362
6403
|
const chipUnits = (o, p, kind, wp, hitEnergy, dir, radius, src) => {
|
|
6363
|
-
var _a, _b;
|
|
6404
|
+
var _a, _b, _c;
|
|
6364
6405
|
if (!p.spec.units || !p.staged || chipEnergy <= 0 || p.st.stripped || isLost(p) || (p.st.stage ?? 0) >= 2) return;
|
|
6365
6406
|
const rule = p.mat.hits?.[kind];
|
|
6366
6407
|
const perKg = rule?.unitJoules ?? chipEnergy;
|
|
@@ -6370,7 +6411,9 @@ var GameFloorplanStructure = (() => {
|
|
|
6370
6411
|
const lp = toLocal(p.pos, p.q, objLocal(o, wp));
|
|
6371
6412
|
const grid = gridOf(p);
|
|
6372
6413
|
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
6414
|
+
const cut = (_b = p.rt).craters ?? (_b.craters = {});
|
|
6373
6415
|
const out = [];
|
|
6416
|
+
const shot = kind === "ballistic";
|
|
6374
6417
|
for (let i = 0; i < grid.length; i++) {
|
|
6375
6418
|
const cell = grid[i];
|
|
6376
6419
|
if (worn[i] === -1) continue;
|
|
@@ -6383,18 +6426,42 @@ var GameFloorplanStructure = (() => {
|
|
|
6383
6426
|
worn[i] = total;
|
|
6384
6427
|
continue;
|
|
6385
6428
|
}
|
|
6386
|
-
|
|
6387
|
-
|
|
6429
|
+
if (!shot) {
|
|
6430
|
+
worn[i] = -1;
|
|
6431
|
+
out.push(cell);
|
|
6432
|
+
continue;
|
|
6433
|
+
}
|
|
6434
|
+
const size = [cell.size[0], cell.size[1], cell.size[2]];
|
|
6435
|
+
const center = [cell.center[0], cell.center[1], cell.center[2]];
|
|
6436
|
+
for (const a of [u, v]) {
|
|
6437
|
+
const w = Math.min(cell.size[a], craterAcross(hitEnergy) * (0.85 + 0.3 * rnd()));
|
|
6438
|
+
const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
|
|
6439
|
+
size[a] = w;
|
|
6440
|
+
center[a] = clamp22(lp[a], lo, hi);
|
|
6441
|
+
const [from, to] = tornToEdge({ p, cell, a, b: a === u ? v : u, at: lp[a], crater: [center[a] - w / 2, center[a] + w / 2], reach: w * EDGE_REACH, gone: (k) => worn[k] === -1 });
|
|
6442
|
+
size[a] = to - from;
|
|
6443
|
+
center[a] = (from + to) / 2;
|
|
6444
|
+
}
|
|
6445
|
+
const taken2 = (cut[i] ?? 0) + size[u] * size[v];
|
|
6446
|
+
if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
|
|
6447
|
+
worn[i] = -1;
|
|
6448
|
+
out.push({ ...cell, crater: true });
|
|
6449
|
+
continue;
|
|
6450
|
+
}
|
|
6451
|
+
worn[i] = 0;
|
|
6452
|
+
cut[i] = taken2;
|
|
6453
|
+
out.push({ center, size, crater: true });
|
|
6388
6454
|
}
|
|
6389
6455
|
if (out.length === 0) return;
|
|
6390
6456
|
const { c, q } = partXf(o, p);
|
|
6391
|
-
const chipped = (
|
|
6457
|
+
const chipped = (_c = p.st).chipped ?? (_c.chipped = []);
|
|
6392
6458
|
const holes = localHolesOf(p);
|
|
6393
6459
|
for (const cell of out) {
|
|
6394
6460
|
const mass = Math.min(p.st.mass, p.mat.density * cell.size[0] * cell.size[1] * cell.size[2]);
|
|
6395
6461
|
const center = toWorld(c, q, cell.center);
|
|
6396
6462
|
const speed = clamp22(Math.sqrt(2 * energy * 0.05 / Math.max(mass, 0.05)), 0.5, 6);
|
|
6397
|
-
const
|
|
6463
|
+
const tag = `c${chipped.length}_`;
|
|
6464
|
+
const fragments = cell.crater ? craterFragments(o, p, cell, dir, speed, mass, tag) : cellFragments(o, p, [cell], wp, dir, speed, mass, tag, true);
|
|
6398
6465
|
p.st.holes = p.st.holes.filter((_, k) => marksInBox(cell.center, cell.size, void 0, [holes[k]]).length === 0);
|
|
6399
6466
|
chipped.push({ center: [cell.center[0], cell.center[1], cell.center[2]], size: [cell.size[0], cell.size[1], cell.size[2]] });
|
|
6400
6467
|
p.st.mass = Math.max(0, p.st.mass - mass);
|
|
@@ -6411,6 +6478,57 @@ var GameFloorplanStructure = (() => {
|
|
|
6411
6478
|
collapseCheck(o, src);
|
|
6412
6479
|
}
|
|
6413
6480
|
};
|
|
6481
|
+
const tornToEdge = (o) => {
|
|
6482
|
+
const { p, cell, a, b, at: at2, crater: crater2, reach, gone } = o;
|
|
6483
|
+
const half = p.dims[a] / 2;
|
|
6484
|
+
const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
|
|
6485
|
+
const free = (side, sign) => {
|
|
6486
|
+
if (sign > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign > 0 || a !== planeAxes(p.thin)[1];
|
|
6487
|
+
const probe = side + sign * 1e-3;
|
|
6488
|
+
return gridOf(p).some((c, k) => gone(k) && Math.abs(probe - c.center[a]) <= c.size[a] / 2 && Math.abs(cell.center[b] - c.center[b]) <= c.size[b] / 2);
|
|
6489
|
+
};
|
|
6490
|
+
if (at2 - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
|
|
6491
|
+
if (hi - at2 <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
|
|
6492
|
+
return crater2;
|
|
6493
|
+
};
|
|
6494
|
+
const craterAcross = (energy) => clamp22(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
|
|
6495
|
+
const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
|
|
6496
|
+
const { c, q } = partXf(o, p);
|
|
6497
|
+
const [u, v] = planeAxes(p.thin);
|
|
6498
|
+
const d = dir ?? rotateVec(q, [p.thin === 0 ? 1 : 0, p.thin === 1 ? 1 : 0, p.thin === 2 ? 1 : 0]);
|
|
6499
|
+
const exitSign = Math.sign(rotateVec(quat.conjugate(q), d)[p.thin]) || 1;
|
|
6500
|
+
const bit = Math.max(0.01, Math.min(cell.size[u], cell.size[v]) / 3);
|
|
6501
|
+
const n = clamp22(Math.round(cell.size[u] * cell.size[v] / (bit * bit * 3)), 4, 10) + Math.floor(rnd() * 3);
|
|
6502
|
+
const out = [];
|
|
6503
|
+
for (let i = 0; i < n; i++) {
|
|
6504
|
+
const back = i % 3 === 2;
|
|
6505
|
+
const lc = [cell.center[0], cell.center[1], cell.center[2]];
|
|
6506
|
+
lc[u] += (rnd() - 0.5) * cell.size[u] * 0.7;
|
|
6507
|
+
lc[v] += (rnd() - 0.5) * cell.size[v] * 0.7;
|
|
6508
|
+
lc[p.thin] += (back ? -exitSign : exitSign) * (p.thickness / 2 + 0.01);
|
|
6509
|
+
const size = [0, 0, 0];
|
|
6510
|
+
size[u] = bit * (0.6 + 0.8 * rnd());
|
|
6511
|
+
size[v] = bit * (0.5 + 0.7 * rnd());
|
|
6512
|
+
size[p.thin] = bit * (0.4 + 0.6 * rnd());
|
|
6513
|
+
const spread3 = [(rnd() - 0.5) * 0.9, (rnd() - 0.3) * 0.9, (rnd() - 0.5) * 0.9];
|
|
6514
|
+
const k = speed * (back ? 0.4 + 0.4 * rnd() : 0.7 + 0.8 * rnd());
|
|
6515
|
+
const vdir = vec.normalize(vec.add(back ? vec.scale(d, -1) : d, spread3));
|
|
6516
|
+
out.push({
|
|
6517
|
+
id: `${p.spec.id}#${tag}${i}`,
|
|
6518
|
+
part: p.spec.id,
|
|
6519
|
+
material: p.spec.material,
|
|
6520
|
+
shape: "chunk",
|
|
6521
|
+
center: toWorld(c, q, lc),
|
|
6522
|
+
size,
|
|
6523
|
+
rotation: q,
|
|
6524
|
+
velocity: [vdir[0] * k, vdir[1] * k + 0.5 * rnd(), vdir[2] * k],
|
|
6525
|
+
angularVelocity: [(rnd() - 0.5) * 20, (rnd() - 0.5) * 20, (rnd() - 0.5) * 20],
|
|
6526
|
+
mass: mass / n,
|
|
6527
|
+
inner: true
|
|
6528
|
+
});
|
|
6529
|
+
}
|
|
6530
|
+
return out;
|
|
6531
|
+
};
|
|
6414
6532
|
const exposeRebar = (o, p, src) => {
|
|
6415
6533
|
const r = p.spec.reinforcement;
|
|
6416
6534
|
if (!r) return;
|
|
@@ -6698,7 +6816,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6698
6816
|
});
|
|
6699
6817
|
}
|
|
6700
6818
|
const patch = [scale * 4, scale * 4, scale * 4];
|
|
6701
|
-
emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry2, size: patch, rotation: q, fragments });
|
|
6819
|
+
emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry2, size: patch, rotation: q, fragments, torn: true });
|
|
6702
6820
|
};
|
|
6703
6821
|
const ballistic = (o, p, entry2, n, d, E, caliber, pathLen, src, round3 = {}) => {
|
|
6704
6822
|
const mat = p.mat;
|
|
@@ -6757,12 +6875,13 @@ var GameFloorplanStructure = (() => {
|
|
|
6757
6875
|
} else if (mat.ductility >= 0.5) {
|
|
6758
6876
|
addDent(o, p, entry2, n, Math.max(caliber * 3 / 1e3, 0.012), clamp22(Math.min(Math.max(p.thickness * 3, 3e-3), ratio * 0.01), 1e-3, 0.05), src);
|
|
6759
6877
|
} else if (brittle) {
|
|
6760
|
-
addCrack(o, p, entry2, n, crackLen, src);
|
|
6878
|
+
if (!p.spec.units) addCrack(o, p, entry2, n, crackLen, src);
|
|
6761
6879
|
if (mat.fracture !== "shatter") addHole(o, p, entry2, n, caliber / 1e3, false, void 0, src);
|
|
6762
6880
|
} else addHole(o, p, entry2, n, caliber / 1e3, false, void 0, src);
|
|
6763
6881
|
debris(o, p, mat.hitDebris, entry2, n, clamp22(Math.round(E / 60) + 2, 2, 14), clamp22(Math.sqrt(E) / 6, 1, 8), src);
|
|
6764
6882
|
wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true, BULLET_JOINT_SPAN);
|
|
6765
|
-
const
|
|
6883
|
+
const hollowTear = mat.fracture === "tear" && p.spec.fill !== void 0 && p.spec.fill < 0.5;
|
|
6884
|
+
const absorbed = penetrated && (mat.ductility >= 0.5 && mat.fracture !== "tear" || hollowTear) ? Math.min(E, thr) : E;
|
|
6766
6885
|
const dmg = applyDamage(o, p, absorbed * DMG_PER_J * scale, "ballistic", entry2, d, absorbed * 0.1, 12, src);
|
|
6767
6886
|
if (!isLost(p)) tearAt(o, p, "ballistic", entry2, penetrated ? exitPoint : void 0, d, E, caliber / 1e3, src);
|
|
6768
6887
|
chipUnits(o, p, "ballistic", entry2, penetrated ? Math.min(E, Math.max(thr, E * 0.5)) : E, d, Math.max(0.05, caliber / 1e3 * 8), src);
|
|
@@ -6847,10 +6966,25 @@ var GameFloorplanStructure = (() => {
|
|
|
6847
6966
|
if (dist <= BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3)) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
|
|
6848
6967
|
return reach;
|
|
6849
6968
|
};
|
|
6969
|
+
const blastProbe = { partsTested: 0, partsNear: 0 };
|
|
6970
|
+
const blastCandidates = (o, point, radius) => {
|
|
6971
|
+
const local = toLocal(o.st.position, o.st.rotation, point);
|
|
6972
|
+
const near = [];
|
|
6973
|
+
for (const p of o.parts) {
|
|
6974
|
+
const reach = radius + p.bound;
|
|
6975
|
+
const dx = local[0] - p.pos[0];
|
|
6976
|
+
const dy = local[1] - p.pos[1];
|
|
6977
|
+
const dz = local[2] - p.pos[2];
|
|
6978
|
+
if (dx * dx + dy * dy + dz * dz < reach * reach) near.push(p);
|
|
6979
|
+
}
|
|
6980
|
+
blastProbe.partsTested += o.parts.length;
|
|
6981
|
+
blastProbe.partsNear += near.length;
|
|
6982
|
+
return near;
|
|
6983
|
+
};
|
|
6850
6984
|
const blastObject = (o, point, energy, radius, src) => {
|
|
6851
6985
|
const start = cur.length;
|
|
6852
6986
|
const res = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] };
|
|
6853
|
-
for (const p of o
|
|
6987
|
+
for (const p of blastCandidates(o, point, radius)) blastPart(o, p, point, energy, radius, src, res);
|
|
6854
6988
|
res.events = cur.slice(start);
|
|
6855
6989
|
return res;
|
|
6856
6990
|
};
|
|
@@ -6974,7 +7108,7 @@ var GameFloorplanStructure = (() => {
|
|
|
6974
7108
|
let order = 0;
|
|
6975
7109
|
for (const o of inRange) {
|
|
6976
7110
|
if (only && only !== o) continue;
|
|
6977
|
-
for (const p of o
|
|
7111
|
+
for (const p of blastCandidates(o, point, radius)) {
|
|
6978
7112
|
if (isLost(p)) continue;
|
|
6979
7113
|
const dist = distToPart(o, p, point);
|
|
6980
7114
|
if (dist < radius) items.push({ dist, order: order++, o, p });
|
|
@@ -7521,6 +7655,7 @@ var GameFloorplanStructure = (() => {
|
|
|
7521
7655
|
const p = getPart(o, partId);
|
|
7522
7656
|
p.pos = [position[0], position[1], position[2]];
|
|
7523
7657
|
p.q = q;
|
|
7658
|
+
poseVersion++;
|
|
7524
7659
|
updateBound(o);
|
|
7525
7660
|
},
|
|
7526
7661
|
remove(id) {
|
|
@@ -7539,6 +7674,7 @@ var GameFloorplanStructure = (() => {
|
|
|
7539
7674
|
const o = getObj(id);
|
|
7540
7675
|
o.base = { pos: [position[0], position[1], position[2]], rot: [rotation[0], rotation[1], rotation[2], rotation[3]] };
|
|
7541
7676
|
applySoilPose(o);
|
|
7677
|
+
slideOffResting(o, rotation);
|
|
7542
7678
|
},
|
|
7543
7679
|
splitGroup(id, group, newId) {
|
|
7544
7680
|
if (impls.has(id)) throw new Error(`object "${id}" is a registered DestructibleImpl and cannot be split; its module owns its pieces`);
|
|
@@ -7562,7 +7698,7 @@ var GameFloorplanStructure = (() => {
|
|
|
7562
7698
|
if (o.spec.name !== void 0) s.name = o.spec.name;
|
|
7563
7699
|
if (o.spec.tags) s.tags = [...o.spec.tags];
|
|
7564
7700
|
if (o.spec.soil !== void 0) s.soil = o.spec.soil;
|
|
7565
|
-
return
|
|
7701
|
+
return s;
|
|
7566
7702
|
};
|
|
7567
7703
|
const inNew = (pid) => moved.has(pid);
|
|
7568
7704
|
const inOld = (pid) => !moved.has(pid);
|
|
@@ -7589,7 +7725,12 @@ var GameFloorplanStructure = (() => {
|
|
|
7589
7725
|
const p = getPart(o, partId);
|
|
7590
7726
|
return whole(() => doHit(o, h, p));
|
|
7591
7727
|
},
|
|
7728
|
+
blastProbe() {
|
|
7729
|
+
return { ...blastProbe };
|
|
7730
|
+
},
|
|
7592
7731
|
explode(point, energy, radius, source, blast) {
|
|
7732
|
+
blastProbe.partsTested = 0;
|
|
7733
|
+
blastProbe.partsNear = 0;
|
|
7593
7734
|
return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
|
|
7594
7735
|
},
|
|
7595
7736
|
raycast(origin, direction, maxDistance = Infinity) {
|
|
@@ -7599,7 +7740,8 @@ var GameFloorplanStructure = (() => {
|
|
|
7599
7740
|
sweepBox(box2, direction, distance2, options2 = {}) {
|
|
7600
7741
|
const d = vec.normalize(direction);
|
|
7601
7742
|
const ignored = options2.ignore === void 0 ? void 0 : objects.get(options2.ignore);
|
|
7602
|
-
const
|
|
7743
|
+
const hosted = options2.ignore === void 0 || ignored ? void 0 : impls.get(options2.ignore);
|
|
7744
|
+
const ignore = ignored ? new Set(ignored.parts.map((p) => `${ignored.id}\0${p.spec.id}`)) : hosted ? new Set(hosted.impl.describe().parts.map((p) => `${hosted.impl.id}\0${p.id}`)) : void 0;
|
|
7603
7745
|
let best = null;
|
|
7604
7746
|
for (const origin of sweepOrigins(box2, d, options2.spacing ?? 0.2)) {
|
|
7605
7747
|
const r = raycastInternal(origin, d, distance2 + SWEEP_BACK, ignore);
|