@adatechnology/game-crowd-three 0.4.0 → 0.5.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.
@@ -333,45 +333,45 @@ var GameCrowdThree = (() => {
333
333
  segmentRadius: SEGMENT_RADIUS
334
334
  };
335
335
  var createCorpseLedger = (options) => {
336
- const entries = [];
336
+ const entries2 = [];
337
337
  return {
338
- entries,
338
+ entries: entries2,
339
339
  get count() {
340
- return entries.length;
340
+ return entries2.length;
341
341
  },
342
342
  add(data) {
343
- if (entries.length < options.max) {
344
- entries.push({ age: 0, data });
343
+ if (entries2.length < options.max) {
344
+ entries2.push({ age: 0, data });
345
345
  return void 0;
346
346
  }
347
347
  let oldest = 0;
348
- for (let index = 1; index < entries.length; index++) if (entries[index].age > entries[oldest].age) oldest = index;
349
- const replaced = entries[oldest].data;
350
- entries[oldest] = { age: 0, data };
348
+ for (let index = 1; index < entries2.length; index++) if (entries2[index].age > entries2[oldest].age) oldest = index;
349
+ const replaced = entries2[oldest].data;
350
+ entries2[oldest] = { age: 0, data };
351
351
  return replaced;
352
352
  },
353
353
  update(dt) {
354
354
  const removed = [];
355
- for (let index = 0; index < entries.length; index++) {
356
- const entry = entries[index];
355
+ for (let index = 0; index < entries2.length; index++) {
356
+ const entry = entries2[index];
357
357
  entry.age += dt;
358
358
  if (entry.age <= options.seconds) continue;
359
359
  removed.push(entry.data);
360
- entries[index] = entries[entries.length - 1];
361
- entries.pop();
360
+ entries2[index] = entries2[entries2.length - 1];
361
+ entries2.pop();
362
362
  index--;
363
363
  }
364
364
  return removed;
365
365
  },
366
366
  remove(index) {
367
- const entry = entries[index];
367
+ const entry = entries2[index];
368
368
  if (!entry) return void 0;
369
- entries[index] = entries[entries.length - 1];
370
- entries.pop();
369
+ entries2[index] = entries2[entries2.length - 1];
370
+ entries2.pop();
371
371
  return entry.data;
372
372
  },
373
373
  clear() {
374
- entries.length = 0;
374
+ entries2.length = 0;
375
375
  }
376
376
  };
377
377
  };
@@ -1511,7 +1511,7 @@ var GameCrowdThree = (() => {
1511
1511
  var POSE_CLIPS = pose_clips_default.clips;
1512
1512
  var POSE_CLIP_LOCALES = pose_clips_default.locales;
1513
1513
 
1514
- // ../game-audio/dist/chunk-DZITVFMJ.js
1514
+ // ../game-audio/dist/chunk-7TLFY7VO.js
1515
1515
  var DISTANCE_CURVES = {
1516
1516
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
1517
1517
  game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
@@ -1574,15 +1574,31 @@ var GameCrowdThree = (() => {
1574
1574
  {
1575
1575
  id: "game",
1576
1576
  master: 0.5,
1577
- noise: { seconds: 1.5, create: "lazy" },
1578
- sources: ["jogo:L62077-62081 master 0.5 to the output", "jogo:L62082-62088 noise 1.5 s made by the first sound that needs it"]
1577
+ noise: {
1578
+ seconds: 1.5,
1579
+ create: "lazy"
1580
+ },
1581
+ sources: [
1582
+ "jogo:L62077-62081 master 0.5 to the output",
1583
+ "jogo:L62082-62088 noise 1.5 s made by the first sound that needs it"
1584
+ ]
1579
1585
  },
1580
1586
  {
1581
1587
  id: "art_scene",
1582
1588
  master: 0.85,
1583
- compressor: { threshold: -12, ratio: 5 },
1584
- reverb: { seconds: 2.2, decay: 3.4, wet: 0.4 },
1585
- noise: { seconds: 2, create: "eager" },
1589
+ compressor: {
1590
+ threshold: -12,
1591
+ ratio: 5
1592
+ },
1593
+ reverb: {
1594
+ seconds: 2.2,
1595
+ decay: 3.4,
1596
+ wet: 0.4
1597
+ },
1598
+ noise: {
1599
+ seconds: 2,
1600
+ create: "eager"
1601
+ },
1586
1602
  sources: [
1587
1603
  "cena:L1308 compressor -12 dB, ratio 5",
1588
1604
  "cena:L1309 master 0.85",
@@ -1590,6 +1606,30 @@ var GameCrowdThree = (() => {
1590
1606
  "cena:L1311 wet 0.4",
1591
1607
  "cena:L1312 noise 2 s made with the chain"
1592
1608
  ]
1609
+ },
1610
+ {
1611
+ id: "kit",
1612
+ master: 0.85,
1613
+ compressor: {
1614
+ threshold: -12,
1615
+ ratio: 5
1616
+ },
1617
+ reverb: {
1618
+ seconds: 2.2,
1619
+ decay: 3.4,
1620
+ wet: 0.4
1621
+ },
1622
+ noise: {
1623
+ seconds: 2,
1624
+ create: "eager"
1625
+ },
1626
+ sources: [
1627
+ "sdk: the art scene chain (cena L1308-L1312) with a limiter after the compressor: the page has none, and a blast with its debris and a fire catching reached +7 dBFS"
1628
+ ],
1629
+ limiter: {
1630
+ ceiling: -1,
1631
+ knee: -6
1632
+ }
1593
1633
  }
1594
1634
  ];
1595
1635
  var MIX_PROFILES = Object.fromEntries(
@@ -1640,6 +1680,339 @@ var GameCrowdThree = (() => {
1640
1680
  }
1641
1681
  ]
1642
1682
  };
1683
+ var entries = (category, list2) => list2.map(([id, priority, current]) => ({ id, category, priority, ...current ? { current } : {} }));
1684
+ var SFX_CATALOG = [
1685
+ ...entries("armas", [
1686
+ ["pistol_22lr", 2, "sfx_pistol"],
1687
+ ["pistol_9mm", 1, "sfx_pistol"],
1688
+ ["pistol_45", 1, "sfx_pistol"],
1689
+ ["revolver_38_357", 2, "sfx_pistol"],
1690
+ ["revolver_44_50ae", 3, "sfx_pistol"],
1691
+ ["smg_9mm_auto", 1, "sfx_pistol"],
1692
+ ["shotgun_12", 1, "sfx_shotgun"],
1693
+ ["rifle_5_56", 1, "sfx_rifle"],
1694
+ ["rifle_7_62x39", 1, "sfx_rifle"],
1695
+ ["rifle_auto_burst", 1, "sfx_rifle"],
1696
+ ["rifle_308_3006", 2, "sfx_rifle"],
1697
+ ["sniper_338_300wm", 2, "sfx_rifle"],
1698
+ ["antimateriel_50bmg", 3, "sfx_rifle"],
1699
+ ["suppressed_pistol", 2],
1700
+ ["suppressed_rifle", 2],
1701
+ ["gunshot_far_pistol", 1],
1702
+ ["gunshot_far_rifle", 1],
1703
+ ["gunshot_far_shotgun", 1],
1704
+ ["gunshot_far_heavy", 2],
1705
+ ["gunshot_tail_indoor", 1],
1706
+ ["gunshot_tail_outdoor", 1],
1707
+ ["bullet_crack_by", 2],
1708
+ ["bullet_whiz", 2],
1709
+ ["ricochet_metal", 2, "ping"],
1710
+ ["dry_fire", 1],
1711
+ ["mag_out", 1],
1712
+ ["mag_in", 1],
1713
+ ["slide_pull_release", 1],
1714
+ ["pump_cycle", 1],
1715
+ ["casing_drop_concreto_pistol", 1],
1716
+ ["casing_drop_concreto_rifle", 1],
1717
+ ["casing_drop_concreto_shell", 1],
1718
+ ["casing_drop_madeira_pistol", 1],
1719
+ ["casing_drop_madeira_rifle", 1],
1720
+ ["casing_drop_madeira_shell", 1],
1721
+ ["casing_drop_metal_pistol", 1],
1722
+ ["casing_drop_metal_rifle", 1],
1723
+ ["casing_drop_metal_shell", 1],
1724
+ ["casing_drop_terra_pistol", 1],
1725
+ ["casing_drop_terra_rifle", 1],
1726
+ ["casing_drop_terra_shell", 1],
1727
+ ["rocket_fire", 2]
1728
+ ]),
1729
+ ...entries("explosoes-fogo", [
1730
+ ["explosion_grenade", 1, "boom"],
1731
+ ["explosion_big", 1, "boom_big"],
1732
+ ["explosion_car", 2, "boom_big"],
1733
+ ["explosion_far", 1],
1734
+ ["debris_rain_stone", 1],
1735
+ ["molotov_break_ignite", 1, "glass_shatter"],
1736
+ ["fire_ignite", 1, "hiss"],
1737
+ ["fire_loop_small", 1],
1738
+ ["fire_loop_large", 1],
1739
+ ["fire_extinguish", 2, "hiss"],
1740
+ ["gas_leak_hiss", 2],
1741
+ ["structure_collapse", 2, "crumble"]
1742
+ ]),
1743
+ ...entries("personagem", [
1744
+ ["footstep_concrete_walk", 1, "sfx_step"],
1745
+ ["footstep_wood_walk", 1, "sfx_step"],
1746
+ ["footstep_dirt_walk", 1, "sfx_step"],
1747
+ ["footstep_grass_walk", 1, "sfx_step"],
1748
+ ["footstep_gravel_walk", 1, "sfx_step"],
1749
+ ["land_concrete", 1, "sfx_step"],
1750
+ ["punch_swing", 1],
1751
+ ["punch_hit_body", 1, "sfx_flesh"],
1752
+ ["kick_hit", 1, "sfx_flesh"],
1753
+ ["knife_stab", 1],
1754
+ ["blunt_hit", 1],
1755
+ ["bite", 1, "sfx_flesh"],
1756
+ ["body_fall", 1],
1757
+ ["player_hurt", 2]
1758
+ ]),
1759
+ ...entries("veiculos", [
1760
+ ["engine_loop_car", 1],
1761
+ ["engine_start", 1],
1762
+ ["crash_light", 1, "crash"],
1763
+ ["crash_heavy", 1, "crash"],
1764
+ ["car_door_open", 1, "latch"],
1765
+ ["car_door_close", 1, "shut_metal"],
1766
+ ["horn_car", 2, "horn"],
1767
+ ["tire_skid_asphalt", 2]
1768
+ ]),
1769
+ ...entries("itens-portas", [
1770
+ ["item_pickup_metal", 1],
1771
+ ["can_open", 1],
1772
+ ["can_crush", 1],
1773
+ ["door_wood_open", 1, "latch"],
1774
+ ["door_wood_close", 1, "shut_wood"],
1775
+ ["door_creak", 1, "creak_wood"],
1776
+ ["door_locked_rattle", 1, "rattle"],
1777
+ ["drawer_open", 2, "slide"],
1778
+ ["fridge_close", 2, "shut_metal"]
1779
+ ]),
1780
+ ...entries("ambiente", [
1781
+ ["rain_loop", 2],
1782
+ ["wind_loop", 2],
1783
+ ["thunder_near", 2],
1784
+ ["thunder_far", 2],
1785
+ ["water_splash", 2]
1786
+ ])
1787
+ ];
1788
+ var SFX_MATERIALS = [
1789
+ ["steel", "metal"],
1790
+ ["aluminium", "metal"],
1791
+ ["wood", "wood"],
1792
+ ["plywood", "wood"],
1793
+ ["mdf", "wood"],
1794
+ ["glass", "glass"],
1795
+ ["tempered_glass", "glass"],
1796
+ ["ceramic", "glass"],
1797
+ ["concrete", "masonry"],
1798
+ ["brick", "masonry"],
1799
+ ["plaster", "masonry"],
1800
+ ["plastic", "soft"],
1801
+ ["fabric", "soft"],
1802
+ ["paper", "soft"],
1803
+ ["foliage", "soft"],
1804
+ ["soil", "soft"],
1805
+ ["flesh", "soft"]
1806
+ ];
1807
+ var SFX_BLOWS = ["bullet", "blunt", "blade", "break", "drag"];
1808
+ var CURRENT_BY_GROUP = {
1809
+ metal: { bullet: "clang", blunt: "clang", blade: "clang", break: "clang", drag: "drag_metal" },
1810
+ wood: { bullet: "wood_hit", blunt: "wood_hit", blade: "wood_hit", break: "crack", drag: "drag_wood" },
1811
+ glass: { bullet: "ping", blunt: "ping", break: "glass_shatter", drag: "drag_glass" },
1812
+ masonry: { bullet: "chip", blunt: "chip", blade: "chip", break: "crumble", drag: "drag_masonry" },
1813
+ soft: { bullet: "thud", blunt: "thud", blade: "thud", break: "thud", drag: "drag_soft" }
1814
+ };
1815
+ var impactSoundId = (material, blow) => `impact_${material}_${blow}`;
1816
+ var SFX_IMPACTS = SFX_MATERIALS.flatMap(
1817
+ ([material, group]) => SFX_BLOWS.map((blow) => {
1818
+ const current = CURRENT_BY_GROUP[group]?.[blow];
1819
+ return { id: impactSoundId(material, blow), category: "impactos", priority: ["steel", "wood", "glass", "concrete", "brick", "soil", "flesh"].includes(material) && blow === "bullet" ? 1 : 2, ...current ? { current } : {} };
1820
+ })
1821
+ );
1822
+ var CALIBRATION_ID = "calibration_shot";
1823
+ var PREFIX = "calibration/";
1824
+ var url = (name) => `${PREFIX}${name}`;
1825
+ var CALIBRATION_SOUND = {
1826
+ id: CALIBRATION_ID,
1827
+ bus: "weapons",
1828
+ close: ["close_1.wav", "close_2.wav", "close_3.wav", "close_4.wav"].map((name) => ({ url: url(name) })),
1829
+ far: ["far_1.wav", "far_2.wav"].map((name) => ({ url: url(name) })),
1830
+ tiers: [
1831
+ { name: "light", from: 0, close: ["light_1.wav", "light_2.wav"].map((name) => ({ url: url(name) })) },
1832
+ { name: "medium", from: 0.34, close: ["close_1.wav", "close_2.wav", "close_3.wav", "close_4.wav"].map((name) => ({ url: url(name) })) },
1833
+ { name: "heavy", from: 0.67, close: ["heavy_1.wav", "heavy_2.wav"].map((name) => ({ url: url(name) })) }
1834
+ ],
1835
+ tail: { indoor: [{ url: url("tail_in.wav") }], outdoor: [{ url: url("tail_out.wav") }] },
1836
+ pitch: 0.04,
1837
+ choke: { voices: 2 },
1838
+ fallback: "sfx_pistol",
1839
+ sources: ["sdk: calibration takes synthesized by the harness (measure/calibration.ts), no file, no licence"]
1840
+ };
1841
+ var CALIBRATION_LOOP_ID = "calibration_loop";
1842
+ var CALIBRATION_LOOP_SOUND = {
1843
+ id: CALIBRATION_LOOP_ID,
1844
+ bus: "ambience",
1845
+ close: ["loop_1.wav", "loop_2.wav", "loop_3.wav"].map((name) => ({ url: url(name) })),
1846
+ loop: { crossfade: 0.15 },
1847
+ sources: ["sdk: calibration takes synthesized by the harness (measure/calibration.ts), no file, no licence"]
1848
+ };
1849
+ var CRITERIA_TARGETS = {
1850
+ /** C1: event to the first sample, and onset to the peak (one 60 fps frame). */
1851
+ syncMs: 20,
1852
+ peakAfterOnsetMs: 1e3 / 60,
1853
+ /** C3: distances measured, metres. */
1854
+ distances: [1, 10, 50, 200],
1855
+ /** C5: plays, distinct takes and the pitch range (fraction). */
1856
+ plays: 10,
1857
+ minTakes: 4,
1858
+ pitch: [0.03, 0.05],
1859
+ /** C6: the highest peak, dBFS. */
1860
+ peakDb: -1,
1861
+ /** C8: the end of each file against its peak, dB. */
1862
+ endDropDb: -40,
1863
+ /** C9: a burst of rapid fire. */
1864
+ burst: 20,
1865
+ burstSpacing: 0.06
1866
+ };
1867
+ var PT = {
1868
+ group: "Som",
1869
+ name: "Painel de som (arquivos e C1\u2013C10)",
1870
+ controls: {
1871
+ category: "1 \xB7 Categoria",
1872
+ sound: "1 \xB7 Som",
1873
+ play: "1 \xB7 \u25B6 Tocar",
1874
+ material: "2 \xB7 Material",
1875
+ blow: "2 \xB7 Golpe",
1876
+ strike: "2 \xB7 \u25B6 Tocar golpe",
1877
+ distance: "3 \xB7 Dist\xE2ncia",
1878
+ bearing: "3 \xB7 Dire\xE7\xE3o",
1879
+ environment: "3 \xB7 Lugar",
1880
+ strength: "3 \xB7 For\xE7a",
1881
+ wall: "3 \xB7 Atr\xE1s da parede",
1882
+ burst: "3 \xB7 Rajada 20\xD7",
1883
+ play_a: "4 \xB7 \u25B6 A (atual)",
1884
+ play_b: "4 \xB7 \u25B6 B (novo)",
1885
+ ab_cycle: "4 \xB7 Alternar A/B",
1886
+ blind: "4 \xB7 \xC0s cegas (X)",
1887
+ reveal: "4 \xB7 Revelar X",
1888
+ prefer_a: "4 \xB7 Prefiro A",
1889
+ prefer_b: "4 \xB7 Prefiro B",
1890
+ measure: "5 \xB7 Medir C1\u2013C10",
1891
+ record: "5 \xB7 Gravar 3 s",
1892
+ approve: "5 \xB7 Aprovo (C10)"
1893
+ },
1894
+ hints: {
1895
+ sound: "A = arquivo, S = sintetizado, F = faltando. O que tem arquivo toca o arquivo; o resto toca o som atual.",
1896
+ strike: "Toca impact_<material>_<golpe>: o arquivo se existir, sen\xE3o o som atual daquele material.",
1897
+ wall: "P\xF5e a parede de casa entre voc\xEA e a fonte: o som fica abafado (C4).",
1898
+ burst: "Vinte vezes a cada 60 ms, como uma rajada (C9).",
1899
+ ab_cycle: "A, B, A, B, um por segundo.",
1900
+ blind: "Toca A ou B sem dizer qual; depois revele.",
1901
+ measure: "Mede o som escolhido no motor real (contexto offline): sincronia, som certo, dist\xE2ncia, lado, varia\xE7\xE3o, volume, for\xE7a, cauda e rajada.",
1902
+ record: "Grava 3 s da sa\xEDda com o som tocando e baixa o arquivo (C10).",
1903
+ approve: "Marca o C10 do som escolhido como aprovado pelo seu ouvido."
1904
+ },
1905
+ categories: {
1906
+ armas: "Armas",
1907
+ impactos: "Impactos",
1908
+ "explosoes-fogo": "Explos\xF5es e fogo",
1909
+ personagem: "Personagem",
1910
+ veiculos: "Ve\xEDculos",
1911
+ "itens-portas": "Itens e portas",
1912
+ ambiente: "Ambiente",
1913
+ calibracao: "Calibra\xE7\xE3o (SDK)"
1914
+ },
1915
+ blows: { bullet: "tiro", blunt: "soco/chute", blade: "faca", break: "quebra", drag: "arrasto/queda" },
1916
+ materials: {
1917
+ steel: "a\xE7o",
1918
+ aluminium: "alum\xEDnio",
1919
+ wood: "madeira",
1920
+ plywood: "compensado",
1921
+ mdf: "MDF",
1922
+ glass: "vidro",
1923
+ tempered_glass: "vidro temperado",
1924
+ ceramic: "cer\xE2mica",
1925
+ concrete: "concreto",
1926
+ brick: "tijolo",
1927
+ plaster: "gesso",
1928
+ plastic: "pl\xE1stico",
1929
+ fabric: "tecido",
1930
+ paper: "papel\xE3o",
1931
+ foliage: "folhagem",
1932
+ soil: "terra",
1933
+ flesh: "carne"
1934
+ },
1935
+ environments: { indoor: "interior", outdoor: "exterior" },
1936
+ strengths: { light: "leve", medium: "m\xE9dio", heavy: "forte" },
1937
+ states: { file: "A", synth: "S", missing: "F" },
1938
+ 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" },
1939
+ 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" },
1940
+ run: { idle: "parada", measuring: "medindo\u2026", done: "pronta", failed: "falhou", recording: "gravando\u2026", recorded: "grava\xE7\xE3o baixada" },
1941
+ words: { none: "\u2014", hidden: "? (revele)", prefers: "prefere", approved: "aprovado pelo dono" },
1942
+ probe: "Fonte do som",
1943
+ wall: "Parede (oclus\xE3o)",
1944
+ 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" }
1945
+ };
1946
+ var EN2 = {
1947
+ ...PT,
1948
+ group: "Sound",
1949
+ name: "Sound panel (files and C1\u2013C10)",
1950
+ controls: {
1951
+ category: "1 \xB7 Category",
1952
+ sound: "1 \xB7 Sound",
1953
+ play: "1 \xB7 \u25B6 Play",
1954
+ material: "2 \xB7 Material",
1955
+ blow: "2 \xB7 Blow",
1956
+ strike: "2 \xB7 \u25B6 Play blow",
1957
+ distance: "3 \xB7 Distance",
1958
+ bearing: "3 \xB7 Bearing",
1959
+ environment: "3 \xB7 Place",
1960
+ strength: "3 \xB7 Strength",
1961
+ wall: "3 \xB7 Behind the wall",
1962
+ burst: "3 \xB7 Burst 20\xD7",
1963
+ play_a: "4 \xB7 \u25B6 A (current)",
1964
+ play_b: "4 \xB7 \u25B6 B (new)",
1965
+ ab_cycle: "4 \xB7 Alternate A/B",
1966
+ blind: "4 \xB7 Blind (X)",
1967
+ reveal: "4 \xB7 Reveal X",
1968
+ prefer_a: "4 \xB7 Prefer A",
1969
+ prefer_b: "4 \xB7 Prefer B",
1970
+ measure: "5 \xB7 Measure C1\u2013C10",
1971
+ record: "5 \xB7 Record 3 s",
1972
+ approve: "5 \xB7 Approve (C10)"
1973
+ },
1974
+ hints: {
1975
+ sound: "A = file, S = synthesized, F = missing. A file plays the file; the rest plays the current sound.",
1976
+ strike: "Plays impact_<material>_<blow>: the file if there is one, else the current sound of that material.",
1977
+ wall: "Puts the house wall between you and the source: the sound is muffled (C4).",
1978
+ burst: "Twenty times every 60 ms, like a burst (C9).",
1979
+ ab_cycle: "A, B, A, B, one a second.",
1980
+ blind: "Plays A or B without saying which; reveal it after.",
1981
+ measure: "Measures the chosen sound through the real engine (offline context): sync, right sound, distance, side, variation, level, strength, tail and burst.",
1982
+ record: "Records 3 s of the output with the sound playing and downloads it (C10).",
1983
+ approve: "Marks C10 of the chosen sound as approved by your ear."
1984
+ },
1985
+ categories: { armas: "Weapons", impactos: "Impacts", "explosoes-fogo": "Explosions and fire", personagem: "Character", veiculos: "Vehicles", "itens-portas": "Items and doors", ambiente: "Ambience", calibracao: "Calibration (SDK)" },
1986
+ blows: { bullet: "bullet", blunt: "punch/kick", blade: "knife", break: "break", drag: "drag/fall" },
1987
+ materials: {
1988
+ steel: "steel",
1989
+ aluminium: "aluminium",
1990
+ wood: "wood",
1991
+ plywood: "plywood",
1992
+ mdf: "MDF",
1993
+ glass: "glass",
1994
+ tempered_glass: "tempered glass",
1995
+ ceramic: "ceramic",
1996
+ concrete: "concrete",
1997
+ brick: "brick",
1998
+ plaster: "plaster",
1999
+ plastic: "plastic",
2000
+ fabric: "fabric",
2001
+ paper: "cardboard",
2002
+ foliage: "foliage",
2003
+ soil: "soil",
2004
+ flesh: "flesh"
2005
+ },
2006
+ environments: { indoor: "indoor", outdoor: "outdoor" },
2007
+ strengths: { light: "light", medium: "medium", heavy: "heavy" },
2008
+ 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" },
2009
+ 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" },
2010
+ run: { idle: "idle", measuring: "measuring\u2026", done: "done", failed: "failed", recording: "recording\u2026", recorded: "recording downloaded" },
2011
+ words: { none: "\u2014", hidden: "? (reveal)", prefers: "prefers", approved: "approved by the owner" },
2012
+ probe: "Sound source",
2013
+ wall: "Wall (occlusion)",
2014
+ 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" }
2015
+ };
1643
2016
 
1644
2017
  // ../game-audio/dist/index.js
1645
2018
  var ATTACK = 2e-3;
@@ -1704,6 +2077,7 @@ var GameCrowdThree = (() => {
1704
2077
  ]
1705
2078
  };
1706
2079
  }
2080
+ var sceneMany = (count, make2) => Array.from({ length: count }, make2);
1707
2081
  function sceneRecipe(id, layers, line, options = {}) {
1708
2082
  return {
1709
2083
  id,
@@ -1716,6 +2090,569 @@ var GameCrowdThree = (() => {
1716
2090
  sources: [`cena:${line}`]
1717
2091
  };
1718
2092
  }
2093
+ var FOLEY_FALLOFF = {
2094
+ model: "inverse_square",
2095
+ k: 0.02,
2096
+ cutoffK: 0.04,
2097
+ minGain: 4e-3
2098
+ };
2099
+ var vary = (f, pct = 0.04) => [Math.round(f * (1 - pct)), Math.round(f * (1 + pct))];
2100
+ var foley = (id, layers, note) => ({
2101
+ id,
2102
+ bus: "world",
2103
+ pan: true,
2104
+ layers,
2105
+ falloff: FOLEY_FALLOFF,
2106
+ sources: [`sdk: ${note}`]
2107
+ });
2108
+ var click = (f, vol, delay = 0) => [
2109
+ sceneNoise({
2110
+ type: "bandpass",
2111
+ f: vary(f, 0.08),
2112
+ q: 4,
2113
+ d: [0.018, 0.03],
2114
+ vol: [vol * 0.85, vol * 1.1],
2115
+ delay
2116
+ }),
2117
+ sceneTone({
2118
+ f: vary(f * 0.8, 0.06),
2119
+ f2: Math.round(f * 0.62),
2120
+ d: [0.015, 0.025],
2121
+ vol: vol * 0.18,
2122
+ delay
2123
+ })
2124
+ ];
2125
+ var meet = (body, panel, vol, latch) => [
2126
+ sceneTone({
2127
+ f: vary(body),
2128
+ f2: Math.round(body * 0.5),
2129
+ d: [0.12, 0.16],
2130
+ vol: [vol * 0.9, vol * 1.1]
2131
+ }),
2132
+ sceneNoise({
2133
+ type: "bandpass",
2134
+ f: vary(panel, 0.06),
2135
+ q: 1.2,
2136
+ d: [0.08, 0.12],
2137
+ vol: [vol * 0.9, vol * 1.1],
2138
+ wet: 0.25
2139
+ }),
2140
+ ...click(latch, vol * 0.45, [0.012, 0.028])
2141
+ ];
2142
+ var LEAF_FOLEY = [
2143
+ // a wooden house door or wardrobe door: latch, a short creak, the leaf on the frame (the hard slam adds the frame rattling)
2144
+ foley("door_wood_open", click(2400, 0.4), "the latch of a wooden door giving"),
2145
+ foley(
2146
+ "door_creak",
2147
+ [
2148
+ sceneTone({ f: [190, 240], f2: 310, d: [0.4, 0.55], vol: [0.04, 0.06] }),
2149
+ sceneNoise({
2150
+ type: "bandpass",
2151
+ f: [480, 560],
2152
+ q: 6,
2153
+ a: 0.05,
2154
+ d: [0.35, 0.5],
2155
+ vol: [0.1, 0.14]
2156
+ })
2157
+ ],
2158
+ "a wooden hinge turning"
2159
+ ),
2160
+ foley("door_wood_close", meet(120, 600, 0.55, 2400), "a wooden leaf meeting its frame"),
2161
+ foley(
2162
+ "door_wood_slam",
2163
+ [
2164
+ ...meet(110, 560, 0.85, 2300),
2165
+ ...sceneMany(
2166
+ 3,
2167
+ () => sceneNoise({
2168
+ type: "bandpass",
2169
+ f: [900, 1500],
2170
+ q: 3,
2171
+ d: 0.03,
2172
+ vol: [0.08, 0.14],
2173
+ delay: [0.05, 0.18]
2174
+ })
2175
+ )
2176
+ ],
2177
+ "a wooden door slammed: the frame and the hinges rattle after the hit"
2178
+ ),
2179
+ // a metal door or gate: a hollow panel that rings a little
2180
+ foley("door_metal_open_close", [...meet(160, 900, 0.55, 2e3), sceneTone({ f: vary(1250), f2: 1150, d: [0.1, 0.16], vol: 0.06, wet: 0.3 })], "a metal door or gate meeting its frame"),
2181
+ foley(
2182
+ "door_creak_metal",
2183
+ [
2184
+ sceneTone({ f: [620, 760], f2: 900, d: [0.3, 0.4], vol: [0.03, 0.045] }),
2185
+ sceneNoise({
2186
+ type: "bandpass",
2187
+ f: [1300, 1500],
2188
+ q: 8,
2189
+ a: 0.04,
2190
+ d: [0.25, 0.35],
2191
+ vol: [0.07, 0.09]
2192
+ })
2193
+ ],
2194
+ "a metal hinge turning"
2195
+ ),
2196
+ // the handle of a locked door shaken: the latch knocking in its keeper, five to seven times in half a second
2197
+ foley(
2198
+ "door_locked_rattle",
2199
+ [
2200
+ ...sceneMany(
2201
+ 6,
2202
+ () => sceneNoise({
2203
+ type: "bandpass",
2204
+ f: [1600, 2600],
2205
+ q: 3,
2206
+ d: [0.025, 0.04],
2207
+ vol: [0.22, 0.34],
2208
+ delay: [0, 0.45]
2209
+ })
2210
+ ),
2211
+ ...sceneMany(
2212
+ 3,
2213
+ () => sceneTone({
2214
+ f: [170, 210],
2215
+ f2: 120,
2216
+ d: 0.05,
2217
+ vol: [0.12, 0.18],
2218
+ delay: [0.02, 0.4]
2219
+ })
2220
+ )
2221
+ ],
2222
+ "the handle of a locked door shaken: latch knocks and the leaf thumping in its frame"
2223
+ ),
2224
+ // a fridge: the rubber seal lets go with a soft suck, the bottles in the door clink; closing it is a soft thump and the seal pulling shut
2225
+ foley(
2226
+ "fridge_open",
2227
+ [
2228
+ sceneNoise({
2229
+ type: "lowpass",
2230
+ f: [320, 380],
2231
+ a: 0.03,
2232
+ d: [0.14, 0.2],
2233
+ vol: [0.32, 0.4]
2234
+ }),
2235
+ sceneNoise({
2236
+ type: "bandpass",
2237
+ f: [800, 950],
2238
+ f2: 1400,
2239
+ q: 2,
2240
+ a: 0.02,
2241
+ d: 0.12,
2242
+ vol: [0.08, 0.12]
2243
+ }),
2244
+ ...sceneMany(
2245
+ 2,
2246
+ () => sceneTone({
2247
+ f: [2600, 4200],
2248
+ d: [0.04, 0.08],
2249
+ vol: [0.015, 0.03],
2250
+ delay: [0.08, 0.22]
2251
+ })
2252
+ )
2253
+ ],
2254
+ "a fridge door: the seal letting go and the bottles in the door"
2255
+ ),
2256
+ foley(
2257
+ "fridge_close",
2258
+ [
2259
+ sceneTone({ f: vary(85), f2: 45, d: [0.1, 0.13], vol: [0.38, 0.46] }),
2260
+ sceneNoise({
2261
+ type: "lowpass",
2262
+ f: [520, 620],
2263
+ d: [0.08, 0.12],
2264
+ vol: [0.3, 0.36]
2265
+ }),
2266
+ sceneNoise({
2267
+ type: "lowpass",
2268
+ f: [260, 320],
2269
+ a: 0.02,
2270
+ d: 0.1,
2271
+ vol: [0.12, 0.18],
2272
+ delay: [0.04, 0.07]
2273
+ }),
2274
+ ...sceneMany(
2275
+ 2,
2276
+ () => sceneTone({
2277
+ f: [2600, 4200],
2278
+ d: [0.04, 0.07],
2279
+ vol: [0.015, 0.03],
2280
+ delay: [0.03, 0.12]
2281
+ })
2282
+ )
2283
+ ],
2284
+ "a fridge door shut: a soft thump, the seal pulling and the bottles"
2285
+ ),
2286
+ // a microwave: the spring catch of the door, plastic on plastic
2287
+ foley(
2288
+ "microwave_open",
2289
+ [
2290
+ ...click(1800, 0.34),
2291
+ sceneTone({
2292
+ f: [3e3, 3400],
2293
+ f2: 2800,
2294
+ d: 0.05,
2295
+ vol: 0.025,
2296
+ delay: [0.01, 0.02]
2297
+ })
2298
+ ],
2299
+ "the spring catch of a microwave door"
2300
+ ),
2301
+ foley(
2302
+ "microwave_close",
2303
+ [
2304
+ sceneNoise({
2305
+ type: "bandpass",
2306
+ f: [1200, 1450],
2307
+ q: 2.5,
2308
+ d: [0.04, 0.06],
2309
+ vol: [0.36, 0.44]
2310
+ }),
2311
+ sceneTone({ f: vary(180), f2: 120, d: 0.05, vol: [0.16, 0.22] }),
2312
+ ...click(2200, 0.2, [8e-3, 0.016])
2313
+ ],
2314
+ "a microwave door clacking shut"
2315
+ ),
2316
+ foley("microwave_beep", [sceneTone({ wave: "square", f: 2e3, d: 0.12, vol: 0.05 })], "the beep of a microwave"),
2317
+ // drawers and sliding leaves: the runners, then the stop
2318
+ foley(
2319
+ "drawer_open",
2320
+ [
2321
+ sceneNoise({
2322
+ type: "bandpass",
2323
+ f: [620, 780],
2324
+ q: 2,
2325
+ a: 0.04,
2326
+ d: [0.28, 0.36],
2327
+ vol: [0.18, 0.24]
2328
+ }),
2329
+ sceneNoise({ type: "bandpass", f: [2e3, 2400], q: 5, d: 0.28, vol: 0.04 }),
2330
+ ...click(1400, 0.16, [0.28, 0.34])
2331
+ ],
2332
+ "a drawer on its runners and its stop"
2333
+ ),
2334
+ foley(
2335
+ "drawer_close",
2336
+ [
2337
+ sceneNoise({
2338
+ type: "bandpass",
2339
+ f: [620, 780],
2340
+ q: 2,
2341
+ a: 0.03,
2342
+ d: [0.2, 0.28],
2343
+ vol: [0.18, 0.24]
2344
+ }),
2345
+ sceneTone({
2346
+ f: vary(150),
2347
+ f2: 90,
2348
+ d: 0.08,
2349
+ vol: [0.22, 0.3],
2350
+ delay: [0.2, 0.26]
2351
+ })
2352
+ ],
2353
+ "a drawer pushed home"
2354
+ )
2355
+ ];
2356
+ var ITEM_FOLEY = [
2357
+ // the hand closing on the item: a touch of skin and cloth, then the item's own small sound
2358
+ foley(
2359
+ "item_pickup_metal",
2360
+ [
2361
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
2362
+ sceneTone({
2363
+ f: [1900, 2600],
2364
+ f2: 1700,
2365
+ d: [0.05, 0.08],
2366
+ vol: [0.06, 0.09],
2367
+ delay: [0.01, 0.03]
2368
+ })
2369
+ ],
2370
+ "picking up a metal thing"
2371
+ ),
2372
+ foley(
2373
+ "item_pickup_plastic",
2374
+ [
2375
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
2376
+ sceneNoise({
2377
+ type: "bandpass",
2378
+ f: [1500, 1900],
2379
+ q: 3,
2380
+ d: 0.03,
2381
+ vol: [0.15, 0.21],
2382
+ delay: [0.01, 0.03]
2383
+ })
2384
+ ],
2385
+ "picking up a plastic thing"
2386
+ ),
2387
+ foley(
2388
+ "item_pickup_glass",
2389
+ [
2390
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.15 }),
2391
+ sceneTone({
2392
+ f: [3200, 4200],
2393
+ d: [0.05, 0.08],
2394
+ vol: [0.038, 0.06],
2395
+ delay: [0.01, 0.03]
2396
+ })
2397
+ ],
2398
+ "picking up a glass thing"
2399
+ ),
2400
+ foley(
2401
+ "item_pickup_paper",
2402
+ [
2403
+ sceneNoise({
2404
+ type: "highpass",
2405
+ f: [2600, 3400],
2406
+ a: 0.01,
2407
+ d: [0.1, 0.14],
2408
+ vol: [0.12, 0.18]
2409
+ }),
2410
+ sceneNoise({ type: "bandpass", f: [800, 1e3], q: 1, d: 0.05, vol: 0.12 })
2411
+ ],
2412
+ "picking up paper or cardboard"
2413
+ ),
2414
+ foley(
2415
+ "item_pickup_fabric",
2416
+ [
2417
+ sceneNoise({
2418
+ type: "bandpass",
2419
+ f: [900, 1300],
2420
+ q: 0.8,
2421
+ a: 0.02,
2422
+ d: [0.12, 0.16],
2423
+ vol: [0.15, 0.21]
2424
+ })
2425
+ ],
2426
+ "picking up cloth"
2427
+ ),
2428
+ foley(
2429
+ "item_pickup_wood",
2430
+ [
2431
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
2432
+ sceneNoise({
2433
+ type: "bandpass",
2434
+ f: [900, 1100],
2435
+ q: 2,
2436
+ d: 0.04,
2437
+ vol: [0.15, 0.21],
2438
+ delay: [0.01, 0.03]
2439
+ })
2440
+ ],
2441
+ "picking up a wooden thing"
2442
+ ),
2443
+ foley(
2444
+ "item_pickup_food",
2445
+ [
2446
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
2447
+ sceneNoise({
2448
+ type: "lowpass",
2449
+ f: [500, 650],
2450
+ d: 0.05,
2451
+ vol: 0.12,
2452
+ delay: [0.01, 0.03]
2453
+ })
2454
+ ],
2455
+ "picking up food"
2456
+ ),
2457
+ foley(
2458
+ "item_throw",
2459
+ [
2460
+ sceneNoise({
2461
+ type: "bandpass",
2462
+ f: [450, 650],
2463
+ f2: 1400,
2464
+ q: 1.5,
2465
+ a: 0.05,
2466
+ d: 0.18,
2467
+ vol: [0.1, 0.14]
2468
+ })
2469
+ ],
2470
+ "the arm throwing something: air"
2471
+ ),
2472
+ // a can: the tab cracks, the gas hisses out; drinking is gulps; crushing it crumples the sheet
2473
+ foley(
2474
+ "can_open",
2475
+ [
2476
+ ...click(3200, 0.36),
2477
+ sceneNoise({
2478
+ type: "highpass",
2479
+ f: [3600, 4400],
2480
+ a: 5e-3,
2481
+ d: [0.22, 0.3],
2482
+ vol: [0.16, 0.22],
2483
+ delay: [0.012, 0.02]
2484
+ }),
2485
+ ...sceneMany(5, () => sceneTone({ f: [4e3, 7e3], d: 0.02, vol: 0.01, delay: [0.05, 0.4] }))
2486
+ ],
2487
+ "the tab of a can and the gas hissing out"
2488
+ ),
2489
+ foley(
2490
+ "can_crush",
2491
+ [
2492
+ sceneNoise({
2493
+ type: "bandpass",
2494
+ f: [1600, 2200],
2495
+ q: 1.2,
2496
+ d: [0.18, 0.25],
2497
+ vol: [0.3, 0.38]
2498
+ }),
2499
+ ...sceneMany(
2500
+ 6,
2501
+ () => sceneTone({
2502
+ f: [1200, 3400],
2503
+ f2: 900,
2504
+ d: 0.03,
2505
+ vol: [0.03, 0.06],
2506
+ delay: [0, 0.2]
2507
+ })
2508
+ )
2509
+ ],
2510
+ "a can crushed in the hand"
2511
+ ),
2512
+ foley(
2513
+ "can_puncture_spray",
2514
+ [
2515
+ sceneNoise({
2516
+ type: "highpass",
2517
+ f: [2400, 3e3],
2518
+ a: 5e-3,
2519
+ d: [0.5, 0.7],
2520
+ vol: [0.2, 0.26]
2521
+ }),
2522
+ sceneNoise({ type: "bandpass", f: [600, 800], q: 2, d: 0.4, vol: 0.06 })
2523
+ ],
2524
+ "a can holed: the jet hissing out"
2525
+ ),
2526
+ foley(
2527
+ "bottle_open",
2528
+ [
2529
+ ...sceneMany(
2530
+ 5,
2531
+ () => sceneNoise({
2532
+ type: "bandpass",
2533
+ f: [2200, 3e3],
2534
+ q: 4,
2535
+ d: 8e-3,
2536
+ vol: [0.1, 0.16],
2537
+ delay: [0, 0.18]
2538
+ })
2539
+ ),
2540
+ sceneNoise({
2541
+ type: "highpass",
2542
+ f: 3800,
2543
+ a: 5e-3,
2544
+ d: 0.12,
2545
+ vol: [0.06, 0.1],
2546
+ delay: [0.18, 0.22]
2547
+ })
2548
+ ],
2549
+ "the screw cap of a bottle turning off"
2550
+ ),
2551
+ foley(
2552
+ "drink_gulp",
2553
+ [
2554
+ sceneNoise({
2555
+ type: "lowpass",
2556
+ f: [280, 360],
2557
+ a: 0.02,
2558
+ d: [0.1, 0.14],
2559
+ vol: [0.24, 0.3]
2560
+ }),
2561
+ sceneTone({ f: [140, 170], f2: 85, d: [0.08, 0.11], vol: [0.12, 0.16] })
2562
+ ],
2563
+ "a gulp"
2564
+ ),
2565
+ foley(
2566
+ "eat_crunch",
2567
+ [
2568
+ ...sceneMany(
2569
+ 4,
2570
+ () => sceneNoise({
2571
+ type: "bandpass",
2572
+ f: [1800, 3200],
2573
+ q: 1.5,
2574
+ d: [0.02, 0.04],
2575
+ vol: [0.12, 0.2],
2576
+ delay: [0, 0.12]
2577
+ })
2578
+ )
2579
+ ],
2580
+ "a bite of something crunchy"
2581
+ ),
2582
+ foley(
2583
+ "eat_chew",
2584
+ [
2585
+ sceneNoise({
2586
+ type: "lowpass",
2587
+ f: [450, 600],
2588
+ a: 0.03,
2589
+ d: [0.1, 0.14],
2590
+ vol: [0.12, 0.16]
2591
+ }),
2592
+ sceneNoise({
2593
+ type: "bandpass",
2594
+ f: [1100, 1400],
2595
+ q: 2,
2596
+ d: 0.04,
2597
+ vol: 0.04,
2598
+ delay: [0.03, 0.06]
2599
+ })
2600
+ ],
2601
+ "chewing"
2602
+ ),
2603
+ foley(
2604
+ "bandage_wrap",
2605
+ [
2606
+ sceneNoise({
2607
+ type: "bandpass",
2608
+ f: [1400, 1800],
2609
+ f2: 2400,
2610
+ q: 1,
2611
+ a: 0.04,
2612
+ d: [0.3, 0.4],
2613
+ vol: [0.12, 0.16]
2614
+ })
2615
+ ],
2616
+ "a bandage unrolled round a limb"
2617
+ ),
2618
+ foley(
2619
+ "pills_shake",
2620
+ [
2621
+ ...sceneMany(
2622
+ 8,
2623
+ () => sceneTone({
2624
+ f: [2400, 3600],
2625
+ d: 0.015,
2626
+ vol: [0.03, 0.05],
2627
+ delay: [0, 0.25]
2628
+ })
2629
+ ),
2630
+ sceneNoise({ type: "bandpass", f: [1500, 1900], q: 2, d: 0.25, vol: 0.05 })
2631
+ ],
2632
+ "pills shaken in their bottle"
2633
+ ),
2634
+ foley(
2635
+ "medkit_use",
2636
+ [
2637
+ ...click(1700, 0.24),
2638
+ sceneNoise({
2639
+ type: "bandpass",
2640
+ f: [1e3, 1400],
2641
+ q: 1,
2642
+ a: 0.03,
2643
+ d: [0.25, 0.32],
2644
+ vol: [0.08, 0.12],
2645
+ delay: [0.05, 0.08]
2646
+ })
2647
+ ],
2648
+ "a first aid kit opened and rummaged"
2649
+ ),
2650
+ foley("flashlight_click", click(2600, 0.3), "the switch of a flashlight")
2651
+ ];
2652
+ var FOLEY_BANK = {
2653
+ id: "foley",
2654
+ sounds: [...LEAF_FOLEY, ...ITEM_FOLEY]
2655
+ };
1719
2656
  var TAKES = [
1720
2657
  { f: 1, t: 1, v: 1 },
1721
2658
  { f: 1.08, t: 0.9, v: 0.92 },
@@ -1883,7 +2820,7 @@ var GameCrowdThree = (() => {
1883
2820
  };
1884
2821
  var BODY_FOLEY_SET_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
1885
2822
 
1886
- // ../game-shapes/dist/chunk-IFXQIDSA.js
2823
+ // ../game-shapes/dist/chunk-M5N2SHNL.js
1887
2824
  function canonicalJson(value) {
1888
2825
  if (value === null) return "null";
1889
2826
  if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
@@ -3130,8 +4067,8 @@ var GameCrowdThree = (() => {
3130
4067
  groups: []
3131
4068
  };
3132
4069
  }
3133
- function make(kind, p2) {
3134
- switch (kind) {
4070
+ function make(p2) {
4071
+ switch (p2.kind) {
3135
4072
  case "box": {
3136
4073
  const size = p2.size ?? [1, 1, 1];
3137
4074
  const segments = p2.segments ?? [1, 1, 1];
@@ -3160,7 +4097,7 @@ var GameCrowdThree = (() => {
3160
4097
  case "mesh":
3161
4098
  return mesh(p2);
3162
4099
  default:
3163
- throw new Error(`game-shapes: unknown primitive kind "${String(kind)}"`);
4100
+ throw new Error(`game-shapes: unknown primitive kind "${String(p2.kind)}"`);
3164
4101
  }
3165
4102
  }
3166
4103
  var templates = /* @__PURE__ */ new Map();
@@ -3168,7 +4105,7 @@ var GameCrowdThree = (() => {
3168
4105
  var stats = { hits: 0, misses: 0 };
3169
4106
  function buildPrimitive(node, options = {}) {
3170
4107
  const parameters = primitiveParameters(node, options);
3171
- if (node.kind === "mesh" || templateLimit === 0) return make(node.kind, parameters);
4108
+ if (node.kind === "mesh" || templateLimit === 0) return make({ ...node, ...parameters });
3172
4109
  const key = `${node.kind}:${canonicalJson(parameters)}`;
3173
4110
  const cached = templates.get(key);
3174
4111
  if (cached) {
@@ -3178,7 +4115,7 @@ var GameCrowdThree = (() => {
3178
4115
  return cached;
3179
4116
  }
3180
4117
  stats.misses++;
3181
- const built2 = make(node.kind, parameters);
4118
+ const built2 = make({ ...node, ...parameters });
3182
4119
  templates.set(key, built2);
3183
4120
  if (templates.size > templateLimit) templates.delete(templates.keys().next().value);
3184
4121
  return built2;
@@ -3484,7 +4421,7 @@ var GameCrowdThree = (() => {
3484
4421
  return releaseObject3D(list2, { keep });
3485
4422
  }
3486
4423
 
3487
- // ../game-characters-three/dist/chunk-3CHBEUHW.js
4424
+ // ../game-characters-three/dist/chunk-XSMP7T6O.js
3488
4425
  var UNDEAD_VOICE_GROUP = "undead_voice";
3489
4426
  var voiced = { bus: "voices", group: UNDEAD_VOICE_GROUP };
3490
4427
  var p = (param) => ({ param });
@@ -3702,12 +4639,12 @@ var GameCrowdThree = (() => {
3702
4639
  const o = add(Hd, cap(0.205, PI / 2), c, 0, 1.835, -5e-3);
3703
4640
  o.scale.set(1, 0.98, 1.08);
3704
4641
  add(Hd, new THREE.CylinderGeometry(0.208, 0.212, 0.04, 20), c, 0, 1.84, -5e-3);
3705
- if (sp.hat.tape) add(Hd, new THREE.CylinderGeometry(0.205, 0.207, 0.035, 20), cmat(sp.hat.tape), 0, 1.9, -5e-3);
3706
- if (sp.hat.photo) {
4642
+ if (sp.hat?.tape) add(Hd, new THREE.CylinderGeometry(0.205, 0.207, 0.035, 20), cmat(sp.hat.tape), 0, 1.9, -5e-3);
4643
+ if (sp.hat?.photo) {
3707
4644
  add(Hd, Bx(0.07, 0.08, 0.012), cmat(16052448), 0.13, 1.9, 0.14, 0, 0.75, 0);
3708
4645
  add(Hd, Bx(0.05, 0.055, 0.014), cmat(9071184), 0.13, 1.9, 0.141, 0, 0.75, 0);
3709
4646
  }
3710
- if (sp.hat.nvg) {
4647
+ if (sp.hat?.nvg) {
3711
4648
  add(Hd, Bx(0.07, 0.05, 0.06), cmat(1710618), 0, 2, 0.175);
3712
4649
  for (const s of [-1, 1]) add(Hd, new THREE.CylinderGeometry(0.024, 0.024, 0.09, 10).rotateX(PI / 2), cmat(2767402), s * 0.032, 1.965, 0.235);
3713
4650
  }
@@ -5902,6 +6839,7 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
5902
6839
  return { requestFall, stagger, shove, step, flush, landed, pending: () => requests.length };
5903
6840
  }
5904
6841
  var CENTRE_HEIGHT = 1;
6842
+ var SHELTERED = 0.5;
5905
6843
  var DISMEMBER_SHARE = 0.5;
5906
6844
  var LIMB_CHANCE = 0.5;
5907
6845
  var STUN_BASE = 0.45;
@@ -5940,22 +6878,23 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
5940
6878
  emitBlood(tally, i);
5941
6879
  ctx.deferKill(i);
5942
6880
  };
5943
- const hurt = (i, blast, distance2, index) => {
5944
- const falloff = (1 - distance2 / blast.radius) ** 2;
6881
+ const hurt = (i, blast, distance2, index, reach = 1) => {
6882
+ const falloff = (1 - distance2 / blast.radius) ** 2 * reach;
5945
6883
  const amount = blast.energy / 1e3 * options.pointsPerKilojoule * falloff;
5946
6884
  const draw = (salt) => () => unit(store.identity[i], ctx.step, salt);
5947
6885
  if (ctx.damage(i, { region: 1, amount, distance: distance2, cut: falloff }, draw(SALT.JAW + index)).died) return true;
5948
6886
  const region = Math.floor(unit(store.identity[i], ctx.step, SALT.REGION + index) * 6);
5949
6887
  return ctx.damage(i, { region, amount: amount / 2, distance: distance2, cut: falloff }, draw(SALT.JAW + 8 + index)).died;
5950
6888
  };
5951
- const shoveOf = (i, blasts) => {
6889
+ const shoveOf = (i, blasts, reaches) => {
5952
6890
  const position = [store.x[i], store.y[i] + CENTRE_HEIGHT * store.height[i], store.z[i]];
5953
6891
  let vx = 0;
5954
6892
  let vy = 0;
5955
6893
  let vz = 0;
5956
6894
  let falloff = 0;
5957
- for (const blast of blasts) {
5958
- const shove = blastShove({ point: blast.point, energy: blast.energy, radius: blast.radius }, { position, mass: store.mass[i] }, options.shove);
6895
+ for (let b = 0; b < blasts.length; b++) {
6896
+ const blast = blasts[b];
6897
+ const shove = blastShove({ point: blast.point, energy: blast.energy, radius: blast.radius, reach: reaches?.[b] ?? 1 }, { position, mass: store.mass[i] }, options.shove);
5959
6898
  if (!shove) continue;
5960
6899
  vx += shove.speed * shove.direction[0];
5961
6900
  vy += shove.speed * shove.direction[1];
@@ -5990,16 +6929,19 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
5990
6929
  };
5991
6930
  const affect = (i, blasts, tallies, candidates) => {
5992
6931
  let dead = store.hp[i] <= 0;
6932
+ const reaches = blasts.map(
6933
+ (blast) => blast.reach && distanceTo(i, blast) <= blast.radius ? blast.reach([store.x[i], store.y[i] + CENTRE_HEIGHT * store.height[i], store.z[i]]) : 1
6934
+ );
5993
6935
  for (let b = 0; b < blasts.length && !dead; b++) {
5994
6936
  const blast = blasts[b];
5995
6937
  const distance2 = distanceTo(i, blast);
5996
6938
  if (distance2 > blast.radius) continue;
5997
6939
  tallies[b].reached++;
5998
- if (blast.lethalRadius !== void 0 && distance2 < blast.lethalRadius) kill(i, blast, distance2, tallies[b]);
5999
- else if (hurt(i, blast, distance2, b)) tallies[b].killed++;
6940
+ if (blast.lethalRadius !== void 0 && distance2 < blast.lethalRadius && reaches[b] >= SHELTERED) kill(i, blast, distance2, tallies[b]);
6941
+ else if (hurt(i, blast, distance2, b, reaches[b])) tallies[b].killed++;
6000
6942
  dead = store.hp[i] <= 0 || dead;
6001
6943
  }
6002
- const shove = shoveOf(i, blasts);
6944
+ const shove = shoveOf(i, blasts, reaches);
6003
6945
  if (shove) applyShove(i, shove, candidates, tallies, blasts);
6004
6946
  };
6005
6947
  const resolve = () => {
@@ -6344,7 +7286,7 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
6344
7286
  const touched = new Int32Array((store.capacity + extraBodies) * CELLS_PER_BODY * 2);
6345
7287
  let touchedCount = 0;
6346
7288
  const entryCapacity = (store.capacity + extraBodies) * CELLS_PER_BODY;
6347
- const entries = { count: 0, cell: new Int32Array(entryCapacity), thickness: new Uint16Array(entryCapacity), identity: new Uint32Array(entryCapacity), agent: new Int32Array(entryCapacity) };
7289
+ const entries2 = { count: 0, cell: new Int32Array(entryCapacity), thickness: new Uint16Array(entryCapacity), identity: new Uint32Array(entryCapacity), agent: new Int32Array(entryCapacity) };
6348
7290
  const standMass = new Float32Array(cellCount);
6349
7291
  const standTouched = new Int32Array(store.capacity);
6350
7292
  let standTouchedCount = 0;
@@ -6364,17 +7306,17 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
6364
7306
  if (cell < 0) continue;
6365
7307
  if (height[cell] === 0) touched[touchedCount++] = cell;
6366
7308
  height[cell] += millimetres;
6367
- const index = entries.count++;
6368
- entries.cell[index] = cell;
6369
- entries.thickness[index] = millimetres;
6370
- entries.identity[index] = identity2;
6371
- entries.agent[index] = agent;
7309
+ const index = entries2.count++;
7310
+ entries2.cell[index] = cell;
7311
+ entries2.thickness[index] = millimetres;
7312
+ entries2.identity[index] = identity2;
7313
+ entries2.agent[index] = agent;
6372
7314
  }
6373
7315
  };
6374
7316
  const sumBodies = () => {
6375
7317
  for (let k = 0; k < touchedCount; k++) height[touched[k]] = 0;
6376
7318
  touchedCount = 0;
6377
- entries.count = 0;
7319
+ entries2.count = 0;
6378
7320
  for (let i = 0; i < store.n; i++) {
6379
7321
  const state = store.balance[i];
6380
7322
  if (store.band[i] !== 0 || state !== BALANCE.FALLEN && state !== BALANCE.GETTING_UP) continue;
@@ -6402,14 +7344,14 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
6402
7344
  return best;
6403
7345
  };
6404
7346
  const slideEntry = (index) => {
6405
- const cell = entries.cell[index];
6406
- const target = lowestNeighbour(cell, entries.thickness[index]);
7347
+ const cell = entries2.cell[index];
7348
+ const target = lowestNeighbour(cell, entries2.thickness[index]);
6407
7349
  if (target < 0) return;
6408
7350
  if (height[target] === 0) touched[touchedCount++] = target;
6409
- height[target] += entries.thickness[index];
6410
- height[cell] -= entries.thickness[index];
6411
- entries.cell[index] = target;
6412
- const agent = entries.agent[index];
7351
+ height[target] += entries2.thickness[index];
7352
+ height[cell] -= entries2.thickness[index];
7353
+ entries2.cell[index] = target;
7354
+ const agent = entries2.agent[index];
6413
7355
  if (agent < 0) return;
6414
7356
  store.x[agent] += (target % grid.n - cell % grid.n) * grid.cell;
6415
7357
  store.z[agent] += (Math.floor(target / grid.n) - Math.floor(cell / grid.n)) * grid.cell;
@@ -6418,17 +7360,17 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
6418
7360
  let over = false;
6419
7361
  for (let k = 0; k < touchedCount && !over; k++) over = height[touched[k]] > maxMillimetres;
6420
7362
  if (!over) return;
6421
- const order = Array.from({ length: entries.count }, (_, index) => index).sort((a, b) => entries.cell[a] - entries.cell[b] || entries.identity[a] - entries.identity[b] || a - b);
7363
+ const order = Array.from({ length: entries2.count }, (_, index) => index).sort((a, b) => entries2.cell[a] - entries2.cell[b] || entries2.identity[a] - entries2.identity[b] || a - b);
6422
7364
  let current = -1;
6423
7365
  let running = 0;
6424
7366
  for (const index of order) {
6425
- const cell = entries.cell[index];
7367
+ const cell = entries2.cell[index];
6426
7368
  if (cell !== current) {
6427
7369
  current = cell;
6428
7370
  running = 0;
6429
7371
  }
6430
7372
  if (height[cell] <= maxMillimetres) continue;
6431
- if (running + entries.thickness[index] <= maxMillimetres) running += entries.thickness[index];
7373
+ if (running + entries2.thickness[index] <= maxMillimetres) running += entries2.thickness[index];
6432
7374
  else slideEntry(index);
6433
7375
  }
6434
7376
  for (let k = 0; k < touchedCount; k++) if (height[touched[k]] > maxMillimetres) height[touched[k]] = maxMillimetres;
@@ -6488,14 +7430,14 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
6488
7430
  }
6489
7431
  function createDefaultWorkerFactory() {
6490
7432
  if (typeof Worker === "undefined") return null;
6491
- let url;
7433
+ let url2;
6492
7434
  try {
6493
- url = new URL("./physics-worker.js", import_meta.url);
7435
+ url2 = new URL("./physics-worker.js", import_meta.url);
6494
7436
  } catch {
6495
7437
  return null;
6496
7438
  }
6497
7439
  return () => {
6498
- const worker = new Worker(url, { type: "module" });
7440
+ const worker = new Worker(url2, { type: "module" });
6499
7441
  return {
6500
7442
  postMessage: (message, transfer) => worker.postMessage(message, transfer ?? []),
6501
7443
  onMessage: (listener) => worker.addEventListener("message", (event) => listener(event.data)),
@@ -9869,10 +10811,10 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
9869
10811
  for (let i = 0; i < count; i++) order[sortStarts[sortBin(distances[i])]++] = i;
9870
10812
  };
9871
10813
  const corpseHistogram = new Uint32Array(budget ? Math.ceil(CORPSE_REACH / BUDGET_BIN) + 1 : 0);
9872
- const fitCorpseEdges = (entries, cx, cz, scale) => {
10814
+ const fitCorpseEdges = (entries2, cx, cz, scale) => {
9873
10815
  if (!budget) return [N.corpseNear, Infinity];
9874
10816
  corpseHistogram.fill(0);
9875
- for (const { data } of entries) {
10817
+ for (const { data } of entries2) {
9876
10818
  const distance2 = Math.hypot(data.x - cx, data.z - cz);
9877
10819
  if (distance2 < CORPSE_REACH) corpseHistogram[Math.floor(distance2 / BUDGET_BIN)]++;
9878
10820
  }
@@ -9951,11 +10893,11 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
9951
10893
  }
9952
10894
  return written;
9953
10895
  },
9954
- corpses(entries, variants, frame, life, sink, plain) {
10896
+ corpses(entries2, variants, frame, life, sink, plain) {
9955
10897
  const cx = frame.camera.x;
9956
10898
  const cz = frame.camera.z;
9957
- const [nearEdge, middleEdge] = fitCorpseEdges(entries, cx, cz, frame.detailScale ?? 1);
9958
- for (const { age: t, data: C } of entries) {
10899
+ const [nearEdge, middleEdge] = fitCorpseEdges(entries2, cx, cz, frame.detailScale ?? 1);
10900
+ for (const { age: t, data: C } of entries2) {
9959
10901
  const dark = Math.min(1, t / life);
9960
10902
  const shade = 1 - dark * N.corpseDarken;
9961
10903
  const fade = t > life - N.corpseFade ? (life - t) / N.corpseFade : 1;
@@ -10483,7 +11425,7 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
10483
11425
  };
10484
11426
  var HERD_SOUND_IDS = { bark: "dog_bark", lapwing: "lapwing_call", cluck: "hen_cluck", moo: "cow_moo" };
10485
11427
 
10486
- // ../game-player/dist/chunk-FRZ6ISLA.js
11428
+ // ../game-player/dist/chunk-RUFQCNZH.js
10487
11429
  var defaults_default2 = {
10488
11430
  sources: {
10489
11431
  game: "specs/001-migracao-entregas-dos-times/artefatos/2UG1Mhe9LqJkQKKVsJkTWR/jogo.js",
@@ -11950,7 +12892,17 @@ ${accessoryHead}`).replace("{ vec3 _nn = objectNormal; bodyAnim(position, _nn);"
11950
12892
  const offFixed = lent.onFrame((step) => world.physics ? stepCrowd(step) : void 0, { phase: "fixedSimulate" });
11951
12893
  const offBlast = lent.on((event) => {
11952
12894
  if (event.type !== "explosion") return;
11953
- world.crowd.blast({ point: event.point, energy: event.energy, radius: event.radius, lethalRadius: event.radius * LETHAL_SHARE, source: event.source, ...event.cause === "part" ? { chain: event.source } : {} });
12895
+ const cover = lent.blastReach;
12896
+ world.crowd.blast({
12897
+ point: event.point,
12898
+ energy: event.energy,
12899
+ radius: event.radius,
12900
+ lethalRadius: event.radius * LETHAL_SHARE,
12901
+ source: event.source,
12902
+ ...event.cause === "part" ? { chain: event.source } : {},
12903
+ // a wall or a car between the blast and an agent takes its share of the shove and the damage
12904
+ ...cover ? { reach: (target) => cover(event.point, [target[0], target[1], target[2]], [event.source]) } : {}
12905
+ });
11954
12906
  });
11955
12907
  if (host) removeProps = sceneOf()?.props?.(host, { cx, cz }, options.props ?? {}) ?? null;
11956
12908
  if (options.eager) queueMicrotask(() => prepareDrawing());