@adatechnology/game-weapons-three 0.13.0 → 0.14.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 CHANGED
@@ -1,5 +1,5 @@
1
- import { I as ItemModels, W as WeaponProps, a as WeaponItemModel, M as ModelKit, b as WeaponModel, c as ModelParts, d as ModelFamily, A as AttachmentModelRegistry, L as LaserRaycast } from './testing-BoxqhX_W.js';
2
- export { e as ARCHETYPE_MODELS, f as AttachmentBuildContext, g as AttachmentModel, h as AttachmentModelBuilder, C as CLASS_REFERENCE_ENERGY, i as COUNTER_ITEM_ID, j as CUES_IN_SAMPLE, k as CasingSound, l as CuePlayed, D as DEFAULT_ENERGY_CURVE, m as DEFAULT_EXPLOSIVES_SCENE, n as DistanceCurve, E as EXPLOSIVES_AREA_ID, o as EXPLOSIVES_TEXT, p as EnergyCurve, q as ExplosivesRoom, r as ExplosivesScene, s as ExplosivesTestModuleOptions, t as ExplosivesText, F as FlybySound, u as FxLayers, G as GAME_DISTANCE_CURVE, v as GAME_SOUND_CLASSES, w as GUNSHOT_PROFILES, x as GUNSHOT_SAMPLE, y as GUNSHOT_SAMPLE_IDS, z as Gunshot, B as GunshotInput, H as GunshotPlayed, J as ItemModelRequest, K as MECHANICAL_SOUNDS, N as MODEL_ENTRIES, O as MOUNTED_M134_ITEM_ID, P as MechanicalSoundId, Q as ModelEntry, R as ModelMaterials, S as ModelOptions, T as MountFrame, U as RELOAD_SAMPLE, V as RELOAD_SAMPLE_HITS, X as ShotExtras, Y as ShotSound, Z as ShotSoundClass, _ as ShotSoundInput, $ as ShotSoundOptions, a0 as SoundClassDef, a1 as SoundStep, a2 as WEAPON_ITEM_PREFIX, a3 as WEIGHT_INTENSITY, a4 as WeaponAudio, a5 as WeaponAudioOptions, a6 as WeaponFx, a7 as WeaponFxOptions, a8 as WeaponSampleOptions, a9 as WeaponsTestModuleOptions, aa as buildItemWeaponModel, ab as buildWeaponModel, ac as buildWeaponModelById, ad as computeCasingSound, ae as computeFlyby, af as computeGunshot, ag as computeShotSound, ah as createExplosivesTestModule, ai as createWeaponAudio, aj as createWeaponFx, ak as createWeaponsTestModule, al as defaultWeaponProps, am as deriveFrames, an as explosivesTextOf, ao as hasWeaponModel, ap as itemModelOfWeapon, aq as mechanicalSoundOf, ar as modelKit, as as mountFrame, at as registerWeaponItemModel, au as weaponSampleBank, av as weaponSampleDefaults, aw as weaponsLayout } from './testing-BoxqhX_W.js';
1
+ import { I as ItemModels, W as WeaponProps, a as WeaponItemModel, M as ModelKit, b as WeaponModel, c as ModelParts, d as ModelFamily, A as AttachmentModelRegistry, L as LaserRaycast } from './testing-DnPjEPC5.js';
2
+ export { e as ARCHETYPE_MODELS, f as AttachmentBuildContext, g as AttachmentModel, h as AttachmentModelBuilder, C as CLASS_REFERENCE_ENERGY, i as COUNTER_ITEM_ID, j as CUES_IN_SAMPLE, k as CasingSound, l as CuePlayed, D as DEFAULT_ENERGY_CURVE, m as DEFAULT_EXPLOSIVES_SCENE, n as DistanceCurve, E as EXPLOSIVES_AREA_ID, o as EXPLOSIVES_TEXT, p as EnergyCurve, q as ExplosivesRoom, r as ExplosivesScene, s as ExplosivesTestModuleOptions, t as ExplosivesText, F as FlybySound, u as FxLayers, G as GAME_DISTANCE_CURVE, v as GAME_SOUND_CLASSES, w as GUNSHOT_PROFILES, x as GUNSHOT_SAMPLE, y as GUNSHOT_SAMPLE_IDS, z as Gunshot, B as GunshotInput, H as GunshotPlayed, J as ItemModelRequest, K as MECHANICAL_SOUNDS, N as MODEL_ENTRIES, O as MOUNTED_M134_ITEM_ID, P as MechanicalSoundId, Q as ModelEntry, R as ModelMaterials, S as ModelOptions, T as MountFrame, U as RELOAD_SAMPLE, V as RELOAD_SAMPLE_HITS, X as ShotExtras, Y as ShotSound, Z as ShotSoundClass, _ as ShotSoundInput, $ as ShotSoundOptions, a0 as SoundClassDef, a1 as SoundStep, a2 as WEAPON_ITEM_PREFIX, a3 as WEIGHT_INTENSITY, a4 as WeaponAudio, a5 as WeaponAudioOptions, a6 as WeaponFx, a7 as WeaponFxOptions, a8 as WeaponSampleOptions, a9 as WeaponsTestModuleOptions, aa as buildItemWeaponModel, ab as buildWeaponModel, ac as buildWeaponModelById, ad as computeCasingSound, ae as computeFlyby, af as computeGunshot, ag as computeShotSound, ah as createExplosivesTestModule, ai as createWeaponAudio, aj as createWeaponFx, ak as createWeaponsTestModule, al as defaultWeaponProps, am as deriveFrames, an as explosivesTextOf, ao as hasWeaponModel, ap as itemModelOfWeapon, aq as mechanicalSoundOf, ar as modelKit, as as mountFrame, at as registerWeaponItemModel, au as weaponSampleBank, av as weaponSampleDefaults, aw as weaponsLayout } from './testing-DnPjEPC5.js';
3
3
  import * as THREE_NS from 'three';
4
4
  import { TestableItem, Vec3, HostEvent, EffectSink, DestructibleSpec, DeepPartial, ToolClipSet } from '@adatechnology/game-contracts';
5
5
  import { ExplosiveDef, Arsenal, WeaponDef, CartridgeDims, CaliberDef, CaseType, ReloadFamily, FittedAttachment, AttachmentDef } from '@adatechnology/game-weapons';
@@ -98,6 +98,24 @@ var GameWeaponsThree = (() => {
98
98
  });
99
99
 
100
100
  // ../game-contracts/dist/index.js
101
+ var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
102
+ var NEAREST = 0.3;
103
+ function sideOnImpulse(tnt, distance3) {
104
+ if (!(tnt > 0)) return 0;
105
+ const w3 = Math.cbrt(tnt);
106
+ const z = Math.max(distance3, NEAREST) / w3;
107
+ const scaled2 = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
108
+ return scaled2 * w3 * 100;
109
+ }
110
+ function bodyImpulse(tnt, distance3) {
111
+ if (!(tnt > 0)) return 0;
112
+ const z = Math.max(distance3, NEAREST) / Math.cbrt(tnt);
113
+ return sideOnImpulse(tnt, distance3) * (2 + 4 / (1 + z * z));
114
+ }
115
+ function blastBodySpeed(tnt, distance3, mass, reach = 1, options = {}) {
116
+ const area3 = options.bodyArea ?? DEFAULT_BLAST_IMPULSE.bodyArea;
117
+ return bodyImpulse(tnt, distance3) * area3 * Math.max(0, reach) / Math.max(mass, 1);
118
+ }
101
119
  var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
102
120
  var DEFAULT_IGNITION_RULES = {
103
121
  fillCurve: [
@@ -4099,6 +4117,7 @@ var GameWeaponsThree = (() => {
4099
4117
  lethalRadius: 5,
4100
4118
  injuryRadius: 15,
4101
4119
  energy: 2e5,
4120
+ tnt: 0.24,
4102
4121
  destructionLevel: 2,
4103
4122
  noise: 500,
4104
4123
  fuse: 4,
@@ -4144,6 +4163,7 @@ var GameWeaponsThree = (() => {
4144
4163
  lethalRadius: 3,
4145
4164
  injuryRadius: 10,
4146
4165
  energy: 43200,
4166
+ tnt: 0.15,
4147
4167
  destructionLevel: 2,
4148
4168
  noise: 450,
4149
4169
  fuse: 3,
@@ -4163,6 +4183,7 @@ var GameWeaponsThree = (() => {
4163
4183
  lethalRadius: 5,
4164
4184
  injuryRadius: 14,
4165
4185
  energy: 2e5,
4186
+ tnt: 1.5,
4166
4187
  destructionLevel: 2,
4167
4188
  noise: 550,
4168
4189
  fire: {
@@ -4209,6 +4230,7 @@ var GameWeaponsThree = (() => {
4209
4230
  lethalRadius: 4,
4210
4231
  injuryRadius: 12,
4211
4232
  energy: 102400,
4233
+ tnt: 0.25,
4212
4234
  destructionLevel: 3,
4213
4235
  noise: 600,
4214
4236
  fuseLength: 0.03,
@@ -4231,6 +4253,7 @@ var GameWeaponsThree = (() => {
4231
4253
  lethalRadius: 6,
4232
4254
  injuryRadius: 18,
4233
4255
  energy: 345600,
4256
+ tnt: 0.76,
4234
4257
  destructionLevel: 3,
4235
4258
  noise: 700,
4236
4259
  triggers: [
@@ -4254,6 +4277,7 @@ var GameWeaponsThree = (() => {
4254
4277
  length: 50
4255
4278
  },
4256
4279
  energy: 102400,
4280
+ tnt: 0.9,
4257
4281
  destructionLevel: 1,
4258
4282
  noise: 500,
4259
4283
  triggers: [
@@ -4277,6 +4301,7 @@ var GameWeaponsThree = (() => {
4277
4301
  lethalRadius: 0,
4278
4302
  injuryRadius: 10,
4279
4303
  energy: 0,
4304
+ tnt: 0.01,
4280
4305
  destructionLevel: 0,
4281
4306
  noise: 400,
4282
4307
  fuseRange: [
@@ -4301,6 +4326,7 @@ var GameWeaponsThree = (() => {
4301
4326
  lethalRadius: 4,
4302
4327
  injuryRadius: 12,
4303
4328
  energy: 102400,
4329
+ tnt: 0.045,
4304
4330
  destructionLevel: 2,
4305
4331
  noise: 450,
4306
4332
  triggers: [
@@ -4319,6 +4345,7 @@ var GameWeaponsThree = (() => {
4319
4345
  lethalRadius: 5,
4320
4346
  injuryRadius: 15,
4321
4347
  energy: 2e5,
4348
+ tnt: 0.45,
4322
4349
  destructionLevel: 3,
4323
4350
  noise: 700,
4324
4351
  triggers: [
@@ -4337,6 +4364,7 @@ var GameWeaponsThree = (() => {
4337
4364
  lethalRadius: 5,
4338
4365
  injuryRadius: 16,
4339
4366
  energy: 2e5,
4367
+ tnt: 0.7,
4340
4368
  destructionLevel: 3,
4341
4369
  noise: 750,
4342
4370
  triggers: [
@@ -4355,6 +4383,7 @@ var GameWeaponsThree = (() => {
4355
4383
  lethalRadius: 5,
4356
4384
  injuryRadius: 16,
4357
4385
  energy: 2e5,
4386
+ tnt: 0.45,
4358
4387
  destructionLevel: 3,
4359
4388
  noise: 750,
4360
4389
  triggers: [
@@ -4373,6 +4402,7 @@ var GameWeaponsThree = (() => {
4373
4402
  lethalRadius: 5,
4374
4403
  injuryRadius: 16,
4375
4404
  energy: 2e5,
4405
+ tnt: 0.7,
4376
4406
  destructionLevel: 3,
4377
4407
  noise: 750,
4378
4408
  triggers: [
@@ -4391,6 +4421,7 @@ var GameWeaponsThree = (() => {
4391
4421
  lethalRadius: 4,
4392
4422
  injuryRadius: 12,
4393
4423
  energy: 102400,
4424
+ tnt: 1,
4394
4425
  destructionLevel: 2,
4395
4426
  noise: 550,
4396
4427
  fire: {
@@ -4424,6 +4455,7 @@ var GameWeaponsThree = (() => {
4424
4455
  lethalRadius: 5,
4425
4456
  injuryRadius: 14,
4426
4457
  energy: 2e5,
4458
+ tnt: 0.5,
4427
4459
  destructionLevel: 2,
4428
4460
  noise: 550,
4429
4461
  fire: {
@@ -4461,6 +4493,7 @@ var GameWeaponsThree = (() => {
4461
4493
  lethalRadius: 4,
4462
4494
  injuryRadius: 12,
4463
4495
  energy: 102400,
4496
+ tnt: 0.5,
4464
4497
  destructionLevel: 3,
4465
4498
  noise: 700,
4466
4499
  fire: {
@@ -4490,6 +4523,7 @@ var GameWeaponsThree = (() => {
4490
4523
  lethalRadius: 12,
4491
4524
  injuryRadius: 30,
4492
4525
  energy: 2764800,
4526
+ tnt: 20,
4493
4527
  destructionLevel: 3,
4494
4528
  noise: 700,
4495
4529
  fire: {
@@ -4517,6 +4551,7 @@ var GameWeaponsThree = (() => {
4517
4551
  lethalRadius: 4,
4518
4552
  injuryRadius: 12,
4519
4553
  energy: 102400,
4554
+ tnt: 0.045,
4520
4555
  destructionLevel: 2,
4521
4556
  noise: 450,
4522
4557
  triggers: [
@@ -13235,6 +13270,7 @@ var GameWeaponsThree = (() => {
13235
13270
  direction: this.facing,
13236
13271
  at: at3,
13237
13272
  energy: def.energy,
13273
+ ...def.tnt !== void 0 ? { tnt: def.tnt } : {},
13238
13274
  lethalRadius: def.lethalRadius,
13239
13275
  injuryRadius: def.injuryRadius,
13240
13276
  noise: def.noise,
@@ -23926,7 +23962,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23926
23962
  return;
23927
23963
  }
23928
23964
  if (ex) {
23929
- emit2({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
23965
+ emit2({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.tnt !== void 0 ? { tnt: ex.tnt } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
23930
23966
  blasts.push({ point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, source: src });
23931
23967
  }
23932
23968
  partLost(o, p, src);
@@ -36893,7 +36929,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36893
36929
  };
36894
36930
  var accessoryTextOf = (locale) => ACCESSORY_TEXT[locale] ?? ACCESSORY_TEXT.en;
36895
36931
 
36896
- // ../game-audio/dist/chunk-7TLFY7VO.js
36932
+ // ../game-audio/dist/chunk-KBTUANNG.js
36897
36933
  var DISTANCE_CURVES = {
36898
36934
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
36899
36935
  game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
@@ -38762,10 +38798,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
38762
38798
  noise: () => noiseBuffer(store, audio, mix3.noise.seconds),
38763
38799
  time
38764
38800
  });
38801
+ const recipeBank = registry.bankOf(plan.id);
38765
38802
  announce({
38766
38803
  id: plan.id,
38767
38804
  kind: "recipe",
38768
38805
  ...fallbackOf ? { fallbackOf } : {},
38806
+ ...recipeBank ? { bank: recipeBank } : {},
38769
38807
  requestedAt,
38770
38808
  startAt: time,
38771
38809
  outputLatency: latencyOf(audio),
@@ -38867,9 +38905,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
38867
38905
  const time = requestedAt + (playOptions.delay ?? 0);
38868
38906
  const chokeList = sample.choke ? choked(sample.id) : void 0;
38869
38907
  const realized = realizeSample(plan, { context: audio, output: sampleOutput(plan.bus), buffer: (url2) => sampleStore.buffer(url2), time });
38908
+ const sampleBank = registry.bankOf(plan.id);
38870
38909
  announce({
38871
38910
  id: plan.id,
38872
38911
  kind: "sample",
38912
+ ...sampleBank ? { bank: sampleBank } : {},
38873
38913
  requestedAt,
38874
38914
  startAt: time,
38875
38915
  outputLatency: latencyOf(audio),
@@ -39190,7 +39230,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39190
39230
  ["casing_drop_terra_pistol", 1],
39191
39231
  ["casing_drop_terra_rifle", 1],
39192
39232
  ["casing_drop_terra_shell", 1],
39193
- ["rocket_fire", 2]
39233
+ ["rocket_fire", 2],
39234
+ ["smg_45_auto", 2, "sfx_pistol"],
39235
+ ["weapon_draw", 2],
39236
+ ["suppressor_attach", 3],
39237
+ ["suppressor_detach", 3]
39194
39238
  ]),
39195
39239
  ...entries("explosoes-fogo", [
39196
39240
  ["explosion_grenade", 1, "boom"],
@@ -39204,7 +39248,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39204
39248
  ["fire_loop_large", 1],
39205
39249
  ["fire_extinguish", 2, "hiss"],
39206
39250
  ["gas_leak_hiss", 2],
39207
- ["structure_collapse", 2, "crumble"]
39251
+ ["structure_collapse", 2, "crumble"],
39252
+ ["grenade_bounce", 1],
39253
+ ["c4_plant", 2],
39254
+ ["c4_beep", 2],
39255
+ ["c4_disarm", 2]
39208
39256
  ]),
39209
39257
  ...entries("personagem", [
39210
39258
  ["footstep_concrete_walk", 1, "sfx_step"],
@@ -39220,7 +39268,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39220
39268
  ["blunt_hit", 1],
39221
39269
  ["bite", 1, "sfx_flesh"],
39222
39270
  ["body_fall", 1],
39223
- ["player_hurt", 2]
39271
+ ["player_hurt", 2],
39272
+ ["footstep_tile_walk", 1, "sfx_step"],
39273
+ ["footstep_water_walk", 1, "sfx_step"],
39274
+ ["footstep_grate_walk", 2, "sfx_step"],
39275
+ ["footstep_duct_walk", 3, "sfx_step"],
39276
+ ["ladder_climb", 2],
39277
+ ["swim", 2],
39278
+ ["zombie_groan", 1],
39279
+ ["zombie_alert", 1],
39280
+ ["zombie_attack", 1],
39281
+ ["zombie_pain", 1],
39282
+ ["zombie_claw_hit", 1, "sfx_flesh"],
39283
+ ["zombie_claw_miss", 2]
39224
39284
  ]),
39225
39285
  ...entries("veiculos", [
39226
39286
  ["engine_loop_car", 1],
@@ -39248,7 +39308,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39248
39308
  ["wind_loop", 2],
39249
39309
  ["thunder_near", 2],
39250
39310
  ["thunder_far", 2],
39251
- ["water_splash", 2]
39311
+ ["water_splash", 2],
39312
+ ["helicopter_loop", 3]
39252
39313
  ])
39253
39314
  ];
39254
39315
  var SFX_MATERIALS = [
@@ -39330,6 +39391,60 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39330
39391
  burst: 20,
39331
39392
  burstSpacing: 0.06
39332
39393
  };
39394
+ var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
39395
+ function splitTier(id) {
39396
+ const match = /^(.*)_(light|medium|heavy)$/.exec(id);
39397
+ return match ? { base: match[1], tier: match[2] } : { base: id };
39398
+ }
39399
+ var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry2) => ({ url: `${baseUrl}${entry2.file}` }));
39400
+ function sampleBankFromManifest(manifest, options) {
39401
+ const baseUrl = options.baseUrl ?? "";
39402
+ const samples = [];
39403
+ const tiersOf = /* @__PURE__ */ new Map();
39404
+ for (const sound3 of manifest.sounds) {
39405
+ const { base, tier } = splitTier(sound3.id);
39406
+ if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound3]);
39407
+ }
39408
+ const bases = /* @__PURE__ */ new Map();
39409
+ for (const sound3 of manifest.sounds) {
39410
+ if (!splitTier(sound3.id).tier) bases.set(sound3.id, sound3);
39411
+ }
39412
+ for (const [base, tiers] of tiersOf) {
39413
+ if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
39414
+ }
39415
+ for (const sound3 of bases.values()) {
39416
+ const numbers = options.sounds?.[sound3.id] ?? options.defaults?.(sound3);
39417
+ const close = refsOf(sound3.layers.close, baseUrl);
39418
+ if (!numbers || close.length === 0) continue;
39419
+ const tiers = (tiersOf.get(sound3.id) ?? []).map((tier) => {
39420
+ const name = splitTier(tier.id).tier;
39421
+ const tierFar = refsOf(tier.layers.far, baseUrl);
39422
+ return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
39423
+ }).sort((a, b) => a.from - b.from);
39424
+ const far = refsOf(sound3.layers.far, baseUrl);
39425
+ const indoor = refsOf(sound3.layers.tail_in, baseUrl);
39426
+ const outdoor = refsOf(sound3.layers.tail_out, baseUrl);
39427
+ const files = [sound3, ...tiersOf.get(sound3.id) ?? []].flatMap((entry2) => Object.values(entry2.layers).flatMap((entries2) => entries2 ?? []));
39428
+ samples.push({
39429
+ id: sound3.id,
39430
+ bus: numbers.bus,
39431
+ close,
39432
+ ...far.length > 0 ? { far } : {},
39433
+ ...tiers.length > 0 ? { tiers } : {},
39434
+ ...numbers.crossover ? { crossover: numbers.crossover } : {},
39435
+ ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
39436
+ ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
39437
+ ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
39438
+ ...numbers.falloff ? { falloff: numbers.falloff } : {},
39439
+ ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
39440
+ ...numbers.group ? { group: numbers.group } : {},
39441
+ ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
39442
+ ...numbers.fallback ? { fallback: numbers.fallback } : {},
39443
+ sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
39444
+ });
39445
+ }
39446
+ return { id: options.id, samples };
39447
+ }
39333
39448
  var PT = {
39334
39449
  group: "Som",
39335
39450
  name: "Painel de som (arquivos e C1\u2013C10)",
@@ -39337,6 +39452,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39337
39452
  category: "1 \xB7 Categoria",
39338
39453
  sound: "1 \xB7 Som",
39339
39454
  play: "1 \xB7 \u25B6 Tocar",
39455
+ play_user: "1 \xB7 \u25B6 Tocar o seu",
39340
39456
  material: "2 \xB7 Material",
39341
39457
  blow: "2 \xB7 Golpe",
39342
39458
  strike: "2 \xB7 \u25B6 Tocar golpe",
@@ -39358,6 +39474,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39358
39474
  approve: "5 \xB7 Aprovo (C10)"
39359
39475
  },
39360
39476
  hints: {
39477
+ play_user: "Toca a sua grava\xE7\xE3o deste som (dos seus pacotes, fora do git), mesmo quando o SDK tem uma melhor e toca na frente.",
39361
39478
  sound: "A = arquivo, S = sintetizado, F = faltando. O que tem arquivo toca o arquivo; o resto toca o som atual.",
39362
39479
  strike: "Toca impact_<material>_<golpe>: o arquivo se existir, sen\xE3o o som atual daquele material.",
39363
39480
  wall: "P\xF5e a parede de casa entre voc\xEA e a fonte: o som fica abafado (C4).",
@@ -39402,9 +39519,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39402
39519
  strengths: { light: "leve", medium: "m\xE9dio", heavy: "forte" },
39403
39520
  states: { file: "A", synth: "S", missing: "F" },
39404
39521
  criteria: { C1: "C1 Sincronia", C2: "C2 Certo p/ a\xE7\xE3o", C3: "C3 Dist\xE2ncia", C4: "C4 Posi\xE7\xE3o", C5: "C5 Varia\xE7\xE3o", C6: "C6 Volume", C7: "C7 Intensidade", C8: "C8 Cauda", C9: "C9 Rajada", C10: "C10 Escuta" },
39405
- metrics: { chosen: "1 \xB7 Escolhido", matrix: "2 \xB7 Matriz", last: "\xDAltimo tocado", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Prefer\xEAncias", state: "5 \xB7 Medi\xE7\xE3o", count: "1 \xB7 Cat\xE1logo" },
39522
+ metrics: { source: "1 \xB7 Fonte do que tocou", chosen: "1 \xB7 Escolhido", matrix: "2 \xB7 Matriz", last: "\xDAltimo tocado", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Prefer\xEAncias", state: "5 \xB7 Medi\xE7\xE3o", count: "1 \xB7 Cat\xE1logo" },
39406
39523
  run: { idle: "parada", measuring: "medindo\u2026", done: "pronta", failed: "falhou", recording: "gravando\u2026", recorded: "grava\xE7\xE3o baixada" },
39407
39524
  words: { none: "\u2014", hidden: "? (revele)", prefers: "prefere", approved: "aprovado pelo dono" },
39525
+ sources: { sdk: "SDK", user: "seu som", synth: "sintetizado" },
39408
39526
  probe: "Fonte do som",
39409
39527
  wall: "Parede (oclus\xE3o)",
39410
39528
  scenarios: { pipeline: "Arquivo \u2192 decodifica \u2192 toca (round-robin, cauda)", criteria: "Crit\xE9rios C1\u2013C9 no som de calibra\xE7\xE3o", loop: "Loop de arquivo: emenda sem buraco (crossfade)", panel: "Painel: categorias, matriz, A/B e parede" }
@@ -39417,6 +39535,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39417
39535
  category: "1 \xB7 Category",
39418
39536
  sound: "1 \xB7 Sound",
39419
39537
  play: "1 \xB7 \u25B6 Play",
39538
+ play_user: "1 \xB7 \u25B6 Play yours",
39420
39539
  material: "2 \xB7 Material",
39421
39540
  blow: "2 \xB7 Blow",
39422
39541
  strike: "2 \xB7 \u25B6 Play blow",
@@ -39438,6 +39557,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39438
39557
  approve: "5 \xB7 Approve (C10)"
39439
39558
  },
39440
39559
  hints: {
39560
+ play_user: "Plays your own take of this sound (from your packs, kept out of git), even where the SDK has a better one that plays first.",
39441
39561
  sound: "A = file, S = synthesized, F = missing. A file plays the file; the rest plays the current sound.",
39442
39562
  strike: "Plays impact_<material>_<blow>: the file if there is one, else the current sound of that material.",
39443
39563
  wall: "Puts the house wall between you and the source: the sound is muffled (C4).",
@@ -39472,69 +39592,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39472
39592
  environments: { indoor: "indoor", outdoor: "outdoor" },
39473
39593
  strengths: { light: "light", medium: "medium", heavy: "heavy" },
39474
39594
  criteria: { C1: "C1 Sync", C2: "C2 Right sound", C3: "C3 Distance", C4: "C4 Position", C5: "C5 Variation", C6: "C6 Level", C7: "C7 Strength", C8: "C8 Tail", C9: "C9 Burst", C10: "C10 Listening" },
39475
- metrics: { chosen: "1 \xB7 Chosen", matrix: "2 \xB7 Matrix", last: "Last played", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Preferences", state: "5 \xB7 Measurement", count: "1 \xB7 Catalogue" },
39595
+ metrics: { source: "1 \xB7 Source of what played", chosen: "1 \xB7 Chosen", matrix: "2 \xB7 Matrix", last: "Last played", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Preferences", state: "5 \xB7 Measurement", count: "1 \xB7 Catalogue" },
39476
39596
  run: { idle: "idle", measuring: "measuring\u2026", done: "done", failed: "failed", recording: "recording\u2026", recorded: "recording downloaded" },
39477
39597
  words: { none: "\u2014", hidden: "? (reveal)", prefers: "prefers", approved: "approved by the owner" },
39598
+ sources: { sdk: "SDK", user: "your sound", synth: "synthesized" },
39478
39599
  probe: "Sound source",
39479
39600
  wall: "Wall (occlusion)",
39480
39601
  scenarios: { pipeline: "File \u2192 decode \u2192 play (round-robin, tail)", criteria: "Criteria C1\u2013C9 on the calibration sound", loop: "File loop: seamless joins (crossfade)", panel: "Panel: categories, matrix, A/B and wall" }
39481
39602
  };
39482
39603
 
39483
39604
  // ../game-audio/dist/index.js
39484
- var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
39485
- function splitTier(id) {
39486
- const match = /^(.*)_(light|medium|heavy)$/.exec(id);
39487
- return match ? { base: match[1], tier: match[2] } : { base: id };
39488
- }
39489
- var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry2) => ({ url: `${baseUrl}${entry2.file}` }));
39490
- function sampleBankFromManifest(manifest, options) {
39491
- const baseUrl = options.baseUrl ?? "";
39492
- const samples = [];
39493
- const tiersOf = /* @__PURE__ */ new Map();
39494
- for (const sound3 of manifest.sounds) {
39495
- const { base, tier } = splitTier(sound3.id);
39496
- if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound3]);
39497
- }
39498
- const bases = /* @__PURE__ */ new Map();
39499
- for (const sound3 of manifest.sounds) {
39500
- if (!splitTier(sound3.id).tier) bases.set(sound3.id, sound3);
39501
- }
39502
- for (const [base, tiers] of tiersOf) {
39503
- if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
39504
- }
39505
- for (const sound3 of bases.values()) {
39506
- const numbers = options.sounds?.[sound3.id] ?? options.defaults?.(sound3);
39507
- const close = refsOf(sound3.layers.close, baseUrl);
39508
- if (!numbers || close.length === 0) continue;
39509
- const tiers = (tiersOf.get(sound3.id) ?? []).map((tier) => {
39510
- const name = splitTier(tier.id).tier;
39511
- const tierFar = refsOf(tier.layers.far, baseUrl);
39512
- return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
39513
- }).sort((a, b) => a.from - b.from);
39514
- const far = refsOf(sound3.layers.far, baseUrl);
39515
- const indoor = refsOf(sound3.layers.tail_in, baseUrl);
39516
- const outdoor = refsOf(sound3.layers.tail_out, baseUrl);
39517
- const files = [sound3, ...tiersOf.get(sound3.id) ?? []].flatMap((entry2) => Object.values(entry2.layers).flatMap((entries2) => entries2 ?? []));
39518
- samples.push({
39519
- id: sound3.id,
39520
- bus: numbers.bus,
39521
- close,
39522
- ...far.length > 0 ? { far } : {},
39523
- ...tiers.length > 0 ? { tiers } : {},
39524
- ...numbers.crossover ? { crossover: numbers.crossover } : {},
39525
- ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
39526
- ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
39527
- ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
39528
- ...numbers.falloff ? { falloff: numbers.falloff } : {},
39529
- ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
39530
- ...numbers.group ? { group: numbers.group } : {},
39531
- ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
39532
- ...numbers.fallback ? { fallback: numbers.fallback } : {},
39533
- sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
39534
- });
39535
- }
39536
- return { id: options.id, samples };
39537
- }
39538
39605
  var ATTACK = 2e-3;
39539
39606
  function lengthOf(d, attack) {
39540
39607
  if (typeof d === "number") return attack + d;
@@ -65281,7 +65348,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
65281
65348
  // a real mass (the vessel and what it holds) replaces the hollow-sheet density
65282
65349
  ...def.mass !== void 0 && shape.wall !== void 0 ? { mass: def.mass } : {},
65283
65350
  ...def.leak ? { contains: { fluid: def.leak.fluid, liters: def.leak.liters, pressurized: def.leak.pressurized } } : {},
65284
- explodes: { energy: def.energy * scale, radius: def.injuryRadius * scale, lethalRadius: def.lethalRadius * scale, effect: def.id, ...def.chain ? { chain: { ...def.chain } } : {} }
65351
+ explodes: { energy: def.energy * scale, radius: def.injuryRadius * scale, lethalRadius: def.lethalRadius * scale, effect: def.id, ...def.tnt !== void 0 ? { tnt: def.tnt * scale } : {}, ...def.chain ? { chain: { ...def.chain } } : {} }
65285
65352
  });
65286
65353
  var meshOf = (THREE, shape) => {
65287
65354
  const geometry = shape.shape.kind === "cylinder" ? new THREE.CylinderGeometry(shape.shape.radius, shape.shape.radius, shape.shape.height, 16) : shape.shape.kind === "box" ? new THREE.BoxGeometry(...shape.shape.size) : new THREE.SphereGeometry(0.2);
@@ -65952,7 +66019,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
65952
66019
  push_found: "{n} bodies were laid around the blast to be measured ({kinds})",
65953
66020
  push_outward: "Every body inside the reach moved away from the blast ({moved} of {n}, {least} m at the least)",
65954
66021
  push_falloff: "{what}: the nearer one moved more than the farther one ({near} m at {nearDistance} m, {far} m at {farDistance} m)",
65955
- push_person: "{who} at {distance} m was pushed {moved} m away",
66022
+ push_person_wave: "{who} at {distance} m moved {moved} m away, no farther than the blast wave pushes a person ({most} m at most)",
65956
66023
  push_sheltered: "{what} at {distance} m stood behind cover ({cover}% of the blast got through) and moved only {moved} m",
65957
66024
  push_heavy: "{what} (too heavy to grab, not fixed) was moved {moved} m by the blast"
65958
66025
  }
@@ -66038,7 +66105,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66038
66105
  push_found: "{n} corpos foram postos em volta da explos\xE3o para serem medidos ({kinds})",
66039
66106
  push_outward: "Todo corpo dentro do alcance se afastou da explos\xE3o ({moved} de {n}, no m\xEDnimo {least} m)",
66040
66107
  push_falloff: "{what}: o mais perto andou mais que o mais longe ({near} m a {nearDistance} m, {far} m a {farDistance} m)",
66041
- push_person: "{who} a {distance} m foi empurrado {moved} m para longe",
66108
+ push_person_wave: "{who} a {distance} m se afastou {moved} m, n\xE3o mais do que a onda da explos\xE3o empurra uma pessoa (no m\xE1ximo {most} m)",
66042
66109
  push_sheltered: "{what} a {distance} m estava atr\xE1s de cobertura ({cover}% da explos\xE3o passou) e andou s\xF3 {moved} m",
66043
66110
  push_heavy: "{what} (pesado demais para pegar, mas solto) foi movido {moved} m pela explos\xE3o"
66044
66111
  }
@@ -66538,7 +66605,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66538
66605
  }
66539
66606
  offs.push(
66540
66607
  lent.on((event) => {
66541
- if (event.type === "explosion") lastBlast = { point: event.point, energy: event.energy, radius: event.radius, cause: event.cause, ...event.explosive === void 0 ? {} : { explosive: event.explosive } };
66608
+ if (event.type === "explosion") lastBlast = { point: event.point, energy: event.energy, radius: event.radius, cause: event.cause, ...event.explosive === void 0 ? {} : { explosive: event.explosive }, ...event.tnt === void 0 ? {} : { tnt: event.tnt } };
66542
66609
  })
66543
66610
  );
66544
66611
  offs.push(lent.onFrame(frame2));
@@ -66590,6 +66657,9 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66590
66657
  var CHEST = 1.1;
66591
66658
  var MIDDLE = 0.3;
66592
66659
  var HEAVY_ITEMS = ["camp_table"];
66660
+ var PERSON_MASS = 70;
66661
+ var GROUND_FRICTION2 = 7;
66662
+ var PERSON_SLACK = 0.4;
66593
66663
  var flat = (a, b) => Math.hypot(a[0] - b[0], a[2] - b[2]);
66594
66664
  var bearing = (centre, distance3, degrees) => [centre[0] + Math.sin(degrees * Math.PI / 180) * distance3, 0, centre[2] + Math.cos(degrees * Math.PI / 180) * distance3];
66595
66665
  var PUSH_LAYOUT = {
@@ -66683,7 +66753,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66683
66753
  for (const row of sheltered) {
66684
66754
  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 } });
66685
66755
  }
66686
- const reached = inReach.filter((row) => row.cover >= SHELTERED);
66756
+ const isPerson = (row) => row.kind === "survivor" || row.kind === "zombie";
66757
+ const reached = inReach.filter((row) => row.cover >= SHELTERED && !isPerson(row));
66687
66758
  const movedAway = reached.filter((row) => row.outward >= MOVED);
66688
66759
  const least = reached.length === 0 ? 0 : Math.min(...reached.map((row) => row.outward));
66689
66760
  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) });
@@ -66694,8 +66765,12 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66694
66765
  const far = ofKind[ofKind.length - 1];
66695
66766
  expect(near.outward > far.outward, fillText2(text.push_falloff, { what: things[kind] ?? kind, near: near.outward.toFixed(2), nearDistance: near.distance.toFixed(1), far: far.outward.toFixed(2), farDistance: far.distance.toFixed(1) }), { near: near.outward, far: far.outward });
66696
66767
  }
66697
- for (const row of reached.filter((entry2) => entry2.kind === "zombie" || entry2.kind === "survivor")) {
66698
- expect(row.outward >= MOVED, fillText2(text.push_person, { who: things[row.kind] ?? row.kind, distance: row.distance.toFixed(1), moved: row.outward.toFixed(2) }), { row: { kind: row.kind, distance: row.distance, outward: row.outward } });
66768
+ for (const row of inReach.filter(isPerson)) {
66769
+ const from = origin.get(row.objectId) ?? row.from;
66770
+ const chest = Math.hypot(from[0] - blast.point[0], from[1] + CHEST - blast.point[1], from[2] - blast.point[2]);
66771
+ const speed = blastBodySpeed(blast.tnt ?? blast.energy * DEFAULT_BLAST_IMPULSE.tntPerJoule, chest, PERSON_MASS, row.cover);
66772
+ const most = speed * speed / (2 * GROUND_FRICTION2) + PERSON_SLACK;
66773
+ expect(row.outward <= most, fillText2(text.push_person_wave, { who: things[row.kind] ?? row.kind, distance: row.distance.toFixed(1), moved: Math.max(0, row.outward).toFixed(2), most: most.toFixed(2) }), { row: { kind: row.kind, distance: row.distance, outward: row.outward, speed, most } });
66699
66774
  }
66700
66775
  const table = rows.find((row) => HEAVY_ITEMS.includes(row.kind) && row.distance < blast.radius * 0.85);
66701
66776
  if (table) expect(table.moved >= MOVED, fillText2(text.push_heavy, { what: things[table.itemId] ?? table.itemId, moved: table.moved.toFixed(2) }), { table });