@adatechnology/game-weapons-three 0.12.0 → 0.13.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/dist/{chunk-ZVLG34JN.js → chunk-U4JAJ533.js} +178 -20
- package/dist/chunk-U4JAJ533.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.global.js +2098 -223
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/{testing-BlaMwqMW.d.ts → testing-DjtsFm2m.d.ts} +491 -6
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +9 -9
- package/dist/chunk-ZVLG34JN.js.map +0 -1
|
@@ -2164,6 +2164,75 @@ var reloadCueSteps = (id, profile = DEFAULT_SOUND_PROFILE, table = RELOAD_CUES)
|
|
|
2164
2164
|
});
|
|
2165
2165
|
};
|
|
2166
2166
|
|
|
2167
|
+
// src/audio/samples.ts
|
|
2168
|
+
import { sampleBankFromManifest } from "@adatechnology/game-audio";
|
|
2169
|
+
|
|
2170
|
+
// src/data/reload-sample-hits.json
|
|
2171
|
+
var reload_sample_hits_default = {
|
|
2172
|
+
$comment: "Seconds from the start of each recorded reload step to its hit (median of its takes), measured on the converted files by tools/sfx-sources/hits.mjs. The reload clip starts the sound that much early, so the hit lands on the frame the part reaches its stop.",
|
|
2173
|
+
hits: {
|
|
2174
|
+
bolt_lift: 0.072,
|
|
2175
|
+
bolt_lock: 0.078,
|
|
2176
|
+
bolt_pull: 0.128,
|
|
2177
|
+
bolt_push: 0.054,
|
|
2178
|
+
charging_handle_pull: 0.074,
|
|
2179
|
+
charging_handle_release: 0.048,
|
|
2180
|
+
cylinder_close: 0.024,
|
|
2181
|
+
cylinder_eject: 0.394,
|
|
2182
|
+
cylinder_open: 0.07,
|
|
2183
|
+
lever_close: 0.147,
|
|
2184
|
+
lever_open: 0.095,
|
|
2185
|
+
mag_out: 0.012,
|
|
2186
|
+
mag_seat: 0.094,
|
|
2187
|
+
pump_back: 0.094,
|
|
2188
|
+
pump_forward: 0.118,
|
|
2189
|
+
shell_insert: 0.21,
|
|
2190
|
+
slide_release: 0.031,
|
|
2191
|
+
speedloader: 0.089
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
|
|
2195
|
+
// src/audio/samples.ts
|
|
2196
|
+
var GUNSHOT_SAMPLE_IDS = [...Object.keys(gunshot_profiles_default.profiles), "suppressed_pistol", "suppressed_rifle"];
|
|
2197
|
+
var GUNSHOT_SAMPLE = {
|
|
2198
|
+
bus: "weapons",
|
|
2199
|
+
gain: 1,
|
|
2200
|
+
pitch: 0.04,
|
|
2201
|
+
crossover: { from: 20, to: 90 },
|
|
2202
|
+
falloff: { model: "inverse_square", k: 5e-4, minGain: 6e-4 },
|
|
2203
|
+
cutoffK: 0.04,
|
|
2204
|
+
priority: 3
|
|
2205
|
+
};
|
|
2206
|
+
var SUPPRESSED_SAMPLE = { ...GUNSHOT_SAMPLE, gain: 0.55, crossover: { from: 10, to: 50 }, falloff: { model: "inverse_square", k: 4e-3, minGain: 8e-4 } };
|
|
2207
|
+
var RELOAD_SAMPLE = { bus: "weapons", gain: 0.32, pitch: 0.05, falloff: { model: "inverse_square", k: 0.05, minGain: 2e-3 }, cutoffK: 0.02, priority: 2 };
|
|
2208
|
+
var CASING_SAMPLE = { bus: "weapons", gain: 0.22, pitch: 0.06, falloff: { model: "inverse_square", k: 0.08, minGain: 3e-3 }, cutoffK: 0.03, priority: 1 };
|
|
2209
|
+
var casingSampleId = (sample) => sample.replace(/_(pistol|rifle|shell)$/, "");
|
|
2210
|
+
var RELOAD_SAMPLE_HITS = reload_sample_hits_default.hits;
|
|
2211
|
+
var WEIGHT_INTENSITY = { light: 0.1, medium: 0.5, heavy: 0.9 };
|
|
2212
|
+
var CUES_IN_SAMPLE = { mag_release: "mag_out", mag_insert: "mag_seat" };
|
|
2213
|
+
var isGunshot = (id) => GUNSHOT_SAMPLE_IDS.includes(id);
|
|
2214
|
+
function weaponSampleDefaults(sound3, overrides = {}) {
|
|
2215
|
+
if (sound3.category !== "armas") return void 0;
|
|
2216
|
+
const base = sound3.id.startsWith("suppressed_") ? SUPPRESSED_SAMPLE : isGunshot(sound3.id) ? GUNSHOT_SAMPLE : sound3.id.startsWith("casing_drop_") ? CASING_SAMPLE : RELOAD_SAMPLE;
|
|
2217
|
+
return { ...base, ...overrides[sound3.id] };
|
|
2218
|
+
}
|
|
2219
|
+
function weaponSampleBank(options) {
|
|
2220
|
+
const bank = sampleBankFromManifest(options.manifest, { id: "weapons_three_samples", ...options.url ? {} : { baseUrl: options.baseUrl ?? "" }, defaults: (sound3) => weaponSampleDefaults(sound3, options.sounds) });
|
|
2221
|
+
const url = options.url;
|
|
2222
|
+
const remap = (refs) => refs && url ? refs.map((ref) => ({ ...ref, url: url(ref.url) })) : refs ? [...refs] : void 0;
|
|
2223
|
+
const samples = (bank.samples ?? []).map((sample) => {
|
|
2224
|
+
const tiers = sample.tiers?.map((tier) => ({ ...tier, close: remap(tier.close) ?? [], ...tier.far ? { far: remap(tier.far) ?? [] } : {} }));
|
|
2225
|
+
return {
|
|
2226
|
+
...sample,
|
|
2227
|
+
close: remap(sample.close) ?? [],
|
|
2228
|
+
...sample.far ? { far: remap(sample.far) ?? [] } : {},
|
|
2229
|
+
...tiers ? { tiers } : {},
|
|
2230
|
+
...isGunshot(sample.id) ? { choke: { voices: 3, fade: 0.06 } } : {}
|
|
2231
|
+
};
|
|
2232
|
+
});
|
|
2233
|
+
return { id: bank.id, samples };
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2167
2236
|
// src/audio.ts
|
|
2168
2237
|
var NOISE_SECONDS = 1.5;
|
|
2169
2238
|
var DEFAULT_SEED = 1;
|
|
@@ -2184,6 +2253,17 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
2184
2253
|
const channel = shared && options.seed !== void 0 ? shared.channel({ seed }) : engine.channel({});
|
|
2185
2254
|
engine.register({ id: `weapons_three@${classBurstId(distanceCurve)}`, sounds: weaponRecipes(distanceCurve) });
|
|
2186
2255
|
const classBurst = classBurstId(distanceCurve);
|
|
2256
|
+
const sampleBank = options.samples ? weaponSampleBank(options.samples) : null;
|
|
2257
|
+
if (sampleBank) engine.register(sampleBank);
|
|
2258
|
+
const sampleIds = new Set((sampleBank?.samples ?? []).map((sample) => sample.id));
|
|
2259
|
+
let sampleLoad = null;
|
|
2260
|
+
const loadSamples = () => sampleLoad ?? (sampleLoad = sampleIds.size > 0 ? engine.loadSamples([...sampleIds]).then(() => void 0, () => void 0) : Promise.resolve());
|
|
2261
|
+
const sampleReady = (id) => {
|
|
2262
|
+
if (!sampleIds.has(id)) return false;
|
|
2263
|
+
if (engine.sampleStatus(id) === "ready") return true;
|
|
2264
|
+
void loadSamples();
|
|
2265
|
+
return false;
|
|
2266
|
+
};
|
|
2187
2267
|
const burst = (config) => {
|
|
2188
2268
|
const id = config.filter === "highpass" ? BURST_IDS.highpass : BURST_IDS.lowpass;
|
|
2189
2269
|
const params = { frequency: config.frequency, q: config.q ?? 0.8, gain: Math.max(config.gain, 2e-4), seconds: config.seconds };
|
|
@@ -2232,8 +2312,14 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
2232
2312
|
};
|
|
2233
2313
|
const casing = (input) => {
|
|
2234
2314
|
const sound3 = computeCasingSound({ ...input, pitch: input.pitch ?? 1 + (channel.random() * 2 - 1) * 0.06 });
|
|
2315
|
+
const recorded = sound3.kind === "shell" ? "" : casingSampleId(sound3.sample);
|
|
2316
|
+
if (recorded && sampleReady(recorded)) {
|
|
2317
|
+
if ((input.bounce ?? 0) === 0) channel.play(recorded, { volume: Math.min(1, Math.max(0.2, (input.speed ?? 1.5) / 2.5)) });
|
|
2318
|
+
options.onCasing?.(sound3, "sample");
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2235
2321
|
for (const voice of sound3.voices) playCasingVoice(voice);
|
|
2236
|
-
options.onCasing?.(sound3);
|
|
2322
|
+
options.onCasing?.(sound3, "synth");
|
|
2237
2323
|
};
|
|
2238
2324
|
const lastTake = /* @__PURE__ */ new Map();
|
|
2239
2325
|
const pitchSpread = options.pitchSpread ?? 0.04;
|
|
@@ -2255,8 +2341,25 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
2255
2341
|
lastTake.set(profile, take);
|
|
2256
2342
|
const pitch = 1 + (channel.random() * 2 - 1) * pitchSpread;
|
|
2257
2343
|
const shot = computeGunshot({ ...base, take, pitch }, options.gunshot);
|
|
2344
|
+
const recorded = shot.samples.close;
|
|
2345
|
+
if (shot.audible && sampleReady(recorded)) {
|
|
2346
|
+
const occlusion = Math.min(1, Math.max(0, extras.occlusion ?? 0));
|
|
2347
|
+
const handle = channel.play(recorded, {
|
|
2348
|
+
volume: (extras.volume ?? 1) * (1 - 0.5 * occlusion),
|
|
2349
|
+
environment: base.space === "indoor" ? "indoor" : "outdoor",
|
|
2350
|
+
...extras.position ? { position: [extras.position[0], extras.position[1], extras.position[2]] } : {},
|
|
2351
|
+
...extras.distance === void 0 ? {} : { distance: extras.distance },
|
|
2352
|
+
...shot.delay > 0 ? { delay: shot.delay } : {}
|
|
2353
|
+
});
|
|
2354
|
+
if (base.space === "indoor") {
|
|
2355
|
+
for (const voice of shot.voices) if (voice.group === "tail") playGunshotVoice(voice, extras);
|
|
2356
|
+
}
|
|
2357
|
+
const layers = handle?.kind === "sample" ? handle.plan.layers.map((layer) => ({ role: layer.role, take: layer.take, rate: layer.rate })) : [];
|
|
2358
|
+
options.onGunshot?.(shot, { ...base, take, pitch }, { kind: "sample", id: recorded, layers });
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2258
2361
|
for (const voice of shot.voices) playGunshotVoice(voice, extras);
|
|
2259
|
-
if (shot.audible) options.onGunshot?.(shot, { ...base, take, pitch });
|
|
2362
|
+
if (shot.audible) options.onGunshot?.(shot, { ...base, take, pitch }, { kind: "synth" });
|
|
2260
2363
|
return;
|
|
2261
2364
|
}
|
|
2262
2365
|
const sound3 = shotSound({ ...extras, energyJ, category });
|
|
@@ -2271,9 +2374,17 @@ function createWeaponAudio(volume = 0.6, options = {}) {
|
|
|
2271
2374
|
mechanical("dry_fire");
|
|
2272
2375
|
},
|
|
2273
2376
|
mechanical,
|
|
2274
|
-
cue(id, profile) {
|
|
2275
|
-
|
|
2377
|
+
cue(id, profile, lead = 0) {
|
|
2378
|
+
const carriedBy = CUES_IN_SAMPLE[id];
|
|
2379
|
+
if (carriedBy && sampleReady(carriedBy)) return "carried";
|
|
2380
|
+
if (sampleReady(id)) {
|
|
2381
|
+
channel.play(id, { intensity: WEIGHT_INTENSITY[(profile ?? DEFAULT_SOUND_PROFILE).weight] });
|
|
2382
|
+
return "sample";
|
|
2383
|
+
}
|
|
2384
|
+
for (const entry of reloadCueSteps(id, profile, cueTable)) step(lead > 0 ? { ...entry, at: entry.at + lead } : entry);
|
|
2385
|
+
return "synth";
|
|
2276
2386
|
},
|
|
2387
|
+
loadSamples,
|
|
2277
2388
|
event(event) {
|
|
2278
2389
|
const id = mechanicalSoundOf(event);
|
|
2279
2390
|
if (id) mechanical(id);
|
|
@@ -6048,6 +6159,7 @@ import { createRng as createRng2, muzzleEnergy as muzzleEnergy4 } from "@adatech
|
|
|
6048
6159
|
|
|
6049
6160
|
// src/animation/clip-builder.ts
|
|
6050
6161
|
import { STAGE_EVENT } from "@adatechnology/game-contracts";
|
|
6162
|
+
var RELOAD_SAMPLE_HITS2 = reload_sample_hits_default.hits;
|
|
6051
6163
|
var ROOT = "root";
|
|
6052
6164
|
var AXIS_INDEX = { x: 0, y: 1, z: 2 };
|
|
6053
6165
|
var EASE_STEPS = 10;
|
|
@@ -6055,7 +6167,10 @@ var ease = (progress) => progress < 0.5 ? 2 * progress * progress : 1 - (-2 * pr
|
|
|
6055
6167
|
var move = (part, axis, start, duration, from, to) => ({ part, channel: "position", axis, start, duration, from, to });
|
|
6056
6168
|
var turn = (part, axis, start, duration, from, to) => ({ part, channel: "rotation", axis, start, duration, from, to });
|
|
6057
6169
|
var cue = (t, type, data) => ({ t, type, ...data ? { data } : {} });
|
|
6058
|
-
var sound2 = (t, id) =>
|
|
6170
|
+
var sound2 = (t, id) => {
|
|
6171
|
+
const lead = RELOAD_SAMPLE_HITS2[id];
|
|
6172
|
+
return lead ? { t, type: "sound", data: { id }, lead } : { t, type: "sound", data: { id } };
|
|
6173
|
+
};
|
|
6059
6174
|
var stage = (id, t) => ({ t, type: STAGE_EVENT, data: { stage: id } });
|
|
6060
6175
|
var valueAt = (tweens, t, includeInstants) => {
|
|
6061
6176
|
let value = 0;
|
|
@@ -7561,7 +7676,7 @@ function createClipEventHandler(world, session) {
|
|
|
7561
7676
|
breechRound();
|
|
7562
7677
|
break;
|
|
7563
7678
|
case "sound":
|
|
7564
|
-
world.sound(session.id, String(data.id), session.soundProfile);
|
|
7679
|
+
world.sound(session.id, String(data.id), session.soundProfile, typeof data.lead === "number" ? data.lead : void 0);
|
|
7565
7680
|
break;
|
|
7566
7681
|
default:
|
|
7567
7682
|
break;
|
|
@@ -8137,9 +8252,9 @@ function createViewmodel(options) {
|
|
|
8137
8252
|
audio,
|
|
8138
8253
|
layers,
|
|
8139
8254
|
groundAt,
|
|
8140
|
-
sound: (weapon, cue2, profile) => {
|
|
8141
|
-
audio?.cue(cue2, profile);
|
|
8142
|
-
options.onSound?.({ weapon, cue: cue2, profile });
|
|
8255
|
+
sound: (weapon, cue2, profile, lead) => {
|
|
8256
|
+
const played = audio?.cue(cue2, profile, lead);
|
|
8257
|
+
options.onSound?.({ weapon, cue: cue2, profile, ...played ? { played } : {} });
|
|
8143
8258
|
},
|
|
8144
8259
|
schedule: (delay, seconds, step, done) => void tasks.push({ delay, seconds, elapsed: 0, step: (progress) => step(ease(progress)), done })
|
|
8145
8260
|
};
|
|
@@ -9536,7 +9651,10 @@ var TEXT = {
|
|
|
9536
9651
|
reloadStart: "Reload started: {weapon} ({ammo}/{capacity})",
|
|
9537
9652
|
reloadClip: "Reload of {weapon}: {kind}, clip {clip} ({seconds} s)",
|
|
9538
9653
|
soundCue: "Sound: {cue} ({weapon})",
|
|
9654
|
+
cueRecorded: " \xB7 recorded",
|
|
9655
|
+
cueCarried: " \xB7 inside the next recording",
|
|
9539
9656
|
gunshotSound: "Shot sound: {profile}, take {take}/4, pitch {pitch}, {space}, {distance} m{far}",
|
|
9657
|
+
gunshotRecorded: " \xB7 recorded take {takes}",
|
|
9540
9658
|
casingSound: "Case lands: {case} on {surface}",
|
|
9541
9659
|
spaces: { indoor: "indoors", outdoor: "outdoors" },
|
|
9542
9660
|
surfaces: { hard: "concrete", wood: "wood", metal: "metal", soft: "dirt" },
|
|
@@ -9568,7 +9686,10 @@ var TEXT = {
|
|
|
9568
9686
|
reloadStart: "Recarga iniciada: {weapon} ({ammo}/{capacity})",
|
|
9569
9687
|
reloadClip: "Recarga de {weapon}: {kind}, clipe {clip} ({seconds} s)",
|
|
9570
9688
|
soundCue: "Som: {cue} ({weapon})",
|
|
9689
|
+
cueRecorded: " \xB7 grava\xE7\xE3o",
|
|
9690
|
+
cueCarried: " \xB7 dentro da grava\xE7\xE3o seguinte",
|
|
9571
9691
|
gunshotSound: "Som do tiro: {profile}, tomada {take}/4, tom {pitch}, {space}, {distance} m{far}",
|
|
9692
|
+
gunshotRecorded: " \xB7 grava\xE7\xE3o, tomada {takes}",
|
|
9572
9693
|
casingSound: "C\xE1psula caiu: {case} em {surface}",
|
|
9573
9694
|
spaces: { indoor: "ambiente fechado", outdoor: "ao ar livre" },
|
|
9574
9695
|
surfaces: { hard: "concreto", wood: "madeira", metal: "metal", soft: "terra" },
|
|
@@ -9690,7 +9811,7 @@ function createWeaponsTestModule(options = {}) {
|
|
|
9690
9811
|
const accessoryText = accessoryTextOf(locale);
|
|
9691
9812
|
const seedOption = options.seed === void 0 ? {} : { seed: options.seed };
|
|
9692
9813
|
let audio;
|
|
9693
|
-
const ownAudio = () => audio === void 0 ? audio = options.sound === false ? null : createWeaponAudio(void 0, seedOption) : audio;
|
|
9814
|
+
const ownAudio = () => audio === void 0 ? audio = options.sound === false ? null : createWeaponAudio(void 0, { ...seedOption, ...options.samples ? { samples: options.samples } : {} }) : audio;
|
|
9694
9815
|
const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id));
|
|
9695
9816
|
const thumbnailBase = options.thumbnailBase ?? DEFAULT_THUMBNAIL_BASE;
|
|
9696
9817
|
const withThumbnail = (item, key) => {
|
|
@@ -9777,18 +9898,22 @@ function createWeaponsTestModule(options = {}) {
|
|
|
9777
9898
|
audio = createWeaponAudio(void 0, {
|
|
9778
9899
|
...seedOption,
|
|
9779
9900
|
engine: lentEngine,
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9901
|
+
...options.samples ? { samples: options.samples } : {},
|
|
9902
|
+
onGunshot: (shot, input, played) => {
|
|
9903
|
+
const recorded = played.kind === "sample" && played.layers.length > 0 ? fill(text.gunshotRecorded, { takes: played.layers.map((layer) => `${layer.role} ${layer.take + 1}`).join(", ") }) : "";
|
|
9904
|
+
lent.log(
|
|
9905
|
+
fill(text.gunshotSound, { profile: shot.profile, take: String(shot.take + 1), pitch: `${shot.pitch >= 1 ? "+" : ""}${((shot.pitch - 1) * 100).toFixed(1)} %`, space: text.spaces[input.space ?? "outdoor"], distance: String(Math.round(input.distance ?? 0)), far: shot.closeMix < 1 ? ` (${Math.round((1 - shot.closeMix) * 100)} % far)` : "" }) + recorded,
|
|
9906
|
+
{ profile: shot.profile, take: shot.take, pitch: shot.pitch, space: input.space ?? "outdoor", distance: input.distance ?? 0, closeMix: shot.closeMix, delay: shot.delay, samples: shot.samples, played },
|
|
9907
|
+
"sound"
|
|
9908
|
+
);
|
|
9909
|
+
},
|
|
9910
|
+
onCasing: (sound3, played) => lent.log(fill(text.casingSound, { case: sound3.kind, surface: text.surfaces[sound3.surface] }) + (played === "sample" ? text.cueRecorded : ""), { case: sound3.kind, surface: sound3.surface, sample: sound3.sample, played }, "sound")
|
|
9786
9911
|
});
|
|
9787
9912
|
}
|
|
9788
9913
|
let simulatedMs = 0;
|
|
9789
9914
|
const offClock = lent.onFrame((dt) => simulatedMs += dt * 1e3);
|
|
9790
9915
|
const created = createWeaponFx({
|
|
9791
|
-
onSound: ({ weapon, cue: cue2, profile }) => lent.log(fill(text.soundCue, { weapon: arsenal.name(weapon), cue: text.soundCues[cue2] ?? cue2 }), { weapon, cue: cue2, weight: profile.weight, material: profile.material }, "sound"),
|
|
9916
|
+
onSound: ({ weapon, cue: cue2, profile, played }) => lent.log(fill(text.soundCue, { weapon: arsenal.name(weapon), cue: text.soundCues[cue2] ?? cue2 }) + (played === "sample" ? text.cueRecorded : played === "carried" ? text.cueCarried : ""), { weapon, cue: cue2, weight: profile.weight, material: profile.material, ...played ? { played } : {} }, "sound"),
|
|
9792
9917
|
THREE: lent.THREE,
|
|
9793
9918
|
scene: lent.scene,
|
|
9794
9919
|
camera: lent.camera,
|
|
@@ -9963,6 +10088,7 @@ var EXPLOSIVES_TEXT = {
|
|
|
9963
10088
|
push_outward: "Every body inside the reach moved away from the blast ({moved} of {n}, {least} m at the least)",
|
|
9964
10089
|
push_falloff: "{what}: the nearer one moved more than the farther one ({near} m at {nearDistance} m, {far} m at {farDistance} m)",
|
|
9965
10090
|
push_person: "{who} at {distance} m was pushed {moved} m away",
|
|
10091
|
+
push_sheltered: "{what} at {distance} m stood behind cover ({cover}% of the blast got through) and moved only {moved} m",
|
|
9966
10092
|
push_heavy: "{what} (too heavy to grab, not fixed) was moved {moved} m by the blast"
|
|
9967
10093
|
}
|
|
9968
10094
|
},
|
|
@@ -10048,6 +10174,7 @@ var EXPLOSIVES_TEXT = {
|
|
|
10048
10174
|
push_outward: "Todo corpo dentro do alcance se afastou da explos\xE3o ({moved} de {n}, no m\xEDnimo {least} m)",
|
|
10049
10175
|
push_falloff: "{what}: o mais perto andou mais que o mais longe ({near} m a {nearDistance} m, {far} m a {farDistance} m)",
|
|
10050
10176
|
push_person: "{who} a {distance} m foi empurrado {moved} m para longe",
|
|
10177
|
+
push_sheltered: "{what} a {distance} m estava atr\xE1s de cobertura ({cover}% da explos\xE3o passou) e andou s\xF3 {moved} m",
|
|
10051
10178
|
push_heavy: "{what} (pesado demais para pegar, mas solto) foi movido {moved} m pela explos\xE3o"
|
|
10052
10179
|
}
|
|
10053
10180
|
}
|
|
@@ -10593,6 +10720,10 @@ var PUSH_KINDS = [
|
|
|
10593
10720
|
];
|
|
10594
10721
|
var PUSH_READ_AT = 0.8;
|
|
10595
10722
|
var MOVED = 0.15;
|
|
10723
|
+
var SHELTERED = 0.5;
|
|
10724
|
+
var SHELTERED_MOST = 1;
|
|
10725
|
+
var CHEST = 1.1;
|
|
10726
|
+
var MIDDLE = 0.3;
|
|
10596
10727
|
var HEAVY_ITEMS = ["camp_table"];
|
|
10597
10728
|
var flat = (a, b) => Math.hypot(a[0] - b[0], a[2] - b[2]);
|
|
10598
10729
|
var bearing = (centre, distance, degrees) => [centre[0] + Math.sin(degrees * Math.PI / 180) * distance, 0, centre[2] + Math.cos(degrees * Math.PI / 180) * distance];
|
|
@@ -10609,9 +10740,11 @@ function pushScenario(all, bench, mode) {
|
|
|
10609
10740
|
name: mode === "p13" ? text.push_p13 : text.push_grenade,
|
|
10610
10741
|
run: ({ room, step, expect }) => {
|
|
10611
10742
|
let centre;
|
|
10743
|
+
let source;
|
|
10612
10744
|
if (mode === "p13") {
|
|
10613
10745
|
room.openArea(EXPLOSIVES_AREA_ID);
|
|
10614
10746
|
const cylinder = room.spawned().find((spawned) => spawned.itemId === CYLINDER_ITEM);
|
|
10747
|
+
source = cylinder?.objectId;
|
|
10615
10748
|
const at = cylinder?.root?.position;
|
|
10616
10749
|
centre = [at?.x ?? 0, 0, at?.z ?? -10.66];
|
|
10617
10750
|
} else {
|
|
@@ -10662,6 +10795,14 @@ function pushScenario(all, bench, mode) {
|
|
|
10662
10795
|
const blast = bench.lastBlast();
|
|
10663
10796
|
expect(!!blast, text.push_told, { waited });
|
|
10664
10797
|
if (!blast) return;
|
|
10798
|
+
const coverOf = new Map(
|
|
10799
|
+
placed.map((body) => {
|
|
10800
|
+
const from = origin.get(body.objectId) ?? body.from;
|
|
10801
|
+
const person = body.kind === "zombie" || body.kind === "survivor";
|
|
10802
|
+
const ignore = source ? [source, body.objectId] : [body.objectId];
|
|
10803
|
+
return [body.objectId, room.world.blastReach?.(blast.point, [from[0], from[1] + (person ? CHEST : MIDDLE), from[2]], { ignore }) ?? 1];
|
|
10804
|
+
})
|
|
10805
|
+
);
|
|
10665
10806
|
step(PUSH_READ_AT);
|
|
10666
10807
|
const rows = placed.map((body) => {
|
|
10667
10808
|
const from = origin.get(body.objectId) ?? body.from;
|
|
@@ -10669,10 +10810,15 @@ function pushScenario(all, bench, mode) {
|
|
|
10669
10810
|
const distance = flat(from, blast.point);
|
|
10670
10811
|
const away = Math.max(1e-6, distance);
|
|
10671
10812
|
const outward = ((now[0] - from[0]) * (from[0] - blast.point[0]) + (now[2] - from[2]) * (from[2] - blast.point[2])) / away;
|
|
10672
|
-
return { ...body, distance, outward, moved: flat(now, from) };
|
|
10813
|
+
return { ...body, distance, outward, moved: flat(now, from), cover: coverOf.get(body.objectId) ?? 1 };
|
|
10673
10814
|
});
|
|
10674
10815
|
const torn = (row) => (PUSH_KINDS.some((entry) => entry.kind === row.kind) || HEAVY_ITEMS.includes(row.kind)) && partsOf(row.objectId) < (partsBefore.get(row.objectId) ?? 0);
|
|
10675
|
-
const
|
|
10816
|
+
const inReach = rows.filter((row) => row.distance < blast.radius * 0.85 && !torn(row));
|
|
10817
|
+
const sheltered = inReach.filter((row) => row.cover < SHELTERED);
|
|
10818
|
+
for (const row of sheltered) {
|
|
10819
|
+
expect(row.outward < SHELTERED_MOST, fillText2(text.push_sheltered, { what: things[row.kind] ?? row.kind, distance: row.distance.toFixed(1), cover: (row.cover * 100).toFixed(0), moved: Math.max(0, row.outward).toFixed(2) }), { row: { kind: row.kind, distance: row.distance, outward: row.outward, cover: row.cover } });
|
|
10820
|
+
}
|
|
10821
|
+
const reached = inReach.filter((row) => row.cover >= SHELTERED);
|
|
10676
10822
|
const movedAway = reached.filter((row) => row.outward >= MOVED);
|
|
10677
10823
|
const least = reached.length === 0 ? 0 : Math.min(...reached.map((row) => row.outward));
|
|
10678
10824
|
expect(reached.length > 0 && movedAway.length === reached.length, fillText2(text.push_outward, { moved: movedAway.length, n: reached.length, least: least.toFixed(2) }), { rows: reached.map((row) => ({ kind: row.kind, distance: row.distance, outward: row.outward })), torn: rows.filter(torn).map((row) => row.objectId) });
|
|
@@ -10842,6 +10988,18 @@ export {
|
|
|
10842
10988
|
DEFAULT_ENERGY_CURVE,
|
|
10843
10989
|
CLASS_REFERENCE_ENERGY,
|
|
10844
10990
|
computeShotSound,
|
|
10991
|
+
GUNSHOT_PROFILES,
|
|
10992
|
+
computeGunshot,
|
|
10993
|
+
computeCasingSound,
|
|
10994
|
+
computeFlyby,
|
|
10995
|
+
GUNSHOT_SAMPLE_IDS,
|
|
10996
|
+
GUNSHOT_SAMPLE,
|
|
10997
|
+
RELOAD_SAMPLE,
|
|
10998
|
+
RELOAD_SAMPLE_HITS,
|
|
10999
|
+
WEIGHT_INTENSITY,
|
|
11000
|
+
CUES_IN_SAMPLE,
|
|
11001
|
+
weaponSampleDefaults,
|
|
11002
|
+
weaponSampleBank,
|
|
10845
11003
|
createWeaponAudio,
|
|
10846
11004
|
BODY_ACTIONS,
|
|
10847
11005
|
weaponProp,
|
|
@@ -10899,4 +11057,4 @@ export {
|
|
|
10899
11057
|
DEFAULT_EXPLOSIVES_SCENE,
|
|
10900
11058
|
createExplosivesTestModule
|
|
10901
11059
|
};
|
|
10902
|
-
//# sourceMappingURL=chunk-
|
|
11060
|
+
//# sourceMappingURL=chunk-U4JAJ533.js.map
|