@adatechnology/game-weapons-three 0.14.1 → 0.15.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/test-area/area.ts","../src/test-area/accessory-bench.ts","../src/attachments-key.ts","../src/test-area/accessory-text.ts","../src/audio.ts","../src/audio/mechanical-sounds.ts","../src/audio/recipes.ts","../src/audio/shot-sound.ts","../src/audio/gunshot.ts","../src/data/gunshot-profiles.json","../src/audio/casing-sound.ts","../src/audio/flyby.ts","../src/data/reload-sounds.json","../src/audio/reload-sounds.ts","../src/audio/samples.ts","../src/data/reload-sample-hits.json","../src/box-fx.ts","../src/fx/layers.ts","../src/laser-raycast.ts","../src/fx/body-hold.ts","../src/fx/hand-hold.ts","../src/props.ts","../src/item-weapon-draw.ts","../src/item-models.ts","../src/models/explosives.ts","../src/models/kit.ts","../src/models/rounded-box.ts","../src/weapon-item-model.ts","../src/models/index.ts","../src/data/models.json","../src/models/break-action.ts","../src/models/attachments/muzzle-brake.ts","../src/models/capture.ts","../src/models/details.ts","../src/models/attachments/bipod.ts","../src/models/rifle-fittings.ts","../src/models/rifle-forend.ts","../src/models/attachments/belt-box.ts","../src/models/attachments/drum.ts","../src/models/helical-magazine.ts","../src/models/rifle-controls.ts","../src/models/rifle-stock.ts","../src/models/rifle.ts","../src/models/break-launcher.ts","../src/models/attachments/mount-frames.ts","../src/models/bullpup.ts","../src/models/launcher-flame.ts","../src/models/launcher-rounds.ts","../src/models/launcher-rocket.ts","../src/models/launcher.ts","../src/models/m134.ts","../src/models/m2.ts","../src/models/p90.ts","../src/models/part-registry.ts","../src/models/pistol-slide.ts","../src/models/pistol-style.ts","../src/models/pistol.ts","../src/models/revolver.ts","../src/fx/viewmodel.ts","../src/animation/clip-builder.ts","../src/animation/accessory-clips.ts","../src/animation/magazine-clips.ts","../src/animation/context.ts","../src/animation/cycle-clips.ts","../src/animation/reload-clips.ts","../src/animation/shot-clips.ts","../src/animation/clip-set.ts","../src/audio/host-events.ts","../src/models/attachments/ammo-backpack.ts","../src/models/attachments/foregrip.ts","../src/models/attachments/laser.ts","../src/models/attachments/light.ts","../src/models/attachments/magazine.ts","../src/models/attachments/muzzle-device.ts","../src/models/attachments/optic.ts","../src/models/attachments/sling.ts","../src/models/attachments/suppressor.ts","../src/models/attachments/tripod.ts","../src/models/attachments/ugl.ts","../src/models/attachments/registry.ts","../src/models/attachments/fit.ts","../src/models/attachments/rig-underbarrel.ts","../src/models/rig-stock.ts","../src/models/condition.ts","../src/models/cartridge.ts","../src/fx/effects.ts","../src/fx/view-hold.ts","../src/fx/heavy.ts","../src/fx/particles.ts","../src/fx/rig.ts","../src/fx/session.ts","../src/fx/viewmodel-events.ts","../src/fx/hand-work.ts","../src/data/hand-work.json","../src/fx.ts","../src/modeled-prop.ts","../assets/weapon-svg/manifest.json","../src/thumbnails.ts","../src/world-explosives.ts","../src/data/world-effects.json","../src/world-effects.ts","../src/test-area/scenarios.ts","../src/test-area/explosives-area.ts","../src/test-area/explosives-bench.ts","../src/test-area/explosives-text.ts","../src/test-area/explosives-scenarios.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport type { AreaPlacement, BenchChange, DestructibleSpec, HostTool, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport type { EngineSink } from '@adatechnology/game-audio'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport { createArsenal, genericWeapons } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport { furnitureSpec } from '@adatechnology/game-floorplan-three'\nimport { isLightBudget, isRenderPools } from '@adatechnology/game-render-three'\nimport { createAccessoryBench, accessoryControls, accessoryLayers, accessoryMetrics } from './accessory-bench'\nimport { accessoryTextOf } from './accessory-text'\nimport { createWeaponAudio } from '../audio'\nimport type { WeaponAudio, WeaponSampleOptions } from '../audio'\nimport { createWeaponFx } from '../fx'\nimport type { WeaponFx } from '../fx'\nimport { createLaserRaycast } from '../laser-raycast'\nimport { ARCHETYPE_MODELS, hasWeaponModel } from '../models'\nimport type { AttachmentModelRegistry } from '../models/attachments/types'\nimport { buildModeledProp, buildTripodMountedProp, modeledPropSpec } from '../modeled-prop'\nimport { BODY_ACTIONS, buildProp, weaponProp } from '../props'\nimport { defaultWeaponProps, hasThrowableModel } from '../weapon-item-model'\nimport type { WeaponProps } from '../weapon-item-model'\nimport type { ItemModels } from '../item-models'\nimport type { WeaponProp } from '../props'\nimport { DEFAULT_THUMBNAIL_BASE, weaponThumbnailCredit, weaponThumbnailUrl } from '../thumbnails'\nimport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from '../world-explosives'\nimport { createWorldEffects } from '../world-effects'\nimport { weaponsScenarios } from './scenarios'\n\nexport interface WeaponsTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to lay out (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** Play sounds (default true; silent anyway where there is no AudioContext). */\n sound?: boolean\n /** The recorded shots and reload steps (game-audio's sfx manifest and where its files are); without it the synthesized sounds play. */\n samples?: WeaponSampleOptions\n /** Wear of the weapon in the hands, which the gallery models show in their metal: `new` (default), `used`, `worn` or `rusty`. */\n condition?: string\n /** Seed of the scatter of casings and smoke (default 1). */\n seed?: number\n /** Builders of accessory models that replace or add to the ones the kit ships (by the `model` of the accessory). */\n attachmentModels?: AttachmentModelRegistry\n /** Folder (ending with a slash) the weapon thumbnails are served from, relative to the page (default `weapon-svg/`); `false` leaves the items without a thumbnail. */\n thumbnailBase?: string | false\n /** The rocket of a launcher flies out of the weapon in the hands (default true). A host that draws the projectile (the test room's `projectileModel`) passes false: one round flies. */\n flyRocket?: boolean\n /** The item models of game-items-three (`itemModels` there): the weapons the gallery did not draw get the team's model instead of the low-poly prop; default `itemModels` there (deprecated: pass it). */\n items?: ItemModels\n /** The weapon item model overrides to draw with (`createWeaponProps(...)`); default the shared set behind `registerWeaponItemModel`. */\n props?: WeaponProps\n}\n\n/** Prefix of the item ids of the weapon props (`weapon_beretta_92fs`). */\nexport const WEAPON_ITEM_PREFIX = 'weapon_'\n// must not start with WEAPON_ITEM_PREFIX: hosts and tests tell the props apart by it\nexport const COUNTER_ITEM_ID = 'counter_weapons'\n\n// how loud an explosion is: a base plus what its reach adds (the game's `explosao` class is at full volume for a blast of 15 m or more)\nconst EXPLOSION_VOLUME_BASE = 0.4\nconst EXPLOSION_VOLUME_PER_METRE = 0.04\nconst SOUND_DISTANCE_MAX = 800\n/** Longest safety fuse the bench offers, metres: one metre burns 131 s, enough to see a delayed trap. */\nconst FUSE_LENGTH_MAX = 1\nconst DEFAULT_FUSE_LENGTH = 0.03\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\n// four columns on the free left side of the room, in two rows: counters fill in this order\nconst COUNTER_X = [-6.5, -9, -11.5, -14]\nconst COUNTER_Z = [-1, 5.5]\n// the M134 mounted on its tripod stands apart from the counters, in front of the targets and pointing at them\nexport const MOUNTED_M134_ITEM_ID = 'm134_tripod'\nconst MOUNTED_M134 = { weaponId: 'm134', at: [-3.5, 0, 2] as Vec3, rotationY: Math.PI / 2 }\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.5\n// the strip of counter a weapon lying across it takes: most are slim, a few are wide (a tripod, two fuel tanks, a bow limb)\nconst DEFAULT_PITCH = 0.16\nconst PITCH_BY_ID: Readonly<Record<string, number>> = { browning_m2: 0.5, m134: 0.45, m2_flamethrower: 0.45, bow: 0.3, crossbow: 0.3 }\n// the explosives of the world stand together in the far corner (the player is at the other end, 17 m away): a bullet, fire or blast starts the chain reaction\nconst WORLD_EXPLOSIVES: Array<{ id: string; at: Vec3 }> = [\n { id: 'fuel_barrel', at: [10, 0, -8] },\n { id: 'fuel_barrel', at: [11.2, 0, -8] },\n { id: 'propane_p13', at: [10.6, 0, -9.3] },\n { id: 'car_fuel_tank', at: [8.6, 0, -9.3] },\n]\n// targets in front of the brick wall of the room, at shooting distances\nconst TARGETS: Array<{ id: string; at: Vec3 }> = [\n { id: 'target_steel_plate', at: [-1.5, 0, -7] },\n { id: 'target_plywood', at: [0, 0, -7] },\n { id: 'target_concrete', at: [1.5, 0, -7] },\n]\n\nconst EMPTY_TOOL: HostTool = { weapon: '', category: '', ammo: 0, capacity: 0, reserve: 0, reloading: false }\n\ninterface Text {\n group: string\n name: string\n counter: string\n targets: Record<string, string>\n reloadStart: string\n /** The line of a reload start: how it goes (`kind`), the clip that plays and its seconds. */\n reloadClip: string\n reloadKinds: Record<string, string>\n /** The line of a sound cue of a reload clip and the name of each cue. */\n soundCue: string\n /** Appended to `soundCue`: the recording played, or the cue sounds inside the next one's recording. */\n cueRecorded: string\n cueCarried: string\n gunshotSound: string\n /** Appended to `gunshotSound` when the recording played: which take near and far. */\n gunshotRecorded: string\n casingSound: string\n spaces: Record<'indoor' | 'outdoor', string>\n surfaces: Record<'hard' | 'wood' | 'metal' | 'soft', string>\n soundCues: Record<string, string>\n reloadEnd: string\n worldExplosives: Record<string, string>\n mountedM134: string\n condition: string\n conditionHint: string\n conditions: Record<string, string>\n ammoQuality: string\n ammoQualityHint: string\n ammoQualities: Record<string, string>\n soundDistance: string\n soundDistanceHint: string\n soundIndoors: string\n soundIndoorsHint: string\n fuseLength: string\n fuseLengthHint: string\n layers: Record<'muzzle_flash' | 'casings' | 'magazines', string>\n metrics: Record<'casings_live' | 'magazines_live' | 'heat', string>\n}\n\nconst TEXT: Record<string, Text> = {\n en: {\n group: 'Weapons',\n name: 'Weapons area',\n counter: 'Weapon counter',\n targets: { target_steel_plate: 'Steel plate target', target_plywood: 'Plywood target', target_concrete: 'Concrete block target' },\n reloadStart: 'Reload started: {weapon} ({ammo}/{capacity})',\n reloadClip: 'Reload of {weapon}: {kind}, clip {clip} ({seconds} s)',\n soundCue: 'Sound: {cue} ({weapon})',\n cueRecorded: ' · recorded',\n cueCarried: ' · inside the next recording',\n gunshotSound: 'Shot sound: {profile}, take {take}/4, pitch {pitch}, {space}, {distance} m{far}',\n gunshotRecorded: ' · recorded take {takes}',\n casingSound: 'Case lands: {case} on {surface}',\n spaces: { indoor: 'indoors', outdoor: 'outdoors' },\n surfaces: { hard: 'concrete', wood: 'wood', metal: 'metal', soft: 'dirt' },\n soundCues: { mag_release: 'magazine release button', mag_out: 'magazine slides out', mag_insert: 'magazine slides in', mag_seat: 'magazine seats (click)', slide_release: 'slide snaps forward', charging_handle_pull: 'charging handle pulled', charging_handle_release: 'charging handle released', bolt_lift: 'bolt handle lifted', bolt_pull: 'bolt pulled back', bolt_push: 'bolt pushed forward', bolt_lock: 'bolt handle locked down', shell_insert: 'round inserted', pump_back: 'pump back', pump_forward: 'pump forward', lever_open: 'lever down', lever_close: 'lever up', cylinder_open: 'cylinder opens', cylinder_eject: 'cases fall out', speedloader: 'speed loader empties', cylinder_close: 'cylinder closes', barrels_open: 'barrels open', casings_eject: 'cases pop out', barrels_close: 'barrels close', belt_cover_open: 'cover opens', belt_insert: 'belt seats', belt_cover_close: 'cover closes', rocket_load: 'rocket slides in', rocket_seat: 'rocket seats', grenade_load: 'grenade goes in', breech_open: 'breech opens', breech_close: 'breech closes', tube_drop: 'empty tube dropped', tube_seat: 'new tube seats' },\n reloadKinds: { tactical: 'tactical (round chambered, no pull)', empty: 'empty chamber (works the action)', one_by_one: 'one by one', full: 'speed loader' },\n reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Fuel barrel', propane_p13: 'Propane cylinder (P13)', car_fuel_tank: 'Car fuel tank' },\n mountedM134: 'M134 Minigun on its tripod',\n condition: 'Weapon condition',\n conditionHint: 'Wear of the weapon: it jams more and the metal shows it',\n conditions: { new: 'New', used: 'Used', worn: 'Worn', rusty: 'Rusty' },\n ammoQuality: 'Ammunition',\n ammoQualityHint: 'Reloaded rounds misfire more often',\n ammoQualities: { factory: 'Factory', reloaded: 'Reloaded' },\n soundDistance: 'Sound distance',\n soundDistanceHint: 'How far the listener is from the shot: farther is quieter and duller',\n soundIndoors: 'Shot indoors',\n soundIndoorsHint: 'In a room the walls answer at once (short, dense tail); outdoors the field answers late (long tail and echoes)',\n fuseLength: 'Dynamite fuse length',\n fuseLengthHint: 'Metres of safety fuse (131 s per metre): a long one is set down lit, for a delayed trap',\n layers: { muzzle_flash: 'Muzzle flash', casings: 'Ejected casings', magazines: 'Dropped magazines' },\n metrics: { casings_live: 'Casings in the scene', magazines_live: 'Magazines in the scene', heat: 'Barrel heat' },\n },\n 'pt-BR': {\n group: 'Armas',\n name: 'Área de armas',\n counter: 'Balcão de armas',\n targets: { target_steel_plate: 'Alvo: chapa de aço', target_plywood: 'Alvo: compensado', target_concrete: 'Alvo: bloco de concreto' },\n reloadStart: 'Recarga iniciada: {weapon} ({ammo}/{capacity})',\n reloadClip: 'Recarga de {weapon}: {kind}, clipe {clip} ({seconds} s)',\n soundCue: 'Som: {cue} ({weapon})',\n cueRecorded: ' · gravação',\n cueCarried: ' · dentro da gravação seguinte',\n gunshotSound: 'Som do tiro: {profile}, tomada {take}/4, tom {pitch}, {space}, {distance} m{far}',\n gunshotRecorded: ' · gravação, tomada {takes}',\n casingSound: 'Cápsula caiu: {case} em {surface}',\n spaces: { indoor: 'ambiente fechado', outdoor: 'ao ar livre' },\n surfaces: { hard: 'concreto', wood: 'madeira', metal: 'metal', soft: 'terra' },\n soundCues: { mag_release: 'botão do carregador', mag_out: 'carregador desliza para fora', mag_insert: 'carregador desliza para dentro', mag_seat: 'carregador encaixa (clique)', slide_release: 'ferrolho volta com estalo', charging_handle_pull: 'alavanca de armar puxada', charging_handle_release: 'alavanca de armar solta', bolt_lift: 'alavanca do ferrolho levantada', bolt_pull: 'ferrolho puxado', bolt_push: 'ferrolho empurrado', bolt_lock: 'alavanca do ferrolho travada', shell_insert: 'cartucho entra', pump_back: 'bomba para trás', pump_forward: 'bomba para frente', lever_open: 'alavanca para baixo', lever_close: 'alavanca para cima', cylinder_open: 'tambor abre', cylinder_eject: 'cápsulas caem', speedloader: 'speedloader esvazia', cylinder_close: 'tambor fecha', barrels_open: 'canos abrem', casings_eject: 'estojos saltam', barrels_close: 'canos fecham', belt_cover_open: 'tampa abre', belt_insert: 'cinta encaixa', belt_cover_close: 'tampa fecha', rocket_load: 'foguete desliza para dentro', rocket_seat: 'foguete encaixa', grenade_load: 'granada entra', breech_open: 'culatra abre', breech_close: 'culatra fecha', tube_drop: 'tubo vazio cai', tube_seat: 'tubo novo encaixa' },\n reloadKinds: { tactical: 'tática (com bala na câmara, sem puxar)', empty: 'vazia (puxa o ferrolho ou a trava)', one_by_one: 'uma a uma', full: 'carregador rápido' },\n reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Barril de combustível', propane_p13: 'Botijão de gás (P13)', car_fuel_tank: 'Tanque de combustível do carro' },\n mountedM134: 'M134 Minigun no tripé',\n condition: 'Estado da arma',\n conditionHint: 'Desgaste da arma: trava mais e o metal mostra',\n conditions: { new: 'Nova', used: 'Usada', worn: 'Gasta', rusty: 'Enferrujada' },\n ammoQuality: 'Munição',\n ammoQualityHint: 'Munição recarregada falha mais',\n ammoQualities: { factory: 'De fábrica', reloaded: 'Recarregada' },\n soundDistance: 'Distância do som',\n soundDistanceHint: 'Quão longe o ouvinte está do tiro: mais longe soa mais baixo e abafado',\n soundIndoors: 'Tiro em ambiente fechado',\n soundIndoorsHint: 'Numa sala as paredes respondem na hora (cauda curta e densa); ao ar livre o campo responde depois (cauda longa e ecos)',\n fuseLength: 'Pavio da dinamite',\n fuseLengthHint: 'Metros de pavio de segurança (131 s por metro): um longo é posto no chão aceso, para armadilha com atraso',\n layers: { muzzle_flash: 'Clarão do cano', casings: 'Cápsulas ejetadas', magazines: 'Pentes que caem' },\n metrics: { casings_live: 'Cápsulas na cena', magazines_live: 'Pentes na cena', heat: 'Calor do cano' },\n },\n}\nconst textOf = (locale: string): Text => TEXT[locale] ?? (TEXT.en as Text)\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\n// the counters are the buffet of the furniture catalogue (a cabinet base under a top), drawn by the house renderer at the counter's measures: its width across x, its length along z\nconst COUNTER_FURNITURE = 'buffet'\n\n/** A counter of the furniture catalogue (`furnitureSpec` of game-floorplan-three), as an item of the area. */\nconst counterItem = (name: string): TestableItem => {\n const counter = (THREE: unknown) => furnitureSpec(THREE, COUNTER_FURNITURE, { w: COUNTER.depth, d: COUNTER.length, h: COUNTER.height })\n return {\n id: COUNTER_ITEM_ID,\n name,\n build: (THREE: unknown) => {\n const piece = counter(THREE)\n const root = piece.build(THREE) as THREE_NS.Object3D\n root.userData.counterSpec = { ...piece.spec, name, tags: [...(piece.spec.tags ?? []), 'furniture'] }\n return root\n },\n spec: (root: unknown) => (root as THREE_NS.Object3D).userData.counterSpec as DestructibleSpec,\n movable: false,\n }\n}\n\nconst targetProp = (id: string, name: string): WeaponProp => {\n const face: Record<string, [string, Vec3, number]> = {\n target_steel_plate: ['steel', [0.5, 0.5, 0.01], 0xb5bcc4],\n target_plywood: ['plywood', [0.6, 0.8, 0.018], 0xc9a26b],\n target_concrete: ['concrete', [0.4, 0.2, 0.2], 0x9a9a94],\n }\n const [material, size, color] = face[id]\n const spec: DestructibleSpec = {\n name,\n parts: [\n { id: 'post', material: 'steel', shape: { kind: 'box', size: [0.05, 1.1, 0.05] }, position: [0, 0.55, -0.05], anchored: true },\n { id: 'face', material, shape: { kind: 'box', size }, position: [0, 1.1 + size[1] / 2, 0] },\n ],\n joints: [{ a: 'post', b: 'face', kind: 'bolt' }],\n tags: ['target'],\n }\n return { spec, colors: { post: 0x3a3d42, face: color } }\n}\n\n/** A weapon on the counters: the gallery model when it drew one, else the item model of game-items-three (one rigid body of its measures), the low-poly prop of its category when neither. */\nconst weaponItem = (def: WeaponDef, name: string, items?: ItemModels, props: WeaponProps = defaultWeaponProps()): TestableItem => {\n const id = `${WEAPON_ITEM_PREFIX}${def.id}`\n if (!hasWeaponModel(def.id) && !props.itemModelOf(def.id, items) && !hasThrowableModel(def)) return asItem(id, name, weaponProp(def, name), { weapon: def.id, movable: true })\n return {\n id,\n name,\n build: (THREE: unknown) => buildModeledProp(THREE as typeof THREE_NS, def, name, undefined, items, props) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n movable: true,\n }\n}\n\n/** The M134 standing on a tripod: the support the `tripod` accessory gives, as a prop of its own (aim at it and press H to take the gun). */\nconst mountedM134Item = (def: WeaponDef, name: string, items?: ItemModels, props?: WeaponProps): TestableItem => ({\n id: MOUNTED_M134_ITEM_ID,\n name,\n build: (THREE: unknown) => buildTripodMountedProp(THREE as typeof THREE_NS, def, name, items, props) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n movable: false,\n})\n\n/** A shooting target of the range (a plate of steel, plywood or concrete on a post): a piece of the weapons kit itself, marked as such. */\nconst targetItem = (id: string, name: string): TestableItem => {\n const prop = targetProp(id, name)\n return { id, name, build: (THREE: unknown) => markKitOrigin(buildProp(THREE as typeof THREE_NS, prop), { owner: 'game-weapons-three', kind: 'target', id }), spec: prop.spec, movable: false }\n}\n\nconst asItem = (id: string, name: string, prop: WeaponProp, extra: Partial<TestableItem> = {}): TestableItem => ({\n id,\n name,\n build: (THREE: unknown) => buildProp(THREE as typeof THREE_NS, prop),\n spec: prop.spec,\n ...extra,\n})\n\n/** Where the counters go and where each weapon lies on them: weapons side by side across the counters in order, each taking its strip, until the counter is full. */\nexport function weaponsLayout(weaponItemIds: string[], pitchOf: (itemId: string) => number = () => DEFAULT_PITCH): AreaPlacement[] {\n const usable = COUNTER.length - 2 * END_MARGIN\n const slots = COUNTER_Z.flatMap((z) => COUNTER_X.map((x) => ({ x, z })))\n const counterOf: Array<{ x: number; z: number; used: number }> = []\n const placements: AreaPlacement[] = []\n for (const item of weaponItemIds) {\n const pitch = pitchOf(item)\n let counter = counterOf[counterOf.length - 1]\n if (!counter || counter.used + pitch > usable + 1e-9) {\n const slot = slots[counterOf.length]\n if (!slot) throw new Error(`weapons area: ${weaponItemIds.length} weapons do not fit on ${slots.length} counters of ${usable.toFixed(2)} m`)\n if (pitch > usable + 1e-9) throw new Error(`weapons area: \"${item}\" takes ${pitch} m and a counter holds ${usable.toFixed(2)} m`)\n counter = { ...slot, used: 0 }\n counterOf.push(counter)\n }\n placements.push({ item, position: [counter.x, COUNTER.height + 0.01, counter.z - COUNTER.length / 2 + END_MARGIN + counter.used + pitch / 2], asleep: true })\n counter.used += pitch\n }\n const counters: AreaPlacement[] = counterOf.map(({ x, z }) => ({ item: COUNTER_ITEM_ID, position: [x, 0, z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n const targets: AreaPlacement[] = TARGETS.map((target) => ({ item: target.id, position: target.at }))\n const explosives: AreaPlacement[] = WORLD_EXPLOSIVES.map((explosive) => ({ item: `${WORLD_EXPLOSIVE_PREFIX}${explosive.id}`, position: explosive.at }))\n return [...counters, ...placements, ...targets, ...explosives]\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: every weapon of the arsenal on counters, the real model of each one the gallery drew (aim at one and\n * press H to equip it), targets at shooting distance, and, through `attach`, the weapon in the hands with its fire and reload motion,\n * ejected casings, dropped magazines and sounds, driven by the host's tool events.\n */\nexport function createWeaponsTestModule(options: WeaponsTestModuleOptions = {}): TestableModule & { readonly audio: WeaponAudio | null; readonly fx: WeaponFx | null } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = textOf(locale)\n const accessoryText = accessoryTextOf(locale)\n const seedOption = options.seed === undefined ? {} : { seed: options.seed }\n // the module's own audio, made when first needed (it makes no context until the first sound); when the host lends a sound engine, `attach` makes one on that engine instead\n let audio: WeaponAudio | null | undefined\n const ownAudio = (): WeaponAudio | null => (audio === undefined ? (audio = options.sound === false ? null : createWeaponAudio(undefined, { ...seedOption, ...(options.samples ? { samples: options.samples } : {}) })) : audio)\n // the generic guns (the `9 mm service pistol`) are not laid out nor listed: the real weapon that stands for each is (the hands still take them by id)\n const generics = genericWeapons(arsenal)\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id) && !generics.has(def.id))\n const thumbnailBase = options.thumbnailBase ?? DEFAULT_THUMBNAIL_BASE\n const withThumbnail = (item: TestableItem, key: string): TestableItem => {\n const thumbnail = thumbnailBase === false ? undefined : weaponThumbnailUrl(key, thumbnailBase)\n if (!thumbnail) return item\n const thumbnailCredit = weaponThumbnailCredit(key)\n return thumbnailCredit ? { ...item, thumbnail, thumbnailCredit } : { ...item, thumbnail }\n }\n // An archetype wearing the model of a brand weapon is the same thing twice on the counters: it stays in the catalogue (the hands still take it) but is not laid out.\n const weaponIds = weaponDefs.filter((def) => !(def.id in ARCHETYPE_MODELS)).map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n const pitchOf = (itemId: string): number => PITCH_BY_ID[itemId.slice(WEAPON_ITEM_PREFIX.length)] ?? DEFAULT_PITCH\n const worldExplosives = WORLD_EXPLOSIVE_IDS.flatMap((id) => {\n const def = arsenal.explosives.get(id)\n const item = def ? worldExplosiveItem(def, text.worldExplosives[id] ?? id, options.items === undefined ? {} : { items: options.items }) : undefined\n return item ? [item] : []\n })\n const worldExplosiveIds = new Set(worldExplosives.map((item) => item.id))\n const mountedM134Def = arsenal.weapons.get(MOUNTED_M134.weaponId)\n const mountedM134 = mountedM134Def && hasWeaponModel(mountedM134Def.id) ? [mountedM134Item(mountedM134Def, text.mountedM134, options.items, options.props)] : []\n let fx: WeaponFx | null = null\n let host: ModuleHost | null = null\n let soundDistance = 0\n let soundIndoors = false\n const heatPercent = (): number => Math.min(100, (host?.tool().heat ?? 0) * 100)\n return {\n id: 'weapons_area',\n name: text.name,\n ground: { surface: 'concrete_slab' },\n group: text.group,\n get audio() {\n return ownAudio()\n },\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => withThumbnail(weaponItem(def, arsenal.name(def.id), options.items, options.props), def.id)),\n counterItem(text.counter),\n ...TARGETS.map((target) => targetItem(target.id, text.targets[target.id] ?? target.id)),\n ...worldExplosives.map((item) => withThumbnail(item, item.id.slice(WORLD_EXPLOSIVE_PREFIX.length))),\n ...mountedM134.map((item) => withThumbnail(item, MOUNTED_M134.weaponId)),\n ],\n scenarios: (scenarioLocale) => weaponsScenarios(scenarioLocale ?? locale),\n area: (): ModuleArea => ({\n placements: [\n ...weaponsLayout(weaponIds, pitchOf).filter((placement) => !placement.item.startsWith(WORLD_EXPLOSIVE_PREFIX) || worldExplosiveIds.has(placement.item)),\n ...mountedM134.map((item) => ({ item: item.id, position: MOUNTED_M134.at, rotationY: MOUNTED_M134.rotationY, asleep: true })),\n ],\n view: { eye: [-3.4, 1.9, 9.2], target: [-9, 0.9, 1.6] },\n }),\n controls: (): ModuleControl[] => [\n {\n kind: 'choice',\n id: 'condition',\n name: text.condition,\n hint: text.conditionHint,\n options: arsenal.rules.conditions.map((entry) => ({ id: entry.id, name: text.conditions[entry.id] ?? entry.id })),\n default: options.condition ?? arsenal.rules.defaultCondition,\n },\n {\n kind: 'choice',\n id: 'ammo_quality',\n name: text.ammoQuality,\n hint: text.ammoQualityHint,\n options: arsenal.rules.ammoQualities.map((entry) => ({ id: entry.id, name: text.ammoQualities[entry.id] ?? entry.id })),\n default: arsenal.rules.defaultAmmoQuality,\n },\n { kind: 'number', id: 'sound_distance', name: text.soundDistance, hint: text.soundDistanceHint, unit: 'm', min: 0, max: SOUND_DISTANCE_MAX, step: 5, default: 0 },\n { kind: 'boolean', id: 'sound_indoors', name: text.soundIndoors, hint: text.soundIndoorsHint, default: false },\n { kind: 'number', id: 'fuse_length', name: text.fuseLength, hint: text.fuseLengthHint, unit: 'm', min: 0.01, max: FUSE_LENGTH_MAX, step: 0.01, default: arsenal.explosives.get('dynamite')?.fuseLength ?? DEFAULT_FUSE_LENGTH },\n ...accessoryControls(accessoryText),\n ],\n layers: (): ModuleLayer[] => [...(['muzzle_flash', 'casings', 'magazines'] as const).map((id) => ({ id, name: text.layers[id] })), ...accessoryLayers(accessoryText)],\n metrics: (): ModuleMetric[] => [\n { id: 'casings_live', name: text.metrics.casings_live, read: () => fx?.casings ?? 0 },\n { id: 'magazines_live', name: text.metrics.magazines_live, read: () => fx?.magazines ?? 0 },\n { id: 'heat', name: text.metrics.heat, unit: '%', max: 100, digits: 0, read: heatPercent },\n ...accessoryMetrics(accessoryText, () => host?.tool() ?? EMPTY_TOOL),\n ],\n attach(lent) {\n host = lent\n const lentEngine = (lent.audio as EngineSink | undefined)?.engine\n if (lentEngine && options.sound !== false) {\n audio?.dispose()\n audio = createWeaponAudio(undefined, {\n ...seedOption,\n engine: lentEngine,\n ...(options.samples ? { samples: options.samples } : {}),\n onGunshot: (shot, input, played) => {\n const recorded = played.kind === 'sample' && played.layers.length > 0 ? fill(text.gunshotRecorded, { takes: played.layers.map((layer) => `${layer.role} ${layer.take + 1}`).join(', ') }) : ''\n lent.log(\n 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,\n { 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 },\n 'sound',\n )\n },\n onCasing: (sound, played) => lent.log(fill(text.casingSound, { case: sound.kind, surface: text.surfaces[sound.surface] }) + (played === 'sample' ? text.cueRecorded : ''), { case: sound.kind, surface: sound.surface, sample: sound.sample, played }, 'sound'),\n })\n }\n let simulatedMs = 0\n const offClock = lent.onFrame((dt) => (simulatedMs += dt * 1000))\n const created = createWeaponFx({\n onSound: ({ weapon, cue, profile, played }) => lent.log(fill(text.soundCue, { weapon: arsenal.name(weapon), cue: text.soundCues[cue] ?? cue }) + (played === 'sample' ? text.cueRecorded : played === 'carried' ? text.cueCarried : ''), { weapon, cue, weight: profile.weight, material: profile.material, ...(played ? { played } : {}) }, 'sound'),\n THREE: lent.THREE as typeof THREE_NS,\n scene: lent.scene as THREE_NS.Scene,\n camera: lent.camera as THREE_NS.Camera,\n arsenal,\n ...(options.items ? { items: options.items } : {}),\n groundAt: lent.groundAt,\n audio: ownAudio(),\n tool: lent.tool,\n soundDistance: () => soundDistance,\n soundSpace: () => (soundIndoors ? 'indoor' : 'outdoor'),\n ...(lent.surfaceAt ? { surfaceAt: (x: number, z: number) => lent.surfaceAt?.(x, z) } : {}),\n raycast: createLaserRaycast(lent.THREE as typeof THREE_NS, lent.scene as THREE_NS.Scene, lent.camera as THREE_NS.Camera),\n // the weapon against a wall asks as often as the laser, on the clock of the simulation (so a fast-forwarded room measures as often per frame)\n contact: createLaserRaycast(lent.THREE as typeof THREE_NS, lent.scene as THREE_NS.Scene, lent.camera as THREE_NS.Camera, { now: () => simulatedMs }),\n ...(lent.holdFrame ? { bodyHold: () => lent.holdFrame?.() ?? null } : {}),\n firstPerson: () => lent.player().cameraMode === 'first',\n ...(lent.effects ? { effects: lent.effects } : {}),\n ...(lent.particleLimit ? { particleLimit: lent.particleLimit } : {}),\n ...(isLightBudget(lent.lights) ? { lights: lent.lights } : {}),\n ...(isRenderPools(lent.pools) ? { pools: lent.pools } : {}),\n ...(options.attachmentModels ? { attachmentModels: options.attachmentModels } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n ...(options.flyRocket === undefined ? {} : { flyRocket: options.flyRocket }),\n })\n fx = created\n const camera = lent.camera as THREE_NS.Camera\n const accessories = createAccessoryBench({ arsenal, host: lent, text: accessoryText })\n const offBench = lent.bench?.onChange((change: BenchChange) => {\n if (accessories.handleChange(change)) return\n if (change.kind === 'layer') {\n if (change.id === 'attachments') created.layers.attachments = change.on\n else if (change.id === 'beams') created.layers.beams = change.on\n else if (change.id === 'muzzle_flash') created.layers.muzzleFlash = change.on\n else if (change.id === 'casings') created.layers.casings = change.on\n else if (change.id === 'magazines') created.layers.magazines = change.on\n } else if (change.kind === 'control' && typeof change.value === 'string') {\n if (change.id === 'condition') {\n created.setCondition(change.value)\n lent.configureTool?.({ condition: change.value })\n } else if (change.id === 'ammo_quality') lent.configureTool?.({ ammo_quality: change.value })\n } else if (change.kind === 'control' && change.id === 'sound_distance' && typeof change.value === 'number') soundDistance = change.value\n else if (change.kind === 'control' && change.id === 'sound_indoors' && typeof change.value === 'boolean') soundIndoors = change.value\n else if (change.kind === 'control' && change.id === 'fuse_length' && typeof change.value === 'number') lent.configureTool?.({ fuse_length: String(change.value) })\n })\n const worldEffects = createWorldEffects({ arsenal })\n const offEvents = lent.on((event) => {\n worldEffects.handle(event, lent.effects)\n if (event.type === 'explosion') {\n const away = Math.hypot(event.point[0] - camera.position.x, event.point[1] - camera.position.y, event.point[2] - camera.position.z)\n ownAudio()?.play('explosion', Math.min(1, EXPLOSION_VOLUME_BASE + event.radius * EXPLOSION_VOLUME_PER_METRE), away)\n return\n }\n const tool = lent.tool()\n created.handle(event, tool)\n if (event.type === 'reload' && event.phase === 'start') {\n const clip = created.clips.find((entry) => entry.name.startsWith('reload'))\n if (clip) {\n const kind = event.kind ?? 'tactical'\n lent.log(fill(text.reloadClip, { weapon: arsenal.name(event.weapon), kind: text.reloadKinds[kind] ?? kind, clip: clip.name, seconds: clip.seconds.toFixed(2) }), { weapon: event.weapon, kind, clip: clip.name, seconds: clip.seconds })\n }\n }\n if (event.type === 'reload') lent.log(fill(event.phase === 'start' ? text.reloadStart : text.reloadEnd, { weapon: arsenal.name(event.weapon), ammo: tool.ammo, capacity: tool.capacity }), { weapon: event.weapon, phase: event.phase })\n })\n const offFrame = lent.onFrame((dt) => created.update(dt))\n const offHands = lent.setHandTargets?.(() => created.handTargets())\n const offMuzzle = lent.setMuzzleSource?.(() => created.muzzle())\n created.handle({ type: 'tool', weapon: lent.tool().weapon }, lent.tool())\n return () => {\n accessories.dispose()\n offBench?.()\n offEvents()\n offFrame()\n offClock()\n offHands?.()\n offMuzzle?.()\n created.dispose()\n audio?.dispose()\n fx = null\n host = null\n }\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { BenchChange, ChoiceOption, HostTool, HostToolAttachment, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ToolCommand } from '@adatechnology/game-contracts'\nimport type { Arsenal, FittedAttachment, MountKind } from '@adatechnology/game-weapons'\nimport { aimZoomOf } from '@adatechnology/game-weapons'\nimport { attachmentsKey } from '../attachments-key'\nimport type { AccessoryText } from './accessory-text'\n\n/** The places of a weapon the bench offers accessories for, in the order the panel lists them. */\nexport const ACCESSORY_MOUNTS: readonly MountKind[] = ['muzzle', 'rail_top', 'rail_left', 'rail_right', 'rail_bottom', 'underbarrel', 'magazine', 'feed', 'sling', 'barrel']\n/** Keys of the accessories. V (the stock) is the room's kick when the weapon has no stock that moves; the others are free in the room. */\nexport const ACCESSORY_KEYS = { light: 'KeyL', laser: 'KeyK', stock: 'KeyV', underbarrel: 'KeyU' } as const\nconst FIT_PREFIX = 'fit_'\nconst NONE = 'none'\nexport const SUPPORTED_CONTROL_ID = 'supported_stance'\nconst ACTION_IDS = { light: 'toggle_light', laser: 'toggle_laser', stock: 'toggle_stock', underbarrel: 'switch_underbarrel' } as const\nconst SECONDARY_BUTTON = 2\nconst TEXT_FIELDS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\nexport const accessoryControls = (text: AccessoryText): ModuleControl[] => [\n ...ACCESSORY_MOUNTS.map((mount): ModuleControl => ({ kind: 'choice', id: `${FIT_PREFIX}${mount}`, name: text.mounts[mount] ?? mount, options: [{ id: NONE, name: text.none }], default: NONE })),\n { kind: 'boolean', id: SUPPORTED_CONTROL_ID, name: text.supported.name, hint: text.supported.hint, default: false },\n ...(Object.keys(ACTION_IDS) as Array<keyof typeof ACTION_IDS>).map((key): ModuleControl => ({ kind: 'action', id: ACTION_IDS[key], name: text.actions[key].name, hint: text.actions[key].hint })),\n]\n\nexport const accessoryLayers = (text: AccessoryText): ModuleLayer[] => [\n { id: 'attachments', name: text.layers.attachments },\n { id: 'beams', name: text.layers.beams },\n]\n\nexport const accessoryMetrics = (text: AccessoryText, tool: () => HostTool): ModuleMetric[] => [\n { id: 'weapon_mass', name: text.metrics.mass, unit: 'kg', digits: 2, read: () => tool().mass ?? 0 },\n { id: 'aim_time', name: text.metrics.aim, unit: 's', digits: 2, read: () => tool().aimSeconds ?? 0 },\n { id: 'accessories_fitted', name: text.metrics.fitted, digits: 0, read: () => (tool().attachments ?? []).length },\n { id: 'suppressed', name: text.metrics.suppressed, read: () => (tool().suppressed ? text.yes : text.no) },\n]\n\nexport interface AccessoryBenchOptions {\n readonly arsenal: Arsenal\n readonly host: ModuleHost\n readonly text: AccessoryText\n}\n\nexport interface AccessoryBench {\n /** Gives it a change of the bench (a choice of accessory for a mount, a button); false when the change is not one of its own. */\n handleChange(change: BenchChange): boolean\n dispose(): void\n}\n\nconst fittedOf = (parts: readonly HostToolAttachment[] | undefined): FittedAttachment[] =>\n (parts ?? []).map((part) => ({ id: part.id, mount: part.mount as MountKind, ...(part.integral ? { integral: true } : {}), ...(part.on === undefined ? {} : { on: part.on }) }))\n\nconst fillText = (template: string, vars: Record<string, string>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => vars[key] ?? '')\n\n/**\n * The accessory bench of the weapons area: a choice per mount that fits and removes what is compatible with the weapon in hand (and only that), the keys of the light (L), the laser (K),\n * the stock (V) and the launcher under the barrel (U), and the right mouse button, which aims: the camera zooms by the optic that is fitted (or by the iron sights of the weapon's category,\n * `rules.aim.ironSightZoom`), over the seconds the weapon takes to the sights.\n */\nexport function createAccessoryBench(options: AccessoryBenchOptions): AccessoryBench {\n const { arsenal, host, text } = options\n const camera = host.camera as THREE_NS.PerspectiveCamera\n const bench = host.bench\n const pending = new Map<MountKind, string>()\n let signature = ''\n let aiming = false\n let aimProgress = 0\n let baseFov = camera.fov\n let appliedZoom = 1\n\n const nameOf = (id: string): string => text.attachments[id] ?? arsenal.attachments.get(id)?.name ?? id\n\n const offers = (tool: HostTool, mount: MountKind): ChoiceOption[] => {\n const fitted = fittedOf(tool.attachments)\n const here = fitted.find((part) => part.mount === mount)\n const choices: ChoiceOption[] = [{ id: NONE, name: text.none }]\n if (here) choices.push({ id: here.id, name: nameOf(here.id) })\n for (const def of arsenal.attachments.values()) {\n if (def.id === here?.id || !arsenal.canFit(tool.weapon, def.id, { fitted, mount }).ok) continue\n choices.push({ id: def.id, name: nameOf(def.id) })\n }\n return choices\n }\n\n const refresh = (): void => {\n const tool = host.tool()\n const next = `${tool.weapon}|${attachmentsKey(tool.attachments)}`\n if (next === signature) return\n signature = next\n const def = arsenal.weapons.get(tool.weapon)\n for (const mount of ACCESSORY_MOUNTS) {\n const has = (def?.mounts ?? []).some((place) => place.kind === mount)\n const here = (tool.attachments ?? []).find((part) => part.mount === mount)\n const choices = offers(tool, mount)\n const isFixed = here?.integral === true\n bench?.patch(`${FIT_PREFIX}${mount}`, { hidden: !has, disabled: isFixed, options: choices, ...(pending.has(mount) ? {} : { value: here?.id ?? NONE }) })\n }\n }\n\n const refuse = (mount: MountKind, reason: string | undefined): void => {\n host.log(fillText(text.fitRefused, { mount: text.mounts[mount] ?? mount, weapon: arsenal.name(host.tool().weapon), reason: reason ?? '' }), { mount, reason })\n pending.delete(mount)\n signature = ''\n }\n\n const settle = (): void => {\n for (const [mount, wanted] of pending) {\n const here = (host.tool().attachments ?? []).find((part) => part.mount === mount && !part.integral)\n if (here?.id === wanted || (!here && wanted === NONE)) {\n pending.delete(mount)\n continue\n }\n const request: ToolCommand = here ? { type: 'remove', attachment: here.id } : { type: 'fit', attachment: wanted, mount }\n const result = host.command?.(request)\n if (!result || (!result.ok && result.reason !== 'busy')) refuse(mount, result?.reason)\n if (result?.reason === 'busy') return\n }\n }\n\n const toggleKind = (kind: 'light' | 'laser'): void => {\n const part = (host.tool().attachments ?? []).find((candidate) => arsenal.attachments.get(candidate.id)?.kind === kind)\n if (!part) host.log(kind === 'light' ? text.noLight : text.noLaser)\n else host.command?.({ type: 'toggle', attachment: part.id })\n }\n\n const toggleStock = (): boolean => {\n const tool = host.tool()\n const kind = arsenal.weapons.get(tool.weapon)?.stock?.kind\n if (kind === undefined || kind === 'fixed' || kind === 'none') return false\n host.command?.({ type: 'stock', state: tool.stock === 'collapsed' ? 'extended' : 'collapsed' })\n return true\n }\n\n const switchUnderbarrel = (): void => {\n const tool = host.tool()\n const hasLauncher = (tool.attachments ?? []).some((part) => arsenal.attachments.get(part.id)?.launcher !== undefined)\n if (!hasLauncher) host.log(text.noLauncher)\n else host.command?.({ type: 'underbarrel', on: tool.underbarrelActive !== true })\n }\n\n const act = (id: string): boolean => {\n if (id === ACTION_IDS.light) toggleKind('light')\n else if (id === ACTION_IDS.laser) toggleKind('laser')\n else if (id === ACTION_IDS.stock) {\n if (!toggleStock()) host.log(text.noStock)\n } else if (id === ACTION_IDS.underbarrel) switchUnderbarrel()\n else return false\n return true\n }\n\n // the optic fitted, else the iron sights of the weapon's category: every gun closes the view in when it aims, not only one with a scope\n const zoomOf = (tool: HostTool): number => aimZoomOf(arsenal, tool.weapon, tool.attachments?.map((part) => part.id))\n\n const aims = (tool: HostTool): boolean => {\n const kind = arsenal.weapons.get(tool.weapon)?.action.kind\n return kind === 'firearm' || kind === 'launcher'\n }\n\n const setAim = (on: boolean): void => {\n if (on === aiming) return\n aiming = on\n host.command?.({ type: 'stance', aiming: on })\n }\n\n const follow = (dt: number): void => {\n const tool = host.tool()\n const seconds = Math.max(0.05, tool.aimSeconds ?? 0.2)\n aimProgress = Math.max(0, Math.min(1, aimProgress + (aiming ? dt : -dt) / seconds))\n const zoom = 1 + (zoomOf(tool) - 1) * aimProgress\n if (Math.abs(zoom - appliedZoom) < 1e-4) return\n if (appliedZoom === 1) baseFov = camera.fov\n appliedZoom = zoom\n camera.fov = zoom === 1 ? baseFov : (2 * Math.atan(Math.tan((baseFov * Math.PI) / 360) / zoom) * 180) / Math.PI\n camera.updateProjectionMatrix()\n }\n\n const onKeyDown = (event: KeyboardEvent): void => {\n // someone else holds the player (at the wheel of a vehicle): L, K, U and V are theirs\n if (host.playerHeld?.()) return\n if (event.repeat || event.ctrlKey || event.metaKey || event.altKey || TEXT_FIELDS.has((event.target as HTMLElement | null)?.tagName ?? '')) return\n const handled = event.code === ACCESSORY_KEYS.light ? act(ACTION_IDS.light) : event.code === ACCESSORY_KEYS.laser ? act(ACTION_IDS.laser) : event.code === ACCESSORY_KEYS.underbarrel ? act(ACTION_IDS.underbarrel) : event.code === ACCESSORY_KEYS.stock && toggleStock()\n if (!handled) return\n event.preventDefault()\n event.stopImmediatePropagation()\n }\n // only the room's own surface aims: a click on a panel, an input or an overlay is left alone\n const isOnRoom = (event: MouseEvent): boolean => Boolean(document.pointerLockElement) || event.target instanceof HTMLCanvasElement\n const onMouseDown = (event: MouseEvent): void => {\n if (event.button !== SECONDARY_BUTTON || !isOnRoom(event) || !aims(host.tool())) return\n event.preventDefault()\n event.stopImmediatePropagation()\n setAim(true)\n }\n const onMouseUp = (event: MouseEvent): void => {\n if (event.button === SECONDARY_BUTTON) setAim(false)\n }\n const onBlur = (): void => setAim(false)\n\n // capture phase: the room grabs on the right button and kicks on V, and these win only where the weapon in hand has something to do with them\n window.addEventListener('keydown', onKeyDown, true)\n window.addEventListener('mousedown', onMouseDown, true)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('blur', onBlur)\n const offFrame = host.onFrame((dt) => {\n refresh()\n settle()\n follow(dt)\n })\n const offEvents = host.on((event) => {\n if (event.type === 'attachment') {\n const template = event.action === 'fit' ? text.fitting : event.action === 'remove' ? text.removing : text.broke\n host.log(fillText(template, { attachment: nameOf(event.attachment), weapon: arsenal.name(event.weapon), seconds: String(event.duration ?? 0) }), { attachment: event.attachment, action: event.action })\n }\n if (event.type !== 'tool') return\n pending.clear()\n setAim(false)\n bench?.patch(SUPPORTED_CONTROL_ID, { value: false })\n signature = ''\n })\n\n return {\n handleChange(change) {\n if (change.kind === 'action') return act(change.id)\n if (change.kind === 'control' && change.id === SUPPORTED_CONTROL_ID && typeof change.value === 'boolean') {\n host.command?.({ type: 'stance', supported: change.value })\n return true\n }\n if (change.kind !== 'control' || !change.id.startsWith(FIT_PREFIX) || typeof change.value !== 'string') return false\n const mount = change.id.slice(FIT_PREFIX.length) as MountKind\n pending.set(mount, change.value)\n settle()\n return true\n },\n dispose() {\n offFrame()\n offEvents()\n window.removeEventListener('keydown', onKeyDown, true)\n window.removeEventListener('mousedown', onMouseDown, true)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('blur', onBlur)\n if (appliedZoom !== 1) {\n camera.fov = baseFov\n camera.updateProjectionMatrix()\n }\n },\n }\n}\n","import type { HostToolAttachment } from '@adatechnology/game-contracts'\n\n/** A cheap identity of what is on the weapon (count, ids, mounts and which are on), compared every frame in place of serializing the whole list. */\nexport const attachmentsKey = (parts: readonly HostToolAttachment[] | undefined): string => {\n if (!parts) return ''\n let key = String(parts.length)\n for (const part of parts) key += `|${part.id}@${part.mount}${part.on ? '+' : ''}`\n return key\n}\n","/** The words of the accessory bench, by locale (`en` and `pt-BR`). */\nexport interface AccessoryText {\n none: string\n mounts: Record<string, string>\n actions: Record<'light' | 'laser' | 'stock' | 'underbarrel', { name: string; hint: string }>\n layers: Record<'attachments' | 'beams', string>\n supported: { name: string; hint: string }\n metrics: Record<'mass' | 'aim' | 'fitted' | 'suppressed', string>\n yes: string\n no: string\n attachments: Record<string, string>\n fitRefused: string\n fitting: string\n removing: string\n broke: string\n noLight: string\n noLaser: string\n noStock: string\n noLauncher: string\n}\n\nexport const ACCESSORY_TEXT: Record<string, AccessoryText> = {\n en: {\n none: 'None',\n mounts: { muzzle: 'Muzzle', rail_top: 'Top rail', rail_left: 'Left rail', rail_right: 'Right rail', rail_bottom: 'Bottom rail', underbarrel: 'Under the barrel', magazine: 'Magazine', feed: 'Feed (backpack)', sling: 'Sling', barrel: 'Barrel' },\n actions: {\n light: { name: 'Light on/off (L)', hint: 'Turns the weapon light on or off' },\n laser: { name: 'Laser on/off (K)', hint: 'Turns the laser sight on or off' },\n stock: { name: 'Fold or open the stock (V)', hint: 'Folds or slides the stock in, or opens it' },\n underbarrel: { name: 'Launcher under the barrel (U)', hint: 'Switches the trigger and the reload between the weapon and the launcher under its barrel' },\n },\n layers: { attachments: 'Accessory models', beams: 'Light cone and laser beam' },\n supported: { name: 'Supported (deployed / prone)', hint: 'The weapon rests on something: a bipod then takes its recoil and spread effect' },\n metrics: { mass: 'Weapon mass', aim: 'Time to the sights', fitted: 'Accessories on the weapon', suppressed: 'Suppressed' },\n yes: 'yes',\n no: 'no',\n attachments: {\n suppressor: 'Suppressor',\n oil_filter_suppressor: 'Improvised oil filter suppressor',\n integral_suppressor: 'Integral suppressor',\n muzzle_brake: 'Muzzle brake',\n muzzle_brake_heavy: 'Heavy muzzle brake',\n compensator: 'Compensator',\n red_dot: 'Red dot sight',\n holographic_sight: 'Holographic sight',\n acog_4x: 'ACOG 4x',\n scope_3_9x: 'Rifle scope 3-9x',\n scope_6_24x: 'Rifle scope 6-24x',\n night_vision_scope: 'Night vision scope',\n thermal_scope: 'Thermal scope',\n integral_optic_1_5x: 'Integral 1.5x optic of the AUG',\n integral_optic_3x: 'Integral 3x optic of the G36',\n pso_1: 'PSO-1 scope',\n fixed_scope_10x: 'Fixed 10x scope of the M24',\n vertical_grip: 'Vertical foregrip',\n bipod: 'Bipod',\n m203: 'M203 grenade launcher',\n gp_25: 'GP-25 grenade launcher',\n ag36: 'AG36 grenade launcher',\n weapon_light: 'Weapon light',\n laser_sight: 'Laser sight',\n extended_magazine: 'Extended magazine',\n drum_magazine: 'Drum magazine',\n dual_coupler: 'Dual magazine coupler',\n sawn_off_barrel: 'Sawn-off barrel',\n long_barrel: 'Long barrel',\n sling: 'Sling',\n ammo_backpack: 'Ammunition backpack',\n tripod: 'Tripod mount',\n },\n fitRefused: 'Could not change {mount} of {weapon}: {reason}',\n fitting: 'Fitting {attachment} on {weapon} ({seconds} s)',\n removing: 'Taking {attachment} off {weapon} ({seconds} s)',\n broke: '{attachment} broke on {weapon}',\n noLight: 'No light on this weapon',\n noLaser: 'No laser on this weapon',\n noStock: 'This weapon has no stock that folds or slides',\n noLauncher: 'No launcher under the barrel of this weapon',\n },\n 'pt-BR': {\n none: 'Nenhum',\n mounts: { muzzle: 'Boca do cano', rail_top: 'Trilho superior', rail_left: 'Trilho esquerdo', rail_right: 'Trilho direito', rail_bottom: 'Trilho inferior', underbarrel: 'Sob o cano', magazine: 'Carregador', feed: 'Alimentação (mochila)', sling: 'Bandoleira', barrel: 'Cano' },\n actions: {\n light: { name: 'Ligar/desligar a lanterna (L)', hint: 'Liga ou desliga a lanterna da arma' },\n laser: { name: 'Ligar/desligar o laser (K)', hint: 'Liga ou desliga o laser da arma' },\n stock: { name: 'Dobrar ou abrir a coronha (V)', hint: 'Dobra ou recolhe a coronha, ou a abre' },\n underbarrel: { name: 'Lança-granada sob o cano (U)', hint: 'Passa o gatilho e a recarga entre a arma e o lança-granada sob o cano' },\n },\n layers: { attachments: 'Modelos dos acessórios', beams: 'Cone da lanterna e feixe do laser' },\n supported: { name: 'Apoiado (bipé aberto / deitado)', hint: 'A arma está apoiada: o bipé passa a valer no recuo e na dispersão' },\n metrics: { mass: 'Massa da arma', aim: 'Tempo até a mira', fitted: 'Acessórios na arma', suppressed: 'Silenciada' },\n yes: 'sim',\n no: 'não',\n attachments: {\n suppressor: 'Supressor',\n oil_filter_suppressor: 'Supressor de filtro de óleo',\n integral_suppressor: 'Supressor integrado',\n muzzle_brake: 'Freio de boca',\n muzzle_brake_heavy: 'Freio de boca pesado',\n compensator: 'Compensador',\n red_dot: 'Mira red dot',\n holographic_sight: 'Mira holográfica',\n acog_4x: 'ACOG 4×',\n scope_3_9x: 'Luneta 3–9×',\n scope_6_24x: 'Luneta 6–24×',\n night_vision_scope: 'Mira noturna',\n thermal_scope: 'Mira térmica',\n integral_optic_1_5x: 'Mira integrada 1,5×',\n integral_optic_3x: 'Mira integrada 3×',\n pso_1: 'Mira PSO-1',\n fixed_scope_10x: 'Luneta fixa 10×',\n vertical_grip: 'Empunhadura vertical',\n bipod: 'Bipé',\n m203: 'Lança-granada M203',\n gp_25: 'Lança-granada GP-25',\n ag36: 'Lança-granada AG36',\n weapon_light: 'Lanterna',\n laser_sight: 'Laser',\n extended_magazine: 'Carregador estendido',\n drum_magazine: 'Carregador tambor',\n dual_coupler: 'Acoplador de carregadores',\n sawn_off_barrel: 'Cano serrado',\n long_barrel: 'Cano longo',\n sling: 'Bandoleira',\n ammo_backpack: 'Mochila de munição',\n tripod: 'Tripé',\n },\n fitRefused: 'Não deu para mudar {mount} de {weapon}: {reason}',\n fitting: 'Encaixando {attachment} em {weapon} ({seconds} s)',\n removing: 'Tirando {attachment} de {weapon} ({seconds} s)',\n broke: '{attachment} quebrou em {weapon}',\n noLight: 'Esta arma não tem lanterna',\n noLaser: 'Esta arma não tem laser',\n noStock: 'Esta arma não tem coronha que dobre ou recolha',\n noLauncher: 'Esta arma não tem lança-granada sob o cano',\n },\n}\n\nexport const accessoryTextOf = (locale: string): AccessoryText => ACCESSORY_TEXT[locale] ?? (ACCESSORY_TEXT.en as AccessoryText)\n","// Weapon sounds: synthesized with WebAudio, and with `samples` the recorded shots and reload steps of game-audio's sfx (the synthesized sound stays\n// as the fallback until the files are loaded). Every call is a no-op where there is no AudioContext (tests, workers), and the context is only\n// created on the first sound, which comes from a click or a key (browsers allow it).\n// The numbers live in ./audio/*: `computeShotSound` is pure and this file only turns its result into nodes.\nimport { warnOnce } from '@adatechnology/game-contracts'\nimport { MIX_PROFILES, createAudioEngine } from '@adatechnology/game-audio'\nimport type { AudioEngine } from '@adatechnology/game-audio'\nimport type { WeaponEvent } from '@adatechnology/game-weapons'\n\nimport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nimport { BURST_IDS, GUNSHOT_IDS, SCENE_NOISE_IDS, SCENE_TONE_IDS, TONE_IDS, classBurstId, weaponRecipes } from './audio/recipes'\nimport { computeGunshot, pickTake } from './audio/gunshot'\nimport { computeCasingSound } from './audio/casing-sound'\nimport { computeFlyby } from './audio/flyby'\nimport type { FlybyInput, FlybyVoice } from './audio/flyby'\nimport type { CasingInput, CasingSound, CasingVoice } from './audio/casing-sound'\nimport type { Gunshot, GunshotInput, GunshotOptions, GunshotSpace, GunshotVoice } from './audio/gunshot'\nimport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\nimport { DEFAULT_SOUND_PROFILE, RELOAD_CUES, reloadCueSteps } from './audio/reload-sounds'\nimport { CUES_IN_SAMPLE, WEIGHT_INTENSITY, casingSampleId, weaponSampleBank } from './audio/samples'\nimport type { WeaponSampleOptions } from './audio/samples'\nimport type { SoundProfile } from './audio/reload-sounds'\nimport { computeShotSound, FALLBACK_SOUND_CLASS, GAME_DISTANCE_CURVE, GAME_SOUND_CLASSES } from './audio/shot-sound'\nimport type { ShotSound, ShotSoundInput, ShotSoundOptions, SoundClassDef } from './audio/shot-sound'\n\nexport { computeShotSound, GAME_SOUND_CLASSES, GAME_DISTANCE_CURVE, DEFAULT_ENERGY_CURVE, CLASS_REFERENCE_ENERGY } from './audio/shot-sound'\nexport type { ShotSound, ShotSoundInput, ShotSoundOptions, ShotSoundClass, SoundClassDef, DistanceCurve, EnergyCurve } from './audio/shot-sound'\nexport { computeGunshot, gunshotProfileOf, pickTake, energyOfGunshot, GUNSHOT_PROFILES, GUNSHOT_CALIBER_PROFILES, GUNSHOT_TAKES, SPEED_OF_SOUND } from './audio/gunshot'\nexport type { Gunshot, GunshotInput, GunshotOptions, GunshotProfile, GunshotProfileId, GunshotFarClass, GunshotSpace, GunshotGroup, GunshotVoice } from './audio/gunshot'\nexport { computeFlyby } from './audio/flyby'\nexport type { FlybyInput, FlybySound, FlybyVoice } from './audio/flyby'\nexport { computeCasingSound, casingSurfaceOf, casingKindOf } from './audio/casing-sound'\nexport type { CasingInput, CasingSound, CasingVoice, CasingSurface, CasingKind } from './audio/casing-sound'\nexport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nexport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\nexport { RELOAD_CUES, RELOAD_CUE_IDS, DEFAULT_SOUND_PROFILE, reloadCueSteps, soundProfileOf } from './audio/reload-sounds'\nexport type { ReloadCueId, SoundProfile } from './audio/reload-sounds'\nexport { CASING_SAMPLE, casingSampleId, CUES_IN_SAMPLE, GUNSHOT_SAMPLE, GUNSHOT_SAMPLE_IDS, RELOAD_SAMPLE, RELOAD_SAMPLE_HITS, WEIGHT_INTENSITY, weaponSampleBank, weaponSampleDefaults } from './audio/samples'\nexport type { WeaponSampleOptions } from './audio/samples'\n\n/** What a reload cue played: its recording, nothing (another cue's recording carries it), or the synthesized steps. */\nexport type CuePlayed = 'sample' | 'carried' | 'synth'\n\n/** What sounded for a shot: the recorded takes (`sample`, with the take of each layer) or the synthesized layers (`synth`). */\nexport type GunshotPlayed = { readonly kind: 'synth' } | { readonly kind: 'sample'; readonly id: string; readonly layers: readonly { readonly role: string; readonly take: number; readonly rate: number }[] }\n\n/** What a shot adds to the energy and the category: where the listener is and how the weapon is set. */\nexport type ShotExtras = Pick<ShotSoundInput, 'caliber' | 'distance' | 'volume' | 'suppressed' | 'indoors'> & {\n /** Where the shot is, for the stereo side (the engine's listener is the other end). Left out, the shot is in front (the player's own weapon). */\n readonly position?: readonly [number, number, number]\n /** 0..1, a wall between the shot and the listener (the host's occlusion test): quieter and duller. */\n readonly occlusion?: number\n /** Open field or a room; `indoors: true` means `'indoor'`. Default outdoor. */\n readonly space?: GunshotSpace\n}\n\n/** `gunshot` (default): the layered shot of `computeGunshot`. `game`: the game's single class burst (`computeShotSound`), kept for the golden traces. */\nexport type ShotModel = 'gunshot' | 'game'\n\nexport interface WeaponAudioOptions extends ShotSoundOptions {\n /** How a shot is built; default `gunshot`. */\n readonly shotModel?: ShotModel\n /** Tunes the layered gunshot (profiles, calibre links, distance law). */\n readonly gunshot?: GunshotOptions\n /** Pitch spread of a shot, ± this fraction (default 0.04, C5). */\n readonly pitchSpread?: number\n /** Told each gunshot played (profile, take, pitch, space, distance), so a host can log what sounded. */\n readonly onGunshot?: (shot: Gunshot, input: GunshotInput, played: GunshotPlayed) => void\n /** Told each case that lands (floor, case type, sample id). */\n readonly onCasing?: (sound: CasingSound, played: 'sample' | 'synth') => void\n /** Seed of the noise buffer, of the start point in it and of the casing pitch: same seed, same sound. Default 1. */\n readonly seed?: number\n /** Replaces or adds mechanical sounds by id. */\n readonly mechanical?: Readonly<Partial<Record<MechanicalSoundId, readonly SoundStep[]>>>\n /** Replaces or adds the sounds of the reload clip cues by id (`reload-sounds.json` has the ones the kit ships). */\n readonly reloadCues?: Readonly<Record<string, readonly SoundStep[]>>\n /** Where the AudioContext comes from (default: the global one); lets a host or a test lend its own. Not used with `engine`. */\n readonly createContext?: () => AudioContext\n /**\n * A sound engine the host already has (one shared engine mixes, limits and pans every module the same way). The weapon sounds are registered in it\n * and play on its `weapons` bus; `seed` gives them their own random stream, the master volume and the context stay the engine's. Without it the\n * weapon audio makes its own engine with the game mix, no voice limit, and the master at `volume`.\n */\n readonly engine?: AudioEngine\n /**\n * The recorded shots and reload steps (game-audio's `assets/sfx/manifest.json` and where its files are served). A shot of a profile with files\n * plays its takes, a reload cue the takes of the weapon's weight; until they are loaded, and for anything without files, the synthesized sound.\n */\n readonly samples?: WeaponSampleOptions\n}\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: the layered gunshot of its calibre (close, action, room or field, far) at its distance, or the game's class burst with `shotModel: 'game'`. */\n shot(energyJ: number, category: string, extras?: ShotExtras): void\n /** The parameters `shot` would play with the `game` model (pure). */\n shotSound(input: ShotSoundInput): ShotSound\n /** The voices `shot` plays with the `gunshot` model (pure; give `take` and `pitch` to fix them). */\n gunshot(input: GunshotInput): Gunshot\n /** Dry click of an empty weapon. */\n click(): void\n /** A mechanical sound by id: a reload stage, `dry_fire`, `jam`, `safety_on`... */\n mechanical(id: MechanicalSoundId): void\n /**\n * A cue of a reload clip (`mag_seat`, `charging_handle_pull`, `pump_back`...) for a weapon's profile (the weight of its metal and what it is made\n * of), where the clip says. `lead` is how early the clip started it (seconds before the part reaches its stop): a recording plays at once, its hit\n * that much later; the synthesized steps, whose hit is at their start, wait `lead`.\n */\n cue(id: string, profile?: SoundProfile, lead?: number): CuePlayed\n /** Loads the recorded files now (they load on the first sound otherwise, and the synthesized sound plays meanwhile). */\n loadSamples(): Promise<void>\n /** The mechanical sound of a weapon event, if it has one (reload stages, empty, misfire, fault, clear, safety, mode, feed). */\n event(event: WeaponEvent): void\n /** A sound class of the game by name (`impact`, `flesh`, `glass`...), with the game's distance muffling. */\n play(soundClass: string, volume?: number, distance?: number): void\n /** Magazine out, or the first shell in. */\n reloadStart(category: string): void\n /** Magazine seated and the action racked. */\n reloadEnd(category: string): void\n /** The pump or lever cycling after a shot. */\n cycle(): void\n /** A casing bouncing on the floor (the art scene's single ring; with the `gunshot` model, a pistol case on concrete). */\n clink(): void\n /** A case hitting the floor: its type (pistol, rifle, shell), the floor material, the speed and which bounce. */\n casing(input: CasingInput): void\n /** A bullet passing the listener (shot by someone else): crack when supersonic, whiz when not; `position` is where it passes, for the side. */\n flyby(input: FlybyInput & { readonly position?: readonly [number, number, number] }): void\n /** A magazine landing on the floor. */\n thud(): void\n /** Master volume, 0 to 1. */\n setVolume(volume: number): void\n dispose(): void\n}\n\nconst NOISE_SECONDS = 1.5\nconst DEFAULT_SEED = 1\n\ntype Tone = { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }\ntype Burst = { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }\n\nexport function createWeaponAudio(volume = 0.6, options: WeaponAudioOptions = {}): WeaponAudio {\n const seed = options.seed ?? DEFAULT_SEED\n const classes: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical }\n const cueTable = { ...RELOAD_CUES, ...options.reloadCues }\n const shared = options.engine\n if (!shared) warnOnce('game-weapons-three.own-audio-engine', 'game-weapons-three made an audio engine of its own because the host lent none (options.engine); pass the host engine so the sounds share one mix and one voice limit')\n // own engine: the game mix at the given volume, noise made with the chain, and no voice limit (these sounds are short and the old audio had none)\n const engine: AudioEngine =\n shared ??\n createAudioEngine({\n seed,\n mix: { ...MIX_PROFILES.game!, master: volume, noise: { seconds: NOISE_SECONDS, create: 'eager' } },\n maxVoices: Number.POSITIVE_INFINITY,\n ...(options.createContext ? { createContext: options.createContext } : {}),\n })\n // an own engine draws everything from its one stream (noise first, then the start points), as the old audio did; a shared one gets a stream per module\n const channel = shared && options.seed !== undefined ? shared.channel({ seed }) : engine.channel({})\n engine.register({ id: `weapons_three@${classBurstId(distanceCurve)}`, sounds: weaponRecipes(distanceCurve) })\n const classBurst = classBurstId(distanceCurve)\n\n // the recorded shots and reload steps: registered now, loaded on the first sound (or `loadSamples`), the synthesized sound until then\n const sampleBank = options.samples ? weaponSampleBank(options.samples) : null\n if (sampleBank) engine.register(sampleBank)\n const sampleIds = new Set((sampleBank?.samples ?? []).map((sample) => sample.id))\n let sampleLoad: Promise<void> | null = null\n const loadSamples = (): Promise<void> => (sampleLoad ??= sampleIds.size > 0 ? engine.loadSamples([...sampleIds]).then(() => undefined, () => undefined) : Promise.resolve())\n const sampleReady = (id: string): boolean => {\n if (!sampleIds.has(id)) return false\n if (engine.sampleStatus(id) === 'ready') return true\n void loadSamples()\n return false\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (config: Burst): void => {\n const id = config.filter === 'highpass' ? BURST_IDS.highpass : BURST_IDS.lowpass\n const params = { frequency: config.frequency, q: config.q ?? 0.8, gain: Math.max(config.gain, 0.0002), seconds: config.seconds }\n channel.play(id, { params, ...(config.at ? { delay: config.at } : {}) })\n }\n\n // the game `sfx`: lowpass noise, gain set at once and an exponential fall to 0.001 (jogo.js L62097-L62110)\n const classBurstAt = (at: number, cutoff: number, gain: number, seconds: number): void => {\n channel.play(classBurst, { params: { cutoff, gain, seconds }, ...(at ? { delay: at } : {}) })\n }\n\n const tone = (config: Tone): void => {\n const id = config.to ? TONE_IDS.sine_sweep : config.type === 'square' ? TONE_IDS.square : TONE_IDS.sine\n const params = { frequency: config.frequency, gain: Math.max(config.gain, 0.0002), seconds: config.seconds, ...(config.to ? { to: config.to } : {}) }\n channel.play(id, { params, ...(config.at ? { delay: config.at } : {}) })\n }\n\n const metal = (at: number, frequency: number, gain: number): void => {\n burst({ at, seconds: 0.05, gain, filter: 'highpass', frequency, q: 2 })\n tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: 'square' })\n }\n\n const play = (soundClass: string, classVolume = 1, distance = 0, at = 0): void => {\n const [cutoff, gain, seconds] = classes[soundClass] ?? FALLBACK_SOUND_CLASS\n // the distance goes through the engine's curve (gain / (1 + d² k), cutoff / (1 + d c), silent below minGain)\n channel.play(classBurst, { volume: classVolume, distance, params: { cutoff, gain, seconds }, ...(at ? { delay: at } : {}) })\n }\n\n // the art scene's sTone and sNoise, heard at the listener\n const sceneTone = (entry: Extract<SoundStep, { layer: 'scene_tone' }>): void => {\n channel.play(SCENE_TONE_IDS[entry.wave], { params: { f: entry.f, f2: entry.f2 ?? entry.f, d: entry.d, vol: entry.vol }, ...(entry.at ? { delay: entry.at } : {}) })\n }\n const sceneNoise = (entry: Extract<SoundStep, { layer: 'scene_noise' }>): void => {\n const slide = entry.f2 !== undefined\n const id = slide ? `${SCENE_NOISE_IDS[entry.type]}_slide` : SCENE_NOISE_IDS[entry.type]\n channel.play(id, { params: { f: entry.f, ...(slide ? { f2: entry.f2 } : {}), q: entry.q, d: entry.d, vol: entry.vol }, ...(entry.at ? { delay: entry.at } : {}) })\n }\n\n const step = (entry: SoundStep): void => {\n if (entry.layer === 'metal') metal(entry.at, entry.frequency, entry.gain)\n else if (entry.layer === 'scene_tone') sceneTone(entry)\n else if (entry.layer === 'scene_noise') sceneNoise(entry)\n else if (entry.layer === 'class') play(entry.soundClass, entry.volume, 0, entry.at)\n else burst({ at: entry.at, seconds: 0.09, gain: entry.gain, filter: 'lowpass', frequency: entry.frequency })\n }\n\n const mechanical = (id: MechanicalSoundId): void => {\n for (const entry of mechanicalTable[id] ?? []) step(entry)\n }\n\n const shotSound = (input: ShotSoundInput): ShotSound => computeShotSound(input, options)\n const gunshot = (input: GunshotInput): Gunshot => computeGunshot(input, options.gunshot)\n const playCasingVoice = (voice: CasingVoice | FlybyVoice, position?: readonly [number, number, number]): void => {\n const id = voice.kind === 'tone' ? GUNSHOT_IDS.tone : GUNSHOT_IDS[voice.filter ?? 'lowpass']\n const params: Record<string, number> = voice.kind === 'tone' ? { frequency: voice.frequency, to: voice.to ?? voice.frequency, gain: voice.gain, seconds: voice.seconds } : { frequency: voice.frequency, q: voice.q ?? 0.7, gain: voice.gain, seconds: voice.seconds }\n channel.play(id, { params, ...(position ? { position: [position[0], position[1], position[2]] as [number, number, number] } : {}) })\n }\n const casing = (input: CasingInput): void => {\n const sound = computeCasingSound({ ...input, pitch: input.pitch ?? 1 + (channel.random() * 2 - 1) * 0.06 })\n // a recording holds every bounce of the case: it plays on the first hit, and the later hits add nothing\n const recorded = sound.kind === 'shell' ? '' : casingSampleId(sound.sample)\n if (recorded && sampleReady(recorded)) {\n if ((input.bounce ?? 0) === 0) channel.play(recorded, { volume: Math.min(1, Math.max(0.2, (input.speed ?? 1.5) / 2.5)) })\n options.onCasing?.(sound, 'sample')\n return\n }\n for (const voice of sound.voices) playCasingVoice(voice)\n options.onCasing?.(sound, 'synth')\n }\n const lastTake = new Map<string, number>()\n const pitchSpread = options.pitchSpread ?? 0.04\n const playGunshotVoice = (voice: GunshotVoice, extras: ShotExtras): void => {\n const id = voice.kind === 'tone' ? GUNSHOT_IDS.tone : voice.wet ? GUNSHOT_IDS.lowpass_wet : GUNSHOT_IDS[voice.filter ?? 'lowpass']\n const params: Record<string, number> = voice.kind === 'tone' ? { frequency: voice.frequency, to: voice.to ?? voice.frequency, gain: voice.gain, seconds: voice.seconds } : { frequency: voice.frequency, q: voice.q ?? 0.7, gain: voice.gain, seconds: voice.seconds }\n channel.play(id, {\n params,\n ...(voice.at > 0 ? { delay: voice.at } : {}),\n ...(extras.position ? { position: [extras.position[0], extras.position[1], extras.position[2]] as [number, number, number] } : {}),\n })\n }\n\n return {\n shot(energyJ, category, extras = {}) {\n if (options.shotModel !== 'game') {\n const base: GunshotInput = { energyJ, category, ...extras, space: extras.space ?? (extras.indoors ? 'indoor' : 'outdoor') }\n const profile = computeGunshot(base, options.gunshot).profile\n const take = pickTake(lastTake.get(profile), channel.random)\n lastTake.set(profile, take)\n const pitch = 1 + (channel.random() * 2 - 1) * pitchSpread\n const shot = computeGunshot({ ...base, take, pitch }, options.gunshot)\n const recorded = shot.samples.close\n if (shot.audible && sampleReady(recorded)) {\n // the recording carries the crack, the body, the action and the field's echo; a room still adds its own tail\n const occlusion = Math.min(1, Math.max(0, extras.occlusion ?? 0))\n const handle = channel.play(recorded, {\n volume: (extras.volume ?? 1) * (1 - 0.5 * occlusion),\n environment: base.space === 'indoor' ? 'indoor' : 'outdoor',\n ...(extras.position ? { position: [extras.position[0], extras.position[1], extras.position[2]] as [number, number, number] } : {}),\n ...(extras.distance === undefined ? {} : { distance: extras.distance }),\n ...(shot.delay > 0 ? { delay: shot.delay } : {}),\n })\n if (base.space === 'indoor') for (const voice of shot.voices) if (voice.group === 'tail') playGunshotVoice(voice, extras)\n const layers = handle?.kind === 'sample' ? handle.plan.layers.map((layer) => ({ role: layer.role, take: layer.take, rate: layer.rate })) : []\n options.onGunshot?.(shot, { ...base, take, pitch }, { kind: 'sample', id: recorded, layers })\n return\n }\n for (const voice of shot.voices) playGunshotVoice(voice, extras)\n if (shot.audible) options.onGunshot?.(shot, { ...base, take, pitch }, { kind: 'synth' })\n return\n }\n const sound = shotSound({ ...extras, energyJ, category })\n if (!sound.audible) return\n classBurstAt(0, sound.cutoff, sound.gain, sound.duration)\n if (sound.crack.gain > 0) burst({ seconds: sound.crack.duration, gain: sound.crack.gain, filter: 'highpass', frequency: sound.crack.cutoff })\n tone({ seconds: sound.body.duration, gain: sound.body.gain, frequency: sound.body.frequency, to: sound.body.to })\n },\n shotSound,\n gunshot,\n click() {\n mechanical('dry_fire')\n },\n mechanical,\n cue(id, profile, lead = 0) {\n // a step the recording of another cue already carries (the release button, the magazine sliding in) stays silent\n const carriedBy = CUES_IN_SAMPLE[id]\n if (carriedBy && sampleReady(carriedBy)) return 'carried'\n if (sampleReady(id)) {\n channel.play(id, { intensity: WEIGHT_INTENSITY[(profile ?? DEFAULT_SOUND_PROFILE).weight] })\n return 'sample'\n }\n // the synthesized steps hit at their start: they wait the lead the clip gave the recording\n for (const entry of reloadCueSteps(id, profile, cueTable)) step(lead > 0 ? { ...entry, at: entry.at + lead } : entry)\n return 'synth'\n },\n loadSamples,\n event(event) {\n const id = mechanicalSoundOf(event)\n if (id) mechanical(id)\n },\n play(soundClass, classVolume, distance) {\n play(soundClass, classVolume, distance)\n },\n reloadStart(category) {\n metal(0, 1500, 0.35)\n if (category !== 'shotgun' && category !== 'revolver') metal(0.12, 900, 0.2)\n },\n reloadEnd(category) {\n metal(0, 1100, 0.45)\n if (category !== 'revolver') metal(0.18, 1900, 0.4)\n },\n cycle() {\n mechanical('cycle')\n },\n casing,\n flyby(input) {\n const sound = computeFlyby({ ...input, pitch: input.pitch ?? 1 + (channel.random() * 2 - 1) * 0.05 })\n for (const voice of sound?.voices ?? []) playCasingVoice(voice, input.position)\n },\n clink() {\n if (options.shotModel !== 'game') {\n casing({})\n return\n }\n // the art scene's `casing` (cena L1344): one ring at 4200-5700 Hz sliding to 3800, 0.25-0.45 s after the case leaves\n const f = 4200 + channel.random() * 1500\n const at = 0.25 + channel.random() * 0.2\n sceneTone({ layer: 'scene_tone', at, wave: 'sine', f, f2: 3800, d: 0.06, vol: 0.06 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n const level = Math.max(0, Math.min(1, next))\n // a shared engine keeps its master: the weapons bus takes the volume\n if (shared) shared.setBus('weapons', { gain: level })\n else engine.setMaster(level)\n },\n dispose() {\n if (!shared) engine.dispose()\n },\n }\n}\n","import type { ReloadStageId, WeaponEvent } from '@adatechnology/game-weapons'\n\nimport type { GAME_SOUND_CLASSES } from './shot-sound'\n\n/** One layer of a mechanical sound; `at` is seconds after the start. */\nexport type SoundStep =\n /** Metal click: a short high noise plus a square tone at 0.6 × the frequency (the SDK synth, as before). */\n | { readonly layer: 'metal'; readonly at: number; readonly frequency: number; readonly gain: number }\n /** A sound class of the game (`recarga`, `vazio`...) played at a volume. */\n | { readonly layer: 'class'; readonly at: number; readonly soundClass: keyof typeof GAME_SOUND_CLASSES; readonly volume: number }\n /** Dull landing: lowpass noise. */\n | { readonly layer: 'thud'; readonly at: number; readonly gain: number; readonly frequency: number }\n /** The art scene's `sTone` (cena L1324): a tone sliding from `f` to `f2` (default `f`) in `d` seconds, at `vol`, `at` seconds after the start. */\n | { readonly layer: 'scene_tone'; readonly at: number; readonly wave: 'sine' | 'square'; readonly f: number; readonly f2?: number; readonly d: number; readonly vol: number }\n /** The art scene's `sNoise` (cena L1323): filtered noise, the filter sliding to `f2` when given, `d` seconds, at `vol`. */\n | { readonly layer: 'scene_noise'; readonly at: number; readonly type: 'lowpass' | 'highpass' | 'bandpass'; readonly f: number; readonly f2?: number; readonly q: number; readonly d: number; readonly vol: number }\n\nexport type MechanicalSoundId =\n | ReloadStageId\n | 'dry_fire'\n | 'misfire'\n | 'feed'\n | 'cycle'\n | 'mode'\n | 'safety_on'\n | 'safety_off'\n | 'jam'\n | 'clear_start'\n | 'clear_end'\n | 'stock_fold'\n | 'light_click'\n | 'attach'\n\nconst metal = (at: number, frequency: number, gain: number): SoundStep => ({ layer: 'metal', at, frequency, gain })\nconst sound = (at: number, soundClass: keyof typeof GAME_SOUND_CLASSES, volume: number): SoundStep => ({ layer: 'class', at, soundClass, volume })\nconst thud = (at: number, gain: number, frequency: number): SoundStep => ({ layer: 'thud', at, gain, frequency })\n\n// The art scene's reload sounds (cena L1335-L1343). `click` is its primitive: a square tick sliding down 30 % and a short highpass noise at 0.8 of the volume.\nconst sceneClick = (at: number, f: number, vol: number): SoundStep[] => [\n { layer: 'scene_tone', at, wave: 'square', f, f2: f * 0.7, d: 0.02, vol },\n { layer: 'scene_noise', at, type: 'highpass', f: 3000, q: 0.7, d: 0.03, vol: vol * 0.8 },\n]\nconst sceneNoise = (at: number, type: 'bandpass', f: number, q: number, d: number, vol: number): SoundStep => ({ layer: 'scene_noise', at, type, f, q, d, vol })\n/** `sfx.empty` */\nconst sceneEmpty = sceneClick(0, 3200, 0.35)\n/** `sfx.magOut` */\nconst sceneMagOut = [...sceneClick(0, 1600, 0.4), sceneNoise(0.03, 'bandpass', 900, 2, 0.08, 0.3)]\n/** `sfx.magIn` */\nconst sceneMagIn = [...sceneClick(0, 1100, 0.5), { layer: 'scene_tone', at: 0, wave: 'sine', f: 320, f2: 200, d: 0.05, vol: 0.35 } as const]\n/** `sfx.bolt` */\nconst sceneBolt = [...sceneClick(0, 2200, 0.4), ...sceneClick(0.12, 2700, 0.4)]\n/** `sfx.shell` */\nconst sceneShell = [...sceneClick(0, 1400, 0.35), sceneNoise(0.02, 'bandpass', 1200, 3, 0.05, 0.25)]\n\nconst slide = [metal(0, 900, 0.35), metal(0.14, 1300, 0.35)]\nconst seat = [metal(0, 1100, 0.45), sound(0, 'reload', 0.8)]\n\n/**\n * Sounds keyed by the rule: the `reload_stage` ids of `RELOAD_STAGES`, plus the other weapon events. The click of an empty weapon and the generic\n * reload tick are the game's `vazio` and `recarga` classes (jogo.js L62101-L62104; played at L68644-L68662). The Cena de Arte delivered the reload sounds\n * (`empty` -> dry_fire, `magOut` -> magazine_out, `magIn` -> magazine_in, `bolt` -> charge, `shell` -> round_in; cena L1339-L1343), so those use them; the gallery\n * (sources/armas-itens__galeria-3d-arsenal.js) has no sound, and the other metal layers are the SDK synth (the same `metal` used since the first version).\n */\nexport const MECHANICAL_SOUNDS: Readonly<Record<MechanicalSoundId, readonly SoundStep[]>> = {\n dry_fire: [sound(0, 'empty', 1), ...sceneEmpty],\n misfire: [sound(0, 'empty', 0.8), metal(0, 2200, 0.2)],\n feed: [metal(0, 1900, 0.2)],\n cycle: [metal(0.22, 900, 0.35), metal(0.36, 1300, 0.35)],\n mode: [metal(0, 2000, 0.15)],\n safety_on: [metal(0, 2200, 0.22)],\n safety_off: [metal(0, 1800, 0.22)],\n jam: [metal(0, 700, 0.4), metal(0.08, 500, 0.35)],\n clear_start: [metal(0, 1000, 0.3)],\n clear_end: [metal(0, 1300, 0.35)],\n stock_fold: [metal(0, 800, 0.3), metal(0.18, 1200, 0.3), thud(0.3, 0.2, 600)],\n light_click: [metal(0, 2400, 0.2), metal(0.03, 1800, 0.12)],\n attach: [metal(0, 1400, 0.35), thud(0.04, 0.2, 700), metal(0.12, 1900, 0.25)],\n magazine_out: [...sceneMagOut, sound(0, 'reload', 0.6)],\n magazine_in: [...sceneMagIn, sound(0, 'reload', 0.8)],\n charge: sceneBolt,\n bolt_open: [metal(0, 900, 0.35)],\n round_in: [...sceneShell, sound(0, 'reload', 0.6)],\n bolt_close: [metal(0, 1300, 0.35)],\n pump_cycle: slide,\n lever_cycle: [metal(0, 1000, 0.35), metal(0.12, 1500, 0.35)],\n cylinder_open: [metal(0, 1500, 0.3)],\n cylinder_eject: [metal(0, 2400, 0.25), metal(0.05, 2800, 0.2)],\n cylinder_load: [metal(0, 2000, 0.2)],\n cylinder_close: seat,\n barrels_open: [metal(0, 1000, 0.4)],\n casings_eject: [metal(0, 2600, 0.25)],\n rounds_in: [metal(0, 2000, 0.25), sound(0, 'reload', 0.6)],\n barrels_close: seat,\n cover_open: [metal(0, 800, 0.4)],\n belt_swap: [metal(0, 1400, 0.3), metal(0.08, 1800, 0.25)],\n cover_close: [metal(0, 1000, 0.45)],\n tank_swap: [thud(0, 0.4, 500), metal(0.05, 600, 0.3)],\n tube_drop: [thud(0, 0.35, 380)],\n tube_seat: seat,\n rocket_seat: [metal(0, 900, 0.45), sound(0, 'reload', 0.8)],\n breech_open: [metal(0, 1000, 0.35)],\n breech_close: seat,\n}\n\n/** Which mechanical sound a weapon event asks for, if any (`shot`, `draw` and `reload` start/end have their own handling). */\nexport const mechanicalSoundOf = (event: WeaponEvent): MechanicalSoundId | undefined => {\n switch (event.type) {\n case 'reload_stage':\n return event.stage\n case 'empty':\n return 'dry_fire'\n case 'misfire':\n return 'misfire'\n case 'feed':\n return 'feed'\n case 'cycle':\n return event.phase === 'start' ? 'cycle' : undefined\n case 'mode':\n return 'mode'\n case 'safety':\n return event.on ? 'safety_on' : 'safety_off'\n case 'fault':\n return 'jam'\n case 'clear':\n return event.phase === 'start' ? 'clear_start' : 'clear_end'\n case 'attachment':\n return event.action === 'break' ? 'jam' : 'attach'\n case 'toggle':\n return 'light_click'\n case 'stock':\n return 'stock_fold'\n case 'underbarrel':\n return 'mode'\n default:\n return undefined\n }\n}\n","// The weapon sounds as recipes of @adatechnology/game-audio, in the `weapon` build order: a filtered noise burst or a tone, each with its own envelope\n// gain. These are the three primitives `createWeaponAudio` was written with (the game's class burst, a free burst and a tone); the numbers that change\n// from sound to sound (cutoff, gain, seconds, frequency) are named params the adapter fills in, so a sound class, a mechanical step or a shot are all data.\nimport { DISTANCE_CURVES } from '@adatechnology/game-audio'\nimport type { Layer, SoundRecipe } from '@adatechnology/game-audio'\n\nimport { GAME_DISTANCE_CURVE } from './shot-sound'\nimport type { DistanceCurve } from './shot-sound'\n\nexport const CLASS_BURST_ID = 'weapon_class_burst'\nexport const BURST_IDS = { lowpass: 'weapon_burst_lowpass', highpass: 'weapon_burst_highpass' } as const\nexport const SCENE_NOISE_IDS = { lowpass: 'scene_noise_lowpass', highpass: 'scene_noise_highpass', bandpass: 'scene_noise_bandpass' } as const\nexport const SCENE_TONE_IDS = { sine: 'scene_tone_sine', square: 'scene_tone_square' } as const\nexport const TONE_IDS = { sine: 'weapon_tone_sine', sine_sweep: 'weapon_tone_sine_sweep', square: 'weapon_tone_square' } as const\n\nconst SOURCE_CLASS_BURST = 'jogo:L62097-62110 sfx: lowpass noise, gain set at once, exponential fall to 0.001, stopped 0.05 s later'\nconst SOURCE_SDK = 'sdk: the weapon synth of weapons-three (burst and tone), moved onto game-audio with the same nodes'\nconst FIT = { kind: 'noise', offset: 'fit' } as const\n\n/** The id of the class burst for a distance curve: the game's keeps the plain id, another curve is named by its numbers so engines can be shared. */\nexport function classBurstId(curve: DistanceCurve): string {\n const same = curve.gainFalloff === GAME_DISTANCE_CURVE.gainFalloff && curve.cutoffFalloff === GAME_DISTANCE_CURVE.cutoffFalloff && curve.minGain === GAME_DISTANCE_CURVE.minGain\n return same ? CLASS_BURST_ID : `${CLASS_BURST_ID}@${curve.gainFalloff},${curve.cutoffFalloff},${curve.minGain}`\n}\n\n/** `classBurst`: params `cutoff`, `gain` and `seconds`; the level is `volume / (1 + d² × gainFalloff)` and the cutoff is divided by `1 + d × cutoffFalloff`. */\nexport function classBurstRecipe(curve: DistanceCurve): SoundRecipe {\n return {\n id: classBurstId(curve),\n bus: 'weapons',\n order: 'weapon',\n duration: { param: 'seconds' },\n layers: [\n {\n gain: { param: 'gain' },\n source: FIT,\n filters: { mode: 'serial', bank: [{ type: 'lowpass', frequency: { set: { param: 'cutoff' } } }] },\n envelope: [\n [0, 1, 'set'],\n ['1d', 0.001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: { model: 'inverse_square', k: curve.gainFalloff, cutoffK: curve.cutoffFalloff, minGain: curve.minGain },\n sources: [SOURCE_CLASS_BURST],\n }\n}\n\nconst burstLayer = (type: 'lowpass' | 'highpass'): Layer => ({\n gain: { param: 'gain' },\n source: FIT,\n filters: { mode: 'serial', bank: [{ type, frequency: { set: { param: 'frequency' } }, q: { param: 'q' } }] },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [0.004, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n})\n\n/** `burst`: params `frequency`, `q`, `gain` and `seconds`; no distance (the caller already folded it in). */\nexport const burstRecipe = (type: 'lowpass' | 'highpass'): SoundRecipe => ({\n id: BURST_IDS[type],\n bus: 'weapons',\n order: 'weapon',\n duration: { param: 'seconds' },\n layers: [burstLayer(type)],\n falloff: { model: 'none' },\n sources: [SOURCE_SDK],\n})\n\nconst toneLayer = (wave: OscillatorType, sweep: boolean): Layer => ({\n gain: { param: 'gain' },\n source: { kind: 'osc', wave, frequency: sweep ? { from: { param: 'frequency' }, to: { param: 'to' }, curve: 'exp', over: 'duration' } : { from: { param: 'frequency' } } },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [0.003, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n})\n\n/** `tone`: params `frequency`, `gain` and `seconds` (and `to` for the sweep). */\nexport const toneRecipe = (id: string, wave: OscillatorType, sweep: boolean): SoundRecipe => ({\n id,\n bus: 'weapons',\n order: 'weapon',\n duration: { param: 'seconds' },\n layers: [toneLayer(wave, sweep)],\n falloff: { model: 'none' },\n sources: [SOURCE_SDK],\n})\n\nconst SOURCE_SCENE = 'cena:L1323-L1324 sNoise and sTone, played at the listener (distance 0), through the art scene output stage'\nconst SCENE_ATTACK = 0.002\n\n/**\n * The art scene's `sNoise`: params `f`, `q`, `d` and `vol` (and `f2`, the filter sliding there over `d`); the noise starts at `random × 1.5` in the buffer, the\n * gain rises to 1 in 0.002 s and falls to 0.0001 over `d`, the source stops 0.05 s later.\n */\nexport const sceneNoiseRecipe = (type: 'lowpass' | 'highpass' | 'bandpass', slide: boolean): SoundRecipe => ({\n id: slide ? `${SCENE_NOISE_IDS[type]}_slide` : SCENE_NOISE_IDS[type],\n bus: 'weapons',\n order: 'layered',\n duration: { param: 'd', add: SCENE_ATTACK },\n pan: true,\n layers: [\n {\n gain: { param: 'vol' },\n source: { kind: 'noise', offset: 'random', offsetScale: 1.5, loop: true },\n filters: { mode: 'serial', bank: [{ type, frequency: slide ? { set: { param: 'f' }, to: { param: 'f2' }, curve: 'exp', over: { param: 'd' } } : { set: { param: 'f' } }, q: { param: 'q' } }] },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [SCENE_ATTACK, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.art_scene,\n sources: [SOURCE_SCENE],\n})\n\n/** The art scene's `sTone`: params `f`, `f2`, `d` and `vol`; the frequency is set at the start and ramps to `f2` as the gain falls. */\nexport const sceneToneRecipe = (wave: 'sine' | 'square'): SoundRecipe => ({\n id: SCENE_TONE_IDS[wave],\n bus: 'weapons',\n order: 'layered',\n duration: { param: 'd', add: SCENE_ATTACK },\n pan: true,\n layers: [\n {\n gain: { param: 'vol' },\n source: { kind: 'osc', wave, frequency: { from: { param: 'f' }, to: { param: 'f2' }, curve: 'exp', over: 'duration' } },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [SCENE_ATTACK, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.art_scene,\n sources: [SOURCE_SCENE],\n})\n\nexport const GUNSHOT_IDS = {\n lowpass: 'gunshot_noise_lowpass',\n highpass: 'gunshot_noise_highpass',\n bandpass: 'gunshot_noise_bandpass',\n lowpass_wet: 'gunshot_noise_lowpass_wet',\n tone: 'gunshot_tone',\n} as const\nconst SOURCE_GUNSHOT = 'sdk: the layered gunshot (audio/gunshot.ts): a 1 ms attack so the peak lands on the shot (C1), panned from the shooter, the room tail sent to the reverb'\nconst GUNSHOT_ATTACK = 0.001\n\n/** A gunshot layer of noise: params `frequency`, `q`, `gain` and `seconds`; the level and distance are already in `gain`, so there is no falloff here. */\nexport const gunshotNoiseRecipe = (type: 'lowpass' | 'highpass' | 'bandpass', wet: boolean): SoundRecipe => ({\n id: wet ? GUNSHOT_IDS.lowpass_wet : GUNSHOT_IDS[type],\n bus: 'weapons',\n order: 'layered',\n duration: { param: 'seconds', add: GUNSHOT_ATTACK },\n pan: true,\n layers: [\n {\n gain: { param: 'gain' },\n ...(wet ? { wet: 1 } : {}),\n source: { kind: 'noise', offset: 'random', offsetScale: 1.2, loop: true },\n filters: { mode: 'serial', bank: [{ type, frequency: { set: { param: 'frequency' } }, q: { param: 'q' } }] },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [GUNSHOT_ATTACK, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: { model: 'none' },\n sources: [SOURCE_GUNSHOT],\n})\n\n/** A gunshot tone: params `frequency`, `to`, `gain` and `seconds` (the body sweeping down). */\nexport const gunshotToneRecipe = (): SoundRecipe => ({\n id: GUNSHOT_IDS.tone,\n bus: 'weapons',\n order: 'layered',\n duration: { param: 'seconds', add: GUNSHOT_ATTACK },\n pan: true,\n layers: [\n {\n gain: { param: 'gain' },\n source: { kind: 'osc', wave: 'sine', frequency: { from: { param: 'frequency' }, to: { param: 'to' }, curve: 'exp', over: 'duration' } },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [GUNSHOT_ATTACK, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: { model: 'none' },\n sources: [SOURCE_GUNSHOT],\n})\n\n/** The recipes of an adapter: the three primitives, with the class burst on the given distance curve. */\nexport function weaponRecipes(curve: DistanceCurve): SoundRecipe[] {\n return [\n classBurstRecipe(curve),\n burstRecipe('lowpass'),\n burstRecipe('highpass'),\n toneRecipe(TONE_IDS.sine, 'sine', false),\n toneRecipe(TONE_IDS.sine_sweep, 'sine', true),\n toneRecipe(TONE_IDS.square, 'square', false),\n ...(['lowpass', 'highpass', 'bandpass'] as const).flatMap((type) => [sceneNoiseRecipe(type, false), sceneNoiseRecipe(type, true)]),\n sceneToneRecipe('sine'),\n sceneToneRecipe('square'),\n gunshotNoiseRecipe('lowpass', false),\n gunshotNoiseRecipe('highpass', false),\n gunshotNoiseRecipe('bandpass', false),\n gunshotNoiseRecipe('lowpass', true),\n gunshotToneRecipe(),\n ]\n}\n","import { muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { CaliberDef } from '@adatechnology/game-weapons'\n\n/** One sound of the game: [lowpass cutoff Hz, gain, seconds]. Literal from the `P` table of `sfx` in the game (jogo.js L62101-L62104). */\nexport type SoundClassDef = readonly [cutoff: number, gain: number, seconds: number]\n\n/** The game names are pistola, escopeta, fuzil, rifle, impacto, carne, passo, vidro, madeira, recarga, vazio and explosao. */\nexport const GAME_SOUND_CLASSES = {\n pistol: [1800, 0.9, 0.18],\n shotgun: [900, 1.2, 0.35],\n rifle: [1400, 1.1, 0.28],\n long_rifle: [1100, 1.3, 0.45],\n impact: [2500, 0.25, 0.05],\n flesh: [600, 0.35, 0.08],\n step: [400, 0.08, 0.05],\n glass: [5000, 0.5, 0.3],\n wood: [700, 0.5, 0.2],\n reload: [3000, 0.15, 0.06],\n empty: [4000, 0.12, 0.03],\n explosion: [200, 1.6, 1.4],\n} as const satisfies Record<string, SoundClassDef>\n\n/** `|| [1000, 0.5, 0.1]` of the game (jogo.js L62104), for a class name that is not in the table. */\nexport const FALLBACK_SOUND_CLASS: SoundClassDef = [1000, 0.5, 0.1]\n\n/** The four classes a shot can have: the game picks one by calibre (jogo.js L68697). */\nexport type ShotSoundClass = 'pistol' | 'shotgun' | 'rifle' | 'long_rifle'\n\n/** Distance muffling of the game (jogo.js L62092, L62105): `gain / (1 + d² × gainFalloff)`, `cutoff / (1 + d × cutoffFalloff)`, silent under `minGain`. */\nexport type DistanceCurve = { readonly gainFalloff: number; readonly cutoffFalloff: number; readonly minGain: number }\nexport const GAME_DISTANCE_CURVE: DistanceCurve = { gainFalloff: 0.004, cutoffFalloff: 0.01, minGain: 0.01 }\n\n/**\n * The calibre energy (joules) scales loudness, length and brightness around the class: each factor is `base + span × k`, where k goes from 0 (50 J)\n * to 1 (50 J × 10^spanDecades) on a log scale, divided by the same factor at the class reference energy. So the game calibres sound exactly as in\n * the game, and a lighter or heavier calibre of the same class is quieter and brighter, or louder and duller.\n */\nexport type EnergyCurve = {\n readonly floorJ: number\n readonly spanDecades: number\n readonly gain: readonly [base: number, span: number]\n readonly duration: readonly [base: number, span: number]\n readonly cutoff: readonly [base: number, span: number]\n /** The muzzle crack (high noise) and the body (low thump) follow the energy alone. */\n readonly crackGain: readonly [base: number, span: number]\n readonly bodyGain: readonly [base: number, span: number]\n readonly bodyDuration: readonly [base: number, span: number]\n readonly bodyFrequency: readonly [base: number, span: number]\n}\n\nexport const DEFAULT_ENERGY_CURVE: EnergyCurve = {\n floorJ: 50,\n spanDecades: 2.5,\n gain: [0.7, 0.6],\n duration: [0.75, 0.5],\n cutoff: [1.15, -0.3],\n crackGain: [0.3, 0.4],\n bodyGain: [0.35, 0.4],\n bodyDuration: [0.14, 0.2],\n bodyFrequency: [140, -70],\n}\n\n/** Muzzle energy of the game calibres in the SDK (9x19, 12ga_00buck × pellets, 7_62x39, 7_62x51): where a class sounds exactly as in the game. */\nexport const CLASS_REFERENCE_ENERGY: Readonly<Record<ShotSoundClass, number>> = { pistol: 500, shotgun: 2700, rifle: 2100, long_rifle: 3500 }\n\nexport type ShotSoundOptions = {\n /** Replaces or adds sound classes (the game table is the default). */\n readonly classes?: Readonly<Record<string, SoundClassDef>>\n readonly distance?: Partial<DistanceCurve>\n readonly energy?: Partial<EnergyCurve>\n readonly referenceEnergy?: Partial<Record<ShotSoundClass, number>>\n /** Picks the class of a shot; the default follows the game (shotgun by shell, handguns by category, then by energy). */\n readonly classOf?: (input: ShotSoundInput, energyJ: number) => ShotSoundClass\n /** Class bands by energy (J): below `handgunBelowJ` a pistol, below `rifleBelowJ` a rifle, above that a long rifle. */\n readonly bands?: { readonly handgunBelowJ: number; readonly rifleBelowJ: number }\n readonly suppressor?: { readonly gain: number; readonly cutoff: number; readonly crack: number; readonly body: number }\n readonly indoors?: { readonly duration: number; readonly cutoff: number }\n}\n\nexport type ShotSoundInput = {\n /** The calibre; its energy (× pellets) is used unless `energyJ` is given. */\n readonly caliber?: CaliberDef\n readonly energyJ?: number\n readonly category?: string\n /** Metres from the listener, default 0. */\n readonly distance?: number\n /** Master gain of the game `sfx` (its `vol`), default 1. */\n readonly volume?: number\n readonly suppressed?: boolean\n readonly indoors?: boolean\n}\n\nexport type ShotSound = {\n readonly soundClass: ShotSoundClass\n readonly energyJ: number\n /** False when the shot is under the game's `minGain` at this distance: nothing is played. */\n readonly audible: boolean\n /** The main noise burst: lowpass cutoff Hz, starting gain and the seconds of the exponential tail (to 0.001). */\n readonly cutoff: number\n readonly gain: number\n readonly duration: number\n /** High noise burst of the muzzle. */\n readonly crack: { readonly gain: number; readonly cutoff: number; readonly duration: number }\n /** Low thump that sweeps from `frequency` to `to`. */\n readonly body: { readonly gain: number; readonly frequency: number; readonly to: number; readonly duration: number }\n}\n\nconst HANDGUN_CATEGORIES: ReadonlySet<string> = new Set(['pistol', 'revolver', 'smg'])\nconst SHELL_KINDS: ReadonlySet<string> = new Set(['buck', 'slug', 'birdshot'])\nconst DEFAULT_BANDS = { handgunBelowJ: 1000, rifleBelowJ: 3000 }\nconst DEFAULT_SUPPRESSOR = { gain: 0.3, cutoff: 0.6, crack: 0, body: 0.5 }\nconst DEFAULT_INDOORS = { duration: 1.5, cutoff: 0.85 }\nconst CRACK_CUTOFF = 3000\nconst CRACK_SECONDS = 0.03\nconst BODY_TO_FREQUENCY = 40\n\nconst linear = ([base, span]: readonly [number, number], k: number): number => base + span * k\n\nconst energyPosition = (energyJ: number, curve: EnergyCurve): number =>\n Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, curve.floorJ) / curve.floorJ) / curve.spanDecades))\n\nexport const energyOfShot = (input: ShotSoundInput): number => {\n if (input.energyJ !== undefined) return input.energyJ\n if (!input.caliber) return 0\n return muzzleEnergy(input.caliber) * (input.caliber.pellets ?? 1)\n}\n\nconst defaultClassOf = (input: ShotSoundInput, energyJ: number, bands: { handgunBelowJ: number; rifleBelowJ: number }): ShotSoundClass => {\n if (input.category === 'shotgun' || (input.caliber?.pellets ?? 1) > 1 || SHELL_KINDS.has(input.caliber?.kind ?? '')) return 'shotgun'\n if (input.category && HANDGUN_CATEGORIES.has(input.category)) return 'pistol'\n if (energyJ < bands.handgunBelowJ) return 'pistol'\n return energyJ < bands.rifleBelowJ ? 'rifle' : 'long_rifle'\n}\n\n/**\n * The parameters of a gunshot, without WebAudio: the sound class and the distance muffling of the game (S2) with the calibre energy of the SDK.\n * Pure and deterministic; the playback layer only turns it into nodes.\n */\nexport const computeShotSound = (input: ShotSoundInput, options: ShotSoundOptions = {}): ShotSound => {\n const curve: EnergyCurve = { ...DEFAULT_ENERGY_CURVE, ...options.energy }\n const distanceCurve: DistanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const energyJ = energyOfShot(input)\n const soundClass = options.classOf ? options.classOf(input, energyJ) : defaultClassOf(input, energyJ, options.bands ?? DEFAULT_BANDS)\n const table: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const [classCutoff, classGain, classSeconds] = table[soundClass] ?? FALLBACK_SOUND_CLASS\n const referenceEnergy = options.referenceEnergy?.[soundClass] ?? CLASS_REFERENCE_ENERGY[soundClass] ?? energyJ\n\n const k = energyPosition(energyJ, curve)\n const referenceK = energyPosition(referenceEnergy, curve)\n const distance = Math.max(0, input.distance ?? 0)\n const attenuation = (input.volume ?? 1) / (1 + distance * distance * distanceCurve.gainFalloff)\n const muffling = 1 / (1 + distance * distanceCurve.cutoffFalloff)\n\n const suppressor = input.suppressed ? { ...DEFAULT_SUPPRESSOR, ...options.suppressor } : { gain: 1, cutoff: 1, crack: 1, body: 1 }\n const indoors = input.indoors ? { ...DEFAULT_INDOORS, ...options.indoors } : { duration: 1, cutoff: 1 }\n\n const gain = classGain * attenuation * (linear(curve.gain, k) / linear(curve.gain, referenceK)) * suppressor.gain\n const duration = classSeconds * (linear(curve.duration, k) / linear(curve.duration, referenceK)) * indoors.duration\n const cutoff = classCutoff * muffling * (linear(curve.cutoff, k) / linear(curve.cutoff, referenceK)) * suppressor.cutoff * indoors.cutoff\n\n return {\n soundClass,\n energyJ,\n audible: attenuation >= distanceCurve.minGain,\n cutoff,\n gain,\n duration,\n crack: { gain: linear(curve.crackGain, k) * attenuation * suppressor.crack, cutoff: CRACK_CUTOFF, duration: CRACK_SECONDS },\n body: {\n gain: linear(curve.bodyGain, k) * attenuation * suppressor.body,\n frequency: linear(curve.bodyFrequency, k),\n to: BODY_TO_FREQUENCY,\n duration: linear(curve.bodyDuration, k) * indoors.duration,\n },\n }\n}\n","// A gunshot as the ear gets it: the close sound (crack, blast and body), the action, the space answering (a room or the open field) and, past ~50 m,\n// the far boom that replaces the close one. Pure and deterministic: the adapter turns the voices into game-audio plays, and each group has the sample\n// id of checklist-sons.md 5.1, so a recorded file replaces a group with no change here.\nimport type { CaliberDef } from '@adatechnology/game-weapons'\nimport { muzzleEnergy } from '@adatechnology/game-weapons'\n\nimport data from '../data/gunshot-profiles.json'\n\nexport type GunshotProfileId = keyof typeof data.profiles\nexport type GunshotFarClass = 'pistol' | 'rifle' | 'shotgun' | 'heavy'\n\ntype Noise = { readonly cutoff: number; readonly gain: number; readonly seconds: number }\nexport interface GunshotProfile {\n /** Muzzle energy (J) the numbers are written for: a lighter or heavier calibre of the family is scaled from it. */\n readonly referenceJ: number\n readonly far: GunshotFarClass\n /** Supersonic N-wave or muzzle snap: highpass noise. */\n readonly crack: { readonly frequency: number; readonly gain: number; readonly seconds: number }\n /** The mid \"slap\" of the muzzle blast: lowpass noise. */\n readonly blast: Noise\n /** The low thump: a sine sweeping `from` → `to`. */\n readonly body: { readonly from: number; readonly to: number; readonly gain: number; readonly seconds: number }\n readonly far_layer: Noise\n readonly tail_out: Noise\n readonly tail_in: Noise\n}\n\nexport const GUNSHOT_PROFILES: Readonly<Record<GunshotProfileId, GunshotProfile>> = data.profiles as Record<GunshotProfileId, GunshotProfile>\nexport const GUNSHOT_CALIBER_PROFILES: Readonly<Record<string, GunshotProfileId>> = data.calibers as Record<string, GunshotProfileId>\n\n/** Speed of sound in air at 20 °C, m/s: a shot 200 m away is heard 0.58 s after the flash. */\nexport const SPEED_OF_SOUND = 343\n/** Takes per shot (C5: at least 4 variations, never the same twice in a row). */\nexport const GUNSHOT_TAKES = 4\n\nexport type GunshotSpace = 'outdoor' | 'indoor'\nexport type GunshotGroup = 'close' | 'mech' | 'tail' | 'far'\n\nexport interface GunshotInput {\n readonly caliber?: CaliberDef\n /** Muzzle energy (J), for a shot with no calibre; the calibre's energy (× pellets) otherwise. */\n readonly energyJ?: number\n readonly category?: string\n /** Metres from the listener, default 0 (the player's own weapon). */\n readonly distance?: number\n readonly suppressed?: boolean\n readonly space?: GunshotSpace\n /** 0..n−1: which take (`pickTake` gives one that is not the last). */\n readonly take?: number\n /** Pitch factor of this shot, around 1 (the adapter draws ±4 %). */\n readonly pitch?: number\n /** Master level, default 1. */\n readonly volume?: number\n /** 0..1, a wall between the shot and the listener: −6 dB and the lowpass cutoffs at 40 % when fully behind it (as game-audio's occlusion). */\n readonly occlusion?: number\n}\n\nexport interface GunshotOptions {\n /** Replaces or adds profiles. */\n readonly profiles?: Readonly<Partial<Record<string, GunshotProfile>>>\n /** Replaces or adds calibre → profile links. */\n readonly calibers?: Readonly<Record<string, string>>\n /** Level law `(reference / d)^exponent` beyond `reference` metres (default 4 m, 0.8: a little gentler than the 6 dB per doubling of the free field, as games do). */\n readonly reference?: number\n readonly exponent?: number\n /** Below this the shot is not played (default 0.004, −48 dB). */\n readonly minGain?: number\n /** The close sound fades to the far one between these distances, metres (default 25 and 80). */\n readonly farFrom?: number\n readonly farTo?: number\n}\n\nexport interface GunshotVoice {\n readonly group: GunshotGroup\n /** Which part of the group: `crack`, `blast`, `body`, `action`, `tail`, `echo`, `reflection`, `boom`. */\n readonly part: string\n /** Seconds after the trigger (the arrival delay included). */\n readonly at: number\n readonly kind: 'noise' | 'tone'\n readonly filter?: 'lowpass' | 'highpass' | 'bandpass'\n /** Filter frequency (noise) or start frequency (tone). */\n readonly frequency: number\n /** Tone end frequency. */\n readonly to?: number\n readonly q?: number\n readonly gain: number\n readonly seconds: number\n /** Send to the reverb (a room). */\n readonly wet?: number\n}\n\nexport interface Gunshot {\n readonly profile: string\n readonly energyJ: number\n readonly supersonic: boolean\n readonly take: number\n readonly pitch: number\n /** Distance / speed of sound. */\n readonly delay: number\n /** 1 = all close, 0 = all far. */\n readonly closeMix: number\n readonly audible: boolean\n /** The sample ids each group can be replaced by (checklist 5.1). */\n readonly samples: Readonly<Record<GunshotGroup, string>>\n readonly voices: readonly GunshotVoice[]\n}\n\nconst SHELL_KINDS: ReadonlySet<string> = new Set(['buck', 'slug', 'birdshot'])\nconst TAKE_JITTER = [\n { cutoff: 1, seconds: 1, body: 1 },\n { cutoff: 0.93, seconds: 1.08, body: 1.04 },\n { cutoff: 1.07, seconds: 0.92, body: 0.96 },\n { cutoff: 0.97, seconds: 1.04, body: 1.02 },\n] as const\n/** A bullet faster than this drags its own crack along (the N-wave); slower ones only have the muzzle snap. */\nconst SUPERSONIC_MS = 360\n\nconst clamp01 = (x: number): number => Math.min(1, Math.max(0, x))\nconst smoothstep = (x: number): number => {\n const t = clamp01(x)\n return t * t * (3 - 2 * t)\n}\n\nexport const energyOfGunshot = (input: Pick<GunshotInput, 'caliber' | 'energyJ'>): number => {\n if (input.energyJ !== undefined) return input.energyJ\n if (!input.caliber) return 0\n return muzzleEnergy(input.caliber) * (input.caliber.pellets ?? 1)\n}\n\n/** The profile of a shot: by calibre (the data's table), then a shotgun by shell, then by energy. */\nexport const gunshotProfileOf = (input: Pick<GunshotInput, 'caliber' | 'energyJ' | 'category'>, options: GunshotOptions = {}): string => {\n const table = { ...GUNSHOT_CALIBER_PROFILES, ...options.calibers }\n const byCaliber = input.caliber ? table[input.caliber.id] : undefined\n if (byCaliber) return byCaliber\n if (input.category === 'shotgun' || SHELL_KINDS.has(input.caliber?.kind ?? '')) return 'shotgun_12'\n const energy = energyOfGunshot(input)\n if (input.category === 'pistol' || input.category === 'revolver' || input.category === 'smg') return energy < 300 ? 'pistol_22lr' : energy < 700 ? 'pistol_9mm' : 'revolver_44_50ae'\n if (energy < 300) return 'pistol_22lr'\n if (energy < 1000) return 'pistol_9mm'\n if (energy < 2000) return 'rifle_5_56'\n if (energy < 3000) return 'rifle_7_62x39'\n if (energy < 5000) return 'rifle_308_3006'\n return energy < 12000 ? 'sniper_338_300wm' : 'antimateriel_50bmg'\n}\n\n/** A take that is not `last` (C5): `random` in [0, 1). */\nexport const pickTake = (last: number | undefined, random: () => number, takes = GUNSHOT_TAKES): number => {\n if (takes <= 1) return 0\n if (last === undefined) return Math.floor(random() * takes) % takes\n const next = Math.floor(random() * (takes - 1)) % (takes - 1)\n return next >= last ? next + 1 : next\n}\n\n/**\n * The voices of one gunshot. Distance: every layer arrives `d / 343` s late; the level falls as `(reference / d)^exponent`, the highs go first (the\n * crack fades over ~60 m, lowpass cutoffs fall with `1 + d / 250`) and the close sound fades into the far boom between `farFrom` and `farTo`. Space:\n * outdoors the field answers with two late echoes and a long low tail; indoors the room answers at once (early reflections and a dense, short tail\n * sent to the reverb). A suppressor takes the blast and the body down and leaves the action and a supersonic crack.\n */\nexport function computeGunshot(input: GunshotInput, options: GunshotOptions = {}): Gunshot {\n const profileId = gunshotProfileOf(input, options)\n const profiles = { ...GUNSHOT_PROFILES, ...options.profiles } as Record<string, GunshotProfile | undefined>\n const profile = profiles[profileId] ?? GUNSHOT_PROFILES.pistol_9mm\n const energyJ = energyOfGunshot(input) || profile.referenceJ\n const take = Math.max(0, Math.floor(input.take ?? 0)) % GUNSHOT_TAKES\n const jitter = TAKE_JITTER[take] ?? TAKE_JITTER[0]\n const pitch = input.pitch ?? 1\n const distance = Math.max(0, input.distance ?? 0)\n const reference = options.reference ?? 4\n const exponent = options.exponent ?? 0.8\n const level = (input.volume ?? 1) * Math.pow(reference / Math.max(distance, reference), exponent) * (1 - 0.5 * clamp01(input.occlusion ?? 0))\n const delay = distance / SPEED_OF_SOUND\n const closeMix = 1 - smoothstep((distance - (options.farFrom ?? 25)) / ((options.farTo ?? 80) - (options.farFrom ?? 25)))\n const occlusion = clamp01(input.occlusion ?? 0)\n const air = (1 - 0.6 * occlusion) / (1 + distance / 250)\n const highs = Math.exp(-distance / 60) * (1 - 0.8 * occlusion)\n const space: GunshotSpace = input.space ?? 'outdoor'\n const supersonic = (input.caliber?.muzzleSpeed ?? 0) > SUPERSONIC_MS\n const shell = input.caliber?.kind === 'slug' ? data.shells.slug : input.caliber?.kind === 'birdshot' ? data.shells.birdshot : undefined\n const sup = data.suppressor\n const suppressed = input.suppressed === true\n // a heavier load of the family is louder, longer and a little lower\n const ratio = energyJ / profile.referenceJ\n const loud = Math.pow(ratio, 0.15)\n const longer = Math.pow(ratio, 0.1)\n const lower = Math.pow(ratio, -0.05) * pitch\n const farClass = profile.far\n const samples: Record<GunshotGroup, string> = {\n close: suppressed ? (farClass === 'pistol' ? 'suppressed_pistol' : 'suppressed_rifle') : profileId,\n mech: `mech_${input.category ?? 'rifle'}`,\n tail: space === 'indoor' ? 'gunshot_tail_indoor' : 'gunshot_tail_outdoor',\n far: `gunshot_far_${farClass}`,\n }\n\n const voices: GunshotVoice[] = []\n const push = (voice: GunshotVoice): void => {\n if (voice.gain > 0.0005) voices.push(voice)\n }\n const near = level * closeMix\n if (near > 0) {\n const crackGain = profile.crack.gain * (shell && 'crackGain' in shell ? shell.crackGain : 1) * (suppressed ? (supersonic ? sup.supersonicCrack : sup.subsonicCrack) : 1)\n push({ group: 'close', part: 'crack', at: delay, kind: 'noise', filter: 'highpass', frequency: profile.crack.frequency * lower, q: 0.7, gain: crackGain * near * highs * loud, seconds: profile.crack.seconds })\n const blastGain = profile.blast.gain * (shell && 'blastGain' in shell ? shell.blastGain : 1) * (suppressed ? sup.blastGain : 1)\n const blastSeconds = profile.blast.seconds * jitter.seconds * longer * (shell && 'blastSeconds' in shell ? shell.blastSeconds : 1)\n push({ group: 'close', part: 'blast', at: delay, kind: 'noise', filter: 'lowpass', frequency: profile.blast.cutoff * jitter.cutoff * lower * air * (suppressed ? sup.blastCutoff : 1), q: 0.8, gain: blastGain * near * loud, seconds: blastSeconds })\n const bodyGain = profile.body.gain * (shell && 'bodyGain' in shell ? shell.bodyGain : 1) * (suppressed ? sup.bodyGain : 1)\n push({ group: 'close', part: 'body', at: delay, kind: 'tone', frequency: profile.body.from * jitter.body * lower, to: profile.body.to * lower, gain: bodyGain * near * loud, seconds: profile.body.seconds * jitter.seconds * longer })\n const mech = (data.mech as unknown as Record<string, { at: number; frequency: number; gain: number } | undefined>)[input.category ?? '']\n // the action is only heard close (it is ~40 dB under the blast)\n if (mech && mech.gain > 0 && distance < 15) push({ group: 'mech', part: 'action', at: delay + mech.at, kind: 'noise', filter: 'bandpass', frequency: mech.frequency * pitch, q: 3, gain: mech.gain * (suppressed ? sup.mechGain : 1) * near, seconds: 0.05 })\n }\n const far = level * (1 - closeMix)\n if (far > 0) {\n const f = profile.far_layer\n const g = f.gain * (suppressed ? sup.farGain : 1) * loud * far\n push({ group: 'far', part: 'boom', at: delay, kind: 'noise', filter: 'lowpass', frequency: f.cutoff * jitter.cutoff * lower * air, q: 0.7, gain: g, seconds: f.seconds * jitter.seconds * longer })\n push({ group: 'far', part: 'body', at: delay, kind: 'tone', frequency: profile.body.to * 1.6 * lower, to: profile.body.to * lower, gain: g * 0.6, seconds: f.seconds * 0.8 })\n }\n // the space: the tail falls slower with distance than the direct sound (far away, the reverberant field is most of what is heard)\n const tailLevel = (input.volume ?? 1) * Math.pow(Math.max(level / (input.volume ?? 1), 1e-6), 0.6) * (suppressed ? sup.tailGain : 1) * loud\n if (space === 'indoor') {\n const t = profile.tail_in\n for (const [at, gain] of data.space.indoorReflections as [number, number][]) {\n push({ group: 'tail', part: 'reflection', at: delay + at, kind: 'noise', filter: 'lowpass', frequency: profile.blast.cutoff * lower * air, q: 0.7, gain: profile.blast.gain * gain * level * (suppressed ? sup.blastGain : 1), seconds: profile.blast.seconds * 0.7 })\n }\n push({ group: 'tail', part: 'tail', at: delay + 0.004, kind: 'noise', filter: 'lowpass', frequency: t.cutoff * lower * air, q: 0.6, gain: t.gain * tailLevel, seconds: t.seconds * longer, wet: data.space.indoorWet })\n } else {\n const t = profile.tail_out\n push({ group: 'tail', part: 'tail', at: delay + 0.03, kind: 'noise', filter: 'lowpass', frequency: t.cutoff * lower * air, q: 0.6, gain: t.gain * tailLevel, seconds: t.seconds * longer })\n for (const [at, gain] of data.space.outdoorEchoes as [number, number][]) {\n push({ group: 'tail', part: 'echo', at: delay + at, kind: 'noise', filter: 'lowpass', frequency: profile.far_layer.cutoff * lower * air, q: 0.7, gain: profile.far_layer.gain * gain * tailLevel, seconds: profile.far_layer.seconds })\n }\n }\n const minGain = options.minGain ?? 0.004\n const audible = voices.some((voice) => voice.gain >= minGain)\n return { profile: profileId, energyJ, supersonic, take, pitch, delay, closeMix, audible, samples, voices: audible ? voices : [] }\n}\n","{\n \"$comment\": \"How each calibre family sounds, as layers the synth plays now and a sample replaces later (ids of checklist-sons.md 5.1). close = crack (supersonic N-wave or the muzzle snap, highpass), blast (the mid 'slap', lowpass) and body (the low thump, a sine sweep). far = what is left at 50 m and more: a lowpassed boom and its echoes. tail_in / tail_out = the room or the open field answering. Seconds are the exponential fall to -60 dB. Values chosen by the SDK from the real character of each calibre (see the checklist's 'Como deve soar'); referenceJ is the muzzle energy the numbers are written for.\",\n \"profiles\": {\n \"pistol_22lr\": {\n \"referenceJ\": 160,\n \"far\": \"pistol\",\n \"crack\": {\n \"frequency\": 5200,\n \"gain\": 0.4,\n \"seconds\": 0.006\n },\n \"blast\": {\n \"cutoff\": 3400,\n \"gain\": 0.517,\n \"seconds\": 0.05\n },\n \"body\": {\n \"from\": 200,\n \"to\": 90,\n \"gain\": 0.045,\n \"seconds\": 0.04\n },\n \"far_layer\": {\n \"cutoff\": 1300,\n \"gain\": 0.22,\n \"seconds\": 0.12\n },\n \"tail_out\": {\n \"cutoff\": 1500,\n \"gain\": 0.08,\n \"seconds\": 0.5\n },\n \"tail_in\": {\n \"cutoff\": 2400,\n \"gain\": 0.24,\n \"seconds\": 0.25\n }\n },\n \"pistol_9mm\": {\n \"referenceJ\": 500,\n \"far\": \"pistol\",\n \"crack\": {\n \"frequency\": 4200,\n \"gain\": 0.55,\n \"seconds\": 0.008\n },\n \"blast\": {\n \"cutoff\": 2500,\n \"gain\": 0.92,\n \"seconds\": 0.09\n },\n \"body\": {\n \"from\": 160,\n \"to\": 55,\n \"gain\": 0.189,\n \"seconds\": 0.1\n },\n \"far_layer\": {\n \"cutoff\": 950,\n \"gain\": 0.35,\n \"seconds\": 0.2\n },\n \"tail_out\": {\n \"cutoff\": 1150,\n \"gain\": 0.2,\n \"seconds\": 0.9\n },\n \"tail_in\": {\n \"cutoff\": 2200,\n \"gain\": 0.45,\n \"seconds\": 0.4\n }\n },\n \"pistol_45\": {\n \"referenceJ\": 480,\n \"far\": \"pistol\",\n \"crack\": {\n \"frequency\": 3400,\n \"gain\": 0.42,\n \"seconds\": 0.009\n },\n \"blast\": {\n \"cutoff\": 1650,\n \"gain\": 0.977,\n \"seconds\": 0.12\n },\n \"body\": {\n \"from\": 120,\n \"to\": 42,\n \"gain\": 0.279,\n \"seconds\": 0.15\n },\n \"far_layer\": {\n \"cutoff\": 760,\n \"gain\": 0.4,\n \"seconds\": 0.25\n },\n \"tail_out\": {\n \"cutoff\": 1000,\n \"gain\": 0.22,\n \"seconds\": 1.0\n },\n \"tail_in\": {\n \"cutoff\": 1900,\n \"gain\": 0.48,\n \"seconds\": 0.45\n }\n },\n \"revolver_38_357\": {\n \"referenceJ\": 800,\n \"far\": \"pistol\",\n \"crack\": {\n \"frequency\": 4000,\n \"gain\": 0.6,\n \"seconds\": 0.009\n },\n \"blast\": {\n \"cutoff\": 2000,\n \"gain\": 1.035,\n \"seconds\": 0.13\n },\n \"body\": {\n \"from\": 135,\n \"to\": 45,\n \"gain\": 0.248,\n \"seconds\": 0.15\n },\n \"far_layer\": {\n \"cutoff\": 820,\n \"gain\": 0.42,\n \"seconds\": 0.28\n },\n \"tail_out\": {\n \"cutoff\": 1100,\n \"gain\": 0.28,\n \"seconds\": 1.4\n },\n \"tail_in\": {\n \"cutoff\": 2000,\n \"gain\": 0.54,\n \"seconds\": 0.5\n }\n },\n \"revolver_44_50ae\": {\n \"referenceJ\": 1800,\n \"far\": \"pistol\",\n \"crack\": {\n \"frequency\": 3100,\n \"gain\": 0.62,\n \"seconds\": 0.012\n },\n \"blast\": {\n \"cutoff\": 1350,\n \"gain\": 1.15,\n \"seconds\": 0.18\n },\n \"body\": {\n \"from\": 100,\n \"to\": 36,\n \"gain\": 0.369,\n \"seconds\": 0.21\n },\n \"far_layer\": {\n \"cutoff\": 650,\n \"gain\": 0.5,\n \"seconds\": 0.33\n },\n \"tail_out\": {\n \"cutoff\": 900,\n \"gain\": 0.34,\n \"seconds\": 1.7\n },\n \"tail_in\": {\n \"cutoff\": 1700,\n \"gain\": 0.6,\n \"seconds\": 0.6\n }\n },\n \"shotgun_12\": {\n \"referenceJ\": 2700,\n \"far\": \"shotgun\",\n \"crack\": {\n \"frequency\": 2600,\n \"gain\": 0.36,\n \"seconds\": 0.012\n },\n \"blast\": {\n \"cutoff\": 900,\n \"gain\": 1.15,\n \"seconds\": 0.26\n },\n \"body\": {\n \"from\": 90,\n \"to\": 32,\n \"gain\": 0.405,\n \"seconds\": 0.3\n },\n \"far_layer\": {\n \"cutoff\": 540,\n \"gain\": 0.55,\n \"seconds\": 0.42\n },\n \"tail_out\": {\n \"cutoff\": 800,\n \"gain\": 0.38,\n \"seconds\": 1.9\n },\n \"tail_in\": {\n \"cutoff\": 1500,\n \"gain\": 0.63,\n \"seconds\": 0.7\n }\n },\n \"rifle_5_56\": {\n \"referenceJ\": 1750,\n \"far\": \"rifle\",\n \"crack\": {\n \"frequency\": 5400,\n \"gain\": 0.78,\n \"seconds\": 0.007\n },\n \"blast\": {\n \"cutoff\": 2700,\n \"gain\": 0.977,\n \"seconds\": 0.11\n },\n \"body\": {\n \"from\": 145,\n \"to\": 50,\n \"gain\": 0.216,\n \"seconds\": 0.12\n },\n \"far_layer\": {\n \"cutoff\": 900,\n \"gain\": 0.5,\n \"seconds\": 0.36\n },\n \"tail_out\": {\n \"cutoff\": 1300,\n \"gain\": 0.4,\n \"seconds\": 2.1\n },\n \"tail_in\": {\n \"cutoff\": 2300,\n \"gain\": 0.57,\n \"seconds\": 0.55\n }\n },\n \"rifle_7_62x39\": {\n \"referenceJ\": 2100,\n \"far\": \"rifle\",\n \"crack\": {\n \"frequency\": 4300,\n \"gain\": 0.72,\n \"seconds\": 0.01\n },\n \"blast\": {\n \"cutoff\": 1850,\n \"gain\": 1.092,\n \"seconds\": 0.15\n },\n \"body\": {\n \"from\": 115,\n \"to\": 40,\n \"gain\": 0.297,\n \"seconds\": 0.17\n },\n \"far_layer\": {\n \"cutoff\": 780,\n \"gain\": 0.52,\n \"seconds\": 0.38\n },\n \"tail_out\": {\n \"cutoff\": 1100,\n \"gain\": 0.42,\n \"seconds\": 2.2\n },\n \"tail_in\": {\n \"cutoff\": 2000,\n \"gain\": 0.6,\n \"seconds\": 0.6\n }\n },\n \"rifle_308_3006\": {\n \"referenceJ\": 3500,\n \"far\": \"rifle\",\n \"crack\": {\n \"frequency\": 4500,\n \"gain\": 0.8,\n \"seconds\": 0.01\n },\n \"blast\": {\n \"cutoff\": 1500,\n \"gain\": 1.15,\n \"seconds\": 0.19\n },\n \"body\": {\n \"from\": 100,\n \"to\": 36,\n \"gain\": 0.36,\n \"seconds\": 0.21\n },\n \"far_layer\": {\n \"cutoff\": 650,\n \"gain\": 0.6,\n \"seconds\": 0.46\n },\n \"tail_out\": {\n \"cutoff\": 950,\n \"gain\": 0.5,\n \"seconds\": 2.7\n },\n \"tail_in\": {\n \"cutoff\": 1800,\n \"gain\": 0.675,\n \"seconds\": 0.7\n }\n },\n \"sniper_338_300wm\": {\n \"referenceJ\": 6600,\n \"far\": \"heavy\",\n \"crack\": {\n \"frequency\": 4200,\n \"gain\": 0.86,\n \"seconds\": 0.012\n },\n \"blast\": {\n \"cutoff\": 1250,\n \"gain\": 1.208,\n \"seconds\": 0.23\n },\n \"body\": {\n \"from\": 85,\n \"to\": 32,\n \"gain\": 0.414,\n \"seconds\": 0.26\n },\n \"far_layer\": {\n \"cutoff\": 580,\n \"gain\": 0.65,\n \"seconds\": 0.52\n },\n \"tail_out\": {\n \"cutoff\": 850,\n \"gain\": 0.56,\n \"seconds\": 3.1\n },\n \"tail_in\": {\n \"cutoff\": 1650,\n \"gain\": 0.72,\n \"seconds\": 0.8\n }\n },\n \"antimateriel_50bmg\": {\n \"referenceJ\": 18000,\n \"far\": \"heavy\",\n \"crack\": {\n \"frequency\": 3500,\n \"gain\": 0.9,\n \"seconds\": 0.015\n },\n \"blast\": {\n \"cutoff\": 900,\n \"gain\": 1.265,\n \"seconds\": 0.3\n },\n \"body\": {\n \"from\": 62,\n \"to\": 25,\n \"gain\": 0.495,\n \"seconds\": 0.36\n },\n \"far_layer\": {\n \"cutoff\": 450,\n \"gain\": 0.7,\n \"seconds\": 0.62\n },\n \"tail_out\": {\n \"cutoff\": 700,\n \"gain\": 0.6,\n \"seconds\": 3.6\n },\n \"tail_in\": {\n \"cutoff\": 1400,\n \"gain\": 0.75,\n \"seconds\": 0.9\n }\n }\n },\n \"calibers\": {\n \"22lr\": \"pistol_22lr\",\n \"380acp\": \"pistol_9mm\",\n \"9x18\": \"pistol_9mm\",\n \"9x19\": \"pistol_9mm\",\n \"32acp\": \"pistol_9mm\",\n \"5_7x28\": \"pistol_9mm\",\n \"4_6x30\": \"pistol_9mm\",\n \"40sw\": \"pistol_45\",\n \"45acp\": \"pistol_45\",\n \"38spl\": \"revolver_38_357\",\n \"357mag\": \"revolver_38_357\",\n \"44mag\": \"revolver_44_50ae\",\n \"50ae\": \"revolver_44_50ae\",\n \"12ga_00buck\": \"shotgun_12\",\n \"12ga_slug\": \"shotgun_12\",\n \"12ga_birdshot\": \"shotgun_12\",\n \"20ga_buck\": \"shotgun_12\",\n \"5_56x45\": \"rifle_5_56\",\n \"5_45x39\": \"rifle_5_56\",\n \"7_62x39\": \"rifle_7_62x39\",\n \"30_30\": \"rifle_308_3006\",\n \"7_62x51\": \"rifle_308_3006\",\n \"7_62x54r\": \"rifle_308_3006\",\n \"30_06\": \"rifle_308_3006\",\n \"45_70_bp\": \"rifle_308_3006\",\n \"300wm\": \"sniper_338_300wm\",\n \"338lapua\": \"sniper_338_300wm\",\n \"408cheytac\": \"antimateriel_50bmg\",\n \"50bmg\": \"antimateriel_50bmg\"\n },\n \"suppressor\": {\n \"$comment\": \"A suppressor takes 20-30 dB off the muzzle blast and most of the low body; a supersonic bullet still cracks (only quieter, it is the bullet, not the muzzle), and the action becomes the loudest thing (the 'pfft' plus the slide or bolt).\",\n \"blastGain\": 0.1,\n \"blastCutoff\": 0.45,\n \"bodyGain\": 0.22,\n \"tailGain\": 0.14,\n \"farGain\": 0.08,\n \"supersonicCrack\": 0.55,\n \"subsonicCrack\": 0.05,\n \"mechGain\": 2.2\n },\n \"shells\": {\n \"$comment\": \"A slug is one heavy projectile: a drier, shorter blast than buckshot; birdshot is the lightest load.\",\n \"slug\": {\n \"blastSeconds\": 0.75,\n \"crackGain\": 1.3\n },\n \"birdshot\": {\n \"blastGain\": 0.8,\n \"bodyGain\": 0.75\n }\n },\n \"mech\": {\n \"$comment\": \"The action cycling right after the shot (slide, bolt carrier): heard close, under the blast, louder when suppressed.\",\n \"pistol\": {\n \"at\": 0.028,\n \"frequency\": 2600,\n \"gain\": 0.08\n },\n \"revolver\": {\n \"at\": 0.0,\n \"frequency\": 1900,\n \"gain\": 0.0\n },\n \"smg\": {\n \"at\": 0.022,\n \"frequency\": 2300,\n \"gain\": 0.09\n },\n \"rifle\": {\n \"at\": 0.03,\n \"frequency\": 2000,\n \"gain\": 0.09\n },\n \"dmr\": {\n \"at\": 0.035,\n \"frequency\": 1800,\n \"gain\": 0.1\n },\n \"machine_gun\": {\n \"at\": 0.03,\n \"frequency\": 1700,\n \"gain\": 0.11\n },\n \"shotgun\": {\n \"at\": 0.0,\n \"frequency\": 1500,\n \"gain\": 0.0\n },\n \"sniper\": {\n \"at\": 0.0,\n \"frequency\": 1600,\n \"gain\": 0.0\n },\n \"hunting\": {\n \"at\": 0.0,\n \"frequency\": 1700,\n \"gain\": 0.0\n },\n \"carbine\": {\n \"at\": 0.026,\n \"frequency\": 2400,\n \"gain\": 0.07\n }\n },\n \"space\": {\n \"$comment\": \"Echoes of the open field (a wall of trees or houses 60 m and 140 m away) and the early reflections of a room.\",\n \"outdoorEchoes\": [\n [\n 0.35,\n 0.32\n ],\n [\n 0.82,\n 0.16\n ]\n ],\n \"indoorReflections\": [\n [\n 0.009,\n 0.7\n ],\n [\n 0.019,\n 0.5\n ],\n [\n 0.033,\n 0.32\n ]\n ],\n \"indoorWet\": 1.0\n }\n}\n","// A spent case hitting the floor: brass rings on concrete and on steel, knocks short on wood and is only a soft tap on dirt or grass; a shotgun hull\n// is plastic with a brass head, so it \"toks\" instead of ringing. Pure: the adapter plays the voices; the sample of each pair is\n// `casing_drop_<surface>_<case>` (checklist-sons.md 5.2).\nimport type { CaseType } from '@adatechnology/game-weapons'\n\nexport type CasingSurface = 'hard' | 'wood' | 'metal' | 'soft'\nexport type CasingKind = 'pistol' | 'rifle' | 'shell'\n\n/** Floor material (a game-destruction id or a plain word) → how a case sounds on it. Unknown floors are hard (concrete). */\nconst SURFACES: Readonly<Record<string, CasingSurface>> = {\n concrete: 'hard',\n stone: 'hard',\n brick: 'hard',\n mortar: 'hard',\n asphalt: 'hard',\n tile: 'hard',\n ceramic: 'hard',\n marble: 'hard',\n glass: 'hard',\n tempered_glass: 'hard',\n wood: 'wood',\n wood_soft: 'wood',\n wood_hard: 'wood',\n green_wood: 'wood',\n plywood: 'wood',\n mdf: 'wood',\n steel: 'metal',\n cast_iron: 'metal',\n iron: 'metal',\n aluminium: 'metal',\n aluminum: 'metal',\n copper: 'metal',\n metal: 'metal',\n soil: 'soft',\n dirt: 'soft',\n sand: 'soft',\n gravel: 'soft',\n turf: 'soft',\n grass: 'soft',\n foliage: 'soft',\n fabric: 'soft',\n carpet: 'soft',\n foam: 'soft',\n rubber: 'soft',\n leather: 'soft',\n}\n\nexport const casingSurfaceOf = (material: string | undefined): CasingSurface => SURFACES[material ?? ''] ?? 'hard'\nexport const casingKindOf = (caseType: CaseType | string | undefined): CasingKind => (caseType === 'shell' ? 'shell' : caseType === 'rifle' || caseType === 'big' ? 'rifle' : 'pistol')\n\nexport interface CasingInput {\n readonly caseType?: CaseType | string\n /** Floor material id (`concrete`, `wood_hard`, `soil`...). */\n readonly surface?: string\n /** Vertical speed at the hit, m/s (the louder the faster). Default 1.5. */\n readonly speed?: number\n /** 0 for the first hit, then 1, 2...: each bounce is softer and a little higher. */\n readonly bounce?: number\n /** Pitch factor around 1 (the adapter draws ±6 %: no two cases ring the same). */\n readonly pitch?: number\n}\n\nexport interface CasingVoice {\n readonly kind: 'tone' | 'noise'\n readonly filter?: 'lowpass' | 'highpass' | 'bandpass'\n readonly frequency: number\n readonly to?: number\n readonly q?: number\n readonly gain: number\n readonly seconds: number\n}\n\nexport interface CasingSound {\n readonly surface: CasingSurface\n readonly kind: CasingKind\n readonly sample: string\n readonly voices: readonly CasingVoice[]\n}\n\n/** Lowest ring of a free brass tube (Hz) and the inharmonic partial of a tube, ×2.76. */\nconst RING: Readonly<Record<'pistol' | 'rifle', number>> = { pistol: 5200, rifle: 3600 }\nconst PARTIAL = 2.76\n/** How long the brass rings on each floor (s): a steel plate lets it sing, wood damps it, dirt stops it. */\nconst RING_SECONDS: Readonly<Record<CasingSurface, number>> = { hard: 0.08, metal: 0.22, wood: 0.025, soft: 0 }\nconst KNOCK: Readonly<Record<CasingSurface, { frequency: number; gain: number; seconds: number }>> = {\n hard: { frequency: 6000, gain: 0.05, seconds: 0.006 },\n metal: { frequency: 5000, gain: 0.06, seconds: 0.008 },\n wood: { frequency: 1400, gain: 0.08, seconds: 0.02 },\n soft: { frequency: 500, gain: 0.05, seconds: 0.03 },\n}\n\nexport function computeCasingSound(input: CasingInput): CasingSound {\n const surface = casingSurfaceOf(input.surface)\n const kind = casingKindOf(input.caseType)\n const pitch = (input.pitch ?? 1) * (1 + 0.03 * (input.bounce ?? 0))\n const level = Math.min(1, Math.max(0.05, (input.speed ?? 1.5) / 2.5)) * Math.pow(0.6, input.bounce ?? 0)\n const voices: CasingVoice[] = []\n const knock = KNOCK[surface]\n if (kind === 'shell') {\n // plastic hull: a hollow \"tok\", the brass head a short tick on a hard floor\n voices.push({ kind: 'noise', filter: 'bandpass', frequency: (surface === 'soft' ? 700 : 1500) * pitch, q: 2.5, gain: 0.09 * level, seconds: surface === 'soft' ? 0.03 : 0.045 })\n if (surface !== 'soft') voices.push({ kind: 'tone', frequency: 2900 * pitch, to: 2800 * pitch, gain: 0.025 * level, seconds: surface === 'metal' ? 0.06 : 0.025 })\n } else {\n voices.push({ kind: 'noise', filter: surface === 'soft' || surface === 'wood' ? 'lowpass' : 'highpass', frequency: knock.frequency * pitch, q: 0.7, gain: knock.gain * level, seconds: knock.seconds })\n const ringSeconds = RING_SECONDS[surface] * (kind === 'rifle' ? 1.3 : 1)\n if (ringSeconds > 0) {\n const f = RING[kind] * pitch\n voices.push({ kind: 'tone', frequency: f, to: f * 0.985, gain: 0.07 * level, seconds: ringSeconds })\n voices.push({ kind: 'tone', frequency: f * PARTIAL, to: f * PARTIAL * 0.99, gain: 0.03 * level, seconds: ringSeconds * 0.6 })\n }\n }\n // the sample ids of the sound infra (game-audio samples): concreto, madeira, terra, metal\n const surfaceName = surface === 'hard' ? 'concreto' : surface === 'soft' ? 'terra' : surface === 'wood' ? 'madeira' : 'metal'\n return { surface, kind, sample: `casing_drop_${surfaceName}_${kind}`, voices }\n}\n","// A bullet passing the listener without hitting: a supersonic one cracks (its shock wave, a sharp \"crack\" heard before the muzzle report), a\n// subsonic one whizzes (a short \"fiu\" sliding down as it passes). Pure; the sample ids are `bullet_crack_by` and `bullet_whiz` (checklist-sons.md 5.1).\nimport { SPEED_OF_SOUND } from './gunshot'\n\nexport interface FlybyInput {\n /** Bullet speed where it passes the listener, m/s. */\n readonly speed: number\n /** Closest distance from the bullet path to the listener's head, metres. Past `maxMiss` nothing is heard. */\n readonly miss: number\n /** Pitch factor around 1. */\n readonly pitch?: number\n /** Default 6 m. */\n readonly maxMiss?: number\n}\n\nexport interface FlybyVoice {\n readonly kind: 'noise' | 'tone'\n readonly filter?: 'highpass' | 'bandpass'\n readonly frequency: number\n readonly to?: number\n readonly q?: number\n readonly gain: number\n readonly seconds: number\n}\n\nexport interface FlybySound {\n readonly supersonic: boolean\n readonly sample: 'bullet_crack_by' | 'bullet_whiz'\n readonly voices: readonly FlybyVoice[]\n}\n\nexport function computeFlyby(input: FlybyInput): FlybySound | null {\n const maxMiss = input.maxMiss ?? 6\n if (input.miss > maxMiss || input.speed <= 0) return null\n const near = 1 / (1 + input.miss / 1.5)\n const pitch = input.pitch ?? 1\n if (input.speed > SPEED_OF_SOUND * 1.05) {\n // the N-wave: a very short, very bright snap, louder the closer and the faster\n const gain = 0.7 * near * Math.min(1.3, input.speed / 800)\n return {\n supersonic: true,\n sample: 'bullet_crack_by',\n voices: [\n { kind: 'noise', filter: 'highpass', frequency: 3000 * pitch, q: 0.7, gain, seconds: 0.012 },\n { kind: 'noise', filter: 'bandpass', frequency: 1800 * pitch, q: 1.2, gain: gain * 0.35, seconds: 0.05 },\n ],\n }\n }\n // the whiz: a band of noise and a faint tone sliding down (Doppler) over the pass\n const gain = 0.22 * near\n const seconds = 0.12 + 0.05 * input.miss\n return {\n supersonic: false,\n sample: 'bullet_whiz',\n voices: [\n { kind: 'noise', filter: 'bandpass', frequency: 2400 * pitch, q: 4, gain, seconds },\n { kind: 'tone', frequency: 1500 * pitch, to: 900 * pitch, gain: gain * 0.35, seconds },\n ],\n }\n}\n","{\n \"source\": \"Authored in the kit. The art scene delivered sfx for the magazine, the bolt and the shell (cena L1339-L1343, used here for mag_seat, charging_handle_release and shell_insert); the gallery draws no sound, so the other cues combine the same primitives (metal click, thud, filtered noise, tones) of game-audio. Each cue is played at the second the reload clip says, so it follows the animation and scales with the weapon's reload time.\",\n \"profiles\": {\n \"weight\": {\n \"light\": {\n \"pitch\": 1.3,\n \"gain\": 0.85\n },\n \"medium\": {\n \"pitch\": 1,\n \"gain\": 1\n },\n \"heavy\": {\n \"pitch\": 0.78,\n \"gain\": 1.2\n }\n },\n \"material\": {\n \"steel\": {\n \"pitch\": 1,\n \"gain\": 1\n },\n \"polymer\": {\n \"pitch\": 0.82,\n \"gain\": 0.8\n }\n }\n },\n \"comment\": \"Light: pistols and revolvers. Medium: rifles, SMGs, bolt guns. Heavy: shotguns, belt-fed guns, launchers. Steel is the default; the polymer frames are listed in `polymer`.\",\n \"weights\": {\n \"pistol\": \"light\",\n \"revolver\": \"light\",\n \"rifle\": \"medium\",\n \"semiint\": \"medium\",\n \"semi12\": \"heavy\",\n \"p90\": \"medium\",\n \"belt\": \"heavy\",\n \"pump\": \"heavy\",\n \"lever\": \"medium\",\n \"bolt\": \"medium\",\n \"boltmag\": \"medium\",\n \"break\": \"heavy\",\n \"rocket\": \"heavy\",\n \"flame\": \"heavy\"\n },\n \"polymer\": [\n \"glock_17\",\n \"glock_18\",\n \"glock_19\",\n \"taurus_g2c\",\n \"taurus_ts9\",\n \"fn_five_seven\",\n \"pistol_9mm\",\n \"fn_p90\",\n \"hk_ump_45\"\n ],\n \"cues\": {\n \"mag_release\": [\n {\n \"layer\": \"scene_tone\",\n \"at\": 0,\n \"wave\": \"square\",\n \"f\": 2400,\n \"f2\": 1680,\n \"d\": 0.02,\n \"vol\": 0.3\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.24\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.12,\n \"frequency\": 700\n }\n ],\n \"mag_out\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 900,\n \"q\": 2,\n \"d\": 0.1,\n \"vol\": 0.3,\n \"f2\": 600\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.08,\n \"frequency\": 1200,\n \"gain\": 0.2\n }\n ],\n \"mag_insert\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 700,\n \"q\": 2,\n \"d\": 0.12,\n \"vol\": 0.3,\n \"f2\": 1100\n }\n ],\n \"mag_seat\": [\n {\n \"layer\": \"scene_tone\",\n \"at\": 0,\n \"wave\": \"square\",\n \"f\": 1100,\n \"f2\": 770,\n \"d\": 0.02,\n \"vol\": 0.5\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.4\n },\n {\n \"layer\": \"scene_tone\",\n \"at\": 0,\n \"wave\": \"sine\",\n \"f\": 320,\n \"f2\": 200,\n \"d\": 0.05,\n \"vol\": 0.35\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.01,\n \"gain\": 0.18,\n \"frequency\": 600\n }\n ],\n \"slide_release\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 900,\n \"gain\": 0.35\n },\n {\n \"layer\": \"scene_tone\",\n \"at\": 0.02,\n \"wave\": \"square\",\n \"f\": 2000,\n \"f2\": 1400,\n \"d\": 0.02,\n \"vol\": 0.4\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0.02,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.32\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.03,\n \"gain\": 0.25,\n \"frequency\": 500\n }\n ],\n \"charging_handle_pull\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1500,\n \"q\": 3,\n \"d\": 0.09,\n \"vol\": 0.3,\n \"f2\": 900\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.06,\n \"frequency\": 1300,\n \"gain\": 0.25\n }\n ],\n \"charging_handle_release\": [\n {\n \"layer\": \"scene_tone\",\n \"at\": 0,\n \"wave\": \"square\",\n \"f\": 2200,\n \"f2\": 1540,\n \"d\": 0.02,\n \"vol\": 0.4\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.32\n },\n {\n \"layer\": \"scene_tone\",\n \"at\": 0.02,\n \"wave\": \"square\",\n \"f\": 2700,\n \"f2\": 1890,\n \"d\": 0.02,\n \"vol\": 0.4\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0.02,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.32\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.03,\n \"gain\": 0.2,\n \"frequency\": 600\n }\n ],\n \"bolt_lift\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1500,\n \"gain\": 0.3\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 2000,\n \"q\": 3,\n \"d\": 0.04,\n \"vol\": 0.15,\n \"f2\": 1500\n }\n ],\n \"bolt_pull\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1400,\n \"q\": 3,\n \"d\": 0.12,\n \"vol\": 0.3,\n \"f2\": 800\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.1,\n \"frequency\": 900,\n \"gain\": 0.3\n }\n ],\n \"bolt_push\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 800,\n \"q\": 3,\n \"d\": 0.1,\n \"vol\": 0.3,\n \"f2\": 1400\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.08,\n \"frequency\": 1100,\n \"gain\": 0.3\n }\n ],\n \"bolt_lock\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1800,\n \"gain\": 0.4\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.2,\n \"frequency\": 700\n }\n ],\n \"shell_insert\": [\n {\n \"layer\": \"scene_tone\",\n \"at\": 0,\n \"wave\": \"square\",\n \"f\": 1400,\n \"f2\": 980,\n \"d\": 0.02,\n \"vol\": 0.35\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"highpass\",\n \"f\": 3000,\n \"q\": 0.7,\n \"d\": 0.03,\n \"vol\": 0.28\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0.02,\n \"type\": \"bandpass\",\n \"f\": 1200,\n \"q\": 3,\n \"d\": 0.05,\n \"vol\": 0.25\n }\n ],\n \"pump_back\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1000,\n \"q\": 2,\n \"d\": 0.12,\n \"vol\": 0.3,\n \"f2\": 700\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.1,\n \"frequency\": 900,\n \"gain\": 0.35\n }\n ],\n \"pump_forward\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 700,\n \"q\": 2,\n \"d\": 0.1,\n \"vol\": 0.3,\n \"f2\": 1000\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.08,\n \"frequency\": 1300,\n \"gain\": 0.4\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.1,\n \"gain\": 0.25,\n \"frequency\": 500\n }\n ],\n \"lever_open\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1000,\n \"gain\": 0.35\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1200,\n \"q\": 3,\n \"d\": 0.08,\n \"vol\": 0.2,\n \"f2\": 800\n }\n ],\n \"lever_close\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1500,\n \"gain\": 0.4\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.2,\n \"frequency\": 550\n }\n ],\n \"cylinder_open\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1500,\n \"gain\": 0.3\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0.02,\n \"type\": \"bandpass\",\n \"f\": 1800,\n \"q\": 3,\n \"d\": 0.08,\n \"vol\": 0.2,\n \"f2\": 1200\n }\n ],\n \"cylinder_eject\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 2400,\n \"gain\": 0.25\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.05,\n \"frequency\": 2800,\n \"gain\": 0.2\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.11,\n \"frequency\": 3200,\n \"gain\": 0.15\n }\n ],\n \"speedloader\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1500,\n \"q\": 3,\n \"d\": 0.08,\n \"vol\": 0.25,\n \"f2\": 2000\n },\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 2000,\n \"gain\": 0.25\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.05,\n \"frequency\": 2400,\n \"gain\": 0.2\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.07,\n \"gain\": 0.15,\n \"frequency\": 800\n }\n ],\n \"cylinder_close\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1100,\n \"gain\": 0.45\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.01,\n \"gain\": 0.2,\n \"frequency\": 500\n }\n ],\n \"barrels_open\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1000,\n \"gain\": 0.4\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.03,\n \"gain\": 0.2,\n \"frequency\": 450\n }\n ],\n \"casings_eject\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 2600,\n \"gain\": 0.25\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.08,\n \"frequency\": 3000,\n \"gain\": 0.2\n }\n ],\n \"barrels_close\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1100,\n \"gain\": 0.5\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.3,\n \"frequency\": 450\n }\n ],\n \"belt_cover_open\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 800,\n \"gain\": 0.4\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.03,\n \"gain\": 0.2,\n \"frequency\": 500\n }\n ],\n \"belt_insert\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1400,\n \"gain\": 0.3\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.08,\n \"frequency\": 1800,\n \"gain\": 0.25\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.1,\n \"gain\": 0.25,\n \"frequency\": 450\n }\n ],\n \"belt_cover_close\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1000,\n \"gain\": 0.45\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.3,\n \"frequency\": 400\n }\n ],\n \"rocket_load\": [\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 600,\n \"q\": 1.5,\n \"d\": 0.25,\n \"vol\": 0.3,\n \"f2\": 400\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.2,\n \"gain\": 0.2,\n \"frequency\": 450\n }\n ],\n \"rocket_seat\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 900,\n \"gain\": 0.45\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.01,\n \"gain\": 0.35,\n \"frequency\": 350\n }\n ],\n \"grenade_load\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1100,\n \"gain\": 0.35\n },\n {\n \"layer\": \"scene_noise\",\n \"at\": 0,\n \"type\": \"bandpass\",\n \"f\": 1000,\n \"q\": 2,\n \"d\": 0.1,\n \"vol\": 0.2,\n \"f2\": 700\n }\n ],\n \"breech_open\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1000,\n \"gain\": 0.35\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.03,\n \"gain\": 0.15,\n \"frequency\": 500\n }\n ],\n \"breech_close\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 1100,\n \"gain\": 0.45\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.25,\n \"frequency\": 450\n }\n ],\n \"tube_drop\": [\n {\n \"layer\": \"thud\",\n \"at\": 0,\n \"gain\": 0.35,\n \"frequency\": 380\n },\n {\n \"layer\": \"metal\",\n \"at\": 0.05,\n \"frequency\": 700,\n \"gain\": 0.2\n }\n ],\n \"tube_seat\": [\n {\n \"layer\": \"metal\",\n \"at\": 0,\n \"frequency\": 900,\n \"gain\": 0.45\n },\n {\n \"layer\": \"thud\",\n \"at\": 0.02,\n \"gain\": 0.3,\n \"frequency\": 380\n }\n ]\n }\n}","import data from '../data/reload-sounds.json'\nimport type { SoundStep } from './mechanical-sounds'\n\n/** The sound cues a reload clip carries (`cue(t, 'sound', { id })`): one per physical step, at the second the animation does it. */\nexport type ReloadCueId = keyof typeof data.cues\n\nexport const RELOAD_CUE_IDS = Object.keys(data.cues) as ReloadCueId[]\n\n/** How a weapon sounds: the weight of its metal (pitch and level) and what it is made of. */\nexport interface SoundProfile {\n readonly weight: keyof typeof data.profiles.weight\n readonly material: keyof typeof data.profiles.material\n}\n\nexport const DEFAULT_SOUND_PROFILE: SoundProfile = { weight: 'medium', material: 'steel' }\n\n/** The recipes of the cues, as data (`data/reload-sounds.json`): layers of the primitives `createWeaponAudio` registers in game-audio. */\nexport const RELOAD_CUES: Readonly<Record<string, readonly SoundStep[]>> = data.cues as unknown as Record<string, readonly SoundStep[]>\n\nconst polymer = new Set<string>(data.polymer)\nconst weights = data.weights as Record<string, SoundProfile['weight']>\n\n/** The profile of a weapon: the weight from the family of its model, polymer when the data lists it. */\nexport const soundProfileOf = (weaponId: string, modelFamily: string): SoundProfile => ({ weight: weights[modelFamily] ?? 'medium', material: polymer.has(weaponId) ? 'polymer' : 'steel' })\n\n/** The layers of a cue for a profile: every frequency times the pitch of weight and material, every level times their gain. Pure. */\nexport const reloadCueSteps = (id: string, profile: SoundProfile = DEFAULT_SOUND_PROFILE, table: Readonly<Record<string, readonly SoundStep[]>> = RELOAD_CUES): readonly SoundStep[] => {\n const steps = table[id]\n if (!steps) return []\n const weight = data.profiles.weight[profile.weight]\n const material = data.profiles.material[profile.material]\n const pitch = weight.pitch * material.pitch\n const gain = weight.gain * material.gain\n return steps.map((entry): SoundStep => {\n switch (entry.layer) {\n case 'metal':\n return { ...entry, frequency: Math.round(entry.frequency * pitch), gain: entry.gain * gain }\n case 'thud':\n return { ...entry, frequency: Math.round(entry.frequency * pitch), gain: entry.gain * gain }\n case 'scene_tone':\n return { ...entry, f: Math.round(entry.f * pitch), ...(entry.f2 === undefined ? {} : { f2: Math.round(entry.f2 * pitch) }), vol: entry.vol * gain }\n case 'scene_noise':\n return { ...entry, f: Math.round(entry.f * pitch), ...(entry.f2 === undefined ? {} : { f2: Math.round(entry.f2 * pitch) }), vol: entry.vol * gain }\n default:\n return entry\n }\n })\n}\n","// The recorded firearm sounds of game-audio's sfx (`assets/sfx/armas`, cut by tools/sfx-sources from The Free Firearm Sound Library, CC0, and the\n// Restrained Firearms Soundpack, CC BY 4.0): the numbers of each sound the files do not say, and the bank the weapon audio registers. A shot plays\n// the takes of its calibre profile (`close` near, `far` from the mid-distance microphone, crossed over by distance); a reload step plays the takes\n// of its cue in the tier of the weapon's weight (light pistols, medium rifles, heavy shotguns); a brass case landing plays the bounces of its floor\n// (Oculus Audio Pack 1, CC BY 4.0: concrete, grass, metal). Without the files the synthesized sounds play.\nimport { sampleBankFromManifest } from '@adatechnology/game-audio'\nimport type { SampleDefaults, SampleSound, SfxManifest, SoundBank } from '@adatechnology/game-audio'\n\nimport hitData from '../data/reload-sample-hits.json'\nimport profiles from '../data/gunshot-profiles.json'\nimport type { SoundProfile } from './reload-sounds'\n\n/** Where the recorded files are: the manifest the converter wrote and how a file of it becomes a url. */\nexport interface WeaponSampleOptions {\n readonly manifest: SfxManifest\n /** Prefix of every file (`/sfx/`), when `url` is not given. Default ''. */\n readonly baseUrl?: string\n /** The url of a file of the manifest (`armas/pistol_9mm_close_01.ogg`): a served path or a `data:` url of the inlined bytes. */\n readonly url?: (file: string) => string\n /** Replaces the numbers of a sound by id (gain, crossover, falloff...). */\n readonly sounds?: Readonly<Record<string, Partial<SampleDefaults>>>\n}\n\n/** The shot sounds: the calibre profiles and the suppressed ones. */\nexport const GUNSHOT_SAMPLE_IDS: readonly string[] = [...Object.keys(profiles.profiles), 'suppressed_pistol', 'suppressed_rifle']\n\n/**\n * A shot as recorded: the near take up to 20 m, the mid-distance one from 90 m, an equal-power crossfade between. The level falls gently (a\n * gunshot carries: about −14 dB at 100 m, −36 dB at 800 m) and the highs go with the air (6.7 kHz at 50 m, 2.2 kHz at 200 m). Three plays ring at once at most, so a burst stays shot\n * by shot.\n */\nexport const GUNSHOT_SAMPLE: SampleDefaults = {\n bus: 'weapons',\n gain: 1,\n pitch: 0.04,\n crossover: { from: 20, to: 90 },\n falloff: { model: 'inverse_square', k: 0.0005, minGain: 0.0006 },\n cutoffK: 0.04,\n priority: 3,\n}\nconst SUPPRESSED_SAMPLE: SampleDefaults = { ...GUNSHOT_SAMPLE, gain: 0.55, crossover: { from: 10, to: 50 }, falloff: { model: 'inverse_square', k: 0.004, minGain: 0.0008 } }\n/** A reload step: heard at the hands, about a third of a shot's level after the converter's peak normalization. */\nexport const RELOAD_SAMPLE: SampleDefaults = { bus: 'weapons', gain: 0.32, pitch: 0.05, falloff: { model: 'inverse_square', k: 0.05, minGain: 0.002 }, cutoffK: 0.02, priority: 2 }\n\n/** A brass case's bounces on a floor: quiet, heard only near. */\nexport const CASING_SAMPLE: SampleDefaults = { bus: 'weapons', gain: 0.22, pitch: 0.06, falloff: { model: 'inverse_square', k: 0.08, minGain: 0.003 }, cutoffK: 0.03, priority: 1 }\n\n/** The recorded bounces of a brass case on a floor (`casing_drop_<concreto|terra|metal>`); wood and the plastic hull of a shell stay synthesized. */\nexport const casingSampleId = (sample: string): string => sample.replace(/_(pistol|rifle|shell)$/, '')\n\n/** Seconds from the start of each recorded reload step to its hit (`data/reload-sample-hits.json`, measured on the files). */\nexport const RELOAD_SAMPLE_HITS: Readonly<Record<string, number>> = hitData.hits\n\n/** The tier a weapon's weight plays (`SFX_TIERS`: light from 0, medium from 0.34, heavy from 0.67). */\nexport const WEIGHT_INTENSITY: Readonly<Record<SoundProfile['weight'], number>> = { light: 0.1, medium: 0.5, heavy: 0.9 }\n\n/**\n * Reload cues the recordings of another cue already carry: the magazine release button is the start of the \"detach magazine\" take, the slide of\n * the magazine into the well the start of the \"insert magazine\" one. When that sample plays, these cues stay silent.\n */\nexport const CUES_IN_SAMPLE: Readonly<Record<string, string>> = { mag_release: 'mag_out', mag_insert: 'mag_seat' }\n\nconst isGunshot = (id: string): boolean => GUNSHOT_SAMPLE_IDS.includes(id)\n\n/** The numbers of a sound of the manifest: a gunshot, a case landing or a reload step (`armas` only). */\nexport function weaponSampleDefaults(sound: { readonly id: string; readonly category: string }, overrides: WeaponSampleOptions['sounds'] = {}): SampleDefaults | undefined {\n if (sound.category !== 'armas') return undefined\n const base = sound.id.startsWith('suppressed_') ? SUPPRESSED_SAMPLE : isGunshot(sound.id) ? GUNSHOT_SAMPLE : sound.id.startsWith('casing_drop_') ? CASING_SAMPLE : RELOAD_SAMPLE\n return { ...base, ...overrides[sound.id] }\n}\n\n/** The bank of the recorded weapon sounds, every url through `url` (or `baseUrl`). Gunshots choke at three voices. */\nexport function weaponSampleBank(options: WeaponSampleOptions): SoundBank {\n const bank = sampleBankFromManifest(options.manifest, { id: 'weapons_three_samples', ...(options.url ? {} : { baseUrl: options.baseUrl ?? '' }), defaults: (sound) => weaponSampleDefaults(sound, options.sounds) })\n const url = options.url\n const remap = <T extends { readonly url: string }>(refs: readonly T[] | undefined): T[] | undefined => (refs && url ? refs.map((ref) => ({ ...ref, url: url(ref.url) })) : refs ? [...refs] : undefined)\n const samples = (bank.samples ?? []).map((sample): SampleSound => {\n const tiers = sample.tiers?.map((tier) => ({ ...tier, close: remap(tier.close) ?? [], ...(tier.far ? { far: remap(tier.far) ?? [] } : {}) }))\n return {\n ...sample,\n close: remap(sample.close) ?? [],\n ...(sample.far ? { far: remap(sample.far) ?? [] } : {}),\n ...(tiers ? { tiers } : {}),\n ...(isGunshot(sample.id) ? { choke: { voices: 3, fade: 0.06 } } : {}),\n }\n })\n return { id: bank.id, samples }\n}\n","{\n \"$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.\",\n \"hits\": {\n \"bolt_lift\": 0.072,\n \"bolt_lock\": 0.078,\n \"bolt_pull\": 0.128,\n \"bolt_push\": 0.054,\n \"charging_handle_pull\": 0.074,\n \"charging_handle_release\": 0.048,\n \"cylinder_close\": 0.024,\n \"cylinder_eject\": 0.394,\n \"cylinder_open\": 0.07,\n \"lever_close\": 0.147,\n \"lever_open\": 0.095,\n \"mag_out\": 0.012,\n \"mag_seat\": 0.094,\n \"pump_back\": 0.094,\n \"pump_forward\": 0.118,\n \"shell_insert\": 0.21,\n \"slide_release\": 0.031,\n \"speedloader\": 0.089\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { GunshotSpace } from './audio/gunshot'\nimport type { EffectSink, HandPose, HandTargets, HostEvent, HostTool, MuzzlePose } from '@adatechnology/game-contracts'\nimport type { LightBudget, RenderPools } from '@adatechnology/game-render-three'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { CuePlayed, WeaponAudio } from './audio'\nimport type { SoundProfile } from './audio/reload-sounds'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport type { AttachmentModelRegistry, LaserRaycast } from './models/attachments/types'\nimport { IN_HAND_NODE_NAME } from './laser-raycast'\nimport { createEyeFrame, placeOnBody } from './fx/body-hold'\nimport { holdOfProp, targetsOf } from './fx/hand-hold'\nimport type { Hold } from './fx/hand-hold'\nimport type { ItemModels } from './item-models'\nimport { BODY_ACTIONS } from './props'\nimport { buildWeaponModel } from './weapon-item-model'\n\nexport interface WeaponFxOptions {\n /** The item models of game-items-three (`itemModels` there) that draw the weapons the gallery did not model; default `itemModels` there (deprecated: pass it). */\n items?: ItemModels\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n /** Height things rest on at (x, z): casings and magazines land there. */\n groundAt: (x: number, z: number) => number\n /** Sounds (`createWeaponAudio`); null or absent: silent. */\n audio?: WeaponAudio | null\n /** Seed of the scatter of the effects of the gallery models. */\n seed?: number\n /** The rocket of a launcher flies out of the viewmodel along the barrel (default true). A host that draws the projectile itself (the test room does) sets it to false, so one round flies, not two. */\n flyRocket?: boolean\n /** The tool as it is now (barrel heat, fuel burning). */\n tool?: () => HostTool\n /** Wear of the weapon: `new`, `used`, `worn` or `rusty`. */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n /** Whether shots are in a room or in the open (the gunshot tail). Default outdoor. */\n soundSpace?: () => GunshotSpace\n /** The floor material under a point, for the sound of a case landing there. Default concrete. */\n surfaceAt?: (x: number, z: number) => string | undefined\n /** Told at every sound cue of a reload clip, at the moment the clip says it (also with no audio): the weapon, the cue id and the profile it sounds with. */\n onSound?: (cue: { weapon: string; cue: string; profile: SoundProfile; played?: CuePlayed }) => void\n /** Builders of accessory models that replace or add to the ones the kit ships (by the `model` of the accessory). */\n attachmentModels?: AttachmentModelRegistry\n /** How far a laser beam goes from a point along a direction (metres), or null when it hits nothing: the dot lands where it ends. */\n raycast?: LaserRaycast\n /** Where the world is (distance from a point along a direction to the first surface, or null): the weapon in the hands comes back from a wall it would go through. */\n contact?: LaserRaycast\n /** Where the body holds the tool (`ModuleHost.holdFrame`): third person draws it there at its real size. */\n bodyHold?: () => HandPose | null\n /** Whether the view is the player's own eye: the gallery's guns are then framed in the view (`VIEW_HOLD`) instead of held on the body. */\n firstPerson?: () => boolean\n /** The host's effects: the muzzle flash, smoke, backblast and flame jet of the gallery models are recipes it plays; without it the viewmodel makes a world of its own for them. */\n effects?: EffectSink\n /** The most casings and magazines alive at once (`host.particleLimit`), read at each spawn; without it the viewmodel keeps a cap of its own. */\n particleLimit?: () => number | undefined\n /** The host's light budget (`host.lights`): the rocket in flight and the weapon light ask it for a light; without it they create lights of their own (deprecated, removed in the next major). */\n lights?: LightBudget\n /** The host's pools (`host.pools`): the burning droplets and the ground flames of a flamethrower take their geometry and material from them; without them each makes its own (deprecated, removed in the next major). */\n pools?: RenderPools\n}\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface BoxFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Takes the weapon out of the hands. */\n unequip(): void\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Where the hands take the prop now (world space): the right around its handle, the left under the barrel of a long gun; null with nothing in the hands. */\n handTargets(): HandTargets | null\n /** The front end of the tool in the hands (world space) where its shot, flame or foam leaves, and the way it points; null for a tool with none (a blade, a bare hand). This presentation draws no muzzle flash. */\n muzzle(): MuzzlePose | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/** Weapons that throw the spent case out on every shot. Revolvers keep them in the cylinder; break-actions open on reload. */\nconst EJECTS_ON_SHOT = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper', 'shotgun'])\n/** What leaves from the front end of the tool: a shot, a flame, a jet of heat, the foam of an extinguisher. */\nconst SPOUTS: ReadonlySet<string> = new Set(['firearm', 'flame', 'heat', 'extinguisher'])\n/** Weapons whose reload drops a magazine. */\nconst DROPS_MAGAZINE = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper'])\n/** Manual actions that cycle (pump, bolt) after each shot: the sound of the cycle. */\nconst CYCLES = new Set(['shotgun_pump_12', 'rifle_bolt_308'])\n// a bow, a crossbow or a tool has no calibre: about a small handgun round\nconst FALLBACK_ENERGY = 300\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst GRAVITY = 9.81\n\ninterface Body {\n mesh: THREE_NS.Mesh\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n radius: number\n age: number\n resting: boolean\n bounces: number\n kind: 'casing' | 'magazine'\n}\n\n/** The presentation of a weapon the gallery did not draw (the generic archetypes): a low-poly prop in the hands, a dip on reload and a casing per shot. */\nexport function createBoxFx(options: WeaponFxOptions): BoxFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const bodies: Body[] = []\n const brass = new THREE.MeshStandardMaterial({ color: 0xc9a24a, metalness: 0.8, roughness: 0.35 })\n const shell = new THREE.MeshStandardMaterial({ color: 0xa8322b, roughness: 0.6 })\n const steel = new THREE.MeshStandardMaterial({ color: 0x2f3237, metalness: 0.5, roughness: 0.5 })\n const hand = new THREE.Group()\n hand.name = IN_HAND_NODE_NAME\n scene.add(hand)\n let model: THREE_NS.Object3D | null = null\n let inHand: string | null = null\n let def: WeaponDef | null = null\n let hold: Hold | null = null\n let kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const v2 = new THREE.Vector3()\n const eyeFrame = createEyeFrame(THREE, camera)\n let rear = 0\n let lengthMetres = 0\n const q = new THREE.Quaternion()\n const q2 = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n // the front end of the prop in its own space (x along it)\n const frontOf = new THREE.Vector3()\n\n const equip = (weapon: string): void => {\n if (model) hand.remove(model)\n model = null\n inHand = null\n def = arsenal.weapons.get(weapon) ?? null\n if (!def || BODY_ACTIONS.has(def.id)) return\n model = buildWeaponModel(THREE, def, options.items)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n rear = new THREE.Box3().setFromObject(model).min.x\n lengthMetres = length\n frontOf.copy(new THREE.Box3().setFromObject(model).getCenter(v)).setX(rear + length)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n hold = holdOfProp(THREE, model, def.category, 1)\n }\n\n // a point near the gun, an offset in camera space turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 => {\n if (!model) return out.set(x, y, z).applyQuaternion(camera.quaternion).add(camera.position)\n return out.set(x, y, z).applyQuaternion(camera.quaternion).add(model.getWorldPosition(v2))\n }\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\n if (!(kind === 'casing' ? layers.casings : layers.magazines)) {\n mesh.geometry.dispose()\n return\n }\n const limit = kind === 'casing' ? MAX_CASINGS : MAX_MAGAZINES\n const same = bodies.filter((b) => b.kind === kind)\n if (same.length >= limit) removeBody(same[0])\n mesh.position.copy(from)\n mesh.castShadow = true\n scene.add(mesh)\n bodies.push({ mesh, velocity, spin: new THREE.Vector3(random() * 20 - 10, random() * 30 - 15, random() * 20 - 10), radius, age: 0, resting: false, bounces: 0, kind })\n }\n\n const ejectCasing = (caliberMm: number, isShell: boolean, downward: boolean): void => {\n const radius = isShell ? 0.0105 : Math.max(0.003, (caliberMm / 1000) * 0.6)\n const length = isShell ? 0.068 : Math.min(0.07, Math.max(0.015, (caliberMm / 1000) * 2.6))\n const mesh = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, 8), isShell ? shell : brass)\n mesh.name = 'casing'\n const from = handPoint(0.03, 0.03, 0.05, new THREE.Vector3())\n const right = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)\n const up = new THREE.Vector3(0, 1, 0)\n const velocity = downward\n ? up.clone().multiplyScalar(-0.5).addScaledVector(right, (random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + random() * 0.8).addScaledVector(up, 1.4 + random() * 0.8)\n throwBody('casing', mesh, from, velocity, radius)\n }\n\n const dropMagazine = (category: string): void => {\n const long = category === 'rifle' || category === 'sniper' || category === 'carbine'\n const size: [number, number, number] = long ? [0.03, 0.17, 0.07] : [0.025, 0.11, 0.035]\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(...size), steel)\n mesh.name = 'magazine'\n const from = handPoint(0, -0.06, 0, new THREE.Vector3())\n throwBody('magazine', mesh, from, new THREE.Vector3(0, -0.4, 0), size[1] / 2)\n audio?.reloadStart(category)\n }\n\n const caliberOf = (weapon: WeaponDef): number => {\n if (weapon.action.kind !== 'firearm') return 9\n return arsenal.calibers.get(weapon.action.caliber)?.diameter ?? 9\n }\n\n function removeBody(body: Body): void {\n body.mesh.removeFromParent()\n body.mesh.geometry.dispose()\n bodies.splice(bodies.indexOf(body), 1)\n }\n\n const onShot = (weapon: WeaponDef): void => {\n kick = 1\n const caliber = weapon.action.kind === 'firearm' ? arsenal.calibers.get(weapon.action.caliber) : undefined\n const energy = caliber ? muzzleEnergy(caliber) * (caliber.pellets ?? 1) : FALLBACK_ENERGY\n audio?.shot(energy, weapon.category, { ...(caliber ? { caliber } : {}), distance: options.soundDistance?.() ?? 0, space: options.soundSpace?.() ?? 'outdoor' })\n if (CYCLES.has(weapon.id)) audio?.cycle()\n if (EJECTS_ON_SHOT.has(weapon.category) && weapon.id !== 'shotgun_double_12') ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', false)\n }\n\n const onReloadStart = (weapon: WeaponDef, tool: HostTool): void => {\n if (DROPS_MAGAZINE.has(weapon.category)) dropMagazine(weapon.category)\n else audio?.reloadStart(weapon.category)\n // revolvers and break-action shotguns dump their spent cases when opened\n if (weapon.category === 'revolver' || weapon.id === 'shotgun_double_12') {\n const spent = Math.max(1, tool.capacity - tool.ammo)\n for (let i = 0; i < spent; i++) ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', true)\n }\n }\n\n const stepBody = (body: Body, dt: number): void => {\n body.age += dt\n if (body.resting) return\n body.velocity.y -= GRAVITY * dt\n body.mesh.position.addScaledVector(body.velocity, dt)\n body.mesh.rotation.x += body.spin.x * dt\n body.mesh.rotation.y += body.spin.y * dt\n body.mesh.rotation.z += body.spin.z * dt\n const floor = groundAt(body.mesh.position.x, body.mesh.position.z) + body.radius\n if (body.mesh.position.y > floor) return\n body.mesh.position.y = floor\n if (Math.abs(body.velocity.y) > 0.7 && body.bounces < 4) {\n body.bounces++\n body.velocity.y = -body.velocity.y * 0.35\n body.velocity.x *= 0.55\n body.velocity.z *= 0.55\n body.spin.multiplyScalar(0.5)\n if (body.kind === 'casing') audio?.clink()\n else audio?.thud()\n return\n }\n if (body.kind === 'magazine' && body.bounces === 0) audio?.thud()\n body.resting = true\n body.mesh.rotation.x = Math.PI / 2\n body.mesh.rotation.z = 0\n }\n\n return {\n unequip() {\n if (model) hand.remove(model)\n model = null\n inHand = null\n hold = null\n },\n muzzle() {\n if (!model || !def || !SPOUTS.has(def.action.kind)) return null\n hand.updateMatrixWorld(true)\n const at = model.localToWorld(v.copy(frontOf))\n const along = v2.set(1, 0, 0).applyQuaternion(model.getWorldQuaternion(q2)).normalize()\n return { position: [at.x, at.y, at.z], direction: [along.x, along.y, along.z], drawsFlash: false }\n },\n handTargets() {\n if (!model || !hold) return null\n hand.updateMatrixWorld(true)\n return targetsOf(THREE, hold, model.getWorldQuaternion(q2), 0)\n },\n handle(event, tool) {\n if (event.type === 'explosion' || event.type === 'player' || event.type === 'footfall') return\n const weapon = arsenal.weapons.get(event.weapon)\n if (event.type === 'tool') equip(event.weapon)\n if (!weapon) return\n if (event.type === 'shot') onShot(weapon)\n else if (event.type === 'empty') audio?.click()\n else if (event.type === 'reload' && event.phase === 'start') onReloadStart(weapon, tool)\n else if (event.type === 'reload' && event.phase === 'end') audio?.reloadEnd(weapon.category)\n reloading = tool.reloading\n },\n update(dt) {\n kick *= Math.exp(-dt * 14)\n dip += ((reloading ? 1 : 0) - dip) * Math.min(1, dt * 8)\n if (inHand && model) {\n const handgun = def?.category === 'pistol' || def?.category === 'revolver'\n placeOnBody({ THREE, hand, holder: model, frame: options.bodyHold?.() ?? eyeFrame(), rear, lengthMetres, handgun, right: hold?.right ?? null, left: hold?.left ?? null })\n hand.position.add(v.set(0, -0.12 * dip, 0.05 * kick).applyQuaternion(camera.quaternion))\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.multiply(q)\n }\n for (const body of [...bodies]) {\n stepBody(body, dt)\n if (body.age > LIFETIME_S) removeBody(body)\n }\n },\n get inHand() {\n return inHand\n },\n get casings() {\n return bodies.filter((b) => b.kind === 'casing').length\n },\n get magazines() {\n return bodies.filter((b) => b.kind === 'magazine').length\n },\n dispose() {\n for (const body of [...bodies]) removeBody(body)\n hand.removeFromParent()\n brass.dispose()\n shell.dispose()\n steel.dispose()\n },\n }\n}\n","/** What the bench turns on or off in the presentation of the weapon: the ejected casings, the dropped magazines, the muzzle flash, the accessory models and the light and laser beams. */\nexport interface FxLayers {\n casings: boolean\n magazines: boolean\n muzzleFlash: boolean\n attachments: boolean\n beams: boolean\n}\n\nexport const createLayers = (): FxLayers => ({ casings: true, magazines: true, muzzleFlash: true, attachments: true, beams: true })\n","import type * as THREE_NS from 'three'\nimport type { LaserRaycast } from './models/attachments/types'\n\n/** Names of the groups that hold the weapon in the hands (and the `userData.viewmodel` flag of what holds it: the room marks the player's body): the beam of a laser never lands on its own weapon or its own holder. */\nexport const VIEWMODEL_NODE_NAME = 'weapon-viewmodel'\nexport const IN_HAND_NODE_NAME = 'weapon-in-hand'\n\n/** The laser is measured this many times per second at most; between the casts the last distance holds. */\nexport const LASER_RAYCAST_HZ = 30\n\nconst isHeld = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (node.name === VIEWMODEL_NODE_NAME || node.name === IN_HAND_NODE_NAME || node.userData?.viewmodel === true) return true\n return false\n}\n\n/** A node counts only when it and every ancestor are visible: `Object3D.visible` of a parent hides the children but the raycaster does not look at it. */\nexport const isVisibleInScene = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\nexport interface LaserRaycastOptions {\n /** Milliseconds clock (default `performance.now`). */\n readonly now?: () => number\n}\n\n/** The ray of a laser sight against what is in the scene, ignoring the weapon in the hands, what is hidden (itself or by an ancestor), what is see-through and what is not a surface (particles, sprites). */\nexport const createLaserRaycast = (THREE: typeof THREE_NS, scene: THREE_NS.Scene, camera: THREE_NS.Camera, options: LaserRaycastOptions = {}): LaserRaycast => {\n const now = options.now ?? ((): number => performance.now())\n const interval = 1000 / LASER_RAYCAST_HZ\n const raycaster = new THREE.Raycaster()\n // batched meshes leave the camera layer (createStaticBatcher), not the world: rays still find them\n raycaster.layers.enableAll()\n // the smoke is made of sprites and translucent solids, and the sprites need the camera to be tested at all\n raycaster.camera = camera\n let lastAt = -Infinity\n let lastReach: number | null = null\n return (origin, direction, maxDistance) => {\n const at = now()\n if (at - lastAt < interval) return lastReach\n lastAt = at\n raycaster.set(origin, direction)\n raycaster.far = maxDistance\n const hit = raycaster.intersectObjects(scene.children, true).find((entry) => {\n const mesh = entry.object as THREE_NS.Mesh\n const material = mesh.material as THREE_NS.Material | undefined\n return mesh.isMesh && isVisibleInScene(mesh) && material?.transparent !== true && !isHeld(mesh)\n })\n lastReach = hit ? hit.distance : null\n return lastReach\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { HandPose, HandTargets } from '@adatechnology/game-contracts'\n\nimport type { HandAnchor } from './hand-hold'\n\n/**\n * Where a body holds a tool in a view that shows the body (third person), in the frame the host lends (`ModuleHost.holdFrame`: the pocket of the right shoulder, -z the aim, x right, y up).\n * Metres of a grown body; the tool is drawn at its real size.\n */\nexport const BODY_HOLD = {\n /** With no body to lend the frame: the pocket of the right shoulder from the eye, in the eye's yaw frame (right, up, back). */\n eyeToPocket: [0.2, -0.275, 0.17],\n /** A shouldered gun's bore runs this far above the shoulder pocket (the cheek on the comb). */\n boreAbove: 0.05,\n /** A handgun's (or a short two-hand gun's) grip: toward the middle of the chest, a little low, at the reach of bent arms. */\n handgunGrip: [-0.15, -0.04, -0.42],\n /** A one-hand tool's grip: low in front of the body, the elbow bent. */\n toolGrip: [0.02, -0.34, -0.3],\n /** A tool at least this long, held by two hands, is shouldered (its stock in the pocket). */\n shoulderedFrom: 0.55,\n /** The farthest a shouldered gun's grip sits ahead of the pocket; a launcher whose grip is farther slides back, its tube behind the shoulder. */\n shoulderGripMax: 0.42,\n /** The nearest a shouldered gun's grip sits ahead of the pocket; a gun with no stock (a pistol grip at its rear) slides forward, its grip not behind the eye. */\n shoulderGripMin: 0.25,\n /** Where such a grip is brought to, ahead of the pocket. */\n shoulderGripTo: 0.34,\n /** The farthest apart two hands hold a long gun (a support hand past it slides back along the gun, toward the grip). */\n supportSpan: 0.5,\n /** How much of the aim's pitch a tool held low in one hand follows. */\n toolPitch: 0.5,\n} as const\n\nexport type BodyHoldPlacement = {\n readonly THREE: typeof THREE_NS\n /** The group the viewmodel moves (its `holder` child carries the model). */\n readonly hand: THREE_NS.Object3D\n readonly holder: THREE_NS.Object3D\n readonly frame: HandPose\n /** The rear end of the model along its barrel (model x), metres. */\n readonly rear: number\n readonly lengthMetres: number\n readonly handgun: boolean\n readonly right: HandAnchor | null\n readonly left: HandAnchor | null\n}\n\nconst scratch = { a: null as THREE_NS.Vector3 | null, b: null as THREE_NS.Vector3 | null, euler: null as THREE_NS.Euler | null }\n\n/** Puts the tool on the body at its real size: a long two-hand gun with its stock in the shoulder pocket, anything else with its grip where a hand holds it ready. */\nexport const placeOnBody = (placement: BodyHoldPlacement): void => {\n const { THREE, hand, holder, frame } = placement\n scratch.a ??= new THREE.Vector3()\n scratch.b ??= new THREE.Vector3()\n holder.scale.setScalar(1)\n hand.position.set(...frame.position)\n hand.quaternion.set(...frame.quaternion)\n const shouldered = !placement.handgun && placement.left !== null && placement.lengthMetres >= BODY_HOLD.shoulderedFrom\n if (shouldered) {\n // the model's barrel (x) runs down the aim (-z) by the holder's quarter turn: the rear end at the pocket\n holder.position.set(0, BODY_HOLD.boreAbove, placement.rear)\n hand.updateMatrixWorld(true)\n if (!placement.right) return\n const grip = hand.worldToLocal(placement.right.part.localToWorld(scratch.a.copy(placement.right.offset)))\n if (-grip.z <= BODY_HOLD.shoulderGripMax && -grip.z >= BODY_HOLD.shoulderGripMin) return\n holder.position.z += -grip.z - BODY_HOLD.shoulderGripTo\n hand.updateMatrixWorld(true)\n return\n }\n // a tool held low in one hand follows the aim's pitch only partly, so a look down does not fold the wrist into the shoulder\n scratch.euler ??= new THREE.Euler()\n const turn = scratch.euler.setFromQuaternion(hand.quaternion, 'YXZ')\n hand.quaternion.setFromEuler(turn.set(turn.x * BODY_HOLD.toolPitch, turn.y, 0, 'YXZ'))\n holder.position.set(0, 0, 0)\n hand.updateMatrixWorld(true)\n if (!placement.right) return\n // a short gun with a support hand is held like a handgun, in the middle of the chest, not low like a one-hand tool\n const grip = placement.handgun || placement.left ? BODY_HOLD.handgunGrip : BODY_HOLD.toolGrip\n const want = scratch.a.set(grip[0], grip[1], grip[2]).applyQuaternion(hand.quaternion).add(hand.position)\n const now = placement.right.part.localToWorld(scratch.b.copy(placement.right.offset))\n hand.position.add(want.sub(now))\n hand.updateMatrixWorld(true)\n}\n\n/** A support hand too far from the grip for two arms (a long rifle's forend) slides back along the gun toward the grip, to `supportSpan`. */\nexport const limitSupportSpan = (targets: HandTargets): HandTargets => {\n const right = targets.R?.position\n const left = targets.L?.position\n if (!right || !left || !targets.L) return targets\n const span = Math.hypot(left[0] - right[0], left[1] - right[1], left[2] - right[2])\n if (span <= BODY_HOLD.supportSpan) return targets\n const k = BODY_HOLD.supportSpan / span\n const position: [number, number, number] = [right[0] + (left[0] - right[0]) * k, right[1] + (left[1] - right[1]) * k, right[2] + (left[2] - right[2]) * k]\n return { ...targets, L: { ...targets.L, position } }\n}\n\n/** With no body to lend `holdFrame`: the pocket of a body's right shoulder under the camera's eye (`BODY_HOLD.eyeToPocket`, turned by the camera's yaw), the frame turned to the camera's aim. */\nexport const createEyeFrame = (THREE: typeof THREE_NS, camera: THREE_NS.Camera): (() => HandPose) => {\n const frame: { position: [number, number, number]; quaternion: [number, number, number, number] } = { position: [0, 0, 0], quaternion: [0, 0, 0, 1] }\n const turn = new THREE.Euler(0, 0, 0, 'YXZ')\n const pocket = new THREE.Vector3()\n return () => {\n turn.setFromQuaternion(camera.quaternion, 'YXZ')\n pocket.set(...BODY_HOLD.eyeToPocket).applyEuler(turn.set(0, turn.y, 0)).add(camera.position)\n frame.position = [pocket.x, pocket.y, pocket.z]\n frame.quaternion = [camera.quaternion.x, camera.quaternion.y, camera.quaternion.z, camera.quaternion.w]\n return frame\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { HandPose, HandTargets } from '@adatechnology/game-contracts'\nimport type { WeaponModel } from '../models'\nimport type { HandWork } from './hand-work'\n\n/**\n * How the hands take a tool, in metres of the model. Constants of the grip (the thickness of a palm against the thing it holds), not of any weapon: the models say where their grip is.\n */\nexport const HAND_HOLD = {\n /** Half the width of a pistol grip, the palm sits this far (plus the palm) off its middle. */\n gripHalfWidth: 0.0145,\n /** Half the thickness of a palm. */\n palm: 0.011,\n /** How far up the grip the web of the hand sits from its middle. */\n gripUp: 0.006,\n /** How far down the grip the supporting hand of a pistol sits from the middle. */\n supportDown: 0.036,\n /** Where along the handguard (0 the receiver, 1 the end of the forend) the supporting hand closes. */\n forendAt: 0.6,\n /** How far under the handguard the palm sits (half a handguard plus the palm). */\n forendUnder: 0.034,\n /** The grip of a long gun that has no drawn pistol grip: how far under the receiver the hand sits. */\n strapUnder: 0.04,\n /** How far lower than touching the palm hangs under a handguard, so the fingers close under it and not over it. */\n forendDrop: 0.03,\n /** How far (radians) the fingers of a support hand under a handguard rise from level. */\n forendTilt: 0.5,\n /** How far a handgun's support hand dips for the new magazine, along the grip. */\n magDip: 0.045,\n /** Closure of the fingers on a grip and on a forend (0 open, 1 closed). */\n closed: 0.9,\n forend: 0.6,\n /** How far the shooting hand slides on its grip so the thumb reaches the safety lever. */\n thumbReach: 0.02,\n /** How fast the supporting hand goes to the magazine and back, per second. */\n magRate: 7,\n} as const\n\n/** A point a hand holds: `offset` in the local space of `part` and the hand's orientation in the model root's space. */\nexport interface HandAnchor {\n part: THREE_NS.Object3D\n offset: THREE_NS.Vector3\n quaternion: THREE_NS.Quaternion\n}\n\n/** Where the hands take a model. `leftMagazine` is where the supporting hand goes while the magazine is changed. */\nexport interface Hold {\n right: HandAnchor | null\n left: HandAnchor | null\n leftMagazine: HandAnchor | null\n scale: number\n grip: number\n gripLeft: number\n /** What the hands do to the parts the clips move (`handWorkOf`); empty until the viewmodel adds it. */\n works?: readonly HandWork[]\n}\n\ntype Three = typeof THREE_NS\n\n/** The orientation whose hand-local x is `x` and y is `y` (z follows from the right-handed frame), both in the space they are given in. */\nexport const handFrame = (THREE: Three, x: THREE_NS.Vector3, y: THREE_NS.Vector3): THREE_NS.Quaternion => {\n const ax = x.clone().normalize()\n const az = ax.clone().cross(y).normalize()\n const ay = az.clone().cross(ax)\n return new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().makeBasis(ax, ay, az))\n}\n\n/** The pose a `Hold` gives a hand now, in the world; `rootQuaternion` is the world rotation of the model root. */\nexport const poseOf = (anchor: HandAnchor, rootQuaternion: THREE_NS.Quaternion): HandPose => {\n const position = anchor.part.localToWorld(anchor.offset.clone())\n const q = rootQuaternion.clone().multiply(anchor.quaternion)\n return { position: [position.x, position.y, position.z], quaternion: [q.x, q.y, q.z, q.w] }\n}\n\n/** Mixes two poses (the supporting hand between the forend and the magazine). */\nexport const blendPose = (THREE: Three, a: HandPose, b: HandPose, k: number): HandPose => {\n const q = new THREE.Quaternion(...a.quaternion).slerp(new THREE.Quaternion(...b.quaternion), k)\n return {\n position: [a.position[0] + (b.position[0] - a.position[0]) * k, a.position[1] + (b.position[1] - a.position[1]) * k, a.position[2] + (b.position[2] - a.position[2]) * k],\n quaternion: [q.x, q.y, q.z, q.w],\n }\n}\n\n/** The targets of a hold: the right hand, the supporting hand (moved toward the magazine by `magazine` 0..1), the grip and the size of the hands. */\nexport const targetsOf = (THREE: Three, hold: Hold, rootQuaternion: THREE_NS.Quaternion, magazine: number, weights?: readonly number[]): HandTargets => {\n let right = hold.right ? poseOf(hold.right, rootQuaternion) : null\n let left: HandPose | null = null\n if (hold.left) {\n left = poseOf(hold.left, rootQuaternion)\n if (hold.leftMagazine && magazine > 0) left = blendPose(THREE, left, poseOf(hold.leftMagazine, rootQuaternion), magazine)\n }\n // the hand that works a part leaves what it was holding and goes to the part for as long as the clip moves it\n hold.works?.forEach((work, index) => {\n const k = weights?.[index] ?? 0\n if (k <= 0) return\n const pose = poseOf(work.anchor, rootQuaternion)\n if (work.hand === 'R') right = right ? blendPose(THREE, right, pose, k) : pose\n else left = left ? blendPose(THREE, left, pose, k) : pose\n })\n return { R: right, L: left, grip: hold.grip, gripL: hold.gripLeft, scale: hold.scale }\n}\n\nconst V = (THREE: Three, x: number, y: number, z: number): THREE_NS.Vector3 => new THREE.Vector3(x, y, z)\n\n/** The palm lies on the right (or left) side of a vertical-ish grip, the fingers go forward and wrap around the front of it. `axis` is the way up the grip, in the space of `root`. */\nconst gripFrame = (THREE: Three, up: THREE_NS.Vector3, side: 1 | -1): THREE_NS.Quaternion => {\n const forward = V(THREE, 1, 0, 0)\n const toSide = V(THREE, 0, 0, 1)\n // fingers along the weapon's x turned with the grip's tilt; the back of the hand to the side the palm is on\n const tilt = new THREE.Quaternion().setFromUnitVectors(V(THREE, 0, 1, 0), up)\n return handFrame(THREE, forward.clone().applyQuaternion(tilt), toSide.clone().applyQuaternion(tilt).multiplyScalar(side))\n}\n\n/** The palm under a forend (palm up, back of the hand down), the fingers going to the right and closing up its right side, the thumb forward along its left. `tilt` raises the fingers, so the wrist is below and to the left: the forearm comes from under the gun. */\nconst forendFrame = (THREE: Three, tilt = 0): THREE_NS.Quaternion => handFrame(THREE, V(THREE, 0, Math.sin(tilt), Math.cos(tilt)), V(THREE, 0, -Math.cos(tilt), Math.sin(tilt)))\n\n/** The hold of a gallery model: the right hand on the pistol grip, the left on the forend (or wrapped under the right on a handgun), on the pump of a pump gun, on the magazine while it is changed. */\nexport function holdOfModel(THREE: Three, model: WeaponModel, holderScale: number): Hold {\n const { root, inner, parts } = model\n const frames = parts.frames\n const toRoot = (x: number, y: number, z: number): THREE_NS.Vector3 => V(THREE, inner.position.x + x * inner.scale.x, y, z)\n const handgun = parts.family === 'pistol' || parts.family === 'revolver'\n root.updateWorldMatrix(true, true)\n\n // the right hand: on the pivot of the drawn pistol grip, else under the receiver at the grip's x\n let gripAt: THREE_NS.Vector3\n let up: THREE_NS.Vector3\n if (parts.grip) {\n gripAt = toRoot(parts.grip.position.x, parts.grip.position.y, parts.grip.position.z)\n up = V(THREE, 0, 1, 0).applyQuaternion(parts.grip.quaternion)\n } else {\n const receiverHeight = frames?.receiverHeight ?? 0.06\n gripAt = toRoot(frames?.gripX ?? 0.07, -receiverHeight / 2 - HAND_HOLD.strapUnder, 0)\n up = V(THREE, Math.sin(0.3), Math.cos(0.3), 0)\n }\n const side = HAND_HOLD.gripHalfWidth + HAND_HOLD.palm\n const right: HandAnchor = {\n part: root,\n offset: gripAt.clone().addScaledVector(up, HAND_HOLD.gripUp).add(V(THREE, 0, 0, side)),\n quaternion: gripFrame(THREE, up, 1),\n }\n\n let left: HandAnchor | null = null\n let leftMagazine: HandAnchor | null = null\n if (handgun) {\n // both hands on a handgun: the left wraps the grip from its side, under the fingers of the right\n left = { part: root, offset: gripAt.clone().addScaledVector(up, -HAND_HOLD.supportDown).add(V(THREE, 0, 0, -side)), quaternion: gripFrame(THREE, up, -1) }\n } else if (parts.pump) {\n const box = new THREE.Box3().setFromObject(parts.pump)\n const center = box.getCenter(new THREE.Vector3())\n const under = parts.pump.worldToLocal(V(THREE, center.x, box.min.y - HAND_HOLD.palm, center.z))\n left = { part: parts.pump, offset: under, quaternion: forendFrame(THREE) }\n } else if (frames) {\n const handguardHeight = frames.receiverHeight * 0.8\n const x = frames.receiverEnd + (frames.handguardEnd - frames.receiverEnd) * HAND_HOLD.forendAt\n left = { part: root, offset: toRoot(x, frames.barrelY - handguardHeight / 2 - HAND_HOLD.palm - HAND_HOLD.forendDrop, 0), quaternion: forendFrame(THREE, HAND_HOLD.forendTilt) }\n }\n if (left && parts.mag) {\n const box = new THREE.Box3().setFromObject(parts.mag)\n const center = box.getCenter(new THREE.Vector3())\n // the magazine well of a handgun is inside the grip: the hand goes under its base, where the new magazine is slapped in\n const local = parts.mag.worldToLocal(V(THREE, center.x, box.min.y - HAND_HOLD.palm, center.z))\n // a handgun's new magazine comes from the belt: the hand dips a little along the grip and stays in the view; a long gun's goes under its magazine\n leftMagazine = handgun && left ? { part: root, offset: left.offset.clone().addScaledVector(up, -HAND_HOLD.magDip), quaternion: left.quaternion } : { part: parts.mag, offset: local, quaternion: forendFrame(THREE) }\n }\n return {\n right,\n left,\n leftMagazine,\n // the hands at the tool's scale: a tool drawn smaller than the hands looks like a toy in them\n scale: holderScale,\n grip: HAND_HOLD.closed,\n gripLeft: HAND_HOLD.forend,\n }\n}\n\n/** The generic low-poly props (a handle and a head lying along x): the right hand around the handle, the left under the head of a long gun. */\nexport function holdOfProp(THREE: Three, group: THREE_NS.Object3D, category: string, scale: number): Hold {\n const handle = group.getObjectByName('handle') ?? group.getObjectByName('body') ?? group\n const head = group.getObjectByName('head')\n const size = (object: THREE_NS.Object3D): THREE_NS.Vector3 => new THREE.Box3().setFromObject(object).getSize(new THREE.Vector3())\n // the handle's long axis is x: the fingers wrap about it, the palm on the right\n const wrap = handFrame(THREE, V(THREE, 0, 1, 0), V(THREE, 0, 0, 1))\n const handleSize = size(handle)\n const right: HandAnchor = { part: group, offset: handle.position.clone().add(V(THREE, 0, handleSize.y / 2 + 0.002, 0)), quaternion: wrap }\n // a long gun's head is its barrel: the left hand under it\n const long = head && ['smg', 'carbine', 'rifle', 'sniper', 'shotgun', 'crossbow', 'flame'].includes(category)\n const headSize = head ? size(head) : null\n const left: HandAnchor | null =\n long && head && headSize ? { part: group, offset: head.position.clone().add(V(THREE, -headSize.x * 0.15, -headSize.y / 2 - HAND_HOLD.palm, 0)), quaternion: forendFrame(THREE) } : null\n return { right, left, leftMagazine: null, scale, grip: HAND_HOLD.closed, gripLeft: HAND_HOLD.forend }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\n\n/** A low-poly prop: its destruction spec (box parts only) and one colour per part. */\nexport interface WeaponProp {\n spec: DestructibleSpec\n colors: Record<string, number>\n}\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind']): JointSpec => ({ a, b, kind })\n\n// A grip and a body lying flat end to end, long axis along +x, the muzzle or head at +x. One thickness for both parts so the prop lies flat,\n// and the parts touch without overlapping: overlapping parts are pushed apart by the physics and the prop slides away.\nconst handled = (name: string, handle: [string, Vec3], head: [string, Vec3]): WeaponProp => {\n const [handleMaterial, rawHandle] = handle\n const [headMaterial, rawHead] = head\n const thickness = Math.max(rawHandle[1], rawHead[1])\n const handleSize: Vec3 = [rawHandle[0], thickness, rawHandle[2]]\n const headSize: Vec3 = [rawHead[0], thickness, rawHead[2]]\n const shift = (handleSize[0] - headSize[0]) / 2\n return {\n spec: {\n name,\n parts: [box('handle', handleMaterial, handleSize, [-handleSize[0] / 2 + shift, thickness / 2, 0]), box('head', headMaterial, headSize, [headSize[0] / 2 + shift, thickness / 2, 0])],\n joints: [joint('handle', 'head', 'screw')],\n tags: ['weapon'],\n },\n colors: { handle: handleMaterial === 'steel' ? 0x3a3d42 : handleMaterial === 'plastic' ? 0x2b2d30 : 0x7a5530, head: headMaterial === 'steel' ? 0x8f969e : headMaterial === 'copper' ? 0xb87333 : 0x6b4a2a },\n }\n}\nconst solid = (name: string, material: string, size: Vec3, color: number): WeaponProp => ({\n spec: { name, parts: [box('body', material, size, [0, size[1] / 2, 0])], joints: [], tags: ['weapon'] },\n colors: { body: color },\n})\n\nconst SHAPES: Record<string, (name: string, id: string) => WeaponProp> = {\n pistol: (n) => handled(n, ['plastic', [0.06, 0.03, 0.11]], ['steel', [0.2, 0.03, 0.04]]),\n revolver: (n) => handled(n, ['wood_soft', [0.06, 0.035, 0.11]], ['steel', [0.24, 0.04, 0.05]]),\n smg: (n) => handled(n, ['plastic', [0.2, 0.05, 0.14]], ['steel', [0.45, 0.05, 0.06]]),\n carbine: (n) => handled(n, ['wood_soft', [0.35, 0.05, 0.12]], ['steel', [0.6, 0.04, 0.05]]),\n rifle: (n) => handled(n, ['wood_soft', [0.35, 0.06, 0.13]], ['steel', [0.75, 0.05, 0.07]]),\n sniper: (n) => handled(n, ['plastic', [0.4, 0.06, 0.14]], ['steel', [0.95, 0.06, 0.08]]),\n shotgun: (n) => handled(n, ['wood_soft', [0.38, 0.06, 0.13]], ['steel', [0.7, 0.05, 0.06]]),\n bow: (n) => solid(n, 'wood_soft', [0.95, 0.03, 0.22], 0x5a3d22),\n crossbow: (n) => handled(n, ['wood_soft', [0.6, 0.06, 0.08]], ['steel', [0.12, 0.04, 0.26]]),\n melee_blunt: (n, id) =>\n id === 'baseball_bat'\n ? solid(n, 'wood_soft', [0.84, 0.06, 0.06], 0xb08550)\n : handled(n, ['wood_soft', [id === 'sledgehammer' ? 0.8 : 0.32, 0.03, 0.03]], ['steel', id === 'sledgehammer' ? [0.08, 0.08, 0.2] : [0.06, 0.04, 0.12]]),\n melee_blade: (n, id) => handled(n, ['wood_soft', [0.13, 0.03, 0.03]], ['steel', id === 'axe' ? [0.5, 0.03, 0.16] : id === 'knife' ? [0.16, 0.01, 0.03] : [0.45, 0.01, 0.05]]),\n tool: (n) => handled(n, ['plastic', [0.12, 0.025, 0.03]], ['steel', [0.16, 0.02, 0.03]]),\n flame: (n, id) => (id === 'flamethrower' ? handled(n, ['steel', [0.3, 0.14, 0.14]], ['steel', [0.6, 0.05, 0.05]]) : solid(n, 'plastic', [0.08, 0.02, 0.04], 0xd9482b)),\n heat: (n) => handled(n, ['steel', [0.2, 0.08, 0.08]], ['copper', [0.25, 0.03, 0.03]]),\n throwable: (n, id) => (id === 'molotov' ? solid(n, 'glass', [0.25, 0.07, 0.07], 0x7fd6b0) : solid(n, 'steel', [id === 'pipe_bomb' ? 0.25 : 0.1, 0.06, 0.06], 0x4c5a3a)),\n extinguisher: (n) => solid(n, 'steel', [0.5, 0.15, 0.15], 0xc0392b),\n}\n\n/** Body actions of the arsenal: nothing to hold or lay on a counter. */\nexport const BODY_ACTIONS: ReadonlySet<string> = new Set(['hand', 'kick', 'shove', 'fists'])\n\n// Real weights from the arsenal data: solid steel boxes would weigh several times more, go past a carry limit and stop being props.\nconst withMass = (prop: WeaponProp, kg: number): WeaponProp => {\n const volumes = prop.spec.parts.map((part) => (part.shape.kind === 'box' ? part.shape.size[0] * part.shape.size[1] * part.shape.size[2] : 0))\n const total = volumes.reduce((sum, volume) => sum + volume, 0) || 1\n return { ...prop, spec: { ...prop.spec, parts: prop.spec.parts.map((part, index) => ({ ...part, mass: (kg * volumes[index]) / total })) } }\n}\n\n/** The prop of a weapon: low-poly parts by category, the real mass of the weapon spread over them. */\nexport function weaponProp(def: Pick<WeaponDef, 'id' | 'category' | 'mass'>, name = def.id): WeaponProp {\n const shape = SHAPES[def.category] ?? SHAPES.tool\n return withMass(shape(name, def.id), def.mass)\n}\n\n/** One mesh per box part, named after the part (what destruction renderers bind to), in a group with its origin on the floor. */\nexport function buildProp(THREE: typeof THREE_NS, prop: WeaponProp): THREE_NS.Group {\n const group = new THREE.Group()\n group.name = prop.spec.name ?? 'weapon'\n for (const part of prop.spec.parts) {\n if (part.shape.kind !== 'box') continue\n const [w, h, d] = part.shape.size\n const material = new THREE.MeshStandardMaterial({ color: prop.colors[part.id] ?? 0x777777, roughness: 0.6, metalness: part.material === 'steel' ? 0.6 : 0.05 })\n const mesh = new THREE.Mesh(new (shapeGeometries(THREE).BoxGeometry)(w, h, d), material)\n mesh.name = part.id\n mesh.position.set(part.position[0], part.position[1], part.position[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n return group\n}\n","import type * as THREE_NS from 'three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\n\nimport { DEFAULT_ITEM_MODELS } from './item-models'\nimport type { ItemModels } from './item-models'\n\nexport type DrawItemWeaponParams = {\n readonly THREE: typeof THREE_NS\n readonly def: Pick<WeaponDef, 'id'>\n readonly items: ItemModels | undefined\n /** The item model id that draws the weapon. */\n readonly itemId: string\n readonly turn: number\n readonly flip: boolean\n}\n\ntype Context = { readonly THREE: typeof THREE_NS; readonly group: THREE_NS.Group; readonly root: THREE_NS.Object3D }\n\nconst sizeOf = ({ THREE, group, root }: Context): THREE_NS.Vector3 => {\n group.updateMatrixWorld(true)\n return new THREE.Box3().setFromObject(root).getSize(new THREE.Vector3())\n}\n\n// the long axis along x, the thinnest along y, then the quarter turns the data asks for\nfunction layFlat(context: Context, turn: number): void {\n const { THREE, root } = context\n let size = sizeOf(context)\n if (size.y > size.x && size.y >= size.z) root.rotateOnWorldAxis(new THREE.Vector3(0, 0, 1), -Math.PI / 2)\n else if (size.z > size.x && size.z > size.y) root.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n size = sizeOf(context)\n if (size.z < size.y) root.rotateOnWorldAxis(new THREE.Vector3(1, 0, 0), Math.PI / 2)\n if (turn) root.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), (turn * Math.PI) / 2)\n}\n\n// the reach across the floor (z) of each half of the item, split at the middle of its length\nfunction reachOfHalves({ THREE, root }: Context): number[] {\n const box = new THREE.Box3().setFromObject(root)\n const middle = (box.min.x + box.max.x) / 2\n const span = [\n [Infinity, -Infinity],\n [Infinity, -Infinity],\n ]\n const point = new THREE.Vector3()\n root.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n const position = mesh.isMesh ? mesh.geometry.getAttribute('position') : undefined\n if (!position) return\n for (let i = 0; i < position.count; i++) {\n point.fromBufferAttribute(position, i).applyMatrix4(mesh.matrixWorld)\n const half = span[point.x > middle ? 1 : 0]\n half[0] = Math.min(half[0], point.z)\n half[1] = Math.max(half[1], point.z)\n }\n })\n return span.map(([low, high]) => high - low)\n}\n\n// the head is the wider end: it goes to +x\nfunction headToPositiveX(context: Context, flip: boolean): void {\n const reach = reachOfHalves(context)\n if (reach[0] > reach[1] !== flip) context.root.rotateOnWorldAxis(new context.THREE.Vector3(0, 1, 0), Math.PI)\n}\n\n// origin at the bottom centre, an empty `handle` at the narrow end where the hand closes\nfunction restOnFloor({ THREE, group, root }: Context): void {\n group.updateMatrixWorld(true)\n const laid = new THREE.Box3().setFromObject(root)\n const centre = laid.getCenter(new THREE.Vector3())\n root.position.sub(new THREE.Vector3(centre.x, laid.min.y, centre.z))\n const length = laid.max.x - laid.min.x\n const handle = new THREE.Object3D()\n handle.name = 'handle'\n handle.position.set(-length * 0.35, 0, 0)\n group.add(handle)\n root.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n if (!mesh.isMesh) return\n mesh.castShadow = true\n mesh.receiveShadow = true\n })\n}\n\nexport function drawItemWeapon({ THREE, def, items, itemId, turn, flip }: DrawItemWeaponParams): THREE_NS.Group {\n const { root } = (items ?? DEFAULT_ITEM_MODELS).build(THREE, { id: itemId, category: 'weapon', size: [0, 0, 0], model: itemId })\n const group = markKitOrigin(new THREE.Group(), { owner: 'game-weapons-three', kind: 'weapon', id: def.id })\n group.name = def.id\n group.add(root)\n const context: Context = { THREE, group, root }\n layFlat(context, turn)\n headToPositiveX(context, flip)\n restOnFloor(context)\n return group\n}\n","import { itemModels } from '@adatechnology/game-items-three'\nimport type * as THREE_NS from 'three'\n\n/** What a weapon or an explosive asks of an item model: the fields of `DrawableItem` of game-items-three that it fills in. */\nexport interface ItemModelRequest {\n id: string\n category: string\n size: [number, number, number]\n model?: string\n}\n\n/**\n * The item models of game-items-three, lent by the host as `items`; `itemModels` of game-items-three fits it, and the host that passes none gets it as the default.\n * The default is deprecated and removed in the next major: pass `items`.\n */\nexport interface ItemModels {\n has(id: string): boolean\n /** `wear`: 0 new, 1 used, 2 spoiled. */\n build(THREE: typeof THREE_NS, item: ItemModelRequest, options?: { wear?: 0 | 1 | 2 }): { root: THREE_NS.Group; kind: string }\n}\n\n/** What the weapons draw with when the host passes no `items`: the item models of game-items-three, as before the `items` option existed. */\nexport const DEFAULT_ITEM_MODELS: ItemModels = itemModels\n","import { markKitOrigin } from '@adatechnology/game-contracts'\nimport type * as THREE_NS from 'three'\n\nimport { modelKit } from './kit'\nimport type { ModelKit } from './kit'\n\ntype ExplosiveBuilder = (kit: ModelKit, group: THREE_NS.Group) => void\n\n// Port of the gallery's `buildExp` (Galeria 3D do Arsenal, explosivos): same measures in metres, same parts, same order; each stands on its base, y up.\n// The `handle` mark is where the hand closes: the middle of the body.\nconst grenade: ExplosiveBuilder = (kit, group) => {\n const { M, sphere, cylinderY, box, torus, THREE } = kit\n sphere(group, 0.032, M.olive, 0, 0.032, 0, 1)\n cylinderY(group, 0.011, 0.022, M.metal, 0, 0.072, 0)\n box(group, 0.012, 0.07, 0.006, M.metal, 0.016, 0.05, 0, 0.2)\n torus(group, new THREE.TorusGeometry(0.0085, 0.0016, 6, 12), M.steel, -0.012, 0.082, 0)\n kit.mark(group, 0, 0.032, 0).name = 'handle'\n}\n\nconst molotov: ExplosiveBuilder = (kit, group) => {\n const { M, cylinderY, box } = kit\n cylinderY(group, 0.036, 0.17, M.bottle, 0, 0.085, 0, 10)\n cylinderY(group, 0.012, 0.06, M.bottle, 0, 0.2, 0, 8, 0.036)\n box(group, 0.03, 0.08, 0.02, M.white, 0.005, 0.25, 0, 0.3)\n cylinderY(group, 0.02, 0.07, M.fire, 0.01, 0.31, 0, 6, 0).userData.flame = true\n kit.mark(group, 0, 0.085, 0).name = 'handle'\n}\n\nconst pipeBomb: ExplosiveBuilder = (kit, group) => {\n const { M, cylinderX, cylinderY } = kit\n cylinderX(group, 0.025, 0.2, M.metal, 0, 0.03, 0, 8)\n cylinderX(group, 0.031, 0.025, M.dark, -0.1, 0.03, 0, 6)\n cylinderX(group, 0.031, 0.025, M.dark, 0.1, 0.03, 0, 6)\n cylinderY(group, 0.002, 0.06, M.white, 0.1, 0.07, 0)\n kit.mark(group, 0, 0.03, 0).name = 'handle'\n}\n\nconst dynamite: ExplosiveBuilder = (kit, group) => {\n const { M, cylinderX } = kit\n for (const [z, y] of [[-0.015, 0], [0.015, 0], [0, 0.026]] as const) cylinderX(group, 0.014, 0.2, M.dynamite, 0, 0.016 + y, z, 8)\n cylinderX(group, 0.031, 0.03, M.dark, -0.04, 0.025, 0, 8)\n cylinderX(group, 0.031, 0.03, M.dark, 0.05, 0.025, 0, 8)\n cylinderX(group, 0.002, 0.1, M.white, 0.14, 0.03, 0, 4)\n kit.mark(group, 0, 0.025, 0).name = 'handle'\n}\n\nconst c4: ExplosiveBuilder = (kit, group) => {\n const { M, box, cylinderY } = kit\n box(group, 0.28, 0.05, 0.11, M.c4, 0, 0.025, 0)\n box(group, 0.05, 0.03, 0.04, M.dark, 0.06, 0.065, 0)\n cylinderY(group, 0.004, 0.05, M.metal, 0.03, 0.07, 0)\n box(group, 0.24, 0.003, 0.003, M.wire, 0.18, 0.055, 0.02)\n box(group, 0.24, 0.003, 0.003, M.metal, 0.18, 0.055, 0.03)\n kit.mark(group, 0, 0.025, 0).name = 'handle'\n}\n\nconst claymore: ExplosiveBuilder = (kit, group) => {\n const { M, box } = kit\n for (const i of [-1, 0, 1]) box(group, 0.075, 0.083, 0.035, M.olive, i * 0.072, 0.12, Math.abs(i) * 0.012, 0, -i * 0.25)\n for (const [x, z] of [[-0.07, 0.03], [-0.07, -0.03], [0.07, 0.03], [0.07, -0.03]] as const) box(group, 0.004, 0.09, 0.004, M.metal, x, 0.04, z, x > 0 ? -0.25 : 0.25)\n kit.mark(group, 0, 0.12, 0).name = 'handle'\n}\n\nconst flashbang: ExplosiveBuilder = (kit, group) => {\n const { M, cylinderY, box } = kit\n cylinderY(group, 0.022, 0.13, M.olive, 0, 0.065, 0, 10)\n for (let i = 0; i < 4; i++) cylinderY(group, 0.023, 0.008, M.dark, 0, 0.025 + i * 0.028, 0, 10)\n cylinderY(group, 0.012, 0.02, M.metal, 0, 0.14, 0)\n box(group, 0.01, 0.08, 0.005, M.metal, 0.024, 0.1, 0, 0.15)\n kit.mark(group, 0, 0.065, 0).name = 'handle'\n}\n\n// the explosives of game-weapons each builder draws (the gallery's keys: granada, molotov, pipe, dyn, c4, claymore, flash)\nconst BUILDERS: Readonly<Record<string, ExplosiveBuilder>> = {\n m67: grenade,\n molotov,\n pipe_bomb: pipeBomb,\n dynamite,\n c4,\n claymore,\n flashbang,\n}\n\n/** The explosive ids of game-weapons the gallery drew (`m67`, `molotov`, `pipe_bomb`, `dynamite`, `c4`, `claymore`, `flashbang`). */\nexport const EXPLOSIVE_MODEL_IDS: readonly string[] = Object.keys(BUILDERS)\n\nexport const hasExplosiveModel = (explosiveId: string): boolean => explosiveId in BUILDERS\n\n/** The gallery model of an explosive standing on its base (y up, origin at the bottom centre, a `handle` mark where the hand closes); undefined for one the gallery did not draw. */\nexport function buildExplosiveModel(THREE: typeof THREE_NS, explosiveId: string): THREE_NS.Group | undefined {\n const builder = BUILDERS[explosiveId]\n if (!builder) return undefined\n const kit = modelKit(THREE)\n const group = markKitOrigin(kit.group(), { owner: 'game-weapons-three', kind: 'explosive', id: explosiveId })\n group.name = explosiveId\n builder(kit, group)\n return group\n}\n","import { markShared, shapeGeometries } from '@adatechnology/game-shapes-three'\nimport type * as THREE_NS from 'three'\nimport { createRoundedBoxGeometry } from './rounded-box'\n\ntype Three = typeof THREE_NS\ntype Material = THREE_NS.Material\nexport type Parent = THREE_NS.Object3D\n\nconst PI = Math.PI\n\nconst createMaterials = (THREE: Three) => {\n const standard = (color: number, roughness = 0.7, metalness = 0.2, extra: THREE_NS.MeshStandardMaterialParameters = {}): THREE_NS.MeshStandardMaterial =>\n new THREE.MeshStandardMaterial({ color, roughness, metalness, ...extra })\n const basic = (color: number, extra: THREE_NS.MeshBasicMaterialParameters = {}): THREE_NS.MeshBasicMaterial => new THREE.MeshBasicMaterial({ color, ...extra })\n const additive = { transparent: true, opacity: 0.95, blending: THREE.AdditiveBlending, depthWrite: false }\n const materials = {\n metal: standard(0x34373a, 0.42, 0.75),\n steel: standard(0x6c6f72, 0.32, 0.85),\n steelL: standard(0x8a8d90, 0.28, 0.9),\n dark: standard(0x1a1c1d, 0.55, 0.5),\n poly: standard(0x242622, 0.8, 0.05),\n olive: standard(0x4b5231, 0.8, 0.05),\n tan: standard(0x9c8a63, 0.8, 0.05),\n wood: standard(0x4a2c17, 0.55, 0),\n woodL: standard(0x5e3a1f, 0.55, 0),\n brass: standard(0xc39a45, 0.28, 0.9),\n copper: standard(0xb06a3b, 0.3, 0.85),\n lead: standard(0x6d6f73, 0.5, 0.5),\n shell: standard(0xa3271c, 0.5, 0.05),\n glass: standard(0x7fa3a8, 0.05, 0.1, { transparent: true, opacity: 0.42 }),\n lens: standard(0x23465a, 0.05, 0.3, { transparent: true, opacity: 0.9, emissive: 0x061820 }),\n rubber: standard(0x151515, 0.85, 0),\n white: standard(0xcfc8b4, 0.8, 0),\n hole: standard(0x080807, 1, 0),\n bake: standard(0x5a3220, 0.55, 0),\n rust: standard(0x6b3a1e, 0.95, 0.3),\n rustD: standard(0x4a2a18, 0.95, 0.25),\n worn: standard(0x55585a, 0.6, 0.6),\n fire: basic(0xff7a22),\n fire2: basic(0xffcf5a),\n flashA: basic(0xffb347, additive),\n flashB: basic(0xfff1c0, additive),\n smokeP: standard(0x8a8a86, 1, 0, { transparent: true, opacity: 0.35, depthWrite: false }),\n /** Launcher paints. */\n yellow: standard(0xb08f22, 0.6, 0),\n red: standard(0x8e1c14, 0.45, 0.1),\n redPaint: standard(0xa3231a, 0.35, 0.2),\n tape: standard(0x8a8c88, 0.9, 0),\n pipe: standard(0x9a5a32, 0.35, 0.8),\n green: standard(0x3a4428, 0.75, 0.05),\n /** Explosive finishes: the molotov's bottle, the dynamite's paper, the C4's putty and the detonator's wire. */\n bottle: standard(0x2f5a34, 0.1, 0.1, { transparent: true, opacity: 0.72 }),\n dynamite: standard(0x9e2a1f, 0.7, 0),\n c4: standard(0x6d6a4c, 0.95, 0),\n wire: standard(0xb02020, 0.5, 0),\n /** Magazine finishes named by the options. */\n bakelite: standard(0x6a2e1c, 0.6, 0),\n polyMag: standard(0x2a2a26, 0.85, 0),\n }\n // shared by every model of this kit: a model put away (discardObject3D of game-shapes-three) must not free them, or the next one uploads them again\n markShared(...Object.values(materials))\n return materials\n}\nexport type ModelMaterials = ReturnType<typeof createMaterials>\n\n/**\n * The gallery's primitives on the host's three.js. Each takes the parent first and the position last as the page does (`box(parent, w, h, d, material, x, y, z, rz, ry, rx)`),\n * so that the builders read like the originals. `roundness` is the page's `RF`: how round the next boxes are, `null` for the default.\n */\nexport interface ModelKit {\n readonly THREE: Three\n readonly M: ModelMaterials\n roundness: number | null\n group(): THREE_NS.Group\n box(parent: Parent, w: number, h: number, d: number, material: Material, x: number, y: number, z: number, rz?: number, ry?: number, rx?: number): THREE_NS.Mesh\n /** Cylinders along x, y and z. `radiusEnd` makes a cone. */\n cylinderX(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderY(parent: Parent, radius: number, height: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderZ(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number): THREE_NS.Mesh\n sphere(parent: Parent, radius: number, material: Material, x: number, y: number, z: number, detail?: number): THREE_NS.Mesh\n torus(parent: Parent, geometry: THREE_NS.TorusGeometry, material: Material, x: number, y: number, z: number): THREE_NS.Mesh\n mark(parent: Parent, x: number, y: number, z: number): THREE_NS.Object3D\n pivot(parent: Parent, x?: number, y?: number, z?: number): THREE_NS.Group\n}\n\nconst kits = new WeakMap<Three, ModelKit>()\n\n/**\n * One kit per three.js namespace: the materials and the geometry cache are shared by every model built with it. The kit's `THREE` is\n * `shapeGeometries(host)`: box, cylinder, cone, sphere and torus come from game-shapes (the same bytes, the same classes); the rest is the host's.\n */\nexport function modelKit(host: Three): ModelKit {\n const cached = kits.get(host)\n if (cached) return cached\n const THREE = shapeGeometries(host)\n const geometries = new Map<string, THREE_NS.BufferGeometry>()\n const shadowed = <TObject extends THREE_NS.Mesh>(mesh: TObject): TObject => {\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n const place = (parent: Parent, mesh: THREE_NS.Mesh, x: number, y: number, z: number): THREE_NS.Mesh => {\n mesh.position.set(x, y, z)\n parent.add(mesh)\n return mesh\n }\n const kit: ModelKit = {\n THREE,\n M: createMaterials(THREE),\n roundness: null,\n group: () => new THREE.Group(),\n box(parent, w, h, d, material, x, y, z, rz = 0, ry = 0, rx = 0) {\n const radius = Math.min(w, h, d) * (kit.roundness ?? 0.2)\n const key = `${w.toFixed(4)},${h.toFixed(4)},${d.toFixed(4)},${radius.toFixed(5)}`\n let geometry = geometries.get(key)\n if (!geometry) {\n geometry = radius > 0.00025 ? createRoundedBoxGeometry(THREE, w, h, d, 2, radius) : new THREE.BoxGeometry(w, h, d)\n markShared(geometry)\n geometries.set(key, geometry)\n }\n const mesh = place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z)\n mesh.rotation.set(rx, ry, rz)\n return mesh\n },\n cylinderX(parent, radius, length, material, x, y, z, segments = 16, radiusEnd) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, length, segments), material))\n mesh.rotation.z = -PI / 2\n return place(parent, mesh, x, y, z)\n },\n cylinderY(parent, radius, height, material, x, y, z, segments = 16, radiusEnd) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, height, segments), material)), x, y, z)\n },\n cylinderZ(parent, radius, length, material, x, y, z, segments = 16) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, segments), material))\n mesh.rotation.x = PI / 2\n return place(parent, mesh, x, y, z)\n },\n sphere(parent, radius, material, x, y, z, detail = 1) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.IcosahedronGeometry(radius, detail), material)), x, y, z)\n },\n torus: (parent, geometry, material, x, y, z) => place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z),\n mark(parent, x, y, z) {\n const object = new THREE.Object3D()\n object.position.set(x, y, z)\n parent.add(object)\n return object\n },\n pivot(parent, x = 0, y = 0, z = 0) {\n const group = new THREE.Group()\n group.position.set(x, y, z)\n parent.add(group)\n return group\n },\n }\n kits.set(host, kit)\n return kit\n}\n\n/** Gives the mesh its own copy of the material, and lists it among the parts that glow with heat. */\nexport function heatify<TMesh extends THREE_NS.Mesh>(glow: THREE_NS.Mesh[], mesh: TMesh): TMesh {\n mesh.material = (mesh.material as Material).clone()\n glow.push(mesh)\n return mesh\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\ntype Axis = 'x' | 'y' | 'z'\n\n// Port of three/examples/jsm/geometries/RoundedBoxGeometry (MIT, three.js authors) onto the host's THREE: the host lends its namespace, not the addon.\nconst uvAlong = (THREE: Three, faceDirection: THREE_NS.Vector3, normal: THREE_NS.Vector3, uvAxis: Axis, projectionAxis: Axis, radius: number, sideLength: number): number => {\n const arcLength = (2 * Math.PI * radius) / 4\n const centerLength = Math.max(sideLength - 2 * radius, 0)\n const halfArc = Math.PI / 4\n const projected = new THREE.Vector3().copy(normal)\n projected[projectionAxis] = 0\n projected.normalize()\n const arcUvRatio = (0.5 * arcLength) / (arcLength + centerLength)\n const arcAngleRatio = 1.0 - projected.angleTo(faceDirection) / halfArc\n if (Math.sign(projected[uvAxis]) === 1) return arcAngleRatio * arcUvRatio\n const centerUv = centerLength / (arcLength + centerLength)\n return centerUv + arcUvRatio + arcUvRatio * (1.0 - arcAngleRatio)\n}\n\ntype Face = { direction: [number, number, number]; u: [Axis, Axis, boolean]; v: [Axis, Axis, boolean] }\n\n// right, left, top, bottom, front, back: the axes each face reads its u and v from, and whether the value is mirrored\nconst FACES: readonly Face[] = [\n { direction: [1, 0, 0], u: ['z', 'y', false], v: ['y', 'z', true] },\n { direction: [-1, 0, 0], u: ['z', 'y', true], v: ['y', 'z', true] },\n { direction: [0, 1, 0], u: ['x', 'z', true], v: ['z', 'x', false] },\n { direction: [0, -1, 0], u: ['x', 'z', true], v: ['z', 'x', true] },\n { direction: [0, 0, 1], u: ['x', 'y', true], v: ['y', 'x', true] },\n { direction: [0, 0, -1], u: ['x', 'y', false], v: ['y', 'x', true] },\n]\n\n/** A box with rounded edges (`segments` per corner) made from the host's BoxGeometry, vertex for vertex like the three.js addon the gallery used. */\nexport function createRoundedBoxGeometry(THREE: Three, width: number, height: number, depth: number, segments: number, radius: number): THREE_NS.BufferGeometry {\n const count = segments * 2 + 1\n const rounding = Math.min(width / 2, height / 2, depth / 2, radius)\n const geometry = new THREE.BoxGeometry(1, 1, 1, count, count, count)\n const flat = geometry.toNonIndexed()\n geometry.setIndex(null)\n geometry.setAttribute('position', flat.attributes.position as THREE_NS.BufferAttribute)\n geometry.setAttribute('normal', flat.attributes.normal as THREE_NS.BufferAttribute)\n geometry.setAttribute('uv', flat.attributes.uv as THREE_NS.BufferAttribute)\n const position = new THREE.Vector3()\n const normal = new THREE.Vector3()\n const box = new THREE.Vector3(width, height, depth).divideScalar(2).subScalar(rounding)\n const positions = geometry.attributes.position.array as Float32Array\n const normals = geometry.attributes.normal.array as Float32Array\n const uvs = geometry.attributes.uv.array as Float32Array\n const faceTriangles = positions.length / 6\n const halfSegment = 0.5 / count\n const sides: Record<Axis, number> = { x: width, y: height, z: depth }\n for (let i = 0, j = 0; i < positions.length; i += 3, j += 2) {\n position.fromArray(positions, i)\n normal.copy(position)\n normal.x -= Math.sign(normal.x) * halfSegment\n normal.y -= Math.sign(normal.y) * halfSegment\n normal.z -= Math.sign(normal.z) * halfSegment\n normal.normalize()\n positions[i] = box.x * Math.sign(position.x) + normal.x * rounding\n positions[i + 1] = box.y * Math.sign(position.y) + normal.y * rounding\n positions[i + 2] = box.z * Math.sign(position.z) + normal.z * rounding\n normals[i] = normal.x\n normals[i + 1] = normal.y\n normals[i + 2] = normal.z\n const face = FACES[Math.floor(i / faceTriangles)]\n if (!face) continue\n const direction = new THREE.Vector3(...face.direction)\n for (const [offset, [uvAxis, projectionAxis, mirrored]] of [[0, face.u], [1, face.v]] as const) {\n const value = uvAlong(THREE, direction, normal, uvAxis, projectionAxis, rounding, sides[uvAxis])\n uvs[j + offset] = mirrored ? 1 - value : value\n }\n }\n return geometry\n}\n","import type * as THREE_NS from 'three'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\n\nimport { drawItemWeapon } from './item-weapon-draw'\nimport { DEFAULT_ITEM_MODELS } from './item-models'\nimport type { ItemModels } from './item-models'\nimport { buildExplosiveModel, hasExplosiveModel } from './models/explosives'\nimport { buildProp, weaponProp } from './props'\n\n/** How a weapon is drawn from an item model of game-items-three: the item (default the weapon id), and the turns the laying-down rule gets wrong. */\nexport interface WeaponItemModel {\n /** Catalog id of the item model; the weapon id when absent. */\n readonly item?: string\n /** Quarter turns about y after the long axis is laid along x (a crossbow's stock is shorter than its limbs). */\n readonly turn?: number\n /** Turn it end for end after the head is found (the head is the narrow end: a knife's blade, a screwdriver's tip, an extinguisher's nozzle). */\n readonly flip?: boolean\n}\n\n// the weapons whose item has another id, or that the laying-down rule turns the wrong way\nexport const SHIPPED_WEAPON_ITEM_MODELS: ReadonlyArray<readonly [string, WeaponItemModel]> = [\n ['wrench', { item: 'adjustable_wrench' }],\n ['extinguisher', { item: 'fire_extinguisher', flip: true }],\n ['blowtorch', { item: 'gas_torch', flip: true }],\n ['crossbow', { turn: 1 }],\n ['knife', { flip: true }],\n ['meat_cleaver', { flip: true }],\n ['screwdriver', { flip: true }],\n // the Itens do Vale Cinzento hammer is a claw hammer: the head and the two-pronged claw\n ['claw_hammer', { item: 'hammer' }],\n]\n\n/** The weapons whose item model has another id or turns another way, with the draw that reads them: one set, with no other set sharing it. */\nexport interface WeaponProps {\n /** Draws a weapon the gallery did not model with an item model of game-items-three (a game adds its own or corrects one; `null` keeps the low-poly prop). */\n register(weaponId: string, model: WeaponItemModel | null): void\n /** The override of a weapon, if the set has one. */\n get(weaponId: string): WeaponItemModel | undefined\n /** The item model of game-items-three that draws a weapon, or undefined when there is none. */\n itemModelOf(weaponId: string, items?: ItemModels): string | undefined\n /** `buildItemWeaponModel` with this set's overrides. */\n buildItemModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, items?: ItemModels): THREE_NS.Group | undefined\n /** `buildWeaponModel` with this set's overrides. */\n buildModel(THREE: typeof THREE_NS, def: WeaponModelDef, items?: ItemModels): THREE_NS.Group\n}\n\n/** What a weapon model is drawn from: the id, the category and mass of the low-poly prop, and the action that names a throwable's explosive. */\nexport type WeaponModelDef = Pick<WeaponDef, 'id' | 'category' | 'mass'> & Partial<Pick<WeaponDef, 'action'>>\n\n/** The gallery model of the explosive a throwable carries (the frag grenade's M67, the molotov, the dynamite...), or undefined for any other weapon. */\n/** Whether the gallery drew the explosive a throwable carries. */\nexport const hasThrowableModel = (def: Partial<Pick<WeaponDef, 'action'>>): boolean => def.action?.kind === 'throwable' && def.action.explosive !== undefined && hasExplosiveModel(def.action.explosive)\n\nexport const buildThrowableModel = (THREE: typeof THREE_NS, def: Partial<Pick<WeaponDef, 'action'>>): THREE_NS.Group | undefined =>\n def.action?.kind === 'throwable' && def.action.explosive !== undefined ? buildExplosiveModel(THREE, def.action.explosive) : undefined\n\nexport const weaponPropsOver = (models: Map<string, WeaponItemModel>): WeaponProps => {\n const itemModelOf = (weaponId: string, items?: ItemModels): string | undefined => {\n const id = models.get(weaponId)?.item ?? weaponId\n return id && (items ?? DEFAULT_ITEM_MODELS).has(id) ? id : undefined\n }\n const buildItemModel = (THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, items?: ItemModels): THREE_NS.Group | undefined => {\n const itemId = itemModelOf(def.id, items)\n if (!itemId) return undefined\n return drawItemWeapon({ THREE, def, items, itemId, turn: models.get(def.id)?.turn ?? 0, flip: models.get(def.id)?.flip === true })\n }\n return {\n register: (weaponId, model) => void models.set(weaponId, model ?? { item: '' }),\n get: (weaponId) => models.get(weaponId),\n itemModelOf,\n buildItemModel,\n buildModel: (THREE, def, items) => buildItemModel(THREE, def, items) ?? buildThrowableModel(THREE, def) ?? buildProp(THREE, weaponProp(def)),\n }\n}\n\nlet defaultProps: WeaponProps | undefined\n\n/** The set behind `registerWeaponItemModel`, `itemModelOfWeapon`, `buildItemWeaponModel` and `buildWeaponModel`, created on first use. */\nexport const defaultWeaponProps = (): WeaponProps => (defaultProps ??= weaponPropsOver(new Map(SHIPPED_WEAPON_ITEM_MODELS)))\n\n/** @deprecated use `createWeaponProps(...).register`. */\nexport const registerWeaponItemModel = (weaponId: string, model: WeaponItemModel | null): void => defaultWeaponProps().register(weaponId, model)\n\n/** The item model of game-items-three that draws a weapon (`baseball_bat`, `axe`, `fire_extinguisher`...), or undefined when there is none. @deprecated use `createWeaponProps(...).itemModelOf`. */\nexport const itemModelOfWeapon = (weaponId: string, items?: ItemModels): string | undefined => defaultWeaponProps().itemModelOf(weaponId, items)\n\n/**\n * A weapon the gallery did not draw, with the team's item model (Itens do Vale Cinzento: the bat, the axe, the machete, the extinguisher...): its long axis turned\n * along +x and laid flat, the wider end (the head) at +x unless `registerWeaponItemModel` says otherwise, the origin at the bottom centre, an empty `handle` at the narrow end where the hand closes. Undefined\n * when `items` (the item models of game-items-three, lent by the host; default `itemModels` there) has none of it.\n * @deprecated use `createWeaponProps(...).buildItemModel`.\n */\nexport const buildItemWeaponModel = (THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, items?: ItemModels): THREE_NS.Group | undefined => defaultWeaponProps().buildItemModel(THREE, def, items)\n\n/** The model of a weapon for the hands or a shelf: the team's item model when the kit has one (`buildItemWeaponModel`), the gallery model of a throwable's explosive, the low-poly prop the counters show otherwise. @deprecated use `createWeaponProps(...).buildModel`. */\nexport const buildWeaponModel = (THREE: typeof THREE_NS, def: WeaponModelDef, items?: ItemModels): THREE_NS.Group => defaultWeaponProps().buildModel(THREE, def, items)\n","import { markKitOrigin } from '@adatechnology/game-contracts'\nimport type * as THREE_NS from 'three'\nimport { WEAPONS } from '@adatechnology/game-weapons'\nimport data from '../data/models.json'\nimport { buildBreakAction } from './break-action'\nimport { buildBreakLauncher } from './break-launcher'\nimport { deriveFrames } from './attachments/mount-frames'\nimport { buildBullpup } from './bullpup'\nimport { modelKit } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildLauncher } from './launcher'\nimport { buildM134 } from './m134'\nimport { buildM2 } from './m2'\nimport { buildP90 } from './p90'\nimport { partRegistry } from './part-registry'\nimport { buildPistol } from './pistol'\nimport { buildRevolver } from './revolver'\nimport { buildRifle } from './rifle'\nimport type { BuiltModel, ModelOptions, ModelParts, WeaponModel } from './types'\n\nexport type { ModelFamily, ModelOptions, ModelParts, WeaponModel } from './types'\n\n/** One weapon of the gallery as `data/models.json` keeps it: the builder, the measures in mm and the builder's options. */\nexport interface ModelEntry {\n readonly builder: 'pistol' | 'revolver' | 'rifle' | 'bullpup' | 'p90' | 'break' | 'breakLauncher' | 'm2' | 'm134' | 'launcher'\n readonly caliber: string\n readonly length: number\n readonly barrel: number\n readonly options: ModelOptions\n readonly variantOf?: string\n}\n\nexport const MODEL_ENTRIES: Readonly<Record<string, ModelEntry>> = data as Record<string, ModelEntry>\n\n/**\n * The model each generic archetype wears: the one of the first brand weapon (lowest id) that points to it with `archetype` and fires the same way (a rocket launcher that points to\n * `shotgun_pump_12` does not lend its tube to the shotgun). An archetype nothing points to, the melee weapons and the bow keep their simple prop.\n */\nexport const ARCHETYPE_MODELS: Readonly<Record<string, string>> = (() => {\n const actionOf = new Map(WEAPONS.map((def) => [def.id, def.action.kind]))\n const chosen: Record<string, string> = {}\n for (const def of [...WEAPONS].sort((a, b) => (a.id < b.id ? -1 : 1))) {\n const { archetype } = def\n if (!archetype || !(def.id in MODEL_ENTRIES) || archetype in MODEL_ENTRIES || archetype in chosen) continue\n if (actionOf.get(archetype) === def.action.kind) chosen[archetype] = def.id\n }\n return chosen\n})()\n\nconst BUILDERS: Record<ModelEntry['builder'], (kit: ModelKit, options: ModelOptions) => BuiltModel> = {\n pistol: buildPistol,\n revolver: buildRevolver,\n rifle: buildRifle,\n bullpup: buildBullpup,\n p90: (kit) => buildP90(kit),\n break: buildBreakAction,\n breakLauncher: buildBreakLauncher,\n m2: (kit) => buildM2(kit),\n m134: (kit) => buildM134(kit),\n launcher: buildLauncher,\n}\n\nconst nameParts = (parts: ModelParts): void => {\n for (const [name, part] of partRegistry(parts)) part.name = name\n}\n\n/** Stretches the model along x to the real length of the weapon (the page's `fitLength`) and puts its rear at the origin. */\nconst fitLength = (kit: ModelKit, inner: THREE_NS.Group, lengthMetres: number): THREE_NS.Group => {\n const box = new kit.THREE.Box3().setFromObject(inner)\n const factor = lengthMetres / (box.max.x - box.min.x)\n inner.scale.x = factor\n inner.position.x = -box.min.x * factor\n const root = kit.group()\n root.add(inner)\n return root\n}\n\nexport const hasWeaponModel = (id: string): boolean => id in MODEL_ENTRIES || id in ARCHETYPE_MODELS\n\n/** The gallery model of a weapon (or of the brand weapon an archetype wears, see `ARCHETYPE_MODELS`), long axis along +x, rear at the origin; undefined for melee, throwables and what nothing drew. */\nexport function buildWeaponModelById(THREE: typeof THREE_NS, id: string): WeaponModel | undefined {\n const entry = MODEL_ENTRIES[ARCHETYPE_MODELS[id] ?? id]\n if (!entry) return undefined\n const kit = modelKit(THREE)\n const options: ModelOptions = { L: entry.length, B: entry.barrel, cal: entry.caliber, ...entry.options }\n if (id in ARCHETYPE_MODELS) delete options.chambers // a generic weapon holds the default six, not the brand's capacity\n const built = BUILDERS[entry.builder](kit, options)\n nameParts(built.parts)\n let root: THREE_NS.Group\n if (entry.builder === 'launcher') {\n root = kit.group()\n root.add(built.group)\n built.group.position.x = -new THREE.Box3().setFromObject(built.group).min.x\n } else root = fitLength(kit, built.group, entry.length / 1000)\n root.name = id\n markKitOrigin(root, { owner: 'game-weapons-three', kind: 'weapon', id })\n const model: WeaponModel = { id, root, inner: built.group, parts: built.parts }\n if (!built.parts.frames) built.parts.frames = deriveFrames(THREE, model)\n return model\n}\n","{\n \"glock_17\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"rel\": 0.7\n }\n },\n \"glock_18\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"sel\": 1,\n \"rpm\": 1200,\n \"rel\": 0.9\n }\n },\n \"glock_19\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 185,\n \"barrel\": 102,\n \"options\": {\n \"st\": \"glock\",\n \"gl\": 0.095,\n \"rel\": 0.7\n }\n },\n \"taurus_g2c\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 159,\n \"barrel\": 81,\n \"options\": {\n \"st\": \"g2c\",\n \"gl\": 0.085,\n \"rel\": 1.5\n }\n },\n \"taurus_ts9\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 194,\n \"barrel\": 104,\n \"options\": {\n \"st\": \"taurus\",\n \"rel\": 1.2\n }\n },\n \"beretta_92fs\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 217,\n \"barrel\": 125,\n \"options\": {\n \"st\": \"beretta\",\n \"h\": 0.032,\n \"rel\": 0.9\n }\n },\n \"sig_sauer_p226\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 196,\n \"barrel\": 112,\n \"options\": {\n \"st\": \"sig\",\n \"h\": 0.034,\n \"rel\": 0.8\n }\n },\n \"cz_75\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 206,\n \"barrel\": 120,\n \"options\": {\n \"st\": \"cz\",\n \"h\": 0.03,\n \"rel\": 0.9\n }\n },\n \"taurus_pt100\": {\n \"builder\": \"pistol\",\n \"caliber\": \".40 S&W\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"pt100\",\n \"stain\": 1,\n \"rel\": 1.2\n }\n },\n \"colt_m1911\": {\n \"builder\": \"pistol\",\n \"caliber\": \".45 ACP\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"m1911\",\n \"h\": 0.029,\n \"gl\": 0.1,\n \"rel\": 1.1\n }\n },\n \"makarov_pm\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×18\",\n \"length\": 161,\n \"barrel\": 94,\n \"options\": {\n \"st\": \"makarov\",\n \"h\": 0.028,\n \"gl\": 0.088,\n \"rel\": 0.8\n }\n },\n \"fn_five_seven\": {\n \"builder\": \"pistol\",\n \"caliber\": \"5,7×28\",\n \"length\": 208,\n \"barrel\": 122,\n \"options\": {\n \"st\": \"fiveseven\",\n \"gl\": 0.12,\n \"rel\": 0.9\n }\n },\n \"desert_eagle_mark_xix\": {\n \"builder\": \"pistol\",\n \"caliber\": \".50 AE\",\n \"length\": 270,\n \"barrel\": 152,\n \"options\": {\n \"st\": \"deagle\",\n \"h\": 0.04,\n \"gl\": 0.125,\n \"deagle\": 1,\n \"steel\": 1,\n \"rel\": 1.8\n }\n },\n \"taurus_82\": {\n \"builder\": \"revolver\",\n \"caliber\": \".38 SPL\",\n \"length\": 240,\n \"barrel\": 102,\n \"options\": {\n \"wood\": 1\n }\n },\n \"sw_686\": {\n \"builder\": \"revolver\",\n \"caliber\": \".357 Magnum\",\n \"length\": 244,\n \"barrel\": 102,\n \"options\": {\n \"steel\": 1,\n \"chambers\": 7\n }\n },\n \"sw_model_29\": {\n \"builder\": \"revolver\",\n \"caliber\": \".44 Magnum\",\n \"length\": 302,\n \"barrel\": 165,\n \"options\": {\n \"wood\": 1\n }\n },\n \"hk_mp5a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 700,\n \"barrel\": 225,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"retract\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"g3\": 1,\n \"rpm\": 800,\n \"sel\": 1\n }\n },\n \"taurus_smt9\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 660,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hg\": \"rail\",\n \"hgFrac\": 0.8,\n \"rail\": 1,\n \"rpm\": 750,\n \"sel\": 1\n }\n },\n \"hk_ump_45\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 690,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.22,\n \"hR\": 0.07,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"rpm\": 600,\n \"sel\": 1,\n \"rail\": 1\n }\n },\n \"uzi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 650,\n \"barrel\": 260,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.06,\n \"magLen\": 1.3,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.065,\n \"hg\": \"poly\",\n \"hgFrac\": 0.4,\n \"grip\": \"none\",\n \"rpm\": 600\n }\n },\n \"fn_p90\": {\n \"builder\": \"p90\",\n \"caliber\": \"5,7×28\",\n \"length\": 500,\n \"barrel\": 264,\n \"options\": {\n \"rpm\": 900\n }\n },\n \"kriss_vector\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 622,\n \"barrel\": 140,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.085,\n \"hg\": \"rail\",\n \"hgFrac\": 0.9,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1100\n }\n },\n \"thompson_m1a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 813,\n \"barrel\": 267,\n \"options\": {\n \"wood\": 1,\n \"mag\": \"box\",\n \"magLen\": 1.2,\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"hg\": \"none\",\n \"hR\": 0.055,\n \"jacket\": 1,\n \"rpm\": 700,\n \"charge\": 1\n }\n },\n \"cz_scorpion_evo_3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 670,\n \"barrel\": 196,\n \"options\": {\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hg\": \"rail\",\n \"hgFrac\": 0.85,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1150\n }\n },\n \"mac_10\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 548,\n \"barrel\": 146,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.04,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hR\": 0.075,\n \"hg\": \"none\",\n \"grip\": \"none\",\n \"brake\": 2,\n \"rpm\": 1090,\n \"rel\": 1.4\n }\n },\n \"remington_870\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"mossberg_500\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"cbc_pump_military_3_0\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 480,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"tubeLen\": 0.95,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"rail\": 1,\n \"noFH\": 1\n }\n },\n \"benelli_m4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1010,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"rail\": 1,\n \"scope\": 1,\n \"noFH\": 1,\n \"charge\": 1\n }\n },\n \"franchi_spas_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1041,\n \"barrel\": 546,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"heat\": 1,\n \"noFH\": 1\n }\n },\n \"kel_tec_ksg\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"12 ga\",\n \"length\": 660,\n \"barrel\": 470,\n \"options\": {\n \"shot\": 1\n }\n },\n \"saiga_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 430,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.15,\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"br\": 0.0105,\n \"hR\": 0.07,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rel\": 1.3\n }\n },\n \"aa_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 966,\n \"barrel\": 457,\n \"options\": {\n \"mag\": \"drum\",\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"br\": 0.0105,\n \"hR\": 0.085,\n \"carry\": 1,\n \"rpm\": 300\n }\n },\n \"boito_double_barrel\": {\n \"builder\": \"break\",\n \"caliber\": \"12 ga\",\n \"length\": 1130,\n \"barrel\": 710,\n \"options\": {}\n },\n \"ak_47\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"bayo\": 1,\n \"rpm\": 600,\n \"rel\": 0.4\n }\n },\n \"akm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 600,\n \"magMat\": \"bakelite\",\n \"rel\": 0.45\n }\n },\n \"ak_74\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 943,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"curved\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"brake\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 650,\n \"magMat\": \"bakelite\"\n }\n },\n \"ak_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 945,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"curved\",\n \"hg\": \"rail\",\n \"hgFrac\": 0.5,\n \"rail\": 1,\n \"brake\": 1,\n \"scope\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rpm\": 700,\n \"magMat\": \"poly\"\n }\n },\n \"imbel_ia2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 850,\n \"barrel\": 330,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.25,\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"charge\": 1,\n \"rpm\": 700\n }\n },\n \"taurus_t4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 750\n }\n },\n \"colt_m4a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"scope\": 2,\n \"ar\": 1,\n \"rpm\": 800\n }\n },\n \"colt_m16a2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1000,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"carry\": 1,\n \"ar\": 1,\n \"rpm\": 800,\n \"burst\": 3\n }\n },\n \"hk416\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 900,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 850\n }\n },\n \"steyr_aug_a1\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"5,56×45\",\n \"length\": 790,\n \"barrel\": 508,\n \"options\": {\n \"rpm\": 680\n }\n },\n \"fn_fal\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1090,\n \"barrel\": 533,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.45,\n \"carry\": 1,\n \"brake\": 1,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"hk_g3a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1025,\n \"barrel\": 450,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"rpm\": 550\n }\n },\n \"sks\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 1020,\n \"barrel\": 520,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.55,\n \"gas\": 1,\n \"charge\": 1,\n \"bayo\": 1\n }\n },\n \"m14_ebr\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1000,\n \"barrel\": 457,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.035,\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 3,\n \"olive\": 1,\n \"charge\": 1\n }\n },\n \"svd_dragunov\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1225,\n \"barrel\": 620,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.32,\n \"mag\": \"box\",\n \"curve\": 0.09,\n \"magLen\": 0.9,\n \"hg\": \"wood\",\n \"hgFrac\": 0.4,\n \"scope\": 4,\n \"brake\": 1,\n \"ak\": 1,\n \"charge\": 1\n }\n },\n \"fn_scar_h\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 965,\n \"barrel\": 400,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"hR\": 0.07,\n \"rail\": 1,\n \"scope\": 2,\n \"charge\": 1,\n \"rpm\": 600\n }\n },\n \"knights_sr_25_mk11\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1156,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"magLen\": 1,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 3,\n \"bipod\": 1,\n \"ar\": 1\n }\n },\n \"hk_psg_1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1208,\n \"barrel\": 650,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"curve\": 0.06,\n \"magLen\": 0.75,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"scope\": 3,\n \"rel\": 0.7\n }\n },\n \"steyr_ssg_69\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1140,\n \"barrel\": 650,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1,\n \"rel\": 0.6\n }\n },\n \"barrett_mrad\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1260,\n \"barrel\": 686,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.75,\n \"hg\": \"rail\",\n \"hgFrac\": 0.55,\n \"rail\": 1,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"cheytac_m200\": {\n \"builder\": \"rifle\",\n \"caliber\": \".408 CheyTac\",\n \"length\": 1397,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"retract\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.85,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.07,\n \"scope\": 4,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"remington_700\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"m24_sws\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1092,\n \"barrel\": 610,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"round\": 1\n }\n },\n \"mosin_nagant_91_30\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1232,\n \"barrel\": 730,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.85,\n \"bolt\": 1,\n \"round\": 1,\n \"bands\": 1\n }\n },\n \"accuracy_awm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1230,\n \"barrel\": 686,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.34,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"sako_trg_42\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1200,\n \"barrel\": 690,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"barrett_m82a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".50 BMG\",\n \"length\": 1448,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.8,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.1,\n \"wR\": 0.05,\n \"br\": 0.014,\n \"scope\": 3,\n \"bipod\": 1,\n \"brake\": 2,\n \"carry\": 1,\n \"charge\": 1\n }\n },\n \"ruger_10_22\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 940,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_7022\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1000,\n \"barrel\": 530,\n \"options\": {\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_122\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1030,\n \"barrel\": 590,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.045,\n \"br\": 0.007,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"winchester_1894\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-30\",\n \"length\": 965,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.05,\n \"fore\": 0,\n \"bands\": 1\n }\n },\n \"rossi_puma\": {\n \"builder\": \"rifle\",\n \"caliber\": \".38 SPL / .357\",\n \"length\": 950,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.048,\n \"fore\": 0\n }\n },\n \"hunting_rifle_30_06\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-06\",\n \"length\": 1100,\n \"barrel\": 560,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"fn_minimi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1040,\n \"barrel\": 465,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850\n }\n },\n \"pkm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1173,\n \"barrel\": 658,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"mag\": \"belt\",\n \"hg\": \"none\",\n \"bipod\": 1,\n \"hR\": 0.08,\n \"br\": 0.01,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"m60\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1105,\n \"barrel\": 560,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"bipod\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 550,\n \"rel\": 1.3\n }\n },\n \"rpg_7\": {\n \"builder\": \"launcher\",\n \"caliber\": \"PG-7V 40/85 mm\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"rpg\"\n }\n },\n \"m72_law\": {\n \"builder\": \"launcher\",\n \"caliber\": \"66 mm HEAT\",\n \"length\": 881,\n \"barrel\": 881,\n \"options\": {\n \"lt\": \"m72\"\n }\n },\n \"at4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm HEAT\",\n \"length\": 1020,\n \"barrel\": 1020,\n \"options\": {\n \"lt\": \"at4\"\n }\n },\n \"carl_gustaf_m4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm (HE / HEAT)\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"carl\"\n }\n },\n \"m2_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Napalm / gasolina gel\",\n \"length\": 1000,\n \"barrel\": 620,\n \"options\": {\n \"lt\": \"flame\"\n }\n },\n \"improvised_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Gasolina + extintor pressurizado\",\n \"length\": 800,\n \"barrel\": 660,\n \"options\": {\n \"lt\": \"flameDIY\"\n }\n },\n \"browning_m2\": {\n \"builder\": \"m2\",\n \"caliber\": \".50 BMG\",\n \"length\": 1650,\n \"barrel\": 1140,\n \"options\": {\n \"rpm\": 550\n }\n },\n \"remington_700_300wm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n },\n \"variantOf\": \"remington_700\"\n },\n \"hk_mp5sd3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 805,\n \"barrel\": 146,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"retract\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"g3\": 1,\n \"rpm\": 700,\n \"sel\": 1,\n \"jacket\": 1,\n \"noFH\": 1,\n \"br\": 0.0115\n },\n \"variantOf\": \"hk_mp5a3\"\n },\n \"fn_parafal\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1020,\n \"barrel\": 440,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.45,\n \"carry\": 1,\n \"brake\": 1,\n \"charge\": 1,\n \"rpm\": 650,\n \"stockLen\": 0.25\n },\n \"variantOf\": \"fn_fal\"\n },\n \"taurus_t4_civil\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 878,\n \"barrel\": 406,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 120\n },\n \"variantOf\": \"taurus_t4\"\n },\n \"taurus_th380\": {\n \"builder\": \"pistol\",\n \"caliber\": \".380 ACP\",\n \"length\": 165,\n \"barrel\": 90,\n \"options\": {\n \"st\": \"g2c\",\n \"gl\": 0.085,\n \"rel\": 1.5\n },\n \"variantOf\": \"taurus_g2c\"\n },\n \"mossberg_500_cruiser\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 720,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"none\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n },\n \"variantOf\": \"mossberg_500\"\n },\n \"hk_mp5k\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 325,\n \"barrel\": 115,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"none\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"g3\": 1,\n \"rpm\": 900,\n \"sel\": 1\n },\n \"variantOf\": \"hk_mp5a3\"\n },\n \"hk_ump9\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 690,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.22,\n \"hR\": 0.07,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"rpm\": 700,\n \"sel\": 1,\n \"rail\": 1\n },\n \"variantOf\": \"hk_ump_45\"\n },\n \"mini_uzi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 600,\n \"barrel\": 197,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.06,\n \"magLen\": 0.9,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.065,\n \"hg\": \"poly\",\n \"hgFrac\": 0.4,\n \"grip\": \"none\",\n \"rpm\": 950\n },\n \"variantOf\": \"uzi\"\n },\n \"hk_mp7a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"4,6×30\",\n \"length\": 638,\n \"barrel\": 180,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.1,\n \"magLen\": 0.8,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.07,\n \"hg\": \"rail\",\n \"hgFrac\": 0.45,\n \"grip\": \"none\",\n \"rail\": 1,\n \"rpm\": 950,\n \"sel\": 1\n }\n },\n \"hk_g36\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 999,\n \"barrel\": 480,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"carry\": 1,\n \"scope\": 2\n }\n },\n \"hk_g36k\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 860,\n \"barrel\": 318,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"carry\": 1,\n \"scope\": 2\n }\n },\n \"hk_g36c\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 720,\n \"barrel\": 228,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"rail\": 1\n }\n },\n \"fn_m249\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1040,\n \"barrel\": 465,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850\n },\n \"variantOf\": \"fn_minimi\"\n },\n \"fn_minimi_para\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 893,\n \"barrel\": 349,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850,\n \"stockLen\": 0.22\n },\n \"variantOf\": \"fn_minimi\"\n },\n \"fn_mag\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1263,\n \"barrel\": 630,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"carry\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 750\n }\n },\n \"rpk\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 1040,\n \"barrel\": 590,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"bayo\": 0,\n \"rpm\": 600,\n \"rel\": 0.4,\n \"bipod\": 1,\n \"magLen\": 1.4\n },\n \"variantOf\": \"ak_47\"\n },\n \"sig_mpx\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 610,\n \"barrel\": 203,\n \"options\": {\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.06,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 850\n }\n },\n \"mg3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1225,\n \"barrel\": 565,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"bipod\": 1,\n \"carry\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 1100\n }\n },\n \"pp19_bizon\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×18\",\n \"length\": 660,\n \"barrel\": 195,\n \"options\": {\n \"mag\": \"helical\",\n \"magLen\": 1,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.06,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"ak\": 1,\n \"charge\": 1,\n \"rpm\": 680\n }\n },\n \"vz61\": {\n \"builder\": \"rifle\",\n \"caliber\": \".32 ACP\",\n \"length\": 517,\n \"barrel\": 115,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.6,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.05,\n \"hg\": \"none\",\n \"rpm\": 850,\n \"sel\": 1\n }\n },\n \"m134\": {\n \"builder\": \"m134\",\n \"caliber\": \"7,62×51\",\n \"length\": 801,\n \"barrel\": 559,\n \"options\": {\n \"rpm\": 3000\n }\n },\n \"m79\": {\n \"builder\": \"breakLauncher\",\n \"caliber\": \"40×46\",\n \"length\": 730,\n \"barrel\": 356,\n \"options\": {\n \"stock\": \"fixed\",\n \"wood\": 1,\n \"mag\": \"none\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.4,\n \"br\": 0.022,\n \"hR\": 0.05\n }\n }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `shotgunBreak`: the double barrel, hinged at the action so that it opens to reload. */\nexport function buildBreakAction(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX, sphere } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const parts: ModelParts = { family: 'break', kick: 1.6, glow: [] }\n box(group, 0.09, 0.05, 0.042, M.steel, L - barrel - 0.04, -0.005, 0)\n for (let i = 0; i < 4; i++) box(group, 0.05, 0.002, 0.043, M.dark, L - barrel - 0.04, 0.01 - i * 0.008, 0)\n const barrels = kit.pivot(group, L - barrel, -0.01, 0)\n parts.barrels = barrels\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, 0.011, 18))\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, -0.011, 18))\n box(barrels, barrel, 0.004, 0.008, M.metal, barrel / 2, 0.022, 0)\n sphere(barrels, 0.002, M.white, barrel - 0.01, 0.026, 0, 1)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, 0.011, 12)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, -0.011, 12)\n box(barrels, 0.22, 0.03, 0.038, M.wood, 0.12, -0.01, 0)\n parts.breech = [kit.mark(barrels, 0.004, 0.01, 0.011), kit.mark(barrels, 0.004, 0.01, -0.011)]\n box(group, 0.12, 0.042, 0.032, M.wood, L - barrel - 0.14, -0.022, 0, 0.14)\n box(group, 0.28, 0.07, 0.036, M.wood, 0.15, -0.05, 0, 0.08)\n box(group, 0.012, 0.13, 0.04, M.rubber, 0.006, -0.06, 0)\n box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.05, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.035, -0.04, 0)\n box(group, 0.04, 0.004, 0.01, M.steel, L - barrel - 0.045, -0.05, 0)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, 0.012, 0.5)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, -0.012, 0.5)\n parts.safety = box(group, 0.02, 0.006, 0.008, M.steel, L - barrel - 0.07, 0.025, 0)\n parts.muzzle = kit.mark(barrels, barrel + 0.01, 0.01, 0)\n parts.eject = parts.breech[0]\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { Parent, ModelKit } from '../kit'\n\n/** The muzzle brake of the gallery's rifles (`brake` 1 the plain one, 2 the heavy one with eight sides), its end flush with the muzzle at `x`. `heat` receives the body so a builder can make it glow. */\nexport function buildBrake(kit: ModelKit, parent: Parent, kind: 1 | 2, x: number, y: number, barrelRadius: number, heat: (body: THREE_NS.Mesh) => void = () => undefined): void {\n const { M, box, cylinderX } = kit\n const scale = kind === 2 ? 3.2 : 2.0\n const length = kind === 2 ? 0.12 : 0.06\n heat(cylinderX(parent, barrelRadius * scale, length, M.dark, x - length / 2, y, 0, kind === 2 ? 8 : 16))\n for (let i = 0; i < 3; i++) box(parent, length * 0.16, barrelRadius * scale * 1.3, barrelRadius * scale * 2.2, M.hole, x - length * 0.25 - i * length * 0.25, y, 0)\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelParts } from './types'\n\n/** Runs `draw` and returns what it added to `parent` (the meshes of one part), so that the part can be hidden later; the scene is exactly what `draw` made. */\nexport function captured(parent: THREE_NS.Object3D, draw: () => void): THREE_NS.Object3D[] {\n const before = parent.children.length\n draw()\n return parent.children.slice(before)\n}\n\n/** Draws a part that ships on the weapon and records its meshes under the id of the accessory it stands for. */\nexport function recordFitting(parts: ModelParts, id: string, parent: THREE_NS.Object3D, draw: () => void): void {\n parts.fittings = { ...parts.fittings, [id]: captured(parent, draw) }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit, Parent } from './kit'\n\nconst PI = Math.PI\n\n/** A picatinny rail: a dark base and the cross slots, on a pivot so that it can lie on any side of the handguard. */\nexport function rail(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, width: number, rotationX = 0): THREE_NS.Group {\n const { M, box } = kit\n const pivot = kit.pivot(parent, 0, y, z)\n pivot.rotation.x = rotationX\n box(pivot, length, 0.005, width, M.dark, x + length / 2, 0, 0)\n const slots = Math.floor(length / 0.0095)\n for (let i = 0; i < slots; i++) box(pivot, 0.0052, 0.0035, width * 1.12, M.metal, x + 0.006 + i * 0.0095, 0.0035, 0)\n return pivot\n}\n\n/** Cooling slots along a handguard. */\nexport function vents(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, count: number, height: number): void {\n for (let i = 0; i < count; i++) kit.box(parent, (length / count) * 0.45, height, 0.003, kit.M.hole, x + ((i + 0.5) * length) / count, y, z)\n}\n\n/** An optic: 1 red dot, 2 short scope, 3 and 4 long scopes with their rings. */\nexport function scope(kit: ModelKit, parent: Parent, kind: number, cx: number, cy: number, cz = 0): void {\n const { M, box, cylinderX, cylinderY, cylinderZ, THREE } = kit\n if (kind === 1) {\n box(parent, 0.044, 0.01, 0.028, M.dark, cx, cy + 0.005, cz)\n cylinderX(parent, 0.0155, 0.034, M.dark, cx + 0.004, cy + 0.026, cz, 18)\n cylinderX(parent, 0.0125, 0.002, M.lens, cx + 0.022, cy + 0.026, cz, 18)\n cylinderY(parent, 0.004, 0.006, M.dark, cx + 0.004, cy + 0.044, cz, 10)\n return\n }\n if (kind === 2) {\n box(parent, 0.07, 0.012, 0.026, M.dark, cx, cy + 0.006, cz)\n cylinderX(parent, 0.016, 0.1, M.dark, cx - 0.01, cy + 0.032, cz, 18)\n cylinderX(parent, 0.016, 0.035, M.dark, cx + 0.055, cy + 0.032, cz, 18, 0.02)\n cylinderX(parent, 0.017, 0.002, M.lens, cx + 0.073, cy + 0.032, cz, 18)\n cylinderY(parent, 0.007, 0.012, M.dark, cx, cy + 0.052, cz, 12)\n box(parent, 0.03, 0.01, 0.012, M.dark, cx - 0.01, cy + 0.054, cz)\n return\n }\n const sleeve = kind === 4 ? 0.2 : 0.32\n cylinderX(parent, 0.0135, sleeve * 0.55, M.dark, cx, cy + 0.045, cz, 18)\n cylinderX(parent, 0.0135, sleeve * 0.25, M.dark, cx + sleeve * 0.36, cy + 0.045, cz, 18, 0.026)\n cylinderX(parent, 0.026, 0.05, M.dark, cx + sleeve * 0.5, cy + 0.045, cz, 18)\n cylinderX(parent, 0.024, 0.002, M.lens, cx + sleeve * 0.5 + 0.026, cy + 0.045, cz, 18)\n cylinderX(parent, 0.019, 0.06, M.dark, cx - sleeve * 0.38, cy + 0.045, cz, 18, 0.0135)\n cylinderX(parent, 0.019, 0.035, M.rubber, cx - sleeve * 0.38 - 0.045, cy + 0.045, cz, 18)\n cylinderX(parent, 0.017, 0.002, M.lens, cx - sleeve * 0.38 - 0.063, cy + 0.045, cz, 18)\n cylinderY(parent, 0.01, 0.022, M.dark, cx, cy + 0.066, cz, 14)\n cylinderY(parent, 0.011, 0.004, M.metal, cx, cy + 0.078, cz, 14)\n cylinderZ(parent, 0.01, 0.022, M.dark, cx, cy + 0.045, cz + 0.022, 14)\n for (const offset of [-0.07, 0.07]) {\n const ring = kit.torus(parent, new THREE.TorusGeometry(0.0155, 0.003, 8, 20), M.dark, cx + offset, cy + 0.045, cz)\n ring.rotation.y = PI / 2\n box(parent, 0.016, 0.03, 0.022, M.dark, cx + offset, cy + 0.018, cz)\n }\n}\n\nexport const buttpad = (kit: ModelKit, parent: Parent, x: number, y: number, height: number, width: number): void => void kit.box(parent, 0.012, height, width, kit.M.rubber, x, y, 0)\n\nexport const swivel = (kit: ModelKit, parent: Parent, x: number, y: number): void => void kit.torus(parent, new kit.THREE.TorusGeometry(0.006, 0.0015, 6, 12), kit.M.metal, x, y, 0)\n","import type { AttachmentModelBuilder } from './types'\nimport type { Parent, ModelKit } from '../kit'\n\n/** The bipod of the gallery's rifles: the hinge block and the two splayed legs with rubber feet, hinged at (`x`, `y`) of `parent`. */\nexport function buildBipod(kit: ModelKit, parent: Parent, x: number, y: number): void {\n const { M, box, cylinderX } = kit\n cylinderX(parent, 0.008, 0.02, M.dark, x, y, 0, 12)\n for (const side of [-1, 1]) {\n const leg = kit.pivot(parent, x, y, side * 0.012)\n leg.rotation.set(side * 0.15, 0, -0.35)\n box(leg, 0.006, 0.2, 0.006, M.dark, 0, -0.1, 0)\n box(leg, 0.01, 0.006, 0.01, M.rubber, 0, -0.2, 0)\n }\n}\n\nexport const buildBipodModel: AttachmentModelBuilder = ({ kit }) => {\n const group = kit.group()\n buildBipod(kit, group, 0, 0)\n return group\n}\n","import { buildBipod } from './attachments/bipod'\nimport { recordFitting } from './capture'\nimport { scope } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** The accessory each `scope` option of the page stands for. */\nconst SCOPE_IDS: Readonly<Record<number, string>> = { 1: 'red_dot', 2: 'acog_4x', 3: 'scope_3_9x', 4: 'scope_6_24x' }\n\n/** What is bolted on after the stock: optic, carry handle, bipod, bolt handle, lever, magazine tube, pump, heat shield, bayonet lug and cleaning rod. */\nexport function buildFittings(context: RifleContext, gripX: number): void {\n const { kit, group, parts, options: o, furniture: furn, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX, cylinderZ, sphere } = kit\n const middle = (x0 + x1) / 2\n if (o.scope) recordFitting(parts, SCOPE_IDS[o.scope] ?? 'scope', group, () => scope(kit, group, o.scope as number, middle + 0.03, hR / 2 + (o.rail ? 0.006 : 0), o.scope === 4 ? -0.02 : 0))\n if (o.carry) {\n box(group, 0.15, 0.026, 0.014, M.metal, middle, hR / 2 + 0.03, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle + 0.07, hR / 2 + 0.014, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle - 0.07, hR / 2 + 0.014, 0)\n }\n if (o.bipod) recordFitting(parts, 'bipod', group, () => buildBipod(kit, group, x1 + (L - x1) * 0.45 + 0.04, by - 0.012))\n if (o.bolt) {\n const handle = kit.pivot(group, x1 - 0.045, by, 0)\n parts.boltHandle = handle\n parts.boltHandleRest = handle.position.x\n cylinderZ(handle, 0.0042, 0.05, M.steelL, 0, 0, wR / 2 + 0.022, 12)\n sphere(handle, 0.0095, M.dark, 0, -0.004, wR / 2 + 0.048, 1)\n cylinderX(group, hR * 0.3, 0.03, M.steel, x0 + 0.005, by, 0, 16)\n }\n if (o.lever) {\n const lever = kit.pivot(group, gripX - 0.02, -hR / 2 - 0.01, 0)\n parts.lever = lever\n box(lever, 0.11, 0.006, 0.012, M.metal, 0.055, -0.052, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.003, -0.028, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.108, -0.028, 0)\n box(lever, 0.04, 0.006, 0.012, M.metal, 0.08, -0.002, 0)\n box(group, 0.03, 0.012, 0.003, M.dark, x1 - 0.04, by, wR / 2 + 0.001)\n }\n if (o.tube) {\n const tubeLength = (L - x1) * (o.tubeLen || 0.8)\n cylinderX(group, 0.0105, tubeLength, M.metal, x1 + tubeLength / 2, by - 0.023, 0, 16)\n cylinderX(group, 0.0125, 0.02, M.dark, x1 + tubeLength + 0.006, by - 0.023, 0, 16)\n }\n if (o.pump) {\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.17, 0.042, 0.046, furn, x1 + 0.14, by - 0.022, 0)\n for (let i = 0; i < 8; i++) box(pump, 0.006, 0.044, 0.048, M.dark, x1 + 0.07 + i * 0.02, by - 0.022, 0)\n }\n if (o.heat) {\n cylinderX(group, r * 1.75, (L - x1) * 0.7, M.dark, x1 + (L - x1) * 0.4, by, 0, 12)\n for (let i = 0; i < 10; i++) box(group, 0.008, r * 1.5, 0.004, M.hole, x1 + (L - x1) * (0.1 + i * 0.06), by + r * 0.8, r * 1.5)\n }\n if (o.bayo) box(group, 0.025, 0.008, 0.01, M.metal, L - 0.07, by - 0.016, 0)\n if (o.rod) cylinderX(group, 0.003, (L - x1) * 0.85, M.steel, x1 + (L - x1) * 0.45, by - 0.014, 0, 8)\n}\n","import { rail, vents } from './details'\nimport type { RifleContext } from './rifle-context'\n\nconst PI = Math.PI\n\n/** Handguard by kind and the front sight, which the page draws unless a long scope replaces it. */\nexport function buildForend(context: RifleContext): void {\n const { kit, group, options: o, furniture: furn, length: L, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box } = kit\n const hasLongScope = (o.scope ?? 0) >= 3\n if (!context.isTraditional && o.hg !== 'none') {\n const handguardLength = (L - x1) * (o.hgFrac || 0.5)\n const hx = x1 + handguardLength / 2\n const hh = hR * 0.8\n if (o.hg === 'rail') {\n box(group, handguardLength, hh, wR * 1.04, M.dark, hx, by - 0.002, 0)\n rail(kit, group, x1, handguardLength, by + hh / 2, 0, wR * 0.66)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, wR * 0.54, wR * 0.4, PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, -wR * 0.54, wR * 0.4, -PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - hh / 2, 0, wR * 0.6, PI)\n } else {\n const material = o.hg === 'wood' ? M.wood : furn\n if (o.ak) {\n box(group, handguardLength, hh * 0.55, wR * 1.08, material, hx, by - hh * 0.22, 0)\n box(group, handguardLength * 0.75, hh * 0.35, wR * 0.7, material, hx - handguardLength * 0.1, by + r * 2.2, 0)\n } else {\n box(group, handguardLength, hh, wR * 1.08, material, hx, by - 0.002, 0)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, wR * 0.54 + 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, -wR * 0.54 - 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n }\n }\n if (!hasLongScope && !o.rail && o.ak) {\n box(group, 0.03, 0.016, wR * 0.6, M.metal, x1 + 0.02, by + r * 2.5 + 0.01, 0)\n box(group, 0.012, 0.004, wR * 0.5, M.dark, x1 + 0.03, by + r * 2.5 + 0.019, 0)\n }\n }\n if (hasLongScope) return\n const sightX = L - (o.ak ? 0.06 : 0.08)\n if (o.ak) {\n box(group, 0.022, 0.022, wR * 0.6, M.metal, sightX, by + 0.008, 0)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, 0.008)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, -0.008)\n box(group, 0.003, 0.016, 0.003, M.dark, sightX, by + 0.022, 0)\n } else if (!o.rail || o.carry) {\n box(group, 0.018, 0.014, wR * 0.55, M.dark, sightX, by + 0.008, 0)\n box(group, 0.012, 0.034, 0.008, M.dark, sightX, by + 0.03, 0, -0.25)\n } else box(group, 0.012, 0.024, 0.012, M.dark, sightX - 0.04, by + hR * 0.4 + 0.012, 0)\n}\n","import type { Parent, ModelKit } from '../kit'\n\n/** The belt box of the gallery's belt-fed rifles: the olive box with its lid and the loose cartridges of the belt on top. Drawn in the frame of the belt pivot. */\nexport function buildBeltBox(kit: ModelKit, belt: Parent): void {\n const { M, box, cylinderX } = kit\n box(belt, 0.11, 0.1, 0.08, M.olive, 0, 0, 0)\n box(belt, 0.112, 0.012, 0.082, M.dark, 0, 0.046, 0)\n for (let i = 0; i < 7; i++) {\n cylinderX(belt, 0.0042, 0.034, M.brass, -0.04 + i * 0.012, 0.07, 0.035, 10)\n box(belt, 0.006, 0.006, 0.012, M.metal, -0.04 + i * 0.012, 0.066, 0.035)\n }\n}\n","import type { Parent, ModelKit } from '../kit'\n\n/** The drum magazine of the gallery (`mag: 'drum'`): the drum with its core, and the neck that goes into the well. Drawn in the frame of the magazine pivot. */\nexport function buildDrum(kit: ModelKit, magazine: Parent): void {\n const { M, box, cylinderZ } = kit\n cylinderZ(magazine, 0.075, 0.07, M.dark, 0.02, -0.085, 0, 22)\n cylinderZ(magazine, 0.05, 0.074, M.metal, 0.02, -0.085, 0, 18)\n box(magazine, 0.05, 0.04, 0.03, M.dark, 0, -0.02, 0)\n}\n","import type { RifleContext } from './rifle-context'\n\nconst PI = Math.PI\nconst LENGTH = 0.26\nconst RADIUS = 0.026\nconst TURNS = 11\n\n/** The helical magazine of the PP-19 Bizon: a drum along the barrel, under it, with the ridge of the helix drawn as slanted bands. Returns the x of its middle. */\nexport function buildHelicalMagazine(context: RifleContext): number {\n const { kit, group, parts, receiverEnd, barrelY, barrelRadius } = context\n const { M, cylinderX, box } = kit\n const x = receiverEnd + LENGTH / 2 + 0.02\n const y = barrelY - barrelRadius - RADIUS - 0.012\n const magazine = kit.pivot(group, x, y, 0)\n parts.mag = magazine\n cylinderX(magazine, RADIUS, LENGTH, M.dark, 0, 0, 0, 20)\n cylinderX(magazine, RADIUS * 1.06, 0.01, M.metal, -LENGTH / 2, 0, 0, 20)\n cylinderX(magazine, RADIUS * 1.06, 0.01, M.metal, LENGTH / 2, 0, 0, 20)\n for (let i = 0; i < TURNS; i++) box(magazine, 0.012, RADIUS * 2.15, 0.014, M.metal, -LENGTH / 2 + ((i + 0.5) * LENGTH) / TURNS, 0, 0, 0, 0, (i * PI) / 4)\n box(magazine, 0.05, 0.03, 0.03, M.dark, -LENGTH / 2 - 0.02, RADIUS * 0.4, 0)\n parts.magDrop = 0.16\n return x\n}\n","import type * as THREE from 'three'\nimport { buildBeltBox } from './attachments/belt-box'\nimport { buildDrum } from './attachments/drum'\nimport { buildHelicalMagazine } from './helical-magazine'\nimport type { RifleContext } from './rifle-context'\n\n/** Grip, trigger group and selector. Returns the x of the grip, which the magazine and the lever hang from. */\nexport function buildGrip(context: RifleContext): number {\n const { kit, group, parts, options: o, furniture: furn, receiverStart: x0, receiverHeight: hR, receiverWidth: wR } = context\n const { M, box } = kit\n const gx = x0 + (o.gripAt || 0.07)\n if (!context.isTraditional && o.grip !== 'none') {\n const grip = kit.pivot(group, gx - 0.012, -hR / 2 - 0.046, 0)\n grip.rotation.z = -0.3\n parts.grip = grip\n box(grip, 0.032, 0.105, 0.028, furn, 0, 0, 0)\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, 0.026, furn, 0.017, 0.022 - i * 0.02, 0)\n box(grip, 0.034, 0.008, 0.03, furn, 0, -0.052, 0)\n }\n box(group, 0.06, 0.004, 0.01, M.metal, gx + 0.03, -hR / 2 - 0.024, 0)\n box(group, 0.004, 0.022, 0.01, M.metal, gx + 0.06, -hR / 2 - 0.013, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.024, -hR / 2 - 0.012, 0, 0.15)\n if (o.sel) parts.safety = box(group, 0.016, 0.005, 0.003, M.dark, gx + 0.005, -hR * 0.15, -wR / 2 - 0.002, 0.4)\n return gx\n}\n\n/** The magazine of the kind the options name (curved, box, drum, internal, belt), and the cover and belt box of a belt-fed gun. Returns the x of the well. */\nexport function buildMagazine(context: RifleContext, gx: number): number {\n const { kit, group, parts, options: o, receiverStart: x0, receiverHeight: hR, receiverWidth: wR, receiverLength: RL } = context\n const { M, box } = kit\n if (o.mag === 'helical') return buildHelicalMagazine(context)\n const mx = o.magAt != null ? x0 + o.magAt : gx + 0.075\n const scale = o.magLen || 1\n const magazine = kit.pivot(group, mx, -hR / 2, 0)\n parts.mag = magazine\n const finish: THREE.Material | undefined = o.magMat === 'bakelite' ? M.bakelite : o.magMat === 'poly' ? M.polyMag : undefined\n if (o.mag === 'curved') {\n let px = 0\n let py = 0\n const material = finish ?? M.metal\n for (const angle of [0.06, 0.22, 0.38]) {\n const length = 0.07 * scale\n const cx = px + (Math.sin(angle) * length) / 2\n const cy = py - (Math.cos(angle) * length) / 2\n box(magazine, 0.052, length + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, length * 0.8, 0.026, M.dark, cx, cy, 0, angle)\n px += Math.sin(angle) * length\n py -= Math.cos(angle) * length\n }\n box(magazine, 0.058, 0.008, 0.028, material, px, py, 0, 0.38)\n parts.magDrop = 0.07 * scale * 3 + 0.04\n } else if (o.mag === 'box') {\n const length = 0.13 * scale\n const curve = o.curve || 0\n const segment = length / 3\n const material = finish ?? M.dark\n let px = 0\n let py = 0\n let angle = 0.08\n for (let i = 0; i < 3; i++) {\n angle = 0.08 + curve * i\n const cx = px + (Math.sin(angle) * segment) / 2\n const cy = py - (Math.cos(angle) * segment) / 2\n box(magazine, 0.05, segment + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, 0.003, 0.026, M.metal, cx, cy, 0, angle)\n px += Math.sin(angle) * segment\n py -= Math.cos(angle) * segment\n }\n box(magazine, 0.056, 0.007, 0.028, material, px, py - 0.002, 0, angle)\n parts.magDrop = length + 0.03\n } else if (o.mag === 'drum') {\n buildDrum(kit, magazine)\n parts.magDrop = 0.2\n } else if (o.mag === 'internal') {\n box(group, 0.08, 0.025, 0.03, context.isTraditional ? context.furniture : M.metal, mx, -hR / 2 - 0.012, 0)\n parts.mag = null\n } else parts.mag = null\n if (o.mag === 'belt') {\n const belt = kit.pivot(group, mx + 0.02, -hR / 2 - 0.05, -0.045)\n parts.belt = belt\n buildBeltBox(kit, belt)\n const cover = kit.pivot(group, x0 + 0.01, hR / 2, 0)\n parts.cover = cover\n box(cover, RL - 0.03, 0.014, wR * 1.05, M.metal, (RL - 0.03) / 2, 0.007, 0)\n box(cover, 0.02, 0.012, wR * 0.6, M.dark, RL - 0.04, 0.016, 0)\n }\n return mx\n}\n","import { buttpad, swivel } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** The stock by kind, in the order the page draws them. `magazineX` places the magazine well plate of the one-piece stock. */\nexport function buildStock(context: RifleContext, magazineX: number): void {\n const { kit, group, options: o, furniture: furn, length: L, stockLength: S, receiverStart: x0, receiverEnd: x1, receiverHeight: hR } = context\n const { M, box, cylinderX } = kit\n if (context.isTraditional) {\n buttpad(kit, group, 0.006, -0.04, 0.13, 0.038)\n box(group, 0.03, 0.13, 0.038, furn, 0.024, -0.04, 0)\n box(group, S, 0.055, 0.034, furn, S / 2, -0.012, 0, 0.06)\n box(group, 0.09, 0.05, 0.032, furn, x0 - 0.02, -0.035, 0, 0.25)\n const forendLength = x1 - x0 + (L - x1) * (o.fore ?? 0.62)\n if (forendLength > 0) box(group, forendLength, 0.045, 0.04, furn, x0 + forendLength / 2, -hR / 2 + 0.004, 0)\n if (o.stock === 'straight') box(group, 0.15, 0.04, 0.035, furn, x1 + 0.08, -hR / 2, 0)\n box(group, 0.04, 0.004, 0.03, M.metal, magazineX, -hR / 2 - 0.022, 0)\n swivel(kit, group, 0.2, -0.08)\n swivel(kit, group, x1 + (L - x1) * 0.45, -hR / 2 - 0.03)\n if (o.bands) for (const fraction of [0.35, 0.75]) cylinderX(group, 0.024, 0.008, M.metal, x1 + (L - x1) * fraction * (o.fore || 0.62), -0.004, 0, 16)\n } else if (o.stock === 'fixed' || o.stock === 'wood') {\n box(group, S, 0.05, 0.03, furn, S / 2, -0.008, 0, 0.05)\n box(group, 0.03, 0.13, 0.036, furn, 0.022, -0.035, 0)\n buttpad(kit, group, 0.004, -0.035, 0.13, 0.036)\n if (o.stock === 'wood') box(group, S * 0.6, 0.03, 0.028, furn, S * 0.55, -0.045, 0, 0.2)\n swivel(kit, group, 0.08, -0.09)\n } else if (o.stock === 'skeleton') {\n box(group, S, 0.014, 0.026, furn, S / 2, 0.012, 0, 0.03)\n box(group, S, 0.014, 0.026, furn, S / 2, -0.05, 0, -0.08)\n box(group, 0.03, 0.12, 0.034, furn, 0.02, -0.025, 0)\n buttpad(kit, group, 0.004, -0.025, 0.12, 0.034)\n } else if (o.stock === 'retract') {\n cylinderX(group, 0.013, S, M.metal, S / 2, 0, 0, 16)\n for (let i = 0; i < 5; i++) box(group, 0.003, 0.003, 0.008, M.dark, S * 0.2 + i * 0.015, -0.013, 0)\n box(group, 0.034, 0.11, 0.036, furn, 0.02, -0.025, 0)\n box(group, S * 0.55, 0.032, 0.03, furn, S * 0.35, 0, 0)\n buttpad(kit, group, 0.003, -0.025, 0.11, 0.036)\n } else if (o.stock === 'fold') {\n box(group, S, 0.006, 0.006, M.metal, S / 2, 0.01, 0.012)\n box(group, S, 0.006, 0.006, M.metal, S / 2, -0.04, 0.012, -0.12)\n box(group, 0.012, 0.1, 0.03, M.metal, 0.006, -0.02, 0.012)\n }\n}\n","import { heatify } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildBrake } from './attachments/muzzle-brake'\nimport { captured, recordFitting } from './capture'\nimport { rail } from './details'\nimport { buildFittings } from './rifle-fittings'\nimport { buildForend } from './rifle-forend'\nimport { buildGrip, buildMagazine } from './rifle-controls'\nimport { buildStock } from './rifle-stock'\nimport type { RifleContext } from './rifle-context'\nimport type { BuiltModel, ModelFamily, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Receiver by kind (round, AR, plain), the AK and G3 extras, the ejection port, the bolt and its charging handle. */\nfunction buildReceiver(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, receiverLength: RL, barrelY: by } = context\n const { M, box, cylinderX, cylinderY, cylinderZ, sphere } = kit\n const receiverMaterial = o.tan ? M.tan : M.metal\n const middle = (x0 + x1) / 2\n if (o.round) {\n cylinderX(group, hR * 0.36, RL, M.steel, middle, by, 0, 20)\n cylinderX(group, hR * 0.32, 0.05, M.steel, x0 - 0.01, by, 0, 18)\n } else if (o.ar) {\n box(group, RL, hR * 0.5, wR, receiverMaterial, middle, hR * 0.25, 0)\n box(group, RL * 0.92, hR * 0.52, wR * 0.96, receiverMaterial, middle - RL * 0.02, -hR * 0.24, 0)\n box(group, 0.05, 0.03, wR * 1.15, receiverMaterial, x0 + RL * 0.62, -hR * 0.5 - 0.01, 0)\n cylinderZ(group, 0.006, 0.012, M.metal, x1 - 0.03, hR * 0.28, wR / 2 + 0.006, 12)\n box(group, 0.012, 0.01, 0.012, M.metal, x1 - 0.05, hR * 0.12, wR / 2 + 0.006)\n box(group, 0.03, 0.008, 0.012, M.dark, x0 + 0.02, hR / 2 + 0.004, 0)\n box(group, 0.012, 0.006, 0.004, M.dark, x0 + RL * 0.55, -hR * 0.15, -wR / 2 - 0.002)\n } else box(group, RL, hR, wR, receiverMaterial, middle, 0, 0)\n if (o.ak) {\n box(group, RL * 0.86, hR * 0.28, wR * 0.95, M.metal, middle - 0.008, hR / 2 + 0.004, 0)\n for (let i = 0; i < 3; i++) box(group, 0.004, hR * 0.3, wR * 0.97, M.dark, x0 + RL * 0.25 + i * 0.02, hR / 2 + 0.004, 0)\n box(group, RL * 0.5, 0.012, 0.003, M.metal, x0 + RL * 0.55, -hR * 0.02, wR / 2 + 0.0015, -0.05)\n box(group, 0.012, 0.014, 0.003, M.dark, x0 + RL * 0.32, -hR * 0.05, wR / 2 + 0.002)\n }\n if (o.g3) {\n cylinderX(group, 0.009, (L - x1) * 0.6, M.metal, x1 + (L - x1) * 0.28, hR * 0.48, 0, 14)\n box(group, 0.012, 0.024, 0.008, M.dark, x1 + (L - x1) * 0.5, hR * 0.48, -0.012)\n cylinderY(group, 0.012, 0.016, M.dark, x0 + 0.03, hR / 2 + 0.008, 0, 12)\n }\n const ejectX = x1 - (o.ejectBack || 0.07)\n const ejectY = o.ar ? hR * 0.2 : by\n box(group, 0.05, hR * 0.36, 0.004, M.hole, ejectX, ejectY, wR / 2 - 0.0004)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n parts.stroke = Math.min(0.1, RL * 0.32)\n box(bolt, 0.044, hR * 0.26, 0.006, M.steelL, ejectX, ejectY, wR / 2 - 0.0012)\n if (o.charge) {\n box(bolt, 0.012, 0.01, 0.03, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.012)\n sphere(bolt, 0.0065, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.028, 1)\n }\n if (o.ar) box(group, 0.012, 0.016, 0.006, receiverMaterial, ejectX - 0.03, ejectY + 0.004, wR / 2 + 0.004)\n if (o.rail) rail(kit, group, x0 - 0.005, RL + 0.07, hR / 2 + (o.ar ? 0 : 0.003), 0, wR * 0.68)\n}\n\n/** Barrel with its jacket, gas tube and muzzle device. */\nfunction buildBarrel(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, barrelLength: Bl, receiverEnd: x1, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX } = kit\n heatify(parts.glow, cylinderX(group, r, Bl, M.metal, L - Bl / 2, by, 0, 16))\n if (o.jacket) {\n cylinderX(group, r * 2, (L - x1) * 0.6, M.dark, x1 + (L - x1) * 0.3, by, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, r * 2.15, 0.004, M.metal, x1 + (L - x1) * (0.05 + i * 0.09), by, 0, 16)\n }\n if (o.gas) cylinderX(group, r * 0.75, (L - x1) * 0.55, M.metal, x1 + (L - x1) * 0.3, by + r * 2.2, 0, 14)\n if (o.brake) {\n const kind = o.brake === 2 ? 2 : 1\n recordFitting(parts, kind === 2 ? 'muzzle_brake_heavy' : 'muzzle_brake', group, () => buildBrake(kit, group, kind, L, by, r, (body) => void heatify(parts.glow, body)))\n } else if (!o.noFH) {\n recordFitting(parts, 'muzzle_default', group, () => {\n heatify(parts.glow, cylinderX(group, r * 1.45, 0.042, M.dark, L - 0.021, by, 0, 16))\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + PI / 4\n box(group, 0.026, 0.0025, 0.004, M.hole, L - 0.02, by + Math.cos(angle) * r * 1.42, Math.sin(angle) * r * 1.42, 0, 0, angle)\n }\n })\n }\n cylinderX(group, r * 0.55, 0.004, M.hole, L + 0.0005, by, 0, 12)\n}\n\nconst familyOf = (o: ModelOptions): ModelFamily => {\n if (o.mag === 'belt') return 'belt'\n if (o.pump) return 'pump'\n if (o.lever) return 'lever'\n if (o.tube) return 'semi12'\n if (o.bolt) return o.mag === 'box' ? 'boltmag' : 'bolt'\n return o.mag === 'internal' ? 'semiint' : 'rifle'\n}\n\n/** Port of the gallery's `rifle`, the builder of 51 of the weapons: receiver, barrel, forend, grip, magazine, stock and what is fitted on them. */\nexport function buildRifle(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'rifle', glow: [] }\n const length = (options.L ?? 0) / 1000\n const barrelLength = (options.B ?? 0) / 1000\n const isTraditional = options.stock === 'trad' || options.stock === 'straight'\n const stockLength = options.stock === 'none' ? 0 : options.stockLen || Math.min(0.36, Math.max(0.2, 0.3 * length))\n const receiverStart = stockLength\n const receiverEnd = Math.max(receiverStart + 0.12, length - barrelLength * 0.92)\n const receiverHeight = options.hR || 0.06\n const context: RifleContext = {\n kit,\n group,\n parts,\n options,\n furniture: options.wood ? M.wood : options.olive ? M.olive : options.tan ? M.tan : M.poly,\n isTraditional,\n length,\n barrelLength,\n stockLength,\n receiverStart,\n receiverEnd,\n receiverHeight,\n receiverWidth: options.wR || 0.034,\n barrelRadius: options.br || 0.0085,\n barrelY: receiverHeight * 0.15,\n receiverLength: receiverEnd - receiverStart,\n }\n buildReceiver(context)\n buildBarrel(context)\n buildForend(context)\n const gripX = buildGrip(context)\n const magazineX = buildMagazine(context, gripX)\n parts.stockMeshes = context.isTraditional ? [] : captured(group, () => buildStock(context, magazineX))\n if (context.isTraditional) buildStock(context, magazineX)\n buildFittings(context, gripX)\n const hasHandguard = !context.isTraditional && options.hg !== 'none'\n parts.frames = {\n length,\n barrelY: context.barrelY,\n barrelRadius: context.barrelRadius,\n receiverStart,\n receiverEnd,\n receiverHeight,\n receiverWidth: context.receiverWidth,\n handguardEnd: receiverEnd + (length - receiverEnd) * (hasHandguard ? options.hgFrac || 0.5 : 0.4),\n magazineX,\n gripX,\n hasRail: Boolean(options.rail),\n }\n const { barrelY: by, receiverWidth: wR } = context\n const ejectX = receiverEnd - (options.ejectBack || 0.07)\n const ejectY = options.ar ? receiverHeight * 0.2 : by\n parts.muzzle = kit.mark(group, length + 0.01, by, 0)\n parts.eject = kit.mark(group, ejectX, ejectY, wR / 2 + 0.006)\n parts.loadPort = kit.mark(group, receiverEnd - 0.05, -receiverHeight / 2 - 0.004, 0)\n parts.topLoad = kit.mark(group, ejectX, receiverHeight / 2 + 0.004, 0)\n parts.family = familyOf(options)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\n\nimport type { ModelKit } from './kit'\nimport { buildRifle } from './rifle'\nimport type { BuiltModel, ModelOptions } from './types'\n\n/**\n * The gallery's M79 (`buildExp('m79')`: the `rifle` builder with a wooden stock and forend and the 40 mm tube) with its break action: the tube and the forend ahead of the\n * receiver hang from a hinge (`barrels`) that folds down to load one grenade at the breech, as the real one opens. The meshes are the page's, moved under the hinge as they stand.\n */\nexport function buildBreakLauncher(kit: ModelKit, options: ModelOptions): BuiltModel {\n const built = buildRifle(kit, options)\n const { group, parts } = built\n const frames = parts.frames\n if (!frames) return built\n const hingeY = frames.barrelY - frames.barrelRadius\n const barrels = kit.pivot(group, frames.receiverEnd, hingeY, 0)\n group.updateMatrixWorld(true)\n const centre = new kit.THREE.Vector3()\n for (const child of [...group.children]) {\n if (child === barrels) continue\n const mesh = child as THREE_NS.Mesh\n const isAhead = mesh.isMesh ? new kit.THREE.Box3().setFromObject(mesh).getCenter(centre).x > frames.receiverEnd : child === parts.muzzle\n if (isAhead) barrels.attach(child)\n }\n parts.barrels = barrels\n parts.breech = [kit.mark(barrels, 0.004, frames.barrelY - hingeY, 0)]\n parts.eject = parts.breech[0]\n parts.family = 'break'\n return built\n}\n","import type * as THREE_NS from 'three'\nimport type { MountKind } from '@adatechnology/game-weapons'\nimport type { ModelFrames, ModelParts } from '../types'\n\ntype Vec3 = [number, number, number]\nconst DEFAULT_BARREL_RADIUS = 0.0085\nconst DEFAULT_RECEIVER_WIDTH = 0.034\nconst RECEIVER_START_FRACTION = 0.25\nconst RECEIVER_END_FRACTION = 0.55\nconst RECEIVER_HEIGHT_FRACTION = 0.4\nconst DEFAULT_GRIP_OFFSET = 0.07\n// how far the handguard reaches past the receiver, as a fraction of what is left of the barrel, for a model that does not say\nconst HANDGUARD_FRACTION = 0.5\n\n/** The shape of a model that carries its `inner` and `root` as `buildWeaponModelById` makes them. */\nexport interface FramedModel {\n readonly root: THREE_NS.Group\n readonly inner: THREE_NS.Group\n readonly parts: ModelParts\n}\n\n/** Where an accessory of one kind of mount goes, in the space of the wrapper (`root`): the origin of its own frame and the sizes it needs from the weapon. */\nexport interface MountFrame {\n readonly mount: MountKind\n readonly position: Vec3\n /** The other end, for what stretches between two points (a sling between its swivels). */\n readonly secondary?: Vec3\n readonly barrelRadius: number\n readonly receiverWidth: number\n readonly receiverHeight: number\n /** The top rail is drawn: an optic needs no adapter. */\n readonly hasRail: boolean\n /** The sign of z for a side rail: left is negative, right is positive (z is to the right of the weapon). */\n readonly side: -1 | 0 | 1\n}\n\n/**\n * Frames for a model whose builder wrote none (pistols, revolvers, bullpups, launchers...): measured from the model as it is built, with `root` still at the origin.\n * The numbers are in the space of `inner`, like the ones the rifle builder writes.\n */\nexport function deriveFrames(THREE: typeof THREE_NS, model: FramedModel): ModelFrames {\n const { root, inner, parts } = model\n root.updateMatrixWorld(true)\n const box = new THREE.Box3().setFromObject(root)\n const span = box.max.x - box.min.x\n const toInnerX = (x: number): number => (x - inner.position.x) / inner.scale.x\n const muzzle = parts.muzzle?.position\n const length = muzzle ? muzzle.x - 0.01 : toInnerX(box.max.x)\n const receiverStart = toInnerX(box.min.x + span * RECEIVER_START_FRACTION)\n const receiverEnd = toInnerX(box.min.x + span * RECEIVER_END_FRACTION)\n return {\n length,\n barrelY: muzzle?.y ?? (box.max.y + box.min.y) / 2,\n barrelRadius: DEFAULT_BARREL_RADIUS,\n receiverStart,\n receiverEnd,\n receiverHeight: (box.max.y - box.min.y) * RECEIVER_HEIGHT_FRACTION,\n receiverWidth: Math.min(DEFAULT_RECEIVER_WIDTH, box.max.z - box.min.z),\n handguardEnd: receiverEnd + (length - receiverEnd) * HANDGUARD_FRACTION,\n magazineX: parts.mag ? parts.mag.position.x : (receiverStart + receiverEnd) / 2,\n gripX: receiverStart + DEFAULT_GRIP_OFFSET,\n hasRail: false,\n }\n}\n\n/** The frame of a mount of the model, or undefined for the mounts nothing is drawn on (`stock`, `barrel`). */\nexport function mountFrame(model: FramedModel, mount: MountKind): MountFrame | undefined {\n const frames = model.parts.frames\n if (!frames) return undefined\n const { inner } = model\n const toRoot = (x: number, y: number, z: number): Vec3 => [inner.position.x + x * inner.scale.x, y, z]\n const handguardHeight = frames.receiverHeight * 0.8\n const railTopY = frames.receiverHeight / 2 + (frames.hasRail ? 0.006 : 0)\n const forendMiddle = (frames.receiverEnd + frames.handguardEnd) / 2\n const base = { mount, barrelRadius: frames.barrelRadius, receiverWidth: frames.receiverWidth, receiverHeight: frames.receiverHeight, hasRail: frames.hasRail }\n switch (mount) {\n case 'muzzle':\n return { ...base, position: toRoot(frames.length, frames.barrelY, 0), side: 0 }\n case 'rail_top':\n return { ...base, position: toRoot((frames.receiverStart + frames.receiverEnd) / 2 + 0.03, railTopY, 0), side: 0 }\n case 'rail_bottom':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY - handguardHeight / 2, 0), side: 0 }\n case 'rail_left':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY, -(frames.receiverWidth * 0.54 + 0.004)), side: -1 }\n case 'rail_right':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY, frames.receiverWidth * 0.54 + 0.004), side: 1 }\n case 'underbarrel': {\n const [x, y] = frames.underbarrel ?? [frames.receiverEnd + (frames.handguardEnd - frames.receiverEnd) * 0.25, frames.barrelY - handguardHeight / 2 - 0.02]\n return { ...base, position: toRoot(x, y, 0), side: 0 }\n }\n case 'magazine':\n return { ...base, position: toRoot(frames.magazineX, -frames.receiverHeight / 2, 0), side: 0 }\n case 'feed': {\n const belt = model.parts.belt?.position\n return { ...base, position: belt ? toRoot(belt.x, belt.y, belt.z) : toRoot(frames.magazineX + 0.02, -frames.receiverHeight / 2 - 0.05, -0.045), side: -1 }\n }\n case 'sling':\n return {\n ...base,\n position: toRoot(frames.receiverEnd + (frames.length - frames.receiverEnd) * 0.45, -frames.receiverHeight / 2 - 0.03, 0),\n secondary: toRoot(0.08, -0.09, 0),\n side: 0,\n }\n default:\n return undefined\n }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { rail, scope } from './details'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `bullpup`: the rifle (AUG) or, with `shot`, the twin-tube pump shotgun (KSG). */\nexport function buildBullpup(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const bodyLength = Math.max(0.32, L - barrel * 0.72)\n const body = options.shot ? M.poly : M.olive\n const parts: ModelParts = { family: options.shot ? 'pump' : 'rifle', stroke: 0.06, glow: [] }\n box(group, bodyLength, 0.075, 0.042, body, bodyLength / 2, 0, 0)\n box(group, bodyLength * 0.9, 0.02, 0.044, M.dark, bodyLength * 0.5, -0.02, 0)\n box(group, 0.032, 0.13, 0.044, M.rubber, 0.016, -0.025, 0)\n const gx = bodyLength * 0.8\n const grip = kit.pivot(group, gx, -0.085, 0)\n grip.rotation.z = -0.25\n parts.grip = grip\n box(grip, 0.03, 0.1, 0.03, M.poly, 0, 0, 0)\n box(group, 0.1, 0.006, 0.03, body, gx + 0.01, -0.06, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.02, -0.05, 0, 0.15)\n heatify(parts.glow, cylinderX(group, options.shot ? 0.0105 : 0.0085, barrel, M.metal, L - barrel / 2, 0.012, 0, 16))\n cylinderX(group, 0.006, 0.004, M.hole, L + 0.001, 0.012, 0, 12)\n box(group, 0.05, 0.024, 0.004, M.hole, bodyLength * 0.25, 0.005, 0.0212)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.044, 0.02, 0.006, M.steelL, bodyLength * 0.25, 0.005, 0.02)\n if (options.shot) {\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, 0.014, 14)\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, -0.014, 14)\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.15, 0.045, 0.052, M.poly, bodyLength + 0.06, -0.015, 0)\n for (let i = 0; i < 6; i++) box(pump, 0.006, 0.047, 0.054, M.dark, bodyLength + 0.005 + i * 0.022, -0.015, 0)\n rail(kit, group, bodyLength * 0.15, bodyLength * 0.8, 0.04, 0, 0.02)\n parts.loadPort = kit.mark(group, bodyLength * 0.2, -0.04, 0)\n } else {\n const magazine = kit.pivot(group, gx - 0.11, -0.03, 0)\n magazine.rotation.z = 0.14\n parts.mag = magazine\n box(magazine, 0.05, 0.14, 0.026, M.glass, 0, -0.07, 0)\n for (let i = 0; i < 6; i++) cylinderX(magazine, 0.003, 0.04, M.brass, 0, -0.01 - i * 0.02, 0, 6)\n parts.magDrop = 0.18\n scope(kit, group, 2, bodyLength * 0.5, 0.04, 0)\n box(group, 0.2, 0.03, 0.02, body, bodyLength * 0.62, 0.048, 0)\n box(group, 0.026, 0.075, 0.026, body, bodyLength + 0.05, -0.05, 0, 0.1)\n }\n parts.muzzle = kit.mark(group, L + 0.01, 0.012, 0)\n parts.eject = kit.mark(group, bodyLength * 0.25, 0.005, 0.03)\n return { group, parts }\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { ModelParts } from './types'\n\ntype Point = [number, number, number]\n\nconst hose = (kit: ModelKit, group: THREE.Group, points: Point[], radius: number, material: THREE.Material): void => {\n const { THREE } = kit\n const curve = new THREE.CatmullRomCurve3(points.map((point) => new THREE.Vector3(...point)))\n const tube = new THREE.Mesh(new THREE.TubeGeometry(curve, 40, radius, 8, false), material)\n tube.castShadow = tube.receiveShadow = true\n group.add(tube)\n}\n\n/** The pilot light at the nozzle; its two flames carry `userData.flame` for the effect that flickers them. */\nconst pilot = (kit: ModelKit, group: THREE.Group, x: number, y: number): void => {\n const { M, cylinderX } = kit\n cylinderX(group, 0.006, 0.03, M.fire2, x + 0.015, y, 0, 6, 0).userData.flame = 1\n cylinderX(group, 0.004, 0.022, M.fire, x + 0.012, y, 0, 6, 0).userData.flame = 1\n}\n\n/** The M2 flamethrower: nozzle gun, hose and the two fuel tanks with the pressure bottle and its gauge. */\nexport function buildFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.15\n heatify(parts.glow, cylinderX(group, 0.016, 0.62, M.steel, 0.42, 0, 0, 14))\n cylinderX(group, 0.022, 0.1, M.dark, 0.78, 0, 0, 14)\n heatify(parts.glow, cylinderX(group, 0.013, 0.1, M.steel, 0.88, 0, 0, 12, 0.009))\n cylinderX(group, 0.018, 0.02, M.metal, 0.73, 0, 0, 14)\n cylinderX(group, 0.012, 0.06, M.metal, 0.84, -0.025, 0, 10)\n pilot(kit, group, 0.92, -0.012)\n const foreGrip = kit.pivot(group, 0.6, -0.02, 0)\n foreGrip.rotation.z = -0.1\n box(foreGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.62, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.05, 0.006, M.metal, 0.02, -0.03, 0, 0.3)\n const rearGrip = kit.pivot(group, 0.17, -0.02, 0)\n rearGrip.rotation.z = -0.28\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.05, 0.004, 0.012, M.metal, 0.2, -0.035, 0)\n cylinderX(group, 0.02, 0.04, M.metal, 0.1, 0, 0, 12)\n hose(kit, group, [[0.08, 0, 0], [0, -0.04, 0], [-0.08, -0.2, 0.05], [-0.18, -0.32, 0.08], [-0.25, -0.33, 0.08]], 0.011, M.rubber)\n for (const z of [-0.1, 0.1]) {\n cylinderY(group, 0.085, 0.5, M.olive, -0.3, -0.05, z, 20)\n sphere(group, 0.085, M.olive, -0.3, 0.2, z, 2).scale.y = 0.45\n sphere(group, 0.085, M.olive, -0.3, -0.3, z, 2).scale.y = 0.45\n cylinderY(group, 0.03, 0.03, M.metal, -0.3, 0.24, z, 12)\n }\n sphere(group, 0.075, M.olive, -0.3, 0.1, 0, 2).position.x = -0.39\n box(group, 0.03, 0.6, 0.24, M.dark, -0.4, -0.05, 0)\n cylinderY(group, 0.03, 0.012, M.metal, -0.39, 0.18, 0, 14)\n const gauge = kit.pivot(group, -0.39, 0.18, 0.003)\n parts.gauge = gauge\n box(gauge, 0.002, 0.022, 0.002, M.red, 0, 0.008, 0.012)\n parts.muzzle = kit.pivot(group, 0.94, 0, 0)\n parts.rear = kit.pivot(group, 0.1, 0, 0)\n}\n\n/** The improvised flamethrower: a copper pipe, a fire extinguisher as the tank and a rubber hose. */\nexport function buildImprovisedFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.12\n heatify(parts.glow, cylinderX(group, 0.011, 0.66, M.pipe, 0.38, 0, 0, 12))\n heatify(parts.glow, cylinderX(group, 0.015, 0.06, M.steel, 0.74, 0, 0, 12, 0.01))\n cylinderX(group, 0.006, 0.05, M.metal, 0.735, -0.02, 0, 8)\n pilot(kit, group, 0.77, -0.02)\n cylinderY(group, 0.012, 0.04, M.redPaint, 0.72, -0.055, 0, 10)\n box(group, 0.02, 0.03, 0.012, M.dark, 0.72, -0.085, 0)\n cylinderX(group, 0.06, 0.42, M.redPaint, 0.3, -0.09, 0, 22)\n sphere(group, 0.06, M.redPaint, 0.51, -0.09, 0, 2).scale.x = 0.5\n sphere(group, 0.06, M.redPaint, 0.09, -0.09, 0, 2).scale.x = 0.5\n cylinderX(group, 0.02, 0.04, M.dark, 0.04, -0.09, 0, 12)\n box(group, 0.02, 0.06, 0.005, M.white, 0.3, -0.09, 0.06)\n for (const x of [0.15, 0.3, 0.45]) cylinderX(group, 0.063, 0.03, M.tape, x, -0.09, 0, 22)\n cylinderX(group, 0.016, 0.03, M.tape, 0.3, 0, 0, 12)\n hose(kit, group, [[0.04, -0.09, 0], [-0.02, -0.06, 0.02], [0, 0, 0.02], [0.05, 0, 0]], 0.007, M.rubber)\n const rearGrip = kit.pivot(group, 0.12, -0.01, 0)\n rearGrip.rotation.z = -0.3\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.17, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.04, 0.006, M.metal, 0, -0.02, 0, 0.2)\n parts.muzzle = kit.pivot(group, 0.78, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\n\nconst PI = Math.PI\n\n/** The PG-7V grenade of the RPG-7: warhead, body and the booster. */\nexport function buildRocketGrenade(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.018, 0.15, M.olive, -0.05, 0, 0, 14)\n cylinderX(round, 0.02, 0.07, M.olive, 0.035, 0, 0, 18, 0.0425)\n cylinderX(round, 0.0425, 0.12, M.olive, 0.13, 0, 0, 20)\n cylinderX(round, 0.0428, 0.012, M.dark, 0.09, 0, 0, 20)\n cylinderX(round, 0.0425, 0.13, M.olive, 0.255, 0, 0, 20, 0.011)\n cylinderX(round, 0.011, 0.03, M.metal, 0.335, 0, 0, 10, 0.004)\n return round\n}\n\n/** The 84 mm round of the Carl Gustaf. */\nexport function buildRecoillessRound(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.041, 0.32, M.green, -0.16, 0, 0, 20)\n cylinderX(round, 0.0415, 0.02, M.yellow, -0.05, 0, 0, 20)\n cylinderX(round, 0.041, 0.12, M.green, 0.06, 0, 0, 20, 0.012)\n cylinderX(round, 0.043, 0.03, M.brass, -0.33, 0, 0, 20)\n return round\n}\n\n/** The rocket that flies off a disposable tube or a rocket launcher without a model of its own round. */\nexport function buildFlyingRocket(kit: ModelKit, launcherType: string | undefined): THREE.Group {\n const { M, box, cylinderX } = kit\n const rocket = kit.group()\n const diameter = launcherType === 'at4' || launcherType === 'carl' ? 0.041 : 0.032\n cylinderX(rocket, diameter * 0.5, 0.2, M.dark, -0.1, 0, 0, 10)\n cylinderX(rocket, diameter, 0.3, M.olive, 0.15, 0, 0, 18)\n cylinderX(rocket, diameter, 0.12, M.olive, 0.36, 0, 0, 18, diameter * 0.25)\n for (let i = 0; i < 4; i++) {\n const fin = box(rocket, 0.06, 0.002, diameter * 1.4, M.metal, -0.17, 0, 0)\n fin.rotation.x = (i * PI) / 4\n }\n return rocket\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { buildRecoillessRound, buildRocketGrenade } from './launcher-rounds'\nimport type { ModelParts } from './types'\n\n/** The RPG-7: tube, wooden heat shield, two grips, optic and the grenade in the muzzle. */\nfunction buildRpg(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.6\n cylinderX(group, 0.036, 0.13, M.dark, 0.065, 0, 0, 20, 0.021)\n cylinderX(group, 0.038, 0.012, M.metal, 0, 0, 0, 20)\n heatify(parts.glow, cylinderX(group, 0.021, 0.83, M.steel, 0.545, 0, 0, 18))\n cylinderX(group, 0.03, 0.3, M.wood, 0.47, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.32, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.62, 0, 0, 16)\n cylinderX(group, 0.024, 0.02, M.metal, 0.94, 0, 0, 16)\n box(group, 0.09, 0.03, 0.032, M.metal, 0.46, -0.028, 0)\n const frontGrip = kit.pivot(group, 0.4, -0.04, 0)\n frontGrip.rotation.z = -0.22\n box(frontGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const rearGrip = kit.pivot(group, 0.5, -0.04, 0)\n rearGrip.rotation.z = -0.18\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.53, -0.05, 0)\n box(group, 0.004, 0.025, 0.012, M.metal, 0.56, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.535, -0.045, 0, 0.15)\n const hammer = kit.pivot(group, 0.44, -0.012, 0)\n parts.hammer = hammer\n box(hammer, 0.012, 0.02, 0.01, M.dark, 0, 0, 0)\n box(group, 0.006, 0.03, 0.006, M.dark, 0.78, 0.032, 0)\n box(group, 0.02, 0.022, 0.014, M.dark, 0.46, 0.032, 0)\n box(group, 0.12, 0.042, 0.032, M.dark, 0.5, 0.04, -0.04)\n cylinderX(group, 0.013, 0.05, M.rubber, 0.42, 0.048, -0.04, 14)\n cylinderX(group, 0.016, 0.004, M.lens, 0.565, 0.048, -0.04, 14)\n box(group, 0.04, 0.012, 0.012, M.metal, 0.5, 0.016, -0.03)\n const round = buildRocketGrenade(kit)\n round.position.x = 0.95\n group.add(round)\n parts.round = round\n parts.roundRest = 0.95\n parts.makeRound = () => buildRocketGrenade(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The M72 LAW: a disposable tube with its sight flaps and the firing pin. */\nfunction buildM72(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY } = kit\n parts.kick = 1.1\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.0365, 0.6, M.olive, 0.58, 0, 0, 20))\n cylinderX(group, 0.032, 0.32, M.olive, 0.16, 0, 0, 20)\n cylinderX(group, 0.039, 0.03, M.rubber, 0.866, 0, 0, 20)\n cylinderX(group, 0.035, 0.025, M.rubber, 0.012, 0, 0, 20)\n cylinderX(group, 0.037, 0.015, M.yellow, 0.8, 0, 0, 20)\n cylinderX(group, 0.037, 0.012, M.dark, 0.3, 0, 0, 20)\n box(group, 0.004, 0.05, 0.05, M.dark, 0.79, 0.055, 0)\n box(group, 0.004, 0.006, 0.04, M.dark, 0.79, 0.078, 0)\n box(group, 0.004, 0.035, 0.024, M.dark, 0.38, 0.05, 0)\n cylinderY(group, 0.004, 0.006, M.lens, 0.38, 0.064, 0, 8)\n parts.trigger = box(group, 0.05, 0.016, 0.024, M.rubber, 0.5, 0.042, 0)\n box(group, 0.1, 0.01, 0.03, M.dark, 0.47, 0.036, 0)\n box(group, 0.02, 0.03, 0.01, M.dark, 0.66, -0.035, 0.03)\n box(group, 0.008, 0.03, 0.008, M.metal, 0.25, -0.04, 0.03)\n parts.muzzle = kit.pivot(group, 0.881, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The AT4: a heavier disposable tube with the fire-control box and the front grip. */\nfunction buildAt4(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.3\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.05, 0.86, M.olive, 0.51, 0, 0, 24))\n cylinderX(group, 0.056, 0.08, M.dark, 0.98, 0, 0, 24)\n cylinderX(group, 0.058, 0.07, M.dark, 0.04, 0, 0, 24, 0.05)\n cylinderX(group, 0.051, 0.015, M.yellow, 0.86, 0, 0, 24)\n box(group, 0.16, 0.026, 0.05, M.dark, 0.42, 0.058, 0)\n box(group, 0.03, 0.012, 0.016, M.red, 0.47, 0.075, 0)\n parts.trigger = box(group, 0.022, 0.012, 0.018, M.rubber, 0.5, 0.074, 0)\n box(group, 0.012, 0.07, 0.02, M.dark, 0.35, 0.09, -0.035)\n box(group, 0.012, 0.05, 0.02, M.dark, 0.71, 0.08, -0.035)\n const grip = kit.pivot(group, 0.68, -0.05, 0)\n grip.rotation.z = -0.15\n parts.grip = grip\n box(grip, 0.035, 0.11, 0.032, M.dark, 0, -0.05, 0)\n box(group, 0.14, 0.035, 0.06, M.rubber, 0.32, -0.06, 0)\n box(group, 0.3, 0.012, 0.055, M.dark, 0.5, -0.05, 0)\n parts.muzzle = kit.pivot(group, 1.02, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The Carl Gustaf M4: a reusable recoilless rifle with a hinged breech that takes a round from behind. */\nfunction buildCarlGustaf(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.4\n heatify(parts.glow, cylinderX(group, 0.045, 0.72, M.dark, 0.59, 0, 0, 24))\n cylinderX(group, 0.05, 0.04, M.rubber, 0.93, 0, 0, 24)\n const breech = kit.pivot(group, 0.21, 0, 0.05)\n parts.breech = [breech]\n cylinderX(breech, 0.06, 0.16, M.dark, -0.1, 0, -0.05, 24, 0.046)\n cylinderX(breech, 0.062, 0.015, M.metal, -0.18, 0, -0.05, 24)\n box(group, 0.025, 0.03, 0.02, M.metal, 0.22, 0, 0.052)\n const foreGrip = kit.pivot(group, 0.62, -0.05, 0)\n foreGrip.rotation.z = -0.2\n box(foreGrip, 0.035, 0.11, 0.034, M.dark, 0, -0.05, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.66, -0.06, 0, 0.15)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.66, -0.07, 0)\n const rearGrip = kit.pivot(group, 0.4, -0.05, 0)\n rearGrip.rotation.z = -0.25\n box(rearGrip, 0.035, 0.1, 0.034, M.dark, 0, -0.05, 0)\n box(group, 0.13, 0.04, 0.07, M.rubber, 0.28, -0.065, 0)\n box(group, 0.16, 0.05, 0.045, M.dark, 0.56, 0.07, -0.035)\n cylinderX(group, 0.016, 0.05, M.rubber, 0.46, 0.075, -0.035, 14)\n cylinderX(group, 0.02, 0.004, M.lens, 0.645, 0.075, -0.035, 14)\n box(group, 0.06, 0.02, 0.02, M.metal, 0.56, 0.04, -0.03)\n box(group, 0.22, 0.01, 0.02, M.dark, 0.6, 0.06, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.5, 0.05, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.7, 0.05, 0.03)\n parts.makeRound = () => buildRecoillessRound(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n\nexport const ROCKET_BUILDERS: Record<string, (kit: ModelKit, group: THREE.Group, parts: ModelParts) => void> = {\n rpg: buildRpg,\n m72: buildM72,\n at4: buildAt4,\n carl: buildCarlGustaf,\n}\n","import type { ModelKit } from './kit'\nimport { buildFlamethrower, buildImprovisedFlamethrower } from './launcher-flame'\nimport { ROCKET_BUILDERS } from './launcher-rocket'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `launcher`: the four rocket launchers and the two flamethrowers, picked by `lt`. */\nexport function buildLauncher(kit: ModelKit, options: ModelOptions): BuiltModel {\n const group = kit.group()\n const type = options.lt ?? ''\n const isFlame = type === 'flame' || type === 'flameDIY'\n const parts: ModelParts = { family: isFlame ? 'flame' : 'rocket', launcherType: type, glow: [] }\n if (type === 'flame') buildFlamethrower(kit, group, parts)\n else if (type === 'flameDIY') buildImprovisedFlamethrower(kit, group, parts)\n else ROCKET_BUILDERS[type]?.(kit, group, parts)\n parts.eject = parts.muzzle\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelParts } from './types'\n\nconst PI = Math.PI\nconst BARRELS = 6\n// the barrels sit on a circle around the rotor axis\nconst CLUSTER_RADIUS = 0.03\nconst BARREL_RADIUS = 0.0078\nconst BARREL_END = 0.8\n\n/** The six barrels and their clamps in one pivot on the rotor axis: the viewmodel turns `parts.barrels` while the gun fires. */\nfunction buildBarrelCluster(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, cylinderX } = kit\n const barrels = kit.pivot(group, 0, 0, 0)\n parts.barrels = barrels\n const length = BARREL_END - 0.3\n let heated: THREE_NS.Material | undefined\n for (let i = 0; i < BARRELS; i++) {\n const angle = (i * 2 * PI) / BARRELS\n const y = Math.cos(angle) * CLUSTER_RADIUS\n const z = Math.sin(angle) * CLUSTER_RADIUS\n const barrel = cylinderX(barrels, BARREL_RADIUS, length, M.metal, 0.3 + length / 2, y, z, 14)\n // the six barrels heat together: one material of their own, shared\n if (heated) barrel.material = heated\n else heated = heatify(parts.glow, barrel).material as THREE_NS.Material\n cylinderX(barrels, BARREL_RADIUS * 0.55, 0.004, M.hole, BARREL_END + 0.0005, y, z, 10)\n }\n cylinderX(barrels, 0.012, length, M.steel, 0.3 + length / 2, 0, 0, 12)\n for (const x of [0.42, 0.58, 0.74]) cylinderX(barrels, CLUSTER_RADIUS + BARREL_RADIUS * 1.6, 0.014, M.steel, x, 0, 0, 24)\n cylinderX(barrels, CLUSTER_RADIUS + BARREL_RADIUS * 1.8, 0.03, M.dark, BARREL_END - 0.015, 0, 0, 24)\n}\n\n/** Housing with the motor, the rotor housing and the two spade grips with the trigger switch of the hand-held gun. */\nfunction buildHousing(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, box, cylinderX, cylinderZ } = kit\n box(group, 0.3, 0.14, 0.15, M.metal, 0.18, 0, 0)\n cylinderX(group, 0.052, 0.12, M.dark, 0.06, 0, 0, 20)\n cylinderX(group, 0.062, 0.2, M.dark, 0.38, 0, 0, 22)\n for (let i = 0; i < 4; i++) cylinderX(group, 0.064, 0.008, M.steel, 0.3 + i * 0.05, 0, 0, 22)\n box(group, 0.04, 0.05, 0.2, M.dark, 0.1, 0.095, 0)\n box(group, 0.2, 0.012, 0.045, M.dark, 0.22, 0.158, 0)\n box(group, 0.012, 0.05, 0.045, M.dark, 0.13, 0.13, 0)\n box(group, 0.012, 0.05, 0.045, M.dark, 0.31, 0.13, 0)\n for (const side of [-1, 1]) {\n box(group, 0.03, 0.03, 0.1, M.poly, 0.06, -0.01, side * 0.14)\n cylinderZ(group, 0.016, 0.07, M.poly, 0.06, -0.01, side * 0.2, 14)\n }\n parts.trigger = box(group, 0.012, 0.02, 0.016, M.dark, 0.1, 0.085, 0.14, 0.3)\n parts.safety = box(group, 0.014, 0.006, 0.01, M.dark, 0.2, 0.073, -0.076, 0.4)\n}\n\n/** The belt box on the left, the feed chute that carries the belt to the rotor, the cover over it and the charging piece. */\nfunction buildFeed(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, box, cylinderX } = kit\n const belt = kit.pivot(group, 0.2, -0.13, -0.16)\n parts.belt = belt\n box(belt, 0.16, 0.12, 0.1, M.olive, 0, 0, 0)\n box(belt, 0.162, 0.012, 0.102, M.dark, 0, 0.056, 0)\n for (let i = 0; i < 8; i++) cylinderX(belt, 0.0046, 0.04, M.brass, -0.07 + i * 0.02, 0.075, 0.04, 10)\n box(group, 0.1, 0.03, 0.1, M.metal, 0.22, -0.06, -0.1, 0, 0, 0.5)\n const cover = kit.pivot(group, 0.1, 0.075, 0)\n parts.cover = cover\n box(cover, 0.24, 0.012, 0.15, M.metal, 0.12, 0.006, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n parts.stroke = 0.03\n box(bolt, 0.03, 0.012, 0.012, M.steelL, 0.28, 0.02, 0.078)\n}\n\n/** The M134 Minigun: a rotary machine gun of six barrels, electric driven, belt fed. A creation of the kit (the team pages have none): there is no page golden, the model has its own. */\nexport function buildM134(kit: ModelKit): BuiltModel {\n const group = kit.group()\n const parts: ModelParts = { family: 'belt', kick: 0.9, glow: [] }\n buildHousing(kit, parts, group)\n buildBarrelCluster(kit, parts, group)\n buildFeed(kit, parts, group)\n parts.frames = {\n length: BARREL_END,\n barrelY: 0,\n barrelRadius: BARREL_RADIUS,\n receiverStart: 0.06,\n receiverEnd: 0.48,\n receiverHeight: 0.14,\n receiverWidth: 0.15,\n handguardEnd: 0.6,\n magazineX: 0.2,\n gripX: 0.06,\n hasRail: false,\n // the tripod head, where the gun balances (the tripod of the counters joins here too)\n underbarrel: [0.4, -0.1],\n }\n parts.muzzle = kit.mark(group, BARREL_END + 0.01, 0, 0)\n parts.eject = kit.mark(group, 0.3, -0.07, 0.08)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `m2`: the Browning .50 on its tripod, with the cover, the belt box and the bolt. */\nexport function buildM2(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX, cylinderZ } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'belt', kick: 2.2, stroke: 0.08, glow: [] }\n box(group, 0.52, 0.13, 0.12, M.metal, 0.36, 0, 0)\n for (let i = 0; i < 5; i++) cylinderZ(group, 0.006, 0.124, M.dark, 0.15 + i * 0.1, -0.03, 0, 10)\n heatify(parts.glow, cylinderX(group, 0.016, 1.14, M.metal, 1.14, 0.01, 0, 16))\n cylinderX(group, 0.034, 0.24, M.dark, 0.74, 0.01, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, 0.036, 0.012, M.metal, 0.66 + i * 0.035, 0.01, 0, 16)\n cylinderX(group, 0.022, 0.05, M.dark, 1.69, 0.01, 0, 16)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, 0.05)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, -0.05)\n box(group, 0.06, 0.02, 0.12, M.metal, 0.09, -0.02, 0)\n const belt = kit.pivot(group, 0.38, -0.05, -0.12)\n parts.belt = belt\n box(belt, 0.16, 0.12, 0.09, M.olive, 0, 0, 0)\n for (let i = 0; i < 8; i++) cylinderX(belt, 0.006, 0.05, M.brass, -0.08 + i * 0.02, 0.08, 0.04, 8)\n const cover = kit.pivot(group, 0.12, 0.065, 0)\n parts.cover = cover\n box(cover, 0.4, 0.012, 0.12, M.metal, 0.2, 0.006, 0)\n box(group, 0.04, 0.05, 0.04, M.dark, 0.66, 0.1, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.03, 0.03, 0.02, M.metal, 0.5, 0, 0.07)\n const tripod = kit.group()\n tripod.position.set(0.42, -0.1, 0)\n group.add(tripod)\n box(tripod, 0.03, 0.06, 0.03, M.metal, 0, 0, 0)\n box(tripod, 0.012, 0.62, 0.012, M.metal, -0.2, -0.25, 0, 0.75)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, 0.16, -0.75, 0, 0.3)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, -0.16, -0.75, 0, -0.3)\n parts.muzzle = kit.mark(group, 1.72, 0.01, 0)\n parts.eject = kit.mark(group, 0.3, -0.07, 0)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { scope } from './details'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `p90`: the bullpup with the horizontal magazine on top. */\nexport function buildP90(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'p90', stroke: 0.04, kick: 0.6, glow: [] }\n box(group, 0.4, 0.07, 0.055, M.poly, 0.2, 0, 0)\n box(group, 0.12, 0.075, 0.05, M.poly, 0.2, -0.07, 0)\n box(group, 0.08, 0.04, 0.03, M.hole, 0.21, -0.06, 0)\n box(group, 0.06, 0.13, 0.056, M.poly, 0.03, -0.03, 0)\n box(group, 0.05, 0.03, 0.056, M.poly, 0.33, -0.04, 0)\n heatify(parts.glow, cylinderX(group, 0.008, 0.09, M.metal, 0.43, 0, 0, 16))\n const magazine = kit.pivot(group, 0.22, 0.047, 0)\n parts.mag = magazine\n parts.magDir = 1\n parts.magDrop = 0.08\n box(magazine, 0.3, 0.022, 0.05, M.glass, 0, 0, 0)\n for (let i = 0; i < 12; i++) cylinderX(magazine, 0.0028, 0.02, M.brass, -0.12 + i * 0.022, 0, 0, 6)\n scope(kit, group, 1, 0.24, 0.06, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.02, 0.012, 0.012, M.dark, 0.3, 0.02, 0.03)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, 0.24, -0.045, 0)\n parts.muzzle = kit.mark(group, 0.48, 0, 0)\n parts.eject = kit.mark(group, 0.2, -0.07, 0)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelParts } from './types'\n\nconst SINGLE_PARTS = ['slide', 'bolt', 'boltHandle', 'mag', 'trigger', 'hammer', 'lever', 'pump', 'belt', 'cover', 'crane', 'cylinder', 'barrels', 'safety', 'muzzle', 'eject', 'loadPort', 'topLoad', 'rear', 'round', 'gauge', 'stock', 'ugl'] as const\n\n/** The parts of a model by the id the clips use: `slide`, `mag`, `trigger`..., `breech_0`, `chamber_3`. */\nexport function partRegistry(parts: ModelParts): Map<string, THREE_NS.Object3D> {\n const registry = new Map<string, THREE_NS.Object3D>()\n for (const key of SINGLE_PARTS) {\n const part = parts[key]\n if (part) registry.set(key, part)\n }\n parts.breech?.forEach((part, index) => registry.set(`breech_${index}`, part))\n parts.chambers?.forEach((part, index) => registry.set(`chamber_${index}`, part))\n return registry\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport type { ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** The slide: its body by style, serrations, ejection port, barrel tip, sights and the small controls that ride on it. */\nexport function buildSlide(kit: ModelKit, slide: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, metal: Material): void {\n const { M, box, cylinderX } = kit\n const { length: L, width: w } = size\n const slideHeight = style.inset ? size.height * 0.92 : size.height\n const slideWidth = style.inset ? w * 0.86 : w\n kit.roundness = style.rf\n if (style.tri) box(slide, L * 0.42, slideHeight, slideWidth, metal, L * 0.21, 0, 0)\n else if (style.open) {\n box(slide, L * 0.45, slideHeight, slideWidth, metal, L * 0.225, 0, 0)\n box(slide, L * 0.55, slideHeight * 0.62, slideWidth, metal, L * 0.72, -slideHeight * 0.19, 0)\n } else box(slide, L, slideHeight, slideWidth, metal, L / 2, 0, 0)\n if (style.slope) box(slide, L * 0.25, slideHeight * 0.5, slideWidth * 0.98, metal, L * 0.86, slideHeight * 0.35, 0, -0.22)\n kit.roundness = null\n for (let i = 0; i < (style.flush ? 9 : 7); i++) box(slide, 0.0022, slideHeight * 0.72, slideWidth + 0.0014, M.dark, 0.007 + i * 0.0052, -0.002, 0, 0)\n if (style.frontSer) for (let i = 0; i < 5; i++) box(slide, 0.0022, slideHeight * 0.6, slideWidth + 0.0014, M.dark, L * 0.76 + i * 0.0052, -0.003, 0)\n if (style.port) {\n box(slide, L * style.port, 0.004, slideWidth * 0.55, M.hole, L * 0.6, slideHeight / 2 - 0.001, slideWidth * 0.12)\n box(slide, L * style.port * 0.85, 0.003, slideWidth * 0.4, M.steelL, L * 0.6, slideHeight / 2 - 0.0004, slideWidth * 0.1)\n box(slide, 0.012, 0.004, 0.002, M.dark, L * 0.55, slideHeight * 0.15, slideWidth / 2 + 0.0008)\n }\n if (style.open) {\n heatify(parts.glow, cylinderX(slide, 0.0062, L * 0.56, M.steelL, L * 0.7, slideHeight * 0.12, 0, 18))\n box(slide, 0.03, 0.004, slideWidth * 0.6, M.hole, L * 0.48, slideHeight / 2 - 0.001, 0)\n }\n if (style.tri) {\n const tube = new kit.THREE.Mesh(new kit.THREE.CylinderGeometry(0.016, 0.016, L * 0.6, 3), metal)\n tube.castShadow = tube.receiveShadow = true\n tube.rotation.set(0, 0, -PI / 2)\n tube.rotateY(PI / 6)\n tube.position.set(L * 0.7, slideHeight * 0.08, 0)\n slide.add(tube)\n heatify(parts.glow, tube)\n box(slide, L * 0.6, 0.006, 0.012, metal, L * 0.7, slideHeight * 0.38, 0)\n for (let i = 0; i < 6; i++) box(slide, 0.008, 0.003, 0.013, M.hole, L * 0.45 + i * 0.04, slideHeight * 0.41, 0)\n }\n if (style.bushing) {\n heatify(parts.glow, cylinderX(slide, 0.0078, 0.006, M.steelL, L + 0.002, 0.001, 0, 18))\n cylinderX(slide, 0.0045, 0.004, M.steel, L + 0.002, -0.012, 0, 12)\n }\n const muzzleY = style.tri ? slideHeight * 0.08 : 0.002\n heatify(parts.glow, cylinderX(slide, style.tri ? 0.0072 : 0.0062, 0.004, M.dark, L + 0.0015, muzzleY, 0, 18))\n cylinderX(slide, 0.0034, 0.005, M.hole, L + 0.0025, muzzleY, 0, 12)\n const top = slideHeight / 2\n if (style.sight === 'u' || style.sight === '3dot') {\n box(slide, 0.004, 0.007, 0.004, M.dark, L - 0.008, top + 0.0035, 0)\n box(slide, 0.0022, 0.0022, 0.0046, M.white, L - 0.008, top + 0.0058, 0)\n box(slide, 0.008, 0.007, 0.016, M.dark, 0.009, top + 0.0035, 0)\n if (style.sight === 'u') box(slide, 0.004, 0.002, 0.0122, M.white, 0.009, top + 0.006, 0)\n else box(slide, 0.0022, 0.0022, 0.0166, M.white, 0.009, top + 0.0058, 0)\n } else {\n box(slide, 0.006, 0.004, 0.003, M.dark, L - 0.006, top + 0.002, 0)\n box(slide, 0.006, 0.004, 0.012, M.dark, 0.008, top + 0.002, 0)\n }\n if (style.decock === 'slide') {\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, slideWidth / 2 + 0.002, 0.3)\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, -slideWidth / 2 - 0.002, 0.3)\n }\n if (style.safety === 'slide') parts.safety = box(slide, 0.012, 0.008, 0.004, M.dark, 0.018, slideHeight * 0.1, -slideWidth / 2 - 0.002, 0.2)\n if (options.sel) {\n const selector = box(slide, 0.01, 0.008, 0.003, M.dark, 0.014, -slideHeight * 0.2, slideWidth / 2 + 0.0014)\n parts.safety ??= selector\n }\n}\n\n","import type * as THREE from 'three'\n\nexport interface PistolStyle {\n rf: number\n ga: number\n grip: 'finger' | 'panel' | 'wood' | 'rubber' | 'star' | 'chunky'\n guard: 'square' | 'round' | 'hook'\n rail?: number\n sight: 'u' | '3dot' | 'small'\n port: number\n slideM?: string\n frame: 'poly' | 'metal'\n frontSer?: number\n safety?: 'thumb' | 'slide'\n hammer?: 'spur' | 'ring' | 'big'\n open?: number\n decock?: 'slide' | 'frame'\n tall?: number\n inset?: number\n bushing?: number\n beaver?: number\n slideStop?: number\n flush?: number\n lanyard?: number\n slope?: number\n tri?: number\n}\n\nexport const STYLES: Record<string, PistolStyle> = {\n glock: { rf: 0.07, ga: -0.36, grip: 'finger', guard: 'square', rail: 1, sight: 'u', port: 0.2, slideM: 'metal', frame: 'poly' },\n taurus: { rf: 0.16, ga: -0.3, grip: 'panel', guard: 'square', rail: 1, sight: '3dot', port: 0.18, frontSer: 1, frame: 'poly' },\n g2c: { rf: 0.2, ga: -0.3, grip: 'panel', guard: 'round', rail: 0, sight: '3dot', port: 0.17, frame: 'poly', safety: 'thumb' },\n beretta: { rf: 0.28, ga: -0.27, grip: 'wood', guard: 'round', hammer: 'spur', sight: '3dot', open: 1, decock: 'slide', port: 0, frame: 'metal' },\n pt100: { rf: 0.25, ga: -0.27, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.17, decock: 'frame', frame: 'metal' },\n sig: { rf: 0.14, ga: -0.3, grip: 'rubber', guard: 'hook', hammer: 'spur', sight: '3dot', port: 0.19, decock: 'frame', rail: 1, tall: 1.12, frame: 'metal' },\n cz: { rf: 0.32, ga: -0.3, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.15, inset: 1, safety: 'thumb', frame: 'metal' },\n m1911: { rf: 0.24, ga: -0.2, grip: 'wood', guard: 'round', hammer: 'ring', sight: 'small', port: 0.12, bushing: 1, beaver: 1, safety: 'thumb', slideStop: 1, frame: 'metal' },\n makarov: { rf: 0.48, ga: -0.24, grip: 'star', guard: 'round', hammer: 'ring', sight: 'small', port: 0.14, flush: 1, safety: 'slide', lanyard: 1, frame: 'metal' },\n fiveseven: { rf: 0.2, ga: -0.4, grip: 'chunky', guard: 'square', rail: 1, sight: '3dot', port: 0.18, slope: 1, frame: 'poly' },\n deagle: { rf: 0.08, ga: -0.28, grip: 'rubber', guard: 'round', hammer: 'big', sight: 'small', port: 0.16, tri: 1, safety: 'slide', frame: 'metal' },\n}\n\nexport type Material = THREE.Material\n\nexport interface PistolSize {\n length: number\n height: number\n width: number\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { buildSlide } from './pistol-slide'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport { STYLES } from './pistol-style'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Frame, grip and magazine below the slide. Returns the grip x and the trigger guard line the guard is drawn from. */\nfunction buildFrame(kit: ModelKit, group: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, materials: { frame: Material; grip: Material }): { gx: number; ty: number } {\n const { M, box, cylinderZ, sphere } = kit\n const { length: L, height: h, width: w } = size\n const fm = materials.frame\n if (style.inset) {\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, w * 0.47)\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, -w * 0.47)\n }\n const frameLength = style.tri ? L * 0.66 : L * 0.8\n kit.roundness = style.rf\n box(group, frameLength, 0.016, w * 0.92, fm, frameLength / 2 + L * 0.06, -h / 2 - 0.008, 0)\n kit.roundness = null\n if (style.rail) for (let i = 0; i < (style.slope ? 5 : 3); i++) box(group, 0.004, 0.003, w * 0.96, M.dark, L * 0.62 + i * 0.009, -h / 2 - 0.017, 0)\n const isGlock = options.st === 'glock' || !options.st\n if (isGlock) {\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, -w / 2 - 0.0012)\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, w / 2 + 0.0012)\n }\n if (style.slideStop) {\n box(group, 0.03, 0.006, 0.003, M.dark, L * 0.42, -h / 2 - 0.002, -w / 2 - 0.0014)\n sphere(group, 0.0028, M.dark, L * 0.55, -h / 2 - 0.003, w / 2 + 0.001, 1)\n } else box(group, 0.012, 0.004, 0.003, M.dark, L * 0.45, -h / 2 - 0.003, -w / 2 - 0.0012)\n if (style.decock === 'frame') box(group, 0.01, 0.012, 0.003, M.dark, L * 0.38, -h / 2 - 0.012, -w / 2 - 0.0014, 0.6)\n if (style.safety === 'thumb') parts.safety = box(group, 0.014, 0.006, 0.004, M.dark, 0.02, -h / 2 - 0.002, -w / 2 - 0.0016)\n const gripLength = options.gl ?? 0.105\n const gx = 0.034 + (L - 0.2) * 0.15\n const gy = -h / 2 - gripLength / 2 + 0.006\n const grip = kit.pivot(group, gx, gy, 0)\n grip.rotation.z = style.ga\n parts.grip = grip\n const gripWidth = style.grip === 'chunky' ? w * 1.18 : w * 1.06\n const gripDepth = style.grip === 'chunky' ? 0.036 : 0.032\n kit.roundness = 0.3\n if (style.grip === 'wood' || style.grip === 'star') {\n box(grip, gripDepth * 0.86, gripLength, w * 0.9, fm, 0, 0, 0)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, w * 0.47)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, -w * 0.47)\n if (style.grip === 'wood') {\n for (let i = 0; i < 6; i++) for (let j = 0; j < 2; j++) box(grip, 0.003, 0.003, 0.0012, M.woodL, -0.006 + j * 0.012, -gripLength * 0.3 + i * 0.012, w * 0.495, 0, 0, 0)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, gripLength * 0.25, w * 0.5, 10)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, -gripLength * 0.3, w * 0.5, 10)\n } else cylinderZ(grip, 0.008, 0.0015, M.dark, 0, gripLength * 0.1, w * 0.5, 5)\n } else box(grip, gripDepth, gripLength, gripWidth, materials.grip, 0, 0, 0)\n kit.roundness = null\n if (style.grip === 'finger') {\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, gripWidth * 0.98, materials.grip, gripDepth / 2 + 0.002, gripLength * 0.18 - i * 0.022, 0)\n for (let i = 0; i < 5; i++) for (let j = 0; j < 3; j++) box(grip, 0.003, 0.003, 0.0012, M.dark, -0.008 + j * 0.008, -gripLength * 0.25 + i * 0.012, gripWidth / 2 + 0.0004)\n }\n if (style.grip === 'panel' || style.grip === 'rubber' || style.grip === 'chunky') for (let i = 0; i < 6; i++) box(grip, gripDepth * 0.75, 0.0025, gripWidth + 0.001, M.dark, 0.002, -gripLength / 2 + 0.018 + i * 0.013, 0)\n if (style.grip === 'chunky') box(grip, 0.008, gripLength * 0.8, gripWidth * 0.9, materials.grip, gripDepth / 2 + 0.002, -0.004, 0)\n if (style.beaver) {\n box(group, 0.026, 0.008, w * 0.9, fm, -0.004, -h / 2 - 0.004, 0, 0.25)\n box(grip, 0.006, gripLength * 0.55, w * 0.9, fm, -gripDepth * 0.5 - 0.002, gripLength * 0.18, 0)\n } else box(group, 0.02, 0.009, w * 0.9, fm, 0.004, -h / 2 - 0.006, 0)\n if (style.lanyard) {\n const ring = kit.torus(grip, new kit.THREE.TorusGeometry(0.005, 0.0013, 6, 12), M.dark, -0.012, -gripLength / 2 + 0.004, 0)\n ring.position.set(-0.012, -gripLength / 2 + 0.004, 0)\n }\n const magazine = kit.pivot(grip)\n parts.mag = magazine\n parts.magDrop = gripLength * 1.15\n box(magazine, 0.022, gripLength * 0.94, w * 0.72, M.dark, 0.003, -0.004, 0)\n if (style.grip === 'chunky') box(magazine, 0.04, 0.01, gripWidth * 1.02, M.poly, 0.003, -gripLength / 2 - 0.004, 0)\n else if (style.flush || style.grip === 'wood') box(magazine, 0.028, 0.004, w * 0.9, M.steel, 0.003, -gripLength / 2 - 0.001, 0)\n else box(magazine, 0.031, 0.006, gripWidth * 1.02, M.dark, 0.003, -gripLength / 2 - 0.002, 0)\n return { gx, ty: -h / 2 }\n}\n\n/** Port of the gallery's `pistol` (Galeria 3D do Arsenal): slide, frame, grip, magazine, trigger and hammer, in the order the page adds them. */\nexport function buildPistol(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box } = kit\n const style = { ...STYLES[options.st ?? 'glock'] } as PistolStyle\n const group = kit.group()\n const parts: ModelParts = { family: 'pistol', kick: options.deagle ? 1.8 : 0.6, glow: [] }\n const size: PistolSize = { length: ((options.L ?? 0) / 1000) * 0.97, height: (options.h ?? 0.031) * (style.tall ?? 1), width: options.deagle ? 0.032 : style.flush ? 0.024 : 0.025 }\n const { length: L, height: h, width: w } = size\n const slideMetal = options.steel ? M.steel : options.stain ? M.steelL : M.metal\n const frameMetal = style.frame === 'poly' ? M.poly : slideMetal\n const gripMaterial = style.grip === 'wood' ? M.wood : style.grip === 'star' ? M.bake : style.grip === 'rubber' ? M.rubber : M.poly\n const slide = kit.pivot(group)\n parts.slide = slide\n parts.stroke = L * 0.15\n buildSlide(kit, slide, parts, options, style, size, slideMetal)\n const { gx, ty } = buildFrame(kit, group, parts, options, style, size, { frame: frameMetal, grip: gripMaterial })\n if (style.guard === 'square') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.074, ty - 0.02, 0)\n box(group, 0.006, 0.004, 0.009, frameMetal, gx + 0.075, ty - 0.034, 0)\n } else if (style.guard === 'hook') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.073, ty - 0.02, 0, 0.2)\n box(group, 0.008, 0.006, 0.009, frameMetal, gx + 0.074, ty - 0.037, 0, 0.4)\n } else {\n const guard = kit.torus(group, new kit.THREE.TorusGeometry(0.019, 0.0022, 6, 16, PI), frameMetal, gx + 0.05, ty - 0.014, 0)\n guard.rotation.z = PI\n guard.scale.set(1.2, 1, 1)\n }\n const isGlock = options.st === 'glock' || !options.st\n parts.trigger = box(group, 0.004, 0.014, 0.004, isGlock ? M.dark : M.steel, gx + 0.042, ty - 0.022, 0, 0.2)\n if (isGlock) box(parts.trigger, 0.0015, 0.008, 0.0045, M.metal, 0, -0.001, 0)\n if (style.hammer) {\n const hammer = kit.pivot(group, 0.003, h / 2 - 0.008, 0)\n parts.hammer = hammer\n if (style.hammer === 'ring') {\n box(hammer, 0.006, 0.012, 0.006, M.dark, -0.002, 0.004, 0, 0.3)\n kit.torus(hammer, new kit.THREE.TorusGeometry(0.0045, 0.0016, 6, 12), M.dark, -0.004, 0.012, 0)\n } else if (style.hammer === 'big') box(hammer, 0.014, 0.02, 0.009, M.dark, -0.004, 0.007, 0, 0.35)\n else {\n box(hammer, 0.008, 0.016, 0.007, M.dark, -0.002, 0.006, 0, 0.3)\n box(hammer, 0.008, 0.004, 0.008, M.dark, -0.006, 0.013, 0, 0.3)\n }\n }\n parts.muzzle = kit.mark(group, L + 0.006, style.tri ? h * 0.08 : 0.002, 0)\n parts.eject = kit.mark(group, L * 0.6, h / 2, w * 0.25)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\nconst DEFAULT_CHAMBERS = 6\n\n/** Port of the gallery's `revolver`: frame, swing-out crane with the cylinder (six chambers, or as many as the weapon holds), barrel, hammer, grip and trigger. */\nexport function buildRevolver(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'revolver', kick: options.cal === '.44 Magnum' ? 1.5 : 0.9, glow: [] }\n const barrel = (options.B ?? 0) / 1000\n const chambers = options.chambers ?? DEFAULT_CHAMBERS\n const metal = options.steel ? M.steel : M.metal\n box(group, 0.08, 0.044, 0.024, metal, 0.07, 0, 0)\n box(group, 0.036, 0.012, 0.022, metal, 0.096, 0.022, 0)\n box(group, 0.024, 0.012, 0.004, M.dark, 0.055, 0.006, -0.013)\n const crane = kit.pivot(group, 0.077, -0.024, 0)\n parts.crane = crane\n const cylinder = kit.pivot(crane, 0, 0.022, 0)\n parts.cylinder = cylinder\n cylinderX(cylinder, 0.0215, 0.042, metal, 0, 0, 0, 24)\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers\n box(cylinder, 0.026, 0.005, 0.005, M.dark, 0, Math.cos(angle) * 0.0205, Math.sin(angle) * 0.0205, 0, 0, angle)\n }\n parts.chambers = []\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers + PI / chambers\n parts.chambers.push(kit.mark(cylinder, -0.022, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013))\n cylinderX(cylinder, 0.0046, 0.002, M.brass, -0.0215, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013, 12)\n }\n heatify(parts.glow, cylinderX(group, 0.0088, barrel, metal, 0.112 + barrel / 2, 0.009, 0, 18))\n box(group, barrel * 0.92, 0.015, 0.013, metal, 0.112 + barrel * 0.46, -0.005, 0)\n cylinderX(group, 0.004, 0.005, M.hole, 0.112 + barrel + 0.0015, 0.009, 0, 12)\n box(group, 0.012, 0.009, 0.004, M.dark, 0.112 + barrel - 0.008, 0.021, 0, -0.3)\n box(group, 0.012, 0.006, 0.012, M.dark, 0.105, 0.031, 0)\n const hammer = kit.pivot(group, 0.036, 0.018, 0)\n box(hammer, 0.01, 0.02, 0.008, M.dark, -0.004, 0.008, 0, 0.45)\n parts.hammer = hammer\n const grip = kit.pivot(group, 0.024, -0.062, 0)\n grip.rotation.z = -0.38\n parts.grip = grip\n box(grip, 0.034, 0.1, 0.031, options.wood ? M.wood : M.rubber, 0, 0, 0)\n if (!options.wood) for (let i = 0; i < 4; i++) box(grip, 0.006, 0.07, 0.033, M.dark, -0.012 + i * 0.008, 0, 0)\n box(group, 0.038, 0.004, 0.008, metal, 0.062, -0.036, 0)\n box(group, 0.004, 0.022, 0.008, metal, 0.08, -0.026, 0, 0.2)\n parts.trigger = box(group, 0.004, 0.015, 0.004, M.dark, 0.06, -0.027, 0, 0.2)\n parts.muzzle = kit.mark(group, 0.112 + barrel + 0.006, 0.009, 0)\n parts.eject = kit.mark(group, 0.077, 0, 0)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport { createToolClipPlayer, toolAnimationStep, warnOnce } from '@adatechnology/game-contracts'\nimport { discardObject3D } from '@adatechnology/game-shapes-three'\nimport type { AnimationPose, EffectSink, HandTargets, HostEvent, HostTool, HostToolAttachment, MuzzlePose, ToolAnimationStep, ToolClipPlayer, HandPose } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, CaliberDef, FittedAttachment, MountKind, WeaponDef } from '@adatechnology/game-weapons'\nimport { ease } from '../animation/clip-builder'\nimport { buildToolClips } from '../animation/clip-set'\nimport type { CuePlayed, WeaponAudio } from '../audio'\nimport type { GunshotSpace } from '../audio/gunshot'\nimport { weaponEventOf } from '../audio/host-events'\nimport { soundProfileOf } from '../audio/reload-sounds'\nimport type { SoundProfile } from '../audio/reload-sounds'\nimport { buildWeaponModelById } from '../models'\nimport { fitAttachmentModels } from '../models/attachments/fit'\nimport type { AttachmentModelRegistry, LaserRaycast } from '../models/attachments/types'\nimport { rigUnderbarrel } from '../models/attachments/rig-underbarrel'\nimport { rigStock } from '../models/rig-stock'\nimport { attachmentsKey } from '../attachments-key'\nimport { VIEWMODEL_NODE_NAME } from '../laser-raycast'\nimport { applyCondition } from '../models/condition'\nimport { cartridgeShape } from '../models/cartridge'\nimport { modelKit } from '../models/kit'\nimport { createVfxRenderer } from '@adatechnology/game-vfx-three'\nimport type { VfxRenderer } from '@adatechnology/game-vfx-three'\nimport { createEffects } from './effects'\nimport { createLayers } from './layers'\nimport { createEyeFrame, limitSupportSpan, placeOnBody } from './body-hold'\nimport { placeInView } from './view-hold'\nimport type { FxLayers } from './layers'\nimport type { LightBudget, RenderPools } from '@adatechnology/game-render-three'\nimport { createRocketLight, flameJet, launchRocket, type HeavyContext } from './heavy'\nimport { createParticles } from './particles'\nimport { createModelRig } from './rig'\nimport type { FxWorld, Session } from './session'\nimport { toWorld, worldPositionOf } from './session'\nimport { createClipEventHandler } from './viewmodel-events'\nimport { handWorkOf, workWeights } from './hand-work'\nimport { HAND_HOLD, holdOfModel, targetsOf } from './hand-hold'\nimport type { Hold } from './hand-hold'\n\nconst PI = Math.PI\nconst HEAT_DISPLAY_MAX_FALLBACK = 120\n/** The weapon against a wall: it comes back as far as it needs to stay `margin` in front of it, up to `max` metres or its own length when longer, at `rate` per second; the world is probed `probe` metres ahead. */\nexport const WALL_PULL = { margin: 0.03, max: 1.2, rate: 14, probe: 3 }\n/** The grips of the hands stay above this height of the view (-1 is the bottom edge, 0 the middle): a weapon held low (a pistol grip on a short body, a heavy gun) is raised, up to `max` metres, at `rate` per second. */\nexport const HAND_IN_VIEW = { floor: -0.88, max: 0.3, rate: 10 }\n// the launcher has no calibre: its shot is the game's `explosao` class, at the volume of a mid-sized blast\nconst LAUNCH_VOLUME = 0.6\n\nexport interface ViewmodelOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n groundAt: (x: number, z: number) => number\n audio: WeaponAudio | null\n /** Seed of the scatter of casings, smoke and sparks. */\n seed?: number\n /** The tool as it is now, for what no event announces: the barrel heat and the fuel burning. */\n tool?: () => HostTool\n /** Wear of the weapon (`new`, `used`, `worn`, `rusty`). */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n /** Whether the shot is in a room or in the open (the tail and echoes of the gunshot). Default outdoor. */\n soundSpace?: () => GunshotSpace\n /** The floor material under a point (`concrete`, `wood_hard`, `soil`...), for the sound of a case landing there. Default concrete. */\n surfaceAt?: (x: number, z: number) => string | undefined\n /** Where the world is: the distance from a point along a direction to the first surface (not the weapon in the hands), or null. The weapon in the hands comes back from a wall it would go through. */\n contact?: LaserRaycast\n /** Where the body holds the tool now (`ModuleHost.holdFrame`): the tool is drawn there at its real size in every view; null or absent (no body), the frame of a body's right shoulder under the camera's eye. */\n bodyHold?: () => HandPose | null\n /** Whether the view is the player's own eye (first person): the gun is then held at the hip in the view at its real size (`VIEW_HOLD`: the barrel parallel to the aim, the grip low and right, where the hand reaches) instead of on the body. */\n firstPerson?: () => boolean\n /** Told at every sound cue of a reload clip, at the moment the clip says it (also with no audio). */\n onSound?: (cue: { weapon: string; cue: string; profile: SoundProfile; played?: CuePlayed }) => void\n /** Builders of accessory models that replace or add to the ones the kit ships. */\n attachmentModels?: AttachmentModelRegistry\n /** How far a laser beam goes (metres) from a point along a direction, or null when it hits nothing. */\n raycast?: LaserRaycast\n /** The most casings and magazines alive at once, read at each spawn (the host's one budget); without it the viewmodel keeps a cap of its own. */\n particleLimit?: () => number | undefined\n /** The host's effects (`host.effects`): the muzzle flash, the smoke, the backblast and the flame jet are recipes it plays. Without it the viewmodel makes a world of its own for them. */\n effects?: EffectSink\n /** The rocket of a launcher flies out along the barrel (default true); false leaves the round to the host. */\n flyRocket?: boolean\n /** The host's light budget (`host.lights`): the rocket in flight and the weapon light ask it for a light. Without it they create lights of their own (deprecated, removed in the next major). */\n lights?: LightBudget\n /** The host's pools (`host.pools`): the burning droplets and the ground flames of a flamethrower take their geometry and material from them. Without them each makes its own (deprecated, removed in the next major). */\n pools?: RenderPools\n}\n\n/** The weapon in the hands for the models the gallery drew: it follows the camera, plays the clips of the rule's events, and throws casings, magazines and smoke. */\nexport interface Viewmodel {\n /** Puts the weapon in the hands; false (and the hands stay as they were) when the gallery has no model for it. */\n equip(weapon: string): boolean\n /** Takes the weapon out of the hands. */\n unequip(): void\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n setCondition(condition: string): void\n /** Where the hands take the weapon now (world space), or null with nothing in the hands. The right hand sits on the grip, the left on the forend, and goes to the magazine while it is changed. */\n handTargets(): HandTargets | null\n /** The muzzle of the model in the hands now (the gallery's `muzzle` mark, world space) and the way the barrel points; null with nothing in the hands or a model with no muzzle. */\n muzzle(): MuzzlePose | null\n readonly inHand: string | null\n /** The clips playing now, with the seconds each lasts. */\n readonly clips: ReadonlyArray<{ name: string; seconds: number }>\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\ninterface Task {\n delay: number\n seconds: number\n elapsed: number\n step: (progress: number, dt: number) => void\n done: (() => void) | undefined\n}\n\nconst fittedOf = (parts: readonly HostToolAttachment[]): FittedAttachment[] =>\n parts.map((part) => ({ id: part.id, mount: part.mount as MountKind, ...(part.integral ? { integral: true } : {}), ...(part.on === undefined ? {} : { on: part.on }) }))\n\n/** The pose the stock pivot holds when the stock is collapsed: a half turn about its axis, or the slide along the weapon. */\nconst collapsedStockPose = (move: NonNullable<Session['model']['parts']['stockMove']>): AnimationPose => {\n if (move.kind === 'retract') return { position: [move.travel, 0, 0] }\n return { rotation: [move.axis === 'x' ? PI : 0, move.axis === 'y' ? PI : 0, move.axis === 'z' ? PI : 0] }\n}\n\n// the shot of the launcher under the barrel and its reload have clips of their own; the rest of the weapon's clips play as they are\nconst underbarrelStep = (step: ToolAnimationStep, tool: HostTool): ToolAnimationStep => (tool.underbarrelActive && step.type === 'play' && (step.clip === 'shot' || step.clip === 'reload') ? { ...step, variant: 'ugl' } : step)\n\nconst caliberOf = (arsenal: Arsenal, def: WeaponDef): CaliberDef | undefined => (def.action.kind === 'firearm' ? arsenal.calibers.get(def.action.caliber) : undefined)\n\n/**\n * The curl of the trigger finger: along the frame (`TRIGGER_FINGER.safe`) until the weapon fires, on the trigger (`ready`) for `readySeconds` after a shot, and pulled in by the turn of the\n * trigger part (the clip's pull, `TRIGGER_TURN` radians), so each shot of a burst or of full auto pulls and releases it; a burst keeps it nearly pulled, with a small tremor per shot.\n */\nexport const TRIGGER_FINGER = { safe: 0, ready: 0.5, pulled: 1, readySeconds: 1.5, burstSeconds: 0.14, tremor: 0.03 } as const\nconst TRIGGER_TURN = 0.35\nconst indexCurl = (turn: number, sinceShot: number): number => {\n const ready = sinceShot < TRIGGER_FINGER.readySeconds ? TRIGGER_FINGER.ready : TRIGGER_FINGER.safe\n const pull = Math.min(1, Math.max(0, turn / TRIGGER_TURN))\n const held = sinceShot < TRIGGER_FINGER.burstSeconds ? TRIGGER_FINGER.pulled - TRIGGER_FINGER.tremor * (0.5 + 0.5 * Math.sin(sinceShot * 220)) : 0\n return Math.max(ready + (TRIGGER_FINGER.pulled - ready) * pull, held)\n}\n\nexport function createViewmodel(options: ViewmodelOptions): Viewmodel {\n const { THREE, scene, camera, arsenal, groundAt, audio } = options\n const kit = modelKit(THREE)\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const distance = (): number => options.soundDistance?.() ?? 0\n const particles = createParticles(THREE, scene, groundAt, options.particleLimit)\n particles.onBounce = (kind, hit) => {\n if (kind === 'magazine') audio?.thud()\n if (kind !== 'casing' || !audio) return\n const caseType = hit?.object.userData['caseType'] as string | undefined\n const surface = hit ? options.surfaceAt?.(hit.object.position.x, hit.object.position.z) : undefined\n audio.casing({ ...(caseType ? { caseType } : {}), ...(surface ? { surface } : {}), ...(hit ? { speed: hit.speed, bounce: hit.bounce } : {}) })\n }\n // a host that lends no effect sink gets a world of its own for the flash and the smoke, stepped and drawn here (as `destruction-three` does)\n if (!options.effects) warnOnce('game-weapons-three.own-effects-world', 'game-weapons-three made an effects world of its own because the host lent none (options.effects); pass the host effects so the effects share one budget')\n const ownVfx: VfxRenderer | undefined = options.effects ? undefined : createVfxRenderer(THREE, { scene, camera, vfx: { profile: 'medium' }, ...(options.lights ? { lights: options.lights } : {}) })\n const effects = createEffects(THREE, options.effects ?? ownVfx, random)\n const hand = new THREE.Group()\n hand.name = VIEWMODEL_NODE_NAME\n scene.add(hand)\n const rocketLight = options.lights ? undefined : createRocketLight(THREE)\n if (rocketLight) scene.add(rocketLight)\n const holder = new THREE.Group()\n holder.quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), PI / 2)\n hand.add(holder)\n let tasks: Task[] = []\n let session: Session | null = null\n let player: ToolClipPlayer | null = null\n let condition = options.condition ?? 'new'\n let lastAmmo = 0\n let smokeDebt = 0\n let secondsSinceShot = Number.POSITIVE_INFINITY\n let hold: Hold | null = null\n let reloading = false\n let magazineHand = 0\n // the trigger finger: the seconds since the last shot and the turn of the trigger part at rest\n let clock = 0\n let lastShot = -Infinity\n let triggerRest = 0\n // whether the feed clip of the weapon in the hands carries its own sound\n let feedCued = false\n const rootQuaternion = new THREE.Quaternion()\n const muzzleAt = new THREE.Vector3()\n const muzzleAlong = new THREE.Vector3()\n\n const world: FxWorld = {\n kit,\n scene,\n particles,\n effects,\n random,\n audio,\n layers,\n groundAt,\n sound: (weapon, cue, profile, lead) => {\n const played = audio?.cue(cue, profile, lead)\n options.onSound?.({ weapon, cue, profile, ...(played ? { played } : {}) })\n },\n schedule: (delay, seconds, step, done) => void tasks.push({ delay, seconds, elapsed: 0, step: (progress) => step(ease(progress)), done }),\n }\n\n const heatMax = arsenal.rules.heat.displayMax || HEAT_DISPLAY_MAX_FALLBACK\n const visual = arsenal.rules.heat.visual\n const hasSuppressor = (parts: readonly FittedAttachment[]): boolean => parts.some((part) => arsenal.attachments.get(part.id)?.kind === 'suppressor')\n\n const release = (): void => {\n if (!session) return\n session.attachments?.dispose()\n // the model is built for this equip (buildWeaponModelById): put away, it frees its own geometry and materials\n discardObject3D(session.model.root)\n player = null\n session = null\n tasks = []\n hold = null\n }\n\n const heavy = (current: Session): HeavyContext => ({\n kit,\n scene,\n particles,\n effects,\n random,\n parts: current.model.parts,\n forward: () => toWorld(current, new THREE.Vector3(1, 0, 0)).normalize(),\n positionOf: (part) => worldPositionOf(current, part, new THREE.Vector3()),\n orientation: () => current.model.root.getWorldQuaternion(new THREE.Quaternion()),\n every: (seconds, step, done) => void tasks.push({ delay: 0, seconds, elapsed: 0, step, done }),\n groundAt,\n ...(options.lights ? { lights: options.lights } : {}),\n ...(options.pools ? { pools: options.pools } : {}),\n ...(rocketLight ? { rocketLight } : {}),\n })\n\n const equip = (weapon: string): boolean => {\n const def = arsenal.weapons.get(weapon)\n const model = def ? buildWeaponModelById(THREE, weapon) : undefined\n if (!def || !model) return false\n release()\n hold = null\n reloading = false\n magazineHand = 0\n reach = 0\n pull = 0\n lift = 0\n rigStock(THREE, model, def)\n rigUnderbarrel(THREE, model, def)\n const modelBox = new THREE.Box3().setFromObject(model.root)\n const length = modelBox.getSize(new THREE.Vector3()).x\n modelRear = modelBox.min.x\n holder.add(model.root)\n const caliber = caliberOf(arsenal, def)\n const dims = caliber?.cartridge\n const hostTool = options.tool?.()\n const onTool = hostTool?.weapon === weapon ? hostTool : undefined\n const fitted = onTool?.attachments ? fittedOf(onTool.attachments) : [...(def.fitted ?? [])]\n session = {\n id: weapon,\n def,\n caliber,\n model,\n holderScale: 1,\n lengthMetres: length,\n caseType: caliber?.caseType ?? 'rifle',\n soundProfile: soundProfileOf(weapon, model.parts.family),\n kit,\n cartridge: caliber && dims ? { dims, shape: cartridgeShape(caliber, dims), ...(caliber.caseType ? { caseType: caliber.caseType } : {}) } : null,\n stuckCase: null,\n nextChamber: 0,\n attachments: null,\n attachmentsSignature: '',\n suppressed: onTool?.suppressed ?? hasSuppressor(fitted),\n }\n session.attachments = fitAttachmentModels(model, fitted, kit, { catalogue: arsenal.attachments, isDrawn: () => layers.attachments, areBeamsOn: () => layers.beams, ...(options.attachmentModels ? { overrides: options.attachmentModels } : {}), ...(options.raycast ? { raycast: options.raycast } : {}), ...(options.lights ? { lights: options.lights } : {}) })\n session.attachmentsSignature = attachmentsKey(onTool?.attachments)\n const action = def.action\n const reloadFamily = action.kind === 'firearm' || action.kind === 'flame' || action.kind === 'launcher' ? action.family : undefined\n const rpm = action.kind === 'firearm' ? action.rpm : 0\n const rig = createModelRig(model)\n const clips = buildToolClips({ parts: model.parts, family: model.parts.family, caseType: session.caseType, reloadFamily })\n feedCued = clips.feed?.events?.some((entry) => entry.type === 'sound') ?? false\n player = createToolClipPlayer({\n clips,\n rig,\n onEvent: createClipEventHandler(world, session),\n repeatInterval: () => (rpm > 0 ? 60 / rpm : 0.1),\n })\n if (model.parts.stockMove && onTool?.stock === 'collapsed') rig.setPartPose('stock', collapsedStockPose(model.parts.stockMove))\n applyCondition(kit, model, condition)\n lastAmmo = options.tool?.().ammo ?? 0\n // the recorded shots and reload steps load as the weapon comes to the hands, so the first shot already plays its recording\n void audio?.loadSamples()\n hand.updateMatrixWorld(true)\n hold = holdOfModel(THREE, model, 1)\n hold = { ...hold, works: handWorkOf(THREE, model, weapon, hold.right) }\n triggerRest = model.parts.trigger?.rotation.z ?? 0\n lastShot = -Infinity\n return true\n }\n\n const syncAttachments = (current: Session, tool: HostTool | undefined): void => {\n if (!current.attachments || tool?.weapon !== current.id) return\n if (tool.suppressed !== undefined) current.suppressed = tool.suppressed\n if (!tool.attachments) return\n const signature = attachmentsKey(tool.attachments)\n if (signature === current.attachmentsSignature) return\n current.attachmentsSignature = signature\n const fitted = fittedOf(tool.attachments)\n if (tool.suppressed === undefined) current.suppressed = hasSuppressor(fitted)\n current.attachments.sync(fitted)\n }\n\n // the weapon against a wall: how far it reaches in front of the eye (measured once, with no pull) and how far it is pulled back now\n let reach = 0\n let pull = 0\n // how far the weapon is raised to keep the hands on it in view\n let lift = 0\n const ahead = new THREE.Vector3()\n const up = new THREE.Vector3()\n const seen = new THREE.Vector3()\n const eyeTurn = new THREE.Quaternion()\n const corner = new THREE.Vector3()\n const bounds = new THREE.Box3()\n const measureReach = (current: Session): number => {\n bounds.setFromObject(current.model.root)\n let farthest = 0\n for (const x of [bounds.min.x, bounds.max.x]) for (const y of [bounds.min.y, bounds.max.y]) for (const z of [bounds.min.z, bounds.max.z]) farthest = Math.max(farthest, corner.set(x, y, z).sub(camera.position).dot(ahead))\n return farthest\n }\n\n // the tool is the body's own, at its real size, in every view\n let modelRear = 0\n const eyeFrame = createEyeFrame(THREE, camera)\n /** How far the weapon, as placed, has to rise for the grips of both hands to stay above `HAND_IN_VIEW.floor` of the view (the grips fixed on the model, not the hands, which move to the port and the magazine, nor a hand on a part that slides). */\n const liftToKeepInView = (): number => {\n if (!hold || !session || !('fov' in camera)) return 0\n const tanHalf = Math.tan((((camera as THREE_NS.PerspectiveCamera).fov ?? 70) * PI) / 360)\n eyeTurn.copy(camera.quaternion).invert()\n const rest = targetsOf(THREE, hold, session.model.root.getWorldQuaternion(rootQuaternion), 0)\n let needed = 0\n for (const [anchor, pose] of [[hold.right, rest.R], [hold.left, rest.L]] as const) {\n if (!anchor || !pose || anchor.part !== session.model.root) continue\n seen.set(...pose.position).sub(camera.position).applyQuaternion(eyeTurn)\n if (-seen.z > 0.05) needed = Math.max(needed, HAND_IN_VIEW.floor * -seen.z * tanHalf - seen.y)\n }\n return Math.max(0, Math.min(HAND_IN_VIEW.max, needed))\n }\n const place = (dt = 0): void => {\n if (!session) return\n const family = session.model.parts.family\n session.holderScale = 1\n if (options.firstPerson?.()) {\n placeInView({ THREE, hand, holder, camera, right: hold?.right ?? null, rear: modelRear, kind: family === 'pistol' || family === 'revolver' ? 'handgun' : family === 'rocket' ? 'launcher' : 'long' })\n lift = 0\n pullFromWall(dt)\n return\n }\n hand.scale.set(1, 1, 1)\n placeOnBody({ THREE, hand, holder, frame: options.bodyHold?.() ?? eyeFrame(), rear: modelRear, lengthMetres: session.lengthMetres, handgun: family === 'pistol' || family === 'revolver', right: hold?.right ?? null, left: hold?.left ?? null })\n hand.updateMatrixWorld(true)\n lift += (liftToKeepInView() - lift) * Math.min(1, dt * HAND_IN_VIEW.rate)\n if (lift > 1e-4) hand.position.addScaledVector(up.set(0, 1, 0).applyQuaternion(camera.quaternion), lift)\n hand.updateMatrixWorld(true)\n pullFromWall(dt)\n }\n const pullFromWall = (dt: number): void => {\n if (!options.contact || !session) return\n ahead.set(0, 0, -1).applyQuaternion(camera.quaternion)\n if (reach === 0) reach = Math.max(0.01, measureReach(session))\n const free = options.contact(camera.position, ahead, WALL_PULL.probe)\n const want = free === null ? 0 : Math.max(0, Math.min(Math.max(WALL_PULL.max, session.lengthMetres * session.holderScale), reach + WALL_PULL.margin - free))\n pull += (want - pull) * Math.min(1, dt * WALL_PULL.rate)\n if (pull < 1e-4) return\n hand.position.addScaledVector(ahead, -pull)\n hand.updateMatrixWorld(true)\n }\n\n const glow = (tool: HostTool | undefined): void => {\n if (!session) return\n const heat = (tool?.heat ?? 0) * heatMax\n const level = Math.max(0, Math.min(1, (heat - visual.glowFrom) / visual.glowSpan))\n for (const mesh of session.model.parts.glow) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n material.emissive.setRGB(level, 0.2 * level * level, 0.02 * level * level)\n material.emissiveIntensity = 2.2 * level\n }\n }\n\n const handleShot = (current: Session, event: Extract<HostEvent, { type: 'shot' }>, tool: HostTool): void => {\n secondsSinceShot = 0\n if (event.suppressed !== undefined) current.suppressed = event.suppressed\n else if (tool.suppressed !== undefined) current.suppressed = tool.suppressed\n else current.suppressed = hasSuppressor(tool.attachments ? fittedOf(tool.attachments) : (current.def.fitted ?? []))\n if (tool.underbarrelActive && current.model.parts.uglMuzzle) {\n audio?.play('explosion', LAUNCH_VOLUME, distance())\n return\n }\n const action = current.def.action\n if (action.kind === 'launcher') {\n // a grenade launcher (the M79) fires no rocket and has no backblast: its grenade is the host's projectile\n if (current.model.parts.family === 'rocket') launchRocket(heavy(current), options.flyRocket !== false)\n audio?.play('explosion', LAUNCH_VOLUME, distance())\n }\n if (action.kind !== 'firearm') return\n const caliber = caliberOf(arsenal, current.def)\n if (!caliber) return\n audio?.shot(muzzleEnergy(caliber) * (caliber.pellets ?? 1), current.def.category, { caliber, distance: distance(), space: options.soundSpace?.() ?? 'outdoor', ...(current.suppressed ? { suppressed: true } : {}) })\n }\n\n return {\n equip,\n unequip: release,\n handle(event, tool) {\n if (event.type === 'explosion' || event.type === 'player' || event.type === 'footfall') return\n if (event.type === 'tool') equip(event.weapon)\n if (!session || !player || event.weapon !== session.id) return\n const current = session\n if (event.type === 'shot') {\n lastShot = clock\n handleShot(current, event, tool)\n }\n else if (event.type === 'reload' && event.phase === 'start') {\n current.nextChamber = 0\n reloading = true\n } else if (event.type === 'reload' && event.phase === 'end') reloading = false\n else if (event.type === 'clear' && event.phase === 'end') current.stuckCase = null\n const mechanical = weaponEventOf(event)\n // the clips of the model say when each step of a reload makes its noise (`sound` cues): the rule's stage and feed events would sound it twice\n const cued = mechanical?.type === 'feed' ? feedCued : mechanical?.type === 'reload_stage' && (player.running.some(({ clip }) => clip.events?.some((entry) => entry.type === 'sound')) ?? false)\n if (mechanical && !cued) audio?.event(mechanical)\n const step = toolAnimationStep(event)\n if (!step) return\n const last = step.type === 'play' && step.clip === 'shot' && current.model.parts.family === 'pistol' && tool.ammo === 0\n player.apply(last ? { ...step, variant: 'last' } : underbarrelStep(step, tool))\n },\n update(dt) {\n clock += dt\n if (session) {\n place(dt)\n player?.update(dt)\n const wantsMagazine = reloading || options.tool?.().reloading === true\n magazineHand += ((wantsMagazine ? 1 : 0) - magazineHand) * Math.min(1, dt * HAND_HOLD.magRate)\n const tool = options.tool?.()\n syncAttachments(session, tool)\n session.attachments?.update()\n glow(tool)\n if (tool && session.def.action.kind === 'flame') {\n if (tool.ammo < lastAmmo) {\n flameJet(heavy(session), dt, session.model.parts.launcherType === 'flame' ? 1 : 0.6)\n // a flamethrower has no shot event: the trigger is down while the fuel burns\n lastShot = clock\n }\n lastAmmo = tool.ammo\n }\n secondsSinceShot += dt\n if (tool && tool.heat !== undefined && tool.heat * heatMax > visual.smokeFrom && secondsSinceShot < visual.smokeSeconds && session.model.parts.muzzle) {\n smokeDebt += dt * (tool.heat * heatMax - visual.smokeFrom) * 0.1\n while (smokeDebt > 1) {\n smokeDebt -= 1\n const k = 0.5 + (tool.heat * heatMax - visual.smokeFrom) / 60\n effects.smoke(worldPositionOf(session, session.model.parts.muzzle, new THREE.Vector3()), new THREE.Vector3((random() - 0.5) * 0.015, 0.07 + random() * 0.08, (random() - 0.5) * 0.015), 0.004 * k, 1.2 + random() * 0.6, Math.min(0.18, 0.06 + k * 0.04))\n }\n }\n }\n for (const task of [...tasks]) {\n task.elapsed += dt\n if (task.elapsed < task.delay) continue\n const progress = task.seconds > 0 ? Math.min(1, (task.elapsed - task.delay) / task.seconds) : 1\n task.step(progress, dt)\n if (progress >= 1) {\n task.done?.()\n tasks = tasks.filter((other) => other !== task)\n }\n }\n particles.update(dt)\n ownVfx?.update(dt)\n },\n setCondition(next) {\n condition = next\n if (session) applyCondition(kit, session.model, condition)\n },\n muzzle() {\n const mark = session?.model.parts.muzzle\n if (!session || !mark) return null\n hand.updateMatrixWorld(true)\n const at = worldPositionOf(session, mark, muzzleAt)\n const along = muzzleAlong.set(1, 0, 0).applyQuaternion(session.model.root.getWorldQuaternion(rootQuaternion)).normalize()\n const kind = session.def.action.kind\n return { position: [at.x, at.y, at.z], direction: [along.x, along.y, along.z], drawsFlash: kind === 'firearm' || kind === 'launcher' }\n },\n handTargets() {\n if (!session || !hold) return null\n hand.updateMatrixWorld(true)\n const targets = targetsOf(THREE, hold, session.model.root.getWorldQuaternion(rootQuaternion), magazineHand, hold.works ? workWeights(hold.works, player?.running ?? []) : undefined)\n const trigger = session.model.parts.trigger\n if (trigger) targets.fingers = { index: indexCurl(trigger.rotation.z - triggerRest, clock - lastShot) }\n return limitSupportSpan(targets)\n },\n get inHand() {\n return session?.id ?? null\n },\n get clips() {\n return (player?.running ?? []).map(({ name, clip }) => ({ name, seconds: clip.duration }))\n },\n get casings() {\n return particles.count('casing')\n },\n get magazines() {\n return particles.count('magazine')\n },\n dispose() {\n release()\n particles.dispose()\n ownVfx?.dispose()\n hand.removeFromParent()\n rocketLight?.removeFromParent()\n rocketLight?.dispose()\n },\n }\n}\n","import { STAGE_EVENT } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from '@adatechnology/game-contracts'\n\nimport hitData from '../data/reload-sample-hits.json'\n\nconst RELOAD_SAMPLE_HITS: Readonly<Record<string, number>> = hitData.hits\n\nexport type Axis = 'x' | 'y' | 'z'\ntype Channel = 'position' | 'rotation'\n\n/** The gallery's `tw(delay, duration, e => part.property = from + (to - from) * e)`: one axis of one part, eased, then held at `to`. */\nexport interface Tween {\n readonly part: string\n readonly channel: Channel\n readonly axis: Axis\n readonly start: number\n readonly duration: number\n readonly from: number\n readonly to: number\n}\n\n/** The part id of the whole weapon in a clip's tweens. */\nexport const ROOT = 'root'\n\nconst AXIS_INDEX: Record<Axis, number> = { x: 0, y: 1, z: 2 }\n// the gallery eases with this curve; keys are linear, so each tween is sampled at this many steps (largest error 0.4% of the move)\nconst EASE_STEPS = 10\n\nexport const ease = (progress: number): number => (progress < 0.5 ? 2 * progress * progress : 1 - (-2 * progress + 2) ** 2 / 2)\n\nexport const move = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'position', axis, start, duration, from, to })\nexport const turn = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'rotation', axis, start, duration, from, to })\n\n/** A step of the clip at `t` the host maps (`muzzle_flash`, `eject_casing`, `drop_magazine`...). */\nexport const cue = (t: number, type: string, data?: Record<string, unknown>): AnimationEventSpec => ({ t, type, ...(data ? { data } : {}) })\n\n/** A sound the host plays at `t` (`id` is a key of `data/reload-sounds.json`): the animation says when each part makes its noise. */\n/**\n * A sound cue of the clip at the instant the part reaches its stop. A cue with a recording leads by the seconds its takes take to reach their hit\n * (`data/reload-sample-hits.json`), so the player starts it that early and the click lands on `t`.\n */\nexport const sound = (t: number, id: string): AnimationEventSpec => {\n const lead = RELOAD_SAMPLE_HITS[id]\n return lead ? { t, type: 'sound', data: { id }, lead } : { t, type: 'sound', data: { id } }\n}\n\nexport const stage = (id: string, t: number): AnimationEventSpec => ({ t, type: STAGE_EVENT, data: { stage: id } })\n\nconst valueAt = (tweens: readonly Tween[], t: number, includeInstants: boolean): number => {\n let value = 0\n for (const tween of tweens) {\n if (tween.start > t || (tween.duration === 0 && (tween.start === t ? !includeInstants : false))) continue\n if (tween.duration === 0 || t >= tween.start + tween.duration) value = tween.to\n else value = tween.from + (tween.to - tween.from) * ease((t - tween.start) / tween.duration)\n }\n return value\n}\n\nconst round = (value: number): number => Math.round(value * 1e6) / 1e6\n\n/** Builds a clip from tweens and cue events: one key at every start, end and sample of a tween, and a step (two keys at one time) for an instant set. */\nexport function composeClip(id: string, tweens: readonly Tween[], events: readonly AnimationEventSpec[] = [], minDuration = 0): AnimationClipSpec {\n const ordered = [...tweens].sort((a, b) => a.start - b.start)\n const duration = Math.max(minDuration, 0.001, ...ordered.map((tween) => tween.start + tween.duration), ...events.map((event) => event.t))\n const times = new Set<number>([0, duration])\n for (const tween of ordered) {\n times.add(round(tween.start))\n if (tween.duration > 0) for (let step = 1; step <= EASE_STEPS; step++) times.add(round(tween.start + (tween.duration * step) / EASE_STEPS))\n }\n const instants = new Set(ordered.filter((tween) => tween.duration === 0).map((tween) => round(tween.start)))\n const channels = new Map<string, Tween[]>()\n for (const tween of ordered) {\n const key = `${tween.part}|${tween.channel}|${tween.axis}`\n channels.set(key, [...(channels.get(key) ?? []), tween])\n }\n const sampleKey = (t: number, includeInstants: boolean): AnimationClipSpec['keys'][number] => {\n const poses = new Map<string, { position: [number, number, number]; rotation: [number, number, number] }>()\n for (const [key, list] of channels) {\n const [part, channel, axis] = key.split('|') as [string, Channel, Axis]\n const pose = poses.get(part) ?? { position: [0, 0, 0], rotation: [0, 0, 0] }\n pose[channel][AXIS_INDEX[axis]] = round(valueAt(list, t, includeInstants))\n poses.set(part, pose)\n }\n const root = poses.get(ROOT)\n poses.delete(ROOT)\n const parts: Record<string, AnimationPose> = {}\n for (const [part, pose] of poses) parts[part] = pose\n return { t, ...(root ? { position: root.position, rotation: root.rotation } : {}), ...(poses.size ? { parts } : {}) }\n }\n const keys: AnimationClipSpec['keys'] = []\n for (const t of [...times].sort((a, b) => a - b)) {\n if (instants.has(t)) keys.push(sampleKey(t, false))\n keys.push(sampleKey(t, true))\n }\n const sorted = [...events].sort((a, b) => a.t - b.t)\n return { id, duration, keys, ...(sorted.length ? { events: sorted } : {}) }\n}\n\n/** The same clip under another id (the clip set keys are the ids). */\nexport const renamed = (clip: AnimationClipSpec, id: string): AnimationClipSpec => ({ ...clip, id })\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { ROOT, composeClip, cue, move, stage, turn } from './clip-builder'\nimport type { ClipContext } from './context'\n\nconst PI = Math.PI\n// the SDK's own motions (the gallery has none for accessories): seconds when the rule does not give the duration, and the sizes of the moves\nconst STOCK_SECONDS = 0.6\nconst TOGGLE_SECONDS = 0.14\nconst TOGGLE_TILT = 0.02\nconst LAUNCHER_SLIDE = 0.05\nconst LAUNCHER_RELOAD = { open: 0, loaded: 0.4, close: 0.8, end: 1.05, slide: 0.3, back: 0.25 }\nconst LAUNCHER_KICK = 0.03\n\n/** The stock folds a half turn about the side of the rule, or slides in along the weapon; the pose is held at the end, so the stock stays where the rule put it. */\nexport function stockClips(context: ClipContext): AnimationClipSpec[] {\n const { stock, stockMove } = context.parts\n if (!stock || !stockMove) return []\n if (stockMove.kind === 'fold') {\n return [\n composeClip('stock_fold', [turn('stock', stockMove.axis, 0, STOCK_SECONDS, 0, PI)]),\n composeClip('stock_unfold', [turn('stock', stockMove.axis, 0, STOCK_SECONDS, PI, 0)]),\n ]\n }\n return [\n composeClip('stock_collapse', [move('stock', 'x', 0, STOCK_SECONDS, 0, stockMove.travel)]),\n composeClip('stock_extend', [move('stock', 'x', 0, STOCK_SECONDS, stockMove.travel, 0)]),\n ]\n}\n\n/** A light or a laser is switched: the weapon tilts a hair and comes back. */\nexport const toggleClip = (): AnimationClipSpec => composeClip('toggle', [turn(ROOT, 'z', 0, TOGGLE_SECONDS / 2, 0, TOGGLE_TILT), turn(ROOT, 'z', TOGGLE_SECONDS / 2, TOGGLE_SECONDS / 2, TOGGLE_TILT, 0)])\n\n/**\n * The launcher under the barrel: its shot flashes at its own muzzle and kicks the weapon, and its reload goes through the stages of the rule (`breech_open`, `round_in`, `breech_close`):\n * the tube slides forward, takes the round and slides back. Only on a weapon with a place for one.\n */\nexport function launcherClips(context: ClipContext): AnimationClipSpec[] {\n if (!context.parts.ugl) return []\n const { open, loaded, close, end, slide, back } = LAUNCHER_RELOAD\n const reload = composeClip(\n 'reload_ugl',\n [move('ugl', 'x', open, slide, 0, LAUNCHER_SLIDE), move('ugl', 'x', close, back, LAUNCHER_SLIDE, 0)],\n [stage('breech_open', open), stage('round_in', loaded), stage('breech_close', close)],\n end,\n )\n const shot = composeClip('shot_ugl', [move(ROOT, 'x', 0, 0.04, 0, -LAUNCHER_KICK), move(ROOT, 'x', 0.04, 0.2, -LAUNCHER_KICK, 0)], [cue(0, 'muzzle_flash', { at: 'ugl' })])\n return [reload, shot]\n}\n","import type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport type { ModelParts } from '../models/types'\nimport { cue, move, sound } from './clip-builder'\nimport type { Tween } from './clip-builder'\n\n/** The magazine goes out, drops away, and a new one rises into the well: the page's `magSwap`, which takes 0.82 s. */\nexport const MAGAZINE_SWAP_SECONDS = 0.82\n/** The new magazine starts to rise here (the `magazine_in` stage). */\nexport const MAGAZINE_IN_AT = 0.45\n\nexport function magazineSwap(parts: ModelParts, start: number): { tweens: Tween[]; events: AnimationEventSpec[]; end: number } {\n const direction = parts.magDir || -1\n const drop = parts.magDrop || 0.15\n return {\n tweens: [\n move('mag', 'y', start, 0.16, 0, direction * drop * 0.6),\n move('mag', 'y', start + 0.16, 0, 0, direction * drop * 2.2),\n move('mag', 'y', start + MAGAZINE_IN_AT, 0.3, direction * drop * 2.2, 0),\n ],\n events: [sound(start, 'mag_release'), cue(start + 0.16, 'drop_magazine', { up: direction > 0 }), sound(start + 0.16, 'mag_out'), sound(start + MAGAZINE_IN_AT, 'mag_insert'), sound(start + MAGAZINE_IN_AT + 0.3, 'mag_seat')],\n end: start + MAGAZINE_SWAP_SECONDS,\n }\n}\n","import type { CaseType, ReloadFamily } from '@adatechnology/game-weapons'\nimport type { ModelFamily, ModelParts } from '../models/types'\n\n/** What the clips of a weapon are written from: its model (parts and mechanism), its calibre's case and how its rule reloads it. */\nexport interface ClipContext {\n readonly parts: ModelParts\n readonly family: ModelFamily\n readonly caseType: CaseType\n readonly reloadFamily: ReloadFamily | undefined\n}\n\n/** Recoil strength by case size, when the model has none of its own (the page's `kickOf`). */\nexport const KICK_BY_CASE: Record<CaseType, number> = { shell: 1.6, big: 2.4, tiny: 0.3, pistol: 0.7, rifle: 1.1 }\n\nexport const kickOf = (context: ClipContext): number => context.parts.kick ?? KICK_BY_CASE[context.caseType]\n\n/** Families whose slide or bolt blows back with each shot. */\nexport const BLOWBACK: ReadonlySet<ModelFamily> = new Set(['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'])\nexport const HAS_CYCLE: ReadonlySet<ModelFamily> = new Set(['pump', 'bolt', 'boltmag', 'lever'])\n// the gallery's travel of the pump, of the bolt and of the lever, and the bolt handle's turn (page values)\nexport const PUMP_TRAVEL = -0.075\nexport const BOLT_TRAVEL = -0.07\nexport const BOLT_TURN = -1.15\nexport const LEVER_TURN = -0.85\n\n/** How far the slide or bolt travels back (the page's `-(P.stroke || .06)`). */\nexport const strokeOf = (parts: ModelParts): number => -(parts.stroke || 0.06)\n\n/** The part that blows back: the slide of a pistol, the bolt of the rest. */\nexport const blowbackPart = (context: ClipContext): 'slide' | 'bolt' => (context.family === 'pistol' ? 'slide' : 'bolt')\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { magazineSwap } from './magazine-clips'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, blowbackPart, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n/** The bolt handle turns up, the bolt runs back and forth with the handle, and the handle turns down: the page's `cycleBolt` from `start`. */\nexport function boltStroke(start: number, hold = 0): Tween[] {\n return [\n turn('boltHandle', 'x', start, 0.09, 0, BOLT_TURN),\n move('boltHandle', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('bolt', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n move('bolt', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', start + 0.4 + hold, 0.09, BOLT_TURN, 0),\n ]\n}\n\n/** The manual action after each shot: the pump slides, the bolt cycles or the lever works. The gallery's times (0.5, 0.82 and 0.55 s) are the rule's `timings.cycle`. */\nexport function cycleClip(context: ClipContext): AnimationClipSpec | undefined {\n const { parts, family } = context\n if (family === 'pump' && parts.pump) return composeClip('cycle', [move('pump', 'x', 0.22, 0.11, 0, PUMP_TRAVEL), move('pump', 'x', 0.36, 0.11, PUMP_TRAVEL, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.5)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip('cycle', boltStroke(0.3), [cue(0.5, 'eject_casing', { down: false })], 0.82)\n if (family === 'lever' && parts.lever) return composeClip('cycle', [turn('lever', 'z', 0.22, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.38, 0.13, LEVER_TURN, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.55)\n return undefined\n}\n\n// where the slide sits when a fault is cleared, as a fraction of its travel, and what is thrown out\nconst STUCK_AT: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6, misfire: 0, failure_to_extract: 0 }\n// the page's clear of a bolt gun holds the bolt back 0.04 s longer than its cycle (eject at 0.22, handle down at 0.44)\nconst CLEAR_HOLD = 0.04\n\n/** Clearing a jam on a mechanism that blows back: the slide goes all the way back, throws out what was stuck and returns. */\nfunction clearBlowback(context: ClipContext, fault: string): AnimationClipSpec {\n const { parts, family } = context\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n const stuck = travel * (STUCK_AT[fault] ?? 0)\n const swap = fault === 'double_feed' && parts.mag ? magazineSwap(parts, 0) : undefined\n const start = swap?.end ?? 0\n const tweens: Tween[] = [...(swap?.tweens ?? [])]\n const events = [...(swap?.events ?? [])]\n if (family === 'belt' && parts.cover) {\n tweens.push(turn('cover', 'z', start, 0.18, 0, 0.9), turn('cover', 'z', start + 0.3, 0.15, 0.9, 0))\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start + 0.5)], [...events, cue(start + 0.5 + 0.1, 'fly_jam', { jam: fault })])\n }\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start)], [...events, cue(start + 0.1, 'fly_jam', { jam: fault })])\n}\n\nconst slideOut = (part: 'slide' | 'bolt', from: number, travel: number, start: number): Tween[] => [move(part, 'x', start, 0.12, from, travel), move(part, 'x', start + 0.2, 0.07, travel, 0)]\n\n/** Clearing on a manual action: the same stroke as a cycle, throwing out what was stuck halfway through. */\nfunction clearManual(context: ClipContext, fault: string): AnimationClipSpec | undefined {\n const { parts, family } = context\n const fly = (t: number) => [cue(t, 'fly_jam', { jam: fault })]\n if (family === 'pump' && parts.pump) return composeClip(`clear_${fault}`, [move('pump', 'x', 0, 0.12, 0, PUMP_TRAVEL), move('pump', 'x', 0.2, 0.12, PUMP_TRAVEL, 0)], fly(0.12), 0.4)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip(`clear_${fault}`, boltStroke(0, CLEAR_HOLD), fly(0.22), 0.6)\n if (family === 'lever' && parts.lever) return composeClip(`clear_${fault}`, [turn('lever', 'z', 0, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.16, 0.13, LEVER_TURN, 0)], fly(0.1), 0.35)\n return undefined\n}\n\n/** One clear clip per fault the rule can raise. Mechanisms without a bolt or slide (revolver, break, launcher) only throw out what was stuck. */\nexport function clearClips(context: ClipContext): AnimationClipSpec[] {\n return ['misfire', 'stovepipe', 'double_feed', 'failure_to_extract'].map((fault) => {\n const manual = clearManual(context, fault)\n if (manual) return manual\n const part = blowbackPart(context)\n if (context.parts[part] && ['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'].includes(context.family)) return clearBlowback(context, fault)\n return composeClip(`clear_${fault}`, [], [cue(0, 'fly_jam', { jam: fault })], 0.1)\n })\n}\n","import type { AnimationClipSpec, AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { RELOAD_STAGES } from '@adatechnology/game-weapons'\nimport type { ReloadKind } from '@adatechnology/game-weapons'\nimport { ROOT, composeClip, cue, move, renamed, sound, stage, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, strokeOf } from './context'\nimport type { ClipContext } from './context'\nimport { boltStroke } from './cycle-clips'\nimport { magazineSwap } from './magazine-clips'\n\nconst KINDS: readonly ReloadKind[] = ['tactical', 'empty', 'one_by_one']\n\n/** Charging handle pulled and released (the page's `charge`): the bolt goes back 0.12 s, then forward 0.06 s, from `start`. */\nconst chargeSounds = (start: number): AnimationEventSpec[] => [sound(start, 'charging_handle_pull'), sound(start + 0.2, 'charging_handle_release')]\nconst charge = (context: ClipContext, start: number): Tween[] => {\n const travel = strokeOf(context.parts)\n return [move('bolt', 'x', start, 0.12, 0, travel), move('bolt', 'x', start + 0.18, 0.06, travel, 0)]\n}\n\ninterface Draft {\n tweens: Tween[]\n events: AnimationEventSpec[]\n end: number\n}\n\n/** The bolt of a bolt action worked from `start` (the cycle of `boltStroke`): the handle up, back, forward and down. */\nconst boltSounds = (start: number): AnimationEventSpec[] => [sound(start, 'bolt_lift'), sound(start + 0.1, 'bolt_pull'), sound(start + 0.26, 'bolt_push'), sound(start + 0.45, 'bolt_lock')]\n\nconst cycleWithoutEject = (start: number): Draft => ({ tweens: boltStroke(start), events: [], end: start + 0.55 })\n\n// the slide racked: seconds back, held at the rear and forward\nconst RACK_BACK = 0.14\nconst RACK_HOLD = 0.04\nconst RACK_FORWARD = 0.06\n\n/** Reloads that take a magazine: swap it (0.82 s), then what the mechanism needs. `kind` `empty` also works the action. */\nfunction magazineReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const swap = magazineSwap(parts, 0)\n const draft: Draft = { tweens: [...swap.tweens], events: [...swap.events], end: swap.end }\n if (family === 'pistol') {\n if (kind === 'empty' && parts.slide) {\n // the new magazine is in and the slide is closed: it is pulled back (by the support hand, or released by the thumb of a pistol that is listed for it) and let go\n const travel = strokeOf(parts)\n draft.tweens.push(move('slide', 'x', swap.end + 0.04, RACK_BACK, 0, travel), move('slide', 'x', swap.end + 0.04 + RACK_BACK + RACK_HOLD, RACK_FORWARD, travel, 0))\n draft.events.push(sound(swap.end + 0.04 + RACK_BACK + RACK_HOLD + 0.02, 'slide_release'))\n draft.end += 0.04 + RACK_BACK + RACK_HOLD + RACK_FORWARD + 0.08\n }\n } else if (family === 'boltmag') {\n const stroke = cycleWithoutEject(swap.end)\n draft.tweens.push(...stroke.tweens)\n draft.events.push(...boltSounds(swap.end))\n draft.end = stroke.end\n } else if (kind === 'empty' && parts.bolt) {\n draft.tweens.push(...charge(context, swap.end))\n draft.events.push(...chargeSounds(swap.end))\n draft.end += 0.35\n }\n return draft\n}\n\n/** Revolver: crane opens, spent cases fall, rounds go in (all at once with a speed loader), crane closes: 1.3 s. */\nfunction revolverReload(kind: ReloadKind): Draft {\n const events = [sound(0, 'cylinder_open'), cue(0.32, 'eject_casing', { from: 'chambers', down: false }), sound(0.32, 'cylinder_eject'), sound(1.2, 'cylinder_close')]\n if (kind !== 'one_by_one') events.push(cue(0.7, 'move_in', { from: 'chambers' }), sound(0.7, 'speedloader'))\n return { tweens: [turn('crane', 'x', 0, 0.22, 0, -1.25), turn('crane', 'x', 1.05, 0.2, -1.25, 0)], events, end: 1.3 }\n}\n\n/** Break action: the barrels fold down, the cases drop, a shell goes in each chamber (two on a double barrel, one on a single tube) and the barrels close: 1.2 s. */\nconst breakReload = (chambers: number): Draft => ({\n tweens: [turn('barrels', 'z', 0, 0.2, 0, -0.5), turn('barrels', 'z', 1.0, 0.15, -0.5, 0)],\n events: [\n sound(0, 'barrels_open'),\n cue(0.25, 'eject_casing', { from: 'breech', down: false }),\n sound(0.25, 'casings_eject'),\n cue(0.65, 'move_in', { from: 'breech' }),\n sound(0.65, 'shell_insert'),\n ...(chambers > 1 ? [sound(0.8, 'shell_insert')] : []),\n sound(1.13, 'barrels_close'),\n ],\n end: 1.2,\n})\n\n/** Belt: the cover lifts, the belt box swaps, the cover closes and the bolt is charged: 1.55 s. */\nconst beltReload = (context: ClipContext): Draft => ({\n tweens: [turn('cover', 'z', 0, 0.2, 0, 0.9), move('belt', 'z', 0.2, 0.25, 0, -0.3), move('belt', 'z', 0.55, 0.3, -0.3, 0), turn('cover', 'z', 0.9, 0.18, 0.9, 0), ...charge(context, 1.15)],\n events: [sound(0, 'belt_cover_open'), sound(0.8, 'belt_insert'), sound(1.05, 'belt_cover_close'), ...chargeSounds(1.15)],\n end: 1.55,\n})\n\n// loading round by round has no fixed length (the rule sets it by the rounds), so these are written over one unit and stretched to the rule's duration\nconst UNIT = 1\n\nfunction tubeReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const draft: Draft = { tweens: [], events: [], end: UNIT }\n if (kind !== 'empty') return draft\n // the shells go into the tube one by one, each as the rule feeds it (the `feed` clip: the hand to the loading port, one sound a shell); this clip is the action worked after the last one,\n // which the rule's closing stage (`pump_cycle`, `lever_cycle`, `charge`) brings to its marker\n if (family === 'pump' && parts.pump) {\n draft.tweens.push(move('pump', 'x', 0.88, 0.05, 0, PUMP_TRAVEL), move('pump', 'x', 0.94, 0.05, PUMP_TRAVEL, 0))\n draft.events.push(sound(0.88, 'pump_back'), sound(0.94, 'pump_forward'))\n } else if (family === 'lever' && parts.lever) {\n draft.tweens.push(turn('lever', 'z', 0.87, 0.06, 0, LEVER_TURN), turn('lever', 'z', 0.94, 0.06, LEVER_TURN, 0))\n draft.events.push(sound(0.87, 'lever_open'), sound(0.94, 'lever_close'))\n } else if (parts.bolt) {\n draft.tweens.push(move('bolt', 'x', 0.88, 0.07, 0, strokeOf(parts)), move('bolt', 'x', 0.95, 0.04, strokeOf(parts), 0))\n draft.events.push(sound(0.88, 'charging_handle_pull'), sound(0.95, 'charging_handle_release'))\n }\n return draft\n}\n\n/** Bolt action loaded from the top: the bolt opens, rounds go in one by one, the bolt closes. */\nfunction boltReload(context: ClipContext): Draft {\n if (!context.parts.boltHandle || !context.parts.bolt) return { tweens: [], events: [], end: UNIT }\n return {\n tweens: [\n turn('boltHandle', 'x', 0, 0.05, 0, BOLT_TURN),\n move('boltHandle', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('bolt', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n move('bolt', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', 0.93, 0.05, BOLT_TURN, 0),\n ],\n events: [sound(0, 'bolt_lift'), sound(0.05, 'bolt_pull'), sound(0.86, 'bolt_push'), sound(0.95, 'bolt_lock')],\n end: UNIT,\n }\n}\n\n/** A semi-automatic with an internal magazine: the bolt back, rounds in from the top, the bolt forward. */\nfunction internalMagazineReload(context: ClipContext): Draft {\n const travel = strokeOf(context.parts)\n return { tweens: context.parts.bolt ? [move('bolt', 'x', 0, 0.04, 0, travel), move('bolt', 'x', 0.89, 0.04, travel, 0)] : [], events: context.parts.bolt ? [sound(0.04, 'charging_handle_pull'), sound(0.89, 'charging_handle_release')] : [], end: UNIT }\n}\n\n/** The rocket launchers and flamethrowers: a round slid in, a disposable tube dropped and a new one seated, a hinged breech, or a tank swapped (needle sweeps). */\nfunction heavyReload(context: ClipContext): Draft {\n const { parts, family } = context\n if (family === 'flame') return { tweens: parts.gauge ? [turn('gauge', 'z', 0, 1, -2.4, 0)] : [], events: [], end: 1.1 }\n if (parts.disposable) {\n return {\n tweens: [move(ROOT, 'y', 0.6, 0, 0, -0.6), move(ROOT, 'y', 0.6, 0.5, -0.6, 0)],\n events: [cue(0, 'drop_tube'), sound(0, 'tube_drop'), cue(0.6, 'seat_tube'), sound(1.08, 'tube_seat')],\n end: 1.15,\n }\n }\n if (parts.round) {\n return {\n tweens: [move('round', 'x', 0, 0.55, 0.45, 0), move('round', 'y', 0, 0.55, 0.12, 0)],\n events: [cue(0, 'show_round'), sound(0, 'rocket_load'), sound(0.55, 'rocket_seat')],\n end: 0.6,\n }\n }\n return {\n tweens: [turn('breech_0', 'y', 0, 0.25, 0, -1.6), turn('breech_0', 'y', 0.76, 0.22, -1.6, 0)],\n events: [sound(0, 'breech_open'), cue(0.3, 'breech_round'), sound(0.3, 'grenade_load'), sound(0.96, 'breech_close')],\n end: 1.05,\n }\n}\n\nconst isTube = (context: ClipContext): boolean => ['pump', 'semi12', 'lever'].includes(context.family)\n\nfunction draftFor(context: ClipContext, kind: ReloadKind): Draft | undefined {\n const { parts, family } = context\n if (family === 'rocket' || family === 'flame') return heavyReload(context)\n if (parts.mag) return magazineReload(context, kind)\n if (family === 'revolver' && parts.crane) return revolverReload(kind)\n if (family === 'break' && parts.barrels) return breakReload(parts.breech?.length ?? 2)\n if (family === 'belt' && parts.cover && parts.belt) return beltReload(context)\n if (isTube(context)) return tubeReload(context, kind)\n if (family === 'bolt') return boltReload(context)\n if (family === 'semiint') return internalMagazineReload(context)\n return undefined\n}\n\n/** The stages of the rule's reload as markers of the clip, at the fractions the rule puts them. */\nconst markers = (context: ClipContext, kind: ReloadKind, duration: number): AnimationEventSpec[] =>\n context.reloadFamily ? RELOAD_STAGES[context.reloadFamily][kind].map((entry) => stage(entry.stage, entry.at * duration)) : []\n\n/** `reload` (a magazine swap or the like), `reload_empty` and `reload_one_by_one`, each only when it differs from the first. */\nexport function reloadClips(context: ClipContext): AnimationClipSpec[] {\n const clips: AnimationClipSpec[] = []\n let first: AnimationClipSpec | undefined\n for (const kind of KINDS) {\n const draft = draftFor(context, kind)\n if (!draft) return []\n const clip = composeClip(kind === 'tactical' ? 'reload' : `reload_${kind}`, draft.tweens, [...draft.events, ...markers(context, kind, draft.end)], draft.end)\n if (!first) first = clip\n else if (JSON.stringify({ ...clip, id: first.id }) === JSON.stringify(first)) continue\n clips.push(clip)\n }\n return clips.length > 0 ? clips : first ? [renamed(first, 'reload')] : []\n}\n\n/** How long the hand takes to put one round in: the shooting hand goes to the port, drops it in and comes back (the rule's seconds per round are longer, the hand waits on the grip between two). */\nexport const FEED_SECONDS = 0.4\n\n/** One more round goes in while a tube, a top-loaded or a revolver loads round by round. */\nexport function feedClip(context: ClipContext): AnimationClipSpec | undefined {\n const { family } = context\n if (family === 'revolver') return composeClip('feed', [], [cue(0, 'move_in', { from: 'chambers', next: true }), sound(0.1, 'shell_insert')], 0.24)\n if (family === 'bolt' || family === 'semiint') return composeClip('feed', [], [cue(0, 'move_in', { from: 'topLoad' }), sound(0.2, 'shell_insert')], FEED_SECONDS)\n if (isTube(context)) return composeClip('feed', [], [cue(0, 'move_in', { from: 'loadPort' }), sound(0.2, 'shell_insert')], FEED_SECONDS)\n return undefined\n}\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { ROOT, composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BLOWBACK, blowbackPart, kickOf, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n// how far the slide stays back for each fault, as a fraction of its travel: the page's `k` (stovepipe .35, double feed .6)\nconst FAULT_SLIDE_BACK: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6 }\n\n/** The trigger finger: the trigger turns back 0.35 rad and returns (the page's `pull`). */\nconst pullTrigger = (context: ClipContext): Tween[] => (context.parts.trigger ? [turn('trigger', 'z', 0, 0.04, 0, 0.35), turn('trigger', 'z', 0.06, 0.08, 0.35, 0)] : [])\n\n/** The whole weapon kicks back and tilts up, then settles (the page's `recoil`). */\nconst recoil = (context: ClipContext): Tween[] => {\n const kick = kickOf(context)\n return [\n move(ROOT, 'x', 0, 0.03, 0, -0.014 * kick),\n turn(ROOT, 'z', 0, 0.03, 0, 0.045 * kick),\n move(ROOT, 'x', 0.03, 0.18, -0.014 * kick, 0),\n turn(ROOT, 'z', 0.03, 0.18, 0.045 * kick, 0),\n ]\n}\n\n/** A rotary gun turns its barrels a sixth of a turn with each shot; six barrels look the same every sixth, so the next shot starts over from rest. */\nconst spinBarrels = (context: ClipContext): Tween[] => (context.parts.barrels && context.family === 'belt' ? [turn('barrels', 'x', 0, 0.03, 0, Math.PI / 3)] : [])\n\nconst hammerFall = (context: ClipContext): Tween[] => (context.parts.hammer && context.family !== 'revolver' ? [turn('hammer', 'z', 0, 0.02, 0, -0.5), turn('hammer', 'z', 0.05, 0.06, -0.5, 0)] : [])\n\n/** What every shot does, then what the mechanism does by family. `locked` leaves the pistol slide back, as after the last round. */\nfunction shotClip(id: string, context: ClipContext, locked: boolean): AnimationClipSpec {\n const { parts, family } = context\n const tweens = [...pullTrigger(context), ...recoil(context), ...hammerFall(context), ...spinBarrels(context)]\n const events = [cue(0, 'muzzle_flash')]\n if (BLOWBACK.has(family)) {\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n if (parts[part]) {\n tweens.push(move(part, 'x', 0, 0.025, 0, travel))\n if (!locked) tweens.push(move(part, 'x', 0.025, 0.045, travel, 0))\n }\n events.push(cue(0.012, 'eject_casing', { down: family === 'p90' || family === 'belt' }))\n } else if (family === 'revolver' && parts.cylinder && parts.hammer) {\n tweens.push(turn('cylinder', 'x', 0, 0.05, 0, Math.PI / 3), turn('hammer', 'z', 0, 0.05, 0, 0.5), turn('hammer', 'z', 0.05, 0.03, 0.5, -0.5), turn('hammer', 'z', 0.12, 0.08, -0.5, 0))\n }\n return composeClip(id, tweens, events)\n}\n\n/** A weapon with a mechanism that moves between shots (pump, bolt, lever) leaves that to the `cycle` clip, which the rule times. */\nexport function shotClips(context: ClipContext): AnimationClipSpec[] {\n const clips = [shotClip('shot', context, false)]\n if (context.family === 'pistol') clips.push(shotClip('shot_last', context, true))\n return clips\n}\n\n/** The trigger pulls and the hammer falls on a round that does not fire. */\nconst dudTweens = (context: ClipContext): Tween[] => [...pullTrigger(context), ...(context.parts.hammer ? [turn('hammer', 'z', 0, 0.03, 0, -0.5)] : [])]\n\n/** A dud that does not stop the weapon (revolver, break action): the cylinder of a revolver still turns. */\nexport function misfireClip(context: ClipContext): AnimationClipSpec {\n const tweens = dudTweens(context)\n if (context.family === 'revolver' && context.parts.cylinder) tweens.push(turn('cylinder', 'x', 0, 0.07, 0, Math.PI / 3))\n return composeClip('misfire', tweens)\n}\n\nexport const emptyClip = (context: ClipContext): AnimationClipSpec => composeClip('empty', pullTrigger(context))\n\n/**\n * A jam after the shot: the slide is stopped part of the way back (`FAULT_SLIDE_BACK`) and the case sticks in the port of a stovepipe. The clip lasts as long\n * as the shot's, so that it holds the slide where the shot would have returned it.\n */\nexport function faultClips(context: ClipContext): AnimationClipSpec[] {\n const { parts, family } = context\n const misfire = composeClip('fault_misfire', dudTweens(context))\n const part = blowbackPart(context)\n if (!BLOWBACK.has(family) || !parts[part]) return [misfire]\n const travel = strokeOf(parts)\n const stopped = Object.entries(FAULT_SLIDE_BACK).map(([fault, back]) =>\n composeClip(`fault_${fault}`, [move(part, 'x', 0, 0.025, 0, travel), move(part, 'x', 0.025, 0.04, travel, travel * back)], fault === 'stovepipe' ? [cue(0.03, 'stuck_case')] : [], 0.25),\n )\n return [misfire, ...stopped]\n}\n\n// the safety (`safety_on`, `safety_off`): the weapon cants to the right so its left side comes up to the eye, the thumb of the shooting hand\n// (`data/hand-work.json`) goes to the lever and flicks it, and the weapon comes back level. Seconds and radians of the motion, not of any weapon.\nexport const SAFETY_MOTION = { cant: 0.22, lift: 0.012, in: 0.14, flickAt: 0.16, flick: 0.1, outAt: 0.32, out: 0.16, lever: 0.6 } as const\n\n/**\n * Putting the safety on or taking it off (destravar): the weapon cants and rises a little toward the eye, the lever (the model's `safety`, when it\n * draws one) flicks down for on and back for off while the thumb is on it, and the weapon settles. Every model has it, so B always shows the move.\n */\nexport function safetyClips(context: ClipContext): AnimationClipSpec[] {\n const { cant, lift, in: rise, flickAt, flick, outAt, out, lever } = SAFETY_MOTION\n const carry = (): Tween[] => [turn(ROOT, 'x', 0, rise, 0, cant), move(ROOT, 'y', 0, rise, 0, lift), turn(ROOT, 'x', outAt, out, cant, 0), move(ROOT, 'y', outAt, out, lift, 0)]\n const flickTo = (from: number, to: number): Tween[] => (context.parts.safety ? [turn('safety', 'z', flickAt, flick, from, to)] : [])\n const clips = [composeClip('safety_on', [...carry(), ...flickTo(0, -lever)]), composeClip('safety_off', [...carry(), ...flickTo(-lever, 0)])]\n if (context.parts.safety) clips.push(composeClip('mode', [turn('safety', 'z', 0, 0.07, 0, 0.4), turn('safety', 'z', 0.07, 0.07, 0.4, 0)]))\n return clips\n}\n\n/** Raising the weapon: it comes up from low with the muzzle down. The gallery shows no hands, so this is the SDK's own motion. */\nexport const drawClip = (): AnimationClipSpec => composeClip('draw', [move(ROOT, 'y', 0, 0.35, -0.1, 0), turn(ROOT, 'z', 0, 0.35, -0.6, 0)])\n","import type { AnimationClipSpec, ToolClipSet } from '@adatechnology/game-contracts'\nimport type { ClipContext } from './context'\nimport { launcherClips, stockClips, toggleClip } from './accessory-clips'\nimport { clearClips, cycleClip } from './cycle-clips'\nimport { feedClip, reloadClips } from './reload-clips'\nimport { drawClip, emptyClip, faultClips, misfireClip, safetyClips, shotClips } from './shot-clips'\n\n/** Every clip a weapon model brings, by the ids `toolAnimationStep` asks for (`shot`, `cycle`, `reload`, `reload_empty`, `fault_<id>`, `clear_<id>`...). */\nexport function buildToolClips(context: ClipContext): ToolClipSet {\n const clips: Array<AnimationClipSpec | undefined> = [\n ...shotClips(context),\n misfireClip(context),\n emptyClip(context),\n cycleClip(context),\n ...reloadClips(context),\n feedClip(context),\n ...faultClips(context),\n ...clearClips(context),\n ...safetyClips(context),\n drawClip(),\n ...stockClips(context),\n toggleClip(),\n ...launcherClips(context),\n ]\n const set: Record<string, AnimationClipSpec> = {}\n for (const clip of clips) if (clip) set[clip.id] = clip\n return set\n}\n","import type { FaultId, FireMode, MountKind, ReloadStageId, StockDef, WeaponEvent } from '@adatechnology/game-weapons'\nimport type { HostEvent } from '@adatechnology/game-contracts'\n\n/**\n * The weapon event a host event stands for, so `mechanicalSoundOf` can pick its sound: reload stages, cycle, dry fire and misfire, jam, clear, safety, mode and feed.\n * Shots that fired a projectile have their own sound (`computeShotSound`), so they are not here.\n */\nexport const weaponEventOf = (event: HostEvent): WeaponEvent | undefined => {\n switch (event.type) {\n case 'misfire':\n return { type: 'misfire', at: 0 }\n case 'stage':\n return { type: 'reload_stage', stage: event.stage as ReloadStageId, at: 0 }\n case 'empty':\n case 'feed':\n return { type: event.type, at: 0 }\n case 'cycle':\n return { type: 'cycle', phase: event.phase, at: 0 }\n case 'mode':\n return { type: 'mode', mode: event.mode as FireMode, at: 0 }\n case 'fault':\n return { type: 'fault', fault: event.fault as FaultId, at: 0 }\n case 'clear':\n return { type: 'clear', fault: event.fault as FaultId, phase: event.phase, at: 0 }\n case 'safety':\n return { type: 'safety', on: event.on, at: 0 }\n case 'attachment':\n return { type: 'attachment', action: event.action, id: event.attachment, mount: event.mount as MountKind, at: 0 }\n case 'toggle':\n return { type: 'toggle', id: event.attachment, on: event.on, at: 0 }\n case 'stock':\n return { type: 'stock', state: event.state, kind: (event.kind ?? 'fold') as StockDef['kind'], at: 0 }\n case 'underbarrel':\n return { type: 'underbarrel', on: event.on, at: 0 }\n default:\n return undefined\n }\n}\n","import { catenary, createCord } from '@adatechnology/game-shapes-three'\nimport { buildBeltBox } from './belt-box'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\n// the pack hangs behind and below the stock, as worn on the back; the belt runs from it to the feed of the weapon\nconst PACK_AT: [number, number, number] = [-0.55, -0.4, 0.1]\nconst PACK_SIZE: [number, number, number] = [0.3, 0.42, 0.2]\nconst BELT_SAG = 0.14\nconst BELT_POINTS = 16\nconst BELT_ROUND_EVERY = 2\n\n/** The ammunition backpack worn on the back and its belt: the pack, the feed box on the weapon (the belt box of the gallery) and the belt of rounds between them on a catenary. */\nexport const buildAmmoBackpack: AttachmentModelBuilder = ({ kit, frame, model }): AttachmentModel => {\n const { THREE, M, box, cylinderZ } = kit\n const group = kit.group()\n const pack: [number, number, number] = [PACK_AT[0] - frame.position[0], PACK_AT[1] - frame.position[1], PACK_AT[2] - frame.position[2]]\n box(group, ...PACK_SIZE, M.olive, ...pack)\n box(group, PACK_SIZE[0] * 1.02, 0.03, PACK_SIZE[2] * 1.02, M.dark, pack[0], pack[1] + PACK_SIZE[1] / 2, pack[2])\n box(group, 0.04, PACK_SIZE[1] * 0.9, 0.012, M.tan, pack[0] + PACK_SIZE[0] / 2, pack[1], pack[2] - 0.04)\n const feed = kit.pivot(group, 0, 0, 0)\n buildBeltBox(kit, feed)\n const points = catenary([pack[0] + PACK_SIZE[0] / 2, pack[1] + PACK_SIZE[1] * 0.3, pack[2]], [0, 0, 0], BELT_SAG, BELT_POINTS)\n const strip = createCord(THREE, points, 0.0035, M.metal)\n group.add(strip)\n points.forEach((point, index) => {\n if (index % BELT_ROUND_EVERY === 0) cylinderZ(group, 0.0045, 0.02, M.brass, point[0], point[1], point[2], 8)\n })\n return {\n object: group,\n ...(model.parts.belt ? { hides: [model.parts.belt] } : {}),\n dispose() {\n strip.geometry.dispose()\n },\n }\n}\n","import type { AttachmentModelBuilder } from './types'\n\nconst RIBS = 4\n\n/** The vertical grip: a clamp on the rail and a ribbed handle hanging from it, as long as the data says. */\nexport const buildForegrip: AttachmentModelBuilder = ({ kit, attachment }) => {\n const { M, box, cylinderY } = kit\n const length = attachment.dims?.length ?? 0.1\n const group = kit.group()\n box(group, 0.045, 0.014, 0.034, M.dark, 0, -0.007, 0)\n cylinderY(group, 0.0135, length, M.poly, 0, -0.014 - length / 2, 0, 14)\n for (let i = 0; i < RIBS; i++) cylinderY(group, 0.0145, 0.004, M.rubber, 0, -0.03 - i * (length / (RIBS + 1)), 0, 14)\n cylinderY(group, 0.0155, 0.01, M.dark, 0, -0.014 - length, 0, 14)\n return group\n}\n","import type { AttachmentModel, AttachmentModelBuilder } from './types'\n\nconst DEFAULT_RANGE = 120\nconst DEFAULT_COLOR = 0xff0000\nconst BEAM_WIDTH = 0.0025\nconst DOT_RADIUS = 0.012\n\n/**\n * The laser sight: a body with an emitter on its rail, a thin beam along the barrel and a dot where it lands. The host measures how far the beam goes (`raycast`, in metres);\n * with no host the beam reaches the range of the data and there is no dot. Off until it is turned on.\n */\nexport const buildLaser: AttachmentModelBuilder = ({ kit, attachment, frame, raycast }): AttachmentModel => {\n const { THREE, M, box, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.08\n const half = (attachment.dims?.diameter ?? 0.025) / 2\n const range = attachment.laser?.range ?? DEFAULT_RANGE\n const color = attachment.laser?.color ?? DEFAULT_COLOR\n const group = kit.group()\n const offset = frame.side === 0 ? { y: -(half + 0.004), z: 0 } : { y: 0, z: frame.side * (half + 0.004) }\n box(group, 0.03, 0.012, 0.028, M.dark, 0, frame.side === 0 ? -0.002 : 0, 0)\n box(group, length, half * 2, half * 2, M.dark, 0, offset.y, offset.z)\n const emitter = new THREE.MeshBasicMaterial({ color: 0x551111 })\n cylinderX(group, half * 0.5, 0.004, emitter, length / 2 + 0.001, offset.y, offset.z, 10)\n const glow = new THREE.MeshBasicMaterial({ color, transparent: true, opacity: 0.7, blending: THREE.AdditiveBlending, depthWrite: false })\n const beam = new THREE.Mesh(new THREE.BoxGeometry(1, BEAM_WIDTH, BEAM_WIDTH), glow)\n const dot = new THREE.Mesh(new THREE.SphereGeometry(DOT_RADIUS, 10, 8), new THREE.MeshBasicMaterial({ color }))\n const front = length / 2 + 0.004\n beam.position.set(front, offset.y, offset.z)\n dot.position.set(front, offset.y, offset.z)\n beam.visible = false\n dot.visible = false\n group.add(beam, dot)\n const origin = new THREE.Vector3()\n const direction = new THREE.Vector3()\n const scale = new THREE.Vector3()\n let isOn = false\n return {\n object: group,\n setOn(on) {\n isOn = on\n emitter.color.setHex(on ? color : 0x551111)\n beam.visible = on\n if (!on) dot.visible = false\n },\n update() {\n if (!isOn) return\n group.updateWorldMatrix(true, false)\n group.getWorldPosition(origin)\n direction.set(1, 0, 0).transformDirection(group.matrixWorld)\n group.getWorldScale(scale)\n const hit = raycast?.(origin, direction, range) ?? null\n const reach = (hit ?? range) / Math.max(scale.x, 1e-6)\n beam.scale.x = reach\n beam.position.x = front + reach / 2\n dot.visible = hit !== null\n dot.position.x = front + reach\n },\n dispose() {\n beam.geometry.dispose()\n dot.geometry.dispose()\n glow.dispose()\n emitter.dispose()\n dot.material.dispose()\n },\n }\n}\n\n","import { LIGHT_PRIORITY } from '@adatechnology/game-render-three'\nimport type { Group, MeshStandardMaterial } from 'three'\nimport type { LightBudget } from '@adatechnology/game-render-three'\nimport type { AttachmentBuildContext, AttachmentModel, AttachmentModelBuilder } from './types'\n\n// candela of the spot: bright enough to read against the room lights at the range of the data\nconst LIGHT_INTENSITY = 150\nconst LENS_GLOW = 3\nconst LIGHT_COLOR = 0xfff1d0\nconst DEFAULT_CONE_DEG = 30\nconst DEFAULT_RANGE = 60\n\n/**\n * The weapon light: a body with a lens on its rail, and a real `SpotLight` along the barrel with the cone and the range of the data. Off until it is turned on.\n * The spot stays in the scene (visible, at intensity 0) while the light is fitted: toggling it changes the intensity only, because a change in the number of lights makes three.js\n * recompile every lit material. The one recompile happens when the accessory is fitted or removed, which is rare and already takes seconds of work.\n */\nexport const buildLight: AttachmentModelBuilder = ({ kit, attachment, frame, lights }): AttachmentModel => {\n const { THREE, M, box, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.1\n const radius = (attachment.dims?.diameter ?? 0.03) / 2\n const group = kit.group()\n const offset = frame.side === 0 ? { y: -(radius + 0.004), z: 0 } : { y: 0, z: frame.side * (radius + 0.004) }\n box(group, 0.035, 0.012, 0.03, M.dark, 0, frame.side === 0 ? -0.002 : 0, 0)\n cylinderX(group, radius, length, M.dark, 0, offset.y, offset.z, 14)\n cylinderX(group, radius * 1.08, 0.012, M.metal, length / 2 - 0.006, offset.y, offset.z, 14)\n const lens = new THREE.MeshStandardMaterial({ color: 0xfff2c8, roughness: 0.1, metalness: 0.2, emissive: 0xfff2c8, emissiveIntensity: 0 })\n cylinderX(group, radius * 0.82, 0.004, lens, length / 2 + 0.001, offset.y, offset.z, 14)\n const cone = (attachment.light?.coneDeg ?? DEFAULT_CONE_DEG) * (Math.PI / 180)\n const range = attachment.light?.range ?? DEFAULT_RANGE\n if (lights) return budgetedLight({ THREE, lights, group, lens, cone, range, at: [length / 2 + 0.01, offset.y, offset.z] })\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget, removed in the next major\n const spot = new THREE.SpotLight(LIGHT_COLOR, LIGHT_INTENSITY, range, cone / 2, 0.35, 1.2)\n spot.position.set(length / 2 + 0.01, offset.y, offset.z)\n spot.intensity = 0\n const target = new THREE.Object3D()\n target.position.set(length / 2 + 1, offset.y, offset.z)\n group.add(spot, target)\n spot.target = target\n return {\n object: group,\n setOn(on) {\n spot.intensity = on ? LIGHT_INTENSITY : 0\n lens.emissiveIntensity = on ? LENS_GLOW : 0\n },\n dispose() {\n lens.dispose()\n spot.dispose()\n },\n }\n}\n\ntype BudgetedLightParams = {\n readonly THREE: AttachmentBuildContext['kit']['THREE']\n readonly lights: LightBudget\n readonly group: Group\n readonly lens: MeshStandardMaterial\n readonly cone: number\n readonly range: number\n readonly at: readonly [number, number, number]\n}\n\n/** The same spot as a source of the host's budget: it competes for a slot only while on, and follows the lens (whose -z points along the barrel, +x of the wrapper). */\nfunction budgetedLight({ THREE, lights, group, lens, cone, range, at }: BudgetedLightParams): AttachmentModel {\n const aim = new THREE.Object3D()\n aim.position.set(at[0], at[1], at[2])\n aim.rotation.y = -Math.PI / 2\n group.add(aim)\n const source = lights.addSource({ owner: 'weapons.light', kind: 'spot', priority: LIGHT_PRIORITY.weaponLight, color: LIGHT_COLOR, intensity: 0, distance: range, decay: 1.2, angle: cone / 2, penumbra: 0.35, position: [0, 0, 0], follow: aim })\n return {\n object: group,\n setOn(on) {\n source.update({ intensity: on ? LIGHT_INTENSITY : 0 })\n lens.emissiveIntensity = on ? LENS_GLOW : 0\n },\n dispose() {\n source.remove()\n lens.dispose()\n },\n }\n}\n","import { buildDrum } from './drum'\nimport type { AttachmentModelBuilder } from './types'\n\nconst EXTENSION_FRACTION = 0.5\nconst MAGAZINE_LEAN = 0.08\n\n/** The drum: the gallery's drum magazine in place of the magazine, in the frame of the magazine pivot so that it moves with the reload. */\nexport const buildDrumMagazine: AttachmentModelBuilder = ({ kit, factoryMagazine }) => {\n const group = kit.group()\n buildDrum(kit, group)\n return { object: group, hangsFrom: 'magazine', hides: factoryMagazine }\n}\n\n/** The extended magazine: a longer floor plate joined under the one the weapon has (+50% of the length of a box magazine). */\nexport const buildExtendedMagazine: AttachmentModelBuilder = ({ kit, model }) => {\n const { M, box } = kit\n const length = Math.max(0.1, (model.parts.magDrop ?? 0.16) - 0.03)\n const extension = length * EXTENSION_FRACTION\n const group = kit.group()\n const lean = Math.sin(MAGAZINE_LEAN) * (length + extension / 2)\n box(group, 0.05, extension + 0.004, 0.024, M.dark, lean, -(Math.cos(MAGAZINE_LEAN) * (length + extension / 2)), 0, MAGAZINE_LEAN)\n box(group, 0.056, 0.007, 0.028, M.dark, lean + Math.sin(MAGAZINE_LEAN) * extension / 2, -(Math.cos(MAGAZINE_LEAN) * (length + extension)) - 0.003, 0)\n return { object: group, hangsFrom: 'magazine' }\n}\n\n/** The dual coupler: the magazine of the weapon copied beside it and strapped to it, so the second one is a short reach away. */\nexport const buildDualCoupler: AttachmentModelBuilder = ({ kit, factoryMagazine }) => {\n const { M, box } = kit\n const group = kit.group()\n const spare = kit.group()\n spare.position.set(0, 0, 0.032)\n for (const piece of factoryMagazine) spare.add(piece.clone(true))\n group.add(spare)\n box(group, 0.05, 0.012, 0.04, M.tape, 0, -0.03, 0.016)\n return { object: group, hangsFrom: 'magazine' }\n}\n","import { buildBrake } from './muzzle-brake'\nimport type { AttachmentModelBuilder } from './types'\n\n/** The muzzle brakes by the gallery's drawing (`brake` 1 and 2) and the compensator, a short tube with slots cut in the top. */\nexport const buildMuzzleBrake = (kind: 1 | 2): AttachmentModelBuilder => ({ kit, frame }) => {\n const group = kit.group()\n buildBrake(kit, group, kind, 0, 0, frame.barrelRadius)\n return group\n}\n\nexport const buildCompensator: AttachmentModelBuilder = ({ kit, frame }) => {\n const { M, box, cylinderX } = kit\n const radius = frame.barrelRadius * 1.9\n const length = 0.07\n const group = kit.group()\n cylinderX(group, radius, length, M.dark, -length / 2, 0, 0, 16)\n for (let i = 0; i < 3; i++) box(group, length * 0.14, radius * 0.9, radius * 0.7, M.hole, -length * 0.2 - i * length * 0.25, radius * 0.75, 0)\n return group\n}\n","import type * as THREE_NS from 'three'\nimport { rail, scope } from '../details'\nimport type { AttachmentBuildContext, AttachmentModel, AttachmentModelBuilder } from './types'\n\ninterface OpticLook {\n /** The page's `scope` kind: 1 red dot, 2 short scope, 3 and 4 long scopes. */\n readonly kind: 1 | 2 | 3 | 4\n /** Colour of the lens for the night and thermal sights. */\n readonly lens?: number\n}\n\nconst OPTICS: Readonly<Record<string, OpticLook>> = {\n red_dot: { kind: 1 },\n holographic_sight: { kind: 1 },\n acog_4x: { kind: 2 },\n scope_3_9x: { kind: 3 },\n scope_6_24x: { kind: 4 },\n night_vision_scope: { kind: 3, lens: 0x35ff6a },\n thermal_scope: { kind: 3, lens: 0xff8a3a },\n pso_1: { kind: 2 },\n fixed_scope_10x: { kind: 4 },\n}\n\nconst ADAPTER_LENGTH = 0.1\nconst ADAPTER_BACK = 0.05\n\nconst tinted = (context: AttachmentBuildContext, group: THREE_NS.Group, color: number): THREE_NS.Material => {\n const { THREE, M } = context.kit\n const lens = new THREE.MeshStandardMaterial({ color, roughness: 0.05, metalness: 0.3, transparent: true, opacity: 0.9, emissive: color, emissiveIntensity: 0.6 })\n group.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n if (mesh.isMesh && mesh.material === M.lens) mesh.material = lens\n })\n return lens\n}\n\n/** An optic by the gallery's `scope(kind)` (the same drawing the rifles ship with), on a short rail when the top of the weapon has none. */\nexport const buildOptic: AttachmentModelBuilder = (context) => {\n const look = OPTICS[context.attachment.model]\n if (!look) return null\n const { kit, frame } = context\n const group = kit.group()\n scope(kit, group, look.kind, 0, 0, 0)\n if (!frame.hasRail && frame.mount === 'rail_top') rail(kit, group, -ADAPTER_BACK, ADAPTER_LENGTH, -0.003, 0, frame.receiverWidth * 0.68)\n if (look.lens === undefined) return group\n const lens = tinted(context, group, look.lens)\n return { object: group, dispose: (): void => lens.dispose() } satisfies AttachmentModel\n}\n\nexport const OPTIC_MODEL_IDS: readonly string[] = Object.keys(OPTICS)\n","import type * as THREE_NS from 'three'\nimport { catenary, createCord } from '@adatechnology/game-shapes-three'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\nconst SAG = 0.2\nconst STRAP_RADIUS = 0.007\nconst CORD_POINTS = 12\n\n/** The sling: a swivel at each end and a strap hanging between them on a catenary (the cord of the interactables). Positions are relative to the front swivel. */\nexport const buildSling: AttachmentModelBuilder = ({ kit, frame }): AttachmentModel | null => {\n if (!frame.secondary) return null\n const { THREE, M } = kit\n const group = kit.group()\n const rear: [number, number, number] = [frame.secondary[0] - frame.position[0], frame.secondary[1] - frame.position[1], frame.secondary[2] - frame.position[2]]\n const swivels: THREE_NS.Mesh[] = []\n for (const at of [[0, 0, 0], rear] as const) {\n const swivel = kit.torus(group, new THREE.TorusGeometry(0.006, 0.0015, 6, 12), M.metal, at[0], at[1], at[2])\n swivel.rotation.y = Math.PI / 2\n swivels.push(swivel)\n }\n const strap = createCord(THREE, catenary(rear, [0, 0, 0], SAG, CORD_POINTS), STRAP_RADIUS, M.olive)\n group.add(strap)\n return {\n object: group,\n dispose() {\n strap.geometry.dispose()\n for (const swivel of swivels) swivel.geometry.dispose()\n },\n }\n}\n","import type { AttachmentModelBuilder } from './types'\n\nconst BAFFLES = 5\n\n/**\n * A suppressor: a dark tube with baffle rings and a capped end, from the length and diameter of the data. Screwed on the muzzle it goes past it and the muzzle moves to its end;\n * an integral one is the front of the barrel and ends at the muzzle. The oil filter is the improvised one: a rusty can taped on.\n */\nexport const buildSuppressor: AttachmentModelBuilder = ({ kit, attachment, fitted }) => {\n const { M, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.2\n const radius = (attachment.dims?.diameter ?? 0.045) / 2\n const isImprovised = attachment.id === 'oil_filter_suppressor'\n const group = kit.group()\n const middle = fitted.integral === true ? -length / 2 : length / 2\n cylinderX(group, radius, length, isImprovised ? M.rust : M.dark, middle, 0, 0, 18)\n if (isImprovised) {\n for (const along of [0.2, 0.8]) cylinderX(group, radius * 1.04, 0.012, M.tape, middle - length / 2 + length * along, 0, 0, 18)\n cylinderX(group, radius * 0.7, 0.008, M.rustD, middle + length / 2 - 0.004, 0, 0, 14)\n } else {\n for (let i = 0; i < BAFFLES; i++) cylinderX(group, radius * 1.03, 0.004, M.metal, middle - length / 2 + (length * (i + 0.5)) / BAFFLES, 0, 0, 18)\n cylinderX(group, radius * 0.9, 0.006, M.steel, middle - length / 2 + 0.003, 0, 0, 18)\n }\n cylinderX(group, radius * 0.22, 0.004, M.hole, middle + length / 2 + 0.0005, 0, 0, 12)\n return { object: group, ...(fitted.integral === true ? {} : { muzzleOffset: length }) }\n}\n","import type { ModelKit, Parent } from '../kit'\nimport type { AttachmentModelBuilder } from './types'\n\n// how far the three legs reach and how thick they are\nconst LEG = { length: 0.62, width: 0.012 }\n\n/** The tripod of three steel legs under the gun, the head at the origin of `parent`: the creation the counters' mounted M134 and the `tripod` accessory both draw. */\nexport function buildTripodLegs(kit: ModelKit, parent: Parent): void {\n const { length, width } = LEG\n kit.box(parent, 0.03, 0.06, 0.03, kit.M.metal, 0, 0, 0)\n kit.box(parent, width, length, width, kit.M.metal, -0.2, -0.25, 0, 0.75)\n kit.box(parent, width, length, width, kit.M.metal, 0.22, -0.25, 0.16, -0.75, 0, 0.3)\n kit.box(parent, width, length, width, kit.M.metal, 0.22, -0.25, -0.16, -0.75, 0, -0.3)\n}\n\nexport const buildTripod: AttachmentModelBuilder = ({ kit }) => {\n const group = kit.group()\n buildTripodLegs(kit, group)\n return group\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../kit'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\ninterface LauncherLook {\n /** Radius of the 40 mm tube and how much of the data length it takes. */\n readonly tubeRadius: number\n readonly tubeFraction: number\n /** The housing around the breech: length (along the weapon), height and width. */\n readonly housing: readonly [number, number, number]\n /** The Soviet and the German ones have a muzzle ring and a front grip; the American one a plain tube. */\n readonly hasFrontGrip: boolean\n}\n\nconst LAUNCHERS: Readonly<Record<string, LauncherLook>> = {\n m203: { tubeRadius: 0.0215, tubeFraction: 0.8, housing: [0.1, 0.05, 0.05], hasFrontGrip: false },\n gp_25: { tubeRadius: 0.023, tubeFraction: 0.78, housing: [0.08, 0.055, 0.05], hasFrontGrip: false },\n ag36: { tubeRadius: 0.02, tubeFraction: 0.8, housing: [0.13, 0.06, 0.05], hasFrontGrip: true },\n}\n\nconst drawFixed = (kit: ModelKit, group: THREE_NS.Object3D, look: LauncherLook, length: number): void => {\n const { M, box, cylinderY } = kit\n const [housingLength, housingHeight, housingWidth] = look.housing\n box(group, housingLength, housingHeight, housingWidth, M.dark, housingLength / 2 - 0.02, -look.tubeRadius, 0)\n // the sights and the trigger of the launcher, under the receiver\n box(group, 0.05, 0.004, 0.012, M.metal, housingLength * 0.45, -look.tubeRadius - housingHeight / 2 - 0.004, 0)\n box(group, 0.004, 0.02, 0.008, M.dark, housingLength * 0.6, -look.tubeRadius - housingHeight / 2 - 0.016, 0)\n if (look.hasFrontGrip) {\n cylinderY(group, 0.012, 0.07, M.poly, length * 0.55, -look.tubeRadius - 0.04, 0, 12)\n box(group, 0.04, 0.01, 0.03, M.dark, length * 0.55, -look.tubeRadius - 0.004, 0)\n }\n}\n\n/**\n * A launcher under the barrel, drawn from the primitives of the kit: the housing and trigger on the weapon, and the 40 mm tube in the sliding pivot the reload clip moves\n * (the barrel of the real ones slides forward to open the breech). The muzzle mark `ugl_muzzle` is where the shot flashes.\n */\nexport const buildUnderbarrelLauncher: AttachmentModelBuilder = ({ kit, attachment, slide }): AttachmentModel | null => {\n const look = LAUNCHERS[attachment.model]\n if (!look || !slide) return null\n const { M, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.35\n const fixed = kit.group()\n drawFixed(kit, fixed, look, length)\n const tubeLength = length * look.tubeFraction\n const start = -0.02\n cylinderX(slide, look.tubeRadius, tubeLength, M.metal, start + tubeLength / 2, -look.tubeRadius, 0, 18)\n cylinderX(slide, look.tubeRadius * 1.12, 0.012, M.dark, start + tubeLength - 0.006, -look.tubeRadius, 0, 18)\n cylinderX(slide, look.tubeRadius * 0.7, 0.004, M.hole, start + tubeLength + 0.0005, -look.tubeRadius, 0, 14)\n const muzzle = kit.mark(slide, start + tubeLength + 0.01, -look.tubeRadius, 0)\n muzzle.name = 'ugl_muzzle'\n return {\n object: fixed,\n muzzle,\n dispose() {\n slide.remove(...slide.children)\n },\n }\n}\n","import { buildAmmoBackpack } from './ammo-backpack'\nimport { buildBipodModel } from './bipod'\nimport { buildForegrip } from './foregrip'\nimport { buildLaser } from './laser'\nimport { buildLight } from './light'\nimport { buildDrumMagazine, buildDualCoupler, buildExtendedMagazine } from './magazine'\nimport { buildCompensator, buildMuzzleBrake } from './muzzle-device'\nimport { OPTIC_MODEL_IDS, buildOptic } from './optic'\nimport { buildSling } from './sling'\nimport { buildSuppressor } from './suppressor'\nimport { buildTripod } from './tripod'\nimport type { AttachmentModelRegistry } from './types'\nimport { buildUnderbarrelLauncher } from './ugl'\n\n/**\n * The model of each accessory by `AttachmentDef.model`. The ports of the gallery (optics, bipod, brakes, drum, belt box, rail) draw what the page draws; the others are creations of the\n * kit. Accessories without a model (the barrel swaps, the integral optics the weapon already draws) are simply not drawn.\n */\nexport const ATTACHMENT_MODELS: AttachmentModelRegistry = {\n ...Object.fromEntries(OPTIC_MODEL_IDS.map((id) => [id, buildOptic])),\n bipod: buildBipodModel,\n muzzle_brake: buildMuzzleBrake(1),\n muzzle_brake_heavy: buildMuzzleBrake(2),\n compensator: buildCompensator,\n suppressor: buildSuppressor,\n oil_filter_suppressor: buildSuppressor,\n integral_suppressor: buildSuppressor,\n vertical_grip: buildForegrip,\n weapon_light: buildLight,\n laser_sight: buildLaser,\n m203: buildUnderbarrelLauncher,\n gp_25: buildUnderbarrelLauncher,\n ag36: buildUnderbarrelLauncher,\n ammo_backpack: buildAmmoBackpack,\n tripod: buildTripod,\n sling: buildSling,\n drum_magazine: buildDrumMagazine,\n extended_magazine: buildExtendedMagazine,\n dual_coupler: buildDualCoupler,\n}\n","import type * as THREE_NS from 'three'\nimport type { LightBudget } from '@adatechnology/game-render-three'\nimport type { AttachmentDef, FittedAttachment } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../types'\nimport type { ModelKit } from '../kit'\nimport { mountFrame } from './mount-frames'\nimport { ATTACHMENT_MODELS } from './registry'\nimport type { AttachmentModel, AttachmentModelRegistry, LaserRaycast } from './types'\n\nexport interface FitAttachmentOptions {\n /** The accessories of the game by id: where each gets its `model`, size and light or laser. */\n readonly catalogue: ReadonlyMap<string, AttachmentDef>\n /** Builders that replace or add to the ones the kit ships (see `ATTACHMENT_MODELS`). */\n readonly overrides?: AttachmentModelRegistry\n /** How far the laser beam goes, asked every frame. */\n readonly raycast?: LaserRaycast\n /** Asked every frame: false hides the models of the accessories the rig drew (the bench layer). */\n readonly isDrawn?: () => boolean\n /** Asked every frame: false puts the light and laser out whatever they are set to (the bench layer for the beams). */\n readonly areBeamsOn?: () => boolean\n /** The host's light budget: the weapon light is a source of it. Without it the light is a `SpotLight` of its own (deprecated, removed in the next major). */\n readonly lights?: LightBudget\n}\n\n/** The accessories drawn on one model: it follows the list of fitted parts. */\nexport interface AttachmentRig {\n /** Puts the models of what is fitted on the weapon and takes the others off: shows or hides what ships on it, switches the lights and lasers. */\n sync(fitted: readonly FittedAttachment[]): void\n /** Call every frame. */\n update(): void\n /** Ids of the accessories that have a model on the weapon now. */\n readonly drawn: readonly string[]\n dispose(): void\n}\n\ninterface Drawn {\n readonly model: AttachmentModel\n readonly mount: string\n}\n\nconst toModel = (made: AttachmentModel | THREE_NS.Object3D): AttachmentModel => ('object' in made ? made : { object: made })\n\n/** The factory flash hider sits where a muzzle device screws on: it is not drawn under one. */\nconst MUZZLE_DEFAULT = 'muzzle_default'\n\n/**\n * Draws the accessories of `fitted` on the model: the ones the builder drew with the weapon (`parts.fittings`) show or hide with the list, the others are built by the registry\n * (`overrides` over `ATTACHMENT_MODELS`) at the frame of their mount and hang from the wrapper (not from `inner`, whose stretch to the real length would stretch them).\n */\nexport function fitAttachmentModels(model: WeaponModel, fitted: readonly FittedAttachment[], kit: ModelKit, options: FitAttachmentOptions): AttachmentRig {\n const registry: AttachmentModelRegistry = { ...ATTACHMENT_MODELS, ...options.overrides }\n const { parts, root, inner } = model\n const factoryMagazine = parts.mag ? [...parts.mag.children] : []\n const muzzleRest = parts.muzzle ? parts.muzzle.position.x : 0\n const drawn = new Map<string, Drawn>()\n const hiddenBy = new Map<THREE_NS.Object3D, Set<string>>()\n const switchedOn = new Map<string, boolean>()\n\n const hide = (id: string, objects: readonly THREE_NS.Object3D[]): void => {\n for (const object of objects) {\n const owners = hiddenBy.get(object) ?? new Set<string>()\n owners.add(id)\n hiddenBy.set(object, owners)\n object.visible = false\n }\n }\n const unhide = (id: string, objects: readonly THREE_NS.Object3D[]): void => {\n for (const object of objects) {\n const owners = hiddenBy.get(object)\n owners?.delete(id)\n if (!owners || owners.size === 0) {\n hiddenBy.delete(object)\n object.visible = true\n }\n }\n }\n const take = (id: string): void => {\n const entry = drawn.get(id)\n if (!entry) return\n drawn.delete(id)\n switchedOn.delete(id)\n entry.model.object.removeFromParent()\n unhide(id, entry.model.hides ?? [])\n if (parts.uglMuzzle && entry.model.muzzle === parts.uglMuzzle) delete parts.uglMuzzle\n entry.model.dispose?.()\n }\n const place = (part: FittedAttachment, attachment: AttachmentDef): void => {\n const builder = registry[attachment.model] ?? registry[attachment.id]\n const frame = mountFrame(model, part.mount as Parameters<typeof mountFrame>[1])\n if (!builder || !frame) return\n const made = builder({ kit, model, attachment, fitted: part, frame, raycast: options.raycast, lights: options.lights, factoryMagazine, slide: parts.ugl })\n if (!made) return\n const entry = toModel(made)\n const parent = entry.hangsFrom === 'magazine' && parts.mag ? parts.mag : root\n if (parent === root) entry.object.position.set(...frame.position)\n parent.add(entry.object)\n hide(attachment.id, entry.hides ?? [])\n if (entry.muzzle) parts.uglMuzzle = entry.muzzle\n drawn.set(attachment.id, { model: entry, mount: part.mount })\n }\n\n const shine = (): void => {\n const isDrawn = options.isDrawn?.() ?? true\n const beams = options.areBeamsOn?.() ?? true\n for (const [id, entry] of drawn) {\n entry.model.object.visible = isDrawn\n entry.model.setOn?.(beams && switchedOn.get(id) === true)\n }\n }\n\n const sync = (list: readonly FittedAttachment[]): void => {\n const wanted = new Map(list.map((part) => [part.id, part]))\n for (const id of [...drawn.keys()]) if (!wanted.has(id) || drawn.get(id)?.mount !== wanted.get(id)?.mount) take(id)\n for (const [id, objects] of Object.entries(parts.fittings ?? {})) {\n if (id === MUZZLE_DEFAULT) continue\n for (const object of objects) object.visible = wanted.has(id)\n }\n for (const object of parts.fittings?.[MUZZLE_DEFAULT] ?? []) object.visible = !list.some((part) => part.mount === 'muzzle')\n for (const part of list) {\n const attachment = options.catalogue.get(part.id)\n if (!attachment || drawn.has(part.id) || parts.fittings?.[part.id]) continue\n if (part.integral === true && attachment.kind === 'optic') continue\n place(part, attachment)\n }\n for (const id of drawn.keys()) switchedOn.set(id, wanted.get(id)?.on === true)\n shine()\n if (parts.muzzle) parts.muzzle.position.x = muzzleRest + [...drawn.values()].reduce((sum, entry) => sum + (entry.model.muzzleOffset ?? 0), 0) / inner.scale.x\n }\n\n sync(fitted)\n return {\n sync,\n update() {\n shine()\n for (const entry of drawn.values()) entry.model.update?.()\n },\n get drawn() {\n return [...drawn.keys()]\n },\n dispose() {\n for (const id of [...drawn.keys()]) take(id)\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../types'\nimport { mountFrame } from './mount-frames'\n\nconst LAUNCHER_INTERFACES: ReadonlySet<string> = new Set(['m203', 'gp25', 'ag36'])\n\n/**\n * After the model is built: when the weapon has a place for a launcher under the barrel, adds the empty pivot `ugl` there. The reload clip slides it (the tube of the launcher is drawn\n * inside it when one is fitted); done after the build so that the model the golden hashes is the one the builder made.\n */\nexport function rigUnderbarrel(THREE: typeof THREE_NS, model: WeaponModel, def: Pick<WeaponDef, 'mounts'>): void {\n const place = def.mounts?.find((mount) => mount.kind === 'underbarrel' && mount.interfaces.some((name) => LAUNCHER_INTERFACES.has(name)))\n const frame = place ? mountFrame(model, 'underbarrel') : undefined\n if (!frame) return\n const pivot = new THREE.Group()\n pivot.name = 'ugl'\n pivot.position.set(...frame.position)\n model.root.add(pivot)\n model.parts.ugl = pivot\n}\n","import type * as THREE_NS from 'three'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from './types'\nimport type { StockMove } from './types'\n\nconst FOLD_AXIS_BY_SIDE: Readonly<Record<string, 'x' | 'y' | 'z'>> = { right: 'y', left: 'y', under: 'z', over: 'z' }\n\n/** Where the hinge of a folding stock sits: at the rear of the receiver, on the side the rule folds it to (z is to the right), under it or over it. */\nconst hingeOf = (model: WeaponModel, side: string): [number, number, number] => {\n const frames = model.parts.frames\n const x = frames?.receiverStart ?? 0\n const halfWidth = (frames?.receiverWidth ?? 0.034) / 2\n const halfHeight = (frames?.receiverHeight ?? 0.06) / 2\n if (side === 'right') return [x, 0, halfWidth]\n if (side === 'left') return [x, 0, -halfWidth]\n if (side === 'under') return [x, -halfHeight, 0]\n return [x, halfHeight, 0]\n}\n\n/**\n * After the model is built: puts the stock the builder drew into one pivot named `stock`, so that the clips can fold it (a half turn about the side of the rule's `foldAxis`)\n * or slide it in (`dimensions.length - lengthCollapsed`). Done after the build so that the model the golden hashes is the one the builder made. A weapon whose stock does not move is left alone.\n */\nexport function rigStock(THREE: typeof THREE_NS, model: WeaponModel, def: Pick<WeaponDef, 'stock' | 'dimensions'>): void {\n const stock = def.stock\n const meshes = model.parts.stockMeshes\n if (!stock || stock.kind === 'fixed' || stock.kind === 'none' || !meshes || meshes.length === 0) return\n const isFolding = stock.kind === 'fold' || stock.kind === 'fold_retract'\n const side = stock.foldAxis ?? 'right'\n const hinge = isFolding ? hingeOf(model, side) : ([0, 0, 0] as [number, number, number])\n const pivot = new THREE.Group()\n pivot.name = 'stock'\n pivot.position.set(...hinge)\n model.inner.add(pivot)\n model.inner.updateMatrixWorld(true)\n for (const mesh of meshes) pivot.attach(mesh)\n const dimensions = def.dimensions\n const travel = dimensions?.lengthCollapsed === undefined ? 0 : (dimensions.length - dimensions.lengthCollapsed) / model.inner.scale.x\n const move: StockMove = isFolding ? { kind: 'fold', axis: FOLD_AXIS_BY_SIDE[side] ?? 'y', travel } : { kind: 'retract', axis: 'x', travel }\n model.parts.stock = pivot\n model.parts.stockMove = move\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from './kit'\nimport type { WeaponModel } from './types'\n\ntype Substitution = ReadonlyMap<THREE_NS.Material, THREE_NS.Material>\n\n/** The paint of worn metal by the rule's condition id (`new` and `used` keep the factory finish): the page's `applyQuality`, with its four steps named like the rule's. */\nconst substitutions = (kit: ModelKit, condition: string): Substitution | null => {\n const { M } = kit\n if (condition === 'rusty')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.rust],\n [M.dark, M.rustD],\n [M.steel, M.rust],\n [M.steelL, M.rust],\n ])\n if (condition === 'worn')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.worn],\n [M.dark, M.worn],\n ])\n return null\n}\n\n/** Dresses the model for how worn the weapon is. The first call keeps the finish each mesh came with, so any condition can be put back. */\nexport function applyCondition(kit: ModelKit, model: WeaponModel, condition: string): void {\n const replacement = substitutions(kit, condition)\n const glowing = new Set<THREE_NS.Object3D>(model.parts.glow)\n const paint = condition === 'rusty' ? kit.M.rust.color : condition === 'worn' ? kit.M.worn.color : undefined\n model.root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh) return\n mesh.userData.baseMaterial ??= mesh.material\n const base = mesh.userData.baseMaterial as THREE_NS.Material\n if (glowing.has(mesh)) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n mesh.userData.baseColor ??= material.color.clone()\n material.color.copy(paint ?? (mesh.userData.baseColor as THREE_NS.Color))\n return\n }\n mesh.material = replacement?.get(base) ?? base\n })\n}\n","import { markKitOrigin } from '@adatechnology/game-contracts'\nimport type * as THREE from 'three'\nimport type { CaliberDef, CartridgeDims } from '@adatechnology/game-weapons'\nimport type { ModelKit } from './kit'\n\n/** The shapes the gallery draws: rimfire, straight rimless (`p`), straight rimmed (`rimp`), bottleneck rimless (`r`), bottleneck rimmed (`rr`) and shotgun shell. */\nexport type CartridgeShape = 'shell' | 'rim' | 'p' | 'rimp' | 'r' | 'rr'\n\n// a bottleneck case narrows to less than this fraction of its diameter at the bullet\nconst BOTTLENECK_RATIO = 0.8\n\n/** The gallery's cartridge type of a calibre, from its case type, rim and dimensions. */\nexport function cartridgeShape(caliber: Pick<CaliberDef, 'caseType' | 'rim'>, dims: CartridgeDims): CartridgeShape {\n if (caliber.caseType === 'shell' || caliber.rim === 'shell') return 'shell'\n if (caliber.rim === 'rimfire') return 'rim'\n const isRimmed = caliber.rim === 'rimmed'\n const isBottleneck = dims.projectileDiameter / dims.caseDiameter < BOTTLENECK_RATIO\n if (isBottleneck) return isRimmed ? 'rr' : 'r'\n return isRimmed ? 'rimp' : 'p'\n}\n\n/** Port of the gallery's `cartridge`: the round standing on its base, in millimetres (the gallery shows it enlarged), brass case and copper or lead bullet. */\nexport function buildCartridge(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): THREE.Group {\n const { M, cylinderY } = kit\n const group = markKitOrigin(kit.group(), { owner: 'game-weapons-three', kind: 'ammunition', id: shape })\n const radius = dims.caseDiameter / 2\n const bulletRadius = dims.projectileDiameter / 2\n const caseLength = dims.caseLength\n if (shape === 'shell') {\n cylinderY(group, radius, caseLength * 0.8, M.shell, 0, caseLength * 0.6, 0, 14)\n cylinderY(group, radius * 1.03, caseLength * 0.22, M.brass, 0, caseLength * 0.11, 0, 14)\n cylinderY(group, radius * 1.08, 1.2, M.brass, 0, 0.6, 0, 14)\n return group\n }\n if (shape === 'rim' || shape === 'rimp' || shape === 'rr') cylinderY(group, radius * 1.15, 1.2, M.brass, 0, 0.6, 0, 14)\n const extra = dims.overallLength - caseLength\n if (shape === 'r' || shape === 'rr') {\n const bodyHeight = caseLength * 0.78\n const shoulder = caseLength * 0.08\n const neck = caseLength - bodyHeight - shoulder\n const neckRadius = bulletRadius + 0.35\n cylinderY(group, radius, bodyHeight, M.brass, 0, bodyHeight / 2, 0, 14)\n cylinderY(group, neckRadius, shoulder, M.brass, 0, bodyHeight + shoulder / 2, 0, 14, radius)\n cylinderY(group, neckRadius, neck, M.brass, 0, bodyHeight + shoulder + neck / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.3, M.copper, 0, caseLength + extra * 0.15, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.7, M.copper, 0, caseLength + extra * 0.3 + extra * 0.35, 0, 14, bulletRadius * 0.12)\n return group\n }\n const bullet = shape === 'rim' || shape === 'rimp' ? M.lead : M.copper\n cylinderY(group, radius, caseLength, M.brass, 0, caseLength / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.45, bullet, 0, caseLength + extra * 0.225, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.55, bullet, 0, caseLength + extra * 0.45 + extra * 0.275, 0, 14, bulletRadius * 0.45)\n return group\n}\n\n/** An empty case in metres, lying along x with the base at the origin: the brass the weapon throws out. */\nexport function buildCasing(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number; length: number } {\n const { M, cylinderX } = kit\n const group = markKitOrigin(kit.group(), { owner: 'game-weapons-three', kind: 'ammunition', id: shape })\n const radius = dims.caseDiameter / 2000\n const length = dims.caseLength / 1000\n if (shape === 'shell') {\n const scale = length / 0.07\n cylinderX(group, 0.0105 * scale, 0.05 * scale, M.shell, 0.008 * scale, 0, 0, 14)\n cylinderX(group, 0.011 * scale, 0.016 * scale, M.brass, -0.025 * scale, 0, 0, 14)\n return { group, radius: 0.0105 * scale, length }\n }\n if (shape === 'r' || shape === 'rr') {\n cylinderX(group, radius, length * 0.75, M.brass, -length * 0.12, 0, 0, 12)\n cylinderX(group, radius * 0.62, length * 0.25, M.brass, length * 0.37, 0, 0, 12, radius * 0.55)\n } else cylinderX(group, radius, length, M.brass, 0, 0, 0, 12)\n return { group, radius, length }\n}\n\n/** A live round in metres, lying along x with the base at the origin: what is loaded into a weapon and what a clear throws out. */\nexport function buildRound(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number } {\n const group = markKitOrigin(kit.group(), { owner: 'game-weapons-three', kind: 'ammunition', id: shape })\n const cartridge = buildCartridge(kit, dims, shape)\n cartridge.scale.setScalar(0.001)\n cartridge.rotation.z = -Math.PI / 2\n group.add(cartridge)\n return { group, radius: dims.caseDiameter / 2000 }\n}\n","import type * as THREE_NS from 'three'\nimport type { EffectSink, Vec3 } from '@adatechnology/game-contracts'\nimport { MUZZLE_SMOKE } from '@adatechnology/game-weapons'\nimport type { MuzzleSmokeProfile } from '@adatechnology/game-weapons'\n\n/** Flash size by case: shells flash biggest, rimfire smallest (the page's `flashK`). */\nexport const FLASH_BY_CASE = { shell: 1.6, big: 2.6, tiny: 0.5, pistol: 0.8, rifle: 1.2 } as const\n\n/** The ids of the recipes of `@adatechnology/game-vfx` the weapon in the hands asks the host's effect sink for (`VIEWMODEL_EFFECTS`). */\nexport const VIEWMODEL_EFFECT_IDS = { flash: 'viewmodel_muzzle_flash', smoke: 'weapon_smoke_puff', backblast: 'launcher_backblast', flameJet: 'flame_jet' } as const\n\nexport interface Effects {\n /** The muzzle flash at `position` pointing along the barrel (x) of `orientation`, with the smoke profile of the shot. */\n muzzleFlash(position: THREE_NS.Vector3, orientation: THREE_NS.Quaternion, size: number, profile?: MuzzleSmokeProfile): void\n /** A puff that rises, grows and fades: the gallery's `smoke(position, velocity, size, life, opacity)`, with `size` its radius. */\n smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void\n /** A rocket leaving the tube: smoke and fire thrown back from `rear`, away from the barrel (x) of `orientation`. */\n backblast(rear: THREE_NS.Vector3, orientation: THREE_NS.Quaternion): void\n /** One frame of a flamethrower's jet from `muzzle` along the barrel (x) of `orientation`: fire thrown ahead and, half the frames, smoke. */\n flameJet(muzzle: THREE_NS.Vector3, orientation: THREE_NS.Quaternion, dt: number, scale: number): void\n}\n\nconst vec = (vector: THREE_NS.Vector3): Vec3 => [vector.x, vector.y, vector.z]\nconst quaternion = (q: THREE_NS.Quaternion): readonly [number, number, number, number] => [q.x, q.y, q.z, q.w]\n\n/**\n * The gallery's first-person effects (the muzzle flash, the puffs of smoke, the backblast and the flame jet) played through the host's effect sink, as recipes of the Workshop\n * (`game-vfx`) drawn as the gallery drew them (solids, not sprites), written in the weapon's own axes: each play gives the barrel's quaternion, pitch and roll included, and\n * the barrel in the world. Each play draws one seed from the viewmodel's stream, and the recipe draws its numbers from that seed in the order the gallery drew them, so the\n * scatter repeats with the viewmodel's seed. Without a sink nothing is shown.\n */\nexport function createEffects(THREE: typeof THREE_NS, sink: EffectSink | undefined, random: () => number): Effects {\n const seed = (): number => 1 + Math.floor(random() * 0x7ffffffe)\n const barrel = (orientation: THREE_NS.Quaternion): Vec3 => vec(new THREE.Vector3(1, 0, 0).applyQuaternion(orientation))\n return {\n muzzleFlash(position, orientation, size, profile = MUZZLE_SMOKE.smokeless) {\n if (profile.puffs <= 0 && profile.flash <= 0) return\n sink?.play({ effect: VIEWMODEL_EFFECT_IDS.flash, point: vec(position), direction: barrel(orientation), orientation: quaternion(orientation), seed: seed(), values: { size, ...profile } })\n },\n smoke(position, velocity, size, life, opacity) {\n sink?.play({ effect: VIEWMODEL_EFFECT_IDS.smoke, point: vec(position), seed: seed(), values: { vx: velocity.x, vy: velocity.y, vz: velocity.z, radius: size, life, opacity } })\n },\n backblast(rear, orientation) {\n sink?.play({ effect: VIEWMODEL_EFFECT_IDS.backblast, point: vec(rear), direction: barrel(orientation), orientation: quaternion(orientation), seed: seed() })\n },\n flameJet(muzzle, orientation, dt, scale) {\n sink?.play({ effect: VIEWMODEL_EFFECT_IDS.flameJet, point: vec(muzzle), direction: barrel(orientation), orientation: quaternion(orientation), seed: seed(), values: { dt, scale } })\n },\n }\n}\n","import type * as THREE_NS from 'three'\n\nimport type { HandAnchor } from './hand-hold'\n\n/**\n * Where a gun sits in the first-person view, at its real size and in the body's hands: held at the hip, the barrel parallel to the aim (its line runs into the crosshair), the grip low and to\n * the right of the eye, as far ahead as the right arm reaches in the view. In the eye's frame: x right, y up, -z ahead, metres. The sights stay below the crosshair; a long gun's stock is\n * beside the body, at the bottom right edge of the screen.\n */\nexport const VIEW_HOLD = {\n /** The right hand's grip, from the eye. */\n grip: [0.2, -0.2, -0.3],\n /** A handgun's grip: higher and nearer the middle, the arms out in front. */\n handgunGrip: [0.13, -0.15, -0.33],\n /** A rocket launcher's grip: its tube rides on the shoulder, so the hands are higher. */\n launcherGrip: [0.2, -0.14, -0.3],\n /** A gun with no grip anchor: the rear of its bore, from the eye. */\n rear: [0.2, -0.24, -0.12],\n} as const\n\nexport type ViewHoldPlacement = {\n readonly THREE: typeof THREE_NS\n /** The group the viewmodel moves; its `holder` child turns the model's barrel (x) down the aim (-z). */\n readonly hand: THREE_NS.Object3D\n readonly holder: THREE_NS.Object3D\n readonly camera: THREE_NS.Camera\n /** Where the right hand holds the gun (`Hold.right`); null puts the rear of the bore at `VIEW_HOLD.rear`. */\n readonly right: HandAnchor | null\n /** The rear end of the model along its barrel (model x), metres. */\n readonly rear: number\n /** How it is held: a pistol or a revolver with `handgunGrip`, a rocket launcher with `launcherGrip`, anything else with `grip`. */\n readonly kind: 'handgun' | 'launcher' | 'long'\n}\n\nconst scratch = { grip: null as THREE_NS.Vector3 | null }\n\n/** Puts the gun in the first-person view (`VIEW_HOLD`): the hand on the camera and turned with it, the holder shifted so the grip lands where the right hand reaches. */\nexport function placeInView(placement: ViewHoldPlacement): void {\n const { THREE, hand, holder, camera, right } = placement\n holder.scale.setScalar(1)\n hand.position.copy(camera.position)\n hand.quaternion.copy(camera.quaternion)\n hand.scale.setScalar(1)\n holder.position.set(0, 0, 0)\n hand.updateMatrixWorld(true)\n if (!right) {\n holder.position.set(VIEW_HOLD.rear[0], VIEW_HOLD.rear[1], VIEW_HOLD.rear[2] + placement.rear)\n hand.updateMatrixWorld(true)\n return\n }\n scratch.grip ??= new THREE.Vector3()\n const grip = hand.worldToLocal(right.part.localToWorld(scratch.grip.copy(right.offset)))\n const [x, y, z] = placement.kind === 'handgun' ? VIEW_HOLD.handgunGrip : placement.kind === 'launcher' ? VIEW_HOLD.launcherGrip : VIEW_HOLD.grip\n holder.position.set(x - grip.x, y - grip.y, z - grip.z)\n hand.updateMatrixWorld(true)\n}\n","import type * as THREE_NS from 'three'\nimport { LIGHT_PRIORITY, geometryKey, materialKey } from '@adatechnology/game-render-three'\nimport type { LightBudget, LightHandle, RenderPools } from '@adatechnology/game-render-three'\nimport { discardObject3D } from '@adatechnology/game-shapes-three'\nimport type { ModelKit } from '../models/kit'\nimport type { ModelParts } from '../models/types'\nimport { buildFlyingRocket } from '../models/launcher-rounds'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\n\n/** What the launchers' and flamethrowers' effects need from the viewmodel. */\nexport interface HeavyContext {\n kit: ModelKit\n scene: THREE_NS.Object3D\n particles: Particles\n effects: Effects\n random: () => number\n parts: ModelParts\n /** Weapon forward in the world, and the world position of a part. */\n forward(): THREE_NS.Vector3\n positionOf(part: THREE_NS.Object3D): THREE_NS.Vector3\n orientation(): THREE_NS.Quaternion\n /** Runs `step(progress)` every frame for `seconds`, then `done`. */\n every(seconds: number, step: (progress: number, dt: number) => void, done?: () => void): void\n groundAt(x: number, z: number): number\n /** The host's light budget: the rocket asks it for a light while it flies. */\n lights?: LightBudget\n /** The host's pools: the burning droplets and the ground flames take their geometry and material from them and give them back, so no program is freed and relinked. Without them each makes its own. */\n pools?: RenderPools\n /** Without a budget: a point light that stays in the scene for good (intensity 0 when idle): the light count is part of every lit material's program key. */\n rocketLight?: THREE_NS.PointLight\n}\n\nexport const ROCKET_LIGHT_NAME = 'rocket-light'\nconst ROCKET_LIGHT_COLOR = 0xff9a40\nconst ROCKET_LIGHT_INTENSITY = 3\nconst ROCKET_LIGHT_DISTANCE = 2.5\nconst DROPLET_SPHERE = [0.006, 6, 4] as const\nconst DROPLET_COLOR = 0xff7a22\nconst FLAME_CONE = [0.02, 0.07, 6] as const\n/** The first two of `flameMaterials`: the ones a ground flame uses. */\nconst FLAME_MATERIALS = [\n { color: 0xff7a22, transparent: true, opacity: 0.9, depthWrite: false },\n { color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false },\n] as const\n\nconst rocketsInFlight = new WeakMap<THREE_NS.PointLight, number>()\n\n/**\n * The light that follows rockets in flight, to be added to the scene once and never removed.\n * @deprecated Pass the host's `lights` (a LightBudget) so the rocket asks for a light while it flies; this one is a light of its own. Removed in the next major.\n */\nexport function createRocketLight(THREE: ModelKit['THREE']): THREE_NS.PointLight {\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget, removed in the next major\n const light = new THREE.PointLight(ROCKET_LIGHT_COLOR, 0, ROCKET_LIGHT_DISTANCE)\n light.name = ROCKET_LIGHT_NAME\n light.position.set(0, -50, 0)\n return light\n}\n\nconst flameMaterials = (kit: ModelKit): THREE_NS.MeshBasicMaterial[] => {\n const { THREE } = kit\n return [\n new THREE.MeshBasicMaterial({ color: 0xff7a22, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xc8361a, transparent: true, opacity: 0.8, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xfff0b0, transparent: true, opacity: 0.9, blending: THREE.AdditiveBlending, depthWrite: false }),\n ]\n}\n\n/** A rocket leaving the tube: backblast smoke and fire at the rear, then the round flying out along the barrel, gaining speed, with a trail. */\nexport function launchRocket(context: HeavyContext, flyRound = true): void {\n const { kit, scene, parts, random } = context\n const { THREE } = kit\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const rear = context.positionOf(parts.rear as THREE_NS.Object3D)\n context.effects.backblast(rear, context.orientation())\n if (!flyRound) {\n if (parts.round) parts.round.visible = false\n return\n }\n const rocket = parts.makeRound ? parts.makeRound() : buildFlyingRocket(kit, parts.launcherType)\n if (parts.round) parts.round.visible = false\n rocket.quaternion.copy(context.orientation())\n rocket.position.copy(muzzle)\n scene.add(rocket)\n const exhaust = new THREE.Mesh(new THREE.ConeGeometry(0.018, 0.12, 8, 1, true), new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }))\n exhaust.rotation.z = PI / 2\n exhaust.position.x = -0.08\n rocket.add(exhaust)\n const flame = context.lights?.acquire({ owner: 'weapons.rocket', priority: LIGHT_PRIORITY.rocket, urgent: true, color: ROCKET_LIGHT_COLOR, intensity: ROCKET_LIGHT_INTENSITY, distance: ROCKET_LIGHT_DISTANCE, position: [muzzle.x, muzzle.y, muzzle.z] })\n const light = context.rocketLight\n if (light) {\n light.intensity = ROCKET_LIGHT_INTENSITY\n rocketsInFlight.set(light, (rocketsInFlight.get(light) ?? 0) + 1)\n }\n context.every(\n 1.6,\n (progress, dt) => {\n const flight = progress * 1.6\n const distance = 1.2 * flight + (flight > 0.25 ? 9 * (flight - 0.25) ** 2 : 0)\n rocket.position.copy(muzzle).addScaledVector(forward, distance)\n rocket.rotation.x += 0.25 * dt * 60\n light?.position.copy(rocket.position)\n flame?.update({ position: [rocket.position.x, rocket.position.y, rocket.position.z] })\n exhaust.scale.set(1, 0.6 + random() * 0.8, 1)\n if (random() < 0.9) context.effects.smoke(rocket.position.clone().addScaledVector(forward, -0.12), new THREE.Vector3((random() - 0.5) * 0.1, 0.05, (random() - 0.5) * 0.1), 0.02 + random() * 0.015, 2.2, 0.5)\n },\n () => {\n // the rocket in flight is a model built for this shot: it frees its own geometry and materials when it is gone\n discardObject3D(rocket)\n exhaust.geometry.dispose()\n ;(exhaust.material as THREE_NS.Material).dispose()\n releaseLight(flame, light)\n },\n )\n}\n\nfunction releaseLight(flame: LightHandle | null | undefined, light: THREE_NS.PointLight | undefined): void {\n flame?.release({ fadeMs: 0 })\n if (!light) return\n const remaining = (rocketsInFlight.get(light) ?? 1) - 1\n rocketsInFlight.set(light, remaining)\n if (remaining > 0) return\n light.intensity = 0\n light.position.set(0, -50, 0)\n}\n\n/** A frame of flame from the nozzle: fire thrown forward and up and smoke downwind (the recipe `flame_jet` of the effect sink), and burning droplets that light the ground where they land. */\nexport function flameJet(context: HeavyContext, dt: number, scale: number): void {\n const { kit, particles, random, parts } = context\n const { THREE } = kit\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n context.effects.flameJet(muzzle, context.orientation(), dt, scale)\n if (random() < 0.18) {\n const pools = context.pools\n const geometry = pools?.geometries.acquire(geometryKey('sphere', DROPLET_SPHERE), () => new THREE.SphereGeometry(...DROPLET_SPHERE))\n const material = pools?.materials.acquire(materialKey('MeshBasicMaterial', { color: DROPLET_COLOR }), () => new THREE.MeshBasicMaterial({ color: DROPLET_COLOR }))\n const droplet = new THREE.Mesh(geometry ?? new THREE.SphereGeometry(...DROPLET_SPHERE), material ?? new THREE.MeshBasicMaterial({ color: DROPLET_COLOR }))\n droplet.position.copy(muzzle).addScaledVector(forward, 0.3 + random() * 0.5)\n const onRemove = pools && geometry && material ? () => { pools.geometries.release(geometry); pools.materials.release(material) } : undefined\n particles.spawn(droplet, forward.clone().multiplyScalar(1.2 * scale).add(new THREE.Vector3(0, 0.2, 0)), { life: 3, radius: 0.003, ownsGeometry: onRemove === undefined, ...(onRemove ? { onRemove } : {}), onGround: (position) => groundFire(context, position) })\n }\n}\n\n/** Three small flames where a burning droplet landed, flickering for four seconds and smoking. */\nfunction groundFire(context: HeavyContext, position: THREE_NS.Vector3): void {\n const { kit, scene, random, pools } = context\n const { THREE } = kit\n const fire = new THREE.Group()\n fire.position.set(position.x, context.groundAt(position.x, position.z) + 0.005, position.z)\n scene.add(fire)\n const materials = pools ? [] : flameMaterials(kit)\n const pooled: Array<{ geometry: THREE_NS.BufferGeometry; material: THREE_NS.Material }> = []\n const flames = [0, 1, 2].map((index) => {\n const own = pools ? undefined : (materials[index % 2] as THREE_NS.Material).clone()\n const part = pools ? pooledFlame(kit, pools, index) : undefined\n if (part) pooled.push(part)\n const flame = new THREE.Mesh(part?.geometry ?? new THREE.ConeGeometry(...FLAME_CONE), part?.material ?? own)\n flame.position.set((random() - 0.5) * 0.04, 0.035, (random() - 0.5) * 0.04)\n fire.add(flame)\n return flame\n })\n let clock = 0\n context.every(\n 4,\n (progress, dt) => {\n clock += dt\n flames.forEach((flame, index) => flame.scale.set(1 - progress * 0.7, (0.6 + Math.sin(clock * 20 + index * 2) * 0.35) * (1 - progress), 1 - progress * 0.7))\n if (random() < 0.08) context.effects.smoke(fire.position.clone().add(new THREE.Vector3(0, 0.08, 0)), new THREE.Vector3(0, 0.15, 0), 0.015, 1.2, 0.25)\n },\n () => {\n fire.removeFromParent()\n if (pools) {\n for (const { geometry, material } of pooled) {\n pools.geometries.release(geometry)\n pools.materials.release(material)\n }\n return\n }\n flames.forEach((flame) => {\n flame.geometry.dispose()\n ;(flame.material as THREE_NS.Material).dispose()\n })\n materials.forEach((material) => material.dispose())\n },\n )\n}\n\n/** The geometry and the material one ground flame shares with every other (the flame only changes its scale). */\nfunction pooledFlame(kit: ModelKit, pools: RenderPools, index: number): { geometry: THREE_NS.BufferGeometry; material: THREE_NS.Material } {\n const { THREE } = kit\n const geometry = pools.geometries.acquire(geometryKey('cone', FLAME_CONE), () => new THREE.ConeGeometry(...FLAME_CONE))\n const flame = FLAME_MATERIALS[index % 2] as (typeof FLAME_MATERIALS)[number]\n const material = pools.materials.acquire(materialKey('MeshBasicMaterial', flame), () => new THREE.MeshBasicMaterial(flame))\n return { geometry, material }\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\nexport type ParticleKind = 'casing' | 'magazine' | 'round' | 'other'\n\nexport interface ParticleOptions {\n kind?: ParticleKind\n /** Seconds before it is removed (default 2). */\n life?: number\n /** Gravity (default 9.8; negative lets smoke rise). */\n gravity?: number\n bounce?: number\n /** Fraction of the speed lost per second. */\n drag?: number\n /** Floor contact radius; negative: no contact (smoke, flames). */\n radius?: number\n spin?: THREE_NS.Vector3\n /** Opacity at birth: it fades to zero over its life. */\n fadeFrom?: number\n /** Growth per second as a fraction of the size. */\n grow?: number\n /** Called when it comes to rest on the floor. */\n onRest?: (object: THREE_NS.Object3D) => void\n /** Called instead of bouncing when it reaches the floor; the particle is removed. */\n onGround?: (position: THREE_NS.Vector3) => void\n /** The geometry of the object is its own (not shared with a model) and goes with it. */\n ownsGeometry?: boolean\n /** Called once when the particle leaves for good (life over, floor, too many): where an object that came from a pool gives its geometry and material back. */\n onRemove?: () => void\n}\n\ninterface Particle extends Required<Pick<ParticleOptions, 'life' | 'gravity' | 'bounce' | 'drag' | 'radius' | 'grow' | 'kind'>> {\n object: THREE_NS.Object3D\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n age: number\n resting: boolean\n fadeFrom: number | undefined\n onRest: ParticleOptions['onRest']\n onGround: ParticleOptions['onGround']\n ownsGeometry: boolean\n onRemove: ParticleOptions['onRemove']\n bounces: number\n}\n\nconst MAX_PARTICLES = 900\nconst FLOOR_FRICTION = 0.45\n\n/** The gallery's particles (casings, magazines, smoke, flames): thrown with a velocity and a spin, bouncing on the floor under them until they rest or die. */\nexport interface Particles {\n spawn(object: THREE_NS.Object3D, velocity: THREE_NS.Vector3, options?: ParticleOptions): void\n update(dt: number): void\n count(kind: ParticleKind): number\n /** Called when something bounces: `casing` or `magazine` (for the sound), with what hit, how fast (m/s, vertical) and which bounce (0 = first). */\n onBounce?: (kind: ParticleKind, hit?: { readonly object: THREE_NS.Object3D; readonly speed: number; readonly bounce: number }) => void\n dispose(): void\n}\n\nconst disposeOwned = (object: THREE_NS.Object3D): void => {\n object.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n}\n\n/** `limit`: the most bodies the host allows at once (its one budget); without it the own cap of 900 stands (no host lends one yet, so no warning). */\nexport function createParticles(THREE: Three, scene: THREE_NS.Object3D, groundAt: (x: number, z: number) => number, limit?: () => number | undefined): Particles {\n let list: Particle[] = []\n const remove = (particle: Particle): void => {\n particle.object.removeFromParent()\n if (particle.ownsGeometry) disposeOwned(particle.object)\n particle.onRemove?.()\n if (particle.fadeFrom !== undefined) ((particle.object as THREE_NS.Mesh).material as THREE_NS.Material).dispose()\n list = list.filter((other) => other !== particle)\n }\n const api: Particles = {\n spawn(object, velocity, options = {}) {\n scene.add(object)\n list.push({\n object,\n velocity,\n spin: options.spin ?? new THREE.Vector3(),\n age: 0,\n resting: false,\n life: options.life ?? 2,\n gravity: options.gravity ?? 9.8,\n bounce: options.bounce ?? 0.3,\n drag: options.drag ?? 0,\n radius: options.radius ?? 0.003,\n grow: options.grow ?? 0,\n kind: options.kind ?? 'other',\n fadeFrom: options.fadeFrom,\n onRest: options.onRest,\n onGround: options.onGround,\n ownsGeometry: options.ownsGeometry ?? false,\n onRemove: options.onRemove,\n bounces: 0,\n })\n const hostLimit = limit?.()\n const oldest = list[0]\n if (list.length > (hostLimit ?? MAX_PARTICLES) && oldest) remove(oldest)\n },\n update(dt) {\n for (const particle of [...list]) {\n particle.age += dt\n if (particle.age > particle.life) {\n remove(particle)\n continue\n }\n const { object } = particle\n if (particle.fadeFrom !== undefined) ((object as THREE_NS.Mesh).material as THREE_NS.Material).opacity = Math.max(0, particle.fadeFrom * (1 - particle.age / particle.life))\n if (particle.resting) continue\n particle.velocity.y -= particle.gravity * dt\n if (particle.drag) particle.velocity.multiplyScalar(Math.max(0, 1 - particle.drag * dt))\n object.position.addScaledVector(particle.velocity, dt)\n object.rotation.x += particle.spin.x * dt\n object.rotation.y += particle.spin.y * dt\n object.rotation.z += particle.spin.z * dt\n if (particle.grow) object.scale.multiplyScalar(1 + particle.grow * dt)\n if (particle.radius < 0) continue\n const floor = groundAt(object.position.x, object.position.z) + particle.radius\n if (object.position.y >= floor || particle.velocity.y >= 0) continue\n if (particle.onGround) {\n particle.onGround(object.position.clone())\n remove(particle)\n continue\n }\n object.position.y = floor\n const impact = Math.abs(particle.velocity.y)\n particle.velocity.y *= -particle.bounce\n particle.velocity.x *= FLOOR_FRICTION\n particle.velocity.z *= FLOOR_FRICTION\n particle.spin.multiplyScalar(FLOOR_FRICTION)\n if (particle.bounces < 4 && Math.abs(particle.velocity.y) >= 0.18) api.onBounce?.(particle.kind, { object, speed: impact, bounce: particle.bounces })\n particle.bounces++\n if (Math.abs(particle.velocity.y) < 0.18) {\n particle.resting = true\n particle.onRest?.(object)\n }\n }\n },\n count: (kind) => list.filter((particle) => particle.kind === kind).length,\n dispose() {\n for (const particle of [...list]) remove(particle)\n },\n }\n return api\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationPose, ToolRig } from '@adatechnology/game-contracts'\nimport { partRegistry } from '../models/part-registry'\nimport type { WeaponModel } from '../models'\n\n/** The rig of a model: clip poses are offsets from the rest the parts had when the rig was made, as the contract says. */\nexport function createModelRig(model: WeaponModel): ToolRig {\n const registry = partRegistry(model.parts)\n const rest = new Map<THREE_NS.Object3D, { position: THREE_NS.Vector3; rotation: THREE_NS.Euler }>()\n for (const part of [...registry.values(), model.root]) rest.set(part, { position: part.position.clone(), rotation: part.rotation.clone() })\n const apply = (object: THREE_NS.Object3D, pose: AnimationPose): void => {\n const base = rest.get(object)\n if (!base) return\n const [dx, dy, dz] = pose.position ?? [0, 0, 0]\n const [rx, ry, rz] = pose.rotation ?? [0, 0, 0]\n object.position.set(base.position.x + dx, base.position.y + dy, base.position.z + dz)\n object.rotation.set(base.rotation.x + rx, base.rotation.y + ry, base.rotation.z + rz)\n }\n return {\n setPartPose(partId, pose) {\n const part = registry.get(partId)\n if (part) apply(part, pose)\n },\n setRootPose: (pose) => apply(model.root, pose),\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { CaliberDef, CartridgeDims, CaseType, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../models'\nimport type { CartridgeShape } from '../models/cartridge'\nimport type { AttachmentRig } from '../models/attachments/fit'\nimport type { ModelKit } from '../models/kit'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\nimport type { WeaponAudio } from '../audio'\nimport type { SoundProfile } from '../audio/reload-sounds'\nimport type { FxLayers } from './layers'\n\n/** What the viewmodel shares with the handlers of the clip events. */\nexport interface FxWorld {\n readonly kit: ModelKit\n readonly scene: THREE_NS.Object3D\n readonly particles: Particles\n readonly effects: Effects\n readonly random: () => number\n readonly audio: WeaponAudio | null\n readonly layers: FxLayers\n groundAt(x: number, z: number): number\n /** A sound cue of a clip: the audio plays it (when there is one) and the host is told. */\n /** A reload cue; `lead`: how early the clip fired it (seconds before the part reaches its stop). */\n sound(weapon: string, cue: string, profile: SoundProfile, lead?: number): void\n /** Runs `step(e)` for `seconds` from `delay` seconds on, with `e` the eased progress, then `done`. */\n schedule(delay: number, seconds: number, step: (eased: number) => void, done?: () => void): void\n}\n\n/** The weapon in the hands: the model, how it is held and what its calibre makes (the case and the round, in metres). */\nexport interface Session {\n readonly id: string\n readonly def: WeaponDef\n readonly caliber: CaliberDef | undefined\n readonly model: WeaponModel\n /** How much the model is scaled down to sit in the hands. */\n /** The size the model is drawn at: smaller than real in front of the eye, 1 on the body. */\n holderScale: number\n readonly lengthMetres: number\n readonly caseType: CaseType\n /** How the weapon sounds: the weight of its metal and what it is made of. */\n readonly soundProfile: SoundProfile\n readonly kit: ModelKit\n readonly cartridge: { dims: CartridgeDims; shape: CartridgeShape; caseType?: string } | null\n stuckCase: THREE_NS.Object3D | null\n nextChamber: number\n /** The accessories drawn on the model, and what was fitted when they were last synced (to see a change). */\n attachments: AttachmentRig | null\n attachmentsSignature: string\n /** Whether a suppressor is fitted for the current shot. */\n suppressed: boolean\n}\n\n/** World position of a part of the model. */\nexport const worldPositionOf = (session: Session, part: THREE_NS.Object3D, out: THREE_NS.Vector3): THREE_NS.Vector3 => {\n session.model.root.updateWorldMatrix(true, true)\n return part.getWorldPosition(out)\n}\n\n/** A direction or offset written in the weapon's own axes (x along the barrel, y up, z to the right) in the world; `scaled` follows the model's size. */\nexport const toWorld = (session: Session, vector: THREE_NS.Vector3, scaled = false): THREE_NS.Vector3 => {\n const quaternion = session.model.root.getWorldQuaternion(new session.kit.THREE.Quaternion())\n const world = vector.clone().applyQuaternion(quaternion)\n return scaled ? world.multiplyScalar(session.holderScale) : world\n}\n","import { discardObject3D } from '@adatechnology/game-shapes-three'\nimport type * as THREE_NS from 'three'\nimport type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { muzzleSmokeOf } from '@adatechnology/game-weapons'\nimport { buildCasing, buildRound } from '../models/cartridge'\nimport { FLASH_BY_CASE } from './effects'\nimport { toWorld, worldPositionOf } from './session'\nimport type { FxWorld, Session } from './session'\n\nconst PI = Math.PI\n// the flash of a 40 mm launcher, a little under the one of a rocket tube\nconst UGL_FLASH = 1.6\n\nconst restFlat = (object: THREE_NS.Object3D): void => {\n object.rotation.x = 0\n object.rotation.z = 0\n}\n\n/** The handlers of the events a clip carries (`muzzle_flash`, `eject_casing`, `drop_magazine`, `move_in`...): the effects the page spawns around the moving parts. */\nexport function createClipEventHandler(world: FxWorld, session: Session): (event: AnimationEventSpec) => void {\n const { kit, particles, effects, random } = world\n const { THREE } = kit\n const { parts, root } = session.model\n const vector = (x: number, y: number, z: number): THREE_NS.Vector3 => new THREE.Vector3(x, y, z)\n const positionOf = (part: THREE_NS.Object3D): THREE_NS.Vector3 => worldPositionOf(session, part, new THREE.Vector3())\n const reach = Math.max(0.55, Math.min(1.2, session.lengthMetres))\n\n const throwCase = (mark: THREE_NS.Object3D, velocity: THREE_NS.Vector3, spin: THREE_NS.Vector3, tilt = 0): void => {\n if (!session.cartridge || !world.layers.casings) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n casing.group.position.copy(positionOf(mark))\n casing.group.rotation.set(0, random() * 0.6 - 0.3, tilt)\n if (session.cartridge.caseType) casing.group.userData['caseType'] = session.cartridge.caseType\n particles.spawn(casing.group, velocity, { kind: 'casing', life: 25, radius: casing.radius, bounce: 0.35, spin, onRest: restFlat, ownsGeometry: true })\n }\n\n const ejectFromPort = (down: boolean): void => {\n if (!parts.eject) return\n const local = down ? vector((random() - 0.5) * 0.3, -0.4, (random() - 0.5) * 0.3) : vector(-0.2 - random() * 0.4, (0.9 + random() * 0.5) * reach, (1 + random() * 0.6) * reach)\n throwCase(parts.eject, toWorld(session, local), vector(random() * 30, random() * 30, random() * 30))\n }\n\n const ejectAll = (marks: THREE_NS.Object3D[] | undefined, spent: (index: number) => { velocity: THREE_NS.Vector3; spin: THREE_NS.Vector3; tilt: number }): void => {\n marks?.forEach((mark, index) => {\n const { velocity, spin, tilt } = spent(index)\n throwCase(mark, toWorld(session, velocity), spin, tilt)\n })\n }\n\n /** A round slides from `from` to `to` (world points) in a quarter of a second, in the weapon's own space so that it follows the weapon. */\n const moveIn = (from: THREE_NS.Vector3, to: THREE_NS.Vector3, tilt: number): void => {\n if (!session.cartridge) return\n const { group } = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n const start = root.worldToLocal(from.clone())\n const end = root.worldToLocal(to.clone())\n group.rotation.z = tilt\n group.position.copy(start)\n root.add(group)\n world.schedule(0, 0.24, (eased) => group.position.lerpVectors(start, end, eased), () => {\n group.removeFromParent()\n group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n })\n }\n\n const offsetFrom = (point: THREE_NS.Vector3, x: number, y: number, z: number): THREE_NS.Vector3 => point.clone().add(toWorld(session, vector(x, y, z), true))\n\n const feedRound = (from: string, next: boolean): void => {\n if (from === 'loadPort' && parts.loadPort) {\n const port = positionOf(parts.loadPort)\n moveIn(offsetFrom(port, -0.03, -0.08, 0.07), port, 0.25)\n } else if (from === 'topLoad' && parts.topLoad) {\n const point = positionOf(parts.topLoad)\n moveIn(offsetFrom(point, 0, 0.07, 0), point, 0)\n } else if (from === 'chambers' && parts.chambers) {\n const marks = next ? [parts.chambers[session.nextChamber++ % parts.chambers.length]] : parts.chambers\n for (const mark of marks) {\n if (!mark) continue\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.07, 0, 0), offsetFrom(point, 0.006, 0, 0), 0)\n }\n } else if (from === 'breech' && parts.breech) {\n for (const mark of parts.breech) {\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.09, 0.05, 0), offsetFrom(point, 0.02, -0.01, 0), -0.5)\n }\n }\n }\n\n const dropMagazine = (up: boolean): void => {\n if (!parts.mag || !world.layers.magazines) return\n root.updateWorldMatrix(true, true)\n const copy = parts.mag.clone(true)\n parts.mag.matrixWorld.decompose(copy.position, copy.quaternion, copy.scale)\n particles.spawn(copy, toWorld(session, vector(up ? -0.25 : 0.05, up ? 0.9 : -0.3, 0.18)), { kind: 'magazine', life: 25, radius: 0.014, bounce: 0.15, spin: vector(1.5, 0.5, 2.5), onRest: (object) => object.rotation.set(0, object.rotation.y, PI / 2) })\n }\n\n const stuckCase = (): void => {\n if (!session.cartridge || !parts.eject) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n const at = root.worldToLocal(offsetFrom(positionOf(parts.eject), 0, casing.length * 0.35, 0))\n casing.group.position.copy(at)\n casing.group.rotation.set(0, 0, PI / 2 - 0.25)\n root.add(casing.group)\n session.stuckCase = casing.group\n }\n\n const flyJam = (jam: string): void => {\n const stuck = session.stuckCase\n session.stuckCase = null\n if (stuck) {\n root.updateWorldMatrix(true, true)\n stuck.updateWorldMatrix(true, false)\n stuck.matrixWorld.decompose(stuck.position, stuck.quaternion, stuck.scale)\n particles.spawn(stuck, toWorld(session, vector(-0.2, 1.2, 1.3)), { kind: 'casing', life: 25, radius: 0.006, bounce: 0.3, spin: vector(9, 14, 7), onRest: restFlat, ownsGeometry: true })\n } else if (jam === 'misfire' && session.cartridge && parts.eject) {\n const round = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n round.group.position.copy(positionOf(parts.eject))\n particles.spawn(round.group, toWorld(session, vector(-0.2, 1.1, 1.2)), { kind: 'round', life: 25, radius: round.radius, bounce: 0.3, spin: vector(8, 12, 6), onRest: restFlat, ownsGeometry: true })\n } else ejectFromPort(false)\n }\n\n return (event) => {\n const data = event.data ?? {}\n switch (event.type) {\n case 'muzzle_flash':\n if (data.at === 'ugl') {\n if (parts.uglMuzzle && world.layers.muzzleFlash) effects.muzzleFlash(positionOf(parts.uglMuzzle), root.getWorldQuaternion(new THREE.Quaternion()), UGL_FLASH)\n } else if (parts.muzzle && world.layers.muzzleFlash && (session.def.action.kind === 'firearm' || session.def.action.kind === 'launcher')) {\n const profile = muzzleSmokeOf({ caliber: session.caliber, weapon: session.def, suppressed: session.suppressed })\n const size = session.def.action.kind === 'launcher' ? 2.2 : FLASH_BY_CASE[session.caseType]\n effects.muzzleFlash(positionOf(parts.muzzle), root.getWorldQuaternion(new THREE.Quaternion()), size, profile)\n }\n break\n case 'eject_casing':\n if (data.from === 'chambers') ejectAll(parts.chambers, () => ({ velocity: vector(-0.5 - random() * 0.3, -0.1 + random() * 0.3, (random() - 0.5) * 0.25), spin: vector(10, 20, 5), tilt: 0 }))\n else if (data.from === 'breech') ejectAll(parts.breech, () => ({ velocity: vector(-1, 0.9, (random() - 0.5) * 0.2), spin: vector(3, 8, 12), tilt: -0.5 }))\n else ejectFromPort(data.down === true)\n break\n case 'drop_magazine':\n dropMagazine(data.up === true)\n break\n case 'move_in':\n feedRound(String(data.from), data.next === true)\n break\n case 'stuck_case':\n stuckCase()\n break\n case 'fly_jam':\n flyJam(String(data.jam))\n break\n case 'show_round':\n if (parts.round) parts.round.visible = true\n break\n case 'drop_tube':\n dropTube()\n break\n case 'seat_tube':\n root.visible = true\n break\n case 'breech_round':\n breechRound()\n break\n case 'sound':\n world.sound(session.id, String(data.id), session.soundProfile, typeof data.lead === 'number' ? data.lead : undefined)\n break\n default:\n break\n }\n }\n\n function dropTube(): void {\n root.updateWorldMatrix(true, true)\n const old = root.clone(true)\n root.matrixWorld.decompose(old.position, old.quaternion, old.scale)\n root.visible = false\n particles.spawn(old, toWorld(session, vector(0.2, 0.4, 0.6)), { life: 8, radius: 0.05, bounce: 0.2, spin: vector(0, 0.8, 2.5) })\n }\n\n function breechRound(): void {\n const make = parts.makeRound\n if (!make) return\n const shell = make()\n session.model.inner.add(shell)\n shell.position.set(-0.25, 0, 0)\n world.schedule(0.02, 0.4, (eased) => (shell.position.x = -0.25 + 0.6 * eased), () => {\n discardObject3D(shell)\n })\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { sampleClip } from '@adatechnology/game-contracts'\nimport type { WeaponModel } from '../models'\nimport data from '../data/hand-work.json'\nimport { HAND_HOLD, handFrame } from './hand-hold'\nimport type { HandAnchor } from './hand-hold'\n\ntype Three = typeof THREE_NS\n\n/** One thing a hand does to a part of a weapon while a clip of the weapon moves it (`data/hand-work.json`). */\nexport interface HandWork {\n hand: 'R' | 'L'\n anchor: HandAnchor\n /** The part whose motion in the clip is the work, or null for work that lasts the whole clip. */\n part: string | null\n clips: readonly string[]\n /** Pauses between two moves of the part shorter than this fraction of the clip do not let go. */\n merge: number\n /** The anchor follows the part it names. */\n id: string\n /** Fractions of the clip the hand takes to arrive and to leave, when this work asks for other than the data's `timing`. */\n lead?: number\n tail?: number\n}\n\nconst V = (THREE: Three, x: number, y: number, z: number): THREE_NS.Vector3 => new THREE.Vector3(x, y, z)\n\n/** The part's box in the space of the model root (x forward, y up, z to the right). */\nconst boxIn = (THREE: Three, root: THREE_NS.Object3D, part: THREE_NS.Object3D): THREE_NS.Box3 => {\n const world = new THREE.Box3().setFromObject(part)\n const box = new THREE.Box3()\n for (const x of [world.min.x, world.max.x]) for (const y of [world.min.y, world.max.y]) for (const z of [world.min.z, world.max.z]) box.expandByPoint(root.worldToLocal(V(THREE, x, y, z)))\n return box\n}\n\n/** Where the model's grip hand rests, so a thumb can reach from it. */\ntype Anchors = (kind: string, partId: string | null) => HandAnchor | null\n\nconst anchorsOf = (THREE: Three, model: WeaponModel, right: HandAnchor | null): Anchors => {\n const { root, parts } = model\n root.updateWorldMatrix(true, true)\n const palm = HAND_HOLD.palm\n const anchorAt = (part: THREE_NS.Object3D, at: THREE_NS.Vector3, quaternion: THREE_NS.Quaternion): HandAnchor => ({ part, offset: part.worldToLocal(root.localToWorld(at.clone())), quaternion })\n return (kind, partId) => {\n const part = partId ? ((parts as unknown as Record<string, THREE_NS.Object3D | undefined>)[partId] ?? null) : null\n if (kind === 'loading_port') {\n const port = parts.loadPort\n if (!port) return null\n const at = root.worldToLocal(port.getWorldPosition(V(THREE, 0, 0, 0))).add(V(THREE, 0, -palm - 0.004, 0))\n return anchorAt(port, at, handFrame(THREE, V(THREE, 0, 0, -1), V(THREE, 0, -1, 0)))\n }\n if (kind === 'thumb_release') {\n if (!right || !parts.slide) return null\n return { part: right.part, offset: right.offset.clone().add(V(THREE, 0, 0.012, 0)), quaternion: right.quaternion }\n }\n if (kind === 'thumb_safety') {\n // the shooting hand stays on the grip and slides up toward the lever, as far as a thumb reaches; with no lever drawn, up the grip\n if (!right) return null\n const toward = parts.safety ? right.part.worldToLocal(parts.safety.getWorldPosition(V(THREE, 0, 0, 0))).sub(right.offset) : V(THREE, 0, HAND_HOLD.thumbReach, 0)\n return { part: right.part, offset: right.offset.clone().add(toward.clampLength(0, HAND_HOLD.thumbReach)), quaternion: right.quaternion }\n }\n if (kind === 'lever_right') {\n // the big lever on the right of an AK-style receiver, over the trigger: the support hand reaches over the top and pushes it\n const receiver = parts.bolt ?? parts.boltHandle\n if (!receiver) return null\n const b = boxIn(THREE, root, receiver)\n const x = parts.trigger ? root.worldToLocal(parts.trigger.getWorldPosition(V(THREE, 0, 0, 0))).x : b.min.x\n return anchorAt(receiver, V(THREE, x, b.getCenter(V(THREE, 0, 0, 0)).y, b.max.z + palm), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 0, 1)))\n }\n if (!part) return null\n const b = boxIn(THREE, root, part)\n const c = b.getCenter(V(THREE, 0, 0, 0))\n switch (kind) {\n case 'slide_rear': // the support hand pinches the rear of the slide from the left, the palm toward it\n return anchorAt(part, V(THREE, b.min.x + 0.014, b.max.y - 0.006, b.min.z - palm), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 0, -1)))\n case 'rear_top': // the charging handle at the rear top of the receiver, taken from above\n return anchorAt(part, V(THREE, b.min.x + 0.016, b.max.y + palm, c.z), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 1, 0)))\n case 'side_right': // the bolt handle on the right of the receiver, reached over the top, the palm toward the gun\n return anchorAt(part, V(THREE, c.x, c.y, b.max.z + palm), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 0, 1)))\n case 'top_handle': // the knob of a bolt, held from the right\n return anchorAt(part, V(THREE, c.x, c.y, b.max.z + palm), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 0, 1)))\n case 'cover_top':\n return anchorAt(part, V(THREE, c.x, b.max.y + palm, c.z), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 1, 0)))\n case 'cylinder_side': // the crane swings out to the left, the support hand pushes it and holds it\n return anchorAt(part, V(THREE, c.x, c.y, b.min.z - palm), handFrame(THREE, V(THREE, 1, 0, 0), V(THREE, 0, 0, -1)))\n default:\n return null\n }\n }\n}\n\nconst releasePistols = new Set<string>(data.pistolRelease.weapons)\nconst akCharge = new Set<string>(data.akCharge.weapons)\n\n/** The work the hands do on this weapon (the entries of `data/hand-work.json` for its family and style that find their part). */\nexport function handWorkOf(THREE: Three, model: WeaponModel, weaponId: string, right: HandAnchor | null): HandWork[] {\n const family = model.parts.family\n const anchors = anchorsOf(THREE, model, right)\n const style = family === 'pistol' ? (releasePistols.has(weaponId) ? 'release' : 'rack') : akCharge.has(weaponId) ? 'ak' : 'ar'\n const out: HandWork[] = []\n for (const entry of data.works as ReadonlyArray<{ family: string; clips: string[]; part?: string; hand: 'R' | 'L'; anchor: string; style?: string; merge?: number; whole?: boolean; lead?: number; tail?: number }>) {\n if (entry.family !== family || (entry.style && entry.style !== style)) continue\n const anchor = anchors(entry.anchor, entry.part ?? null)\n if (!anchor) continue\n out.push({ hand: entry.hand, anchor, part: entry.whole ? null : (entry.part ?? null), clips: entry.clips, merge: entry.merge ?? 0, id: entry.anchor, ...(entry.lead === undefined ? {} : { lead: entry.lead }), ...(entry.tail === undefined ? {} : { tail: entry.tail }) })\n }\n return out\n}\n\nconst segmentsCache = new WeakMap<AnimationClipSpec, Map<string, Array<[number, number]>>>()\n\n/** The spans of the clip (seconds) in which `part` moves, with the pauses shorter than `merge` (a fraction of the clip) closed. */\nexport const motionOf = (clip: AnimationClipSpec, part: string, merge: number): Array<[number, number]> => {\n const cache = segmentsCache.get(clip) ?? new Map<string, Array<[number, number]>>()\n segmentsCache.set(clip, cache)\n const key = `${part}|${merge}`\n const found = cache.get(key)\n if (found) return found\n const steps = 240\n const dt = clip.duration / steps\n const spans: Array<[number, number]> = []\n let start: number | null = null\n for (let i = 1; i <= steps; i++) {\n const a = sampleClip(clip, part, (i - 1) * dt)\n const b = sampleClip(clip, part, i * dt)\n const moving = [0, 1, 2].some((axis) => Math.abs(b.position[axis]! - a.position[axis]!) > 1e-6 || Math.abs(b.rotation[axis]! - a.rotation[axis]!) > 1e-6)\n if (moving && start === null) start = (i - 1) * dt\n if (!moving && start !== null) {\n spans.push([start, (i - 1) * dt])\n start = null\n }\n }\n if (start !== null) spans.push([start, clip.duration])\n const joined: Array<[number, number]> = []\n for (const span of spans) {\n const last = joined[joined.length - 1]\n if (last && span[0] - last[1] <= merge * clip.duration) last[1] = span[1]\n else joined.push([span[0], span[1]])\n }\n cache.set(key, joined)\n return joined\n}\n\nconst smooth = (x: number): number => {\n const k = Math.min(1, Math.max(0, x))\n return k * k * (3 - 2 * k)\n}\n\n/** How much each piece of work holds its hand now (0..1), from the clips that are running. */\nexport function workWeights(works: readonly HandWork[], running: ReadonlyArray<{ name: string; time: number; clip: AnimationClipSpec }>): number[] {\n return works.map((work) => {\n const lead = work.lead ?? data.timing.lead\n const tail = work.tail ?? data.timing.tail\n let best = 0\n for (const { name, time, clip } of running) {\n if (!work.clips.includes(name)) continue\n const spans: Array<[number, number]> = work.part ? motionOf(clip, work.part, work.merge) : [[0, clip.duration]]\n for (const [from, to] of spans) {\n const before = lead * clip.duration\n const after = tail * clip.duration\n const w = work.part ? smooth((time - (from - before)) / before) * smooth(((to + after) - time) / after) : smooth(time / before) * smooth((clip.duration - time) / after)\n best = Math.max(best, w)\n }\n }\n return best\n })\n}\n","{\n \"source\": \"Authored in the kit: the gallery's clips move the parts (slide, bolt, bolt handle, crane, cover) but the Galeria 3D do Arsenal draws no hands, so which hand works which part is written here. Times are not here: a hand takes a part while the clip of the weapon moves it, so they follow the clip and the seconds of the rule's reload.\",\n \"timing\": {\n \"lead\": 0.08,\n \"tail\": 0.06,\n \"comment\": \"fractions of the clip's duration: the hand arrives this long before the part starts to move and lets go this long after it stops\"\n },\n \"pistolRelease\": {\n \"comment\": \"Pistols whose slide stop is worked with the thumb of the shooting hand after the magazine is in. Empty by default: every pistol is racked by the support hand taking the rear of the slide (the reading shot of the move). Put an id here only for a pistol that is meant to be released by the thumb.\",\n \"weapons\": []\n },\n \"akCharge\": {\n \"comment\": \"Guns charged by a handle on the right of the receiver, reached over the top by the support hand; the rest of the magazine guns are charged at the rear top (AR style).\",\n \"weapons\": [\n \"ak_47\",\n \"akm\",\n \"ak_74\",\n \"ak_12\",\n \"rpk\",\n \"saiga_12\",\n \"sks\",\n \"m14_ebr\",\n \"fn_fal\",\n \"fn_parafal\",\n \"hk_g3a3\",\n \"hk_psg_1\",\n \"svd_dragunov\"\n ]\n },\n \"works\": [\n {\n \"family\": \"pistol\",\n \"clips\": [\n \"reload_empty\"\n ],\n \"part\": \"slide\",\n \"hand\": \"L\",\n \"anchor\": \"slide_rear\",\n \"style\": \"rack\"\n },\n {\n \"family\": \"pistol\",\n \"clips\": [\n \"reload_empty\"\n ],\n \"part\": \"slide\",\n \"hand\": \"R\",\n \"anchor\": \"thumb_release\",\n \"style\": \"release\"\n },\n {\n \"family\": \"rifle\",\n \"clips\": [\n \"reload_empty\"\n ],\n \"part\": \"bolt\",\n \"hand\": \"L\",\n \"anchor\": \"rear_top\",\n \"style\": \"ar\"\n },\n {\n \"family\": \"rifle\",\n \"clips\": [\n \"reload_empty\"\n ],\n \"part\": \"bolt\",\n \"hand\": \"L\",\n \"anchor\": \"side_right\",\n \"style\": \"ak\"\n },\n {\n \"family\": \"p90\",\n \"clips\": [\n \"reload_empty\"\n ],\n \"part\": \"bolt\",\n \"hand\": \"L\",\n \"anchor\": \"rear_top\",\n \"style\": \"ar\"\n },\n {\n \"family\": \"belt\",\n \"clips\": [\n \"reload\"\n ],\n \"part\": \"cover\",\n \"hand\": \"L\",\n \"anchor\": \"cover_top\",\n \"merge\": 1\n },\n {\n \"family\": \"boltmag\",\n \"clips\": [\n \"reload\",\n \"reload_empty\",\n \"reload_one_by_one\",\n \"cycle\"\n ],\n \"part\": \"boltHandle\",\n \"hand\": \"R\",\n \"anchor\": \"top_handle\"\n },\n {\n \"family\": \"bolt\",\n \"clips\": [\n \"reload\",\n \"reload_empty\",\n \"reload_one_by_one\",\n \"feed\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"loading_port\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"bolt\",\n \"clips\": [\n \"reload\",\n \"reload_empty\",\n \"reload_one_by_one\",\n \"cycle\"\n ],\n \"part\": \"boltHandle\",\n \"hand\": \"R\",\n \"anchor\": \"top_handle\"\n },\n {\n \"family\": \"pump\",\n \"clips\": [\n \"feed\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"loading_port\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"semi12\",\n \"clips\": [\n \"feed\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"loading_port\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"semiint\",\n \"clips\": [\n \"reload\",\n \"reload_empty\",\n \"reload_one_by_one\",\n \"feed\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"loading_port\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"lever\",\n \"clips\": [\n \"feed\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"loading_port\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"revolver\",\n \"clips\": [\n \"reload\",\n \"reload_one_by_one\"\n ],\n \"part\": \"crane\",\n \"hand\": \"L\",\n \"anchor\": \"cylinder_side\",\n \"merge\": 1\n },\n {\n \"family\": \"pistol\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"revolver\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"rifle\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3,\n \"style\": \"ar\"\n },\n {\n \"family\": \"p90\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"pump\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"semi12\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"semiint\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"break\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"bolt\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"boltmag\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"lever\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"belt\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"R\",\n \"anchor\": \"thumb_safety\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n },\n {\n \"family\": \"rifle\",\n \"clips\": [\n \"safety_on\",\n \"safety_off\"\n ],\n \"hand\": \"L\",\n \"anchor\": \"lever_right\",\n \"style\": \"ak\",\n \"whole\": true,\n \"lead\": 0.3,\n \"tail\": 0.3\n }\n ],\n \"safety\": {\n \"comment\": \"Safety on and off (B): the shooting hand slides up its grip so the thumb flicks the lever while the clip cants the weapon; an AK-style rifle (akCharge) has its big lever on the right, pushed by the support hand over the top.\"\n }\n}\n","import type { HandTargets, HostEvent, HostTool, MuzzlePose } from '@adatechnology/game-contracts'\nimport { createBoxFx } from './box-fx'\nimport type { WeaponFxOptions } from './box-fx'\nimport { hasWeaponModel } from './models'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport { createViewmodel } from './fx/viewmodel'\n\nexport type { WeaponFxOptions } from './box-fx'\nexport type { FxLayers } from './fx/layers'\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface WeaponFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Dresses the weapon for its wear (`new`, `used`, `worn`, `rusty`); the gallery models show it in their metal. */\n setCondition(condition: string): void\n /** Where the hands take the weapon (world space, read every frame after `update`): the grip and the forend of the model, or the handle of the generic prop; null with nothing in the hands. */\n handTargets(): HandTargets | null\n /** The muzzle of the weapon in the hands as drawn now (world space): the gallery model's mark, or the front of the generic prop; null for a tool that fires no shot. */\n muzzle(): MuzzlePose | null\n /** What is drawn (casings, magazines, muzzle flash): change a field and the next event follows it. */\n readonly layers: FxLayers\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** The clips of the model playing now with the seconds each lasts (scaled to the rule's duration): which reload variant went (`reload` or `reload_empty`...). */\n readonly clips: ReadonlyArray<{ name: string; seconds: number }>\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/**\n * The presentation of the tool in the hands. The weapons the gallery drew (`MODEL_ENTRIES`) get their model and the clips the rule's events call for\n * (fire, cycle, jam, clear, safety, the seven reloads); the generic archetypes keep their low-poly prop.\n */\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const layers = options.layers ?? createLayers()\n const box = createBoxFx({ ...options, layers })\n const model = createViewmodel({\n layers,\n ...(options.soundDistance ? { soundDistance: options.soundDistance } : {}),\n ...(options.soundSpace ? { soundSpace: options.soundSpace } : {}),\n ...(options.surfaceAt ? { surfaceAt: options.surfaceAt } : {}),\n ...(options.onSound ? { onSound: options.onSound } : {}),\n THREE: options.THREE,\n scene: options.scene,\n camera: options.camera,\n arsenal: options.arsenal,\n groundAt: options.groundAt,\n audio: options.audio ?? null,\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n ...(options.tool ? { tool: options.tool } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.attachmentModels ? { attachmentModels: options.attachmentModels } : {}),\n ...(options.raycast ? { raycast: options.raycast } : {}),\n ...(options.contact ? { contact: options.contact } : {}),\n ...(options.bodyHold ? { bodyHold: options.bodyHold } : {}),\n ...(options.firstPerson ? { firstPerson: options.firstPerson } : {}),\n ...(options.effects ? { effects: options.effects } : {}),\n ...(options.flyRocket === undefined ? {} : { flyRocket: options.flyRocket }),\n ...(options.particleLimit ? { particleLimit: options.particleLimit } : {}),\n ...(options.lights ? { lights: options.lights } : {}),\n ...(options.pools ? { pools: options.pools } : {}),\n })\n return {\n handle(event, tool) {\n if (event.type === 'explosion' || event.type === 'player' || event.type === 'footfall') return\n if (event.type === 'tool') {\n if (hasWeaponModel(event.weapon)) box.unequip()\n else model.unequip()\n }\n if (model.inHand !== null || (event.type === 'tool' && hasWeaponModel(event.weapon))) model.handle(event, tool)\n else box.handle(event, tool)\n },\n update(dt) {\n box.update(dt)\n model.update(dt)\n },\n setCondition: (condition) => model.setCondition(condition),\n handTargets: () => model.handTargets() ?? box.handTargets(),\n muzzle: () => (model.inHand !== null ? model.muzzle() : box.muzzle()),\n layers,\n get inHand() {\n return model.inHand ?? box.inHand\n },\n get clips() {\n return model.clips\n },\n get casings() {\n return box.casings + model.casings\n },\n get magazines() {\n return box.magazines + model.magazines\n },\n dispose() {\n box.dispose()\n model.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, Vec3 } from '@adatechnology/game-contracts'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport { mergeByMaterial } from '@adatechnology/game-shapes-three'\n\nimport type { ItemModels } from './item-models'\nimport { buildWeaponModelById } from './models'\nimport { buildTripodLegs } from './models/attachments/tripod'\nimport { modelKit } from './models/kit'\nimport { buildThrowableModel, defaultWeaponProps } from './weapon-item-model'\nimport type { WeaponProps } from './weapon-item-model'\n\nconst MODEL_BODY = 'body'\n\n/**\n * The prop of a weapon the gallery drew (or that an item model draws, `buildItemWeaponModel`), for a counter or the floor: its model lying on the side, centred on the footprint with its underside on the floor, joined into one mesh per\n * material (the hands keep the model with its pivots, `buildWeaponModelById`), every mesh naming the one rigid part (`body`) that moves it. The size of that part is left in\n * `userData.footprint` for `modeledPropSpec`.\n */\nexport function buildModeledProp(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'> & Partial<Pick<WeaponDef, 'action'>>, name: string, decorate?: (root: THREE_NS.Object3D) => void, items?: ItemModels, props: WeaponProps = defaultWeaponProps()): THREE_NS.Group | undefined {\n const model = buildWeaponModelById(THREE, def.id) ?? (() => {\n const root = props.buildItemModel(THREE, def, items) ?? buildThrowableModel(THREE, def)\n return root ? { root } : undefined\n })()\n if (!model) return undefined\n decorate?.(model.root)\n const group = markKitOrigin(new THREE.Group(), { owner: 'game-weapons-three', kind: 'weapon', id: def.id })\n group.name = name\n const box = new THREE.Box3().setFromObject(model.root)\n const center = box.getCenter(new THREE.Vector3())\n model.root.position.set(-center.x, -box.min.y, -center.z)\n group.add(model.root)\n group.updateMatrixWorld(true)\n for (const mesh of mergeByMaterial(THREE, model.root, group)) {\n mesh.userData.destructionPart = MODEL_BODY\n group.add(mesh)\n }\n group.remove(model.root)\n const size = box.getSize(new THREE.Vector3())\n group.userData.footprint = [size.x, size.y, size.z]\n return group\n}\n\n// where the tripod joins the gun (along it, under it)\nconst TRIPOD_HEAD = { x: 0.4, y: -0.1 }\n\n/** A modeled weapon on a tripod of three steel legs under its middle (the same legs the `tripod` accessory draws in the hands). */\nexport function buildTripodMountedProp(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, name: string, items?: ItemModels, props?: WeaponProps): THREE_NS.Group | undefined {\n return buildModeledProp(\n THREE,\n def,\n name,\n (root) => {\n const kit = modelKit(THREE)\n buildTripodLegs(kit, kit.pivot(root, TRIPOD_HEAD.x, TRIPOD_HEAD.y, 0))\n },\n items,\n props,\n )\n}\n\n/** The destruction spec of a modeled prop: one steel box of its measures, with the real mass of the weapon. */\nexport function modeledPropSpec(root: unknown, def: Pick<WeaponDef, 'mass'>, name: string): DestructibleSpec {\n const footprint = ((root as THREE_NS.Object3D).userData.footprint ?? [0.3, 0.1, 0.1]) as Vec3\n const size: Vec3 = [Math.max(0.02, footprint[0]), Math.max(0.02, footprint[1]), Math.max(0.02, footprint[2])]\n return { name, parts: [{ id: MODEL_BODY, material: 'steel', shape: { kind: 'box', size }, position: [0, size[1] / 2, 0], mass: def.mass }], joints: [], tags: ['weapon'] }\n}\n","{\n \"version\": 1,\n \"assets\": {\n \"aa_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/aa_12.svg\"\n },\n \"accuracy_awm\": {\n \"source\": \"generated\",\n \"file\": \"generated/accuracy_awm.svg\"\n },\n \"ag36\": {\n \"source\": \"generated\",\n \"file\": \"generated/ag36.svg\"\n },\n \"ak_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/ak_12.svg\"\n },\n \"ak_47\": {\n \"source\": \"commons\",\n \"file\": \"commons/ak_47.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:AK-47_silhouette.svg\"\n },\n \"ak_74\": {\n \"source\": \"generated\",\n \"file\": \"generated/ak_74.svg\"\n },\n \"akm\": {\n \"source\": \"generated\",\n \"file\": \"generated/akm.svg\"\n },\n \"anti_materiel_50\": {\n \"source\": \"generated\",\n \"file\": \"generated/anti_materiel_50.svg\"\n },\n \"at4\": {\n \"source\": \"generated\",\n \"file\": \"generated/at4.svg\"\n },\n \"axe\": {\n \"source\": \"generated\",\n \"file\": \"generated/axe.svg\"\n },\n \"barrett_m82a1\": {\n \"source\": \"commons\",\n \"file\": \"commons/barrett_m82a1.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Barret_M82_silhouette.svg\"\n },\n \"barrett_mrad\": {\n \"source\": \"generated\",\n \"file\": \"generated/barrett_mrad.svg\"\n },\n \"baseball_bat\": {\n \"source\": \"generated\",\n \"file\": \"generated/baseball_bat.svg\"\n },\n \"benelli_m4\": {\n \"source\": \"commons\",\n \"file\": \"commons/benelli_m4.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Benelli_M4_Super_90_silhouette.svg\"\n },\n \"beretta_92fs\": {\n \"source\": \"commons\",\n \"file\": \"commons/beretta_92fs.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Beretta_M9_silhouette.svg\"\n },\n \"blowtorch\": {\n \"source\": \"generated\",\n \"file\": \"generated/blowtorch.svg\"\n },\n \"boito_double_barrel\": {\n \"source\": \"generated\",\n \"file\": \"generated/boito_double_barrel.svg\"\n },\n \"bow_compound\": {\n \"source\": \"generated\",\n \"file\": \"generated/bow_compound.svg\"\n },\n \"browning_m2\": {\n \"source\": \"generated\",\n \"file\": \"generated/browning_m2.svg\"\n },\n \"c4\": {\n \"source\": \"generated\",\n \"file\": \"generated/c4.svg\"\n },\n \"car_fuel_tank\": {\n \"source\": \"generated\",\n \"file\": \"generated/car_fuel_tank.svg\"\n },\n \"carbine_22\": {\n \"source\": \"generated\",\n \"file\": \"generated/carbine_22.svg\"\n },\n \"carl_gustaf_m4\": {\n \"source\": \"generated\",\n \"file\": \"generated/carl_gustaf_m4.svg\"\n },\n \"cast_iron_skillet\": {\n \"source\": \"generated\",\n \"file\": \"generated/cast_iron_skillet.svg\"\n },\n \"cbc_122\": {\n \"source\": \"generated\",\n \"file\": \"generated/cbc_122.svg\"\n },\n \"cbc_7022\": {\n \"source\": \"generated\",\n \"file\": \"generated/cbc_7022.svg\"\n },\n \"cbc_pump_military_3_0\": {\n \"source\": \"generated\",\n \"file\": \"generated/cbc_pump_military_3_0.svg\"\n },\n \"chainsaw\": {\n \"source\": \"generated\",\n \"file\": \"generated/chainsaw.svg\"\n },\n \"cheytac_m200\": {\n \"source\": \"generated\",\n \"file\": \"generated/cheytac_m200.svg\"\n },\n \"claw_hammer\": {\n \"source\": \"generated\",\n \"file\": \"generated/claw_hammer.svg\"\n },\n \"claymore\": {\n \"source\": \"generated\",\n \"file\": \"generated/claymore.svg\"\n },\n \"colt_m16a2\": {\n \"source\": \"commons\",\n \"file\": \"commons/colt_m16a2.svg\",\n \"author\": \"Anonymous\",\n \"license\": \"CC0\",\n \"licenseUrl\": \"http://creativecommons.org/publicdomain/zero/1.0/deed.en\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:M16-Rifle.svg\"\n },\n \"colt_m1911\": {\n \"source\": \"commons\",\n \"file\": \"commons/colt_m1911.svg\",\n \"author\": \"Skoll\",\n \"license\": \"CC BY 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Colt-m1911_-_game-icons.svg\"\n },\n \"colt_m4a1\": {\n \"source\": \"commons\",\n \"file\": \"commons/colt_m4a1.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Colt_M4A1_silhouette.svg\"\n },\n \"crossbow\": {\n \"source\": \"generated\",\n \"file\": \"generated/crossbow.svg\"\n },\n \"crowbar\": {\n \"source\": \"generated\",\n \"file\": \"generated/crowbar.svg\"\n },\n \"cutting_torch\": {\n \"source\": \"generated\",\n \"file\": \"generated/cutting_torch.svg\"\n },\n \"cz_75\": {\n \"source\": \"generated\",\n \"file\": \"generated/cz_75.svg\"\n },\n \"cz_scorpion_evo_3\": {\n \"source\": \"generated\",\n \"file\": \"generated/cz_scorpion_evo_3.svg\"\n },\n \"desert_eagle_mark_xix\": {\n \"source\": \"commons\",\n \"file\": \"commons/desert_eagle_mark_xix.svg\",\n \"author\": \"Skoll\",\n \"license\": \"CC BY 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Desert-eagle_-_game-icons.svg\"\n },\n \"dynamite\": {\n \"source\": \"generated\",\n \"file\": \"generated/dynamite.svg\"\n },\n \"extinguisher\": {\n \"source\": \"generated\",\n \"file\": \"generated/extinguisher.svg\"\n },\n \"flamethrower\": {\n \"source\": \"generated\",\n \"file\": \"generated/flamethrower.svg\"\n },\n \"flashbang\": {\n \"source\": \"generated\",\n \"file\": \"generated/flashbang.svg\"\n },\n \"fn_fal\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_fal.svg\"\n },\n \"fn_five_seven\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_five_seven.svg\"\n },\n \"fn_m249\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_m249.svg\"\n },\n \"fn_mag\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_mag.svg\"\n },\n \"fn_minimi\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_minimi.svg\"\n },\n \"fn_minimi_para\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_minimi_para.svg\"\n },\n \"fn_p90\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_p90.svg\"\n },\n \"fn_parafal\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_parafal.svg\"\n },\n \"fn_scar_h\": {\n \"source\": \"generated\",\n \"file\": \"generated/fn_scar_h.svg\"\n },\n \"frag_grenade\": {\n \"source\": \"generated\",\n \"file\": \"generated/frag_grenade.svg\"\n },\n \"franchi_spas_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/franchi_spas_12.svg\"\n },\n \"fuel_barrel\": {\n \"source\": \"generated\",\n \"file\": \"generated/fuel_barrel.svg\"\n },\n \"glock_17\": {\n \"source\": \"generated\",\n \"file\": \"generated/glock_17.svg\"\n },\n \"glock_18\": {\n \"source\": \"generated\",\n \"file\": \"generated/glock_18.svg\"\n },\n \"glock_19\": {\n \"source\": \"commons\",\n \"file\": \"commons/glock_19.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Glock_19_silhouette.svg\"\n },\n \"gp_25\": {\n \"source\": \"generated\",\n \"file\": \"generated/gp_25.svg\"\n },\n \"hacksaw\": {\n \"source\": \"generated\",\n \"file\": \"generated/hacksaw.svg\"\n },\n \"hammer\": {\n \"source\": \"generated\",\n \"file\": \"generated/hammer.svg\"\n },\n \"hatchet\": {\n \"source\": \"generated\",\n \"file\": \"generated/hatchet.svg\"\n },\n \"hk416\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk416.svg\"\n },\n \"hk_g36\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_g36.svg\"\n },\n \"hk_g36c\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_g36c.svg\"\n },\n \"hk_g36k\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_g36k.svg\"\n },\n \"hk_g3a3\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_g3a3.svg\"\n },\n \"hk_mp5a3\": {\n \"source\": \"commons\",\n \"file\": \"commons/hk_mp5a3.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:H%26K_MP5_silhouette.svg\"\n },\n \"hk_mp5k\": {\n \"source\": \"commons\",\n \"file\": \"commons/hk_mp5k.svg\",\n \"author\": \"Skoll\",\n \"license\": \"CC BY 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Mp5k_-_game-icons.svg\"\n },\n \"hk_mp5sd3\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_mp5sd3.svg\"\n },\n \"hk_mp7a1\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_mp7a1.svg\"\n },\n \"hk_psg_1\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_psg_1.svg\"\n },\n \"hk_ump9\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_ump9.svg\"\n },\n \"hk_ump_45\": {\n \"source\": \"generated\",\n \"file\": \"generated/hk_ump_45.svg\"\n },\n \"hunting_rifle_30_06\": {\n \"source\": \"generated\",\n \"file\": \"generated/hunting_rifle_30_06.svg\"\n },\n \"imbel_ia2\": {\n \"source\": \"generated\",\n \"file\": \"generated/imbel_ia2.svg\"\n },\n \"improvised_flamethrower\": {\n \"source\": \"generated\",\n \"file\": \"generated/improvised_flamethrower.svg\"\n },\n \"improvised_spear\": {\n \"source\": \"generated\",\n \"file\": \"generated/improvised_spear.svg\"\n },\n \"iron_pipe\": {\n \"source\": \"generated\",\n \"file\": \"generated/iron_pipe.svg\"\n },\n \"kel_tec_ksg\": {\n \"source\": \"generated\",\n \"file\": \"generated/kel_tec_ksg.svg\"\n },\n \"knife\": {\n \"source\": \"generated\",\n \"file\": \"generated/knife.svg\"\n },\n \"knights_sr_25_mk11\": {\n \"source\": \"generated\",\n \"file\": \"generated/knights_sr_25_mk11.svg\"\n },\n \"kriss_vector\": {\n \"source\": \"generated\",\n \"file\": \"generated/kriss_vector.svg\"\n },\n \"lighter\": {\n \"source\": \"generated\",\n \"file\": \"generated/lighter.svg\"\n },\n \"m134\": {\n \"source\": \"generated\",\n \"file\": \"generated/m134.svg\"\n },\n \"m14_ebr\": {\n \"source\": \"generated\",\n \"file\": \"generated/m14_ebr.svg\"\n },\n \"m203\": {\n \"source\": \"generated\",\n \"file\": \"generated/m203.svg\"\n },\n \"m24_sws\": {\n \"source\": \"generated\",\n \"file\": \"generated/m24_sws.svg\"\n },\n \"m2_flamethrower\": {\n \"source\": \"generated\",\n \"file\": \"generated/m2_flamethrower.svg\"\n },\n \"m60\": {\n \"source\": \"generated\",\n \"file\": \"generated/m60.svg\"\n },\n \"m72_law\": {\n \"source\": \"generated\",\n \"file\": \"generated/m72_law.svg\"\n },\n \"m79\": {\n \"source\": \"generated\",\n \"file\": \"generated/m79.svg\"\n },\n \"mac_10\": {\n \"source\": \"commons\",\n \"file\": \"commons/mac_10.svg\",\n \"author\": \"Skoll\",\n \"license\": \"CC BY 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Mac-10_-_game-icons.svg\"\n },\n \"machete\": {\n \"source\": \"generated\",\n \"file\": \"generated/machete.svg\"\n },\n \"makarov_pm\": {\n \"source\": \"generated\",\n \"file\": \"generated/makarov_pm.svg\"\n },\n \"meat_cleaver\": {\n \"source\": \"generated\",\n \"file\": \"generated/meat_cleaver.svg\"\n },\n \"mg3\": {\n \"source\": \"generated\",\n \"file\": \"generated/mg3.svg\"\n },\n \"mini_uzi\": {\n \"source\": \"generated\",\n \"file\": \"generated/mini_uzi.svg\"\n },\n \"molotov\": {\n \"source\": \"generated\",\n \"file\": \"generated/molotov.svg\"\n },\n \"mosin_nagant_91_30\": {\n \"source\": \"generated\",\n \"file\": \"generated/mosin_nagant_91_30.svg\"\n },\n \"mossberg_500\": {\n \"source\": \"generated\",\n \"file\": \"generated/mossberg_500.svg\"\n },\n \"mossberg_500_cruiser\": {\n \"source\": \"generated\",\n \"file\": \"generated/mossberg_500_cruiser.svg\"\n },\n \"nail_bat\": {\n \"source\": \"generated\",\n \"file\": \"generated/nail_bat.svg\"\n },\n \"pickaxe\": {\n \"source\": \"generated\",\n \"file\": \"generated/pickaxe.svg\"\n },\n \"pipe_bomb\": {\n \"source\": \"generated\",\n \"file\": \"generated/pipe_bomb.svg\"\n },\n \"pistol_22\": {\n \"source\": \"generated\",\n \"file\": \"generated/pistol_22.svg\"\n },\n \"pistol_45\": {\n \"source\": \"generated\",\n \"file\": \"generated/pistol_45.svg\"\n },\n \"pistol_9mm\": {\n \"source\": \"generated\",\n \"file\": \"generated/pistol_9mm.svg\"\n },\n \"pkm\": {\n \"source\": \"generated\",\n \"file\": \"generated/pkm.svg\"\n },\n \"police_baton\": {\n \"source\": \"generated\",\n \"file\": \"generated/police_baton.svg\"\n },\n \"pp19_bizon\": {\n \"source\": \"generated\",\n \"file\": \"generated/pp19_bizon.svg\"\n },\n \"propane_p13\": {\n \"source\": \"generated\",\n \"file\": \"generated/propane_p13.svg\"\n },\n \"pry_bar\": {\n \"source\": \"generated\",\n \"file\": \"generated/pry_bar.svg\"\n },\n \"recurve_bow\": {\n \"source\": \"generated\",\n \"file\": \"generated/recurve_bow.svg\"\n },\n \"remington_700\": {\n \"source\": \"generated\",\n \"file\": \"generated/remington_700.svg\"\n },\n \"remington_700_300wm\": {\n \"source\": \"generated\",\n \"file\": \"generated/remington_700_300wm.svg\"\n },\n \"remington_870\": {\n \"source\": \"generated\",\n \"file\": \"generated/remington_870.svg\"\n },\n \"revolver_357\": {\n \"source\": \"generated\",\n \"file\": \"generated/revolver_357.svg\"\n },\n \"revolver_38\": {\n \"source\": \"generated\",\n \"file\": \"generated/revolver_38.svg\"\n },\n \"rifle_5_56\": {\n \"source\": \"generated\",\n \"file\": \"generated/rifle_5_56.svg\"\n },\n \"rifle_7_62x39\": {\n \"source\": \"generated\",\n \"file\": \"generated/rifle_7_62x39.svg\"\n },\n \"rifle_bolt_308\": {\n \"source\": \"generated\",\n \"file\": \"generated/rifle_bolt_308.svg\"\n },\n \"rossi_puma\": {\n \"source\": \"generated\",\n \"file\": \"generated/rossi_puma.svg\"\n },\n \"rpg_7\": {\n \"source\": \"generated\",\n \"file\": \"generated/rpg_7.svg\"\n },\n \"rpk\": {\n \"source\": \"generated\",\n \"file\": \"generated/rpk.svg\"\n },\n \"ruger_10_22\": {\n \"source\": \"generated\",\n \"file\": \"generated/ruger_10_22.svg\"\n },\n \"saiga_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/saiga_12.svg\"\n },\n \"sako_trg_42\": {\n \"source\": \"commons\",\n \"file\": \"commons/sako_trg_42.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Sako_TRG_silhouette.svg\"\n },\n \"screwdriver\": {\n \"source\": \"generated\",\n \"file\": \"generated/screwdriver.svg\"\n },\n \"shotgun_double_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/shotgun_double_12.svg\"\n },\n \"shotgun_pump_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/shotgun_pump_12.svg\"\n },\n \"shotgun_semi_12\": {\n \"source\": \"generated\",\n \"file\": \"generated/shotgun_semi_12.svg\"\n },\n \"sickle\": {\n \"source\": \"generated\",\n \"file\": \"generated/sickle.svg\"\n },\n \"sig_mpx\": {\n \"source\": \"generated\",\n \"file\": \"generated/sig_mpx.svg\"\n },\n \"sig_sauer_p226\": {\n \"source\": \"generated\",\n \"file\": \"generated/sig_sauer_p226.svg\"\n },\n \"sks\": {\n \"source\": \"generated\",\n \"file\": \"generated/sks.svg\"\n },\n \"sledgehammer\": {\n \"source\": \"generated\",\n \"file\": \"generated/sledgehammer.svg\"\n },\n \"smg_9mm\": {\n \"source\": \"generated\",\n \"file\": \"generated/smg_9mm.svg\"\n },\n \"sniper_338\": {\n \"source\": \"generated\",\n \"file\": \"generated/sniper_338.svg\"\n },\n \"steyr_aug_a1\": {\n \"source\": \"commons\",\n \"file\": \"commons/steyr_aug_a1.svg\",\n \"author\": \"Fleshgrinder\",\n \"license\": \"Public domain\",\n \"licenseUrl\": \"https://commons.wikimedia.org/wiki/File:Steyr_AUG_A1_407mm.svg\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Steyr_AUG_A1_407mm.svg\"\n },\n \"steyr_ssg_69\": {\n \"source\": \"generated\",\n \"file\": \"generated/steyr_ssg_69.svg\"\n },\n \"svd_dragunov\": {\n \"source\": \"commons\",\n \"file\": \"commons/svd_dragunov.svg\",\n \"author\": \"Bes-ART\",\n \"license\": \"CC BY-SA 4.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/4.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Dragunov_silhouette.svg\"\n },\n \"sw_686\": {\n \"source\": \"generated\",\n \"file\": \"generated/sw_686.svg\"\n },\n \"sw_model_29\": {\n \"source\": \"generated\",\n \"file\": \"generated/sw_model_29.svg\"\n },\n \"tactical_knife\": {\n \"source\": \"generated\",\n \"file\": \"generated/tactical_knife.svg\"\n },\n \"taurus_82\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_82.svg\"\n },\n \"taurus_g2c\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_g2c.svg\"\n },\n \"taurus_pt100\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_pt100.svg\"\n },\n \"taurus_smt9\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_smt9.svg\"\n },\n \"taurus_t4\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_t4.svg\"\n },\n \"taurus_t4_civil\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_t4_civil.svg\"\n },\n \"taurus_th380\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_th380.svg\"\n },\n \"taurus_ts9\": {\n \"source\": \"generated\",\n \"file\": \"generated/taurus_ts9.svg\"\n },\n \"thompson_m1a1\": {\n \"source\": \"generated\",\n \"file\": \"generated/thompson_m1a1.svg\"\n },\n \"utility_knife\": {\n \"source\": \"commons\",\n \"file\": \"commons/utility_knife.svg\",\n \"author\": \"Lucasbosch\",\n \"license\": \"CC BY-SA 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by-sa/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:OLFA_5019_SVR-2_9_mm_utility_knife_with_ABB_blade.svg\"\n },\n \"uzi\": {\n \"source\": \"commons\",\n \"file\": \"commons/uzi.svg\",\n \"author\": \"floatingbrainiac\",\n \"license\": \"CC0\",\n \"licenseUrl\": \"http://creativecommons.org/publicdomain/zero/1.0/deed.en\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Uzi_silhouette.svg\"\n },\n \"vz61\": {\n \"source\": \"commons\",\n \"file\": \"commons/vz61.svg\",\n \"author\": \"Skoll\",\n \"license\": \"CC BY 3.0\",\n \"licenseUrl\": \"https://creativecommons.org/licenses/by/3.0\",\n \"page\": \"https://commons.wikimedia.org/wiki/File:Cz-skorpion_-_game-icons.svg\"\n },\n \"winchester_1894\": {\n \"source\": \"generated\",\n \"file\": \"generated/winchester_1894.svg\"\n },\n \"wrench\": {\n \"source\": \"generated\",\n \"file\": \"generated/wrench.svg\"\n }\n }\n}\n","import manifest from '../assets/weapon-svg/manifest.json'\n\n/** Where a thumbnail came from: the model of the kit (`generated`) or a freely licensed drawing of the real weapon (`commons`, with its author and licence). */\nexport interface WeaponThumbnailEntry {\n readonly source: 'generated' | 'commons'\n /** Path of the SVG inside `assets/weapon-svg`. */\n readonly file: string\n readonly author?: string\n readonly license?: string\n readonly licenseUrl?: string\n readonly page?: string\n}\n\n/** Every weapon (and world explosive) that has a thumbnail, by weapon id: the Commons file when one was kept, else the one generated from the 3D model. */\nexport const WEAPON_THUMBNAILS: Readonly<Record<string, WeaponThumbnailEntry>> = (manifest as { assets: Record<string, WeaponThumbnailEntry> }).assets\n\n/** `Author, licence` of a Commons thumbnail (the credit its licence asks for), or undefined for a generated one. */\nexport function weaponThumbnailCredit(id: string): string | undefined {\n const entry = WEAPON_THUMBNAILS[id]\n return entry?.source === 'commons' && entry.author && entry.license ? `${entry.author}, ${entry.license}` : undefined\n}\n\n/** The folder of the thumbnails relative to the page that shows them; the site build copies `assets/weapon-svg` there. */\nexport const DEFAULT_THUMBNAIL_BASE = 'weapon-svg/'\n\n/** The URL of a weapon's thumbnail under `base` (which ends with a slash), or undefined when it has none. */\nexport function weaponThumbnailUrl(id: string, base: string = DEFAULT_THUMBNAIL_BASE): string | undefined {\n const entry = WEAPON_THUMBNAILS[id]\n return entry ? `${base}${entry.file}` : undefined\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, PartShape, PartSpec, TestableItem, Vec3 } from '@adatechnology/game-contracts'\nimport type { ExplosiveDef } from '@adatechnology/game-weapons'\nimport { DEFAULT_ITEM_MODELS } from './item-models'\nimport type { ItemModelRequest, ItemModels } from './item-models'\n\n/** Prefix of the item ids of the explosives that sit in the world (`world_fuel_barrel`). */\nexport const WORLD_EXPLOSIVE_PREFIX = 'world_'\n\ninterface WorldShape {\n readonly shape: PartShape\n readonly position: Vec3\n readonly color: number\n /** The team's model of the thing (an item of `game-items-three`): when set it is drawn instead of the plain `shape`, which stays what the destruction world hits. */\n readonly model?: ItemModelRequest\n /** Wall thickness in metres when it is not the thin sheet of the others (a P13 shell is 2.5 mm of steel). */\n readonly wall?: number\n}\n\n/** Name of the mesh of the brass valve on the P13 model (the team's `botijao`: the 0xb8913a cylinder on the neck). */\nexport const P13_VALVE_MESH = 'valve'\nconst P13_VALVE_COLOR = 0xb8913a\n/** The shell of a P13 is 2.5 mm of steel (a 13 kg cylinder weighs about 15 kg empty). */\nconst P13_WALL = 0.0025\n\n// The game's drum (jogo.js addExplo 68141: radius 0.3, height 0.9); the car tank is a real measure. The P13 is the team's real model, at the size of the item `lpg_cylinder_13kg` of the goods catalogue (0.353 x 0.49 x 0.358 m, 29 kg).\nconst SHAPES: Readonly<Record<string, WorldShape>> = {\n fuel_barrel: { shape: { kind: 'cylinder', radius: 0.3, height: 0.9 }, position: [0, 0.45, 0], color: 0x2f5f9a },\n propane_p13: {\n shape: { kind: 'cylinder', radius: 0.176, height: 0.49 },\n position: [0, 0.245, 0],\n color: 0x355f86,\n model: { id: 'lpg_cylinder_13kg', category: 'fuel', size: [0.35299, 0.49, 0.35844], model: 'lpg_cylinder_13kg' },\n wall: P13_WALL,\n },\n car_fuel_tank: { shape: { kind: 'box', size: [0.9, 0.25, 0.5] }, position: [0, 0.4, 0], color: 0x4b4f55 },\n}\n\n/** The ids of the explosives of the arsenal that the area puts in the world. */\nexport const WORLD_EXPLOSIVE_IDS: readonly string[] = Object.keys(SHAPES)\n\n// A hollow steel shell: thin and light, so a bullet or a blast breaks it (the weight of a solid steel part would hold it together).\nconst SHELL = { thickness: 0.001, fill: 0.03 }\n\n/** What the bench (or a game) changes about a world explosive without touching the arsenal: the multiplier of its energy and reach, read each time one is spawned. */\nexport interface WorldExplosiveOptions {\n /** Multiplies `energy`, `lethalRadius` and `injuryRadius` of the explosive (default 1: the arsenal's numbers). It is a game value, not a physical table; the arsenal's own place for it is `ArsenalOptions.patch.explosives`. */\n readonly scale?: () => number\n /** The item models of game-items-three (`itemModels` there): the P13 is drawn with the team's model; default `itemModels` there (deprecated: pass it). */\n readonly items?: ItemModels\n}\n\n/** The part of a world explosive: the energy, the reach, the chain and the effect (the explosive's id in the host's catalogue) of the explosive def, which is what `explosivePart` of game-destruction builds. */\nconst explosivePart = (def: ExplosiveDef, shape: WorldShape, scale: number): PartSpec => ({\n id: 'tank',\n material: 'steel',\n shape: shape.shape,\n position: shape.position,\n ...(shape.wall === undefined ? SHELL : { thickness: shape.wall }),\n // a real mass (the vessel and what it holds) replaces the hollow-sheet density\n ...(def.mass !== undefined && shape.wall !== undefined ? { mass: def.mass } : {}),\n ...(def.leak ? { contains: { fluid: def.leak.fluid, liters: def.leak.liters, pressurized: def.leak.pressurized } } : {}),\n explodes: { energy: def.energy * scale, radius: def.injuryRadius * scale, lethalRadius: def.lethalRadius * scale, effect: def.id, ...(def.tnt !== undefined ? { tnt: def.tnt * scale } : {}), ...(def.chain ? { chain: { ...def.chain } } : {}) },\n})\n\nconst meshOf = (THREE: typeof THREE_NS, shape: WorldShape): THREE_NS.Mesh => {\n 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)\n const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: shape.color, roughness: 0.55, metalness: 0.5 }))\n mesh.name = 'tank'\n mesh.userData.destructionPart = 'tank'\n mesh.position.set(...shape.position)\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n}\n\n/** The team's model of a world explosive (a group, base at the origin), every mesh mapped to the part `tank`; the brass valve is named `valve`. Undefined for the ones that have no model of the team. */\nconst modelOf = (THREE: typeof THREE_NS, shape: WorldShape, items: ItemModels | undefined, wear: 0 | 2 = 0): THREE_NS.Group | undefined => {\n if (!shape.model) return undefined\n const { root, kind } = (items ?? DEFAULT_ITEM_MODELS).build(THREE, shape.model, { wear })\n if (kind !== 'model') return undefined\n root.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n if (!mesh.isMesh) return\n mesh.userData.destructionPart = 'tank'\n mesh.castShadow = true\n mesh.receiveShadow = true\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n if (material.color?.getHex() === P13_VALVE_COLOR) mesh.name = P13_VALVE_MESH\n })\n return root\n}\n\n/** Where the valve is on a spawned cylinder, in the world (the centre of the brass mesh), or undefined when the object has none. */\nexport const worldExplosiveValve = (THREE: typeof THREE_NS, root: THREE_NS.Object3D): Vec3 | undefined => {\n const valve = root.getObjectByName(P13_VALVE_MESH)\n if (!valve) return undefined\n root.updateMatrixWorld(true)\n const centre = new THREE.Box3().setFromObject(valve).getCenter(new THREE.Vector3())\n return [centre.x, centre.y, centre.z]\n}\n\n/**\n * What is left of a world explosive after the blast, as an object to fly: the same model, worn and darkened (the torn shell of the P13 in the Laboratório de Explosões, `SC.p13`),\n * with no part mapped. Undefined for the explosives that have no model of the team.\n */\nexport const worldExplosiveShell = (THREE: typeof THREE_NS, defId: string, items?: ItemModels): THREE_NS.Group | undefined => {\n const shape = SHAPES[defId]\n const model = shape ? modelOf(THREE, shape, items, 2) : undefined\n if (!model) return undefined\n model.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n if (!mesh.isMesh) return\n delete mesh.userData.destructionPart\n ;(mesh.material as THREE_NS.MeshStandardMaterial).color.multiplyScalar(0.35)\n })\n model.name = `${WORLD_EXPLOSIVE_PREFIX}${defId}_shell`\n return model\n}\n\n/** An explosive of the arsenal standing in the world: it goes off by a bullet, fire or another blast, after the delay its `chain` gives. */\nexport const worldExplosiveItem = (def: ExplosiveDef, name: string, options: WorldExplosiveOptions = {}): TestableItem | undefined => {\n const shape = SHAPES[def.id]\n if (!shape) return undefined\n const scale = (): number => options.scale?.() ?? 1\n const spec = (): DestructibleSpec => ({ name, parts: [explosivePart(def, shape, scale())], joints: [], tags: ['explosive'] })\n return {\n id: `${WORLD_EXPLOSIVE_PREFIX}${def.id}`,\n name,\n build: (THREE: unknown) => {\n const T = THREE as typeof THREE_NS\n const model = modelOf(T, shape, options.items)\n if (model) return model\n const group = new T.Group()\n group.add(meshOf(T, shape))\n return group\n },\n spec,\n }\n}\n","{\n \"pistol\": { \"muzzle\": \"muzzle_glock\", \"casing\": \"casing_brass\" },\n \"tiny\": { \"muzzle\": \"muzzle_glock\", \"casing\": \"casing_brass\" },\n \"rifle\": { \"muzzle\": \"muzzle_ak\", \"casing\": \"casing_brass\" },\n \"shell\": { \"muzzle\": \"muzzle_r870\", \"casing\": \"casing_shell\" },\n \"big\": { \"muzzle\": \"muzzle_barrett\", \"casing\": \"casing_50\" }\n}\n","import type { Arsenal } from '@adatechnology/game-weapons'\nimport type { EffectSink, HostEvent, Vec3 } from '@adatechnology/game-contracts'\nimport worldEffectData from './data/world-effects.json'\n\n/** The effect ids a weapon of a case type shows when it is seen from outside: its muzzle flash and its ejected case (the host's catalogue names them). */\nexport interface WorldEffectIds {\n readonly muzzle: string\n readonly casing: string\n}\n\nexport const WORLD_EFFECTS: Readonly<Record<string, WorldEffectIds>> = worldEffectData\n\nexport interface WorldEffectsOptions {\n readonly arsenal: Arsenal\n /** The case type of a weapon (`pistol`, `rifle`, `shell`, `big`, `tiny`); default from its caliber. */\n readonly caseTypeOf?: (weapon: string) => string | undefined\n /** The ids by case type; default `WORLD_EFFECTS`. A game adds or changes entries. */\n readonly ids?: Readonly<Record<string, WorldEffectIds>>\n}\n\n/** Where the case leaves the weapon: a hand to the right of the muzzle, behind it. */\nconst PORT_BACK = 0.35\nconst PORT_RIGHT = 0.04\n\n/**\n * The shooter's flash and ejected case for a shot the viewer sees from outside (a `shot` event that carries `origin`), played through the host's\n * effect sink. The player's own first-person shot has no `origin` and is drawn by the weapon in the hands, so nothing doubles.\n */\nexport function createWorldEffects(options: WorldEffectsOptions): { handle(event: HostEvent, sink: EffectSink | undefined): number } {\n const ids = options.ids ?? WORLD_EFFECTS\n const caseTypeOf =\n options.caseTypeOf ??\n ((weapon: string): string | undefined => {\n const def = options.arsenal.weapons.get(weapon)\n return def && def.action.kind === 'firearm' ? options.arsenal.calibers.get(def.action.caliber)?.caseType : undefined\n })\n let counter = 0\n return {\n /** Plays what the event asks for and answers how many effects started. */\n handle(event, sink) {\n if (!sink || event.type !== 'shot' || !event.origin) return 0\n const caseType = caseTypeOf(event.weapon) ?? 'rifle'\n const entry = ids[caseType]\n if (!entry) return 0\n const direction: Vec3 = event.direction ?? [0, 0, -1]\n const seed = ++counter\n let started = 0\n for (let shot = 0; shot < Math.max(1, event.rounds ?? 1); shot++) {\n if (sink.play({ effect: entry.muzzle, point: event.origin, direction, seed: seed * 8 + shot }) !== null) started++\n }\n const side: Vec3 = [direction[2], 0, -direction[0]]\n const port: Vec3 = [\n event.origin[0] - direction[0] * PORT_BACK + side[0] * PORT_RIGHT,\n event.origin[1] - direction[1] * PORT_BACK,\n event.origin[2] - direction[2] * PORT_BACK + side[2] * PORT_RIGHT,\n ]\n if (sink.play({ effect: entry.casing, point: port, direction, seed: seed * 8 + 7 }) !== null) started++\n return started\n },\n }\n}\n","import type { ModuleScenario } from '@adatechnology/game-contracts'\n\n/** The members of the test room's `ScenarioContext` these scenarios use (structural: this package does not depend on the room). */\ninterface ScenarioContext {\n room: {\n spawn(itemId: string, position?: [number, number, number], rotationY?: number): { objectId: string }\n setTool(id: string): unknown\n waitUntilReady(): number\n look(from: [number, number, number], to: [number, number, number]): void\n use(hold?: number): unknown\n world: { part(objectId: string, partId: string): { status: string; hp: number; maxHp: number; holes: Array<{ through?: boolean }>; dents: unknown[]; cracks: unknown[]; temperature?: number; melt?: number } | null }\n log: { entries(filter: { type?: string; objectId?: string }): Array<{ data?: Record<string, unknown> }> }\n }\n step(seconds: number): void\n expect(ok: boolean, label: string, data?: Record<string, unknown>): void\n}\n\n/** The target stands at (0, 0, TARGET_Z); its face is `FACE_Y` above the floor and looks toward +z (the shooter). */\nconst TARGET_Z = -4\nconst SHOOTER_Z = -1.5\n\n/**\n * Scenarios of the weapons module against its own real targets (`target_steel_plate`, `target_plywood`, `target_concrete`) and real weapons: the 9 mm pistol\n * through steel, the same round stopped by concrete, the pump shotgun on plywood and the hammer on steel. They were the room's generic bullet-hole checks\n * before the room stopped shipping items of its own.\n */\nexport function weaponsScenarios(locale: string): Array<ModuleScenario<ScenarioContext>> {\n const pt = locale.toLowerCase().startsWith('pt')\n const T = (p: string, e: string): string => (pt ? p : e)\n const faceY = (id: string): number => (id === 'target_steel_plate' ? 1.35 : id === 'target_plywood' ? 1.5 : 1.2)\n const aimAt = (room: ScenarioContext['room'], id: string): void => room.look([0, faceY(id) + 0.05, SHOOTER_Z], [0, faceY(id), TARGET_Z])\n\n return [\n {\n id: 'target_steel_heavy_through_hole',\n name: T('Alvo de aço: um .50 BMG do Barrett M82A1 atravessa a chapa e o 9 mm só amassa', 'Steel target: the .50 BMG of the Barrett M82A1 goes through the plate and the 9 mm only dents it'),\n run: ({ room, step, expect }) => {\n const id = room.spawn('target_steel_plate', [0, 0, TARGET_Z]).objectId\n room.setTool('pistol_9mm')\n room.waitUntilReady()\n aimAt(room, 'target_steel_plate')\n room.use()\n step(0.3)\n const pistol = room.world.part(id, 'face')\n expect((pistol?.dents.length ?? 0) > 0 && !pistol?.holes.some((h) => h.through), T(`9 mm na chapa de 10 mm: amassados ${pistol?.dents.length ?? 0}, furos que atravessam ${pistol?.holes.filter((h) => h.through).length ?? 0} (esperado: amassa e não atravessa)`, `9 mm on the 10 mm plate: dents ${pistol?.dents.length ?? 0}, through holes ${pistol?.holes.filter((h) => h.through).length ?? 0} (expected: dents it, no through hole)`))\n room.setTool('barrett_m82a1')\n room.waitUntilReady()\n aimAt(room, 'target_steel_plate')\n room.use()\n step(0.3)\n const rifle = room.world.part(id, 'face')\n const hole = rifle?.holes.find((h) => h.through)\n expect(!!hole, T(`.50 BMG na chapa: furo que atravessa ${hole ? 'sim' : 'não'} (furos: ${rifle?.holes.length ?? 0})`, `.50 BMG on the plate: through hole ${hole ? 'yes' : 'no'} (holes: ${rifle?.holes.length ?? 0})`), { holes: rifle?.holes.length })\n },\n },\n {\n id: 'target_concrete_stops_bullet',\n name: T('Alvo de concreto: um 9 mm não atravessa o bloco', 'Concrete target: a 9 mm does not go through the block'),\n run: ({ room, step, expect }) => {\n const id = room.spawn('target_concrete', [0, 0, TARGET_Z]).objectId\n room.setTool('pistol_9mm')\n room.waitUntilReady()\n aimAt(room, 'target_concrete')\n room.use()\n step(0.2)\n const face = room.world.part(id, 'face')\n const through = face?.holes.some((h) => h.through) ?? true\n const marks = (face?.holes.length ?? 0) + (face?.dents.length ?? 0) + (face?.cracks.length ?? 0)\n expect(!through && marks > 0, T(`Bloco de concreto: atravessou ${through ? 'sim' : 'não'}, marcas ${marks} (esperado: não atravessar e marcar)`, `Concrete block: went through ${through ? 'yes' : 'no'}, marks ${marks} (expected: stopped and marked)`), { through, marks })\n },\n },\n {\n id: 'target_plywood_shotgun_holes',\n name: T('Alvo de compensado: a escopeta de ferrolho crava vários chumbos na madeira', 'Plywood target: the pump shotgun drives several pellets through the wood'),\n run: ({ room, step, expect }) => {\n const id = room.spawn('target_plywood', [0, 0, TARGET_Z]).objectId\n room.setTool('shotgun_pump_12')\n room.waitUntilReady()\n aimAt(room, 'target_plywood')\n room.use()\n step(1.1)\n const holes = room.world.part(id, 'face')?.holes.length ?? 0\n expect(holes >= 3, T(`Chumbos na madeira num tiro: ${holes} furos (esperado: 3 ou mais)`, `Pellets in the wood from one shot: ${holes} holes (expected: 3 or more)`), { holes })\n },\n },\n {\n id: 'target_steel_hammer_dents',\n name: T('Alvo de aço: a marreta amassa a chapa sem romper', 'Steel target: the hammer dents the plate without breaking it'),\n run: ({ room, step, expect }) => {\n const id = room.spawn('target_steel_plate', [0, 0, TARGET_Z]).objectId\n room.setTool('hammer')\n room.waitUntilReady()\n room.look([0, 1.4, TARGET_Z + 0.65], [0, 1.35, TARGET_Z])\n let swings = 0\n for (; swings < 8 && (room.world.part(id, 'face')?.dents.length ?? 0) === 0; swings++) {\n room.use()\n step(1)\n }\n const face = room.world.part(id, 'face')\n expect((face?.dents.length ?? 0) > 0 && face?.status !== 'broken', T(`Amassados na chapa depois de ${swings} golpe(s): ${face?.dents.length ?? 0}`, `Dents in the plate after ${swings} swing(s): ${face?.dents.length ?? 0}`), { swings })\n },\n },\n {\n id: 'target_steel_torch_melts',\n name: T('Alvo de aço: o maçarico de corte derrete a chapa', 'Steel target: the cutting torch melts the plate'),\n run: ({ room, expect }) => {\n const id = room.spawn('target_steel_plate', [0, 0, TARGET_Z]).objectId\n room.setTool('cutting_torch')\n room.waitUntilReady()\n room.look([0, faceY('target_steel_plate') + 0.05, TARGET_Z + 0.2], [0, faceY('target_steel_plate'), TARGET_Z])\n room.use(20)\n const face = room.world.part(id, 'face')\n expect((face?.melt ?? 0) > 0.02 || face?.status === 'melted' || (face?.holes.length ?? 0) > 0, T(`Chapa depois do maçarico: ${Math.round(face?.temperature ?? 0)} °C, derretido ${Math.round((face?.melt ?? 0) * 100)}%`, `Plate after the torch: ${Math.round(face?.temperature ?? 0)} °C, ${Math.round((face?.melt ?? 0) * 100)}% melted`), { temperature: face?.temperature, melt: face?.melt })\n },\n },\n ]\n}\n","import type { AreaPlacement, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { EXPLOSIONS } from '@adatechnology/game-vfx'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal, ExplosiveDef } from '@adatechnology/game-weapons'\nimport { EXPLOSIVES_AREA_ID, createExplosivesBench } from './explosives-bench'\nimport type { ItemModels } from '../item-models'\nimport type { ExplosivesRoom } from './explosives-bench'\nimport { explosivesScenarios } from './explosives-scenarios'\nimport { explosivesTextOf } from './explosives-text'\nimport { WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from '../world-explosives'\n\nexport { EXPLOSIVES_AREA_ID }\nexport type { ExplosivesRoom }\n\n/** Where the things of the scene stand (metres, in the room's world; the brick wall is the room's own at z = -11). The kitchen corner is against the wall; the player looks at it from about 6 m. */\nexport interface ExplosivesScene {\n /** Item ids and positions of the kitchen furniture (items of the household module); one that the room does not know is left out. */\n readonly furniture: ReadonlyArray<{ readonly item: string; readonly at: Vec3; readonly rotationY?: number }>\n /** The cylinder. */\n readonly cylinder: Vec3\n /** The zombie (about 3 m from the cylinder) and the survivor (about 8 m): item ids of the characters module. */\n readonly zombie: { readonly item: string; readonly at: Vec3 }\n readonly survivor: { readonly item: string; readonly at: Vec3 }\n /** The player's eye (about 6 m from the cylinder: outside the 5 m lethal ring, the lamp rig of the weather module is behind it). */\n readonly eye: Vec3\n}\n\n/** The kitchen corner of the default scene: fridge, cabinet, the cylinder and the stove side by side against the wall, a table 2 m away. */\nexport const DEFAULT_EXPLOSIVES_SCENE: ExplosivesScene = {\n furniture: [\n { item: 'fridge', at: [-1.65, 0, -10.55] },\n { item: 'kitchen_cabinet_base', at: [-0.78, 0, -10.6] },\n { item: 'stove', at: [0.72, 0, -10.58] },\n { item: 'camp_table', at: [2.4, 0, -10.2] },\n ],\n cylinder: [0.02, 0, -10.66],\n zombie: { item: 'zombie_walker', at: [-1.6, 0, -8.1] },\n survivor: { item: 'person_police_officer', at: [6, 0, -5.3] },\n eye: [0, 1.7, -4.7],\n}\n\nexport interface ExplosivesTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to read the P13 from (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** The room the module drives: its destruction world, effects and tools. Without it the module still lays the area and the bench shows, but the actions only say they need the room. */\n room?: ExplosivesRoom\n /** Overrides of the default scene (see `ExplosivesScene`). */\n scene?: Partial<ExplosivesScene>\n /** Strength multiplier the bench starts at (default 1: the arsenal's numbers; a game value, see the README). */\n blastScale?: number\n /** The item models of game-items-three (`itemModels` there): the P13 is drawn with the team's model (default `itemModels` there, deprecated: pass it). */\n items?: ItemModels\n}\n\nconst EXPLOSIVE_ID = 'propane_p13'\n/** Aim and view of the area: the player's eye and the point it looks at. */\nconst AIM_HEIGHT = 0.25\n\n/**\n * The explosives test area as a `TestableModule`: the P13 cooking gas cylinder in a kitchen corner against a brick wall, with furniture, a zombie at 3 m, a survivor at 8 m and rings on the floor at the\n * lethal and injury radii. The bench shoots it, opens its valve, lights it with a lighter, throws it in a fire or restarts the scene; every phase is told in the room's log in the locale of the room.\n * The module reads the sequence (the torch delay, the gas, the flight of the shell) from the arsenal def of `propane_p13` and the blast from its `chain`, so a game changes them with `ArsenalOptions.patch.explosives`.\n */\nexport function createExplosivesTestModule(options: ExplosivesTestModuleOptions = {}): TestableModule & { readonly bench: ReturnType<typeof createExplosivesBench> } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = explosivesTextOf(locale)\n const scene: ExplosivesScene = { ...DEFAULT_EXPLOSIVES_SCENE, ...options.scene }\n const def = arsenal.explosives.get(EXPLOSIVE_ID) as ExplosiveDef | undefined\n if (!def) throw new Error(`explosives area: the arsenal has no \"${EXPLOSIVE_ID}\"`)\n const bench = createExplosivesBench({ locale, text, def, scene, room: options.room, blastScale: options.blastScale ?? 1, ...(options.items ? { items: options.items } : {}), profile: EXPLOSIONS[EXPLOSIVE_ID] })\n return {\n id: EXPLOSIVES_AREA_ID,\n name: text.name,\n ground: { surface: 'concrete_slab' },\n group: text.group,\n bench,\n // the cylinder of this area is the world explosive of the weapons module with the bench's strength: the same id, the same model, the same part\n items: (): TestableItem[] => {\n const item = worldExplosiveItem(def, text.cylinder, { scale: () => bench.blastScale(), ...(options.items ? { items: options.items } : {}) })\n return item ? [item] : []\n },\n area: (): ModuleArea => {\n bench.areaOpened()\n const placements: AreaPlacement[] = [\n ...scene.furniture.map((piece) => ({ item: piece.item, position: piece.at, ...(piece.rotationY === undefined ? {} : { rotationY: piece.rotationY }) })),\n { item: `${WORLD_EXPLOSIVE_PREFIX}${EXPLOSIVE_ID}`, position: scene.cylinder },\n // facing the cylinder (the front of an item looks to +z, the cylinder is at -z)\n { item: scene.zombie.item, position: scene.zombie.at, rotationY: Math.PI },\n { item: scene.survivor.item, position: scene.survivor.at, rotationY: Math.PI },\n ]\n const centre: Vec3 = [scene.cylinder[0], AIM_HEIGHT, scene.cylinder[2]]\n return { placements, view: { eye: scene.eye, target: centre } }\n },\n controls: (): ModuleControl[] => bench.controls(),\n layers: (): ModuleLayer[] => bench.layers(),\n metrics: (): ModuleMetric[] => bench.metrics(),\n scenarios: (scenarioLocale?: string): Array<ModuleScenario<never>> => explosivesScenarios(scenarioLocale ?? locale, bench) as Array<ModuleScenario<never>>,\n attach: (host: ModuleHost) => bench.attach(host),\n }\n}\n","import { discardObject3D } from '@adatechnology/game-shapes-three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type * as THREE_NS from 'three'\nimport type { BenchChange, BenchSheet, DestructionEvent, Hit, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, Vec3 } from '@adatechnology/game-contracts'\nimport type { ExplosiveDef } from '@adatechnology/game-weapons'\nimport type { ItemModels } from '../item-models'\nimport { fillText } from './explosives-text'\nimport type { ExplosivesText } from './explosives-text'\nimport { WORLD_EXPLOSIVE_PREFIX, worldExplosiveShell, worldExplosiveValve } from '../world-explosives'\n\n/** Id of the explosives module (`?area=explosives_area` opens it). */\nexport const EXPLOSIVES_AREA_ID = 'explosives_area'\n\n/** The parts of a part state the bench reads (structural: `PartState` of the destruction world fits). */\ninterface PartView {\n readonly liters?: number\n readonly temperature: number\n readonly status: string\n readonly holes: ReadonlyArray<{ readonly diameter: number; readonly through: boolean }>\n readonly cracks: readonly unknown[]\n readonly burning: boolean\n}\n\n/** What the explosives module needs from the room it drives (structural: the `TestRoom` of game-test-room fits). */\nexport interface ExplosivesRoom {\n readonly world: {\n readonly time: number\n ids(): string[]\n on(type: '*', fn: (event: DestructionEvent) => void): () => void\n hit(objectId: string, hit: Hit): unknown\n vent(objectId: string, partId: string, opening?: { point?: Vec3; normal?: Vec3; diameter?: number }): boolean\n seal(objectId: string, partId: string): number\n part(objectId: string, partId: string): PartView | null\n state(objectId: string): { readonly parts: readonly (PartView & { readonly id: string; readonly hp: number; readonly maxHp: number })[] } | null\n /** The share of a blast at `point` that reaches `target` through the cover between them (game-destruction `blastReach`). */\n blastReach?(point: Vec3, target: Vec3, options?: { readonly ignore?: readonly string[] }): number\n }\n readonly renderer: {\n impulse(objectId: string, impulse: Vec3, point?: Vec3): void\n /** World boxes of what is drawn around (x, z) (game-destruction-three `solidsNear`). */\n solidsNear?(x: number, z: number, radius: number): ReadonlyArray<{ readonly objectId: string; readonly min: Vec3; readonly max: Vec3 }>\n }\n readonly vfx: {\n spawn(kind: string, point: Vec3, velocity: Vec3, options?: { color?: number; size?: number; life?: number; alpha?: number }): void\n burst(kind: string, point: Vec3, normal: Vec3, count: number, speed?: number): void\n fire(options: { point: Vec3; radius: number; life: number }): number\n stop(handle: number): void\n }\n spawned(): ReadonlyArray<{ readonly objectId: string; readonly itemId: string; readonly root: unknown }>\n openArea(group: string): unknown\n clear(): void\n spawn(itemId: string, position?: Vec3, rotationY?: number): { readonly objectId: string; readonly itemId: string; readonly root: unknown }\n setTool(weaponId: string): void\n waitUntilReady(maxSeconds?: number): number\n look(position: Vec3, target: Vec3): void\n use(hold?: number): void\n on(type: 'spawn', fn: (data: unknown) => void): () => void\n}\n\n/** The bench of the explosives area as the module and its scenarios see it. */\nexport interface ExplosivesBench {\n readonly room: ExplosivesRoom | undefined\n readonly def: ExplosiveDef\n /** The strength multiplier now (the next cylinder laid takes it). */\n blastScale(): number\n /** Called by the module's `area`: the cylinders spawned from now on belong to the area (they get their rings). */\n areaOpened(): void\n controls(): ModuleControl[]\n layers(): ModuleLayer[]\n metrics(): ModuleMetric[]\n attach(host: ModuleHost): () => void\n /** The actions of the bench, by the id of their button. Each answers whether it did something. */\n readonly actions: Readonly<Record<'shoot' | 'valve' | 'light' | 'fire' | 'reset', () => boolean>>\n /** The cylinder of the scene (the first one alive), with what the bench knows about it. */\n vessel(): VesselView | undefined\n /** The wall of the scene, the zombie and the survivor, as the aftermath reads them. */\n /** The last explosion the host told (a part of the world or a thrown explosive): where, how strong and how far; undefined before the first, and after the area is cleared. */\n lastBlast(): { readonly point: Vec3; readonly energy: number; readonly radius: number; readonly cause: string; readonly explosive?: string; readonly tnt?: number } | undefined\n witnesses(): Array<{ kind: 'person' | 'wall' | 'object'; id: string; itemId: string; distance: number; alive?: boolean; vitality?: number; broken?: number; marks?: number; pieces?: number }>\n}\n\nexport interface VesselView {\n readonly objectId: string\n /** World time of the first leak, of the jet catching fire and of the blast (seconds); undefined until they happen. */\n readonly leakAt: number | undefined\n readonly litAt: number | undefined\n readonly explodedAt: number | undefined\n readonly cause: 'shot' | 'valve' | undefined\n readonly valveOpen: boolean\n readonly lit: boolean\n readonly exploded: boolean\n readonly point: Vec3 | undefined\n}\n\ninterface Leak {\n point: Vec3\n direction: Vec3\n rate: number\n}\n\ninterface Vessel {\n objectId: string\n root: THREE_NS.Object3D\n /** The strength multiplier it was laid with. */\n scale: number\n leaks: Leak[]\n leakAt?: number\n cause?: 'shot' | 'valve'\n valveRequested: boolean\n valveOpen: boolean\n lit: boolean\n litAt?: number\n explodeAt?: number\n explodedAt?: number\n exploded: boolean\n centre?: Vec3\n fireUntil?: number\n fireHandle?: number\n firePoint?: Vec3\n nextHeatLog: number\n torchFrame: number\n rings?: THREE_NS.Object3D\n}\n\ninterface Shell {\n mesh: THREE_NS.Object3D\n position: [number, number, number]\n velocity: [number, number, number]\n spin: [number, number, number]\n age: number\n trail: number\n landed: boolean\n start: Vec3\n}\n\n// How the flame of a lighter or of the burning jet acts on the cylinder: a source hotter than the auto-ignition of propane, held for a moment\nconst FLAME_C = 1100\nconst FLAME_RADIUS = 0.2\nconst FLAME_SECONDS = 0.3\n/** The fire chain of a part primes at 300 °C when it has no `atC` (game-destruction `FIRE_PRIME_C`). */\nconst FIRE_CHAIN_C = 300\n/** Where the fire of \"throw it in the fire\" is lit, metres from the cylinder (toward +x, the table) and for how many seconds the bench keeps it hot. */\nconst FIRE_OFFSET: Vec3 = [0.4, 0, 0.15]\nconst FIRE_VISUAL_RADIUS = 0.6\n/** The shove of the gas jet on the cylinder while it hisses (N·s per frame, against the jet) and the seconds the aftermath waits after the blast. */\nconst HISS_SHOVE = 0.35\nconst AFTERMATH_DELAY = 2\n/** The shot: the weapon of the bench and the height of the aim above the foot of the cylinder. */\nconst SHOOTER = 'pistol_9mm'\nconst AIM_HEIGHT = 0.2\nconst GRAVITY = 9.81\n/** The table and the other pieces whose state the aftermath reports. */\nconst REPORTED_OBJECTS = ['fridge', 'kitchen_cabinet_base', 'stove', 'camp_table']\nconst RING_SEGMENTS = 128\n/** The room's brick target wall (id `target_wall`, at z = -11): the aftermath reads it and the pieces it breaks into. */\nconst WALL_ID = 'target_wall'\nconst WALL_Z = -11\n\nconst dist = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\nconst num = (value: number, digits = 1): string => value.toFixed(digits)\n\nexport interface ExplosivesBenchOptions {\n readonly locale: string\n readonly text: ExplosivesText\n readonly def: ExplosiveDef\n readonly scene: { readonly cylinder: Vec3 }\n readonly room: ExplosivesRoom | undefined\n readonly blastScale: number\n readonly items?: ItemModels\n readonly profile: { readonly visualRadius?: number; readonly residualFires?: ReadonlyArray<{ readonly radius: number; readonly life: number }> } | undefined\n}\n\n/**\n * The state and the actions of the explosives area: it follows the world's events of the cylinder (leak, primed, explode), tells each phase in the room's log, plays the torch and the flight\n * of the shell (the Laboratório de Explosões, `SC.p13`) and drives the destruction world for the bench actions. The module wraps it in a `TestableModule`.\n */\nexport function createExplosivesBench(options: ExplosivesBenchOptions): ExplosivesBench {\n const { text, def, room, profile } = options\n const log = text.log\n let host: ModuleHost | null = null\n let strength = options.blastScale\n let inArea = false\n let lastBlast: ReturnType<ExplosivesBench['lastBlast']>\n let ringsOn = true\n let initial = true\n let aftermathDue: Array<{ at: number; vessel: Vessel; point: Vec3 }> = []\n const vessels = new Map<string, Vessel>()\n const wallParts = new Set<string>()\n const shells: Shell[] = []\n const T = (): typeof THREE_NS => host?.THREE as typeof THREE_NS\n const now = (): number => room?.world.time ?? 0\n const say = (message: string, data: Record<string, unknown> = {}): void => host?.log(message, { source: EXPLOSIVES_AREA_ID, ...data })\n\n const leakConfig = def.leak\n const igniteDelay = leakConfig?.igniteDelay ?? 0.8\n const hissSeconds = leakConfig?.hissSeconds ?? igniteDelay\n const chainFire = (() => {\n const fire = def.chain?.fire\n return fire === undefined ? 1.4 : typeof fire === 'number' ? fire : fire[0]\n })()\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // The cylinder in the world\n // ------------------------------------------------------------------------------------------------------------------------------------\n const liters = (vessel: Vessel): number => room?.world.part(vessel.objectId, 'tank')?.liters ?? 0\n const throughHoles = (vessel: Vessel): number => room?.world.part(vessel.objectId, 'tank')?.holes.filter((hole) => hole.through).length ?? 0\n const leaking = (vessel: Vessel): boolean => !vessel.exploded && liters(vessel) > 0 && throughHoles(vessel) > 0\n const centreOf = (vessel: Vessel): Vec3 => {\n const p = vessel.root.getWorldPosition(new (T().Vector3)())\n return [p.x, p.y + AIM_HEIGHT, p.z]\n }\n const valveOf = (vessel: Vessel): Vec3 => worldExplosiveValve(T(), vessel.root) ?? centreOf(vessel)\n const target = (): Vessel | undefined => [...vessels.values()].find((vessel) => !vessel.exploded) ?? [...vessels.values()][0]\n const lethalOf = (vessel: Vessel): number => def.lethalRadius * vessel.scale\n const injuryOf = (vessel: Vessel): number => def.injuryRadius * vessel.scale\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Rings on the floor at the lethal and injury radii\n // ------------------------------------------------------------------------------------------------------------------------------------\n const labelSprite = (words: string, colour: string, at: Vec3): THREE_NS.Object3D | null => {\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 256\n canvas.height = 64\n const context = canvas.getContext('2d')\n if (!context) return null\n context.fillStyle = colour\n context.font = 'bold 40px sans-serif'\n context.textAlign = 'center'\n context.fillText(words, 128, 46)\n const sprite = new (T().Sprite)(new (T().SpriteMaterial)({ map: new (T().CanvasTexture)(canvas), transparent: true, depthWrite: false }))\n sprite.scale.set(2.4, 0.6, 1)\n sprite.position.set(...at)\n return sprite\n } catch {\n return null\n }\n }\n const ringLine = (radius: number, colour: number): THREE_NS.Object3D => {\n const points: number[] = []\n for (let i = 0; i < RING_SEGMENTS; i++) {\n const angle = (i / RING_SEGMENTS) * Math.PI * 2\n points.push(Math.cos(angle) * radius, 0, Math.sin(angle) * radius)\n }\n const geometry = new (T().BufferGeometry)()\n geometry.setAttribute('position', new (T().Float32BufferAttribute)(points, 3))\n return new (T().LineLoop)(geometry, new (T().LineBasicMaterial)({ color: colour }))\n }\n const drawRings = (vessel: Vessel): void => {\n // a measuring overlay of the bench, not a piece\n const group = markKitOrigin(new (T().Group)(), { owner: 'game-weapons-three', kind: 'aid' })\n group.name = 'blast_rings'\n const lethal = lethalOf(vessel)\n const injury = injuryOf(vessel)\n group.add(ringLine(lethal, 0xff3b30), ringLine(injury, 0xffb020))\n const lethalLabel = labelSprite(`${num(lethal, 0)} m ${text.rings.lethal}`, '#ff6a5e', [0, 0.35, lethal])\n const injuryLabel = labelSprite(`${num(injury, 0)} m ${text.rings.injury}`, '#ffc44d', [0, 0.35, injury])\n for (const label of [lethalLabel, injuryLabel]) if (label) group.add(label)\n const p = vessel.root.getWorldPosition(new (T().Vector3)())\n group.position.set(p.x, 0.03, p.z)\n group.visible = ringsOn\n ;(host?.scene as THREE_NS.Scene).add(group)\n vessel.rings = group\n }\n const clearRings = (vessel: Vessel): void => {\n // the rings carry their own lines and two canvas labels: freed with them, or each blast leaves two textures behind\n if (vessel.rings) discardObject3D(vessel.rings)\n vessel.rings = undefined\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Phases\n // ------------------------------------------------------------------------------------------------------------------------------------\n const phaseOf = (vessel: Vessel | undefined): keyof ExplosivesText['phases'] => {\n if (!vessel) return 'rest'\n if (vessel.exploded) return 'exploded'\n if (vessel.explodeAt !== undefined) return 'primed'\n if (vessel.lit) return 'torch'\n return vessel.leakAt === undefined ? 'rest' : 'leaking'\n }\n\n /** The flame reaches the leak: the gas lights (a `heat` hit at the leak), and the world primes the fire chain. */\n const ignite = (vessel: Vessel, by: 'shot' | 'lighter'): void => {\n if (vessel.lit || vessel.exploded || !room) return\n const leak = vessel.leaks[vessel.leaks.length - 1]\n const point = leak?.point ?? valveOf(vessel)\n room.world.hit(vessel.objectId, { type: 'heat', point, temperature: FLAME_C, radius: FLAME_RADIUS, duration: FLAME_SECONDS, source: 'p13_flame' })\n vessel.lit = true\n vessel.litAt = now()\n const rest = vessel.explodeAt === undefined ? chainFire : Math.max(0, vessel.explodeAt - now())\n if (by === 'shot') say(fillText(log.jet_lit, { seconds: num(now() - (vessel.leakAt ?? now()), 1), rest: num(rest, 1) }), { phase: 'torch', objectId: vessel.objectId, seconds: now() - (vessel.leakAt ?? now()), rest })\n else say(fillText(log.lighter_lit, {}), { phase: 'torch', objectId: vessel.objectId, by })\n }\n\n const shove = (vessel: Vessel): void => {\n const leak = vessel.leaks[vessel.leaks.length - 1]\n if (!room || !leak) return\n const [dx, dy, dz] = leak.direction\n const length = Math.hypot(dx, dy, dz) || 1\n room.renderer.impulse(vessel.objectId, [(-dx / length) * HISS_SHOVE, (-dy / length) * HISS_SHOVE * 0.2, (-dz / length) * HISS_SHOVE], leak.point)\n }\n\n const torchSprites = (vessel: Vessel): void => {\n const leak = vessel.leaks[vessel.leaks.length - 1]\n if (!room || !leak) return\n const [dx, dy, dz] = leak.direction\n const length = Math.hypot(dx, dy, dz) || 1\n const flame = (): number => 3 + Math.random() * 2.5\n for (let i = 0; i < 3; i++) room.vfx.spawn('fire', leak.point, [(dx / length) * flame() + (Math.random() - 0.5) * 0.7, (dy / length) * flame() + 0.6 + (Math.random() - 0.5) * 0.7, (dz / length) * flame() + (Math.random() - 0.5) * 0.7], { size: 0.45 + Math.random() * 0.35, life: 0.7 })\n if (vessel.torchFrame++ % 3 === 0) room.vfx.spawn('smoke', leak.point, [(dx / length) * 2, 1.5, (dz / length) * 2], { size: 0.7, life: 1 })\n }\n\n const launchShell = (vessel: Vessel, point: Vec3): void => {\n const config = def.shell\n if (!config || !host) return\n const mesh = worldExplosiveShell(T(), def.id, options.items)\n if (!mesh) return\n mesh.position.set(point[0], Math.max(point[1], 0.3), point[2])\n ;(host.scene as THREE_NS.Scene).add(mesh)\n shells.push({\n mesh,\n position: [point[0], Math.max(point[1], 0.3), point[2]],\n velocity: [(Math.random() - 0.5) * 3, config.launchSpeed, (Math.random() - 0.5) * 3],\n spin: [(Math.random() - 0.5) * 12, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 12],\n age: 0,\n trail: config.trailSeconds,\n landed: false,\n start: point,\n })\n say(fillText(log.shell, { speed: num(config.launchSpeed, 0), trail: num(config.trailSeconds, 1) }), { phase: 'shell', speed: config.launchSpeed, trailSeconds: config.trailSeconds })\n void vessel\n }\n\n const stepShells = (dt: number): void => {\n if (!host) return\n for (const shell of shells) {\n if (shell.landed) continue\n shell.age += dt\n shell.velocity[1] -= GRAVITY * dt\n for (let axis = 0; axis < 3; axis++) shell.position[axis] = (shell.position[axis] as number) + (shell.velocity[axis] as number) * dt\n const ground = host.groundAt(shell.position[0], shell.position[2]) + 0.18\n if (shell.position[1] <= ground && shell.velocity[1] < 0) {\n shell.position[1] = ground\n if (Math.abs(shell.velocity[1]) > 1.5) {\n shell.velocity = [shell.velocity[0] * 0.5, -shell.velocity[1] * 0.35, shell.velocity[2] * 0.5]\n } else {\n shell.landed = true\n shell.mesh.rotation.set(Math.PI / 2, shell.mesh.rotation.y, 0)\n const away = dist(shell.start, [shell.position[0], shell.position[1], shell.position[2]])\n say(fillText(log.shell_landed, { distance: num(away, 1), seconds: num(shell.age, 1) }), { phase: 'shell_landed', distance: away, seconds: shell.age })\n }\n } else {\n shell.mesh.rotation.x += shell.spin[0] * dt\n shell.mesh.rotation.y += shell.spin[1] * dt\n shell.mesh.rotation.z += shell.spin[2] * dt\n }\n shell.mesh.position.set(shell.position[0], shell.position[1], shell.position[2])\n if (room && shell.age < shell.trail) {\n const at: Vec3 = [shell.position[0], shell.position[1], shell.position[2]]\n room.vfx.spawn('fire', at, [(Math.random() - 0.5) * 0.6, -0.3 + Math.random() * 0.4, (Math.random() - 0.5) * 0.6], { size: 0.6, life: 0.6 })\n room.vfx.spawn('smoke', at, [(Math.random() - 0.5) * 0.4, 0.2, (Math.random() - 0.5) * 0.4], { size: 0.7, life: 1.2 })\n }\n }\n }\n\n const clearShells = (): void => {\n discardObject3D(shells.map((shell) => shell.mesh))\n shells.length = 0\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // What the blast left\n // ------------------------------------------------------------------------------------------------------------------------------------\n /** The most vitality each person was seen with (the body counts raw points, 100 for a fit one): what the fraction that is left is measured against. Read at the first leak, before any blast. */\n const fullVitality = new Map<string, number>()\n const witnesses = (): ReturnType<ExplosivesBench['witnesses']> => {\n if (!room) return []\n const origin = [...vessels.values()][0]?.centre ?? options.scene.cylinder\n const found: ReturnType<ExplosivesBench['witnesses']> = []\n for (const spawned of room.spawned()) {\n const position = (spawned.root as THREE_NS.Object3D).getWorldPosition(new (T().Vector3)())\n const at: Vec3 = [position.x, position.y, position.z]\n const distance = dist([at[0], 0, at[2]], [origin[0], 0, origin[2]])\n if (spawned.itemId.startsWith('zombie_') || spawned.itemId.startsWith('person_')) {\n const state = room.world.state(spawned.objectId) as { body?: { alive?: boolean; vitality?: number } } | null\n const alive = state?.body?.alive ?? true\n const raw = state?.body?.vitality\n if (raw !== undefined) fullVitality.set(spawned.objectId, Math.max(fullVitality.get(spawned.objectId) ?? 0, raw))\n const vitality = raw === undefined ? undefined : Math.max(0, raw) / Math.max(1e-9, fullVitality.get(spawned.objectId) ?? raw)\n found.push({ kind: 'person', id: spawned.objectId, itemId: spawned.itemId, distance, alive, ...(vitality === undefined ? {} : { vitality }) })\n } else if (REPORTED_OBJECTS.includes(spawned.itemId)) {\n const parts = room.world.state(spawned.objectId)?.parts ?? []\n found.push({ kind: 'object', id: spawned.objectId, itemId: spawned.itemId, distance, broken: parts.filter((part) => part.status === 'broken').length, marks: parts.filter((part) => part.burning).length })\n }\n }\n // the wall breaks loose into pieces that are objects of their own (ids of the world), still holding the parts the wall had: count by those\n if (wallParts.size > 0) {\n let broken = 0\n let marks = 0\n let pieces = 0\n for (const id of room.world.ids()) {\n const mine = (room.world.state(id)?.parts ?? []).filter((part) => wallParts.has(part.id))\n if (mine.length === 0) continue\n pieces++\n broken += mine.filter((part) => part.status === 'broken').length\n marks += mine.reduce((n, part) => n + part.cracks.length + part.holes.length, 0)\n }\n found.push({ kind: 'wall', id: 'target_wall', itemId: 'target_wall', distance: Math.abs(WALL_Z - origin[2]), broken, marks, pieces })\n }\n return found\n }\n\n const whoIs = (itemId: string): string => (itemId.startsWith('zombie_') ? text.things.zombie : text.things.survivor)\n\n const aftermath = (point: Vec3): void => {\n for (const w of witnesses()) {\n const distance = num(w.distance, 1)\n if (w.kind === 'person') {\n const verdict = w.alive === false ? text.verdicts.dead : w.vitality !== undefined && w.vitality < 0.999 ? fillText(text.verdicts.hurt, { vitality: num(w.vitality * 100, 0) }) : text.verdicts.unhurt\n say(fillText(log.aftermath_person, { who: whoIs(w.itemId), distance, verdict }), { phase: 'aftermath', kind: w.kind, objectId: w.id, distance: w.distance, alive: w.alive, vitality: w.vitality, point })\n } else if (w.kind === 'wall') {\n const verdict = (w.pieces ?? 1) > 1 ? fillText(text.verdicts.wall_pieces, { pieces: w.pieces ?? 0, n: w.marks ?? 0 }) : (w.broken ?? 0) > 0 ? fillText(text.verdicts.wall_broken, { n: w.broken ?? 0 }) : (w.marks ?? 0) > 0 ? fillText(text.verdicts.wall_cracked, { n: w.marks ?? 0 }) : text.verdicts.wall_intact\n say(fillText(log.aftermath_wall, { verdict }), { phase: 'aftermath', kind: w.kind, objectId: w.id, broken: w.broken, marks: w.marks, pieces: w.pieces })\n } else {\n const verdict = (w.broken ?? 0) > 0 ? fillText(text.verdicts.lost_parts, { n: w.broken ?? 0 }) : (w.marks ?? 0) > 0 ? text.verdicts.burning : text.verdicts.standing\n say(fillText(log.aftermath_object, { what: text.things[w.itemId] ?? w.itemId, distance, verdict }), { phase: 'aftermath', kind: w.kind, objectId: w.id, distance: w.distance, broken: w.broken })\n }\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Events of the world\n // ------------------------------------------------------------------------------------------------------------------------------------\n const onEvent = (event: DestructionEvent): void => {\n const vessel = vessels.get(event.object)\n if (!vessel || !('part' in event) || event.part !== 'tank') return\n if (event.type === 'leak') {\n witnesses()\n if (vessel.leakAt === undefined) {\n vessel.leakAt = event.time\n vessel.cause = vessel.valveRequested ? 'valve' : 'shot'\n }\n vessel.valveRequested = false\n vessel.leaks.push({ point: event.point, direction: event.direction, rate: event.rate })\n if (vessel.leaks.length > 8) vessel.leaks.shift()\n const holes = room?.world.part(vessel.objectId, 'tank')?.holes ?? []\n const diameter = (holes[holes.length - 1]?.diameter ?? 0.009) * 1000\n const vars = { diameter: num(diameter, 0), rate: num(event.rate, 2), liters: num(liters(vessel), 1) }\n say(fillText(vessel.cause === 'valve' && vessel.leaks.length === 1 ? log.leak_valve : log.leak_shot, vars), { phase: 'leak', objectId: vessel.objectId, cause: vessel.cause, ratePerS: event.rate, diameterMm: diameter, liters: liters(vessel), pressurized: event.pressurized })\n } else if (event.type === 'primed') {\n vessel.explodeAt = event.time + event.delay\n say(fillText(log.primed, { trigger: text.triggers[event.trigger], delay: num(event.delay, 1) }), { phase: 'primed', objectId: vessel.objectId, trigger: event.trigger, delaySeconds: event.delay })\n } else if (event.type === 'explode') {\n vessel.exploded = true\n vessel.explodedAt = event.time\n vessel.centre = event.point\n const radius = profile?.visualRadius\n const fireball = (radius ?? 2) * 2\n const lethal = lethalOf(vessel)\n const injury = injuryOf(vessel)\n say(fillText(log.explode, { fireball: num(fireball, 1), lethal: num(lethal, 1), injury: num(injury, 1), energy: num((def.energy * vessel.scale) / 1000, 0), scale: num(vessel.scale, 2) }), {\n phase: 'explode', objectId: vessel.objectId, fireballMetres: fireball, lethalRadius: lethal, injuryRadius: injury, energyJ: def.energy * vessel.scale, scale: vessel.scale, point: event.point,\n sinceLeakSeconds: vessel.leakAt === undefined ? undefined : event.time - vessel.leakAt,\n })\n const residual = profile?.residualFires?.[0]\n if (residual) say(fillText(log.residual, { radius: num(residual.radius, 1), seconds: num(residual.life, 0) }), { phase: 'residual', radius: residual.radius, seconds: residual.life })\n if (vessel.fireHandle !== undefined) room?.vfx.stop(vessel.fireHandle)\n launchShell(vessel, event.point)\n aftermathDue.push({ at: now() + AFTERMATH_DELAY, vessel, point: event.point })\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // The frame\n // ------------------------------------------------------------------------------------------------------------------------------------\n const frame = (dt: number): void => {\n const t = now()\n for (const vessel of vessels.values()) {\n if (vessel.exploded) {\n vessel.lit = false\n continue\n }\n if (vessel.leakAt !== undefined) {\n // the white jet hisses and shoves the cylinder; a hole in the shell lights after the delay of the arsenal (the valve waits for a flame)\n if (t - vessel.leakAt <= hissSeconds && leaking(vessel)) shove(vessel)\n if (vessel.cause === 'shot' && !vessel.lit && t - vessel.leakAt >= igniteDelay && leaking(vessel)) ignite(vessel, 'shot')\n }\n if (vessel.lit) {\n if (leaking(vessel)) torchSprites(vessel)\n else vessel.lit = false\n }\n if (vessel.fireUntil !== undefined && t < vessel.fireUntil && room && vessel.firePoint) {\n const fire = def.fire\n room.world.hit(vessel.objectId, { type: 'heat', point: vessel.firePoint, temperature: fire?.temperature ?? 700, radius: fire?.radius ?? 1.4, duration: dt, source: 'p13_fire' })\n if (vessel.explodeAt === undefined && t >= vessel.nextHeatLog) {\n vessel.nextHeatLog = t + 1\n say(fillText(log.heating, { temperature: num(room.world.part(vessel.objectId, 'tank')?.temperature ?? 0, 0), limit: num(FIRE_CHAIN_C, 0) }), { phase: 'heating', objectId: vessel.objectId })\n }\n }\n }\n stepShells(dt)\n if (aftermathDue.length > 0) {\n const ready = aftermathDue.filter((entry) => entry.at <= t)\n aftermathDue = aftermathDue.filter((entry) => entry.at > t)\n for (const entry of ready) aftermath(entry.point)\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // The actions of the bench\n // ------------------------------------------------------------------------------------------------------------------------------------\n const needRoom = (): boolean => {\n if (room) return true\n say(log.no_room)\n return false\n }\n const withVessel = (): Vessel | undefined => {\n const vessel = target()\n if (!vessel || vessel.exploded) say(log.no_vessel)\n return vessel && !vessel.exploded ? vessel : undefined\n }\n\n const shoot = (): boolean => {\n if (!needRoom() || !room || !host) return false\n const vessel = withVessel()\n if (!vessel) return false\n if (host.tool().weapon !== SHOOTER) room.setTool(SHOOTER)\n room.waitUntilReady()\n const eye = (host.camera as THREE_NS.Camera).position\n const aim = centreOf(vessel)\n room.look([eye.x, eye.y, eye.z], aim)\n say(fillText(log.shoot, { distance: num(dist([eye.x, eye.y, eye.z], aim), 1) }), { phase: 'shoot', objectId: vessel.objectId, weapon: SHOOTER })\n room.use()\n return true\n }\n\n const valve = (): boolean => {\n if (!needRoom() || !room) return false\n const vessel = withVessel()\n if (!vessel) return false\n if (vessel.valveOpen) {\n if (vessel.explodeAt !== undefined) {\n say(log.valve_closed_late, { phase: 'valve', objectId: vessel.objectId })\n return false\n }\n room.world.seal(vessel.objectId, 'tank')\n vessel.valveOpen = false\n if (throughHoles(vessel) === 0) {\n vessel.leakAt = undefined\n vessel.cause = undefined\n vessel.leaks = []\n vessel.lit = false\n }\n say(fillText(log.valve_closed, { liters: num(liters(vessel), 1) }), { phase: 'valve_closed', objectId: vessel.objectId, liters: liters(vessel) })\n return true\n }\n vessel.valveRequested = true\n const opened = room.world.vent(vessel.objectId, 'tank', { point: valveOf(vessel), normal: [0, 1, 0] })\n vessel.valveRequested = false\n vessel.valveOpen = opened\n return opened\n }\n\n const light = (): boolean => {\n if (!needRoom() || !room) return false\n const vessel = withVessel()\n if (!vessel) return false\n const at = vessel.leaks[vessel.leaks.length - 1]?.point ?? valveOf(vessel)\n room.vfx.burst('fire', at, [0, 1, 0], 6, 0.8)\n if (!leaking(vessel)) {\n say(log.lighter_none, { phase: 'lighter', objectId: vessel.objectId, leaking: false })\n return false\n }\n ignite(vessel, 'lighter')\n return true\n }\n\n const fire = (): boolean => {\n if (!needRoom() || !room) return false\n const vessel = withVessel()\n if (!vessel) return false\n const base = vessel.root.getWorldPosition(new (T().Vector3)())\n const point: Vec3 = [base.x + FIRE_OFFSET[0], base.y + FIRE_OFFSET[1], base.z + FIRE_OFFSET[2]]\n const config = def.fire ?? { temperature: 700, radius: 1.4, seconds: 7 }\n vessel.firePoint = point\n vessel.fireUntil = now() + config.seconds + 3\n vessel.nextHeatLog = now()\n vessel.fireHandle = room.vfx.fire({ point, radius: FIRE_VISUAL_RADIUS, life: config.seconds + 3 })\n // the table next to it catches too\n for (const spawned of room.spawned()) {\n if (spawned.itemId !== 'camp_table') continue\n const top = (spawned.root as THREE_NS.Object3D).getWorldPosition(new (T().Vector3)())\n room.world.hit(spawned.objectId, { type: 'heat', point: [top.x, top.y + 0.7, top.z], temperature: config.temperature + 200, radius: 0.9, duration: 3, source: 'p13_fire' })\n }\n say(fillText(log.fire_set, { temperature: num(config.temperature, 0), radius: num(config.radius, 1) }), { phase: 'fire', objectId: vessel.objectId, temperatureC: config.temperature, radius: config.radius })\n return true\n }\n\n const reset = (): boolean => {\n if (!needRoom() || !room) return false\n room.openArea(EXPLOSIVES_AREA_ID)\n say(fillText(log.reset, { scale: num(strength, 2) }), { phase: 'reset', scale: strength })\n return true\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Bench declaration\n // ------------------------------------------------------------------------------------------------------------------------------------\n const actionIds = ['shoot', 'valve', 'light', 'fire', 'reset'] as const\n const actions = { shoot, valve, light, fire, reset }\n\n const sheet = (): BenchSheet => {\n const energy = (def.energy * strength) / 1000\n return {\n kicker: text.sheet.kicker,\n title: text.sheet.title,\n body: text.sheet.body,\n facts: [\n { label: text.sheet.facts.energy, value: `${num(energy, 0)} kJ (x${num(strength, 2)})` },\n { label: text.sheet.facts.lethal, value: `${num(def.lethalRadius * strength, 1)} m` },\n { label: text.sheet.facts.injury, value: `${num(def.injuryRadius * strength, 1)} m` },\n { label: text.sheet.facts.gas, value: `${num(leakConfig?.liters ?? 0, 0)} l` },\n { label: text.sheet.facts.mass, value: `${num(def.mass ?? 0, 0)} kg` },\n { label: text.sheet.facts.torch, value: `${num(igniteDelay, 1)} s` },\n { label: text.sheet.facts.shot_chain, value: `${num(typeof def.chain?.shot === 'number' ? def.chain.shot : (def.chain?.shot?.[0] ?? 0), 1)} s` },\n { label: text.sheet.facts.fire_chain, value: `${num(chainFire, 1)} s` },\n ],\n steps: text.sheet.steps,\n note: text.sheet.note,\n timeline: {\n segments: [\n { name: text.sheet.segments.jet, start: 0, end: igniteDelay, color: '#e8eef2' },\n { name: text.sheet.segments.torch, start: igniteDelay, end: chainFire, color: '#ff9a2e' },\n { name: text.sheet.segments.blast, start: chainFire, end: chainFire + 1, color: '#ff4d2e' },\n ],\n ticks: [0, igniteDelay, chainFire],\n metric: 'clock',\n },\n }\n }\n\n const adopt = (data: unknown): void => {\n const spawned = data as { objectId: string; itemId: string; root: THREE_NS.Object3D }\n if (spawned.itemId !== `${WORLD_EXPLOSIVE_PREFIX}${def.id}`) return\n const vessel: Vessel = { objectId: spawned.objectId, root: spawned.root, scale: strength, leaks: [], valveRequested: false, valveOpen: false, lit: false, exploded: false, nextHeatLog: 0, torchFrame: 0 }\n vessels.set(vessel.objectId, vessel)\n if (wallParts.size === 0) for (const part of room?.world.state(WALL_ID)?.parts ?? []) wallParts.add(part.id)\n if (inArea && host) drawRings(vessel)\n }\n\n const change = (change: BenchChange): void => {\n if (change.kind === 'action') {\n if ((actionIds as readonly string[]).includes(change.id)) actions[change.id as (typeof actionIds)[number]]()\n } else if (change.kind === 'layer' && change.id === 'rings') {\n ringsOn = change.on\n for (const vessel of vessels.values()) if (vessel.rings) vessel.rings.visible = ringsOn\n } else if (change.kind === 'control' && change.id === 'blast_scale' && typeof change.value === 'number') {\n // the first change is the host's echo of the declared default\n const first = initial\n initial = false\n if (change.value === strength && !first) return\n strength = change.value\n host?.bench?.sheet?.(sheet())\n if (first) return\n say(fillText(log.scale, { scale: num(strength, 2), energy: num((def.energy * strength) / 1000, 0), lethal: num(def.lethalRadius * strength, 1), injury: num(def.injuryRadius * strength, 1) }), { phase: 'scale', scale: strength })\n if (inArea) reset()\n }\n }\n\n return {\n room,\n def,\n blastScale: () => strength,\n areaOpened: () => {\n inArea = true\n },\n controls: (): ModuleControl[] => [\n ...actionIds.map((id) => ({ kind: 'action' as const, id, name: text.actions[id].name, hint: text.actions[id].hint })),\n { kind: 'number', id: 'blast_scale', name: text.blastScale.name, hint: text.blastScale.hint, unit: 'x', min: 0.25, max: 3, step: 0.05, default: options.blastScale },\n ],\n layers: (): ModuleLayer[] => [{ id: 'rings', name: text.layers.rings }],\n metrics: (): ModuleMetric[] => [\n { id: 'gas', name: text.metrics.gas, unit: 'l', digits: 1, max: leakConfig?.liters ?? 24, read: () => liters(target() ?? ({ objectId: '' } as Vessel)) },\n { id: 'clock', name: text.metrics.clock, unit: 's', digits: 2, read: () => { const v = target(); return v?.leakAt === undefined ? 0 : (v.explodedAt ?? now()) - v.leakAt } },\n { id: 'phase', name: text.metrics.phase, read: () => text.phases[phaseOf(target())] },\n ],\n attach(lent: ModuleHost): () => void {\n host = lent\n const offs: Array<() => void> = []\n if (room) {\n offs.push(room.world.on('*', onEvent))\n offs.push(room.on('spawn', adopt))\n for (const spawned of room.spawned()) adopt(spawned)\n }\n offs.push(\n lent.on((event) => {\n if (event.type === 'explosion') lastBlast = { point: event.point, energy: event.energy, radius: event.radius, cause: event.cause, ...(event.explosive === undefined ? {} : { explosive: event.explosive }), ...(event.tnt === undefined ? {} : { tnt: event.tnt }) }\n }),\n )\n offs.push(lent.onFrame(frame))\n offs.push(lent.bench?.onChange(change) ?? (() => undefined))\n offs.push(\n lent.onClear?.(() => {\n for (const vessel of vessels.values()) clearRings(vessel)\n vessels.clear()\n clearShells()\n wallParts.clear()\n aftermathDue = []\n lastBlast = undefined\n inArea = false\n }) ?? (() => undefined),\n )\n lent.bench?.sheet?.(sheet())\n return () => {\n for (const off of offs) off()\n for (const vessel of vessels.values()) clearRings(vessel)\n vessels.clear()\n clearShells()\n host = null\n }\n },\n actions,\n vessel: (): VesselView | undefined => {\n const v = target()\n if (!v) return undefined\n return { objectId: v.objectId, leakAt: v.leakAt, litAt: v.litAt, explodedAt: v.explodedAt, cause: v.cause, valveOpen: v.valveOpen, lit: v.lit, exploded: v.exploded, point: v.leaks[v.leaks.length - 1]?.point }\n },\n lastBlast: () => lastBlast,\n witnesses,\n }\n}\n","/** The words of the explosives area (the P13 cylinder bench and its narration), by locale (`en` and `pt-BR`). `{name}` marks a value the module fills in. */\nexport interface ExplosivesText {\n group: string\n name: string\n cylinder: string\n actions: Record<'shoot' | 'valve' | 'light' | 'fire' | 'reset', { name: string; hint: string }>\n blastScale: { name: string; hint: string }\n layers: Record<'rings', string>\n metrics: Record<'gas' | 'clock' | 'phase', string>\n phases: Record<'rest' | 'leaking' | 'torch' | 'primed' | 'exploded', string>\n rings: { lethal: string; injury: string }\n triggers: Record<'shot' | 'fire' | 'explosion', string>\n things: Record<string, string>\n verdicts: { wall_pieces: string; lost_parts: string; dead: string; hurt: string; unhurt: string; wall_broken: string; wall_cracked: string; wall_intact: string; burning: string; standing: string }\n log: {\n leak_shot: string\n leak_valve: string\n valve_closed: string\n valve_closed_late: string\n primed: string\n jet_lit: string\n jet_lit_by: string\n lighter_none: string\n lighter_lit: string\n fire_set: string\n heating: string\n explode: string\n shell: string\n shell_landed: string\n residual: string\n aftermath_person: string\n aftermath_wall: string\n aftermath_object: string\n reset: string\n scale: string\n no_room: string\n shoot: string\n no_vessel: string\n }\n sheet: {\n kicker: string\n title: string\n body: string\n facts: Record<'energy' | 'lethal' | 'injury' | 'gas' | 'mass' | 'torch' | 'shot_chain' | 'fire_chain', string>\n steps: Array<{ at: string; text: string }>\n segments: Record<'jet' | 'torch' | 'blast', string>\n note: string\n }\n scenarios: {\n shot: string\n shot_leak: string\n shot_ignite: string\n shot_explode: string\n shot_zombie: string\n shot_survivor: string\n shot_wall: string\n valve: string\n valve_leak: string\n valve_quiet: string\n valve_lit: string\n valve_explode: string\n fire: string\n fire_explode: string\n chain: string\n chain_explode: string\n push_p13: string\n push_grenade: string\n push_found: string\n push_told: string\n push_outward: string\n push_falloff: string\n push_person_wave: string\n push_sheltered: string\n push_heavy: string\n }\n}\n\nexport const EXPLOSIVES_TEXT: Record<string, ExplosivesText> = {\n en: {\n group: 'Explosives',\n name: 'Explosives area',\n cylinder: 'Propane cylinder (P13)',\n actions: {\n shoot: { name: 'Shoot the cylinder', hint: 'Equips the 9 mm pistol, aims at the cylinder and fires: a hole in the shell, a white gas jet, a torch, the blast' },\n valve: { name: 'Open the valve', hint: 'Opens (or closes) the valve: the gas leaks with no fire until a flame reaches it' },\n light: { name: 'Light it (lighter)', hint: 'Holds a lighter flame at the valve: a gas leak catches fire and the cylinder goes off' },\n fire: { name: 'Throw it in the fire', hint: 'Lights a fire next to the cylinder (and the table): the shell heats up until the fire chain sets it off' },\n reset: { name: 'Restart', hint: 'Lays the scene again: a new cylinder, wall, furniture and people' },\n },\n blastScale: { name: 'Blast strength (game multiplier)', hint: 'Multiplies the energy and the lethal and injury radii of the P13 for the next one laid (restarts the scene). 1 is the arsenal; the arsenal itself is changed with ArsenalOptions.patch.explosives.propane_p13' },\n layers: { rings: 'Lethal and injury rings' },\n metrics: { gas: 'Gas left in the cylinder', clock: 'Seconds since the first leak', phase: 'Phase' },\n phases: { rest: 'At rest', leaking: 'Leaking gas', torch: 'Burning jet', primed: 'About to go off', exploded: 'Exploded' },\n rings: { lethal: 'lethal', injury: 'injury' },\n triggers: { shot: 'a bullet', fire: 'fire', explosion: 'another blast' },\n things: { zombie: 'Zombie', survivor: 'Survivor', fridge: 'Fridge', kitchen_cabinet_base: 'Kitchen cabinet', stove: 'Stove', camp_table: 'Table', can: 'Can of beans', bottle: 'Water bottle', chair: 'Chair' },\n verdicts: { wall_pieces: 'broke loose into {pieces} pieces and cracked ({n} marks)', lost_parts: 'lost {n} parts', dead: 'dead', hurt: 'hurt (vitality {vitality}%)', unhurt: 'unhurt', wall_broken: 'cracked and lost {n} brick panels', wall_cracked: 'cracked ({n} marks)', wall_intact: 'intact', burning: 'burning', standing: 'standing' },\n log: {\n leak_shot: 'Hole of {diameter} mm in the shell: gas leaking at {rate} l/s ({liters} l left in the cylinder)',\n leak_valve: 'Valve open: gas leaking at {rate} l/s with no fire ({liters} l left in the cylinder)',\n valve_closed: 'Valve closed: the leak stopped ({liters} l left)',\n valve_closed_late: 'Too late to close the valve: the cylinder is already going off',\n primed: 'The cylinder was set off by {trigger}: it goes off in {delay} s',\n jet_lit: 'The jet caught fire (torch) {seconds} s after the hole; the cylinder goes off in {rest} s',\n jet_lit_by: 'The leaking gas caught fire (torch) from {by}; the cylinder goes off in {rest} s',\n lighter_none: 'Lighter flame at the valve: no gas is leaking, nothing happens',\n lighter_lit: 'Lighter flame at the leaking valve: the gas lights',\n fire_set: 'Fire lit next to the cylinder ({temperature} °C, radius {radius} m): the shell heats up',\n heating: 'Shell at {temperature} °C (the fire chain starts at {limit} °C)',\n explode: 'Cylinder exploded: fireball of {fireball} m, lethal up to {lethal} m, injuries up to {injury} m (energy {energy} kJ, strength x{scale})',\n shell: 'The torn shell flew up at {speed} m/s trailing fire for {trail} s',\n shell_landed: 'The shell came down {distance} m away after {seconds} s',\n residual: 'Residual fire of {radius} m for {seconds} s',\n aftermath_person: '{who} at {distance} m: {verdict}',\n aftermath_wall: 'Wall behind the cylinder: {verdict}',\n aftermath_object: '{what} at {distance} m: {verdict}',\n reset: 'Scene laid again with a blast strength of x{scale}',\n scale: 'Blast strength x{scale}: energy {energy} kJ, lethal {lethal} m, injury {injury} m (valid for the next cylinder; the scene restarts)',\n no_room: 'The explosives area was loaded without the room: this action needs it',\n shoot: '9 mm shot at the cylinder from {distance} m',\n no_vessel: 'There is no cylinder in the scene (restart it)',\n },\n sheet: {\n kicker: 'P13 cooking gas cylinder',\n title: 'What happens to a P13 under a bullet, a flame or a blast',\n body: 'Every kitchen has one. It goes off from a bullet or from fire, and it chains. The sequence is the Explosives Lab one (SC.p13): the gas jet hisses, catches fire as a torch, and the shell goes off.',\n facts: { energy: 'Energy', lethal: 'Lethal radius', injury: 'Injury radius', gas: 'Gas', mass: 'Mass', torch: 'Torch after the hole', shot_chain: 'Blast after a bullet', fire_chain: 'Blast after fire' },\n steps: [\n { at: '0 s', text: 'The bullet goes through the 2.5 mm steel shell: a white gas jet leaves the hole, hissing and shoving the cylinder' },\n { at: '0.8 s', text: 'The jet catches fire and burns as a torch at the hole' },\n { at: '1.4 s', text: 'The fuel fireball (light 70), the mushroom rises 7 m over 8 s, the shell flies up at 13 m/s trailing fire' },\n { at: '1.4 s - 8.4 s', text: 'Residual fire of 1.4 m for 7 s; walls, furniture and people inside the rings take the blast' },\n ],\n segments: { jet: 'White gas jet', torch: 'Torch', blast: 'Blast' },\n note: 'Opening the valve leaks the gas with no fire; a flame near it lights the leak and the cylinder goes off 1.4 s later. The numbers come from the arsenal (propane_p13); the strength multiplier is a game value.',\n },\n scenarios: {\n shot: 'P13 cylinder: a 9 mm through the shell leaks gas, the jet lights and the cylinder goes off with its chain delay',\n shot_leak: 'The shot made a gas leak with a white pressurized jet',\n shot_ignite: 'The jet caught fire (torch) between 0.7 and 1.0 s after the hole',\n shot_explode: 'The cylinder exploded within 1.6 s of the shot',\n shot_zombie: 'The zombie 3 m from the cylinder did not survive the blast',\n shot_survivor: 'The survivor 8 m away, past the lethal ring, is hurt but alive',\n shot_wall: 'The brick wall behind it was marked by the blast',\n valve: 'P13 cylinder: the open valve leaks gas without fire and the cylinder goes off only when a flame lights it',\n valve_leak: 'The open valve leaks gas',\n valve_quiet: 'Four seconds of leaking gas with no flame: no fire and no blast',\n valve_lit: 'The lighter flame lit the leak',\n valve_explode: 'The cylinder went off within 1.6 s of the flame',\n fire: 'P13 cylinder in a fire: the heat sets it off by the fire chain',\n fire_explode: 'The cylinder in the fire exploded',\n chain: 'P13 cylinder: another blast next to it sets it off by the explosion chain',\n chain_explode: 'The second cylinder exploded after the first one',\n push_p13: 'P13 blast: the loose items, the furniture and the people around it are thrown away from it, less the farther they stand',\n push_grenade: 'Thrown M67 grenade: the loose items and the people around it are thrown away from it, less the farther they stand',\n push_told: 'The explosion reached the host as an event',\n push_found: '{n} bodies were laid around the blast to be measured ({kinds})',\n push_outward: 'Every body inside the reach moved away from the blast ({moved} of {n}, {least} m at the least)',\n push_falloff: '{what}: the nearer one moved more than the farther one ({near} m at {nearDistance} m, {far} m at {farDistance} m)',\n push_person_wave: '{who} at {distance} m moved {moved} m away, no farther than the blast wave pushes a person ({most} m at most)',\n push_sheltered: '{what} at {distance} m stood behind cover ({cover}% of the blast got through) and moved only {moved} m',\n push_heavy: '{what} (too heavy to grab, not fixed) was moved {moved} m by the blast',\n },\n },\n 'pt-BR': {\n group: 'Explosivos',\n name: 'Área de explosivos',\n cylinder: 'Botijão de gás (P13)',\n actions: {\n shoot: { name: 'Atirar no botijão', hint: 'Equipa a pistola 9 mm, mira no botijão e atira: furo no casco, jato branco de gás, maçarico, explosão' },\n valve: { name: 'Abrir o registro', hint: 'Abre (ou fecha) o registro: o gás vaza sem fogo até uma chama encostar' },\n light: { name: 'Acender (isqueiro)', hint: 'Põe a chama de um isqueiro no registro: gás vazando pega fogo e o botijão explode' },\n fire: { name: 'Jogar no fogo', hint: 'Acende um fogo ao lado do botijão (e da mesa): o casco esquenta até a cadeia de fogo detonar' },\n reset: { name: 'Reiniciar', hint: 'Monta a cena de novo: botijão novo, parede, móveis e pessoas' },\n },\n blastScale: { name: 'Força da explosão (multiplicador de jogo)', hint: 'Multiplica a energia e os raios letal e de ferimento do P13 para o próximo botijão montado (reinicia a cena). 1 é o arsenal; o arsenal em si muda com ArsenalOptions.patch.explosives.propane_p13' },\n layers: { rings: 'Anéis letal e de ferimento' },\n metrics: { gas: 'Gás no botijão', clock: 'Segundos desde o primeiro vazamento', phase: 'Fase' },\n phases: { rest: 'Em repouso', leaking: 'Vazando gás', torch: 'Jato em chamas', primed: 'Prestes a explodir', exploded: 'Explodiu' },\n rings: { lethal: 'letal', injury: 'ferimento' },\n triggers: { shot: 'um tiro', fire: 'fogo', explosion: 'outra explosão' },\n things: { zombie: 'Zumbi', survivor: 'Sobrevivente', fridge: 'Geladeira', kitchen_cabinet_base: 'Armário de cozinha', stove: 'Fogão', camp_table: 'Mesa', can: 'Lata de feijão', bottle: 'Garrafa de água', chair: 'Cadeira' },\n verdicts: { wall_pieces: 'se soltou em {pieces} pedaços e trincou ({n} marcas)', lost_parts: 'perdeu {n} peças', dead: 'morto', hurt: 'ferido (vitalidade {vitality}%)', unhurt: 'ileso', wall_broken: 'trincou e perdeu {n} painéis de tijolo', wall_cracked: 'trincou ({n} marcas)', wall_intact: 'intacta', burning: 'pegando fogo', standing: 'de pé' },\n log: {\n leak_shot: 'Furo de {diameter} mm no casco: gás vazando a {rate} l/s ({liters} l no botijão)',\n leak_valve: 'Registro aberto: gás vazando a {rate} l/s, sem fogo ({liters} l no botijão)',\n valve_closed: 'Registro fechado: o vazamento parou ({liters} l restantes)',\n valve_closed_late: 'Tarde demais para fechar o registro: o botijão já vai explodir',\n primed: 'O botijão foi detonado por {trigger}: explode em {delay} s',\n jet_lit: 'O jato pegou fogo (maçarico) {seconds} s depois do furo; o botijão explode em {rest} s',\n jet_lit_by: 'O gás vazando pegou fogo (maçarico) por {by}; o botijão explode em {rest} s',\n lighter_none: 'Chama do isqueiro no registro: não há gás vazando, nada acontece',\n lighter_lit: 'Chama do isqueiro no registro que vaza: o gás acendeu',\n fire_set: 'Fogo aceso ao lado do botijão ({temperature} °C, raio {radius} m): o casco esquenta',\n heating: 'Casco a {temperature} °C (a cadeia de fogo começa em {limit} °C)',\n explode: 'Botijão explodiu: bola de fogo de {fireball} m, letal até {lethal} m, ferimentos até {injury} m (energia {energy} kJ, força x{scale})',\n shell: 'O casco rasgado voou para cima a {speed} m/s com rastro de fogo por {trail} s',\n shell_landed: 'O casco caiu a {distance} m depois de {seconds} s',\n residual: 'Fogo residual de {radius} m por {seconds} s',\n aftermath_person: '{who} a {distance} m: {verdict}',\n aftermath_wall: 'Parede atrás do botijão: {verdict}',\n aftermath_object: '{what} a {distance} m: {verdict}',\n reset: 'Cena montada de novo com força de explosão x{scale}',\n scale: 'Força da explosão x{scale}: energia {energy} kJ, letal {lethal} m, ferimento {injury} m (vale para o próximo botijão; a cena reinicia)',\n no_room: 'A área de explosivos foi carregada sem a sala: esta ação precisa dela',\n shoot: 'Tiro de 9 mm no botijão a {distance} m',\n no_vessel: 'Não há botijão na cena (reinicie)',\n },\n sheet: {\n kicker: 'Botijão de gás de cozinha P13',\n title: 'O que acontece com um P13 sob um tiro, uma chama ou uma explosão',\n body: 'Toda cozinha tem um. Explode com tiro ou fogo, e entra em cadeia. A sequência é a do Laboratório de Explosões (SC.p13): o jato de gás assobia, pega fogo como maçarico e o casco explode.',\n facts: { energy: 'Energia', lethal: 'Raio letal', injury: 'Raio de ferimento', gas: 'Gás', mass: 'Massa', torch: 'Maçarico após o furo', shot_chain: 'Explosão após um tiro', fire_chain: 'Explosão após fogo' },\n steps: [\n { at: '0 s', text: 'A bala atravessa o casco de aço de 2,5 mm: um jato branco de gás sai do furo, assobiando e sacudindo o botijão' },\n { at: '0,8 s', text: 'O jato pega fogo e queima como maçarico no furo' },\n { at: '1,4 s', text: 'A bola de fogo de combustível (luz 70), o cogumelo sobe 7 m em 8 s, o casco voa a 13 m/s com rastro de fogo' },\n { at: '1,4 s - 8,4 s', text: 'Fogo residual de 1,4 m por 7 s; paredes, móveis e pessoas dentro dos anéis levam a explosão' },\n ],\n segments: { jet: 'Jato branco de gás', torch: 'Maçarico', blast: 'Explosão' },\n note: 'Abrir o registro vaza o gás sem fogo; uma chama perto acende o vazamento e o botijão explode 1,4 s depois. Os números vêm do arsenal (propane_p13); o multiplicador de força é um valor de jogo.',\n },\n scenarios: {\n shot: 'Botijão P13: um 9 mm no casco vaza gás, o jato acende e o botijão explode com o atraso da cadeia',\n shot_leak: 'O tiro fez um vazamento de gás com jato branco pressurizado',\n shot_ignite: 'O jato pegou fogo (maçarico) entre 0,7 e 1,0 s depois do furo',\n shot_explode: 'O botijão explodiu até 1,6 s depois do tiro',\n shot_zombie: 'O zumbi a 3 m do botijão não sobreviveu à explosão',\n shot_survivor: 'O sobrevivente a 8 m, depois do anel letal, fica ferido mas vivo',\n shot_wall: 'A parede de tijolo atrás dele ficou marcada pela explosão',\n valve: 'Botijão P13: o registro aberto vaza gás sem fogo e o botijão só explode quando uma chama acende',\n valve_leak: 'O registro aberto vaza gás',\n valve_quiet: 'Quatro segundos de gás vazando sem chama: sem fogo e sem explosão',\n valve_lit: 'A chama do isqueiro acendeu o vazamento',\n valve_explode: 'O botijão explodiu até 1,6 s depois da chama',\n fire: 'Botijão P13 no fogo: o calor detona pela cadeia de fogo',\n fire_explode: 'O botijão no fogo explodiu',\n chain: 'Botijão P13: outra explosão ao lado detona pela cadeia de explosão',\n chain_explode: 'O segundo botijão explodiu depois do primeiro',\n push_p13: 'Explosão do P13: os itens soltos, os móveis e as pessoas em volta são jogados para longe, menos quanto mais longe estão',\n push_grenade: 'Granada M67 arremessada: os itens soltos e as pessoas em volta são jogados para longe, menos quanto mais longe estão',\n push_told: 'A explosão chegou ao host como evento',\n push_found: '{n} corpos foram postos em volta da explosão para serem medidos ({kinds})',\n push_outward: 'Todo corpo dentro do alcance se afastou da explosão ({moved} de {n}, no mínimo {least} m)',\n push_falloff: '{what}: o mais perto andou mais que o mais longe ({near} m a {nearDistance} m, {far} m a {farDistance} m)',\n push_person_wave: '{who} a {distance} m se afastou {moved} m, não mais do que a onda da explosão empurra uma pessoa (no máximo {most} m)',\n push_sheltered: '{what} a {distance} m estava atrás de cobertura ({cover}% da explosão passou) e andou só {moved} m',\n push_heavy: '{what} (pesado demais para pegar, mas solto) foi movido {moved} m pela explosão',\n },\n },\n}\n\nexport const explosivesTextOf = (locale: string): ExplosivesText => EXPLOSIVES_TEXT[locale] ?? (EXPLOSIVES_TEXT.en as ExplosivesText)\n\n/** Fills `{name}` marks of a template. */\nexport const fillText = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n","import { blastBodySpeed, DEFAULT_BLAST_IMPULSE } from '@adatechnology/game-contracts'\nimport type { DestructionEvent, ModuleScenario, Vec3 } from '@adatechnology/game-contracts'\nimport { EXPLOSIVES_AREA_ID } from './explosives-bench'\nimport type { ExplosivesBench, ExplosivesRoom } from './explosives-bench'\nimport { explosivesTextOf, fillText } from './explosives-text'\nimport { WORLD_EXPLOSIVE_PREFIX } from '../world-explosives'\n\n/** The members of the test room's `ScenarioContext` these scenarios use (structural: this package does not depend on the room). */\ninterface ScenarioContext {\n room: ExplosivesRoom\n step(seconds: number): void\n expect(ok: boolean, label: string, data?: Record<string, unknown>): void\n}\n\n/** The time the torch is expected after the hole and the longest the blast may take after a trigger of the shot chain (the chain says 1.4 s; the scenario allows a margin). */\nconst TORCH_WINDOW: [number, number] = [0.7, 1.0]\nconst BLAST_WITHIN = 1.6\nconst CYLINDER_ITEM = `${WORLD_EXPLOSIVE_PREFIX}propane_p13`\n\n\n/** Loose things laid around a blast to be measured: the kind and the item of the goods catalogue (the distances are in PUSH_LAYOUT). */\nconst PUSH_KINDS: ReadonlyArray<{ readonly kind: 'can' | 'bottle' | 'chair'; readonly item: string }> = [\n { kind: 'can', item: 'item_canned_beans' },\n { kind: 'bottle', item: 'item_water_bottle' },\n { kind: 'chair', item: 'dining_chair' },\n]\n/** Seconds after the blast at which the shove is read: the bodies are still flying, not yet piled against each other. */\nconst PUSH_READ_AT = 0.8\n/** Metres a body must move to count as moved. */\nconst MOVED = 0.15\n/** Below this share of the blast getting through the cover (a stove, a cupboard, a fridge between), a body is sheltered: it is not expected to fly, only to move less than in the open. */\nconst SHELTERED = 0.5\n/** Least bound (m) on how far a sheltered body may move outward: behind solid cover the blast barely reaches it. */\nconst SHELTERED_MOST = 1\n/** Height (m) of the point of a body the blast is measured at: the chest of a person, the middle of a loose thing. */\nconst CHEST = 1.1\nconst MIDDLE = 0.3\n/** Metres around a body its drawn boxes are looked for in (a chair is the widest of them). */\nconst AIM_SEARCH = 1.5\n/** The heavy, free furniture of the area that the blast also reaches (a table too heavy to grab, not fixed). */\nconst HEAVY_ITEMS = ['camp_table']\n/** Mass (kg) of a person of the area, the slowing of a body sliding on the ground (m/s², `stepKnock`), and the slack (m) a body may move beyond the wave's push (a step, a fall). */\nconst PERSON_MASS = 70\nconst GROUND_FRICTION = 7\nconst PERSON_SLACK = 0.4\n\ninterface Placed {\n readonly kind: string\n readonly objectId: string\n readonly itemId: string\n readonly from: Vec3\n readonly root: { readonly position: { readonly x: number; readonly y: number; readonly z: number } }\n}\n\nconst flat = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[2] - b[2])\n\nconst bearing = (centre: Vec3, distance: number, degrees: number): Vec3 => [centre[0] + Math.sin((degrees * Math.PI) / 180) * distance, 0, centre[2] + Math.cos((degrees * Math.PI) / 180) * distance]\n\n/** Where each kind lies, as [distance from the centre, bearing in degrees from +z]: no two of one kind on the same bearing, and none on the line of fire (the player shoots along the axis) or on the line to the zombie or the survivor of the area. */\nconst PUSH_LAYOUT: Record<(typeof PUSH_KINDS)[number]['kind'], ReadonlyArray<readonly [number, number]>> = {\n can: [[2.5, -52], [5, 12], [8, 78]],\n bottle: [[2.5, 26], [5, -62], [8, -78]],\n chair: [[2.5, -18], [5, 60], [8, -42]],\n}\n\n/** The shove of a blast on what lies around it, read 0.8 s after it: every body inside the reach moved away, the near ones more than the far ones, the people and the heavy furniture too. */\nfunction pushScenario(all: ReturnType<typeof explosivesTextOf>, bench: ExplosivesBench, mode: 'p13' | 'grenade'): ModuleScenario<ScenarioContext> {\n const text = all.scenarios\n const things = all.things\n return {\n id: `explosives_push_${mode}`,\n name: mode === 'p13' ? text.push_p13 : text.push_grenade,\n run: ({ room, step, expect }) => {\n let centre: Vec3\n let source: string | undefined\n if (mode === 'p13') {\n room.openArea(EXPLOSIVES_AREA_ID)\n const cylinder = room.spawned().find((spawned) => spawned.itemId === CYLINDER_ITEM)\n source = cylinder?.objectId\n const at = (cylinder?.root as { position: { x: number; z: number } } | undefined)?.position\n centre = [at?.x ?? 0, 0, at?.z ?? -10.66]\n } else {\n room.clear()\n centre = [0, 0, -6]\n }\n const placed: Placed[] = []\n const lay = (kind: string, item: string, at: Vec3): void => {\n try {\n const spawned = room.spawn(item, at, 0)\n placed.push({ kind, objectId: spawned.objectId, itemId: item, from: at, root: spawned.root as Placed['root'] })\n } catch {\n // the page does not carry this item (a room with a smaller catalogue): the others are still measured\n }\n }\n for (const { kind, item } of PUSH_KINDS) PUSH_LAYOUT[kind].forEach(([distance, degrees]) => lay(kind, item, bearing(centre, distance, degrees)))\n if (mode === 'grenade') {\n // off the bearing of every loose thing: a zombie thrown outward lands on what lies behind it on its line\n lay('zombie', 'zombie_walker', bearing(centre, 3.4, -130))\n lay('survivor', 'person_police_officer', bearing(centre, 7.5, 78))\n lay('camp_table', 'camp_table', bearing(centre, 3, 90))\n }\n step(0.6)\n const start = (body: Placed): Vec3 => [body.root.position.x, body.root.position.y, body.root.position.z]\n const origin = new Map(placed.map((body) => [body.objectId, start(body)] as const))\n const partsOf = (objectId: string): number => room.world.state(objectId)?.parts.length ?? 0\n // the loose things of the area itself that the blast reaches: the zombie, the survivor and the table\n for (const spawned of room.spawned()) {\n const known = placed.some((body) => body.objectId === spawned.objectId)\n const role = spawned.itemId.startsWith('zombie_') ? 'zombie' : spawned.itemId.startsWith('person_') ? 'survivor' : HEAVY_ITEMS.includes(spawned.itemId) ? spawned.itemId : undefined\n if (known || !role || mode !== 'p13') continue\n const root = spawned.root as Placed['root']\n const body: Placed = { kind: role, objectId: spawned.objectId, itemId: spawned.itemId, from: [root.position.x, root.position.y, root.position.z], root }\n placed.push(body)\n origin.set(body.objectId, body.from)\n }\n const partsBefore = new Map(placed.map((body) => [body.objectId, partsOf(body.objectId)] as const))\n expect(placed.length > 0, fillText(text.push_found, { n: placed.length, kinds: [...new Set(placed.map((body) => body.kind))].join(', ') }), { placed: placed.map((body) => body.itemId) })\n // the share of the blast that got to each body through what stood between; the blast and the body itself left out\n // where the blast is measured on each body: the middle of what is drawn of it, as the renderer shoves it (a bottle lying on the floor is low, under a stove's top), the chest of a person\n const aimOf = new Map(\n placed.map((body) => {\n const from = origin.get(body.objectId) ?? body.from\n if (body.kind === 'zombie' || body.kind === 'survivor') return [body.objectId, [from[0], from[1] + CHEST, from[2]] as Vec3] as const\n const boxes = room.renderer.solidsNear?.(from[0], from[2], AIM_SEARCH).filter((box) => box.objectId === body.objectId) ?? []\n if (boxes.length === 0) return [body.objectId, [from[0], from[1] + MIDDLE, from[2]] as Vec3] as const\n const low = [0, 1, 2].map((axis) => Math.min(...boxes.map((box) => box.min[axis]!)))\n const high = [0, 1, 2].map((axis) => Math.max(...boxes.map((box) => box.max[axis]!)))\n return [body.objectId, [0, 1, 2].map((axis) => (low[axis]! + high[axis]!) / 2) as Vec3] as const\n }),\n )\n const coverAt = (point: Vec3): Map<string, number> =>\n new Map(\n placed.map((body) => {\n const ignore = source ? [source, body.objectId] : [body.objectId]\n return [body.objectId, room.world.blastReach?.(point, aimOf.get(body.objectId) ?? body.from, { ignore }) ?? 1] as const\n }),\n )\n // the cover as the wave met it, read when the part of the world goes off (the cylinder says so before it tears and throws what stands around), as the renderer\n // shoves by it: the cupboard it tears apart was cover, the stove it throws was not in the way yet; a thrown charge goes off as a world blast\n let coverOf: Map<string, number> | undefined\n const stopListening = room.world.on('*', (event) => {\n if ((event.type === 'explode' || event.type === 'blast') && !coverOf) coverOf = coverAt(event.point)\n })\n if (mode === 'p13') bench.actions.shoot()\n else {\n room.setTool('frag_grenade')\n step(0.5)\n room.look([0, 1.6, 9.5], [0, 1, -2.5])\n room.use()\n }\n let waited = 0\n while (!bench.lastBlast() && waited < 9) {\n step(0.05)\n waited += 0.05\n }\n stopListening()\n const blast = bench.lastBlast()\n expect(!!blast, text.push_told, { waited })\n if (!blast) return\n const cover = coverOf ?? coverAt(blast.point)\n step(PUSH_READ_AT)\n const rows = placed.map((body) => {\n const from = origin.get(body.objectId) ?? body.from\n const now = start(body)\n const distance = flat(from, blast.point)\n const away = Math.max(1e-6, distance)\n const outward = ((now[0] - from[0]) * (from[0] - blast.point[0]) + (now[2] - from[2]) * (from[2] - blast.point[2])) / away\n return { ...body, distance, outward, moved: flat(now, from), cover: cover.get(body.objectId) ?? 1 }\n })\n // a loose item or a heavy piece of furniture the blast tore apart (a can whose welded shell split, a camp table whose legs flew off) is no longer one body: its root is\n // the piece that kept it, not where the thing went, and it can meet its own pieces in the air\n const torn = (row: { kind: string; objectId: string }): boolean =>\n (PUSH_KINDS.some((entry) => entry.kind === row.kind) || HEAVY_ITEMS.includes(row.kind)) && partsOf(row.objectId) < (partsBefore.get(row.objectId) ?? 0)\n const inReach = rows.filter((row) => row.distance < blast.radius * 0.85 && !torn(row))\n // a person (a survivor or a zombie of the area) is not a loose thing: the blast wave decides how far it goes (checked below)\n const isPerson = (row: { kind: string }): boolean => row.kind === 'survivor' || row.kind === 'zombie'\n const reached = inReach.filter((row) => row.cover >= SHELTERED && !isPerson(row))\n // what stood behind cover is not thrown like what stood in the open: the push goes as the square root of the share that got through, so the way it goes as the\n // share itself; it moves no farther than that share of what one of its kind went in the open nearer the blast (and a metre at most when none was)\n const sheltered = inReach.filter((row) => row.cover < SHELTERED)\n for (const row of sheltered) {\n const open = reached.filter((other) => other.kind === row.kind && other.distance <= row.distance).map((other) => other.outward)\n const most = Math.max(SHELTERED_MOST, row.cover * Math.max(0, ...open))\n expect(row.outward < most, fillText(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, most } })\n }\n const movedAway = reached.filter((row) => row.outward >= MOVED)\n const least = reached.length === 0 ? 0 : Math.min(...reached.map((row) => row.outward))\n expect(reached.length > 0 && movedAway.length === reached.length, fillText(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) })\n for (const { kind } of PUSH_KINDS) {\n const ofKind = reached.filter((row) => row.kind === kind).sort((a, b) => a.distance - b.distance)\n if (ofKind.length < 2) continue\n const near = ofKind[0]!\n const far = ofKind[ofKind.length - 1]!\n expect(near.outward > far.outward, fillText(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 })\n }\n // a person of the area (survivor or zombie, both knocked by `knockOf`) is pushed by the blast wave itself (`blastBodySpeed`): never farther than that push slides a body on the\n // ground, so a grenade does not throw a person. The horde of the crowd keeps the shove of its own physics (the team's horde bench), checked in its own bench.\n for (const row of inReach.filter(isPerson)) {\n const from = origin.get(row.objectId) ?? row.from\n const chest = Math.hypot(from[0] - blast.point[0], from[1] + CHEST - blast.point[1], from[2] - blast.point[2])\n const speed = blastBodySpeed(blast.tnt ?? blast.energy * DEFAULT_BLAST_IMPULSE.tntPerJoule, chest, PERSON_MASS, row.cover)\n const most = (speed * speed) / (2 * GROUND_FRICTION) + PERSON_SLACK\n expect(row.outward <= most, fillText(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 } })\n }\n // a torn table is still moved by the blast, whichever way its root went among its pieces\n const table = rows.find((row) => HEAVY_ITEMS.includes(row.kind) && row.distance < blast.radius * 0.85)\n if (table) expect(table.moved >= MOVED, fillText(text.push_heavy, { what: things[table.itemId] ?? table.itemId, moved: table.moved.toFixed(2) }), { table })\n },\n }\n}\n\n/**\n * Scenarios of the explosives area against the real cylinder, wall, furniture, zombie and survivor: a 9 mm through the shell, the open valve with and without a flame, the cylinder in a fire and a second\n * cylinder set off by the blast of the first. Each one runs the bench action a person would press, then reads the world's events and the state of what stood near.\n */\nexport function explosivesScenarios(locale: string, bench: ExplosivesBench): Array<ModuleScenario<ScenarioContext>> {\n const text = explosivesTextOf(locale).scenarios\n const record = (room: ExplosivesRoom): { events: Array<{ type: string; time: number; object: string }>; stop: () => void } => {\n const events: Array<{ type: string; time: number; object: string }> = []\n const stop = room.world.on('*', (event: DestructionEvent) => {\n if (event.object.startsWith(CYLINDER_ITEM)) events.push({ type: event.type, time: event.time, object: event.object })\n })\n return { events, stop }\n }\n const first = (events: Array<{ type: string; time: number }>, type: string, after = -Infinity): { type: string; time: number } | undefined => events.find((event) => event.type === type && event.time >= after)\n\n return [\n {\n id: 'explosives_p13_shot',\n name: text.shot,\n run: ({ room, step, expect }) => {\n room.openArea(EXPLOSIVES_AREA_ID)\n const { events, stop } = record(room)\n bench.actions.shoot()\n step(2.4)\n stop()\n const leak = first(events, 'leak')\n const explode = first(events, 'explode')\n const view = bench.vessel()\n expect(!!leak, text.shot_leak, { events: events.map((event) => event.type) })\n const torchAfter = view?.litAt !== undefined && view.leakAt !== undefined ? view.litAt - view.leakAt : -1\n expect(torchAfter >= TORCH_WINDOW[0] && torchAfter <= TORCH_WINDOW[1] + 0.05, `${text.shot_ignite} (${torchAfter.toFixed(2)} s)`, { torchAfter })\n const blastAfter = leak && explode ? explode.time - leak.time : -1\n expect(blastAfter > 0 && blastAfter <= BLAST_WITHIN, `${text.shot_explode} (${blastAfter.toFixed(2)} s)`, { blastAfter })\n const witnesses = bench.witnesses()\n const zombie = witnesses.find((w) => w.itemId.startsWith('zombie_'))\n expect(!!zombie && (zombie.alive === false || (zombie.vitality ?? 1) < 0.5), `${text.shot_zombie} (${zombie?.distance.toFixed(1)} m)`, { zombie })\n const survivor = witnesses.find((w) => w.kind === 'person' && !w.itemId.startsWith('zombie_'))\n expect(!!survivor && survivor.alive === true && (survivor.vitality ?? 1) < 1, `${text.shot_survivor} (${survivor?.distance.toFixed(1)} m, ${survivor?.alive ? 'alive' : 'dead'})`, { survivor })\n const wall = witnesses.find((w) => w.kind === 'wall')\n expect((wall?.marks ?? 0) + (wall?.broken ?? 0) + ((wall?.pieces ?? 1) - 1) > 0, text.shot_wall, { wall })\n },\n },\n {\n id: 'explosives_p13_valve',\n name: text.valve,\n run: ({ room, step, expect }) => {\n room.openArea(EXPLOSIVES_AREA_ID)\n const { events, stop } = record(room)\n bench.actions.valve()\n step(4)\n expect(!!first(events, 'leak'), text.valve_leak)\n expect(!first(events, 'primed') && !first(events, 'explode'), text.valve_quiet, { events: events.map((event) => event.type) })\n const before = room.world.time\n bench.actions.light()\n step(2.2)\n stop()\n expect(bench.vessel()?.lit === true || bench.vessel()?.litAt !== undefined, text.valve_lit)\n const explode = first(events, 'explode', before)\n expect(!!explode && explode.time - before <= BLAST_WITHIN, `${text.valve_explode} (${explode ? (explode.time - before).toFixed(2) : 'no blast'} s)`, { after: explode ? explode.time - before : null })\n },\n },\n {\n id: 'explosives_p13_fire',\n name: text.fire,\n run: ({ room, step, expect }) => {\n room.openArea(EXPLOSIVES_AREA_ID)\n const { events, stop } = record(room)\n bench.actions.fire()\n step(8)\n stop()\n expect(!!first(events, 'explode'), text.fire_explode, { events: events.map((event) => event.type) })\n },\n },\n {\n id: 'explosives_p13_chain',\n name: text.chain,\n run: ({ room, step, expect }) => {\n room.openArea(EXPLOSIVES_AREA_ID)\n const near: Vec3 = [1.0, 0, -10.0]\n const second = room.spawn(CYLINDER_ITEM, near, 0)\n const { events, stop } = record(room)\n bench.actions.shoot()\n step(4)\n stop()\n const blasts = events.filter((event) => event.type === 'explode')\n const other = blasts.find((event) => event.object === second.objectId)\n expect(blasts.length >= 2 && !!other, `${text.chain_explode} (${blasts.length} blasts)`, { blasts: blasts.map((event) => `${event.object}@${event.time.toFixed(2)}`) })\n },\n },\n pushScenario(explosivesTextOf(locale), bench, 'p13'),\n pushScenario(explosivesTextOf(locale), bench, 'grenade'),\n ]\n}\n"],"mappings":"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","names":["markKitOrigin","handled","slide","muzzleEnergy","SHELL_KINDS","muzzleEnergy","gain","sound","metal","sceneNoise","slide","sound","muzzleEnergy","grip","turn","weights","box","turn","box","markKitOrigin","shapeGeometries","flat","box","shapeGeometries","box","markKitOrigin","caliberOf","muzzleEnergy","markKitOrigin","box","box","PI","box","box","box","PI","box","box","box","PI","box","box","box","PI","box","box","box","box","PI","round","box","box","round","PI","box","box","box","PI","slide","metal","box","PI","box","slide","PI","box","metal","BUILDERS","box","markKitOrigin","warnOnce","discardObject3D","createRng","muzzleEnergy","RELOAD_SAMPLE_HITS","sound","PI","slide","sound","sound","box","box","box","DEFAULT_RANGE","box","box","box","catenary","createCord","swivel","box","slide","move","markKitOrigin","scratch","LIGHT_PRIORITY","PI","LIGHT_PRIORITY","quaternion","discardObject3D","PI","round","discardObject3D","V","box","quaternion","b","PI","fittedOf","move","turn","createRng","warnOnce","cue","discardObject3D","muzzleEnergy","box","markKitOrigin","markKitOrigin","box","SHAPES","markKitOrigin","sound","cue","createArsenal","discardObject3D","markKitOrigin","fillText","GRAVITY","fire","markKitOrigin","discardObject3D","fillText","change","body","fillText","box","AIM_HEIGHT","createArsenal"]}