@adatechnology/game-weapons-three 0.5.0 → 0.6.1
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/README.md +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.global.js +1631 -120
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +200 -96
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -290,16 +290,26 @@ var ACCESSORY_TEXT = {
|
|
|
290
290
|
var accessoryTextOf = (locale) => ACCESSORY_TEXT[locale] ?? ACCESSORY_TEXT.en;
|
|
291
291
|
|
|
292
292
|
// src/audio.ts
|
|
293
|
-
import {
|
|
293
|
+
import { MIX_PROFILES, createAudioEngine } from "@adatechnology/game-audio";
|
|
294
294
|
|
|
295
295
|
// src/audio/mechanical-sounds.ts
|
|
296
296
|
var metal = (at, frequency, gain) => ({ layer: "metal", at, frequency, gain });
|
|
297
297
|
var sound = (at, soundClass, volume) => ({ layer: "class", at, soundClass, volume });
|
|
298
298
|
var thud = (at, gain, frequency) => ({ layer: "thud", at, gain, frequency });
|
|
299
|
+
var sceneClick = (at, f, vol) => [
|
|
300
|
+
{ layer: "scene_tone", at, wave: "square", f, f2: f * 0.7, d: 0.02, vol },
|
|
301
|
+
{ layer: "scene_noise", at, type: "highpass", f: 3e3, q: 0.7, d: 0.03, vol: vol * 0.8 }
|
|
302
|
+
];
|
|
303
|
+
var sceneNoise = (at, type, f, q, d, vol) => ({ layer: "scene_noise", at, type, f, q, d, vol });
|
|
304
|
+
var sceneEmpty = sceneClick(0, 3200, 0.35);
|
|
305
|
+
var sceneMagOut = [...sceneClick(0, 1600, 0.4), sceneNoise(0.03, "bandpass", 900, 2, 0.08, 0.3)];
|
|
306
|
+
var sceneMagIn = [...sceneClick(0, 1100, 0.5), { layer: "scene_tone", at: 0, wave: "sine", f: 320, f2: 200, d: 0.05, vol: 0.35 }];
|
|
307
|
+
var sceneBolt = [...sceneClick(0, 2200, 0.4), ...sceneClick(0.12, 2700, 0.4)];
|
|
308
|
+
var sceneShell = [...sceneClick(0, 1400, 0.35), sceneNoise(0.02, "bandpass", 1200, 3, 0.05, 0.25)];
|
|
299
309
|
var slide = [metal(0, 900, 0.35), metal(0.14, 1300, 0.35)];
|
|
300
310
|
var seat = [metal(0, 1100, 0.45), sound(0, "reload", 0.8)];
|
|
301
311
|
var MECHANICAL_SOUNDS = {
|
|
302
|
-
dry_fire: [sound(0, "empty", 1),
|
|
312
|
+
dry_fire: [sound(0, "empty", 1), ...sceneEmpty],
|
|
303
313
|
misfire: [sound(0, "empty", 0.8), metal(0, 2200, 0.2)],
|
|
304
314
|
feed: [metal(0, 1900, 0.2)],
|
|
305
315
|
cycle: [metal(0.22, 900, 0.35), metal(0.36, 1300, 0.35)],
|
|
@@ -312,11 +322,11 @@ var MECHANICAL_SOUNDS = {
|
|
|
312
322
|
stock_fold: [metal(0, 800, 0.3), metal(0.18, 1200, 0.3), thud(0.3, 0.2, 600)],
|
|
313
323
|
light_click: [metal(0, 2400, 0.2), metal(0.03, 1800, 0.12)],
|
|
314
324
|
attach: [metal(0, 1400, 0.35), thud(0.04, 0.2, 700), metal(0.12, 1900, 0.25)],
|
|
315
|
-
magazine_out: [
|
|
316
|
-
magazine_in:
|
|
317
|
-
charge:
|
|
325
|
+
magazine_out: [...sceneMagOut, sound(0, "reload", 0.6)],
|
|
326
|
+
magazine_in: [...sceneMagIn, sound(0, "reload", 0.8)],
|
|
327
|
+
charge: sceneBolt,
|
|
318
328
|
bolt_open: [metal(0, 900, 0.35)],
|
|
319
|
-
round_in: [
|
|
329
|
+
round_in: [...sceneShell, sound(0, "reload", 0.6)],
|
|
320
330
|
bolt_close: [metal(0, 1300, 0.35)],
|
|
321
331
|
pump_cycle: slide,
|
|
322
332
|
lever_cycle: [metal(0, 1e3, 0.35), metal(0.12, 1500, 0.35)],
|
|
@@ -371,6 +381,9 @@ var mechanicalSoundOf = (event) => {
|
|
|
371
381
|
}
|
|
372
382
|
};
|
|
373
383
|
|
|
384
|
+
// src/audio/recipes.ts
|
|
385
|
+
import { DISTANCE_CURVES } from "@adatechnology/game-audio";
|
|
386
|
+
|
|
374
387
|
// src/audio/shot-sound.ts
|
|
375
388
|
import { muzzleEnergy } from "@adatechnology/game-weapons";
|
|
376
389
|
var GAME_SOUND_CLASSES = {
|
|
@@ -457,100 +470,185 @@ var computeShotSound = (input, options = {}) => {
|
|
|
457
470
|
};
|
|
458
471
|
};
|
|
459
472
|
|
|
473
|
+
// src/audio/recipes.ts
|
|
474
|
+
var CLASS_BURST_ID = "weapon_class_burst";
|
|
475
|
+
var BURST_IDS = { lowpass: "weapon_burst_lowpass", highpass: "weapon_burst_highpass" };
|
|
476
|
+
var SCENE_NOISE_IDS = { lowpass: "scene_noise_lowpass", highpass: "scene_noise_highpass", bandpass: "scene_noise_bandpass" };
|
|
477
|
+
var SCENE_TONE_IDS = { sine: "scene_tone_sine", square: "scene_tone_square" };
|
|
478
|
+
var TONE_IDS = { sine: "weapon_tone_sine", sine_sweep: "weapon_tone_sine_sweep", square: "weapon_tone_square" };
|
|
479
|
+
var SOURCE_CLASS_BURST = "jogo:L62097-62110 sfx: lowpass noise, gain set at once, exponential fall to 0.001, stopped 0.05 s later";
|
|
480
|
+
var SOURCE_SDK = "sdk: the weapon synth of weapons-three (burst and tone), moved onto game-audio with the same nodes";
|
|
481
|
+
var FIT = { kind: "noise", offset: "fit" };
|
|
482
|
+
function classBurstId(curve) {
|
|
483
|
+
const same = curve.gainFalloff === GAME_DISTANCE_CURVE.gainFalloff && curve.cutoffFalloff === GAME_DISTANCE_CURVE.cutoffFalloff && curve.minGain === GAME_DISTANCE_CURVE.minGain;
|
|
484
|
+
return same ? CLASS_BURST_ID : `${CLASS_BURST_ID}@${curve.gainFalloff},${curve.cutoffFalloff},${curve.minGain}`;
|
|
485
|
+
}
|
|
486
|
+
function classBurstRecipe(curve) {
|
|
487
|
+
return {
|
|
488
|
+
id: classBurstId(curve),
|
|
489
|
+
bus: "weapons",
|
|
490
|
+
order: "weapon",
|
|
491
|
+
duration: { param: "seconds" },
|
|
492
|
+
layers: [
|
|
493
|
+
{
|
|
494
|
+
gain: { param: "gain" },
|
|
495
|
+
source: FIT,
|
|
496
|
+
filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: { param: "cutoff" } } }] },
|
|
497
|
+
envelope: [
|
|
498
|
+
[0, 1, "set"],
|
|
499
|
+
["1d", 1e-3, "exp", "fixed"]
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
],
|
|
503
|
+
falloff: { model: "inverse_square", k: curve.gainFalloff, cutoffK: curve.cutoffFalloff, minGain: curve.minGain },
|
|
504
|
+
sources: [SOURCE_CLASS_BURST]
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
var burstLayer = (type) => ({
|
|
508
|
+
gain: { param: "gain" },
|
|
509
|
+
source: FIT,
|
|
510
|
+
filters: { mode: "serial", bank: [{ type, frequency: { set: { param: "frequency" } }, q: { param: "q" } }] },
|
|
511
|
+
envelope: [
|
|
512
|
+
[0, 1e-4, "set", "fixed"],
|
|
513
|
+
[4e-3, 1, "exp"],
|
|
514
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
515
|
+
]
|
|
516
|
+
});
|
|
517
|
+
var burstRecipe = (type) => ({
|
|
518
|
+
id: BURST_IDS[type],
|
|
519
|
+
bus: "weapons",
|
|
520
|
+
order: "weapon",
|
|
521
|
+
duration: { param: "seconds" },
|
|
522
|
+
layers: [burstLayer(type)],
|
|
523
|
+
falloff: { model: "none" },
|
|
524
|
+
sources: [SOURCE_SDK]
|
|
525
|
+
});
|
|
526
|
+
var toneLayer = (wave, sweep) => ({
|
|
527
|
+
gain: { param: "gain" },
|
|
528
|
+
source: { kind: "osc", wave, frequency: sweep ? { from: { param: "frequency" }, to: { param: "to" }, curve: "exp", over: "duration" } : { from: { param: "frequency" } } },
|
|
529
|
+
envelope: [
|
|
530
|
+
[0, 1e-4, "set", "fixed"],
|
|
531
|
+
[3e-3, 1, "exp"],
|
|
532
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
533
|
+
]
|
|
534
|
+
});
|
|
535
|
+
var toneRecipe = (id, wave, sweep) => ({
|
|
536
|
+
id,
|
|
537
|
+
bus: "weapons",
|
|
538
|
+
order: "weapon",
|
|
539
|
+
duration: { param: "seconds" },
|
|
540
|
+
layers: [toneLayer(wave, sweep)],
|
|
541
|
+
falloff: { model: "none" },
|
|
542
|
+
sources: [SOURCE_SDK]
|
|
543
|
+
});
|
|
544
|
+
var SOURCE_SCENE = "cena:L1323-L1324 sNoise and sTone, played at the listener (distance 0), through the art scene output stage";
|
|
545
|
+
var SCENE_ATTACK = 2e-3;
|
|
546
|
+
var sceneNoiseRecipe = (type, slide2) => ({
|
|
547
|
+
id: slide2 ? `${SCENE_NOISE_IDS[type]}_slide` : SCENE_NOISE_IDS[type],
|
|
548
|
+
bus: "weapons",
|
|
549
|
+
order: "layered",
|
|
550
|
+
duration: { param: "d", add: SCENE_ATTACK },
|
|
551
|
+
pan: true,
|
|
552
|
+
layers: [
|
|
553
|
+
{
|
|
554
|
+
gain: { param: "vol" },
|
|
555
|
+
source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
|
|
556
|
+
filters: { mode: "serial", bank: [{ type, frequency: slide2 ? { set: { param: "f" }, to: { param: "f2" }, curve: "exp", over: { param: "d" } } : { set: { param: "f" } }, q: { param: "q" } }] },
|
|
557
|
+
envelope: [
|
|
558
|
+
[0, 1e-4, "set", "fixed"],
|
|
559
|
+
[SCENE_ATTACK, 1, "exp"],
|
|
560
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
falloff: DISTANCE_CURVES.art_scene,
|
|
565
|
+
sources: [SOURCE_SCENE]
|
|
566
|
+
});
|
|
567
|
+
var sceneToneRecipe = (wave) => ({
|
|
568
|
+
id: SCENE_TONE_IDS[wave],
|
|
569
|
+
bus: "weapons",
|
|
570
|
+
order: "layered",
|
|
571
|
+
duration: { param: "d", add: SCENE_ATTACK },
|
|
572
|
+
pan: true,
|
|
573
|
+
layers: [
|
|
574
|
+
{
|
|
575
|
+
gain: { param: "vol" },
|
|
576
|
+
source: { kind: "osc", wave, frequency: { from: { param: "f" }, to: { param: "f2" }, curve: "exp", over: "duration" } },
|
|
577
|
+
envelope: [
|
|
578
|
+
[0, 1e-4, "set", "fixed"],
|
|
579
|
+
[SCENE_ATTACK, 1, "exp"],
|
|
580
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
581
|
+
]
|
|
582
|
+
}
|
|
583
|
+
],
|
|
584
|
+
falloff: DISTANCE_CURVES.art_scene,
|
|
585
|
+
sources: [SOURCE_SCENE]
|
|
586
|
+
});
|
|
587
|
+
function weaponRecipes(curve) {
|
|
588
|
+
return [
|
|
589
|
+
classBurstRecipe(curve),
|
|
590
|
+
burstRecipe("lowpass"),
|
|
591
|
+
burstRecipe("highpass"),
|
|
592
|
+
toneRecipe(TONE_IDS.sine, "sine", false),
|
|
593
|
+
toneRecipe(TONE_IDS.sine_sweep, "sine", true),
|
|
594
|
+
toneRecipe(TONE_IDS.square, "square", false),
|
|
595
|
+
...["lowpass", "highpass", "bandpass"].flatMap((type) => [sceneNoiseRecipe(type, false), sceneNoiseRecipe(type, true)]),
|
|
596
|
+
sceneToneRecipe("sine"),
|
|
597
|
+
sceneToneRecipe("square")
|
|
598
|
+
];
|
|
599
|
+
}
|
|
600
|
+
|
|
460
601
|
// src/audio.ts
|
|
461
602
|
var NOISE_SECONDS = 1.5;
|
|
462
|
-
var
|
|
463
|
-
const scope2 = globalThis;
|
|
464
|
-
const Ctor = scope2.AudioContext ?? scope2.webkitAudioContext;
|
|
465
|
-
return Ctor ? new Ctor() : null;
|
|
466
|
-
};
|
|
603
|
+
var DEFAULT_SEED = 1;
|
|
467
604
|
function createWeaponAudio(volume = 0.6, options = {}) {
|
|
468
|
-
const
|
|
469
|
-
const rng = createRng(options.seed ?? 1);
|
|
605
|
+
const seed = options.seed ?? DEFAULT_SEED;
|
|
470
606
|
const classes = { ...GAME_SOUND_CLASSES, ...options.classes };
|
|
471
607
|
const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance };
|
|
472
608
|
const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical };
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
master.gain.value = level;
|
|
484
|
-
master.connect(ctx.destination);
|
|
485
|
-
noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate);
|
|
486
|
-
const data = noise.getChannelData(0);
|
|
487
|
-
for (let i = 0; i < data.length; i++) data[i] = rng() * 2 - 1;
|
|
488
|
-
}
|
|
489
|
-
if (ctx.state === "suspended") void ctx.resume();
|
|
490
|
-
return ctx;
|
|
491
|
-
};
|
|
609
|
+
const shared = options.engine;
|
|
610
|
+
const engine = shared ?? createAudioEngine({
|
|
611
|
+
seed,
|
|
612
|
+
mix: { ...MIX_PROFILES.game, master: volume, noise: { seconds: NOISE_SECONDS, create: "eager" } },
|
|
613
|
+
maxVoices: Number.POSITIVE_INFINITY,
|
|
614
|
+
...options.createContext ? { createContext: options.createContext } : {}
|
|
615
|
+
});
|
|
616
|
+
const channel = shared && options.seed !== void 0 ? shared.channel({ seed }) : engine.channel({});
|
|
617
|
+
engine.register({ id: `weapons_three@${classBurstId(distanceCurve)}`, sounds: weaponRecipes(distanceCurve) });
|
|
618
|
+
const classBurst = classBurstId(distanceCurve);
|
|
492
619
|
const burst = (config) => {
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
const source = audio.createBufferSource();
|
|
497
|
-
source.buffer = noise;
|
|
498
|
-
const filter = audio.createBiquadFilter();
|
|
499
|
-
filter.type = config.filter;
|
|
500
|
-
filter.frequency.value = config.frequency;
|
|
501
|
-
filter.Q.value = config.q ?? 0.8;
|
|
502
|
-
const gain = audio.createGain();
|
|
503
|
-
gain.gain.setValueAtTime(1e-4, start);
|
|
504
|
-
gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 2e-4), start + 4e-3);
|
|
505
|
-
gain.gain.exponentialRampToValueAtTime(1e-4, start + config.seconds);
|
|
506
|
-
source.connect(filter).connect(gain).connect(master);
|
|
507
|
-
source.start(start, rng() * Math.max(0, NOISE_SECONDS - config.seconds));
|
|
508
|
-
source.stop(start + config.seconds + 0.05);
|
|
620
|
+
const id = config.filter === "highpass" ? BURST_IDS.highpass : BURST_IDS.lowpass;
|
|
621
|
+
const params = { frequency: config.frequency, q: config.q ?? 0.8, gain: Math.max(config.gain, 2e-4), seconds: config.seconds };
|
|
622
|
+
channel.play(id, { params, ...config.at ? { delay: config.at } : {} });
|
|
509
623
|
};
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
if (!audio || !noise || !master) return;
|
|
513
|
-
const start = audio.currentTime + at;
|
|
514
|
-
const source = audio.createBufferSource();
|
|
515
|
-
source.buffer = noise;
|
|
516
|
-
const filter = audio.createBiquadFilter();
|
|
517
|
-
filter.type = "lowpass";
|
|
518
|
-
filter.frequency.value = cutoff;
|
|
519
|
-
const envelope = audio.createGain();
|
|
520
|
-
envelope.gain.setValueAtTime(gain, start);
|
|
521
|
-
envelope.gain.exponentialRampToValueAtTime(1e-3, start + seconds);
|
|
522
|
-
source.connect(filter).connect(envelope).connect(master);
|
|
523
|
-
source.start(start, rng() * Math.max(0, NOISE_SECONDS - seconds));
|
|
524
|
-
source.stop(start + seconds + 0.05);
|
|
624
|
+
const classBurstAt = (at, cutoff, gain, seconds) => {
|
|
625
|
+
channel.play(classBurst, { params: { cutoff, gain, seconds }, ...at ? { delay: at } : {} });
|
|
525
626
|
};
|
|
526
627
|
const tone = (config) => {
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const osc = audio.createOscillator();
|
|
531
|
-
osc.type = config.type ?? "sine";
|
|
532
|
-
osc.frequency.setValueAtTime(config.frequency, start);
|
|
533
|
-
if (config.to) osc.frequency.exponentialRampToValueAtTime(config.to, start + config.seconds);
|
|
534
|
-
const gain = audio.createGain();
|
|
535
|
-
gain.gain.setValueAtTime(1e-4, start);
|
|
536
|
-
gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 2e-4), start + 3e-3);
|
|
537
|
-
gain.gain.exponentialRampToValueAtTime(1e-4, start + config.seconds);
|
|
538
|
-
osc.connect(gain).connect(master);
|
|
539
|
-
osc.start(start);
|
|
540
|
-
osc.stop(start + config.seconds + 0.05);
|
|
628
|
+
const id = config.to ? TONE_IDS.sine_sweep : config.type === "square" ? TONE_IDS.square : TONE_IDS.sine;
|
|
629
|
+
const params = { frequency: config.frequency, gain: Math.max(config.gain, 2e-4), seconds: config.seconds, ...config.to ? { to: config.to } : {} };
|
|
630
|
+
channel.play(id, { params, ...config.at ? { delay: config.at } : {} });
|
|
541
631
|
};
|
|
542
632
|
const metal2 = (at, frequency, gain) => {
|
|
543
633
|
burst({ at, seconds: 0.05, gain, filter: "highpass", frequency, q: 2 });
|
|
544
634
|
tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: "square" });
|
|
545
635
|
};
|
|
546
636
|
const play = (soundClass, classVolume = 1, distance = 0, at = 0) => {
|
|
547
|
-
const attenuation = classVolume / (1 + distance * distance * distanceCurve.gainFalloff);
|
|
548
|
-
if (attenuation < distanceCurve.minGain) return;
|
|
549
637
|
const [cutoff, gain, seconds] = classes[soundClass] ?? FALLBACK_SOUND_CLASS;
|
|
550
|
-
classBurst
|
|
638
|
+
channel.play(classBurst, { volume: classVolume, distance, params: { cutoff, gain, seconds }, ...at ? { delay: at } : {} });
|
|
639
|
+
};
|
|
640
|
+
const sceneTone = (entry) => {
|
|
641
|
+
channel.play(SCENE_TONE_IDS[entry.wave], { params: { f: entry.f, f2: entry.f2 ?? entry.f, d: entry.d, vol: entry.vol }, ...entry.at ? { delay: entry.at } : {} });
|
|
642
|
+
};
|
|
643
|
+
const sceneNoise2 = (entry) => {
|
|
644
|
+
const slide2 = entry.f2 !== void 0;
|
|
645
|
+
const id = slide2 ? `${SCENE_NOISE_IDS[entry.type]}_slide` : SCENE_NOISE_IDS[entry.type];
|
|
646
|
+
channel.play(id, { params: { f: entry.f, ...slide2 ? { f2: entry.f2 } : {}, q: entry.q, d: entry.d, vol: entry.vol }, ...entry.at ? { delay: entry.at } : {} });
|
|
551
647
|
};
|
|
552
648
|
const step = (entry) => {
|
|
553
649
|
if (entry.layer === "metal") metal2(entry.at, entry.frequency, entry.gain);
|
|
650
|
+
else if (entry.layer === "scene_tone") sceneTone(entry);
|
|
651
|
+
else if (entry.layer === "scene_noise") sceneNoise2(entry);
|
|
554
652
|
else if (entry.layer === "class") play(entry.soundClass, entry.volume, 0, entry.at);
|
|
555
653
|
else burst({ at: entry.at, seconds: 0.09, gain: entry.gain, filter: "lowpass", frequency: entry.frequency });
|
|
556
654
|
};
|
|
@@ -562,7 +660,7 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
562
660
|
shot(energyJ, category, extras = {}) {
|
|
563
661
|
const sound2 = shotSound({ ...extras, energyJ, category });
|
|
564
662
|
if (!sound2.audible) return;
|
|
565
|
-
|
|
663
|
+
classBurstAt(0, sound2.cutoff, sound2.gain, sound2.duration);
|
|
566
664
|
if (sound2.crack.gain > 0) burst({ seconds: sound2.crack.duration, gain: sound2.crack.gain, filter: "highpass", frequency: sound2.crack.cutoff });
|
|
567
665
|
tone({ seconds: sound2.body.duration, gain: sound2.body.gain, frequency: sound2.body.frequency, to: sound2.body.to });
|
|
568
666
|
},
|
|
@@ -590,28 +688,26 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
590
688
|
mechanical("cycle");
|
|
591
689
|
},
|
|
592
690
|
clink() {
|
|
593
|
-
const f =
|
|
594
|
-
|
|
595
|
-
|
|
691
|
+
const f = 4200 + channel.random() * 1500;
|
|
692
|
+
const at = 0.25 + channel.random() * 0.2;
|
|
693
|
+
sceneTone({ layer: "scene_tone", at, wave: "sine", f, f2: 3800, d: 0.06, vol: 0.06 });
|
|
596
694
|
},
|
|
597
695
|
thud() {
|
|
598
696
|
burst({ seconds: 0.09, gain: 0.35, filter: "lowpass", frequency: 380 });
|
|
599
697
|
},
|
|
600
698
|
setVolume(next) {
|
|
601
|
-
level = Math.max(0, Math.min(1, next));
|
|
602
|
-
if (
|
|
699
|
+
const level = Math.max(0, Math.min(1, next));
|
|
700
|
+
if (shared) shared.setBus("weapons", { gain: level });
|
|
701
|
+
else engine.setMaster(level);
|
|
603
702
|
},
|
|
604
703
|
dispose() {
|
|
605
|
-
|
|
606
|
-
ctx = null;
|
|
607
|
-
master = null;
|
|
608
|
-
noise = null;
|
|
704
|
+
if (!shared) engine.dispose();
|
|
609
705
|
}
|
|
610
706
|
};
|
|
611
707
|
}
|
|
612
708
|
|
|
613
709
|
// src/box-fx.ts
|
|
614
|
-
import { createRng
|
|
710
|
+
import { createRng, muzzleEnergy as muzzleEnergy2 } from "@adatechnology/game-weapons";
|
|
615
711
|
|
|
616
712
|
// src/fx/layers.ts
|
|
617
713
|
var createLayers = () => ({ casings: true, magazines: true, muzzleFlash: true, attachments: true, beams: true });
|
|
@@ -3862,7 +3958,7 @@ var GRAVITY = 9.81;
|
|
|
3862
3958
|
function createBoxFx(options) {
|
|
3863
3959
|
const { THREE, scene, camera, arsenal, groundAt } = options;
|
|
3864
3960
|
const audio = options.audio ?? null;
|
|
3865
|
-
const random =
|
|
3961
|
+
const random = createRng(options.seed ?? 1);
|
|
3866
3962
|
const layers = options.layers ?? createLayers();
|
|
3867
3963
|
const bodies = [];
|
|
3868
3964
|
const brass = new THREE.MeshStandardMaterial({ color: 13214282, metalness: 0.8, roughness: 0.35 });
|
|
@@ -4029,7 +4125,7 @@ function createBoxFx(options) {
|
|
|
4029
4125
|
|
|
4030
4126
|
// src/fx/viewmodel.ts
|
|
4031
4127
|
import { createToolClipPlayer, toolAnimationStep } from "@adatechnology/game-contracts";
|
|
4032
|
-
import { createRng as
|
|
4128
|
+
import { createRng as createRng2, muzzleEnergy as muzzleEnergy3 } from "@adatechnology/game-weapons";
|
|
4033
4129
|
|
|
4034
4130
|
// src/animation/clip-builder.ts
|
|
4035
4131
|
import { STAGE_EVENT } from "@adatechnology/game-contracts";
|
|
@@ -5520,7 +5616,7 @@ var caliberOf = (arsenal, def) => def.action.kind === "firearm" ? arsenal.calibe
|
|
|
5520
5616
|
function createViewmodel(options) {
|
|
5521
5617
|
const { THREE, scene, camera, arsenal, groundAt, audio } = options;
|
|
5522
5618
|
const kit = modelKit(THREE);
|
|
5523
|
-
const random =
|
|
5619
|
+
const random = createRng2(options.seed ?? 1);
|
|
5524
5620
|
const layers = options.layers ?? createLayers();
|
|
5525
5621
|
const distance = () => options.soundDistance?.() ?? 0;
|
|
5526
5622
|
const particles = createParticles(THREE, scene, groundAt);
|
|
@@ -6769,7 +6865,8 @@ function createWeaponsTestModule(options = {}) {
|
|
|
6769
6865
|
const arsenal = options.arsenal ?? createArsenal({ locale });
|
|
6770
6866
|
const text = textOf(locale);
|
|
6771
6867
|
const accessoryText = accessoryTextOf(locale);
|
|
6772
|
-
const
|
|
6868
|
+
const seedOption = options.seed === void 0 ? {} : { seed: options.seed };
|
|
6869
|
+
let audio = options.sound === false ? null : createWeaponAudio(void 0, seedOption);
|
|
6773
6870
|
const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id));
|
|
6774
6871
|
const thumbnailBase = options.thumbnailBase ?? DEFAULT_THUMBNAIL_BASE;
|
|
6775
6872
|
const withThumbnail = (item, key) => {
|
|
@@ -6796,7 +6893,9 @@ function createWeaponsTestModule(options = {}) {
|
|
|
6796
6893
|
id: "weapons_area",
|
|
6797
6894
|
name: text.name,
|
|
6798
6895
|
group: text.group,
|
|
6799
|
-
audio
|
|
6896
|
+
get audio() {
|
|
6897
|
+
return audio;
|
|
6898
|
+
},
|
|
6800
6899
|
get fx() {
|
|
6801
6900
|
return fx;
|
|
6802
6901
|
},
|
|
@@ -6844,6 +6943,11 @@ function createWeaponsTestModule(options = {}) {
|
|
|
6844
6943
|
],
|
|
6845
6944
|
attach(lent) {
|
|
6846
6945
|
host = lent;
|
|
6946
|
+
const lentEngine = lent.audio?.engine;
|
|
6947
|
+
if (audio && lentEngine) {
|
|
6948
|
+
audio.dispose();
|
|
6949
|
+
audio = createWeaponAudio(void 0, { ...seedOption, engine: lentEngine });
|
|
6950
|
+
}
|
|
6847
6951
|
const created = createWeaponFx({
|
|
6848
6952
|
THREE: lent.THREE,
|
|
6849
6953
|
scene: lent.scene,
|