@adatechnology/game-test-room 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.global.js +133 -39
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +27 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -406,6 +406,8 @@ interface RoomAvatarState {
|
|
|
406
406
|
running: boolean;
|
|
407
407
|
crouch: boolean;
|
|
408
408
|
down: boolean;
|
|
409
|
+
/** Which way the body falls while `down`: true face down, false on its back; left out, the avatar picks. A blast falls it the way it pushed. */
|
|
410
|
+
fallForward?: boolean;
|
|
409
411
|
/** A firearm is the tool in hand. */
|
|
410
412
|
armed: boolean;
|
|
411
413
|
/** Camera pitch, radians, positive looking up (the room's own convention). */
|
package/dist/index.global.js
CHANGED
|
@@ -23543,7 +23543,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
23543
23543
|
this.startFire(ev);
|
|
23544
23544
|
this.activate(ev.object, ev.part);
|
|
23545
23545
|
this.sound("ignite", ev.point, 0.7);
|
|
23546
|
-
this.sound("burn_loop", ev.point, 0.5);
|
|
23546
|
+
this.sound("burn_loop", ev.point, 0.5, this.burning(ev.object, ev.part));
|
|
23547
23547
|
break;
|
|
23548
23548
|
case "primed":
|
|
23549
23549
|
if (ev.trigger !== "explosion") {
|
|
@@ -23551,7 +23551,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
23551
23551
|
this.primedBurning.add(`${ev.object}|${ev.part}`);
|
|
23552
23552
|
this.activate(ev.object, ev.part);
|
|
23553
23553
|
this.sound("primed", ev.point, 0.7, { seconds: ev.delay });
|
|
23554
|
-
this.sound("burn_loop", ev.point, 0.5);
|
|
23554
|
+
this.sound("burn_loop", ev.point, 0.5, { fuel: "gas" });
|
|
23555
23555
|
}
|
|
23556
23556
|
break;
|
|
23557
23557
|
case "spall":
|
|
@@ -23577,15 +23577,15 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
23577
23577
|
this.stopFire(`${ev.object}|${ev.part}`);
|
|
23578
23578
|
this.vfx.burst("steam", f.point, [0, 1, 0], 14, 1.2);
|
|
23579
23579
|
}
|
|
23580
|
-
if (f || primed) this.sound("burn_end", f?.point ?? this.rootPoint(ev.object), 0.5);
|
|
23580
|
+
if (f || primed) this.sound("burn_end", f?.point ?? this.rootPoint(ev.object), 0.5, primed ? { fuel: "gas" } : this.burning(ev.object, ev.part));
|
|
23581
23581
|
this.activate(ev.object, ev.part);
|
|
23582
23582
|
this.sound("extinguish", f?.point ?? this.rootPoint(ev.object), 0.6);
|
|
23583
23583
|
break;
|
|
23584
23584
|
}
|
|
23585
23585
|
case "burnout": {
|
|
23586
23586
|
this.stopFire(`${ev.object}|${ev.part}`);
|
|
23587
|
-
this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
23588
|
-
this.sound("burn_end", ev.point, 0.5);
|
|
23587
|
+
const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
23588
|
+
this.sound("burn_end", ev.point, 0.5, primed ? { fuel: "gas" } : this.burning(ev.object, ev.part));
|
|
23589
23589
|
this.vfx.burst("ash", ev.point, [0, 1, 0], 16, 1);
|
|
23590
23590
|
this.vfx.burst("smoke", ev.point, [0, 1, 0], 6, 0.8, { color: SMOKE_TONES.grey });
|
|
23591
23591
|
const pv = this.partVis(ev.object, ev.part);
|
|
@@ -23653,7 +23653,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
23653
23653
|
break;
|
|
23654
23654
|
}
|
|
23655
23655
|
case "explode":
|
|
23656
|
-
this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
23656
|
+
if (this.primedBurning.delete(`${ev.object}|${ev.part}`)) this.sound("burn_end", ev.point, 0.5, { fuel: "gas" });
|
|
23657
23657
|
this.onExplode(ev);
|
|
23658
23658
|
break;
|
|
23659
23659
|
case "destroyed":
|
|
@@ -23668,6 +23668,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
23668
23668
|
if (detail) this.o.onSound?.(key2, point, volume, detail);
|
|
23669
23669
|
else this.o.onSound?.(key2, point, volume);
|
|
23670
23670
|
}
|
|
23671
|
+
/** What a burning part is made of, for the fire's sound. */
|
|
23672
|
+
burning(objectId, partId) {
|
|
23673
|
+
const material = this.partVis(objectId, partId)?.material || this.world.part(objectId, partId)?.material;
|
|
23674
|
+
return material ? { material } : void 0;
|
|
23675
|
+
}
|
|
23671
23676
|
partVis(objectId, partId) {
|
|
23672
23677
|
return this.bounds.get(objectId)?.parts.get(partId) ?? null;
|
|
23673
23678
|
}
|
|
@@ -24536,6 +24541,47 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24536
24541
|
volume: 0,
|
|
24537
24542
|
sources: ["sdk: the roar under the crackles of a fire"]
|
|
24538
24543
|
};
|
|
24544
|
+
var FIRE_FUEL_OF = {
|
|
24545
|
+
wood_soft: "wood",
|
|
24546
|
+
wood_hard: "wood",
|
|
24547
|
+
plywood: "wood",
|
|
24548
|
+
mdf: "wood",
|
|
24549
|
+
green_wood: "wood",
|
|
24550
|
+
foliage: "wood",
|
|
24551
|
+
cactus: "wood",
|
|
24552
|
+
paper: "fabric",
|
|
24553
|
+
fabric: "fabric",
|
|
24554
|
+
leather: "fabric",
|
|
24555
|
+
foam: "plastic",
|
|
24556
|
+
plastic: "plastic",
|
|
24557
|
+
rubber: "plastic",
|
|
24558
|
+
wax: "plastic"
|
|
24559
|
+
};
|
|
24560
|
+
var FIRE_LOOP_OF = {
|
|
24561
|
+
wood: "fire_loop",
|
|
24562
|
+
fabric: "fire_loop",
|
|
24563
|
+
plastic: "fire_loop_plastic",
|
|
24564
|
+
gas: "fire_loop_gas",
|
|
24565
|
+
liquid: "fire_loop_liquid"
|
|
24566
|
+
};
|
|
24567
|
+
var FIRE_CRACKLE_OF = { wood: 1, fabric: 0.5, plastic: 0.35, gas: 0, liquid: 0 };
|
|
24568
|
+
var roar = (id, bank, source) => ({
|
|
24569
|
+
id,
|
|
24570
|
+
bus: "world",
|
|
24571
|
+
order: "chain_loop",
|
|
24572
|
+
source: { kind: "noise", loop: true },
|
|
24573
|
+
filters: { mode: "serial", bank },
|
|
24574
|
+
volume: 0,
|
|
24575
|
+
sources: [source]
|
|
24576
|
+
});
|
|
24577
|
+
var FIRE_FUEL_LOOPS = [
|
|
24578
|
+
// a gas jet: a steady, broad roar, brighter than wood and without crackles
|
|
24579
|
+
roar("fire_loop_gas", [{ type: "highpass", frequency: { set: 220 }, q: 0.7 }, { type: "lowpass", frequency: { set: 2400 }, q: 0.6 }], "sdk: a gas jet burning (a vessel venting into the flame)"),
|
|
24580
|
+
// a fuel pool: a soft, low, rolling roar
|
|
24581
|
+
roar("fire_loop_liquid", [{ type: "highpass", frequency: { set: 90 }, q: 0.7 }, { type: "lowpass", frequency: { set: 650 }, q: 0.9 }], "sdk: a pool of fuel burning"),
|
|
24582
|
+
// plastic and rubber: a thin sizzle over a low burn
|
|
24583
|
+
roar("fire_loop_plastic", [{ type: "bandpass", frequency: { set: 1800 }, q: 0.6 }], "sdk: plastic and rubber melting in the fire")
|
|
24584
|
+
];
|
|
24539
24585
|
var BLAST_SOUND_OF = {
|
|
24540
24586
|
grenade: "explosion_grenade",
|
|
24541
24587
|
big: "explosion_big",
|
|
@@ -24680,7 +24726,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24680
24726
|
impact2("plastic_crack", [sceneNoise({ type: "bandpass", f: 1800, q: 2, d: 0.06, vol: 0.75 }), sceneTone({ f: [450, 550], f2: 250, d: 0.05, vol: 0.22 })]),
|
|
24681
24727
|
impact2("mdf_crumble", [sceneNoise({ type: "lowpass", f: 700, d: 0.25, vol: 0.75, wet: 0.2 }), ...sceneMany(4, () => sceneNoise({ type: "lowpass", f: 500, d: 0.05, vol: 0.32, delay: [0.05, 0.3] }))])
|
|
24682
24728
|
];
|
|
24683
|
-
var DESTRUCTION_SOUND_BANK = { id: "destruction_three", sounds: [...SCENE_SOUNDS, ...DRAG_SOUNDS, ...LEAF_SOUNDS, ...IMPACT_SOUNDS, EXPLOSION_BOOM, ...BLAST_SOUNDS, ...FIRE_SOUNDS], loops: [BURN_LOOP, FIRE_LOOP] };
|
|
24729
|
+
var DESTRUCTION_SOUND_BANK = { id: "destruction_three", sounds: [...SCENE_SOUNDS, ...DRAG_SOUNDS, ...LEAF_SOUNDS, ...IMPACT_SOUNDS, EXPLOSION_BOOM, ...BLAST_SOUNDS, ...FIRE_SOUNDS], loops: [BURN_LOOP, FIRE_LOOP, ...FIRE_FUEL_LOOPS] };
|
|
24684
24730
|
var IMPACT_SOUND_KEYS = {
|
|
24685
24731
|
impact_metal_ballistic: { sound: "metal_bullet" },
|
|
24686
24732
|
impact_metal_blunt: { sound: "metal_blunt" },
|
|
@@ -24829,31 +24875,52 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24829
24875
|
const rules = { ...DESTRUCTION_SOUND_KEYS.art_scene, ...options.style === "game" ? DESTRUCTION_SOUND_KEYS.game : {}, ...options.keys };
|
|
24830
24876
|
const blastByKind = options.style !== "game" && !(options.keys && "explode" in options.keys);
|
|
24831
24877
|
const channel = engine.channel({ seed: options.seed ?? 1 });
|
|
24832
|
-
|
|
24833
|
-
|
|
24878
|
+
const fuelOf = { ...FIRE_FUEL_OF, ...options.fuels };
|
|
24879
|
+
const loopOf = { ...FIRE_LOOP_OF, ...options.fireLoop ? { wood: fireLoop, fabric: fireLoop } : {}, ...options.fireLoops };
|
|
24880
|
+
const defaultFuel = options.defaultFuel ?? "wood";
|
|
24881
|
+
const loops = /* @__PURE__ */ new Map();
|
|
24834
24882
|
const fires = [];
|
|
24835
24883
|
let nextCrackle = 0;
|
|
24884
|
+
const fuelFor = (detail) => detail?.fuel ?? (detail?.material !== void 0 ? fuelOf[detail.material] : void 0) ?? defaultFuel;
|
|
24836
24885
|
const setFire = () => {
|
|
24837
24886
|
if (options.burnLoop === false) return;
|
|
24838
|
-
|
|
24839
|
-
|
|
24840
|
-
|
|
24841
|
-
|
|
24887
|
+
const count = /* @__PURE__ */ new Map();
|
|
24888
|
+
for (const f of fires) {
|
|
24889
|
+
const id = loopOf[f.fuel];
|
|
24890
|
+
count.set(id, (count.get(id) ?? 0) + 1);
|
|
24891
|
+
}
|
|
24892
|
+
for (const [id, handle] of loops) {
|
|
24893
|
+
if (count.has(id)) continue;
|
|
24894
|
+
handle.stop();
|
|
24895
|
+
loops.delete(id);
|
|
24896
|
+
}
|
|
24897
|
+
for (const [id, n] of count) {
|
|
24898
|
+
let handle = loops.get(id);
|
|
24899
|
+
if (!handle) {
|
|
24900
|
+
handle = engine.loop(id);
|
|
24901
|
+
loops.set(id, handle);
|
|
24902
|
+
}
|
|
24903
|
+
handle.set({ volume: Math.min(fire2.max, fire2.perFire * n) });
|
|
24842
24904
|
}
|
|
24843
|
-
loop ?? (loop = engine.loop(fireLoop));
|
|
24844
|
-
loop.set({ volume: Math.min(fire2.max, fire2.perFire * burning) });
|
|
24845
24905
|
};
|
|
24846
|
-
const forget = (point) => {
|
|
24906
|
+
const forget = (point, fuel) => {
|
|
24847
24907
|
let best = -1;
|
|
24848
24908
|
let bestD = Infinity;
|
|
24849
24909
|
fires.forEach((f, i) => {
|
|
24850
|
-
|
|
24910
|
+
if (fuel !== void 0 && f.fuel !== fuel) return;
|
|
24911
|
+
const d = (f.point[0] - point[0]) ** 2 + (f.point[1] - point[1]) ** 2 + (f.point[2] - point[2]) ** 2;
|
|
24851
24912
|
if (d < bestD) {
|
|
24852
24913
|
bestD = d;
|
|
24853
24914
|
best = i;
|
|
24854
24915
|
}
|
|
24855
24916
|
});
|
|
24856
|
-
if (best
|
|
24917
|
+
if (best < 0 && fuel !== void 0) forget(point, void 0);
|
|
24918
|
+
else if (best >= 0) fires.splice(best, 1);
|
|
24919
|
+
};
|
|
24920
|
+
const reset = () => {
|
|
24921
|
+
for (const handle of loops.values()) handle.stop();
|
|
24922
|
+
loops.clear();
|
|
24923
|
+
fires.length = 0;
|
|
24857
24924
|
};
|
|
24858
24925
|
const blastSound = (point, volume, detail) => {
|
|
24859
24926
|
const named = detail?.effect === void 0 ? void 0 : kinds[detail.effect];
|
|
@@ -24865,14 +24932,12 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24865
24932
|
return {
|
|
24866
24933
|
onSound(key2, point, volume, detail) {
|
|
24867
24934
|
if (key2 === "burn_loop") {
|
|
24868
|
-
|
|
24869
|
-
fires.push(point);
|
|
24935
|
+
fires.push({ point, fuel: fuelFor(detail) });
|
|
24870
24936
|
setFire();
|
|
24871
24937
|
return;
|
|
24872
24938
|
}
|
|
24873
24939
|
if (key2 === "burn_end") {
|
|
24874
|
-
|
|
24875
|
-
forget(point);
|
|
24940
|
+
forget(point, detail?.fuel ?? (detail?.material !== void 0 ? fuelOf[detail.material] : void 0));
|
|
24876
24941
|
setFire();
|
|
24877
24942
|
return;
|
|
24878
24943
|
}
|
|
@@ -24902,12 +24967,15 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24902
24967
|
},
|
|
24903
24968
|
update(dt) {
|
|
24904
24969
|
if (!crackles || fires.length === 0 || options.burnLoop === false) return;
|
|
24970
|
+
const weight = fires.reduce((sum2, f) => sum2 + FIRE_CRACKLE_OF[f.fuel], 0);
|
|
24971
|
+
if (weight <= 0) return;
|
|
24905
24972
|
nextCrackle -= dt;
|
|
24906
24973
|
for (let i = 0; i < 4 && nextCrackle <= 0; i++) {
|
|
24907
|
-
const rate = Math.min(crackles.max, crackles.base + crackles.perSqrtFire * Math.sqrt(
|
|
24974
|
+
const rate = Math.min(crackles.max, crackles.base * Math.min(1, weight) + crackles.perSqrtFire * Math.sqrt(weight));
|
|
24908
24975
|
nextCrackle += (0.4 + channel.random() * 1.2) / rate;
|
|
24909
|
-
|
|
24910
|
-
|
|
24976
|
+
let pick3 = channel.random() * weight;
|
|
24977
|
+
const at3 = fires.find((f) => (pick3 -= FIRE_CRACKLE_OF[f.fuel]) <= 0) ?? fires[fires.length - 1];
|
|
24978
|
+
engine.play(channel.random() < 0.18 ? "fire_pop" : "fire_crackle", { position: at3.point, volume: crackles.volume });
|
|
24911
24979
|
}
|
|
24912
24980
|
if (nextCrackle < 0) nextCrackle = 0;
|
|
24913
24981
|
},
|
|
@@ -24916,13 +24984,14 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24916
24984
|
for (const k of detail?.keys ?? []) if (k in rules) return rules[k] ?? void 0;
|
|
24917
24985
|
return rules[key2] ?? void 0;
|
|
24918
24986
|
},
|
|
24919
|
-
burning: () =>
|
|
24920
|
-
|
|
24921
|
-
|
|
24922
|
-
|
|
24923
|
-
|
|
24924
|
-
|
|
24925
|
-
|
|
24987
|
+
burning: () => fires.length,
|
|
24988
|
+
burningBy: () => {
|
|
24989
|
+
const by = {};
|
|
24990
|
+
for (const f of fires) by[f.fuel] = (by[f.fuel] ?? 0) + 1;
|
|
24991
|
+
return by;
|
|
24992
|
+
},
|
|
24993
|
+
reset,
|
|
24994
|
+
dispose: reset
|
|
24926
24995
|
};
|
|
24927
24996
|
}
|
|
24928
24997
|
var blast2 = (gain) => ({ bus: "world", gain, falloff: BLAST_FALLOFF, cutoffK: 6e-3, priority: 3 });
|
|
@@ -24941,7 +25010,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
24941
25010
|
fire_extinguish: fire(0.7),
|
|
24942
25011
|
gas_leak: fire(0.5),
|
|
24943
25012
|
// the roar: recorded fires chained with a crossfade (the level comes from `createDestructionSound`, by how much burns)
|
|
24944
|
-
fire_loop: { bus: "world", gain: 4, loop: { crossfade: 1 } }
|
|
25013
|
+
fire_loop: { bus: "world", gain: 4, loop: { crossfade: 1 } },
|
|
25014
|
+
// each fuel has its own roar: a gas jet (burners and torches), a pool of fuel, plastic and rubber sizzling under the flames
|
|
25015
|
+
fire_loop_gas: { bus: "world", gain: 6, loop: { crossfade: 1 } },
|
|
25016
|
+
fire_loop_liquid: { bus: "world", gain: 3.5, loop: { crossfade: 1 } },
|
|
25017
|
+
fire_loop_plastic: { bus: "world", gain: 1, loop: { crossfade: 0.6 } }
|
|
24945
25018
|
};
|
|
24946
25019
|
|
|
24947
25020
|
// src/body-sounds.ts
|
|
@@ -47790,6 +47863,7 @@ void main(){
|
|
|
47790
47863
|
var LYING_EYE = 0.3;
|
|
47791
47864
|
var LYING_PITCH = 1.05;
|
|
47792
47865
|
var LYING_ROLL = 0.35;
|
|
47866
|
+
var LYING_PITCH_FACE_DOWN = -1.05;
|
|
47793
47867
|
function createPlayer(THREE, o) {
|
|
47794
47868
|
const cam = o.camera;
|
|
47795
47869
|
let yaw = 0;
|
|
@@ -47828,11 +47902,12 @@ void main(){
|
|
|
47828
47902
|
floorLevel += Math.max(-reach, Math.min(reach, gap));
|
|
47829
47903
|
};
|
|
47830
47904
|
let knocked = null;
|
|
47905
|
+
let knockedForward = false;
|
|
47831
47906
|
let rollSide = 1;
|
|
47832
47907
|
const apply = () => {
|
|
47833
47908
|
const lying = knocked?.lying ?? 0;
|
|
47834
47909
|
const fallen = lying * lying * (3 - 2 * lying);
|
|
47835
|
-
euler.set(pitch + (LYING_PITCH - pitch) * fallen, yaw, LYING_ROLL * rollSide * fallen, "YXZ");
|
|
47910
|
+
euler.set(pitch + ((knockedForward ? LYING_PITCH_FACE_DOWN : LYING_PITCH) - pitch) * fallen, yaw, LYING_ROLL * rollSide * fallen, "YXZ");
|
|
47836
47911
|
cam.quaternion.setFromEuler(euler);
|
|
47837
47912
|
const standing = eye - CROUCH_DROP * crouch - bend;
|
|
47838
47913
|
cam.position.set(px.x, floorLevel + y + standing + (LYING_EYE - standing) * fallen, px.z);
|
|
@@ -48110,6 +48185,7 @@ void main(){
|
|
|
48110
48185
|
if (next.down) {
|
|
48111
48186
|
const right = Math.cos(yaw) * next.velocity[0] - Math.sin(yaw) * next.velocity[2];
|
|
48112
48187
|
rollSide = right >= 0 ? -1 : 1;
|
|
48188
|
+
knockedForward = -Math.sin(yaw) * next.velocity[0] - Math.cos(yaw) * next.velocity[2] > 0;
|
|
48113
48189
|
crouchLatched = false;
|
|
48114
48190
|
}
|
|
48115
48191
|
if (knocked.airborne) vy2 = Math.max(vy2, knocked.velocity[1]);
|
|
@@ -48117,6 +48193,9 @@ void main(){
|
|
|
48117
48193
|
get knocked() {
|
|
48118
48194
|
return knocked;
|
|
48119
48195
|
},
|
|
48196
|
+
get knockedForward() {
|
|
48197
|
+
return knockedForward;
|
|
48198
|
+
},
|
|
48120
48199
|
update(dt) {
|
|
48121
48200
|
if (knocked) {
|
|
48122
48201
|
stepKnocked(dt);
|
|
@@ -53946,6 +54025,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
53946
54025
|
explosives.clear();
|
|
53947
54026
|
fireZones.length = 0;
|
|
53948
54027
|
burningStains.length = 0;
|
|
54028
|
+
destructionSound?.reset();
|
|
53949
54029
|
terrain.setLayout(defaultGround);
|
|
53950
54030
|
for (const id of [...entries2.keys()]) if (!entries2.get(id)?.arena) removeEntry(id);
|
|
53951
54031
|
clearLoose();
|
|
@@ -54113,6 +54193,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54113
54193
|
avatarState.running = !player.crouching && (player.keys.has("ShiftLeft") || player.keys.has("ShiftRight"));
|
|
54114
54194
|
avatarState.crouch = crouchForced || player.crouching || push.isBent;
|
|
54115
54195
|
avatarState.down = downForced || Boolean(player.knocked?.down || (player.knocked?.lying ?? 0) > 0.5);
|
|
54196
|
+
avatarState.fallForward = downForced ? void 0 : player.knockedForward;
|
|
54116
54197
|
avatarState.armed = armedForced ?? tool.def.action.kind === "firearm";
|
|
54117
54198
|
avatarState.pitch = player.pitch;
|
|
54118
54199
|
avatarState.holding = heldPiece !== null;
|
|
@@ -54312,6 +54393,15 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54312
54393
|
};
|
|
54313
54394
|
const fireZones = [];
|
|
54314
54395
|
const burningStains = [];
|
|
54396
|
+
const poolFire = (point, burning) => playSound(burning ? "burn_loop" : "burn_end", point, 0.5, { fuel: "liquid" });
|
|
54397
|
+
const dropZone = (i) => {
|
|
54398
|
+
const [zone] = fireZones.splice(i, 1);
|
|
54399
|
+
if (zone) poolFire(zone.point, false);
|
|
54400
|
+
};
|
|
54401
|
+
const dropStain = (i) => {
|
|
54402
|
+
const [stain] = burningStains.splice(i, 1);
|
|
54403
|
+
if (stain) poolFire(stain.center, false);
|
|
54404
|
+
};
|
|
54315
54405
|
const stainRadius = (s) => {
|
|
54316
54406
|
let sum2 = 0;
|
|
54317
54407
|
for (const r of s.front) sum2 += r;
|
|
@@ -54328,6 +54418,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54328
54418
|
if (stainBurning(s)) continue;
|
|
54329
54419
|
const seconds = Math.max(3, Math.min(20, 4 + s.liters * 30 + stainRadius(s) * 6));
|
|
54330
54420
|
burningStains.push({ center: [s.center[0], s.center[1], s.center[2]], remaining: seconds, acc: 0 });
|
|
54421
|
+
poolFire([s.center[0], s.center[1], s.center[2]], true);
|
|
54331
54422
|
lit = true;
|
|
54332
54423
|
log.add({
|
|
54333
54424
|
channel: "event",
|
|
@@ -54358,7 +54449,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54358
54449
|
const a = rnd2() * Math.PI * 2;
|
|
54359
54450
|
const r = Math.sqrt(rnd2()) * z.radius;
|
|
54360
54451
|
renderer.emit("fire", [z.point[0] + Math.cos(a) * r, z.point[1] + 0.05, z.point[2] + Math.sin(a) * r], [0, 1, 0], 2, 1.5);
|
|
54361
|
-
if (z.remaining <= 0)
|
|
54452
|
+
if (z.remaining <= 0) dropZone(i);
|
|
54362
54453
|
}
|
|
54363
54454
|
if (burningStains.length) {
|
|
54364
54455
|
const stains = fluids.stains();
|
|
@@ -54379,7 +54470,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54379
54470
|
if (b.remaining <= 0 || !st) {
|
|
54380
54471
|
fluids.clearStains(b.center, r + 0.1);
|
|
54381
54472
|
log.add({ channel: "event", type: "stain_burned", text: t("ev.stain_burned"), data: { point: b.center } });
|
|
54382
|
-
|
|
54473
|
+
dropStain(i);
|
|
54383
54474
|
}
|
|
54384
54475
|
}
|
|
54385
54476
|
}
|
|
@@ -54716,8 +54807,8 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54716
54807
|
hit.add(r.object);
|
|
54717
54808
|
world.extinguish(r.object, void 0, u.coolC * Math.max(u.duration, 0.05) * 6);
|
|
54718
54809
|
fluids.clearStains(r.point, 0.5);
|
|
54719
|
-
for (let i = burningStains.length - 1; i >= 0; i--) if (Math.hypot(burningStains[i].center[0] - r.point[0], burningStains[i].center[2] - r.point[2]) < 1.2)
|
|
54720
|
-
for (let i = fireZones.length - 1; i >= 0; i--) if (Math.hypot(fireZones[i].point[0] - r.point[0], fireZones[i].point[2] - r.point[2]) < 1.5)
|
|
54810
|
+
for (let i = burningStains.length - 1; i >= 0; i--) if (Math.hypot(burningStains[i].center[0] - r.point[0], burningStains[i].center[2] - r.point[2]) < 1.2) dropStain(i);
|
|
54811
|
+
for (let i = fireZones.length - 1; i >= 0; i--) if (Math.hypot(fireZones[i].point[0] - r.point[0], fireZones[i].point[2] - r.point[2]) < 1.5) dropZone(i);
|
|
54721
54812
|
}
|
|
54722
54813
|
});
|
|
54723
54814
|
log.coalesce(
|
|
@@ -54728,7 +54819,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54728
54819
|
};
|
|
54729
54820
|
const startFire = (weapon, at3, fire3, impact3) => {
|
|
54730
54821
|
fluids.splash("fuel", [at3[0], Math.max(at3[1], groundAt(at3[0], at3[2])), at3[2]], 0.5);
|
|
54731
|
-
|
|
54822
|
+
const zone = { point: [at3[0], Math.max(0.02, groundAt(at3[0], at3[2])), at3[2]], radius: fire3.radius, temperature: fire3.temperature, remaining: fire3.seconds, acc: 0 };
|
|
54823
|
+
fireZones.push(zone);
|
|
54824
|
+
poolFire(zone.point, true);
|
|
54732
54825
|
renderer.emit("fire", at3, [0, 1, 0], 24, 3);
|
|
54733
54826
|
action("molotov_fire", t("act.molotov_fire", { weapon: toolName(weapon), seconds: num(fire3.seconds, 0), radius: num(fire3.radius, 1) }), { data: { weapon, impact: impact3 } });
|
|
54734
54827
|
};
|
|
@@ -55866,6 +55959,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
55866
55959
|
loading,
|
|
55867
55960
|
addView: (view) => moduleViews.add(view),
|
|
55868
55961
|
setViewCamera: (view) => moduleViews.setMain(view ?? null),
|
|
55962
|
+
holdPlayer: (held) => player.setWalkHeld(held),
|
|
55869
55963
|
...options.blastShove ? { blastShove: options.blastShove } : {},
|
|
55870
55964
|
blastReach: (point, target, ignore) => world.blastReach(point, target, ignore ? { ignore } : {}),
|
|
55871
55965
|
tool: () => ({
|