@adatechnology/game-destruction 0.10.0 → 0.12.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 +39 -1
- package/dist/index.global.js +398 -34
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +398 -34
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.global.js
CHANGED
|
@@ -486,7 +486,9 @@ var GameDestruction = (() => {
|
|
|
486
486
|
const band = { c: [root.c[0], root.c[1], root.c[2]], s: [dims[0], dims[1], dims[2]] };
|
|
487
487
|
band.c[L] = (lo + hi) / 2;
|
|
488
488
|
band.s[L] = Math.max(hi - lo, 0.01);
|
|
489
|
-
|
|
489
|
+
if (inp.style === "snap") {
|
|
490
|
+
for (const b of bsp(band, Math.max(3, Math.min(6, inp.maxFragments - out.length)), [0, 1, 2], inp.rnd)) out.push({ center: b.c, size: b.s, q: quat.identity(), shape: "chunk", weight: b.s[0] * b.s[1] * b.s[2] });
|
|
491
|
+
} else for (const p of splinterBox(inp, band, Math.max(3, inp.maxFragments - out.length))) out.push(p);
|
|
490
492
|
return out;
|
|
491
493
|
};
|
|
492
494
|
var tearStack = (inp, root, t, u, v, n, sheet) => {
|
|
@@ -517,6 +519,7 @@ var GameDestruction = (() => {
|
|
|
517
519
|
const t = sorted[0];
|
|
518
520
|
const [u, v] = [sorted[1], sorted[2]].sort((a, b) => a - b);
|
|
519
521
|
if (style === "snap") {
|
|
522
|
+
if (inp.cut) return severAt(inp, root, inp.cut.at, inp.cut.gap);
|
|
520
523
|
const n2 = Math.min(maxFragments, 2 + Math.floor(rnd() * 3));
|
|
521
524
|
for (const b of bsp(root, n2, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: "slab", weight: b.s[0] * b.s[1] * b.s[2] });
|
|
522
525
|
return out;
|
|
@@ -696,6 +699,27 @@ var GameDestruction = (() => {
|
|
|
696
699
|
for (const x of spread(dims[u], COVER, spacing, MAX_BARS_PER_DIRECTION)) out.push(bar(v, dims[v] / 2 - 0.02, [[u, x], [thin, 0]]));
|
|
697
700
|
return out;
|
|
698
701
|
};
|
|
702
|
+
var clipBarsToBox = (bars, u, v, center, size) => {
|
|
703
|
+
const out = [];
|
|
704
|
+
for (const [a, b] of bars) {
|
|
705
|
+
const axis = a[u] !== b[u] ? u : v;
|
|
706
|
+
const other = axis === u ? v : u;
|
|
707
|
+
if (Math.abs(a[other] - center[other]) > size[other] / 2) continue;
|
|
708
|
+
const lo = Math.max(Math.min(a[axis], b[axis]), center[axis] - size[axis] / 2), hi = Math.min(Math.max(a[axis], b[axis]), center[axis] + size[axis] / 2);
|
|
709
|
+
if (hi - lo < 1e-6) continue;
|
|
710
|
+
const p = [a[0], a[1], a[2]], q = [b[0], b[1], b[2]];
|
|
711
|
+
p[axis] = lo;
|
|
712
|
+
q[axis] = hi;
|
|
713
|
+
out.push([p, q]);
|
|
714
|
+
}
|
|
715
|
+
return out;
|
|
716
|
+
};
|
|
717
|
+
var bendBar = ([a, b], thin, bow, i) => {
|
|
718
|
+
const length = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
719
|
+
const m = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2];
|
|
720
|
+
m[thin] += (i % 2 === 0 ? 1 : -1) * bow * length;
|
|
721
|
+
return [[a, m], [m, b]];
|
|
722
|
+
};
|
|
699
723
|
var clipBarsToDisc = (bars, u, v, center, radius) => {
|
|
700
724
|
const out = [];
|
|
701
725
|
for (const [a, b] of bars) {
|
|
@@ -1673,14 +1697,21 @@ var GameDestruction = (() => {
|
|
|
1673
1697
|
smoke: "grey"
|
|
1674
1698
|
},
|
|
1675
1699
|
visual: {
|
|
1676
|
-
charColor: 1709072
|
|
1700
|
+
charColor: 1709072,
|
|
1701
|
+
innerColor: 14730131
|
|
1677
1702
|
},
|
|
1678
1703
|
tags: [
|
|
1679
1704
|
"wood",
|
|
1680
1705
|
"organic",
|
|
1681
1706
|
"flammable"
|
|
1682
1707
|
],
|
|
1683
|
-
compressive: 1e5
|
|
1708
|
+
compressive: 1e5,
|
|
1709
|
+
hits: {
|
|
1710
|
+
blunt: {
|
|
1711
|
+
tear: "splinters",
|
|
1712
|
+
tearJoules: 60
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1684
1715
|
},
|
|
1685
1716
|
{
|
|
1686
1717
|
id: "wood_hard",
|
|
@@ -1710,14 +1741,21 @@ var GameDestruction = (() => {
|
|
|
1710
1741
|
smoke: "grey"
|
|
1711
1742
|
},
|
|
1712
1743
|
visual: {
|
|
1713
|
-
charColor: 1709072
|
|
1744
|
+
charColor: 1709072,
|
|
1745
|
+
innerColor: 13213802
|
|
1714
1746
|
},
|
|
1715
1747
|
tags: [
|
|
1716
1748
|
"wood",
|
|
1717
1749
|
"organic",
|
|
1718
1750
|
"flammable"
|
|
1719
1751
|
],
|
|
1720
|
-
compressive: 15e4
|
|
1752
|
+
compressive: 15e4,
|
|
1753
|
+
hits: {
|
|
1754
|
+
blunt: {
|
|
1755
|
+
tear: "splinters",
|
|
1756
|
+
tearJoules: 150
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1721
1759
|
},
|
|
1722
1760
|
{
|
|
1723
1761
|
id: "plywood",
|
|
@@ -1747,14 +1785,24 @@ var GameDestruction = (() => {
|
|
|
1747
1785
|
smoke: "grey"
|
|
1748
1786
|
},
|
|
1749
1787
|
visual: {
|
|
1750
|
-
charColor: 1709072
|
|
1788
|
+
charColor: 1709072,
|
|
1789
|
+
innerColor: 14862234
|
|
1751
1790
|
},
|
|
1752
1791
|
tags: [
|
|
1753
1792
|
"wood",
|
|
1754
1793
|
"organic",
|
|
1755
1794
|
"flammable"
|
|
1756
1795
|
],
|
|
1757
|
-
compressive: 6e4
|
|
1796
|
+
compressive: 6e4,
|
|
1797
|
+
hits: {
|
|
1798
|
+
ballistic: {
|
|
1799
|
+
tear: "splinters"
|
|
1800
|
+
},
|
|
1801
|
+
blunt: {
|
|
1802
|
+
tear: "splinters",
|
|
1803
|
+
tearJoules: 80
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1758
1806
|
},
|
|
1759
1807
|
{
|
|
1760
1808
|
id: "mdf",
|
|
@@ -1781,14 +1829,25 @@ var GameDestruction = (() => {
|
|
|
1781
1829
|
smoke: "grey"
|
|
1782
1830
|
},
|
|
1783
1831
|
visual: {
|
|
1784
|
-
charColor: 1709072
|
|
1832
|
+
charColor: 1709072,
|
|
1833
|
+
innerColor: 12096362
|
|
1785
1834
|
},
|
|
1786
1835
|
tags: [
|
|
1787
1836
|
"wood",
|
|
1788
1837
|
"organic",
|
|
1789
1838
|
"flammable"
|
|
1790
1839
|
],
|
|
1791
|
-
compressive: 3e4
|
|
1840
|
+
compressive: 3e4,
|
|
1841
|
+
hits: {
|
|
1842
|
+
ballistic: {
|
|
1843
|
+
tear: "lumps",
|
|
1844
|
+
tearJoules: 120
|
|
1845
|
+
},
|
|
1846
|
+
blunt: {
|
|
1847
|
+
tear: "lumps",
|
|
1848
|
+
tearJoules: 20
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1792
1851
|
},
|
|
1793
1852
|
{
|
|
1794
1853
|
id: "glass",
|
|
@@ -1902,8 +1961,20 @@ var GameDestruction = (() => {
|
|
|
1902
1961
|
damageScale: {
|
|
1903
1962
|
explosive: 1.2
|
|
1904
1963
|
},
|
|
1964
|
+
hits: {
|
|
1965
|
+
ballistic: {
|
|
1966
|
+
unitJoules: 500,
|
|
1967
|
+
floor: 900,
|
|
1968
|
+
crater: true
|
|
1969
|
+
},
|
|
1970
|
+
blunt: {
|
|
1971
|
+
unitJoules: 1500,
|
|
1972
|
+
floor: 60
|
|
1973
|
+
}
|
|
1974
|
+
},
|
|
1905
1975
|
hitDebris: "chips",
|
|
1906
1976
|
breakDebris: "dust",
|
|
1977
|
+
visual: { innerColor: 10197652 },
|
|
1907
1978
|
thermal: {
|
|
1908
1979
|
conductivity: 0.15,
|
|
1909
1980
|
heatCapacity: 2.5
|
|
@@ -1934,6 +2005,7 @@ var GameDestruction = (() => {
|
|
|
1934
2005
|
],
|
|
1935
2006
|
hitDebris: "chips",
|
|
1936
2007
|
breakDebris: "dust",
|
|
2008
|
+
visual: { innerColor: 12085567 },
|
|
1937
2009
|
thermal: {
|
|
1938
2010
|
conductivity: 0.15,
|
|
1939
2011
|
heatCapacity: 2.5
|
|
@@ -1964,6 +2036,7 @@ var GameDestruction = (() => {
|
|
|
1964
2036
|
],
|
|
1965
2037
|
hitDebris: "dust",
|
|
1966
2038
|
breakDebris: "dust",
|
|
2039
|
+
visual: { innerColor: 14999507 },
|
|
1967
2040
|
thermal: {
|
|
1968
2041
|
conductivity: 0.1,
|
|
1969
2042
|
heatCapacity: 1.5
|
|
@@ -1989,6 +2062,7 @@ var GameDestruction = (() => {
|
|
|
1989
2062
|
],
|
|
1990
2063
|
hitDebris: "chips",
|
|
1991
2064
|
breakDebris: "dust",
|
|
2065
|
+
visual: { innerColor: 9407364 },
|
|
1992
2066
|
thermal: {
|
|
1993
2067
|
conductivity: 0.2,
|
|
1994
2068
|
heatCapacity: 2.5
|
|
@@ -2270,7 +2344,8 @@ var GameDestruction = (() => {
|
|
|
2270
2344
|
smoke: "white"
|
|
2271
2345
|
},
|
|
2272
2346
|
visual: {
|
|
2273
|
-
charColor: 1709072
|
|
2347
|
+
charColor: 1709072,
|
|
2348
|
+
innerColor: 14207126
|
|
2274
2349
|
},
|
|
2275
2350
|
tags: [
|
|
2276
2351
|
"plant",
|
|
@@ -2278,7 +2353,12 @@ var GameDestruction = (() => {
|
|
|
2278
2353
|
"organic",
|
|
2279
2354
|
"flammable"
|
|
2280
2355
|
],
|
|
2281
|
-
compressive: 6e4
|
|
2356
|
+
compressive: 6e4,
|
|
2357
|
+
hits: {
|
|
2358
|
+
blunt: {
|
|
2359
|
+
tear: "none"
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2282
2362
|
},
|
|
2283
2363
|
{
|
|
2284
2364
|
id: "cactus",
|
|
@@ -2393,6 +2473,130 @@ var GameDestruction = (() => {
|
|
|
2393
2473
|
"masonry"
|
|
2394
2474
|
],
|
|
2395
2475
|
compressive: 2e4
|
|
2476
|
+
},
|
|
2477
|
+
{
|
|
2478
|
+
id: "asphalt",
|
|
2479
|
+
density: 2350,
|
|
2480
|
+
hpPerKg: 10,
|
|
2481
|
+
penetration: 14,
|
|
2482
|
+
penetrationClass: "concrete",
|
|
2483
|
+
penetrationScale: 0.8,
|
|
2484
|
+
ductility: 0.1,
|
|
2485
|
+
fracture: "crumble",
|
|
2486
|
+
fragmentSize: [
|
|
2487
|
+
0.03,
|
|
2488
|
+
0.15
|
|
2489
|
+
],
|
|
2490
|
+
hitDebris: "chips",
|
|
2491
|
+
breakDebris: "dust",
|
|
2492
|
+
thermal: {
|
|
2493
|
+
conductivity: 0.1,
|
|
2494
|
+
heatCapacity: 2,
|
|
2495
|
+
ignitionC: 400,
|
|
2496
|
+
burnRate: 2e-3,
|
|
2497
|
+
smoke: "black"
|
|
2498
|
+
},
|
|
2499
|
+
tags: [
|
|
2500
|
+
"masonry",
|
|
2501
|
+
"brittle"
|
|
2502
|
+
],
|
|
2503
|
+
compressive: 3e4
|
|
2504
|
+
},
|
|
2505
|
+
{
|
|
2506
|
+
id: "sand",
|
|
2507
|
+
density: 1600,
|
|
2508
|
+
hpPerKg: 2,
|
|
2509
|
+
penetration: 6,
|
|
2510
|
+
ductility: 0.4,
|
|
2511
|
+
fracture: "crumble",
|
|
2512
|
+
fragmentSize: [
|
|
2513
|
+
0.01,
|
|
2514
|
+
0.04
|
|
2515
|
+
],
|
|
2516
|
+
hitDebris: "dust",
|
|
2517
|
+
breakDebris: "dust",
|
|
2518
|
+
thermal: {
|
|
2519
|
+
conductivity: 0.1,
|
|
2520
|
+
heatCapacity: 2
|
|
2521
|
+
},
|
|
2522
|
+
tags: [
|
|
2523
|
+
"soil"
|
|
2524
|
+
],
|
|
2525
|
+
compressive: 1e4
|
|
2526
|
+
},
|
|
2527
|
+
{
|
|
2528
|
+
id: "gravel",
|
|
2529
|
+
density: 1800,
|
|
2530
|
+
hpPerKg: 3,
|
|
2531
|
+
penetration: 8,
|
|
2532
|
+
ductility: 0.3,
|
|
2533
|
+
fracture: "crumble",
|
|
2534
|
+
fragmentSize: [
|
|
2535
|
+
0.02,
|
|
2536
|
+
0.06
|
|
2537
|
+
],
|
|
2538
|
+
hitDebris: "chips",
|
|
2539
|
+
breakDebris: "dust",
|
|
2540
|
+
thermal: {
|
|
2541
|
+
conductivity: 0.1,
|
|
2542
|
+
heatCapacity: 2
|
|
2543
|
+
},
|
|
2544
|
+
tags: [
|
|
2545
|
+
"soil",
|
|
2546
|
+
"masonry"
|
|
2547
|
+
],
|
|
2548
|
+
compressive: 2e4
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
id: "turf",
|
|
2552
|
+
density: 900,
|
|
2553
|
+
hpPerKg: 3,
|
|
2554
|
+
penetration: 4,
|
|
2555
|
+
ductility: 0.5,
|
|
2556
|
+
fracture: "crumble",
|
|
2557
|
+
fragmentSize: [
|
|
2558
|
+
0.03,
|
|
2559
|
+
0.1
|
|
2560
|
+
],
|
|
2561
|
+
hitDebris: "dust",
|
|
2562
|
+
breakDebris: "dust",
|
|
2563
|
+
thermal: {
|
|
2564
|
+
conductivity: 0.1,
|
|
2565
|
+
heatCapacity: 1.5,
|
|
2566
|
+
ignitionC: 250,
|
|
2567
|
+
burnRate: 0.03,
|
|
2568
|
+
smoke: "white"
|
|
2569
|
+
},
|
|
2570
|
+
tags: [
|
|
2571
|
+
"soil",
|
|
2572
|
+
"organic"
|
|
2573
|
+
],
|
|
2574
|
+
compressive: 15e3
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
id: "mortar",
|
|
2578
|
+
density: 1900,
|
|
2579
|
+
hpPerKg: 10,
|
|
2580
|
+
penetration: 12,
|
|
2581
|
+
penetrationClass: "concrete",
|
|
2582
|
+
penetrationScale: 1.2,
|
|
2583
|
+
ductility: 0.03,
|
|
2584
|
+
fracture: "crumble",
|
|
2585
|
+
fragmentSize: [
|
|
2586
|
+
0.02,
|
|
2587
|
+
0.08
|
|
2588
|
+
],
|
|
2589
|
+
hitDebris: "chips",
|
|
2590
|
+
breakDebris: "dust",
|
|
2591
|
+
thermal: {
|
|
2592
|
+
conductivity: 0.15,
|
|
2593
|
+
heatCapacity: 2.5
|
|
2594
|
+
},
|
|
2595
|
+
tags: [
|
|
2596
|
+
"masonry",
|
|
2597
|
+
"brittle"
|
|
2598
|
+
],
|
|
2599
|
+
compressive: 1e5
|
|
2396
2600
|
}
|
|
2397
2601
|
];
|
|
2398
2602
|
|
|
@@ -2729,6 +2933,32 @@ var GameDestruction = (() => {
|
|
|
2729
2933
|
|
|
2730
2934
|
// src/world.ts
|
|
2731
2935
|
var THIN_SHEET_DISHING = 5e-3;
|
|
2936
|
+
var SWEEP_BACK = 0.01;
|
|
2937
|
+
function sweepOrigins(box, d, spacing) {
|
|
2938
|
+
const origins = [];
|
|
2939
|
+
const line = (from, to) => {
|
|
2940
|
+
const n = Math.max(1, Math.ceil((to - from) / spacing));
|
|
2941
|
+
return Array.from({ length: n + 1 }, (_, i) => from + (to - from) * i / n);
|
|
2942
|
+
};
|
|
2943
|
+
for (const axis of [0, 1, 2]) {
|
|
2944
|
+
if (Math.abs(d[axis]) < 1e-3) continue;
|
|
2945
|
+
const lead = d[axis] > 0 ? box.max[axis] - SWEEP_BACK : box.min[axis] + SWEEP_BACK;
|
|
2946
|
+
const u = (axis + 1) % 3;
|
|
2947
|
+
const v = (axis + 2) % 3;
|
|
2948
|
+
for (const a of line(box.min[u], box.max[u])) {
|
|
2949
|
+
for (const b of line(box.min[v], box.max[v])) {
|
|
2950
|
+
const point = [0, 0, 0];
|
|
2951
|
+
point[axis] = lead;
|
|
2952
|
+
point[u] = a;
|
|
2953
|
+
point[v] = b;
|
|
2954
|
+
origins.push(point);
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
return origins;
|
|
2959
|
+
}
|
|
2960
|
+
var THIN_SHEET_CRUSH = 5e-4;
|
|
2961
|
+
var THIN_SHEET_CONTACT = 0.025;
|
|
2732
2962
|
var DMG_PER_J = 0.02;
|
|
2733
2963
|
var BLAST_COUPLING = 0.1;
|
|
2734
2964
|
var SHELTER_DEFAULTS = { k: 2800, brokenTransmission: 0.5, minPath: 5e-3 };
|
|
@@ -2745,11 +2975,15 @@ var GameDestruction = (() => {
|
|
|
2745
2975
|
var SEVER_BAND = 0.1;
|
|
2746
2976
|
var SEVER_ASPECT = 3;
|
|
2747
2977
|
var SEVER_BALLISTIC = 2;
|
|
2978
|
+
var TEAR_JOULES = 150;
|
|
2979
|
+
var tears = 0;
|
|
2748
2980
|
var SUPPORT_TOLERANCE = 0.05;
|
|
2749
2981
|
var UNIT_FRAGMENT_FACTOR = 4;
|
|
2750
2982
|
var BREACH_GRID_CAP = 4096;
|
|
2751
2983
|
var CHIP_ENERGY = 200;
|
|
2752
2984
|
var CHIP_SPLASH = 0.5;
|
|
2985
|
+
var BAR_BOW = 0.08;
|
|
2986
|
+
var BULLET_JOINT_SPAN = 0.3;
|
|
2753
2987
|
var CUT_SLICE = 1;
|
|
2754
2988
|
var cutFactorOf = (shape) => clamp2(Math.max(...shapeDims(shape)) / CUT_SLICE, 1, 50);
|
|
2755
2989
|
var clamp2 = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
@@ -2759,8 +2993,24 @@ var GameDestruction = (() => {
|
|
|
2759
2993
|
return v === void 0 ? void 0 : v * (mat.penetrationScale ?? 1);
|
|
2760
2994
|
};
|
|
2761
2995
|
var capacityScale = (p) => {
|
|
2762
|
-
|
|
2763
|
-
|
|
2996
|
+
const residual = p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY;
|
|
2997
|
+
if (p.st.stripped) return residual;
|
|
2998
|
+
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, 1 - sectionLoss(p));
|
|
2999
|
+
return Math.max(p.spec.reinforcement ? residual : 0.05, kept);
|
|
3000
|
+
};
|
|
3001
|
+
var sectionLoss = (p) => {
|
|
3002
|
+
const cells = p.st.chipped;
|
|
3003
|
+
if (!cells?.length) return 0;
|
|
3004
|
+
const [u, v] = planeAxes(p.thin);
|
|
3005
|
+
const along = p.dims[u] >= p.dims[v] ? u : v;
|
|
3006
|
+
const across = along === u ? v : u;
|
|
3007
|
+
let worst = 0;
|
|
3008
|
+
for (const c of cells) {
|
|
3009
|
+
let gone = 0;
|
|
3010
|
+
for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) gone += d.size[across];
|
|
3011
|
+
worst = Math.max(worst, gone / Math.max(p.dims[across], 1e-6));
|
|
3012
|
+
}
|
|
3013
|
+
return Math.min(1, worst);
|
|
2764
3014
|
};
|
|
2765
3015
|
var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
|
|
2766
3016
|
var clone = (v) => structuredClone(v);
|
|
@@ -3860,7 +4110,7 @@ var GameDestruction = (() => {
|
|
|
3860
4110
|
emit({ ...base(o, src), type: "crack", part: p.spec.id, crack, worldPoint: wp });
|
|
3861
4111
|
setStage(o, p, 1, {}, src);
|
|
3862
4112
|
};
|
|
3863
|
-
const debris = (o, p, kind, point, normal, count, speed, src) => emit({ ...base(o, src), type: "debris", part: p.spec.id, kind, point, normal, count, speed });
|
|
4113
|
+
const debris = (o, p, kind, point, normal, count, speed, src, material) => emit({ ...base(o, src), type: "debris", part: p.spec.id, kind, point, normal, count, speed, ...material && material !== p.spec.material ? { material } : {} });
|
|
3864
4114
|
const holeRate = (hole, pressurized) => (pressurized ? 0.5 : 0.1) * (hole.diameter / 9e-3);
|
|
3865
4115
|
const detachEvents = (o, opened, by, src) => {
|
|
3866
4116
|
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]) });
|
|
@@ -3901,7 +4151,13 @@ var GameDestruction = (() => {
|
|
|
3901
4151
|
const small = pa.dims[0] * pa.dims[1] * pa.dims[2] <= pb.dims[0] * pb.dims[1] * pb.dims[2] ? pa : pb;
|
|
3902
4152
|
return Math.max(0.06, 0.5 * Math.min(small.dims[0], small.dims[1], small.dims[2]));
|
|
3903
4153
|
};
|
|
3904
|
-
const
|
|
4154
|
+
const jointLength = (o, j) => {
|
|
4155
|
+
const A = partWorldAabb(o, o.parts[j.ia]), B = partWorldAabb(o, o.parts[j.ib]);
|
|
4156
|
+
let len = 0;
|
|
4157
|
+
for (let k = 0; k < 3; k++) len = Math.max(len, Math.min(A.max[k], B.max[k]) - Math.max(A.min[k], B.min[k]));
|
|
4158
|
+
return len;
|
|
4159
|
+
};
|
|
4160
|
+
const wearJoints = (o, p, amount, near, radius = 0.06, src, split = false, span) => {
|
|
3905
4161
|
if (amount <= 0) return;
|
|
3906
4162
|
const mine = (o.byPart.get(p.spec.id) ?? []).filter((j) => !j.st.open);
|
|
3907
4163
|
if (split && mine.length) amount /= mine.length;
|
|
@@ -3909,7 +4165,7 @@ var GameDestruction = (() => {
|
|
|
3909
4165
|
if (j.st.open) continue;
|
|
3910
4166
|
if (j.spec.kind === "rebar" && (isReinforced(o.parts[j.ia].spec) || isReinforced(o.parts[j.ib].spec))) continue;
|
|
3911
4167
|
if (near && jointReach(o, j, near) > Math.max(radius, jointReachLimit(o, j))) continue;
|
|
3912
|
-
j.st.hp -= amount;
|
|
4168
|
+
j.st.hp -= span === void 0 ? amount : amount * Math.min(1, span / Math.max(jointLength(o, j), 1e-6));
|
|
3913
4169
|
if (j.st.hp <= 0) {
|
|
3914
4170
|
j.st.hp = 0;
|
|
3915
4171
|
j.st.open = true;
|
|
@@ -3938,7 +4194,13 @@ var GameDestruction = (() => {
|
|
|
3938
4194
|
if (spalls.length > MAX_SPALLS) spalls.shift();
|
|
3939
4195
|
markDamaged(p);
|
|
3940
4196
|
emit({ ...base(o, src), type: "spall", part: p.spec.id, layer: layer.index, point: wp, area: Math.PI * radius * radius });
|
|
3941
|
-
debris(o, p, layer.mat.hitDebris, wp, normal, 5, 2, src);
|
|
4197
|
+
debris(o, p, layer.mat.hitDebris, wp, normal, 5, 2, src, layer.mat.id);
|
|
4198
|
+
setStage(o, p, 1, {}, src);
|
|
4199
|
+
};
|
|
4200
|
+
const crater = (o, p, wp, normal, radius, src) => {
|
|
4201
|
+
markDamaged(p);
|
|
4202
|
+
emit({ ...base(o, src), type: "spall", part: p.spec.id, layer: -1, point: wp, area: Math.PI * radius * radius });
|
|
4203
|
+
debris(o, p, p.mat.breakDebris, wp, normal, 6, 1.5, src);
|
|
3942
4204
|
setStage(o, p, 1, {}, src);
|
|
3943
4205
|
};
|
|
3944
4206
|
const insideOpening = (o, p, objectPoint) => {
|
|
@@ -4017,9 +4279,13 @@ var GameDestruction = (() => {
|
|
|
4017
4279
|
const lp = toLocal(p.pos, p.q, objectPoint);
|
|
4018
4280
|
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);
|
|
4019
4281
|
};
|
|
4020
|
-
const chipUnits = (o, p, wp,
|
|
4282
|
+
const chipUnits = (o, p, kind, wp, hitEnergy, dir, radius, src) => {
|
|
4021
4283
|
var _a, _b;
|
|
4022
|
-
if (!p.spec.units ||
|
|
4284
|
+
if (!p.spec.units || !p.staged || chipEnergy <= 0 || p.st.stripped || isLost(p) || (p.st.stage ?? 0) >= 2) return;
|
|
4285
|
+
const rule = p.mat.hits?.[kind];
|
|
4286
|
+
const perKg = rule?.unitJoules ?? chipEnergy;
|
|
4287
|
+
const energy = hitEnergy - (rule?.floor ?? 0);
|
|
4288
|
+
if (perKg <= 0 || energy <= 0) return;
|
|
4023
4289
|
const [u, v] = planeAxes(p.thin);
|
|
4024
4290
|
const lp = toLocal(p.pos, p.q, objLocal(o, wp));
|
|
4025
4291
|
const grid = gridOf(p);
|
|
@@ -4033,7 +4299,7 @@ var GameDestruction = (() => {
|
|
|
4033
4299
|
const share = gap === 0 ? 1 : CHIP_SPLASH * (1 - gap / radius);
|
|
4034
4300
|
const total = (worn[i] ?? 0) + energy * share;
|
|
4035
4301
|
const mass = p.mat.density * cell.size[0] * cell.size[1] * cell.size[2];
|
|
4036
|
-
if (total <
|
|
4302
|
+
if (total < perKg * mass) {
|
|
4037
4303
|
worn[i] = total;
|
|
4038
4304
|
continue;
|
|
4039
4305
|
}
|
|
@@ -4058,7 +4324,32 @@ var GameDestruction = (() => {
|
|
|
4058
4324
|
emit({ ...base(o, src), type: "chip", part: p.spec.id, center, size: [cell.size[0], cell.size[1], cell.size[2]], rotation: q, fragments });
|
|
4059
4325
|
debris(o, p, p.mat.breakDebris, center, vec.scale(dir ?? [0, 1, 0], -1), 6, 2, src);
|
|
4060
4326
|
}
|
|
4327
|
+
if (p.spec.reinforcement) exposeRebar(o, p, src);
|
|
4061
4328
|
for (const cell of out) addBreach(o, p, toWorld(c, q, cell.center), cell.size[u] * cell.size[v], energy, dir, src);
|
|
4329
|
+
if (p.structural && !isLost(p)) {
|
|
4330
|
+
solveStructure(o);
|
|
4331
|
+
collapseCheck(o, src);
|
|
4332
|
+
}
|
|
4333
|
+
};
|
|
4334
|
+
const exposeRebar = (o, p, src) => {
|
|
4335
|
+
const r = p.spec.reinforcement;
|
|
4336
|
+
if (!r) return;
|
|
4337
|
+
const [u, v] = planeAxes(p.thin);
|
|
4338
|
+
const all = rebarBars(p.dims, p.thin, r.spacing);
|
|
4339
|
+
let bars;
|
|
4340
|
+
if (p.st.stripped) bars = all;
|
|
4341
|
+
else {
|
|
4342
|
+
bars = [];
|
|
4343
|
+
for (const cell of p.st.chipped ?? []) bars.push(...clipBarsToBox(all, u, v, cell.center, cell.size));
|
|
4344
|
+
const op = p.st.opening;
|
|
4345
|
+
if (op) {
|
|
4346
|
+
const lc = toLocal(p.pos, p.q, op.center);
|
|
4347
|
+
bars.push(...clipBarsToDisc(all, u, v, [lc[u], lc[v]], op.radius + 0.05));
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4350
|
+
const bow = clamp2(((p.st.stress ?? 0) - 1) / 0.5, 0, 1);
|
|
4351
|
+
if (bow > 0) bars = bars.flatMap((bar2, i) => bendBar(bar2, p.thin, bow * BAR_BOW, i));
|
|
4352
|
+
emit({ ...base(o, src), type: "expose", part: p.spec.id, bars: worldBars(o, p, bars) });
|
|
4062
4353
|
};
|
|
4063
4354
|
const openBreach = (o, p, center, total, energy, dir, src) => {
|
|
4064
4355
|
const [u, v] = planeAxes(p.thin);
|
|
@@ -4086,10 +4377,7 @@ var GameDestruction = (() => {
|
|
|
4086
4377
|
setStage(o, p, 2, { opening: { center: worldCenter, radius }, fragments }, src);
|
|
4087
4378
|
debris(o, p, p.mat.breakDebris, worldCenter, vec.scale(dir ?? [0, 1, 0], -1), 14, 3, src);
|
|
4088
4379
|
const reinforcement = p.spec.reinforcement;
|
|
4089
|
-
if (reinforcement)
|
|
4090
|
-
const bars = worldBars(o, p, clipBarsToDisc(rebarBars(p.dims, p.thin, reinforcement.spacing), u, v, [lc[u], lc[v]], radius + 0.05));
|
|
4091
|
-
if (bars.length > 0) emit({ ...base(o, src), type: "expose", part: p.spec.id, bars });
|
|
4092
|
-
}
|
|
4380
|
+
if (reinforcement) exposeRebar(o, p, src);
|
|
4093
4381
|
if (p.structural) solveStructure(o);
|
|
4094
4382
|
};
|
|
4095
4383
|
const stripPart = (o, p, reinforcement, src) => {
|
|
@@ -4101,8 +4389,8 @@ var GameDestruction = (() => {
|
|
|
4101
4389
|
p.st.burning = false;
|
|
4102
4390
|
p.rt.jet = false;
|
|
4103
4391
|
markDamaged(p);
|
|
4104
|
-
emit({ ...base(o, src), type: "expose", part: p.spec.id, bars: worldBars(o, p, bars) });
|
|
4105
4392
|
solveStructure(o);
|
|
4393
|
+
exposeRebar(o, p, src);
|
|
4106
4394
|
collapseCheck(o, src);
|
|
4107
4395
|
};
|
|
4108
4396
|
const unitFragmentPlan = (p, cap) => {
|
|
@@ -4156,7 +4444,7 @@ var GameDestruction = (() => {
|
|
|
4156
4444
|
const grain = p.spec.grain ? AXIS[p.spec.grain] : void 0;
|
|
4157
4445
|
const hitLocal = toLocal(c, q, hitW);
|
|
4158
4446
|
const unitPlan = p.spec.units ? unitFragmentPlan(p, maxFragments * UNIT_FRAGMENT_FACTOR) : [];
|
|
4159
|
-
const axis = style === "splinter" ? severAxis(p) : -1;
|
|
4447
|
+
const axis = style === "splinter" || style === "snap" ? severAxis(p) : -1;
|
|
4160
4448
|
const cutAt = axis < 0 ? void 0 : p.rt.cutAt ?? (origin ? hitLocal[axis] : void 0);
|
|
4161
4449
|
const plan = unitPlan.length > 0 ? unitPlan : planFragments({
|
|
4162
4450
|
style,
|
|
@@ -4228,7 +4516,7 @@ var GameDestruction = (() => {
|
|
|
4228
4516
|
};
|
|
4229
4517
|
const CHAIN_TRIGGER_OF = { ballistic: "shot", explosive: "explosion" };
|
|
4230
4518
|
const severAxis = (p) => {
|
|
4231
|
-
if (p.mat.fracture !== "splinter" || p.spec.shape.kind !== "box") return -1;
|
|
4519
|
+
if (p.mat.fracture !== "splinter" && p.mat.fracture !== "snap" || p.spec.shape.kind !== "box") return -1;
|
|
4232
4520
|
const d = p.dims;
|
|
4233
4521
|
const order = [0, 1, 2].sort((a, b) => d[b] - d[a]);
|
|
4234
4522
|
return d[order[0]] >= SEVER_ASPECT * d[order[1]] && d[order[0]] >= 3 * SEVER_BAND ? order[0] : -1;
|
|
@@ -4289,6 +4577,49 @@ var GameDestruction = (() => {
|
|
|
4289
4577
|
}
|
|
4290
4578
|
}
|
|
4291
4579
|
};
|
|
4580
|
+
const tearOf = (mat, kind) => {
|
|
4581
|
+
const h = mat.hits?.[kind];
|
|
4582
|
+
const tear = h?.tear ?? (kind === "ballistic" && mat.penetrationClass === "wood" ? "splinters" : "none");
|
|
4583
|
+
return { tear, joules: h?.tearJoules ?? TEAR_JOULES };
|
|
4584
|
+
};
|
|
4585
|
+
const tearAt = (o, p, kind, entry, exit, d, E, scale, src) => {
|
|
4586
|
+
const { tear, joules } = tearOf(p.mat, kind);
|
|
4587
|
+
if (tear === "none") return;
|
|
4588
|
+
const shot = kind === "ballistic";
|
|
4589
|
+
const n = shot ? exit ? clamp2(Math.round(E / joules), 1, 7) : 1 : clamp2(Math.floor(E / joules), 0, 5);
|
|
4590
|
+
if (n === 0) return;
|
|
4591
|
+
const fibre = tear === "lumps";
|
|
4592
|
+
const { q } = partXf(o, p);
|
|
4593
|
+
const along = (p.spec.grain ? AXIS[p.spec.grain] : void 0) ?? [0, 1, 2].sort((a, b) => p.dims[b] - p.dims[a])[0];
|
|
4594
|
+
const fragments = [];
|
|
4595
|
+
for (let i = 0; i < n; i++) {
|
|
4596
|
+
const back = !exit || i % 3 === 2;
|
|
4597
|
+
const len = scale * (fibre ? 1.2 + 1.2 * rnd() : 3 + 4 * rnd()), w = scale * (0.8 + 0.8 * rnd()), t = scale * (fibre ? 0.7 + 0.6 * rnd() : 0.4 + 0.4 * rnd());
|
|
4598
|
+
const size = [w, w, w];
|
|
4599
|
+
size[along] = len;
|
|
4600
|
+
size[(along + 1) % 3] = w;
|
|
4601
|
+
size[(along + 2) % 3] = t;
|
|
4602
|
+
const spread3 = [(rnd() - 0.5) * 0.8, (rnd() - 0.2) * 0.8, (rnd() - 0.5) * 0.8];
|
|
4603
|
+
const speed = shot ? back ? 1.5 + 2 * rnd() : 2 + 4 * rnd() : 0.8 + 1.2 * rnd();
|
|
4604
|
+
const v = vec.scale(vec.normalize(vec.add(back ? vec.scale(d, -1) : d, spread3)), speed);
|
|
4605
|
+
const mass = size[0] * size[1] * size[2] * p.mat.density;
|
|
4606
|
+
fragments.push({
|
|
4607
|
+
id: `${p.spec.id}#t${tears++}-${i}`,
|
|
4608
|
+
part: p.spec.id,
|
|
4609
|
+
material: p.spec.material,
|
|
4610
|
+
shape: fibre ? "chunk" : "splinter",
|
|
4611
|
+
center: back || !exit ? vec.madd(entry, d, -0.01) : vec.madd(exit, d, 0.01),
|
|
4612
|
+
size,
|
|
4613
|
+
rotation: q,
|
|
4614
|
+
velocity: v,
|
|
4615
|
+
inner: true,
|
|
4616
|
+
angularVelocity: [(rnd() - 0.5) * 30, (rnd() - 0.5) * 30, (rnd() - 0.5) * 30],
|
|
4617
|
+
mass
|
|
4618
|
+
});
|
|
4619
|
+
}
|
|
4620
|
+
const patch = [scale * 4, scale * 4, scale * 4];
|
|
4621
|
+
emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry, size: patch, rotation: q, fragments });
|
|
4622
|
+
};
|
|
4292
4623
|
const ballistic = (o, p, entry, n, d, E, caliber, pathLen, src, round = {}) => {
|
|
4293
4624
|
const mat = p.mat;
|
|
4294
4625
|
const piercing = round.piercing ?? 1;
|
|
@@ -4317,6 +4648,7 @@ var GameDestruction = (() => {
|
|
|
4317
4648
|
return { penetrated: false, exitEnergy: 0, damage: dmg2 };
|
|
4318
4649
|
}
|
|
4319
4650
|
if (p.layers.length > 0) spallOuter(o, p, entry, face, n, Math.max(0.03, caliber / 1e3 * 4), src);
|
|
4651
|
+
else if (mat.hits?.ballistic?.crater) crater(o, p, entry, n, clamp2(0.02 + Math.sqrt(E) * 15e-4, 0.02, 0.15), src);
|
|
4320
4652
|
const brittle = mat.ductility < 0.3;
|
|
4321
4653
|
const ratio = Ep / Math.max(thr, 1e-6);
|
|
4322
4654
|
const crackLen = clamp2(0.03 + ratio * 0.2, 0.03, 0.8);
|
|
@@ -4349,9 +4681,11 @@ var GameDestruction = (() => {
|
|
|
4349
4681
|
if (mat.fracture !== "shatter") addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
|
|
4350
4682
|
} else addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
|
|
4351
4683
|
debris(o, p, mat.hitDebris, entry, n, clamp2(Math.round(E / 60) + 2, 2, 14), clamp2(Math.sqrt(E) / 6, 1, 8), src);
|
|
4352
|
-
wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true);
|
|
4353
|
-
const
|
|
4354
|
-
|
|
4684
|
+
wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true, BULLET_JOINT_SPAN);
|
|
4685
|
+
const absorbed = penetrated && mat.ductility >= 0.5 && mat.fracture !== "tear" ? Math.min(E, thr) : E;
|
|
4686
|
+
const dmg = applyDamage(o, p, absorbed * DMG_PER_J * scale, "ballistic", entry, d, absorbed * 0.1, 12, src);
|
|
4687
|
+
if (!isLost(p)) tearAt(o, p, "ballistic", entry, penetrated ? exitPoint : void 0, d, E, caliber / 1e3, src);
|
|
4688
|
+
chipUnits(o, p, "ballistic", entry, penetrated ? Math.min(E, Math.max(thr, E * 0.5)) : E, d, Math.max(0.05, caliber / 1e3 * 8), src);
|
|
4355
4689
|
return { penetrated, exitEnergy: penetrated ? penMm !== void 0 ? E * (1 - thr / Ep) : E - thr / (hard ? piercing : 1) : 0, exitPoint, damage: dmg };
|
|
4356
4690
|
};
|
|
4357
4691
|
const melee = (o, p, kind, E, point, n, d, contactR, src) => {
|
|
@@ -4359,14 +4693,20 @@ var GameDestruction = (() => {
|
|
|
4359
4693
|
const thrMm = mat.penetration * p.thickness * 1e3;
|
|
4360
4694
|
const fragile = kind === "blunt" ? fragility(mat.ductility, p.thickness) : 1;
|
|
4361
4695
|
const Ec = E * fragile;
|
|
4696
|
+
const sheet = mat.ductility >= 0.5 && p.thickness <= THIN_SHEET_CRUSH;
|
|
4697
|
+
const fold = sheet ? Math.min(4, Math.sqrt(1e-3 / p.thickness)) : 1;
|
|
4698
|
+
const patch = sheet ? Math.min(contactR, THIN_SHEET_CONTACT) : contactR;
|
|
4362
4699
|
if (E > 0) {
|
|
4363
4700
|
if (kind === "blunt") {
|
|
4364
|
-
if (mat.ductility >= 0.5) addDent(o, p, point, n, Math.max(
|
|
4701
|
+
if (mat.ductility >= 0.5) addDent(o, p, point, n, Math.max(patch, 0.015), clamp2(E * 1e-4 * fold, 1e-3, sheet ? Math.min(0.06, Math.min(...p.dims) * 0.45) : 0.06), src);
|
|
4365
4702
|
else if (mat.ductility < 0.3) {
|
|
4366
4703
|
if (Ec >= 5) addCrack(o, p, point, n, clamp2(0.04 + Math.min(Ec, E * 6) * 8e-4, 0.04, 0.6), src);
|
|
4367
4704
|
} else if (E >= thrMm * 0.2) addDent(o, p, point, n, Math.max(contactR, 0.015), clamp2(E * 6e-5, 1e-3, 0.04), src);
|
|
4368
4705
|
} else if (mat.fracture === "tear") {
|
|
4369
4706
|
addHole(o, p, point, n, clamp2(0.02 + E * 5e-4, 0.02, 0.3), true, void 0, src);
|
|
4707
|
+
} else if (mat.ductility >= 0.3 && E >= thrMm) {
|
|
4708
|
+
addHole(o, p, point, n, clamp2(contactR, 0.01, 0.08), true, void 0, src);
|
|
4709
|
+
if (sheet) addDent(o, p, point, n, Math.max(patch * 0.6, 0.01), clamp2(E * 4e-5 * fold, 5e-4, 0.02), src);
|
|
4370
4710
|
} else if (mat.ductility >= 0.5) {
|
|
4371
4711
|
addDent(o, p, point, n, Math.max(contactR, 0.01), clamp2(E * 4e-5, 5e-4, 0.02), src);
|
|
4372
4712
|
}
|
|
@@ -4379,7 +4719,8 @@ var GameDestruction = (() => {
|
|
|
4379
4719
|
const scale = mat.damageScale?.[kind] ?? 1;
|
|
4380
4720
|
const done = applyDamage(o, p, Ec * DMG_PER_J * scale * (kind === "slash" ? p.cutFactor : 1), kind, point, d, E * 0.1, 12, src);
|
|
4381
4721
|
addBreach(o, p, point, breachAreaOf(p, done, false), E, d, src);
|
|
4382
|
-
if (kind === "blunt") chipUnits(o, p, point, E, d, Math.max(contactR, 0.03), src);
|
|
4722
|
+
if (kind === "blunt") chipUnits(o, p, "blunt", point, E, d, Math.max(contactR, 0.03), src);
|
|
4723
|
+
if (E > 0 && !isLost(p)) tearAt(o, p, kind, point, void 0, d, E, clamp2(contactR * 0.2, 6e-3, 0.02), src);
|
|
4383
4724
|
return done;
|
|
4384
4725
|
};
|
|
4385
4726
|
const blastPart = (o, p, point, energy, radius, src, res, reachAt) => {
|
|
@@ -4958,6 +5299,7 @@ var GameDestruction = (() => {
|
|
|
4958
5299
|
if (p.rt.stressT <= 0) {
|
|
4959
5300
|
p.rt.stressT = 0.5;
|
|
4960
5301
|
emit({ ...base(o), type: "stress", part: p.spec.id, stress, load: p.st.load ?? 0 });
|
|
5302
|
+
if (p.spec.reinforcement && (p.st.stripped || p.st.chipped?.length || p.st.opening)) exposeRebar(o, p);
|
|
4961
5303
|
}
|
|
4962
5304
|
applyDamage(o, p, overloadRate(stress) * p.st.maxHp * dt, "blunt", null, null, 5, 3);
|
|
4963
5305
|
} else if (stress > 0.8 && p.mat.ductility < 0.3 && p.rt.stressT <= 0 && p.st.cracks.length < 6) {
|
|
@@ -5174,6 +5516,18 @@ var GameDestruction = (() => {
|
|
|
5174
5516
|
const r = raycastInternal(origin, direction, maxDistance);
|
|
5175
5517
|
return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null;
|
|
5176
5518
|
},
|
|
5519
|
+
sweepBox(box, direction, distance, options2 = {}) {
|
|
5520
|
+
const d = vec.normalize(direction);
|
|
5521
|
+
const ignored = options2.ignore === void 0 ? void 0 : objects.get(options2.ignore);
|
|
5522
|
+
const ignore = ignored ? new Set(ignored.parts.map((p) => `${ignored.id}\0${p.spec.id}`)) : void 0;
|
|
5523
|
+
let best = null;
|
|
5524
|
+
for (const origin of sweepOrigins(box, d, options2.spacing ?? 0.2)) {
|
|
5525
|
+
const r = raycastInternal(origin, d, distance + SWEEP_BACK, ignore);
|
|
5526
|
+
if (!r || best && r.distance >= best.distance) continue;
|
|
5527
|
+
best = { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: Math.max(0, r.distance - SWEEP_BACK) };
|
|
5528
|
+
}
|
|
5529
|
+
return best;
|
|
5530
|
+
},
|
|
5177
5531
|
shoot(origin, direction, energy, caliber, source, round) {
|
|
5178
5532
|
const extras = typeof round === "number" ? { piercing: round } : round ?? {};
|
|
5179
5533
|
return withCollapses(run(() => {
|
|
@@ -5818,7 +6172,12 @@ var GameDestruction = (() => {
|
|
|
5818
6172
|
cactus: "cactus",
|
|
5819
6173
|
flesh_fruit: "fruit",
|
|
5820
6174
|
wax: "wax",
|
|
5821
|
-
soil: "soil"
|
|
6175
|
+
soil: "soil",
|
|
6176
|
+
asphalt: "asphalt",
|
|
6177
|
+
sand: "sand",
|
|
6178
|
+
gravel: "gravel",
|
|
6179
|
+
turf: "turf",
|
|
6180
|
+
mortar: "mortar"
|
|
5822
6181
|
},
|
|
5823
6182
|
partStatus: { intact: "intact", damaged: "damaged", collapsed: "collapsed", broken: "broken", melted: "melted", ashes: "ashes" },
|
|
5824
6183
|
jointKinds: {
|
|
@@ -5909,7 +6268,12 @@ var GameDestruction = (() => {
|
|
|
5909
6268
|
cactus: "cacto",
|
|
5910
6269
|
flesh_fruit: "fruta",
|
|
5911
6270
|
wax: "cera",
|
|
5912
|
-
soil: "terra"
|
|
6271
|
+
soil: "terra",
|
|
6272
|
+
asphalt: "asfalto",
|
|
6273
|
+
sand: "areia",
|
|
6274
|
+
gravel: "brita",
|
|
6275
|
+
turf: "grama",
|
|
6276
|
+
mortar: "argamassa"
|
|
5913
6277
|
},
|
|
5914
6278
|
partStatus: { intact: "intacto", damaged: "danificado", collapsed: "desabado", broken: "quebrado", melted: "derretido", ashes: "cinzas" },
|
|
5915
6279
|
jointKinds: {
|