@adatechnology/game-destruction-three 0.7.1 → 0.7.2
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 +998 -366
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +2 -48
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.global.js
CHANGED
|
@@ -1361,77 +1361,77 @@ var GameDestructionThree = (() => {
|
|
|
1361
1361
|
}));
|
|
1362
1362
|
}
|
|
1363
1363
|
function spawnPuff(pool, random, init) {
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
return
|
|
1394
|
-
}
|
|
1395
|
-
function ageOrKeep2(
|
|
1396
|
-
|
|
1397
|
-
return
|
|
1398
|
-
}
|
|
1399
|
-
function moveOnRing(
|
|
1364
|
+
const puff3 = pool.acquire();
|
|
1365
|
+
puff3.x = init.x ?? 0;
|
|
1366
|
+
puff3.y = init.y ?? 0;
|
|
1367
|
+
puff3.z = init.z ?? 0;
|
|
1368
|
+
puff3.vx = init.vx ?? 0;
|
|
1369
|
+
puff3.vy = init.vy ?? 0;
|
|
1370
|
+
puff3.vz = init.vz ?? 0;
|
|
1371
|
+
puff3.s0 = init.s0 ?? 0.2;
|
|
1372
|
+
puff3.s1 = init.s1 ?? 1;
|
|
1373
|
+
puff3.sg = init.sg ?? 0.1;
|
|
1374
|
+
puff3.gk = init.gk ?? 6;
|
|
1375
|
+
puff3.life = init.life ?? 3;
|
|
1376
|
+
puff3.t = 0;
|
|
1377
|
+
puff3.h0 = init.h0 ?? 0;
|
|
1378
|
+
puff3.hl = init.hl ?? 0.4;
|
|
1379
|
+
puff3.drag = init.drag ?? 3;
|
|
1380
|
+
puff3.buoy = init.buoy ?? 0.5;
|
|
1381
|
+
puff3.grav = init.grav ?? 0;
|
|
1382
|
+
puff3.kind = init.kind ?? 0;
|
|
1383
|
+
puff3.seed = random.next();
|
|
1384
|
+
puff3.wind = init.wind ?? 1;
|
|
1385
|
+
puff3.color = init.color ?? SMOKE_COLORS.grey;
|
|
1386
|
+
puff3.ring = init.ring ?? null;
|
|
1387
|
+
puff3.ph = init.ph ?? 0;
|
|
1388
|
+
puff3.th = init.th ?? 0;
|
|
1389
|
+
puff3.rng = random;
|
|
1390
|
+
puff3.age = 0;
|
|
1391
|
+
puff3.heat = 0;
|
|
1392
|
+
puff3.size = 0;
|
|
1393
|
+
return puff3;
|
|
1394
|
+
}
|
|
1395
|
+
function ageOrKeep2(puff3, dt) {
|
|
1396
|
+
puff3.t += dt;
|
|
1397
|
+
return puff3.t < puff3.life;
|
|
1398
|
+
}
|
|
1399
|
+
function moveOnRing(puff3, ring2, wind) {
|
|
1400
1400
|
const ringTime = ring2.t;
|
|
1401
1401
|
const centerY = ring2.y0 + ring2.rise * (1 - Math.exp(-ringTime * ring2.rk));
|
|
1402
1402
|
const majorRadius = ring2.R0 + (ring2.R1 - ring2.R0) * (1 - Math.exp(-ringTime * 1.6));
|
|
1403
|
-
const theta =
|
|
1403
|
+
const theta = puff3.th + ringTime * ring2.roll;
|
|
1404
1404
|
const minorRadius = ring2.r * (0.8 + 0.4 * Math.min(1, ringTime));
|
|
1405
1405
|
const radius = majorRadius + minorRadius * Math.cos(theta);
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
}
|
|
1410
|
-
function moveFree(
|
|
1411
|
-
const damping = Math.exp(-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
if (
|
|
1420
|
-
|
|
1421
|
-
if (
|
|
1406
|
+
puff3.x = ring2.x + Math.cos(puff3.ph) * radius + wind.x * ringTime * 0.6;
|
|
1407
|
+
puff3.z = ring2.z + Math.sin(puff3.ph) * radius + wind.z * ringTime * 0.6;
|
|
1408
|
+
puff3.y = centerY + minorRadius * Math.sin(theta);
|
|
1409
|
+
}
|
|
1410
|
+
function moveFree(puff3, dt, age, heat, wind) {
|
|
1411
|
+
const damping = Math.exp(-puff3.drag * dt);
|
|
1412
|
+
puff3.vx *= damping;
|
|
1413
|
+
puff3.vy *= damping;
|
|
1414
|
+
puff3.vz *= damping;
|
|
1415
|
+
puff3.vy += (puff3.buoy * (heat > 0 ? 1.6 : 1) - puff3.grav) * dt;
|
|
1416
|
+
puff3.x += (puff3.vx + wind.x * puff3.wind * age) * dt;
|
|
1417
|
+
puff3.y += puff3.vy * dt;
|
|
1418
|
+
puff3.z += (puff3.vz + wind.z * puff3.wind * age) * dt;
|
|
1419
|
+
if (puff3.y < puff3.s0 * FLOOR_FRACTION) {
|
|
1420
|
+
puff3.y = puff3.s0 * FLOOR_FRACTION;
|
|
1421
|
+
if (puff3.vy < 0) puff3.vy *= FLOOR_BOUNCE;
|
|
1422
1422
|
}
|
|
1423
1423
|
}
|
|
1424
1424
|
function updatePuffs(pool, dt, wind) {
|
|
1425
1425
|
pool.compact(ageOrKeep2, dt);
|
|
1426
|
-
for (const
|
|
1427
|
-
const age =
|
|
1428
|
-
const heat =
|
|
1429
|
-
if (
|
|
1430
|
-
else moveFree(
|
|
1431
|
-
const size =
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1426
|
+
for (const puff3 of pool.items) {
|
|
1427
|
+
const age = puff3.t / puff3.life;
|
|
1428
|
+
const heat = puff3.h0 > 0 ? puff3.h0 * Math.pow(Math.max(0, 1 - puff3.t / puff3.hl), 1.25) : 0;
|
|
1429
|
+
if (puff3.ring) moveOnRing(puff3, puff3.ring, wind);
|
|
1430
|
+
else moveFree(puff3, dt, age, heat, wind);
|
|
1431
|
+
const size = puff3.s0 + (puff3.s1 - puff3.s0) * (1 - Math.exp(-puff3.t * puff3.gk)) + puff3.sg * Math.min(puff3.t, GROWTH_CAP_SECONDS);
|
|
1432
|
+
puff3.size = size * Math.min(1, puff3.t * ARRIVAL_FRAME + ARRIVAL_BASE);
|
|
1433
|
+
puff3.age = age;
|
|
1434
|
+
puff3.heat = heat;
|
|
1435
1435
|
}
|
|
1436
1436
|
}
|
|
1437
1437
|
var GROUND_LIFT = 0.02;
|
|
@@ -1488,9 +1488,9 @@ var GameDestructionThree = (() => {
|
|
|
1488
1488
|
var HOT_GLOW_COLOR = [1, 0.45, 0.12];
|
|
1489
1489
|
function addPuff(core, random, init) {
|
|
1490
1490
|
core.spawned.puffs++;
|
|
1491
|
-
const
|
|
1492
|
-
core.trace?.puff?.(
|
|
1493
|
-
return
|
|
1491
|
+
const puff3 = spawnPuff(core.puffs, random, init);
|
|
1492
|
+
core.trace?.puff?.(puff3);
|
|
1493
|
+
return puff3;
|
|
1494
1494
|
}
|
|
1495
1495
|
function addSpark(core, init) {
|
|
1496
1496
|
core.spawned.sparks++;
|
|
@@ -1672,6 +1672,7 @@ var GameDestructionThree = (() => {
|
|
|
1672
1672
|
var neg = call("neg");
|
|
1673
1673
|
var abs = call("abs");
|
|
1674
1674
|
var sqrt = call("sqrt");
|
|
1675
|
+
var exp = call("exp");
|
|
1675
1676
|
var sin = call("sin");
|
|
1676
1677
|
var cos = call("cos");
|
|
1677
1678
|
var atan2 = call("atan2");
|
|
@@ -1717,10 +1718,12 @@ var GameDestructionThree = (() => {
|
|
|
1717
1718
|
var INDEX = { $: "index" };
|
|
1718
1719
|
var QUALITY = { $: "quality" };
|
|
1719
1720
|
var FRESH = { $: "fresh" };
|
|
1721
|
+
var DIRECTION = { $: "direction" };
|
|
1720
1722
|
var CAMERA_POSITION = { $: "cameraPosition" };
|
|
1721
1723
|
var burst = (system, count, spawn2) => ({ op: "burst", system, count, spawn: spawn2 });
|
|
1722
1724
|
var spawn = (system, options) => ({ op: "spawn", system, spawn: options });
|
|
1723
1725
|
var emit = (key, system, rate, options) => ({ op: "emit", key, system, rate, spawn: options });
|
|
1726
|
+
var mesh = (options) => ({ op: "mesh", spawn: options });
|
|
1724
1727
|
var debris = (options) => ({ op: "debris", spawn: options });
|
|
1725
1728
|
var decal = (...args) => ({ op: "decal", args });
|
|
1726
1729
|
var ring = (...args) => ({ op: "ring", args });
|
|
@@ -2732,6 +2735,241 @@ var GameDestructionThree = (() => {
|
|
|
2732
2735
|
)
|
|
2733
2736
|
]
|
|
2734
2737
|
};
|
|
2738
|
+
var SPOTS_X = [-3, 1, 5];
|
|
2739
|
+
var SPOTS_Z = [-1, -2.4, 0.4];
|
|
2740
|
+
var FOG_AND_ASH = {
|
|
2741
|
+
id: "fog_and_ash",
|
|
2742
|
+
pageId: "neblina",
|
|
2743
|
+
team: "world",
|
|
2744
|
+
budget: { particles: 120, lights: 1 },
|
|
2745
|
+
loop: 0,
|
|
2746
|
+
view: { eye: [3, 1.8, 7.5], target: [-3, 1.2, -1] },
|
|
2747
|
+
setup: [
|
|
2748
|
+
cue("fog", { density: 0.075 }),
|
|
2749
|
+
cue("lamp_cone", { visible: true }),
|
|
2750
|
+
cue("zombie_visible", { index: -1, visible: false }),
|
|
2751
|
+
repeat(
|
|
2752
|
+
SPOTS_X.length,
|
|
2753
|
+
set("turn", rnd(-0.6, 0.6)),
|
|
2754
|
+
behavior("walkers", "place", { index: INDEX, x: pick(SPOTS_X, INDEX), z: pick(SPOTS_Z, INDEX), facing: variable("turn") })
|
|
2755
|
+
)
|
|
2756
|
+
],
|
|
2757
|
+
timeline: [],
|
|
2758
|
+
tick: [
|
|
2759
|
+
emit("fog", "normal", 5, { p: [rnd(-14, 10), rnd(0.2, 1.1), rnd(-3, 8)], v: [rnd(0.15, 0.35), 0, rnd(-0.05, 0.05)], sp: 0, life: [9, 13], size: [3, 5], grow: 1.4, c0: 8227488, a: 0.13, fi: 0.35 }),
|
|
2760
|
+
emit("ash", "normal", 14, { p: [rnd(-10, 8), rnd(4, 6), rnd(-3, 7)], v: [rnd(0.1, 0.4), -0.35, rnd(-0.1, 0.1)], sp: [0.05, 0.15], life: [8, 12], size: [0.025, 0.04], c0: 10525328, a: 0.75, fi: 0.1, gnd: 1 })
|
|
2761
|
+
]
|
|
2762
|
+
};
|
|
2763
|
+
var RAIN_CAPACITY = 4e3;
|
|
2764
|
+
var FALL_SPEED = 15;
|
|
2765
|
+
var WIND_PER_FALL = 0.07;
|
|
2766
|
+
var STREAK_SLANT = 0.04;
|
|
2767
|
+
var STREAK_LENGTH = 0.6;
|
|
2768
|
+
var BOX_X = [-15, 15];
|
|
2769
|
+
var BOX_Z = [-6, 16];
|
|
2770
|
+
var START_HEIGHT = [0, 16];
|
|
2771
|
+
var REENTRY_HEIGHT = [14, 17];
|
|
2772
|
+
var SPLASH_CHANCE = 0.35;
|
|
2773
|
+
var SPLASH_RANGE = 12;
|
|
2774
|
+
var SPRITE_CHANCE = 0.5;
|
|
2775
|
+
var UP9 = [0, 1, 0];
|
|
2776
|
+
var WORKSHOP_PUDDLES = [
|
|
2777
|
+
[-1.5, 2.2, 1.6, 0.9],
|
|
2778
|
+
[3, 3.6, 1.1, 0.7],
|
|
2779
|
+
[-6, 3.2, 1.3, 0.8],
|
|
2780
|
+
[1.4, -2.2, 0.9, 0.5]
|
|
2781
|
+
];
|
|
2782
|
+
var inPuddle = (puddles, x, z) => puddles.some((p) => ((x - p[0]) / p[2]) ** 2 + ((z - p[1]) / p[3]) ** 2 < 1);
|
|
2783
|
+
var RainField = class {
|
|
2784
|
+
constructor(engine) {
|
|
2785
|
+
__publicField2(this, "engine", engine);
|
|
2786
|
+
__publicField2(this, "positions", new Float32Array(RAIN_CAPACITY * 6));
|
|
2787
|
+
__publicField2(this, "count", 0);
|
|
2788
|
+
__publicField2(this, "wind", 1);
|
|
2789
|
+
__publicField2(this, "on", false);
|
|
2790
|
+
__publicField2(this, "centerX", 0);
|
|
2791
|
+
__publicField2(this, "centerZ", 0);
|
|
2792
|
+
__publicField2(this, "puddles", WORKSHOP_PUDDLES);
|
|
2793
|
+
__publicField2(this, "puddleAt");
|
|
2794
|
+
}
|
|
2795
|
+
/** `initRain` (W321): `count` streaks (thinned by the quality), each drawn at a random place in the box. */
|
|
2796
|
+
init(count, wind) {
|
|
2797
|
+
const { random } = this.engine;
|
|
2798
|
+
this.count = Math.min(RAIN_CAPACITY, Math.round(count * this.engine.context.quality.mult));
|
|
2799
|
+
this.wind = wind;
|
|
2800
|
+
this.on = true;
|
|
2801
|
+
for (let index = 0; index < this.count; index++) {
|
|
2802
|
+
const offset = index * 6;
|
|
2803
|
+
const x = random.between(BOX_X[0], BOX_X[1]);
|
|
2804
|
+
const y = random.between(START_HEIGHT[0], START_HEIGHT[1]);
|
|
2805
|
+
const z = random.between(BOX_Z[0], BOX_Z[1]);
|
|
2806
|
+
this.set(offset, x, y, z);
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
/**
|
|
2810
|
+
* What a game does with the field every frame: the box follows the camera (`centerX`, `centerZ`), the streaks thin or thicken to `count` (a new streak
|
|
2811
|
+
* starts at a random place of the box, as `init` draws it) and the wind slants them. The golden never calls it.
|
|
2812
|
+
*/
|
|
2813
|
+
drive(count, wind, centerX, centerZ) {
|
|
2814
|
+
const { random } = this.engine;
|
|
2815
|
+
const target = Math.max(0, Math.min(RAIN_CAPACITY, Math.round(count * this.engine.context.quality.mult)));
|
|
2816
|
+
this.wind = wind;
|
|
2817
|
+
this.centerX = centerX;
|
|
2818
|
+
this.centerZ = centerZ;
|
|
2819
|
+
this.on = target > 0;
|
|
2820
|
+
for (let index = this.count; index < target; index++) {
|
|
2821
|
+
this.set(index * 6, random.between(BOX_X[0], BOX_X[1]) + centerX, random.between(START_HEIGHT[0], START_HEIGHT[1]), random.between(BOX_Z[0], BOX_Z[1]) + centerZ);
|
|
2822
|
+
}
|
|
2823
|
+
this.count = target;
|
|
2824
|
+
}
|
|
2825
|
+
/** `updateRain` (W322-329). `camera` is where the eye is; `splash` lets the drops that land leave a splash. */
|
|
2826
|
+
update(dt, splash, camera2) {
|
|
2827
|
+
if (!this.on) return;
|
|
2828
|
+
const { random, context } = this.engine;
|
|
2829
|
+
const positions = this.positions;
|
|
2830
|
+
const fall = FALL_SPEED * dt;
|
|
2831
|
+
const slant = this.wind * fall * WIND_PER_FALL;
|
|
2832
|
+
const reach = SPLASH_RANGE / (1 + context.quality.level);
|
|
2833
|
+
for (let index = 0; index < this.count; index++) {
|
|
2834
|
+
const o = index * 6;
|
|
2835
|
+
positions[o] += slant;
|
|
2836
|
+
positions[o + 3] += slant;
|
|
2837
|
+
positions[o + 1] -= fall;
|
|
2838
|
+
positions[o + 4] -= fall;
|
|
2839
|
+
const ground = context.groundAt(positions[o], positions[o + 2]);
|
|
2840
|
+
if (positions[o + 4] < ground) {
|
|
2841
|
+
const x = positions[o];
|
|
2842
|
+
const z = positions[o + 2];
|
|
2843
|
+
if (splash && random.next() < SPLASH_CHANCE) {
|
|
2844
|
+
const distance = Math.hypot(x - camera2[0], z - camera2[2]);
|
|
2845
|
+
if (distance < reach) {
|
|
2846
|
+
if (random.next() < SPRITE_CHANCE) {
|
|
2847
|
+
this.engine.spawn("normal", { p: [x, ground + 0.01, z], dir: UP9, cone: 0.6, sp: [0.6, 1.3], life: [0.18, 0.3], size: 0.035, c0: 12110044, a: 0.6, g: 9.8, fi: 0 });
|
|
2848
|
+
}
|
|
2849
|
+
if (this.puddleAt ? this.puddleAt(x, z) : inPuddle(this.puddles, x, z)) {
|
|
2850
|
+
this.engine.ring([[x, ground + 0.012, z], 0.01, random.between(0.12, 0.25), random.between(0.4, 0.6), 6978192]);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
const nx = random.between(BOX_X[0], BOX_X[1]) + this.centerX;
|
|
2855
|
+
const ny = random.between(REENTRY_HEIGHT[0], REENTRY_HEIGHT[1]);
|
|
2856
|
+
const nz = random.between(BOX_Z[0], BOX_Z[1]) + this.centerZ;
|
|
2857
|
+
this.set(o, nx, ny, nz);
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
/** `rain.visible = false; RN.on = false` (W440): the field stops; the streaks stay where they were. */
|
|
2862
|
+
clear() {
|
|
2863
|
+
this.on = false;
|
|
2864
|
+
}
|
|
2865
|
+
set(offset, x, y, z) {
|
|
2866
|
+
const positions = this.positions;
|
|
2867
|
+
positions[offset] = x;
|
|
2868
|
+
positions[offset + 1] = y;
|
|
2869
|
+
positions[offset + 2] = z;
|
|
2870
|
+
positions[offset + 3] = x + this.wind * STREAK_SLANT;
|
|
2871
|
+
positions[offset + 4] = y - STREAK_LENGTH;
|
|
2872
|
+
positions[offset + 5] = z;
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
var DROPS = [900, 2200, 4e3];
|
|
2876
|
+
var SLANT = [0.3, 1.2, 4.5];
|
|
2877
|
+
var STORM = 2;
|
|
2878
|
+
var FLASH_STEPS = ite(lt(variable("flash"), 0.08), 1, ite(lt(variable("flash"), 0.16), 0.2, ite(lt(variable("flash"), 0.26), 0.8, 0)));
|
|
2879
|
+
var RAIN_AND_PUDDLES = {
|
|
2880
|
+
id: "rain_and_puddles",
|
|
2881
|
+
pageId: "chuva",
|
|
2882
|
+
team: "world",
|
|
2883
|
+
params: { id: "intensity", options: ["drizzle", "rain", "storm"], default: 1 },
|
|
2884
|
+
budget: { particles: 4e3, decals: 4 },
|
|
2885
|
+
loop: 0,
|
|
2886
|
+
view: { eye: [2, 2, 7], target: [-1, 0.6, 1] },
|
|
2887
|
+
setup: [
|
|
2888
|
+
cue("lamp_cone", { visible: true }),
|
|
2889
|
+
...WORKSHOP_PUDDLES.map(([x, z, radiusX, radiusZ]) => decal(x, 0, z, radiusX * 2, 790550, { grow: 0, life: 1e6, ar: radiusZ / radiusX }))
|
|
2890
|
+
],
|
|
2891
|
+
timeline: [
|
|
2892
|
+
behavior("rain", "init", { count: ite(eq(PARAM, 0), DROPS[0], ite(eq(PARAM, 1), DROPS[1], DROPS[2])), wind: ite(eq(PARAM, 0), SLANT[0], ite(eq(PARAM, 1), SLANT[1], SLANT[2])) }),
|
|
2893
|
+
set("nextStrike", rnd(2, 4)),
|
|
2894
|
+
set("flash", -1)
|
|
2895
|
+
],
|
|
2896
|
+
tick: [
|
|
2897
|
+
behavior("rain", "update", { dt: DELTA, splash: gt(PARAM, 0) }),
|
|
2898
|
+
when(eq(PARAM, STORM), [
|
|
2899
|
+
when(gt(TIME, variable("nextStrike")), [set("nextStrike", add(TIME, rnd(3.5, 6))), set("flash", 0)]),
|
|
2900
|
+
when(ge(variable("flash"), 0), [
|
|
2901
|
+
set("flash", add(variable("flash"), DELTA)),
|
|
2902
|
+
set("light", FLASH_STEPS),
|
|
2903
|
+
cue("lightning", { intensity: variable("light") }),
|
|
2904
|
+
screen({ max: { white: mul(variable("light"), 0.12) } }),
|
|
2905
|
+
when(gt(variable("flash"), 0.4), [set("flash", -1), cue("lightning", { intensity: 0 })])
|
|
2906
|
+
]),
|
|
2907
|
+
emit("sheet", "normal", 2.5, { p: [-12, 2.5, rnd(-1, 8)], box: [0, 2, 0], v: [7, -0.5, 0], sp: 0, life: [3, 4], size: [3, 5], grow: 1.3, c0: 9083568, a: 0.06, fi: 0.3 })
|
|
2908
|
+
])
|
|
2909
|
+
]
|
|
2910
|
+
};
|
|
2911
|
+
var CAR_ORIGIN2 = [5.6, 0, 0.8];
|
|
2912
|
+
var CAR_ROTATION2 = [0, -0.4, 0];
|
|
2913
|
+
var carPoint = (x, y, z) => localToWorld(CAR_ORIGIN2, CAR_ROTATION2, [x, y, z]);
|
|
2914
|
+
var carDirection = (from, to) => normalized([to[0] - from[0], to[1] - from[1], to[2] - from[2]]);
|
|
2915
|
+
var BEAM_FROM = carPoint(0, 0.74, 2.15);
|
|
2916
|
+
var BEAM_DIRECTION = carDirection(BEAM_FROM, carPoint(0, 0.74, 3.15));
|
|
2917
|
+
var BEAM_SIDE = [BEAM_DIRECTION[2], 0, -BEAM_DIRECTION[0]];
|
|
2918
|
+
var WALKERS = 6;
|
|
2919
|
+
var WALK_SPEED2 = 0.7;
|
|
2920
|
+
var DROPS2 = 1800;
|
|
2921
|
+
var SLANT2 = 0.8;
|
|
2922
|
+
var startWalking = [
|
|
2923
|
+
set("spot", query("car", "point", rnd(-2, 2), 0, rnd(8, 18))),
|
|
2924
|
+
set("goal", query("car", "point", rnd(-0.6, 0.6), 0, 2.6)),
|
|
2925
|
+
behavior("walkers", "place", { index: INDEX, x: pick(variable("spot"), 0), z: pick(variable("spot"), 2), facing: 0 }),
|
|
2926
|
+
behavior("walkers", "walk", { index: INDEX, to: variable("goal"), speed: WALK_SPEED2 })
|
|
2927
|
+
];
|
|
2928
|
+
var HEADLIGHTS_IN_RAIN = {
|
|
2929
|
+
id: "headlights_in_rain",
|
|
2930
|
+
pageId: "farol",
|
|
2931
|
+
team: "vehicles",
|
|
2932
|
+
budget: { particles: 600, lights: 2 },
|
|
2933
|
+
loop: 0,
|
|
2934
|
+
view: { eye: [-2.5, 2, 5.5], target: [4, 1, 6] },
|
|
2935
|
+
setup: [
|
|
2936
|
+
cue("fog", { density: 0.05 }),
|
|
2937
|
+
cue("headlights", { on: true, intensity: 2.4, color: 16773584 }),
|
|
2938
|
+
behavior("rain", "init", { count: DROPS2, wind: SLANT2 }),
|
|
2939
|
+
repeat(WALKERS, ...startWalking)
|
|
2940
|
+
],
|
|
2941
|
+
timeline: [],
|
|
2942
|
+
tick: [
|
|
2943
|
+
behavior("rain", "update", { dt: DELTA, splash: true }),
|
|
2944
|
+
emit(
|
|
2945
|
+
"lit",
|
|
2946
|
+
"streak",
|
|
2947
|
+
600,
|
|
2948
|
+
local(
|
|
2949
|
+
"depth",
|
|
2950
|
+
rnd(1, 13),
|
|
2951
|
+
local(
|
|
2952
|
+
"spread",
|
|
2953
|
+
mul(variable("depth"), 0.33, sqrt(rand())),
|
|
2954
|
+
local(
|
|
2955
|
+
"turn",
|
|
2956
|
+
rnd(0, 6.283),
|
|
2957
|
+
local("base", vadd(BEAM_FROM, vscale(BEAM_DIRECTION, variable("depth")), vscale(BEAM_SIDE, mul(cos(variable("turn")), variable("spread")))), {
|
|
2958
|
+
p: vwith(variable("base"), 1, add(vy(variable("base")), mul(sin(variable("turn")), variable("spread"), 0.6))),
|
|
2959
|
+
v: [0.8, -14, 0],
|
|
2960
|
+
sp: 0,
|
|
2961
|
+
life: 0.06,
|
|
2962
|
+
len: 0.035,
|
|
2963
|
+
c0: 13622512,
|
|
2964
|
+
a: 0.9
|
|
2965
|
+
})
|
|
2966
|
+
)
|
|
2967
|
+
)
|
|
2968
|
+
)
|
|
2969
|
+
),
|
|
2970
|
+
repeat(WALKERS, when(not(query("walkers", "is_walking", INDEX)), startWalking))
|
|
2971
|
+
]
|
|
2972
|
+
};
|
|
2735
2973
|
var YAW = -Math.PI / 2;
|
|
2736
2974
|
var COS = Math.cos(YAW);
|
|
2737
2975
|
var SIN = Math.sin(YAW);
|
|
@@ -2759,10 +2997,6 @@ var GameDestructionThree = (() => {
|
|
|
2759
2997
|
fireLight(0, [vx(variable("contact")), 0.34, vz(variable("contact"))], 1.6, mul(TIME, 3))
|
|
2760
2998
|
]
|
|
2761
2999
|
};
|
|
2762
|
-
var CAR_ORIGIN2 = [5.6, 0, 0.8];
|
|
2763
|
-
var CAR_ROTATION2 = [0, -0.4, 0];
|
|
2764
|
-
var carPoint = (x, y, z) => localToWorld(CAR_ORIGIN2, CAR_ROTATION2, [x, y, z]);
|
|
2765
|
-
var carDirection = (from, to) => normalized([to[0] - from[0], to[1] - from[1], to[2] - from[2]]);
|
|
2766
3000
|
var HOOD = carPoint(0, 1.02, 1.4);
|
|
2767
3001
|
var EXHAUST = carPoint(0.5, 0.3, -2.2);
|
|
2768
3002
|
var EXHAUST_DIRECTION = carDirection(EXHAUST, carPoint(0.5, 0.3, -3));
|
|
@@ -2796,7 +3030,7 @@ var GameDestructionThree = (() => {
|
|
|
2796
3030
|
], [fireLightOff(0)])
|
|
2797
3031
|
]
|
|
2798
3032
|
};
|
|
2799
|
-
var
|
|
3033
|
+
var UP10 = [0, 1, 0];
|
|
2800
3034
|
var doorVelocity = (side) => {
|
|
2801
3035
|
const out = carPoint(side * 4, 3, 0.3);
|
|
2802
3036
|
const centre = carPoint(0, 0, 0.3);
|
|
@@ -2806,7 +3040,7 @@ var GameDestructionThree = (() => {
|
|
|
2806
3040
|
call2("explode", vadd(query("car", "position"), [0, 0.6, 0]), 1.8, 2759188),
|
|
2807
3041
|
cue("car_burnt"),
|
|
2808
3042
|
behavior("car", "launch", { rise: 4.5, spin: 0.9 }),
|
|
2809
|
-
repeat(scaled(30), debris({ p: vadd(query("car", "position"), [0, 1.3, 0]), dir:
|
|
3043
|
+
repeat(scaled(30), debris({ p: vadd(query("car", "position"), [0, 1.3, 0]), dir: UP10, cone: 1.3, sp: [2, 6], size: [0.06, 6e-3, 0.06], c: 11061464, life: 20 })),
|
|
2810
3044
|
debris({ p: carPoint(0, 1, 1.4), v: [rnd(-1, 1), 9, rnd(-1, 1)], sp: 0, size: [1.6, 0.06, 1.2], c: 3808536, spin: 6, life: 20, bounce: 0.2 }),
|
|
2811
3045
|
...[-1, 1].map((side) => debris({ p: carPoint(side * 0.95, 0.7, 0.3), v: doorVelocity(side), sp: 0, size: [0.06, 0.7, 1.1], c: 3808536, spin: 5, life: 20, bounce: 0.2 })),
|
|
2812
3046
|
debris({ p: carPoint(0.95, 0.38, 1.35), v: [3, 4, 2], sp: 0, size: [0.3, 0.76, 0.76], c: 1118481, spin: 8, life: 20, bounce: 0.4 })
|
|
@@ -2976,7 +3210,7 @@ var GameDestructionThree = (() => {
|
|
|
2976
3210
|
])
|
|
2977
3211
|
]
|
|
2978
3212
|
};
|
|
2979
|
-
var
|
|
3213
|
+
var WALKERS2 = 6;
|
|
2980
3214
|
var NEAR = 9;
|
|
2981
3215
|
var RANGE = 7;
|
|
2982
3216
|
var RESTING_BPM = 70;
|
|
@@ -2992,7 +3226,7 @@ var GameDestructionThree = (() => {
|
|
|
2992
3226
|
setup: [
|
|
2993
3227
|
cue("zombie_visible", { index: -1, visible: false }),
|
|
2994
3228
|
repeat(
|
|
2995
|
-
|
|
3229
|
+
WALKERS2,
|
|
2996
3230
|
set("startX", rnd(-4, 4)),
|
|
2997
3231
|
set("startZ", sub(rnd(-4, -2), mul(INDEX, 0.6))),
|
|
2998
3232
|
behavior("walkers", "place", { index: INDEX, x: variable("startX"), z: variable("startZ"), facing: 0 }),
|
|
@@ -3002,7 +3236,7 @@ var GameDestructionThree = (() => {
|
|
|
3002
3236
|
timeline: [],
|
|
3003
3237
|
tick: [
|
|
3004
3238
|
set("nearest", 99),
|
|
3005
|
-
repeat(
|
|
3239
|
+
repeat(WALKERS2, set("nearest", min(variable("nearest"), vdist(walkerPoint, CAMERA_POSITION)))),
|
|
3006
3240
|
set("fear", clamp(div(sub(NEAR, variable("nearest")), RANGE), 0, 1)),
|
|
3007
3241
|
set("bpm", add(RESTING_BPM, mul(BPM_RISE, variable("fear")))),
|
|
3008
3242
|
when(lt(mod(div(mul(TIME, variable("bpm")), 60), 1), div(mul(DELTA, variable("bpm")), 60)), [screen({ set: { beat: add(0.4, mul(0.6, variable("fear"))) } })]),
|
|
@@ -3069,7 +3303,7 @@ var GameDestructionThree = (() => {
|
|
|
3069
3303
|
]
|
|
3070
3304
|
};
|
|
3071
3305
|
var FACING4 = [0, 0, 1];
|
|
3072
|
-
var
|
|
3306
|
+
var UP11 = [0, 1, 0];
|
|
3073
3307
|
var ORIGIN = [0, 0, 0];
|
|
3074
3308
|
var FORWARD4 = [0, 0, -1];
|
|
3075
3309
|
var IMPACT_MATERIALS = ["concrete", "metal", "wood", "glass", "flesh", "water"];
|
|
@@ -3199,12 +3433,148 @@ var GameDestructionThree = (() => {
|
|
|
3199
3433
|
team: "destruction",
|
|
3200
3434
|
budget: { particles: 20, debris: 8 },
|
|
3201
3435
|
loop: 2,
|
|
3202
|
-
timeline: [call2("chips", ORIGIN,
|
|
3436
|
+
timeline: [call2("chips", ORIGIN, UP11, 8, 0.9), call2("rust_at", ORIGIN, 6)]
|
|
3203
3437
|
}
|
|
3204
3438
|
];
|
|
3205
|
-
var
|
|
3439
|
+
var PI = Math.PI;
|
|
3440
|
+
var SMOKE = { color: 9079430, width: 10, height: 8, gravity: -0.08, drag: 2.2, growth: 2.1 };
|
|
3441
|
+
var FLASH_SECONDS = 0.055;
|
|
3442
|
+
var FLASH_RAMP = [0.6, 0.9];
|
|
3443
|
+
var FLASH_OPACITY = 0.95;
|
|
3444
|
+
var FLAME_COLORS = [16742946, 16760896, 13121050, 16773296];
|
|
3445
|
+
var FLAME_ADDITIVE = 3;
|
|
3446
|
+
var ORIGIN2 = [0, 0, 0];
|
|
3447
|
+
var SIZE = variable("size");
|
|
3448
|
+
var wide = (width) => mul(sub(rand(), 0.5), width);
|
|
3449
|
+
var puff2 = (point, velocity, world, radius, life, opacity) => mesh({
|
|
3450
|
+
shape: "sphere",
|
|
3451
|
+
p: point,
|
|
3452
|
+
v: velocity,
|
|
3453
|
+
wv: world,
|
|
3454
|
+
r: radius,
|
|
3455
|
+
seg: SMOKE.width,
|
|
3456
|
+
seg2: SMOKE.height,
|
|
3457
|
+
life,
|
|
3458
|
+
c0: SMOKE.color,
|
|
3459
|
+
a: opacity,
|
|
3460
|
+
fade: true,
|
|
3461
|
+
lit: true,
|
|
3462
|
+
g: SMOKE.gravity,
|
|
3463
|
+
drag: SMOKE.drag,
|
|
3464
|
+
grow: SMOKE.growth
|
|
3465
|
+
});
|
|
3466
|
+
var flameBit = (point, velocity, world, radius, life) => [
|
|
3467
|
+
set("bitPoint", point),
|
|
3468
|
+
set("bitVelocity", velocity),
|
|
3469
|
+
set("bitWorld", world),
|
|
3470
|
+
set("bitRadius", radius),
|
|
3471
|
+
set("bitLife", life),
|
|
3472
|
+
set("bitColour", floor(mul(rand(), FLAME_COLORS.length))),
|
|
3473
|
+
mesh({
|
|
3474
|
+
shape: "icosahedron",
|
|
3475
|
+
p: variable("bitPoint"),
|
|
3476
|
+
v: variable("bitVelocity"),
|
|
3477
|
+
wv: variable("bitWorld"),
|
|
3478
|
+
r: variable("bitRadius"),
|
|
3479
|
+
seg: 1,
|
|
3480
|
+
rot: [mul(rand(), 3), mul(rand(), 3), 0],
|
|
3481
|
+
spin: [3, 4, 2],
|
|
3482
|
+
life: variable("bitLife"),
|
|
3483
|
+
c0: pick(FLAME_COLORS, variable("bitColour")),
|
|
3484
|
+
add: eq(variable("bitColour"), FLAME_ADDITIVE),
|
|
3485
|
+
a: 0.9,
|
|
3486
|
+
fade: true,
|
|
3487
|
+
g: -1.4,
|
|
3488
|
+
drag: 1.4,
|
|
3489
|
+
grow: 2.2
|
|
3490
|
+
})
|
|
3491
|
+
];
|
|
3492
|
+
var flashPiece = (shape, radius, height, width, at3, rot, color) => mesh({ shape, r: radius, ...height === void 0 ? {} : { h: height }, seg: width, seg2: shape === "sphere" ? 8 : 1, p: ORIGIN2, at: at3, rot, roll: variable("roll"), ramp: FLASH_RAMP, life: FLASH_SECONDS, c0: color, a: FLASH_OPACITY, add: true });
|
|
3493
|
+
var MUZZLE_FLASH2 = {
|
|
3494
|
+
id: "viewmodel_muzzle_flash",
|
|
3495
|
+
pageId: "event:viewmodel_muzzle_flash",
|
|
3496
|
+
team: "weapons",
|
|
3497
|
+
budget: { particles: 12, lights: 1 },
|
|
3498
|
+
loop: 0.1,
|
|
3499
|
+
timeline: [
|
|
3500
|
+
set("angles", []),
|
|
3501
|
+
repeat(4, append("angles", add(div(mul(INDEX, PI), 2), mul(rand(), 0.6)))),
|
|
3502
|
+
set("roll", mul(rand(), PI)),
|
|
3503
|
+
flash(ORIGIN2, 16756832, mul(4, SIZE), FLASH_SECONDS, mul(2, SIZE), true, true),
|
|
3504
|
+
flashPiece("cone_open", mul(0.013, SIZE), mul(0.085, SIZE), 10, [mul(0.042, SIZE), 0, 0], [0, 0, -PI / 2], 16757575),
|
|
3505
|
+
repeat(
|
|
3506
|
+
4,
|
|
3507
|
+
set("angle", pick(variable("angles"), INDEX)),
|
|
3508
|
+
flashPiece(
|
|
3509
|
+
"cone",
|
|
3510
|
+
mul(5e-3, SIZE),
|
|
3511
|
+
mul(0.04, SIZE),
|
|
3512
|
+
6,
|
|
3513
|
+
[mul(0.012, SIZE), mul(cos(variable("angle")), 0.016, SIZE), mul(sin(variable("angle")), 0.016, SIZE)],
|
|
3514
|
+
[variable("angle"), 0, -PI / 2],
|
|
3515
|
+
16757575
|
|
3516
|
+
)
|
|
3517
|
+
),
|
|
3518
|
+
flashPiece("sphere", mul(0.016, SIZE), void 0, 12, [mul(8e-3, SIZE), 0, 0], [0, 0, 0], 16773568),
|
|
3519
|
+
repeat(
|
|
3520
|
+
6,
|
|
3521
|
+
puff2(
|
|
3522
|
+
ORIGIN2,
|
|
3523
|
+
[add(0.15, mul(rand(), 0.35)), add(0.03, mul(rand(), 0.12)), mul(sub(rand(), 0.5), 0.14)],
|
|
3524
|
+
[0, 0, 0],
|
|
3525
|
+
mul(0.013, SIZE),
|
|
3526
|
+
add(1.3, mul(rand(), 0.6)),
|
|
3527
|
+
0.45
|
|
3528
|
+
)
|
|
3529
|
+
)
|
|
3530
|
+
]
|
|
3531
|
+
};
|
|
3532
|
+
var SMOKE_PUFF = {
|
|
3533
|
+
id: "weapon_smoke_puff",
|
|
3534
|
+
pageId: "event:weapon_smoke_puff",
|
|
3535
|
+
team: "weapons",
|
|
3536
|
+
budget: { particles: 1 },
|
|
3537
|
+
loop: 0.1,
|
|
3538
|
+
timeline: [puff2(ORIGIN2, void 0, [variable("vx"), variable("vy"), variable("vz")], variable("radius"), variable("life"), variable("opacity"))]
|
|
3539
|
+
};
|
|
3540
|
+
var BACKBLAST = {
|
|
3541
|
+
id: "launcher_backblast",
|
|
3542
|
+
pageId: "event:launcher_backblast",
|
|
3543
|
+
team: "weapons",
|
|
3544
|
+
budget: { particles: 40 },
|
|
3545
|
+
loop: 0.1,
|
|
3546
|
+
timeline: [
|
|
3547
|
+
repeat(26, puff2(ORIGIN2, [neg(add(1.5, mul(rand(), 3))), 0, 0], [wide(1.4), wide(0.8), wide(1.4)], add(0.03, mul(rand(), 0.03)), add(1.8, mul(rand(), 1.4)), 0.5)),
|
|
3548
|
+
repeat(14, ...flameBit(ORIGIN2, [neg(add(2, mul(rand(), 2))), 0, 0], [wide(1), wide(0.6), wide(1)], 0.02, 0.25))
|
|
3549
|
+
]
|
|
3550
|
+
};
|
|
3551
|
+
var FLAME_JET = {
|
|
3552
|
+
id: "flame_jet",
|
|
3553
|
+
pageId: "event:flame_jet",
|
|
3554
|
+
team: "weapons",
|
|
3555
|
+
budget: { particles: 30 },
|
|
3556
|
+
loop: 0.1,
|
|
3557
|
+
timeline: [
|
|
3558
|
+
repeat(
|
|
3559
|
+
floor(mul(420, variable("dt"), variable("scale"))),
|
|
3560
|
+
set("speed", mul(add(2.2, mul(rand(), 1.1)), variable("scale"))),
|
|
3561
|
+
...flameBit(
|
|
3562
|
+
[mul(rand(), variable("speed"), min(variable("dt"), 0.3)), 0, 0],
|
|
3563
|
+
[variable("speed"), 0, 0],
|
|
3564
|
+
[wide(0.35), mul(sub(rand(), 0.3), 0.3), wide(0.35)],
|
|
3565
|
+
add(0.02, mul(rand(), 0.022)),
|
|
3566
|
+
add(0.4, mul(rand(), 0.35))
|
|
3567
|
+
)
|
|
3568
|
+
),
|
|
3569
|
+
when(lt(rand(), 0.5), [
|
|
3570
|
+
puff2([add(mul(1.1, variable("scale")), mul(rand(), 0.4)), 0, 0], void 0, [mul(vx(DIRECTION), 0.6), 0.35, mul(vz(DIRECTION), 0.6)], 0.03, 1.6, 0.4)
|
|
3571
|
+
])
|
|
3572
|
+
]
|
|
3573
|
+
};
|
|
3574
|
+
var VIEWMODEL_EFFECTS = [MUZZLE_FLASH2, SMOKE_PUFF, BACKBLAST, FLAME_JET];
|
|
3575
|
+
var ALL_EFFECTS = [BLOOD_HIT, HEADSHOT, DISMEMBER, BLOATER_CLOUD, SCREAMER_SHRIEK, CORPSE_DECAY, REANIMATION, EYES_IN_FOG, MUZZLE_FLASH, IMPACT_BY_MATERIAL, PENETRATION, CASINGS_AND_MAGAZINE, MOLOTOV, GRENADE, EXPLOSIVE_BARREL, SHOPFRONT_GLASS, DOOR_STAGES, BUILDING_COLLAPSE, BLOCK_WALL, METAL_DOOR_EFFECT, IRON_RAILING, WOODEN_FENCE, HIT_POINT_BREAKAGE, PRESSURE_CYLINDERS, BUILDING_FIRE, RAIN_AND_PUDDLES, FOG_AND_ASH, SCRAPING_SPARKS, ENGINE_SMOKE, FUEL_LEAK, CAR_EXPLOSION, WINDSHIELD, HEADLIGHTS_IN_RAIN, DAMAGE_AND_BITE, INFECTION_PHASES, PANIC, BLOATER_BLINDNESS, CAMPFIRE, COUGH_AND_BREATH];
|
|
3206
3576
|
var WORKSHOP_EFFECTS = Object.fromEntries(ALL_EFFECTS.map((effect) => [effect.id, effect]));
|
|
3207
|
-
var GAME_EFFECTS = { ...WORKSHOP_EFFECTS, ...Object.fromEntries(EVENT_EFFECTS.map((effect) => [effect.id, effect])) };
|
|
3577
|
+
var GAME_EFFECTS = { ...WORKSHOP_EFFECTS, ...Object.fromEntries([...EVENT_EFFECTS, ...VIEWMODEL_EFFECTS].map((effect) => [effect.id, effect])) };
|
|
3208
3578
|
var LEHMER_MULTIPLIER = 16807;
|
|
3209
3579
|
var LEHMER_MODULUS = 2147483647;
|
|
3210
3580
|
var HASH_MIX = 2654435761;
|
|
@@ -3300,7 +3670,7 @@ var GameDestructionThree = (() => {
|
|
|
3300
3670
|
}
|
|
3301
3671
|
var COLUMNS = 6;
|
|
3302
3672
|
var ROWS = 5;
|
|
3303
|
-
var
|
|
3673
|
+
var ORIGIN3 = [-2.2, 0, 2.6];
|
|
3304
3674
|
var BLOCK_SIZE = [0.5, 0.44, 0.25];
|
|
3305
3675
|
var OBJECT_ID_DRAWS2 = 4;
|
|
3306
3676
|
var FLOOR2 = 0.13;
|
|
@@ -3343,7 +3713,7 @@ var GameDestructionThree = (() => {
|
|
|
3343
3713
|
const chipScale = random.between(0.8, 1.3) * scale;
|
|
3344
3714
|
for (let draw = 0; draw < OBJECT_ID_DRAWS2; draw++) random.next();
|
|
3345
3715
|
best.holes.push({ x: offsetX, y: offsetY, scale, chipTurn, chipScale });
|
|
3346
|
-
impact(host.engine, "concrete", [
|
|
3716
|
+
impact(host.engine, "concrete", [ORIGIN3[0] + x, y, ORIGIN3[2] + 0.13], [0, 0, 1], 0.8);
|
|
3347
3717
|
} else if (action === "collapse") {
|
|
3348
3718
|
const { x, y } = args;
|
|
3349
3719
|
for (const block of blocks) {
|
|
@@ -3393,7 +3763,7 @@ var GameDestructionThree = (() => {
|
|
|
3393
3763
|
}
|
|
3394
3764
|
};
|
|
3395
3765
|
}
|
|
3396
|
-
var
|
|
3766
|
+
var ORIGIN4 = [5.6, 0, 0.8];
|
|
3397
3767
|
var MAX_TILT = 0.25;
|
|
3398
3768
|
function createCarBehavior() {
|
|
3399
3769
|
let y = 0;
|
|
@@ -3425,8 +3795,13 @@ var GameDestructionThree = (() => {
|
|
|
3425
3795
|
}
|
|
3426
3796
|
}
|
|
3427
3797
|
},
|
|
3428
|
-
query(_host, name) {
|
|
3429
|
-
if (name === "position") return [
|
|
3798
|
+
query(_host, name, args) {
|
|
3799
|
+
if (name === "position") return [ORIGIN4[0], y, ORIGIN4[2]];
|
|
3800
|
+
if (name === "point") {
|
|
3801
|
+
const [x, py, z] = args;
|
|
3802
|
+
const point = carPoint(x, py, z);
|
|
3803
|
+
return [point[0], point[1] + y, point[2]];
|
|
3804
|
+
}
|
|
3430
3805
|
if (name === "roll") return roll;
|
|
3431
3806
|
throw new Error(`car: unknown query ${name}`);
|
|
3432
3807
|
},
|
|
@@ -3626,6 +4001,29 @@ var GameDestructionThree = (() => {
|
|
|
3626
4001
|
}
|
|
3627
4002
|
};
|
|
3628
4003
|
}
|
|
4004
|
+
function createRainBehavior() {
|
|
4005
|
+
return {
|
|
4006
|
+
reset() {
|
|
4007
|
+
},
|
|
4008
|
+
act(host, action, args) {
|
|
4009
|
+
const { engine, camera: camera2 } = host;
|
|
4010
|
+
if (action === "init") {
|
|
4011
|
+
const { count, wind } = args;
|
|
4012
|
+
engine.rain.init(count, wind);
|
|
4013
|
+
} else if (action === "update") {
|
|
4014
|
+
const { dt, splash } = args;
|
|
4015
|
+
engine.rain.update(dt, splash, camera2.position);
|
|
4016
|
+
}
|
|
4017
|
+
},
|
|
4018
|
+
query(host, name) {
|
|
4019
|
+
if (name === "count") return host.engine.rain.count;
|
|
4020
|
+
if (name === "on") return host.engine.rain.on;
|
|
4021
|
+
throw new Error(`rain: unknown query ${name}`);
|
|
4022
|
+
},
|
|
4023
|
+
update() {
|
|
4024
|
+
}
|
|
4025
|
+
};
|
|
4026
|
+
}
|
|
3629
4027
|
var WALKER_COUNT = 10;
|
|
3630
4028
|
var ARRIVAL_DISTANCE = 0.05;
|
|
3631
4029
|
var SWAY_AMPLITUDE = 0.04;
|
|
@@ -3691,7 +4089,8 @@ var GameDestructionThree = (() => {
|
|
|
3691
4089
|
blocks: () => createBlocksBehavior(),
|
|
3692
4090
|
plate: () => createPlateBehavior(),
|
|
3693
4091
|
cylinder: () => createCylinderBehavior(),
|
|
3694
|
-
car: () => createCarBehavior()
|
|
4092
|
+
car: () => createCarBehavior(),
|
|
4093
|
+
rain: () => createRainBehavior()
|
|
3695
4094
|
};
|
|
3696
4095
|
var NOOP = () => {
|
|
3697
4096
|
};
|
|
@@ -3762,6 +4161,8 @@ var GameDestructionThree = (() => {
|
|
|
3762
4161
|
return Math.abs(asNumber(first));
|
|
3763
4162
|
case "sqrt":
|
|
3764
4163
|
return Math.sqrt(asNumber(first));
|
|
4164
|
+
case "exp":
|
|
4165
|
+
return Math.exp(asNumber(first));
|
|
3765
4166
|
case "sin":
|
|
3766
4167
|
return Math.sin(asNumber(first));
|
|
3767
4168
|
case "cos":
|
|
@@ -3880,7 +4281,7 @@ var GameDestructionThree = (() => {
|
|
|
3880
4281
|
return evaluateCall(value.$, args.map((entry) => resolve(entry, context)));
|
|
3881
4282
|
}
|
|
3882
4283
|
}
|
|
3883
|
-
var
|
|
4284
|
+
var UP12 = [0, 1, 0];
|
|
3884
4285
|
var ZERO = [0, 0, 0];
|
|
3885
4286
|
var FULL_TURN_DRAWN = 6.283;
|
|
3886
4287
|
function scaledSizes(range, factor) {
|
|
@@ -3893,7 +4294,7 @@ var GameDestructionThree = (() => {
|
|
|
3893
4294
|
p: centre,
|
|
3894
4295
|
r: radius,
|
|
3895
4296
|
flat: true,
|
|
3896
|
-
dir: options.dir ??
|
|
4297
|
+
dir: options.dir ?? UP12,
|
|
3897
4298
|
cone: 0.35,
|
|
3898
4299
|
sp: [0.4, 1.4],
|
|
3899
4300
|
v: wind,
|
|
@@ -3910,7 +4311,7 @@ var GameDestructionThree = (() => {
|
|
|
3910
4311
|
p: centre,
|
|
3911
4312
|
r: radius * 0.6,
|
|
3912
4313
|
flat: true,
|
|
3913
|
-
dir:
|
|
4314
|
+
dir: UP12,
|
|
3914
4315
|
cone: 0.3,
|
|
3915
4316
|
sp: [0.3, 0.8],
|
|
3916
4317
|
life: [0.2, 0.4],
|
|
@@ -3925,14 +4326,14 @@ var GameDestructionThree = (() => {
|
|
|
3925
4326
|
if (engine.quality < 2) {
|
|
3926
4327
|
engine.emit(`${key}e`, "streak", 10 * factor, dt, () => {
|
|
3927
4328
|
const jitter = plus(wind, engine.random.between(-0.4, 0.4), 0, engine.random.between(-0.4, 0.4));
|
|
3928
|
-
return { p: centre, box: [radius, 0, radius], dir:
|
|
4329
|
+
return { p: centre, box: [radius, 0, radius], dir: UP12, cone: 0.5, sp: [1.5, 3.5], v: jitter, life: [0.8, 1.8], len: 0.03, c0: 16756816, c1: 6295552, g: -0.6, drag: 0.4 };
|
|
3929
4330
|
});
|
|
3930
4331
|
}
|
|
3931
4332
|
if (options.noSmoke) return;
|
|
3932
4333
|
engine.emit(`${key}s`, "normal", (options.smoke || 14) * factor, dt, () => ({
|
|
3933
4334
|
p: plus(centre, 0, 0.8 * sqrtFactor, 0),
|
|
3934
4335
|
r: radius * 0.7,
|
|
3935
|
-
dir:
|
|
4336
|
+
dir: UP12,
|
|
3936
4337
|
cone: 0.35,
|
|
3937
4338
|
sp: [0.6, 1.4],
|
|
3938
4339
|
v: wind,
|
|
@@ -3972,15 +4373,15 @@ var GameDestructionThree = (() => {
|
|
|
3972
4373
|
engine.screen.shake += 0.7 * scale;
|
|
3973
4374
|
engine.screen.white += 0.18 * scale;
|
|
3974
4375
|
engine.burst("add", 55 * scale, { p: point, r: 0.3 * scale, sp: [2, 7 * scale], drag: 4, life: [0.25, 0.6], size: [0.7 * scale, 1.4 * scale], grow: 1.7, c0: 16773296, c1: 10103304, fi: 0.04 });
|
|
3975
|
-
engine.burst("add", 28 * scale, { p: plus(point, 0, 0.3, 0), r: 0.3, dir:
|
|
4376
|
+
engine.burst("add", 28 * scale, { p: plus(point, 0, 0.3, 0), r: 0.3, dir: UP12, cone: 0.7, sp: [2, 5 * scale], drag: 1.5, life: [0.6, 1.1], size: [0.6 * scale, 1 * scale], grow: 1.3, c0: 16760928, c1: 5902853, g: -2, fi: 0.05 });
|
|
3976
4377
|
engine.ring([plus(point, 0, 0.05, 0), 0.3, 7 * scale, 0.55, 16767136]);
|
|
3977
4378
|
const toCamera = normalized([cameraPosition[0] - point[0], cameraPosition[1] - point[1], cameraPosition[2] - point[2]]);
|
|
3978
4379
|
engine.ring([plus(point, 0, 1, 0), 0.3, 5 * scale, 0.35, 16773328, toCamera]);
|
|
3979
|
-
engine.burst("normal", 32 * scale, { p: plus(point, 0, 0.6, 0), r: 0.8 * scale, dir:
|
|
4380
|
+
engine.burst("normal", 32 * scale, { p: plus(point, 0, 0.6, 0), r: 0.8 * scale, dir: UP12, cone: 1.1, sp: [1, 3], drag: 1.2, life: [3, 6], size: [1 * scale, 1.8 * scale], grow: 2.6, c0: 2828068, c1: 987155, a: 0.6, fi: 0.18, g: -0.35 });
|
|
3980
4381
|
ringOfDust(engine, point, scale);
|
|
3981
|
-
if (engine.quality < 2) engine.burst("streak", 44 * scale, { p: point, dir:
|
|
4382
|
+
if (engine.quality < 2) engine.burst("streak", 44 * scale, { p: point, dir: UP12, cone: 1.45, sp: [10, 26], life: [0.3, 0.7], len: 0.03, c0: 16760944, c1: 8396800, g: 9.8, gnd: 2 });
|
|
3982
4383
|
for (let index = 0; index < engine.scaled(16 * scale); index++) {
|
|
3983
|
-
engine.debrisPiece({ p: point, dir:
|
|
4384
|
+
engine.debrisPiece({ p: point, dir: UP12, cone: 1.2, sp: [3, 9], size: [0.12, 0.06, 0.1], k: [0.6, 1.6], c: chipColor || 2762274, life: 9 });
|
|
3984
4385
|
}
|
|
3985
4386
|
engine.decal([point[0], engine.context.groundAt(point[0], point[2]), point[2], 3 * scale, 657930, { grow: 0.15, life: 60 }]);
|
|
3986
4387
|
}
|
|
@@ -4123,6 +4524,7 @@ var GameDestructionThree = (() => {
|
|
|
4123
4524
|
if (!def) return;
|
|
4124
4525
|
this.schedule.clear();
|
|
4125
4526
|
this.variables.clear();
|
|
4527
|
+
for (const [name, value] of Object.entries(this.setup.values ?? {})) this.variables.set(name, value);
|
|
4126
4528
|
for (const behavior2 of this.deps.behaviors()) behavior2.reset(this.host);
|
|
4127
4529
|
this.time = 0;
|
|
4128
4530
|
this.within(() => {
|
|
@@ -4181,6 +4583,10 @@ var GameDestructionThree = (() => {
|
|
|
4181
4583
|
return engine.spawn(step.system, this.value(step.spawn));
|
|
4182
4584
|
case "emit":
|
|
4183
4585
|
return engine.emit(step.key, step.system, this.value(step.rate), this.dt, () => this.value(step.spawn));
|
|
4586
|
+
case "mesh": {
|
|
4587
|
+
engine.mesh(this.value(step.spawn));
|
|
4588
|
+
return;
|
|
4589
|
+
}
|
|
4184
4590
|
case "debris":
|
|
4185
4591
|
return engine.debrisPiece(this.value(step.spawn));
|
|
4186
4592
|
case "decal":
|
|
@@ -4262,7 +4668,7 @@ var GameDestructionThree = (() => {
|
|
|
4262
4668
|
this.index = previous;
|
|
4263
4669
|
}
|
|
4264
4670
|
};
|
|
4265
|
-
var
|
|
4671
|
+
var ORIGIN5 = [0, 0, 0];
|
|
4266
4672
|
var DEFAULT_HEADING = [0, 0, -1];
|
|
4267
4673
|
var DEFAULT_MAX_INSTANCES = 48;
|
|
4268
4674
|
var ENDLESS_SECONDS = 60;
|
|
@@ -4307,7 +4713,7 @@ var GameDestructionThree = (() => {
|
|
|
4307
4713
|
}
|
|
4308
4714
|
function placementOf(entry) {
|
|
4309
4715
|
const origin = entry.follow ? [entry.origin[0] + positionOf2(entry.follow)[0], entry.origin[1] + positionOf2(entry.follow)[1], entry.origin[2] + positionOf2(entry.follow)[2]] : entry.origin;
|
|
4310
|
-
return { origin, anchor: entry.anchor, yaw: entry.yaw };
|
|
4716
|
+
return { origin, anchor: entry.anchor, yaw: entry.yaw, ...entry.orientation ? { orientation: entry.orientation } : {} };
|
|
4311
4717
|
}
|
|
4312
4718
|
function drawing(entry, action) {
|
|
4313
4719
|
const context = engine.context;
|
|
@@ -4331,8 +4737,9 @@ var GameDestructionThree = (() => {
|
|
|
4331
4737
|
random: playOptions.seed !== void 0 ? streamOf(playOptions.seed) : void 0,
|
|
4332
4738
|
follow: playOptions.follow,
|
|
4333
4739
|
origin: point,
|
|
4334
|
-
anchor: def.anchor ??
|
|
4740
|
+
anchor: def.anchor ?? ORIGIN5,
|
|
4335
4741
|
yaw: yawOf(heading, playOptions.direction),
|
|
4742
|
+
orientation: playOptions.orientation,
|
|
4336
4743
|
seconds: playOptions.seconds ?? (def.loop && def.loop > 0 ? def.loop : ENDLESS_SECONDS)
|
|
4337
4744
|
};
|
|
4338
4745
|
playing.push(entry);
|
|
@@ -4341,7 +4748,8 @@ var GameDestructionThree = (() => {
|
|
|
4341
4748
|
() => instance.begin(def, paramIndex(def, playOptions.param), {
|
|
4342
4749
|
placement: placementOf(entry),
|
|
4343
4750
|
...playOptions.direction ? { direction: playOptions.direction } : {},
|
|
4344
|
-
...playOptions.normal ? { normal: playOptions.normal } : {}
|
|
4751
|
+
...playOptions.normal ? { normal: playOptions.normal } : {},
|
|
4752
|
+
...playOptions.values ? { values: playOptions.values } : {}
|
|
4345
4753
|
})
|
|
4346
4754
|
);
|
|
4347
4755
|
return entry.handle;
|
|
@@ -4601,15 +5009,15 @@ var GameDestructionThree = (() => {
|
|
|
4601
5009
|
return shock;
|
|
4602
5010
|
}
|
|
4603
5011
|
function pushPuffs(puffs, shock, reach, dt, age) {
|
|
4604
|
-
for (const
|
|
4605
|
-
if (
|
|
4606
|
-
const dx =
|
|
4607
|
-
const dz =
|
|
5012
|
+
for (const puff3 of puffs) {
|
|
5013
|
+
if (puff3.ring || puff3.t > PUSH_AGE_LIMIT) continue;
|
|
5014
|
+
const dx = puff3.x - shock.x;
|
|
5015
|
+
const dz = puff3.z - shock.z;
|
|
4608
5016
|
const distance = Math.hypot(dx, dz) + 1e-3;
|
|
4609
|
-
if (Math.abs(distance - reach) < PUSH_BAND &&
|
|
5017
|
+
if (Math.abs(distance - reach) < PUSH_BAND && puff3.y < PUSH_CEILING) {
|
|
4610
5018
|
const strength = 4 * dt * (1 - age);
|
|
4611
|
-
|
|
4612
|
-
|
|
5019
|
+
puff3.vx += dx / distance * strength * 6;
|
|
5020
|
+
puff3.vz += dz / distance * strength * 6;
|
|
4613
5021
|
}
|
|
4614
5022
|
}
|
|
4615
5023
|
}
|
|
@@ -4909,10 +5317,10 @@ var GameDestructionThree = (() => {
|
|
|
4909
5317
|
const life = random.between(ring2.life * 0.75, ring2.life);
|
|
4910
5318
|
const h0 = random.between(1, 1.25);
|
|
4911
5319
|
const hl = random.between(0.9, 1.6);
|
|
4912
|
-
const
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
5320
|
+
const puff3 = addPuff(core, random, { x, y, z, s0: spec.radius * 0.2, s1, sg: spec.radius * 0.06, gk: 3, life, h0, hl, color, kind: 0 });
|
|
5321
|
+
puff3.ring = ring2;
|
|
5322
|
+
puff3.ph = random.next() * Math.PI * 2;
|
|
5323
|
+
puff3.th = random.next() * Math.PI * 2;
|
|
4916
5324
|
}
|
|
4917
5325
|
const stemCount = Math.round((spec.stem || 18) * Math.max(lod, 0.4));
|
|
4918
5326
|
for (let index = 0; index < stemCount; index++) {
|
|
@@ -5713,7 +6121,7 @@ var GameDestructionThree = (() => {
|
|
|
5713
6121
|
};
|
|
5714
6122
|
var TWO_PI_ROUNDED = 6.2832;
|
|
5715
6123
|
var WIDE_CONE = 3.1;
|
|
5716
|
-
var
|
|
6124
|
+
var UP13 = [0, 1, 0];
|
|
5717
6125
|
function drawRange(random, range) {
|
|
5718
6126
|
if (Array.isArray(range)) return random.between(range[0], range[1]);
|
|
5719
6127
|
return range || 0;
|
|
@@ -5741,7 +6149,7 @@ var GameDestructionThree = (() => {
|
|
|
5741
6149
|
}
|
|
5742
6150
|
function coneDirection(random, direction, cone, out) {
|
|
5743
6151
|
if (cone >= WIDE_CONE) return randomUnit(random, out);
|
|
5744
|
-
const [dx, dy, dz] = direction ??
|
|
6152
|
+
const [dx, dy, dz] = direction ?? UP13;
|
|
5745
6153
|
const cosTilt = 1 - random.next() * (1 - Math.cos(cone));
|
|
5746
6154
|
const sinTilt = Math.sqrt(1 - cosTilt * cosTilt);
|
|
5747
6155
|
const phase = random.next() * TWO_PI_ROUNDED;
|
|
@@ -5861,12 +6269,12 @@ var GameDestructionThree = (() => {
|
|
|
5861
6269
|
}
|
|
5862
6270
|
};
|
|
5863
6271
|
var CAPACITY2 = 400;
|
|
5864
|
-
var
|
|
6272
|
+
var UP14 = [0, 1, 0];
|
|
5865
6273
|
var DEFAULT_LIFE2 = 60;
|
|
5866
6274
|
var DEFAULT_GROW = 1.2;
|
|
5867
6275
|
var EVAPORATION = { fuel: [6, 5], water: [40, 20] };
|
|
5868
6276
|
function createDecal() {
|
|
5869
|
-
return { on: false, x: 0, y: 0, z: 0, sx: 0, sy: 0, t: 0, life: 0, grow: 0, color: 0, normal:
|
|
6277
|
+
return { on: false, x: 0, y: 0, z: 0, sx: 0, sy: 0, t: 0, life: 0, grow: 0, color: 0, normal: UP14, fluid: void 0, dryColor: -1, dryAt: 0, dryTime: 0 };
|
|
5870
6278
|
}
|
|
5871
6279
|
var DecalPool = class {
|
|
5872
6280
|
constructor(context) {
|
|
@@ -5879,7 +6287,7 @@ var GameDestructionThree = (() => {
|
|
|
5879
6287
|
const random = this.context.random;
|
|
5880
6288
|
const index = this.next++ % CAPACITY2;
|
|
5881
6289
|
const decal2 = this.decals[index];
|
|
5882
|
-
const normal = options.n ??
|
|
6290
|
+
const normal = options.n ?? UP14;
|
|
5883
6291
|
random.between(0, 6.28);
|
|
5884
6292
|
const offset = 4e-3 + index % 40 * 4e-4;
|
|
5885
6293
|
decal2.on = true;
|
|
@@ -5920,6 +6328,94 @@ var GameDestructionThree = (() => {
|
|
|
5920
6328
|
}
|
|
5921
6329
|
}
|
|
5922
6330
|
};
|
|
6331
|
+
var CAPACITY3 = 400;
|
|
6332
|
+
var IDENTITY = [0, 0, 0, 1];
|
|
6333
|
+
function multiply(a, b) {
|
|
6334
|
+
const [ax, ay, az, aw] = a;
|
|
6335
|
+
const [bx, by, bz, bw] = b;
|
|
6336
|
+
return [aw * bx + ax * bw + ay * bz - az * by, aw * by - ax * bz + ay * bw + az * bx, aw * bz + ax * by - ay * bx + az * bw, aw * bw - ax * bx - ay * by - az * bz];
|
|
6337
|
+
}
|
|
6338
|
+
var aboutX = (angle) => [Math.sin(angle / 2), 0, 0, Math.cos(angle / 2)];
|
|
6339
|
+
var MeshPool = class {
|
|
6340
|
+
constructor(capacity = CAPACITY3) {
|
|
6341
|
+
__publicField2(this, "capacity", capacity);
|
|
6342
|
+
__publicField2(this, "particles", []);
|
|
6343
|
+
__publicField2(this, "serial", 0);
|
|
6344
|
+
}
|
|
6345
|
+
get count() {
|
|
6346
|
+
return this.particles.length;
|
|
6347
|
+
}
|
|
6348
|
+
spawn(options, frame = IDENTITY) {
|
|
6349
|
+
const velocity = options.v ?? [0, 0, 0];
|
|
6350
|
+
const world = options.wv ?? [0, 0, 0];
|
|
6351
|
+
const particle = {
|
|
6352
|
+
id: ++this.serial,
|
|
6353
|
+
shape: options.shape,
|
|
6354
|
+
radius: options.r,
|
|
6355
|
+
height: options.h ?? 0,
|
|
6356
|
+
segments: options.seg ?? 0,
|
|
6357
|
+
segments2: options.seg2 ?? 0,
|
|
6358
|
+
color: options.c0,
|
|
6359
|
+
additive: options.add === true,
|
|
6360
|
+
lit: options.lit === true,
|
|
6361
|
+
x: options.p[0],
|
|
6362
|
+
y: options.p[1],
|
|
6363
|
+
z: options.p[2],
|
|
6364
|
+
frame: options.roll ? multiply(frame, aboutX(options.roll)) : frame,
|
|
6365
|
+
at: options.at ?? [0, 0, 0],
|
|
6366
|
+
rx: options.rot?.[0] ?? 0,
|
|
6367
|
+
ry: options.rot?.[1] ?? 0,
|
|
6368
|
+
rz: options.rot?.[2] ?? 0,
|
|
6369
|
+
scale: 1,
|
|
6370
|
+
opacity: options.a,
|
|
6371
|
+
age: 0,
|
|
6372
|
+
life: options.life,
|
|
6373
|
+
vx: velocity[0] + world[0],
|
|
6374
|
+
vy: velocity[1] + world[1],
|
|
6375
|
+
vz: velocity[2] + world[2],
|
|
6376
|
+
spin: options.spin ?? [0, 0, 0],
|
|
6377
|
+
gravity: options.g ?? 0,
|
|
6378
|
+
drag: options.drag ?? 0,
|
|
6379
|
+
grow: options.grow ?? 0,
|
|
6380
|
+
ramp: options.ramp,
|
|
6381
|
+
fade: options.fade === true,
|
|
6382
|
+
startOpacity: options.a
|
|
6383
|
+
};
|
|
6384
|
+
this.particles.push(particle);
|
|
6385
|
+
if (this.particles.length > this.capacity) this.particles.shift();
|
|
6386
|
+
return particle;
|
|
6387
|
+
}
|
|
6388
|
+
update(dt) {
|
|
6389
|
+
const live = this.particles;
|
|
6390
|
+
for (let index = 0; index < live.length; index++) {
|
|
6391
|
+
const particle = live[index];
|
|
6392
|
+
particle.age += dt;
|
|
6393
|
+
if (particle.ramp ? particle.age >= particle.life : particle.age > particle.life) {
|
|
6394
|
+
live.splice(index--, 1);
|
|
6395
|
+
continue;
|
|
6396
|
+
}
|
|
6397
|
+
if (particle.fade) particle.opacity = Math.max(0, particle.startOpacity * (1 - particle.age / particle.life));
|
|
6398
|
+
particle.vy -= particle.gravity * dt;
|
|
6399
|
+
if (particle.drag) {
|
|
6400
|
+
const keep = Math.max(0, 1 - particle.drag * dt);
|
|
6401
|
+
particle.vx *= keep;
|
|
6402
|
+
particle.vy *= keep;
|
|
6403
|
+
particle.vz *= keep;
|
|
6404
|
+
}
|
|
6405
|
+
particle.x += particle.vx * dt;
|
|
6406
|
+
particle.y += particle.vy * dt;
|
|
6407
|
+
particle.z += particle.vz * dt;
|
|
6408
|
+
particle.rx += particle.spin[0] * dt;
|
|
6409
|
+
particle.ry += particle.spin[1] * dt;
|
|
6410
|
+
particle.rz += particle.spin[2] * dt;
|
|
6411
|
+
if (particle.grow) particle.scale *= 1 + particle.grow * dt;
|
|
6412
|
+
if (particle.ramp) particle.scale = particle.ramp[0] + Math.min(1, particle.age / particle.life) * particle.ramp[1];
|
|
6413
|
+
}
|
|
6414
|
+
}
|
|
6415
|
+
clear() {
|
|
6416
|
+
this.particles.length = 0;
|
|
6417
|
+
}
|
|
6418
|
+
};
|
|
5923
6419
|
var DEFAULT_FADE_IN = 0.1;
|
|
5924
6420
|
var FLOATS_PER_VECTOR = 3;
|
|
5925
6421
|
var BYTE_MAX2 = 255;
|
|
@@ -6209,11 +6705,11 @@ var GameDestructionThree = (() => {
|
|
|
6209
6705
|
};
|
|
6210
6706
|
var RING_CAPACITY = 120;
|
|
6211
6707
|
var LIGHT_CAPACITY = 4;
|
|
6212
|
-
var
|
|
6708
|
+
var UP15 = [0, 1, 0];
|
|
6213
6709
|
var DEFAULT_LIGHT_DISTANCE = 14;
|
|
6214
6710
|
var WaveRingPool = class {
|
|
6215
6711
|
constructor() {
|
|
6216
|
-
__publicField2(this, "rings", Array.from({ length: RING_CAPACITY }, () => ({ on: false, point:
|
|
6712
|
+
__publicField2(this, "rings", Array.from({ length: RING_CAPACITY }, () => ({ on: false, point: UP15, from: 0, to: 0, t: 0, duration: 1, color: 0, normal: UP15, hold: 0 })));
|
|
6217
6713
|
__publicField2(this, "count", 0);
|
|
6218
6714
|
__publicField2(this, "next", 0);
|
|
6219
6715
|
}
|
|
@@ -6226,7 +6722,7 @@ var GameDestructionThree = (() => {
|
|
|
6226
6722
|
ring2.t = 0;
|
|
6227
6723
|
ring2.duration = duration;
|
|
6228
6724
|
ring2.color = color;
|
|
6229
|
-
ring2.normal = normal ??
|
|
6725
|
+
ring2.normal = normal ?? UP15;
|
|
6230
6726
|
ring2.hold = hold || 0;
|
|
6231
6727
|
}
|
|
6232
6728
|
clear() {
|
|
@@ -6246,7 +6742,7 @@ var GameDestructionThree = (() => {
|
|
|
6246
6742
|
var FlashLightPool = class {
|
|
6247
6743
|
constructor(context) {
|
|
6248
6744
|
__publicField2(this, "context", context);
|
|
6249
|
-
__publicField2(this, "lights", Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 16760944, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0 })));
|
|
6745
|
+
__publicField2(this, "lights", Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 16760944, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0, steady: false })));
|
|
6250
6746
|
__publicField2(this, "fire", [
|
|
6251
6747
|
{ x: 0, y: 0, z: 0, intensity: 0 },
|
|
6252
6748
|
{ x: 0, y: 0, z: 0, intensity: 0 }
|
|
@@ -6256,7 +6752,7 @@ var GameDestructionThree = (() => {
|
|
|
6256
6752
|
get lit() {
|
|
6257
6753
|
return this.lights.filter((light) => light.intensity > 0).length;
|
|
6258
6754
|
}
|
|
6259
|
-
flash(point, color, intensity, duration, distance, force) {
|
|
6755
|
+
flash(point, color, intensity, duration, distance, force, steady) {
|
|
6260
6756
|
const { level } = this.context.quality;
|
|
6261
6757
|
if (level >= 1 && !force) return;
|
|
6262
6758
|
if (level >= 2 && force !== "boom") return;
|
|
@@ -6269,6 +6765,7 @@ var GameDestructionThree = (() => {
|
|
|
6269
6765
|
light.peak = intensity;
|
|
6270
6766
|
light.duration = duration;
|
|
6271
6767
|
light.t = 0;
|
|
6768
|
+
light.steady = steady === true;
|
|
6272
6769
|
light.intensity = intensity;
|
|
6273
6770
|
}
|
|
6274
6771
|
clear() {
|
|
@@ -6280,7 +6777,7 @@ var GameDestructionThree = (() => {
|
|
|
6280
6777
|
if (light.intensity <= 0) continue;
|
|
6281
6778
|
light.t += dt;
|
|
6282
6779
|
const age = light.t / light.duration;
|
|
6283
|
-
light.intensity = age >= 1 ? 0 : light.peak * (1 - age) * (1 - age);
|
|
6780
|
+
light.intensity = age >= 1 ? 0 : light.steady ? light.peak : light.peak * (1 - age) * (1 - age);
|
|
6284
6781
|
}
|
|
6285
6782
|
}
|
|
6286
6783
|
};
|
|
@@ -6288,6 +6785,14 @@ var GameDestructionThree = (() => {
|
|
|
6288
6785
|
var FIRE_FLICKER_SWAY = 0.25;
|
|
6289
6786
|
var FIRE_FLICKER_JITTER = 0.08;
|
|
6290
6787
|
var LENS_FADE = 0.16;
|
|
6788
|
+
function rotate(q, v) {
|
|
6789
|
+
const [qx, qy, qz, qw] = q;
|
|
6790
|
+
const ix = qw * v[0] + qy * v[2] - qz * v[1];
|
|
6791
|
+
const iy = qw * v[1] + qz * v[0] - qx * v[2];
|
|
6792
|
+
const iz = qw * v[2] + qx * v[1] - qy * v[0];
|
|
6793
|
+
const iw = -qx * v[0] - qy * v[1] - qz * v[2];
|
|
6794
|
+
return [ix * qw + iw * -qx + iy * -qz - iz * -qy, iy * qw + iw * -qy + iz * -qx - ix * -qz, iz * qw + iw * -qz + ix * -qy - iy * -qx];
|
|
6795
|
+
}
|
|
6291
6796
|
function workshopGround(x, z) {
|
|
6292
6797
|
return z < -2.9 && z > -4.5 && Math.abs(x) < 13 ? 0.12 : 0;
|
|
6293
6798
|
}
|
|
@@ -6301,6 +6806,8 @@ var GameDestructionThree = (() => {
|
|
|
6301
6806
|
__publicField2(this, "decals");
|
|
6302
6807
|
__publicField2(this, "rings", new WaveRingPool());
|
|
6303
6808
|
__publicField2(this, "lights");
|
|
6809
|
+
__publicField2(this, "rain", new RainField(this));
|
|
6810
|
+
__publicField2(this, "meshes", new MeshPool());
|
|
6304
6811
|
__publicField2(this, "screen", createScreenState());
|
|
6305
6812
|
__publicField2(this, "lens", []);
|
|
6306
6813
|
__publicField2(this, "post", {});
|
|
@@ -6333,7 +6840,11 @@ var GameDestructionThree = (() => {
|
|
|
6333
6840
|
place(point) {
|
|
6334
6841
|
const placement = this.placement;
|
|
6335
6842
|
if (!placement) return point;
|
|
6336
|
-
const { anchor, origin, yaw } = placement;
|
|
6843
|
+
const { anchor, origin, yaw, orientation } = placement;
|
|
6844
|
+
if (orientation) {
|
|
6845
|
+
const turned = rotate(orientation, [point[0] - anchor[0], point[1] - anchor[1], point[2] - anchor[2]]);
|
|
6846
|
+
return [origin[0] + turned[0], origin[1] + turned[1], origin[2] + turned[2]];
|
|
6847
|
+
}
|
|
6337
6848
|
const x = point[0] - anchor[0];
|
|
6338
6849
|
const z = point[2] - anchor[2];
|
|
6339
6850
|
const cos2 = Math.cos(yaw);
|
|
@@ -6344,6 +6855,7 @@ var GameDestructionThree = (() => {
|
|
|
6344
6855
|
turn(vector) {
|
|
6345
6856
|
const placement = this.placement;
|
|
6346
6857
|
if (!placement) return vector;
|
|
6858
|
+
if (placement.orientation) return rotate(placement.orientation, vector);
|
|
6347
6859
|
const cos2 = Math.cos(placement.yaw);
|
|
6348
6860
|
const sin2 = Math.sin(placement.yaw);
|
|
6349
6861
|
return [cos2 * vector[0] + sin2 * vector[2], vector[1], -sin2 * vector[0] + cos2 * vector[2]];
|
|
@@ -6372,6 +6884,14 @@ var GameDestructionThree = (() => {
|
|
|
6372
6884
|
}
|
|
6373
6885
|
this.accumulators.set(key, carried);
|
|
6374
6886
|
}
|
|
6887
|
+
/** A solid particle (a cone, a sphere): the group sits at `p` turned by the placement, `v` is turned with it and `wv` is not. */
|
|
6888
|
+
mesh(recipe) {
|
|
6889
|
+
const placement = this.placement;
|
|
6890
|
+
const options = placement ? { ...recipe, p: this.place(recipe.p), ...recipe.v ? { v: this.turn(recipe.v) } : {} } : recipe;
|
|
6891
|
+
this.context.trace?.("mesh", [options]);
|
|
6892
|
+
const grouped = recipe.at !== void 0 || recipe.roll !== void 0;
|
|
6893
|
+
return this.meshes.spawn(options, placement && grouped ? placement.orientation ?? [0, Math.sin(placement.yaw / 2), 0, Math.cos(placement.yaw / 2)] : void 0);
|
|
6894
|
+
}
|
|
6375
6895
|
debrisPiece(recipe) {
|
|
6376
6896
|
const options = this.placed(recipe);
|
|
6377
6897
|
this.context.trace?.("debris", [options]);
|
|
@@ -6392,10 +6912,11 @@ var GameDestructionThree = (() => {
|
|
|
6392
6912
|
this.context.trace?.("ring", args);
|
|
6393
6913
|
this.rings.add(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
6394
6914
|
}
|
|
6915
|
+
/** `steady` (a seventh number): the light holds its intensity for its duration and goes out, where the Workshop's fades with the square of its age. */
|
|
6395
6916
|
flash(recipe) {
|
|
6396
|
-
const args = this.placement ? [this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5]] : recipe;
|
|
6397
|
-
this.context.trace?.("flash", args);
|
|
6398
|
-
this.lights.flash(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
6917
|
+
const args = this.placement ? [this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5], recipe[6]] : recipe;
|
|
6918
|
+
this.context.trace?.("flash", args.slice(0, 6));
|
|
6919
|
+
this.lights.flash(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
6399
6920
|
}
|
|
6400
6921
|
/** `fireLight` (W400): sways with the clock and flickers with one draw. */
|
|
6401
6922
|
fireLight(slot, recipe, intensity, time) {
|
|
@@ -6420,6 +6941,7 @@ var GameDestructionThree = (() => {
|
|
|
6420
6941
|
this.debris.update(dt);
|
|
6421
6942
|
this.decals.update(dt);
|
|
6422
6943
|
this.rings.update(dt);
|
|
6944
|
+
this.meshes.update(dt);
|
|
6423
6945
|
this.lights.update(dt);
|
|
6424
6946
|
updateScreen(this.screen, dt);
|
|
6425
6947
|
for (let index = this.lens.length - 1; index >= 0; index--) {
|
|
@@ -6436,7 +6958,9 @@ var GameDestructionThree = (() => {
|
|
|
6436
6958
|
this.debris.clear();
|
|
6437
6959
|
this.decals.clear();
|
|
6438
6960
|
this.rings.clear();
|
|
6961
|
+
this.meshes.clear();
|
|
6439
6962
|
this.lights.clear();
|
|
6963
|
+
this.rain.clear();
|
|
6440
6964
|
this.accumulators.clear();
|
|
6441
6965
|
resetScreenState(this.screen);
|
|
6442
6966
|
this.lens.length = 0;
|
|
@@ -6582,16 +7106,16 @@ var GameDestructionThree = (() => {
|
|
|
6582
7106
|
},
|
|
6583
7107
|
push(point, radius, speed) {
|
|
6584
7108
|
spriteSystem.push(point, radius, speed);
|
|
6585
|
-
for (const
|
|
6586
|
-
const dx =
|
|
6587
|
-
const dy =
|
|
6588
|
-
const dz =
|
|
7109
|
+
for (const puff3 of core.puffs.items) {
|
|
7110
|
+
const dx = puff3.x - point[0];
|
|
7111
|
+
const dy = puff3.y - point[1];
|
|
7112
|
+
const dz = puff3.z - point[2];
|
|
6589
7113
|
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
6590
7114
|
if (distance >= radius) continue;
|
|
6591
7115
|
const strength = speed * (1 - distance / radius) / (distance + 1e-3);
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
7116
|
+
puff3.vx += dx * strength;
|
|
7117
|
+
puff3.vy += dy * strength;
|
|
7118
|
+
puff3.vz += dz * strength;
|
|
6595
7119
|
}
|
|
6596
7120
|
},
|
|
6597
7121
|
stop(handle) {
|
|
@@ -6608,6 +7132,12 @@ var GameDestructionThree = (() => {
|
|
|
6608
7132
|
camera2.y = position[1];
|
|
6609
7133
|
camera2.z = position[2];
|
|
6610
7134
|
},
|
|
7135
|
+
setWind(next) {
|
|
7136
|
+
wind.x = next[0];
|
|
7137
|
+
wind.y = next[1];
|
|
7138
|
+
wind.z = next[2];
|
|
7139
|
+
},
|
|
7140
|
+
wind: () => [wind.x, wind.y, wind.z],
|
|
6611
7141
|
forceLod(scale) {
|
|
6612
7142
|
core.clock.forcedLod = scale;
|
|
6613
7143
|
},
|
|
@@ -6805,11 +7335,11 @@ void main(){
|
|
|
6805
7335
|
geometry.setAttribute("aC", attributes[2]);
|
|
6806
7336
|
geometry.instanceCount = 0;
|
|
6807
7337
|
const material = new THREE.ShaderMaterial({ uniforms, vertexShader: PUFF_VERTEX, fragmentShader: PUFF_FRAGMENT });
|
|
6808
|
-
const
|
|
6809
|
-
|
|
6810
|
-
|
|
7338
|
+
const mesh2 = new THREE.Mesh(geometry, material);
|
|
7339
|
+
mesh2.name = "vfx-puffs";
|
|
7340
|
+
mesh2.frustumCulled = false;
|
|
6811
7341
|
return {
|
|
6812
|
-
mesh,
|
|
7342
|
+
mesh: mesh2,
|
|
6813
7343
|
sync() {
|
|
6814
7344
|
let n = 0;
|
|
6815
7345
|
for (const p of pool.items) {
|
|
@@ -6850,12 +7380,12 @@ void main(){
|
|
|
6850
7380
|
geometry.setAttribute("aE", attributes[2]);
|
|
6851
7381
|
geometry.instanceCount = 0;
|
|
6852
7382
|
const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: SPARK_VERTEX, fragmentShader: SPARK_FRAGMENT });
|
|
6853
|
-
const
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
7383
|
+
const mesh2 = new THREE.Mesh(geometry, material);
|
|
7384
|
+
mesh2.name = "vfx-sparks";
|
|
7385
|
+
mesh2.frustumCulled = false;
|
|
7386
|
+
mesh2.renderOrder = 5;
|
|
6857
7387
|
return {
|
|
6858
|
-
mesh,
|
|
7388
|
+
mesh: mesh2,
|
|
6859
7389
|
sync() {
|
|
6860
7390
|
let n = 0;
|
|
6861
7391
|
for (const s of pool.items) {
|
|
@@ -6893,12 +7423,12 @@ void main(){
|
|
|
6893
7423
|
geometry.setAttribute("aC", attributes[1]);
|
|
6894
7424
|
geometry.instanceCount = 0;
|
|
6895
7425
|
const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: GLOW_VERTEX, fragmentShader: GLOW_FRAGMENT });
|
|
6896
|
-
const
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
7426
|
+
const mesh2 = new THREE.Mesh(geometry, material);
|
|
7427
|
+
mesh2.name = "vfx-glows";
|
|
7428
|
+
mesh2.frustumCulled = false;
|
|
7429
|
+
mesh2.renderOrder = 6;
|
|
6900
7430
|
return {
|
|
6901
|
-
mesh,
|
|
7431
|
+
mesh: mesh2,
|
|
6902
7432
|
sync() {
|
|
6903
7433
|
let n = 0;
|
|
6904
7434
|
for (const g of pool.items) {
|
|
@@ -6927,14 +7457,14 @@ void main(){
|
|
|
6927
7457
|
const rockMaterial = new THREE.MeshStandardMaterial({ color: 16777215, roughness: 0.85, flatShading: true });
|
|
6928
7458
|
const plateMaterial = rockMaterial.clone();
|
|
6929
7459
|
const make = (geometry, material) => {
|
|
6930
|
-
const
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
return
|
|
7460
|
+
const mesh2 = new THREE.InstancedMesh(geometry, material, capacity);
|
|
7461
|
+
mesh2.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
|
|
7462
|
+
mesh2.castShadow = true;
|
|
7463
|
+
mesh2.receiveShadow = true;
|
|
7464
|
+
mesh2.frustumCulled = false;
|
|
7465
|
+
mesh2.count = 0;
|
|
7466
|
+
mesh2.setColorAt(0, new THREE.Color(1, 1, 1));
|
|
7467
|
+
return mesh2;
|
|
6938
7468
|
};
|
|
6939
7469
|
const rocks = make(shapes.rock, rockMaterial);
|
|
6940
7470
|
const plates = make(shapes.plate, plateMaterial);
|
|
@@ -6953,20 +7483,20 @@ void main(){
|
|
|
6953
7483
|
euler.set(chunk.rx, chunk.ry, chunk.rz);
|
|
6954
7484
|
quaternion.setFromEuler(euler);
|
|
6955
7485
|
matrix.compose(position.set(chunk.x, chunk.y, chunk.z), quaternion, scale.set(chunk.sx, chunk.sy, chunk.sz));
|
|
6956
|
-
const
|
|
7486
|
+
const mesh2 = chunk.plate ? plates : rocks;
|
|
6957
7487
|
const index = chunk.plate ? plateCount++ : rockCount++;
|
|
6958
|
-
|
|
7488
|
+
mesh2.setMatrixAt(index, matrix);
|
|
6959
7489
|
const color = colorOf2(chunk);
|
|
6960
|
-
const colors =
|
|
7490
|
+
const colors = mesh2.instanceColor.array;
|
|
6961
7491
|
colors[index * 3] = color[0];
|
|
6962
7492
|
colors[index * 3 + 1] = color[1];
|
|
6963
7493
|
colors[index * 3 + 2] = color[2];
|
|
6964
7494
|
}
|
|
6965
7495
|
rocks.count = rockCount;
|
|
6966
7496
|
plates.count = plateCount;
|
|
6967
|
-
for (const
|
|
6968
|
-
|
|
6969
|
-
|
|
7497
|
+
for (const mesh2 of [rocks, plates]) {
|
|
7498
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
7499
|
+
mesh2.instanceColor.needsUpdate = true;
|
|
6970
7500
|
}
|
|
6971
7501
|
return rockCount + plateCount;
|
|
6972
7502
|
},
|
|
@@ -7150,28 +7680,28 @@ void main(){
|
|
|
7150
7680
|
position.setXYZ(index, worldX, (options.ground?.heightAt(worldX, worldZ) ?? 0) + mark.lift, worldZ);
|
|
7151
7681
|
}
|
|
7152
7682
|
geometry.computeVertexNormals();
|
|
7153
|
-
const
|
|
7154
|
-
|
|
7155
|
-
return
|
|
7683
|
+
const mesh2 = new THREE.Mesh(geometry, material);
|
|
7684
|
+
mesh2.receiveShadow = true;
|
|
7685
|
+
return mesh2;
|
|
7156
7686
|
}
|
|
7157
7687
|
function addRock(mark) {
|
|
7158
|
-
const
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
return
|
|
7688
|
+
const mesh2 = new THREE.Mesh(mark.plate ? options.plateGeometry : options.rockGeometry, rockMaterial(mark.color));
|
|
7689
|
+
mesh2.position.set(mark.x, mark.y, mark.z);
|
|
7690
|
+
mesh2.scale.set(mark.scale[0], mark.scale[1], mark.scale[2]);
|
|
7691
|
+
mesh2.rotation.set(mark.rotation[0], mark.rotation[1], mark.rotation[2]);
|
|
7692
|
+
mesh2.castShadow = true;
|
|
7693
|
+
mesh2.receiveShadow = true;
|
|
7694
|
+
return mesh2;
|
|
7165
7695
|
}
|
|
7166
7696
|
function addBlood(mark) {
|
|
7167
|
-
const
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
blood.push({ mesh, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 });
|
|
7174
|
-
return
|
|
7697
|
+
const mesh2 = new THREE.Mesh(bloodGeometry, bloodMaterial);
|
|
7698
|
+
mesh2.position.set(mark.x, mark.y, mark.z);
|
|
7699
|
+
mesh2.scale.set(mark.scaleX, 1, mark.scaleZ);
|
|
7700
|
+
mesh2.rotation.y = mark.rotation;
|
|
7701
|
+
mesh2.receiveShadow = true;
|
|
7702
|
+
mesh2.scale.multiplyScalar(0.05);
|
|
7703
|
+
blood.push({ mesh: mesh2, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 });
|
|
7704
|
+
return mesh2;
|
|
7175
7705
|
}
|
|
7176
7706
|
function build(mark) {
|
|
7177
7707
|
if (mark.kind === "scorch") return conform(mark, scorchMaterials[mark.variant]);
|
|
@@ -7382,6 +7912,73 @@ void main() {
|
|
|
7382
7912
|
}
|
|
7383
7913
|
};
|
|
7384
7914
|
}
|
|
7915
|
+
var SPHERE_DEFAULT_WIDTH = 8;
|
|
7916
|
+
var SPHERE_DEFAULT_HEIGHT = 6;
|
|
7917
|
+
function geometryOf(THREE, particle) {
|
|
7918
|
+
switch (particle.shape) {
|
|
7919
|
+
case "cone":
|
|
7920
|
+
return new THREE.ConeGeometry(particle.radius, particle.height, particle.segments || void 0, particle.segments2 || 1, false);
|
|
7921
|
+
case "cone_open":
|
|
7922
|
+
return new THREE.ConeGeometry(particle.radius, particle.height, particle.segments || void 0, particle.segments2 || 1, true);
|
|
7923
|
+
case "sphere":
|
|
7924
|
+
return new THREE.SphereGeometry(particle.radius, particle.segments || SPHERE_DEFAULT_WIDTH, particle.segments2 || SPHERE_DEFAULT_HEIGHT);
|
|
7925
|
+
case "icosahedron":
|
|
7926
|
+
return new THREE.IcosahedronGeometry(particle.radius, particle.segments);
|
|
7927
|
+
}
|
|
7928
|
+
}
|
|
7929
|
+
function materialOf(THREE, particle) {
|
|
7930
|
+
if (particle.lit) return new THREE.MeshStandardMaterial({ color: particle.color, roughness: 1, metalness: 0, transparent: true, opacity: particle.opacity, depthWrite: false });
|
|
7931
|
+
return new THREE.MeshBasicMaterial({ color: particle.color, transparent: true, opacity: particle.opacity, depthWrite: false, ...particle.additive ? { blending: THREE.AdditiveBlending } : {} });
|
|
7932
|
+
}
|
|
7933
|
+
function createMeshLayer(THREE, pool) {
|
|
7934
|
+
const group = new THREE.Group();
|
|
7935
|
+
group.name = "workshop-meshes";
|
|
7936
|
+
const drawn = /* @__PURE__ */ new Map();
|
|
7937
|
+
const frame = new THREE.Quaternion();
|
|
7938
|
+
const euler = new THREE.Euler();
|
|
7939
|
+
const turn = new THREE.Quaternion();
|
|
7940
|
+
const offset = new THREE.Vector3();
|
|
7941
|
+
function release(mesh2) {
|
|
7942
|
+
mesh2.removeFromParent();
|
|
7943
|
+
mesh2.geometry.dispose();
|
|
7944
|
+
mesh2.material.dispose();
|
|
7945
|
+
}
|
|
7946
|
+
return {
|
|
7947
|
+
group,
|
|
7948
|
+
sync() {
|
|
7949
|
+
const live = /* @__PURE__ */ new Set();
|
|
7950
|
+
for (const particle of pool.particles) {
|
|
7951
|
+
live.add(particle.id);
|
|
7952
|
+
let mesh2 = drawn.get(particle.id);
|
|
7953
|
+
if (!mesh2) {
|
|
7954
|
+
mesh2 = new THREE.Mesh(geometryOf(THREE, particle), materialOf(THREE, particle));
|
|
7955
|
+
mesh2.frustumCulled = false;
|
|
7956
|
+
mesh2.renderOrder = particle.additive ? 5 : 3;
|
|
7957
|
+
drawn.set(particle.id, mesh2);
|
|
7958
|
+
group.add(mesh2);
|
|
7959
|
+
}
|
|
7960
|
+
frame.set(particle.frame[0], particle.frame[1], particle.frame[2], particle.frame[3]);
|
|
7961
|
+
offset.set(particle.at[0], particle.at[1], particle.at[2]).multiplyScalar(particle.scale).applyQuaternion(frame);
|
|
7962
|
+
mesh2.position.set(particle.x + offset.x, particle.y + offset.y, particle.z + offset.z);
|
|
7963
|
+
turn.setFromEuler(euler.set(particle.rx, particle.ry, particle.rz));
|
|
7964
|
+
mesh2.quaternion.copy(frame).multiply(turn);
|
|
7965
|
+
mesh2.scale.setScalar(particle.scale);
|
|
7966
|
+
mesh2.material.opacity = particle.opacity;
|
|
7967
|
+
}
|
|
7968
|
+
for (const [id, mesh2] of drawn) {
|
|
7969
|
+
if (live.has(id)) continue;
|
|
7970
|
+
release(mesh2);
|
|
7971
|
+
drawn.delete(id);
|
|
7972
|
+
}
|
|
7973
|
+
return pool.count;
|
|
7974
|
+
},
|
|
7975
|
+
dispose() {
|
|
7976
|
+
for (const mesh2 of drawn.values()) release(mesh2);
|
|
7977
|
+
drawn.clear();
|
|
7978
|
+
group.removeFromParent();
|
|
7979
|
+
}
|
|
7980
|
+
};
|
|
7981
|
+
}
|
|
7385
7982
|
var WORKSHOP_SPRITE_VERTEX = `attribute float size;attribute float alpha;attribute vec3 pcol;varying vec3 vC;varying float vA;uniform float uScale;
|
|
7386
7983
|
void main(){vC=pcol;vA=alpha;vec4 mv=modelViewMatrix*vec4(position,1.);gl_PointSize=clamp(size*uScale/-mv.z,1.,512.);gl_Position=projectionMatrix*mv;}`;
|
|
7387
7984
|
var WORKSHOP_SPRITE_FRAGMENT = `uniform float uSoft;varying vec3 vC;varying float vA;
|
|
@@ -7457,13 +8054,37 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7457
8054
|
}
|
|
7458
8055
|
};
|
|
7459
8056
|
}
|
|
8057
|
+
function rainLayer(THREE, rain) {
|
|
8058
|
+
const geometry = new THREE.BufferGeometry();
|
|
8059
|
+
const position = new THREE.BufferAttribute(rain.positions, 3).setUsage(THREE.DynamicDrawUsage);
|
|
8060
|
+
geometry.setAttribute("position", position);
|
|
8061
|
+
geometry.setDrawRange(0, 0);
|
|
8062
|
+
const material = new THREE.LineBasicMaterial({ color: 10466255, transparent: true, opacity: 0.35, depthWrite: false });
|
|
8063
|
+
const lines = new THREE.LineSegments(geometry, material);
|
|
8064
|
+
lines.frustumCulled = false;
|
|
8065
|
+
lines.name = "workshop-rain";
|
|
8066
|
+
return {
|
|
8067
|
+
object: lines,
|
|
8068
|
+
sync() {
|
|
8069
|
+
const drawn = rain.on && rain.count > 0;
|
|
8070
|
+
lines.visible = drawn;
|
|
8071
|
+
geometry.setDrawRange(0, drawn ? rain.count * 2 : 0);
|
|
8072
|
+
position.needsUpdate = true;
|
|
8073
|
+
return drawn;
|
|
8074
|
+
},
|
|
8075
|
+
dispose() {
|
|
8076
|
+
geometry.dispose();
|
|
8077
|
+
material.dispose();
|
|
8078
|
+
}
|
|
8079
|
+
};
|
|
8080
|
+
}
|
|
7460
8081
|
function debrisLayer(THREE, pool) {
|
|
7461
8082
|
const geometry = new THREE.BoxGeometry(1, 1, 1);
|
|
7462
8083
|
const material = new THREE.MeshStandardMaterial({ color: 16777215, roughness: 0.45, metalness: 0.25, flatShading: true });
|
|
7463
|
-
const
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
8084
|
+
const mesh2 = new THREE.InstancedMesh(geometry, material, DEBRIS_CAPACITY);
|
|
8085
|
+
mesh2.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
|
|
8086
|
+
mesh2.frustumCulled = false;
|
|
8087
|
+
mesh2.name = "workshop-debris";
|
|
7467
8088
|
const euler = new THREE.Euler();
|
|
7468
8089
|
const quaternion = new THREE.Quaternion();
|
|
7469
8090
|
const position = new THREE.Vector3();
|
|
@@ -7471,16 +8092,16 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7471
8092
|
const matrix = new THREE.Matrix4();
|
|
7472
8093
|
const colour = new THREE.Color();
|
|
7473
8094
|
const hidden = new THREE.Matrix4().makeScale(0, 0, 0);
|
|
7474
|
-
for (let index = 0; index < DEBRIS_CAPACITY; index++)
|
|
7475
|
-
|
|
8095
|
+
for (let index = 0; index < DEBRIS_CAPACITY; index++) mesh2.setMatrixAt(index, hidden);
|
|
8096
|
+
mesh2.setColorAt(0, colour.setHex(16777215));
|
|
7476
8097
|
return {
|
|
7477
|
-
object:
|
|
8098
|
+
object: mesh2,
|
|
7478
8099
|
sync() {
|
|
7479
8100
|
let drawn = false;
|
|
7480
8101
|
for (let index = 0; index < DEBRIS_CAPACITY; index++) {
|
|
7481
8102
|
const piece = pool.pieces[index];
|
|
7482
8103
|
if (!piece.on) {
|
|
7483
|
-
|
|
8104
|
+
mesh2.setMatrixAt(index, hidden);
|
|
7484
8105
|
continue;
|
|
7485
8106
|
}
|
|
7486
8107
|
drawn = true;
|
|
@@ -7488,11 +8109,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7488
8109
|
euler.set(piece.rx, piece.ry, piece.rz);
|
|
7489
8110
|
quaternion.setFromEuler(euler);
|
|
7490
8111
|
matrix.compose(position.set(piece.x, piece.y, piece.z), quaternion, scale.set(piece.sx * shrink, piece.sy * shrink, piece.sz * shrink));
|
|
7491
|
-
|
|
7492
|
-
|
|
8112
|
+
mesh2.setMatrixAt(index, matrix);
|
|
8113
|
+
mesh2.setColorAt(index, colour.setHex(piece.color));
|
|
7493
8114
|
}
|
|
7494
|
-
|
|
7495
|
-
if (
|
|
8115
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
8116
|
+
if (mesh2.instanceColor) mesh2.instanceColor.needsUpdate = true;
|
|
7496
8117
|
return drawn;
|
|
7497
8118
|
},
|
|
7498
8119
|
dispose() {
|
|
@@ -7549,11 +8170,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7549
8170
|
const dryMesh = new THREE.InstancedMesh(geometry, dry, DECAL_CAPACITY);
|
|
7550
8171
|
const group = new THREE.Group();
|
|
7551
8172
|
group.name = "workshop-decals";
|
|
7552
|
-
for (const
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
group.add(
|
|
8173
|
+
for (const mesh2 of [wetMesh, dryMesh]) {
|
|
8174
|
+
mesh2.frustumCulled = false;
|
|
8175
|
+
mesh2.renderOrder = 1;
|
|
8176
|
+
mesh2.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
|
|
8177
|
+
group.add(mesh2);
|
|
7557
8178
|
}
|
|
7558
8179
|
const hidden = new THREE.Matrix4().makeScale(0, 0, 0);
|
|
7559
8180
|
const colour = new THREE.Color();
|
|
@@ -7590,13 +8211,13 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7590
8211
|
quaternion.multiply(turn.setFromAxisAngle(forward, index * 2.399963));
|
|
7591
8212
|
const offset = 4e-3 + index % 40 * 4e-4;
|
|
7592
8213
|
matrix.compose(position.set(decal2.x + normal.x * offset, decal2.y + normal.y * offset, decal2.z + normal.z * offset), quaternion, scale.set(look.sx, look.sy, 1));
|
|
7593
|
-
const
|
|
7594
|
-
|
|
7595
|
-
|
|
8214
|
+
const mesh2 = look.dried ? dryMesh : wetMesh;
|
|
8215
|
+
mesh2.setMatrixAt(index, matrix);
|
|
8216
|
+
mesh2.setColorAt(index, colour);
|
|
7596
8217
|
}
|
|
7597
|
-
for (const
|
|
7598
|
-
|
|
7599
|
-
if (
|
|
8218
|
+
for (const mesh2 of [wetMesh, dryMesh]) {
|
|
8219
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
8220
|
+
if (mesh2.instanceColor) mesh2.instanceColor.needsUpdate = true;
|
|
7600
8221
|
}
|
|
7601
8222
|
return drawn;
|
|
7602
8223
|
},
|
|
@@ -7610,10 +8231,10 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7610
8231
|
function ringLayer(THREE, pool) {
|
|
7611
8232
|
const geometry = new THREE.RingGeometry(0.86, 1, 40);
|
|
7612
8233
|
const material = new THREE.MeshBasicMaterial({ color: 16777215, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide });
|
|
7613
|
-
const
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
8234
|
+
const mesh2 = new THREE.InstancedMesh(geometry, material, RING_CAPACITY3);
|
|
8235
|
+
mesh2.frustumCulled = false;
|
|
8236
|
+
mesh2.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
|
|
8237
|
+
mesh2.name = "workshop-rings";
|
|
7617
8238
|
const hidden = new THREE.Matrix4().makeScale(0, 0, 0);
|
|
7618
8239
|
const colour = new THREE.Color();
|
|
7619
8240
|
const normal = new THREE.Vector3();
|
|
@@ -7622,16 +8243,16 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7622
8243
|
const position = new THREE.Vector3();
|
|
7623
8244
|
const scale = new THREE.Vector3();
|
|
7624
8245
|
const matrix = new THREE.Matrix4();
|
|
7625
|
-
|
|
7626
|
-
for (let index = 0; index < RING_CAPACITY3; index++)
|
|
8246
|
+
mesh2.setColorAt(0, colour.setHex(0));
|
|
8247
|
+
for (let index = 0; index < RING_CAPACITY3; index++) mesh2.setMatrixAt(index, hidden);
|
|
7627
8248
|
return {
|
|
7628
|
-
object:
|
|
8249
|
+
object: mesh2,
|
|
7629
8250
|
sync() {
|
|
7630
8251
|
let drawn = false;
|
|
7631
8252
|
for (let index = 0; index < RING_CAPACITY3; index++) {
|
|
7632
8253
|
const ring2 = pool.rings[index];
|
|
7633
8254
|
if (!ring2.on) {
|
|
7634
|
-
|
|
8255
|
+
mesh2.setMatrixAt(index, hidden);
|
|
7635
8256
|
continue;
|
|
7636
8257
|
}
|
|
7637
8258
|
drawn = true;
|
|
@@ -7639,11 +8260,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7639
8260
|
const radius = ring2.from + (ring2.to - ring2.from) * (1 - Math.pow(1 - k, 2));
|
|
7640
8261
|
quaternion.setFromUnitVectors(forward, normal.set(ring2.normal[0], ring2.normal[1], ring2.normal[2]));
|
|
7641
8262
|
matrix.compose(position.set(ring2.point[0], ring2.point[1], ring2.point[2]), quaternion, scale.set(radius, radius, 1));
|
|
7642
|
-
|
|
7643
|
-
|
|
8263
|
+
mesh2.setMatrixAt(index, matrix);
|
|
8264
|
+
mesh2.setColorAt(index, colour.setHex(ring2.color).multiplyScalar(ring2.hold ? ring2.hold : 1 - k));
|
|
7644
8265
|
}
|
|
7645
|
-
|
|
7646
|
-
if (
|
|
8266
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
8267
|
+
if (mesh2.instanceColor) mesh2.instanceColor.needsUpdate = true;
|
|
7647
8268
|
return drawn;
|
|
7648
8269
|
},
|
|
7649
8270
|
dispose() {
|
|
@@ -7659,11 +8280,14 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7659
8280
|
spriteLayer(THREE, engine.add, true, 1, pointScale),
|
|
7660
8281
|
spriteLayer(THREE, engine.normal, false, 0.55, pointScale),
|
|
7661
8282
|
streakLayer(THREE, engine.streaks),
|
|
8283
|
+
rainLayer(THREE, engine.rain),
|
|
7662
8284
|
debrisLayer(THREE, engine.debris),
|
|
7663
8285
|
decalLayer(THREE, engine.decals),
|
|
7664
8286
|
ringLayer(THREE, engine.rings)
|
|
7665
8287
|
];
|
|
7666
8288
|
for (const layer2 of layers) group.add(layer2.object);
|
|
8289
|
+
const meshes = createMeshLayer(THREE, engine.meshes);
|
|
8290
|
+
group.add(meshes.group);
|
|
7667
8291
|
const flashLights = engine.lights.lights.map(() => new THREE.PointLight(16760944, 0, 14));
|
|
7668
8292
|
const fireLights = engine.lights.fire.map(() => new THREE.PointLight(FIRE_LIGHT_COLOR, 0, FIRE_LIGHT_DISTANCE));
|
|
7669
8293
|
for (const light of [...flashLights, ...fireLights]) group.add(light);
|
|
@@ -7672,6 +8296,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7672
8296
|
sync() {
|
|
7673
8297
|
let drawCalls = 0;
|
|
7674
8298
|
for (const layer2 of layers) if (layer2.sync()) drawCalls++;
|
|
8299
|
+
drawCalls += meshes.sync();
|
|
7675
8300
|
engine.lights.lights.forEach((source, index) => {
|
|
7676
8301
|
const light = flashLights[index];
|
|
7677
8302
|
light.position.set(source.x, source.y, source.z);
|
|
@@ -7688,6 +8313,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7688
8313
|
},
|
|
7689
8314
|
dispose() {
|
|
7690
8315
|
for (const layer2 of layers) layer2.dispose();
|
|
8316
|
+
meshes.dispose();
|
|
7691
8317
|
group.clear();
|
|
7692
8318
|
}
|
|
7693
8319
|
};
|
|
@@ -7803,8 +8429,10 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7803
8429
|
return world.play(request.effect, request.point, {
|
|
7804
8430
|
...request.direction ? { direction: request.direction } : {},
|
|
7805
8431
|
...request.normal ? { normal: request.normal } : {},
|
|
8432
|
+
...request.orientation ? { orientation: request.orientation } : {},
|
|
7806
8433
|
...request.seed !== void 0 ? { seed: request.seed } : {},
|
|
7807
|
-
...request.param !== void 0 ? { param: request.param } : {}
|
|
8434
|
+
...request.param !== void 0 ? { param: request.param } : {},
|
|
8435
|
+
...request.values ? { values: request.values } : {}
|
|
7808
8436
|
});
|
|
7809
8437
|
},
|
|
7810
8438
|
stop: (handle) => world.stop(handle),
|
|
@@ -7965,11 +8593,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7965
8593
|
* Bullet holes that stay on a fragment (`Fragment.marks`): dark discs that are children of its mesh, so they fall, spin and settle with it. The mesh is
|
|
7966
8594
|
* a unit box scaled to the fragment, so each disc is scaled back; exact for a mark on a face, which is where a bullet hole is.
|
|
7967
8595
|
*/
|
|
7968
|
-
addMarks(
|
|
8596
|
+
addMarks(mesh2, f) {
|
|
7969
8597
|
if (!f.marks?.length) return;
|
|
7970
8598
|
this.markGeometry ?? (this.markGeometry = new this.THREE.CircleGeometry(1, 10));
|
|
7971
8599
|
this.markMaterial ?? (this.markMaterial = new this.THREE.MeshBasicMaterial({ color: 723465, depthWrite: false, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 }));
|
|
7972
|
-
const sc =
|
|
8600
|
+
const sc = mesh2.scale;
|
|
7973
8601
|
for (const mark of f.marks) {
|
|
7974
8602
|
const disc = new this.THREE.Mesh(this.markGeometry, this.markMaterial);
|
|
7975
8603
|
const radius = Math.max(4e-3, mark.diameter) * 0.6;
|
|
@@ -7977,22 +8605,22 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
7977
8605
|
disc.position.set(mark.point[0] / sc.x + n.x * 2e-3 / sc.x, mark.point[1] / sc.y + n.y * 2e-3 / sc.y, mark.point[2] / sc.z + n.z * 2e-3 / sc.z);
|
|
7978
8606
|
disc.quaternion.setFromUnitVectors(this.w.set(0, 0, 1), n);
|
|
7979
8607
|
disc.scale.set(radius / sc.x, radius / sc.y, radius / sc.z);
|
|
7980
|
-
|
|
8608
|
+
mesh2.add(disc);
|
|
7981
8609
|
}
|
|
7982
8610
|
}
|
|
7983
8611
|
/** Create the mesh of a fragment and start its motion. `maxAllowed` is the live budget. */
|
|
7984
8612
|
spawn(f, material, home, maxAllowed) {
|
|
7985
8613
|
const geo = f.shape === "shard" ? this.shardGeometry(hashString(f.id)) : this.box;
|
|
7986
|
-
const
|
|
7987
|
-
|
|
7988
|
-
|
|
8614
|
+
const mesh2 = new this.THREE.Mesh(geo, material);
|
|
8615
|
+
mesh2.position.set(f.center[0], f.center[1], f.center[2]);
|
|
8616
|
+
mesh2.quaternion.set(f.rotation[0], f.rotation[1], f.rotation[2], f.rotation[3]).normalize();
|
|
7989
8617
|
const sz = f.size;
|
|
7990
8618
|
const sc = new this.THREE.Vector3(Math.max(5e-3, sz[0]), Math.max(5e-3, sz[1]), Math.max(3e-3, sz[2]));
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
this.o.scene.add(
|
|
8619
|
+
mesh2.scale.copy(sc);
|
|
8620
|
+
mesh2.castShadow = true;
|
|
8621
|
+
this.o.scene.add(mesh2);
|
|
7994
8622
|
const live = {
|
|
7995
|
-
mesh,
|
|
8623
|
+
mesh: mesh2,
|
|
7996
8624
|
home,
|
|
7997
8625
|
vel: new this.THREE.Vector3(f.velocity[0], f.velocity[1], f.velocity[2]),
|
|
7998
8626
|
ang: new this.THREE.Vector3(f.angularVelocity[0], f.angularVelocity[1], f.angularVelocity[2]),
|
|
@@ -8013,8 +8641,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8013
8641
|
alive--;
|
|
8014
8642
|
}
|
|
8015
8643
|
}
|
|
8016
|
-
this.addMarks(
|
|
8017
|
-
return
|
|
8644
|
+
this.addMarks(mesh2, f);
|
|
8645
|
+
return mesh2;
|
|
8018
8646
|
}
|
|
8019
8647
|
/** Add velocity to every fragment within `radius` of a point (blasts). */
|
|
8020
8648
|
blast(point, radius, speed) {
|
|
@@ -8053,24 +8681,24 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8053
8681
|
}
|
|
8054
8682
|
}
|
|
8055
8683
|
step(f, dt, g) {
|
|
8056
|
-
const
|
|
8684
|
+
const mesh2 = f.mesh;
|
|
8057
8685
|
f.vel.y -= g * dt;
|
|
8058
|
-
|
|
8686
|
+
mesh2.position.addScaledVector(f.vel, dt);
|
|
8059
8687
|
const w = f.ang.length();
|
|
8060
8688
|
if (w > 1e-5) {
|
|
8061
8689
|
this.dq.setFromAxisAngle(this.v.copy(f.ang).multiplyScalar(1 / w), w * dt);
|
|
8062
|
-
|
|
8690
|
+
mesh2.quaternion.premultiply(this.dq).normalize();
|
|
8063
8691
|
}
|
|
8064
|
-
this.m.makeRotationFromQuaternion(
|
|
8692
|
+
this.m.makeRotationFromQuaternion(mesh2.quaternion);
|
|
8065
8693
|
const e = this.m.elements;
|
|
8066
8694
|
const h = f.half;
|
|
8067
8695
|
const sc = f.dying ? f.fade : 1;
|
|
8068
8696
|
const ext = (Math.abs(e[1]) * h.x + Math.abs(e[5]) * h.y + Math.abs(e[9]) * h.z) * sc;
|
|
8069
|
-
const gy = this.o.groundAt(
|
|
8697
|
+
const gy = this.o.groundAt(mesh2.position.x, mesh2.position.z);
|
|
8070
8698
|
let contact = false;
|
|
8071
|
-
if (
|
|
8699
|
+
if (mesh2.position.y - ext < gy) {
|
|
8072
8700
|
contact = true;
|
|
8073
|
-
|
|
8701
|
+
mesh2.position.y = gy + ext;
|
|
8074
8702
|
if (f.vel.y < -0.6) {
|
|
8075
8703
|
f.vel.y = -f.vel.y * 0.25;
|
|
8076
8704
|
f.vel.x *= 0.7;
|
|
@@ -8103,8 +8731,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8103
8731
|
}
|
|
8104
8732
|
/** Tip the fragment towards lying on its flattest face. */
|
|
8105
8733
|
settle(f, dt) {
|
|
8106
|
-
const
|
|
8107
|
-
this.m.makeRotationFromQuaternion(
|
|
8734
|
+
const mesh2 = f.mesh;
|
|
8735
|
+
this.m.makeRotationFromQuaternion(mesh2.quaternion);
|
|
8108
8736
|
const e = this.m.elements;
|
|
8109
8737
|
const up = [e[1], e[5], e[9]];
|
|
8110
8738
|
const half = [f.half.x, f.half.y, f.half.z];
|
|
@@ -8119,8 +8747,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8119
8747
|
this.v.set(e[axis2 * 4], e[axis2 * 4 + 1], e[axis2 * 4 + 2]).multiplyScalar(sign);
|
|
8120
8748
|
this.w.set(0, 1, 0);
|
|
8121
8749
|
this.dq.setFromUnitVectors(this.v, this.w);
|
|
8122
|
-
this.q.copy(this.dq).multiply(
|
|
8123
|
-
|
|
8750
|
+
this.q.copy(this.dq).multiply(mesh2.quaternion);
|
|
8751
|
+
mesh2.quaternion.slerp(this.q, clamp6(dt * 7, 0, 1));
|
|
8124
8752
|
}
|
|
8125
8753
|
/** Remove the fragments of one object (after `restore`). */
|
|
8126
8754
|
removeHome(home) {
|
|
@@ -8192,13 +8820,13 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8192
8820
|
}
|
|
8193
8821
|
}
|
|
8194
8822
|
while (this.spots.length >= this.cap) this.remove(this.spots[0]);
|
|
8195
|
-
const
|
|
8823
|
+
const mesh2 = new this.THREE.Mesh(this.geometry, this.material(kind, color));
|
|
8196
8824
|
const y = this.groundAt(x, z) + 4e-3 + this.spots.length % 8 * 4e-4;
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
this.scene.add(
|
|
8201
|
-
this.spots.push({ mesh, kind, home, x, z, radius: 1e-3, target: Math.min(MAX_RADIUS, radius) });
|
|
8825
|
+
mesh2.position.set(x, y, z);
|
|
8826
|
+
mesh2.scale.setScalar(1e-3);
|
|
8827
|
+
mesh2.renderOrder = 1;
|
|
8828
|
+
this.scene.add(mesh2);
|
|
8829
|
+
this.spots.push({ mesh: mesh2, kind, home, x, z, radius: 1e-3, target: Math.min(MAX_RADIUS, radius) });
|
|
8202
8830
|
}
|
|
8203
8831
|
remove(s) {
|
|
8204
8832
|
const i = this.spots.indexOf(s);
|
|
@@ -8578,7 +9206,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8578
9206
|
/** Bars drawn now, over every part. */
|
|
8579
9207
|
get count() {
|
|
8580
9208
|
let n = 0;
|
|
8581
|
-
for (const
|
|
9209
|
+
for (const mesh2 of this.cages.values()) n += mesh2.count;
|
|
8582
9210
|
return n;
|
|
8583
9211
|
}
|
|
8584
9212
|
/** Meshes of the live cages (tests and picking). */
|
|
@@ -8589,25 +9217,25 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8589
9217
|
set(key, bars) {
|
|
8590
9218
|
this.remove(key);
|
|
8591
9219
|
if (bars.length === 0) return;
|
|
8592
|
-
const
|
|
9220
|
+
const mesh2 = new this.THREE.InstancedMesh(this.geometry, this.material, bars.length);
|
|
8593
9221
|
bars.forEach(([a, b], i) => {
|
|
8594
9222
|
this.dir.set(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
8595
9223
|
const length = this.dir.length();
|
|
8596
9224
|
this.mid.set((a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2);
|
|
8597
9225
|
this.q.setFromUnitVectors(this.up, length > 1e-9 ? this.dir.divideScalar(length) : this.up);
|
|
8598
9226
|
this.m.compose(this.mid, this.q, this.scale.set(1, Math.max(length, 1e-4), 1));
|
|
8599
|
-
|
|
9227
|
+
mesh2.setMatrixAt(i, this.m);
|
|
8600
9228
|
});
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
this.scene.add(
|
|
8604
|
-
this.cages.set(key,
|
|
9229
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
9230
|
+
mesh2.castShadow = true;
|
|
9231
|
+
this.scene.add(mesh2);
|
|
9232
|
+
this.cages.set(key, mesh2);
|
|
8605
9233
|
}
|
|
8606
9234
|
remove(key) {
|
|
8607
|
-
const
|
|
8608
|
-
if (!
|
|
8609
|
-
this.scene.remove(
|
|
8610
|
-
|
|
9235
|
+
const mesh2 = this.cages.get(key);
|
|
9236
|
+
if (!mesh2) return;
|
|
9237
|
+
this.scene.remove(mesh2);
|
|
9238
|
+
mesh2.dispose();
|
|
8611
9239
|
this.cages.delete(key);
|
|
8612
9240
|
}
|
|
8613
9241
|
/** Remove the cages of every part of `object` (keys are `object|part`). */
|
|
@@ -8626,9 +9254,9 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8626
9254
|
|
|
8627
9255
|
// ../game-destruction/dist/index.js
|
|
8628
9256
|
var EPS = 1e-9;
|
|
8629
|
-
var
|
|
9257
|
+
var IDENTITY2 = [0, 0, 0, 1];
|
|
8630
9258
|
var quat = {
|
|
8631
|
-
identity: () => [
|
|
9259
|
+
identity: () => [IDENTITY2[0], IDENTITY2[1], IDENTITY2[2], IDENTITY2[3]],
|
|
8632
9260
|
/** Hamilton product `a * b` (apply `b` first, then `a`). */
|
|
8633
9261
|
mul: (a, b) => [
|
|
8634
9262
|
a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1],
|
|
@@ -9951,25 +10579,25 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
9951
10579
|
/**
|
|
9952
10580
|
* @param range vertex range `[v0, v1)` of a merged mesh this part is drawn by (see `MeshRange`); `hosts` caches the shared state per mesh for one `bind`.
|
|
9953
10581
|
*/
|
|
9954
|
-
makeMeshVis(
|
|
10582
|
+
makeMeshVis(mesh2, home, range, hosts) {
|
|
9955
10583
|
let host = null;
|
|
9956
10584
|
if (range) {
|
|
9957
|
-
host = hosts?.get(
|
|
10585
|
+
host = hosts?.get(mesh2) ?? null;
|
|
9958
10586
|
if (!host) {
|
|
9959
|
-
host = { mesh, origGeometry:
|
|
9960
|
-
hosts?.set(
|
|
10587
|
+
host = { mesh: mesh2, origGeometry: mesh2.geometry, origMaterial: mesh2.material, ownGeo: false, work: null, ownMat: false, sharers: [] };
|
|
10588
|
+
hosts?.set(mesh2, host);
|
|
9961
10589
|
}
|
|
9962
10590
|
}
|
|
9963
10591
|
const mv = {
|
|
9964
|
-
mesh,
|
|
10592
|
+
mesh: mesh2,
|
|
9965
10593
|
home,
|
|
9966
|
-
origGeometry:
|
|
9967
|
-
origMaterial:
|
|
9968
|
-
origVisible:
|
|
9969
|
-
origParent:
|
|
9970
|
-
origPosition:
|
|
9971
|
-
origQuaternion:
|
|
9972
|
-
origScale:
|
|
10594
|
+
origGeometry: mesh2.geometry,
|
|
10595
|
+
origMaterial: mesh2.material,
|
|
10596
|
+
origVisible: mesh2.visible,
|
|
10597
|
+
origParent: mesh2.parent,
|
|
10598
|
+
origPosition: mesh2.position.clone(),
|
|
10599
|
+
origQuaternion: mesh2.quaternion.clone(),
|
|
10600
|
+
origScale: mesh2.scale.clone(),
|
|
9973
10601
|
ownMat: false,
|
|
9974
10602
|
ownGeo: false,
|
|
9975
10603
|
work: null,
|
|
@@ -10094,15 +10722,15 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10094
10722
|
* Returns false when nothing was changed (too far, low quality on a heavy mesh, or no editable positions).
|
|
10095
10723
|
*/
|
|
10096
10724
|
applyDent(mv, worldPoint, worldNormal, dent) {
|
|
10097
|
-
const
|
|
10725
|
+
const mesh2 = mv.mesh;
|
|
10098
10726
|
if (this.lowQuality && this.vertexCount(mv) > 2e4) return false;
|
|
10099
|
-
|
|
10100
|
-
const s =
|
|
10101
|
-
const lp =
|
|
10102
|
-
const ln = this.b.copy(worldNormal).transformDirection(this.m4.copy(
|
|
10727
|
+
mesh2.updateWorldMatrix(true, false);
|
|
10728
|
+
const s = mesh2.matrixWorld.getMaxScaleOnAxis() || 1;
|
|
10729
|
+
const lp = mesh2.worldToLocal(this.a.copy(worldPoint));
|
|
10730
|
+
const ln = this.b.copy(worldNormal).transformDirection(this.m4.copy(mesh2.matrixWorld).invert()).normalize();
|
|
10103
10731
|
const r = dent.radius / s;
|
|
10104
10732
|
const depth = dent.depth / s;
|
|
10105
|
-
const geo =
|
|
10733
|
+
const geo = mesh2.geometry;
|
|
10106
10734
|
let bb;
|
|
10107
10735
|
if (mv.host) bb = this.localBox(mv, this.lbox);
|
|
10108
10736
|
else {
|
|
@@ -10112,7 +10740,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10112
10740
|
if (bb && !bb.isEmpty() && bb.distanceToPoint(lp) > r) return false;
|
|
10113
10741
|
if (!this.ownGeometry(mv)) return false;
|
|
10114
10742
|
const work = mv.host ? mv.host.work : mv.work;
|
|
10115
|
-
const pos = positionAttr(
|
|
10743
|
+
const pos = positionAttr(mesh2.geometry);
|
|
10116
10744
|
const r2 = r * r;
|
|
10117
10745
|
let touched = false;
|
|
10118
10746
|
const px = lp.x;
|
|
@@ -10178,11 +10806,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10178
10806
|
// Decals
|
|
10179
10807
|
// ------------------------------------------------------------------------------------------------------------------------------------
|
|
10180
10808
|
/** Decal pose in mesh space: position and a rotation taking +Z to the surface normal. */
|
|
10181
|
-
decalPose(
|
|
10182
|
-
|
|
10183
|
-
const s =
|
|
10184
|
-
const ln = worldNormal.clone().transformDirection(this.m4.copy(
|
|
10185
|
-
const pos =
|
|
10809
|
+
decalPose(mesh2, worldPoint, worldNormal, lift) {
|
|
10810
|
+
mesh2.updateWorldMatrix(true, false);
|
|
10811
|
+
const s = mesh2.matrixWorld.getMaxScaleOnAxis() || 1;
|
|
10812
|
+
const ln = worldNormal.clone().transformDirection(this.m4.copy(mesh2.matrixWorld).invert()).normalize();
|
|
10813
|
+
const pos = mesh2.worldToLocal(worldPoint.clone()).addScaledVector(ln, lift / s);
|
|
10186
10814
|
const quat2 = new this.THREE.Quaternion().setFromUnitVectors(new this.THREE.Vector3(0, 0, 1), ln);
|
|
10187
10815
|
return { s, pos, quat: quat2 };
|
|
10188
10816
|
}
|
|
@@ -10318,7 +10946,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10318
10946
|
if (Math.abs(m - pv.meltApplied) < 0.01) return;
|
|
10319
10947
|
pv.meltApplied = m;
|
|
10320
10948
|
for (const mv of pv.meshes) {
|
|
10321
|
-
const
|
|
10949
|
+
const mesh2 = mv.mesh;
|
|
10322
10950
|
if (mv.host) {
|
|
10323
10951
|
mv.meltApplied = m;
|
|
10324
10952
|
mv.touched = true;
|
|
@@ -10326,27 +10954,27 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10326
10954
|
continue;
|
|
10327
10955
|
}
|
|
10328
10956
|
if (mv.meltApplied === 0 && m > 0) {
|
|
10329
|
-
|
|
10330
|
-
mv.bottomY = this.box.setFromObject(
|
|
10957
|
+
mesh2.updateWorldMatrix(true, false);
|
|
10958
|
+
mv.bottomY = this.box.setFromObject(mesh2).min.y;
|
|
10331
10959
|
}
|
|
10332
10960
|
mv.meltApplied = m;
|
|
10333
10961
|
mv.moved = true;
|
|
10334
10962
|
const sy = lerp5(1, 0.25, m);
|
|
10335
10963
|
const sxz = 1 + 0.18 * m;
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
const bottom = this.box.setFromObject(
|
|
10964
|
+
mesh2.scale.set(mv.origScale.x * sxz, mv.origScale.y * sy, mv.origScale.z * sxz);
|
|
10965
|
+
mesh2.position.copy(mv.origPosition);
|
|
10966
|
+
mesh2.updateWorldMatrix(true, false);
|
|
10967
|
+
const bottom = this.box.setFromObject(mesh2).min.y;
|
|
10340
10968
|
const dy = mv.bottomY - bottom;
|
|
10341
|
-
if (Math.abs(dy) > 1e-6 &&
|
|
10342
|
-
|
|
10343
|
-
const inv = this.m4.copy(
|
|
10969
|
+
if (Math.abs(dy) > 1e-6 && mesh2.parent) {
|
|
10970
|
+
mesh2.parent.updateWorldMatrix(true, false);
|
|
10971
|
+
const inv = this.m4.copy(mesh2.parent.matrixWorld).invert();
|
|
10344
10972
|
this.a.set(0, dy, 0).applyMatrix4(inv);
|
|
10345
10973
|
this.b.set(0, 0, 0).applyMatrix4(inv);
|
|
10346
|
-
|
|
10974
|
+
mesh2.position.copy(mv.origPosition).add(this.a.sub(this.b));
|
|
10347
10975
|
}
|
|
10348
10976
|
if (!(this.lowQuality && this.vertexCount(mv) > 2e4) && this.ownGeometry(mv)) {
|
|
10349
|
-
this.writePositions(mv, positionAttr(
|
|
10977
|
+
this.writePositions(mv, positionAttr(mesh2.geometry));
|
|
10350
10978
|
}
|
|
10351
10979
|
}
|
|
10352
10980
|
}
|
|
@@ -10424,10 +11052,10 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10424
11052
|
const sy = lerp5(1, 0.25, melt);
|
|
10425
11053
|
const sxz = 1 + 0.18 * melt;
|
|
10426
11054
|
for (let i = range[0] * 3, v = 0; i < range[1] * 3; i += 3, v++) {
|
|
10427
|
-
const
|
|
11055
|
+
const noise = (Math.imul(v + 1, 2654435761) >>> 0) % 1e3 / 1e3;
|
|
10428
11056
|
arr[i] = cx + (work[i] - cx) * sxz;
|
|
10429
11057
|
arr[i + 2] = cz + (work[i + 2] - cz) * sxz;
|
|
10430
|
-
arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy -
|
|
11058
|
+
arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy - noise * melt * h * 0.04);
|
|
10431
11059
|
}
|
|
10432
11060
|
}
|
|
10433
11061
|
/** The colour attribute of the host's current geometry (created white when there is none) with vertex colours switched on in its material. */
|
|
@@ -10619,30 +11247,30 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
10619
11247
|
this.restoreRanged(mv);
|
|
10620
11248
|
return;
|
|
10621
11249
|
}
|
|
10622
|
-
const
|
|
11250
|
+
const mesh2 = mv.mesh;
|
|
10623
11251
|
for (const d of mv.decals) this.disposeDecal(d);
|
|
10624
11252
|
mv.decals.length = 0;
|
|
10625
11253
|
if (mv.ownGeo) {
|
|
10626
|
-
|
|
10627
|
-
|
|
11254
|
+
mesh2.geometry.dispose();
|
|
11255
|
+
mesh2.geometry = mv.origGeometry;
|
|
10628
11256
|
mv.ownGeo = false;
|
|
10629
11257
|
mv.work = null;
|
|
10630
11258
|
}
|
|
10631
11259
|
if (mv.ownMat) {
|
|
10632
|
-
for (const m of materialsOf(
|
|
10633
|
-
|
|
11260
|
+
for (const m of materialsOf(mesh2.material)) m.dispose();
|
|
11261
|
+
mesh2.material = mv.origMaterial;
|
|
10634
11262
|
mv.ownMat = false;
|
|
10635
11263
|
mv.baseColors = null;
|
|
10636
11264
|
}
|
|
10637
|
-
|
|
10638
|
-
if (mv.origParent &&
|
|
10639
|
-
mv.origParent.add(
|
|
11265
|
+
mesh2.visible = mv.origVisible;
|
|
11266
|
+
if (mv.origParent && mesh2.parent !== mv.origParent) {
|
|
11267
|
+
mv.origParent.add(mesh2);
|
|
10640
11268
|
mv.moved = true;
|
|
10641
11269
|
}
|
|
10642
11270
|
if (mv.moved) {
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
11271
|
+
mesh2.position.copy(mv.origPosition);
|
|
11272
|
+
mesh2.quaternion.copy(mv.origQuaternion);
|
|
11273
|
+
mesh2.scale.copy(mv.origScale);
|
|
10646
11274
|
mv.moved = false;
|
|
10647
11275
|
}
|
|
10648
11276
|
mv.meltApplied = 0;
|
|
@@ -11780,6 +12408,56 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
11780
12408
|
};
|
|
11781
12409
|
}
|
|
11782
12410
|
var GAME_SFX_BANK = { id: "game_sfx", sounds: [...GAME_SFX_CLASSES, GAME_SFX_FALLBACK].map((row) => noiseClassRecipe(row)) };
|
|
12411
|
+
var ATTACK = 2e-3;
|
|
12412
|
+
function lengthOf(d, attack) {
|
|
12413
|
+
if (typeof d === "number") return attack + d;
|
|
12414
|
+
if (Array.isArray(d)) return [attack + d[0], attack + d[1]];
|
|
12415
|
+
return { ...d, add: (d.add ?? 0) + attack };
|
|
12416
|
+
}
|
|
12417
|
+
var envelope = (attack) => [
|
|
12418
|
+
[0, 1e-4, "set", "fixed"],
|
|
12419
|
+
[attack, 1, "exp"],
|
|
12420
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
12421
|
+
];
|
|
12422
|
+
function sceneNoise(o) {
|
|
12423
|
+
const a = o.a ?? ATTACK;
|
|
12424
|
+
const over = typeof o.d === "number" ? o.d : 0;
|
|
12425
|
+
return {
|
|
12426
|
+
filters: {
|
|
12427
|
+
mode: "serial",
|
|
12428
|
+
bank: [{ type: o.type ?? "lowpass", frequency: o.f2 === void 0 ? { set: o.f } : { set: o.f, to: o.f2, curve: "exp", over }, q: o.q ?? 0.7 }]
|
|
12429
|
+
},
|
|
12430
|
+
duration: lengthOf(o.d, a),
|
|
12431
|
+
gain: o.vol,
|
|
12432
|
+
...o.delay === void 0 ? {} : { at: o.delay },
|
|
12433
|
+
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
12434
|
+
source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
|
|
12435
|
+
envelope: envelope(a)
|
|
12436
|
+
};
|
|
12437
|
+
}
|
|
12438
|
+
function sceneTone(o) {
|
|
12439
|
+
return {
|
|
12440
|
+
source: { kind: "osc", wave: o.wave ?? "sine", frequency: { from: o.f, to: o.f2 ?? "from", curve: "exp", over: "duration" } },
|
|
12441
|
+
duration: lengthOf(o.d, ATTACK),
|
|
12442
|
+
gain: o.vol,
|
|
12443
|
+
...o.delay === void 0 ? {} : { at: o.delay },
|
|
12444
|
+
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
12445
|
+
envelope: envelope(ATTACK)
|
|
12446
|
+
};
|
|
12447
|
+
}
|
|
12448
|
+
var sceneMany = (count, make) => Array.from({ length: count }, make);
|
|
12449
|
+
function sceneRecipe(id, layers, line, options = {}) {
|
|
12450
|
+
return {
|
|
12451
|
+
id,
|
|
12452
|
+
bus: options.bus ?? "world",
|
|
12453
|
+
pan: true,
|
|
12454
|
+
layers,
|
|
12455
|
+
falloff: DISTANCE_CURVES.art_scene,
|
|
12456
|
+
...options.vars ? { vars: options.vars } : {},
|
|
12457
|
+
...options.group ? { group: options.group } : {},
|
|
12458
|
+
sources: [`cena:${line}`]
|
|
12459
|
+
};
|
|
12460
|
+
}
|
|
11783
12461
|
var BENCH_BANK = {
|
|
11784
12462
|
id: "audio_bench",
|
|
11785
12463
|
sounds: [
|
|
@@ -11827,88 +12505,42 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
11827
12505
|
};
|
|
11828
12506
|
|
|
11829
12507
|
// src/audio/recipes.ts
|
|
11830
|
-
var
|
|
11831
|
-
var lengthOf = (d, attack) => {
|
|
11832
|
-
if (typeof d === "number") return attack + d;
|
|
11833
|
-
if (Array.isArray(d)) return [attack + d[0], attack + d[1]];
|
|
11834
|
-
return { ...d, add: (d.add ?? 0) + attack };
|
|
11835
|
-
};
|
|
11836
|
-
var envelope = (attack) => [
|
|
11837
|
-
[0, 1e-4, "set", "fixed"],
|
|
11838
|
-
[attack, 1, "exp"],
|
|
11839
|
-
["1d", 1e-4, "exp", "fixed"]
|
|
11840
|
-
];
|
|
11841
|
-
function noise(o) {
|
|
11842
|
-
const a = o.a ?? ATTACK;
|
|
11843
|
-
const over = typeof o.d === "number" ? o.d : 0;
|
|
11844
|
-
return {
|
|
11845
|
-
filters: {
|
|
11846
|
-
mode: "serial",
|
|
11847
|
-
bank: [{ type: o.type ?? "lowpass", frequency: o.f2 === void 0 ? { set: o.f } : { set: o.f, to: o.f2, curve: "exp", over }, q: o.q ?? 0.7 }]
|
|
11848
|
-
},
|
|
11849
|
-
duration: lengthOf(o.d, a),
|
|
11850
|
-
gain: o.vol,
|
|
11851
|
-
...o.delay === void 0 ? {} : { at: o.delay },
|
|
11852
|
-
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
11853
|
-
source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
|
|
11854
|
-
envelope: envelope(a)
|
|
11855
|
-
};
|
|
11856
|
-
}
|
|
11857
|
-
function tone(o) {
|
|
11858
|
-
return {
|
|
11859
|
-
source: { kind: "osc", wave: o.wave ?? "sine", frequency: { from: o.f, to: o.f2 ?? "from", curve: "exp", over: "duration" } },
|
|
11860
|
-
duration: lengthOf(o.d, ATTACK),
|
|
11861
|
-
gain: o.vol,
|
|
11862
|
-
...o.delay === void 0 ? {} : { at: o.delay },
|
|
11863
|
-
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
11864
|
-
envelope: envelope(ATTACK)
|
|
11865
|
-
};
|
|
11866
|
-
}
|
|
11867
|
-
var many = (count, make) => Array.from({ length: count }, make);
|
|
11868
|
-
var scene = (id, layers, line, vars) => ({
|
|
11869
|
-
id,
|
|
11870
|
-
bus: "world",
|
|
11871
|
-
pan: true,
|
|
11872
|
-
layers,
|
|
11873
|
-
falloff: DISTANCE_CURVES.art_scene,
|
|
11874
|
-
...vars ? { vars } : {},
|
|
11875
|
-
sources: [`cena:${line}`]
|
|
11876
|
-
});
|
|
12508
|
+
var scene = (id, layers, line, vars) => sceneRecipe(id, layers, line, vars ? { vars } : {});
|
|
11877
12509
|
var boomLayers = (big) => [
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
...big ? [
|
|
11882
|
-
...
|
|
12510
|
+
sceneNoise({ f: 1200, f2: 120, d: 1.8, vol: 2, wet: 1.2 }),
|
|
12511
|
+
sceneTone({ f: 65, f2: 24, d: 1, vol: 1.8 }),
|
|
12512
|
+
sceneNoise({ type: "highpass", f: 1500, d: 0.2, vol: 0.8 }),
|
|
12513
|
+
...big ? [sceneNoise({ f: 500, f2: 90, a: 0.2, d: 2.4, vol: 1.2, wet: 1, delay: 0.15 })] : [],
|
|
12514
|
+
...sceneMany(8, () => sceneTone({ f: [2600, 5600], d: 0.05, vol: 0.08, delay: [0.4, 1.6] }))
|
|
11883
12515
|
];
|
|
11884
12516
|
var SCENE_SOUNDS = [
|
|
11885
12517
|
scene(
|
|
11886
12518
|
"glass_shatter",
|
|
11887
|
-
[
|
|
12519
|
+
[sceneNoise({ type: "highpass", f: 2800, d: 0.45, vol: 0.9, wet: 0.5 }), ...sceneMany(12, () => sceneTone({ f: [3e3, 7500], d: [0.06, 0.14], vol: 0.18, delay: [0, 0.55] }))],
|
|
11888
12520
|
"L1359 glass"
|
|
11889
12521
|
),
|
|
11890
12522
|
scene(
|
|
11891
12523
|
"wood_hit",
|
|
11892
|
-
[
|
|
12524
|
+
[sceneNoise({ type: "bandpass", f: 850, q: 1, d: 0.25, vol: 0.9, wet: 0.3 }), sceneTone({ f: 210, f2: 90, d: 0.1, vol: 0.6 }), sceneNoise({ type: "highpass", f: 2e3, d: 0.04, vol: 0.5 })],
|
|
11893
12525
|
"L1360 wood"
|
|
11894
12526
|
),
|
|
11895
|
-
scene("thunk", [
|
|
11896
|
-
scene("ping", [
|
|
11897
|
-
scene("clang", [
|
|
11898
|
-
scene("chip", [
|
|
12527
|
+
scene("thunk", [sceneNoise({ type: "bandpass", f: 700, q: 2, d: 0.07, vol: 0.4 })], "L1361 thunk"),
|
|
12528
|
+
scene("ping", [sceneTone({ f: [2600, 3500], f2: 1400, d: 0.14, vol: 0.18, wet: 0.3 })], "L1362 ping"),
|
|
12529
|
+
scene("clang", [sceneTone({ f: [520, 720], f2: 480, d: 0.5, vol: 0.35, wet: 0.4 }), sceneTone({ f: 1370, f2: 1300, d: 0.3, vol: 0.15 }), sceneNoise({ type: "highpass", f: 2e3, d: 0.05, vol: 0.5 })], "L1363 clang"),
|
|
12530
|
+
scene("chip", [sceneNoise({ type: "bandpass", f: 1600, q: 1.2, d: 0.06, vol: 0.5 })], "L1364 chip"),
|
|
11899
12531
|
scene(
|
|
11900
12532
|
"crumble",
|
|
11901
|
-
[
|
|
12533
|
+
[sceneNoise({ f: 900, f2: 200, d: 0.6, vol: 0.9, wet: 0.3 }), ...sceneMany(5, () => sceneNoise({ type: "bandpass", f: [500, 1400], q: 2, d: 0.05, vol: 0.4, delay: [0.1, 0.5] }))],
|
|
11902
12534
|
"L1365 crumble"
|
|
11903
12535
|
),
|
|
11904
12536
|
// `thud(x, z, v)`: `v` is the `scale` param (default 1)
|
|
11905
|
-
scene("thud", [
|
|
12537
|
+
scene("thud", [sceneTone({ f: 75, f2: 38, d: 0.22, vol: { param: "scale", scale: 0.6 } }), sceneNoise({ f: 420, d: 0.16, vol: { param: "scale", scale: 0.45 } })], "L1358 thud", { scale: 1 }),
|
|
11906
12538
|
// `hiss(x, z, d)`: `seconds` is the param `d` (default 1.2)
|
|
11907
|
-
scene("hiss", [
|
|
12539
|
+
scene("hiss", [sceneNoise({ type: "highpass", f: 3500, a: 0.05, d: { param: "seconds" }, vol: 0.35 })], "L1366 hiss", { seconds: 1.2 }),
|
|
11908
12540
|
scene("boom", boomLayers(false), "L1367 boom"),
|
|
11909
12541
|
scene("boom_big", boomLayers(true), "L1367 boom (big)"),
|
|
11910
|
-
scene("burst", [
|
|
11911
|
-
scene("crack", [
|
|
12542
|
+
scene("burst", [sceneNoise({ f: 700, f2: 120, d: 0.7, vol: 1.4, wet: 0.5 }), sceneNoise({ type: "highpass", f: 3e3, a: 0.05, d: 1.2, vol: 0.4, delay: 0.1 })], "L1357 burst"),
|
|
12543
|
+
scene("crack", [sceneNoise({ type: "highpass", f: 1800, d: 0.05, vol: 0.8 }), sceneTone({ f: 420, f2: 180, d: 0.06, vol: 0.4 })], "L1354 crack")
|
|
11912
12544
|
];
|
|
11913
12545
|
var EXPLOSION_BOOM = {
|
|
11914
12546
|
id: "explosion_boom",
|