@adatechnology/game-weapons-three 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +605 -9
- package/dist/index.global.js +18140 -921
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +5984 -268
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/area.ts","../src/audio.ts","../src/props.ts","../src/fx.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport type { AreaPlacement, DestructibleSpec, ModuleArea, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal } from '@adatechnology/game-weapons'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { BODY_ACTIONS, buildProp, weaponProp } from './props'\nimport type { WeaponProp } from './props'\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}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\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\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\nconst COUNTER_X = [-6.5, -9, -11.5]\nconst COUNTER_Z = -1\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.6\nconst SLOT_GAP = 0.3\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 TEXT: Record<string, { group: string; name: string; counter: string; targets: Record<string, string>; reloadStart: string; reloadEnd: string }> = {\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 reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\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 reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n },\n}\nconst textOf = (locale: string): (typeof TEXT)['en'] => TEXT[locale] ?? TEXT.en\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\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\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: three counters on the free left side of the room, props across them. */\nexport function weaponsLayout(weaponItemIds: string[]): AreaPlacement[] {\n const perCounter = Math.floor((COUNTER.length - 2 * END_MARGIN) / SLOT_GAP) + 1\n const counters = COUNTER_X.slice(0, Math.max(1, Math.ceil(weaponItemIds.length / perCounter)))\n const placements: AreaPlacement[] = counters.map((x) => ({ item: COUNTER_ITEM_ID, position: [x, 0, COUNTER_Z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n weaponItemIds.forEach((item, index) => {\n const x = counters[Math.min(counters.length - 1, Math.floor(index / perCounter))]\n const z = COUNTER_Z - COUNTER.length / 2 + END_MARGIN + (index % perCounter) * SLOT_GAP\n // long props side by side overlap in the gentle piece separation of the renderer: asleep, they stay until grabbed\n placements.push({ item, position: [x, COUNTER.height + 0.01, z], asleep: true })\n })\n for (const target of TARGETS) placements.push({ item: target.id, position: target.at })\n return placements\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: one prop per weapon of the arsenal on counters (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 audio = options.sound === false ? null : createWeaponAudio()\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\n const weaponIds = weaponDefs.map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n let fx: WeaponFx | null = null\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => asItem(`${WEAPON_ITEM_PREFIX}${def.id}`, arsenal.name(def.id), weaponProp(def, arsenal.name(def.id)), { weapon: def.id, movable: true })),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id], targetProp(target.id, text.targets[target.id]), { movable: false })),\n ],\n area: (): ModuleArea => ({ placements: weaponsLayout(weaponIds), view: { eye: [-3.4, 1.7, 2.6], target: [-9, 0.9, -1.2] } }),\n attach(host) {\n const created = createWeaponFx({\n THREE: host.THREE as typeof THREE_NS,\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.Camera,\n arsenal,\n groundAt: host.groundAt,\n audio,\n })\n fx = created\n const offEvents = host.on((event) => {\n const tool = host.tool()\n created.handle(event, tool)\n if (event.type === 'reload') host.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 = host.onFrame((dt) => created.update(dt))\n created.handle({ type: 'tool', weapon: host.tool().weapon }, host.tool())\n return () => {\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n }\n },\n }\n}\n","// Weapon sounds synthesized with WebAudio: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only created on the first sound, which comes from a click or a key (browsers allow it).\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: louder and longer the more muzzle energy (joules). */\n shot(energyJ: number, category: string): void\n /** Dry click of an empty weapon. */\n click(): 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. */\n clink(): 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\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 0.6\n\nexport function createWeaponAudio(volume = 0.6): WeaponAudio {\n const Ctor = (globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }).AudioContext ?? (globalThis as { webkitAudioContext?: AudioContextCtor }).webkitAudioContext\n let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!Ctor) return null\n if (!ctx) {\n ctx = new Ctor()\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = Math.random() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (options: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = options.filter\n filter.frequency.value = options.frequency\n filter.Q.value = options.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start)\n source.stop(start + options.seconds + 0.05)\n }\n\n const tone = (options: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = options.type ?? 'sine'\n osc.frequency.setValueAtTime(options.frequency, start)\n if (options.to) osc.frequency.exponentialRampToValueAtTime(options.to, start + options.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + options.seconds + 0.05)\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 return {\n shot(energyJ, category) {\n // 200 J (.22) to 15 000 J (.50 BMG) mapped to 0..1\n const k = Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, 50) / 50) / 2.5))\n const shotgun = category === 'shotgun'\n burst({ seconds: 0.12 + k * 0.35 + (shotgun ? 0.1 : 0), gain: 0.5 + k * 0.5, filter: 'lowpass', frequency: 4200 - k * 2600 })\n burst({ seconds: 0.03, gain: 0.6, filter: 'highpass', frequency: 3000 })\n tone({ seconds: 0.14 + k * 0.2, gain: 0.35 + k * 0.4, frequency: 140 - k * 70, to: 40 })\n },\n click() {\n metal(0, 2600, 0.25)\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 metal(0.22, 900, 0.35)\n metal(0.36, 1300, 0.35)\n },\n clink() {\n const f = 3200 + Math.random() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\n },\n }\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'\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 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\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\nimport { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\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}\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 /** Weapon shown in the hands, or null. */\n readonly inHand: string | 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/** 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'])\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\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\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\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 = 'weapon-in-hand'\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 kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\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)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\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(Math.random() * 20 - 10, Math.random() * 30 - 15, Math.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, (Math.random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + Math.random() * 0.8).addScaledVector(up, 1.4 + Math.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 ? 0.5 * (caliber.bulletGrams / 1000) * caliber.muzzleSpeed ** 2 * (caliber.pellets ?? 1) : 300\n audio?.shot(energy, weapon.category)\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 handle(event, tool) {\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) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.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"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/area.ts","../src/attachments-key.ts","../src/accessory-bench.ts","../src/accessory-text.ts","../src/audio.ts","../src/audio/mechanical-sounds.ts","../src/audio/shot-sound.ts","../src/box-fx.ts","../src/fx/layers.ts","../src/laser-raycast.ts","../src/merge-by-material.ts","../src/models/index.ts","../src/data/models.json","../src/models/rounded-box.ts","../src/models/kit.ts","../src/models/break-action.ts","../src/models/attachments/mount-frames.ts","../src/models/details.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/models/attachments/muzzle-brake.ts","../src/models/capture.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/attachments/tripod.ts","../src/props.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/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/heavy.ts","../src/fx/particles.ts","../src/fx/rig.ts","../src/fx/session.ts","../src/fx/viewmodel-events.ts","../src/fx.ts","../src/world-explosives.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 { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport { createAccessoryBench, accessoryControls, accessoryLayers, accessoryMetrics } from './accessory-bench'\nimport { accessoryTextOf } from './accessory-text'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } 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 { BODY_ACTIONS, buildModeledProp, buildProp, buildTripodMountedProp, modeledPropSpec, weaponProp } from './props'\nimport type { WeaponProp } from './props'\nimport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from './world-explosives'\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 /** 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}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\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 = 200\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 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 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 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 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 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 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\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\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 (one rigid body of its measures), the low-poly prop of its category when it did not. */\nconst weaponItem = (def: WeaponDef, name: string): TestableItem => {\n const id = `${WEAPON_ITEM_PREFIX}${def.id}`\n if (!hasWeaponModel(def.id)) 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) 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): TestableItem => ({\n id: MOUNTED_M134_ITEM_ID,\n name,\n build: (THREE: unknown) => buildTripodMountedProp(THREE as typeof THREE_NS, def, name) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n 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 audio = options.sound === false ? null : createWeaponAudio(undefined, options.seed === undefined ? {} : { seed: options.seed })\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\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) : 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)] : []\n let fx: WeaponFx | null = null\n let host: ModuleHost | null = null\n let soundDistance = 0\n const heatPercent = (): number => Math.min(100, (host?.tool().heat ?? 0) * 100)\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => weaponItem(def, arsenal.name(def.id))),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id] ?? target.id, targetProp(target.id, text.targets[target.id] ?? target.id), { movable: false })),\n ...worldExplosives,\n ...mountedM134,\n ],\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: '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 created = createWeaponFx({\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 groundAt: lent.groundAt,\n audio,\n tool: lent.tool,\n soundDistance: () => soundDistance,\n raycast: createLaserRaycast(lent.THREE as typeof THREE_NS, lent.scene as THREE_NS.Scene, lent.camera as THREE_NS.Camera),\n ...(options.attachmentModels ? { attachmentModels: options.attachmentModels } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.seed === undefined ? {} : { seed: options.seed }),\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 === 'fuse_length' && typeof change.value === 'number') lent.configureTool?.({ fuse_length: String(change.value) })\n })\n const offEvents = lent.on((event) => {\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 audio?.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') 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 created.handle({ type: 'tool', weapon: lent.tool().weapon }, lent.tool())\n return () => {\n accessories.dispose()\n offBench?.()\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n host = null\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","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 { 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, 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 const zoomOf = (tool: HostTool): number => {\n const optic = (tool.attachments ?? []).map((part) => arsenal.attachments.get(part.id)?.optic).find((entry) => entry !== undefined)\n return optic?.zoom[0] ?? 1\n }\n\n const isFirearm = (tool: HostTool): boolean => arsenal.weapons.get(tool.weapon)?.action.kind === 'firearm'\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 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) || !isFirearm(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","/** 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 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: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only 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 { createRng } from '@adatechnology/game-weapons'\nimport type { WeaponEvent } from '@adatechnology/game-weapons'\n\nimport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nimport type { MechanicalSoundId, SoundStep } from './audio/mechanical-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 { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nexport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\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\nexport interface WeaponAudioOptions extends ShotSoundOptions {\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 /** Where the AudioContext comes from (default: the global one); lets a host or a test lend its own. */\n readonly createContext?: () => AudioContext\n}\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: class and distance muffling of the game, loudness and body from the muzzle energy (joules). */\n shot(energyJ: number, category: string, extras?: ShotExtras): void\n /** The parameters `shot` would play (pure). */\n shotSound(input: ShotSoundInput): ShotSound\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 /** 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. */\n clink(): 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\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 1.5\n\nconst globalContext = (): AudioContext | null => {\n const scope = globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }\n const Ctor = scope.AudioContext ?? scope.webkitAudioContext\n return Ctor ? new Ctor() : null\n}\n\nexport function createWeaponAudio(volume = 0.6, options: WeaponAudioOptions = {}): WeaponAudio {\n const makeContext = options.createContext ?? globalContext\n const rng = createRng(options.seed ?? 1)\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 let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!ctx) {\n const created = makeContext()\n if (!created) return null\n ctx = created\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = rng() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (config: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = config.filter\n filter.frequency.value = config.frequency\n filter.Q.value = config.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - config.seconds))\n source.stop(start + config.seconds + 0.05)\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 classBurst = (at: number, cutoff: number, gain: number, seconds: number): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + at\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = 'lowpass'\n filter.frequency.value = cutoff\n const envelope = audio.createGain()\n envelope.gain.setValueAtTime(gain, start)\n envelope.gain.exponentialRampToValueAtTime(0.001, start + seconds)\n source.connect(filter).connect(envelope).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - seconds))\n source.stop(start + seconds + 0.05)\n }\n\n const tone = (config: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = config.type ?? 'sine'\n osc.frequency.setValueAtTime(config.frequency, start)\n if (config.to) osc.frequency.exponentialRampToValueAtTime(config.to, start + config.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + config.seconds + 0.05)\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 attenuation = classVolume / (1 + distance * distance * distanceCurve.gainFalloff)\n if (attenuation < distanceCurve.minGain) return\n const [cutoff, gain, seconds] = classes[soundClass] ?? FALLBACK_SOUND_CLASS\n classBurst(at, cutoff / (1 + distance * distanceCurve.cutoffFalloff), gain * attenuation, seconds)\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 === '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\n return {\n shot(energyJ, category, extras = {}) {\n const sound = shotSound({ ...extras, energyJ, category })\n if (!sound.audible) return\n classBurst(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 click() {\n mechanical('dry_fire')\n },\n mechanical,\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 clink() {\n const f = 3200 + rng() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\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\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\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 gallery (sources/armas-itens__galeria-3d-arsenal.js)\n * has no sound, so the 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), metal(0, 2600, 0.25)],\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: [metal(0, 1500, 0.35), sound(0, 'reload', 0.6)],\n magazine_in: seat,\n charge: slide,\n bolt_open: [metal(0, 900, 0.35)],\n round_in: [metal(0, 2000, 0.2), 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","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","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\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 { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\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 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 /** 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}\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 /** 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/** 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 HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\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 kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\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)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\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 })\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 },\n handle(event, tool) {\n if (event.type === 'explosion') 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) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.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: the beam of a laser never lands on its own weapon. */\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) 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 // the smoke is made of sprites, which 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'\n\nconst ATTRIBUTES = ['position', 'normal', 'uv'] as const\n\nconst isVisible = (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\n/** A copy of the geometry with the matrix baked in, not indexed, keeping only what every model has (position, normal, uv), so that any two of them can be joined. */\nconst bake = (THREE: typeof THREE_NS, mesh: THREE_NS.Mesh, matrix: THREE_NS.Matrix4): THREE_NS.BufferGeometry => {\n const source = mesh.geometry.index ? mesh.geometry.toNonIndexed() : mesh.geometry.clone()\n const baked = new THREE.BufferGeometry()\n const count = source.getAttribute('position').count\n for (const name of ATTRIBUTES) {\n const attribute = source.getAttribute(name)\n baked.setAttribute(name, attribute ?? new THREE.BufferAttribute(new Float32Array(count * (name === 'uv' ? 2 : 3)), name === 'uv' ? 2 : 3))\n }\n source.dispose()\n return baked.applyMatrix4(matrix)\n}\n\n/** One non-indexed geometry out of several, in order (the port of `mergeGeometries` of three/addons for the three attributes above). */\nconst join = (THREE: typeof THREE_NS, geometries: readonly THREE_NS.BufferGeometry[]): THREE_NS.BufferGeometry => {\n const merged = new THREE.BufferGeometry()\n for (const name of ATTRIBUTES) {\n const size = (geometries[0]?.getAttribute(name) as THREE_NS.BufferAttribute).itemSize\n const total = geometries.reduce((sum, geometry) => sum + geometry.getAttribute(name).count, 0)\n const array = new Float32Array(total * size)\n let offset = 0\n for (const geometry of geometries) {\n array.set(geometry.getAttribute(name).array, offset)\n offset += geometry.getAttribute(name).count * size\n }\n merged.setAttribute(name, new THREE.BufferAttribute(array, size))\n }\n return merged\n}\n\n/**\n * Every visible mesh under `root` (whose world matrix must be up to date), baked into the space of `space` and joined by material: one mesh per material, no shadow cast.\n * Weapons lying on a counter are never animated, so the hundreds of meshes of a model cost one draw call per material instead.\n */\nexport function mergeByMaterial(THREE: typeof THREE_NS, root: THREE_NS.Object3D, space: THREE_NS.Object3D): THREE_NS.Mesh[] {\n const toSpace = space.matrixWorld.clone().invert()\n const byMaterial = new Map<THREE_NS.Material, THREE_NS.BufferGeometry[]>()\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return\n const list = byMaterial.get(mesh.material) ?? []\n list.push(bake(THREE, mesh, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)))\n byMaterial.set(mesh.material, list)\n })\n return [...byMaterial].map(([material, geometries]) => {\n const merged = new THREE.Mesh(join(THREE, geometries), material)\n for (const geometry of geometries) geometry.dispose()\n merged.castShadow = false\n merged.receiveShadow = true\n return merged\n })\n}\n","import type * as THREE_NS from 'three'\nimport { WEAPONS } from '@adatechnology/game-weapons'\nimport data from '../data/models.json'\nimport { buildBreakAction } from './break-action'\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 } from './types'\n\nexport type { ModelFamily, ModelOptions, ModelParts } 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' | '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\n/** A weapon model: `root` (the page's `wr`) holds `inner` (what the builder made, fitted to the real length); `parts` are pivots and marks inside `inner`. */\nexport interface WeaponModel {\n readonly id: string\n readonly root: THREE_NS.Group\n readonly inner: THREE_NS.Group\n readonly parts: ModelParts\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 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 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}\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 { 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 return {\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 /** Magazine finishes named by the options. */\n bakelite: standard(0x6a2e1c, 0.6, 0),\n polyMag: standard(0x2a2a26, 0.85, 0),\n }\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/** One kit per three.js namespace: the materials and the geometry cache are shared by every model built with it. */\nexport function modelKit(THREE: Three): ModelKit {\n const cached = kits.get(THREE)\n if (cached) return cached\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 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(THREE, 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 { 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 { 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 * 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 { 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 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 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 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 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 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 { 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 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 { 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 { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport { mergeByMaterial } from './merge-by-material'\nimport { buildWeaponModelById } from './models'\nimport { buildTripodLegs } from './models/attachments/tripod'\nimport { modelKit } from './models/kit'\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 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\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n\nconst MODEL_BODY = 'body'\n\n/**\n * The prop of a weapon the gallery drew, 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'>, name: string, decorate?: (root: THREE_NS.Object3D) => void): THREE_NS.Group | undefined {\n const model = buildWeaponModelById(THREE, def.id)\n if (!model) return undefined\n decorate?.(model.root)\n const group = new THREE.Group()\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): THREE_NS.Group | undefined {\n return buildModeledProp(THREE, def, name, (root) => {\n const kit = modelKit(THREE)\n buildTripodLegs(kit, kit.pivot(root, TRIPOD_HEAD.x, TRIPOD_HEAD.y, 0))\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","import type * as THREE_NS from 'three'\nimport { createToolClipPlayer, toolAnimationStep } from '@adatechnology/game-contracts'\nimport type { AnimationPose, HostEvent, HostTool, HostToolAttachment, ToolAnimationStep, ToolClipPlayer } 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 { WeaponAudio } from '../audio'\nimport { weaponEventOf } from '../audio/host-events'\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 { createEffects } from './effects'\nimport { createLayers } from './layers'\nimport type { FxLayers } from './layers'\nimport { flameJet, launchRocket } from './heavy'\nimport 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'\n\nconst PI = Math.PI\n// where the weapon sits against the camera: right, down and ahead; long guns are drawn smaller so they do not fill the view\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst HEAT_DISPLAY_MAX_FALLBACK = 120\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 /** 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}\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 readonly inHand: string | null\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\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)\n particles.onBounce = (kind) => (kind === 'casing' ? audio?.clink() : kind === 'magazine' ? audio?.thud() : undefined)\n const effects = createEffects(kit, scene, particles, random)\n const hand = new THREE.Group()\n hand.name = VIEWMODEL_NODE_NAME\n scene.add(hand)\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\n const world: FxWorld = {\n kit,\n scene,\n particles,\n effects,\n random,\n audio,\n layers,\n groundAt,\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\n const release = (): void => {\n if (!session) return\n session.attachments?.dispose()\n session.model.root.removeFromParent()\n player = null\n session = null\n tasks = []\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 })\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 rigStock(THREE, model, def)\n rigUnderbarrel(THREE, model, def)\n const length = new THREE.Box3().setFromObject(model.root).getSize(new THREE.Vector3()).x\n const scale = length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1\n holder.scale.setScalar(scale)\n holder.position.set(0, 0, Math.min(0.25, 0.25 * length * scale))\n holder.add(model.root)\n const caliber = caliberOf(arsenal, def)\n const dims = caliber?.cartridge\n session = {\n id: weapon,\n def,\n model,\n holderScale: scale,\n lengthMetres: length,\n caseType: caliber?.caseType ?? 'rifle',\n kit,\n cartridge: caliber && dims ? { dims, shape: cartridgeShape(caliber, dims) } : null,\n stuckCase: null,\n nextChamber: 0,\n attachments: null,\n attachmentsSignature: '',\n }\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.attachments = fitAttachmentModels(model, fitted, kit, { catalogue: arsenal.attachments, isDrawn: () => layers.attachments, areBeamsOn: () => layers.beams, ...(options.attachmentModels ? { overrides: options.attachmentModels } : {}), ...(options.raycast ? { raycast: options.raycast } : {}) })\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 player = createToolClipPlayer({\n clips: buildToolClips({ parts: model.parts, family: model.parts.family, caseType: session.caseType, reloadFamily }),\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 return true\n }\n\n const syncAttachments = (current: Session, tool: HostTool | undefined): void => {\n if (!current.attachments || tool?.weapon !== current.id || !tool.attachments) return\n const signature = attachmentsKey(tool.attachments)\n if (signature === current.attachmentsSignature) return\n current.attachmentsSignature = signature\n current.attachments.sync(fittedOf(tool.attachments))\n }\n\n const place = (): void => {\n const [x, y, z] = HAND_OFFSET\n hand.position.set(x, y, z).applyQuaternion(camera.quaternion).add(camera.position)\n hand.quaternion.copy(camera.quaternion)\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 - 50) / 50))\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 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 launchRocket(heavy(current))\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(), ...(event.suppressed === true ? { suppressed: true } : {}) })\n }\n\n return {\n equip,\n unequip: release,\n handle(event, tool) {\n if (event.type === 'explosion') 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') handleShot(current, event, tool)\n else if (event.type === 'reload' && event.phase === 'start') current.nextChamber = 0\n else if (event.type === 'clear' && event.phase === 'end') current.stuckCase = null\n const mechanical = weaponEventOf(event)\n if (mechanical) 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 if (session) {\n place()\n player?.update(dt)\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) flameJet(heavy(session), dt, session.model.parts.launcherType === 'flame' ? 1 : 0.6)\n lastAmmo = tool.ammo\n }\n if (tool && tool.heat !== undefined && tool.heat * heatMax > 10 && session.model.parts.muzzle) {\n smokeDebt += dt * tool.heat * heatMax * 0.1\n while (smokeDebt > 1) {\n smokeDebt -= 1\n const k = 0.5 + (tool.heat * heatMax) / 60\n effects.smoke(worldPositionOf(session, session.model.parts.muzzle, new THREE.Vector3()), new THREE.Vector3((random() - 0.5) * 0.03, 0.07 + random() * 0.08, (random() - 0.5) * 0.03), 0.007 * k, 1.6 + random(), Math.min(0.42, 0.14 + k * 0.1))\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 effects.update(dt)\n particles.update(dt)\n },\n setCondition(next) {\n condition = next\n if (session) applyCondition(kit, session.model, condition)\n },\n get inHand() {\n return session?.id ?? null\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 effects.dispose()\n hand.removeFromParent()\n },\n }\n}\n","import { STAGE_EVENT } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from '@adatechnology/game-contracts'\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\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 } 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: [cue(start + 0.16, 'drop_magazine', { up: direction > 0 })],\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, 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 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\nconst cycleWithoutEject = (start: number): Draft => ({ tweens: boltStroke(start), events: [], end: start + 0.55 })\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 draft.tweens.push(move('slide', 'x', 0, 0, 0, strokeOf(parts)), move('slide', 'x', swap.end, 0.05, strokeOf(parts), 0))\n draft.end += 0.12\n }\n } else if (family === 'boltmag') {\n const stroke = cycleWithoutEject(swap.end)\n draft.tweens.push(...stroke.tweens)\n draft.end = stroke.end\n } else if (kind === 'empty' && parts.bolt) {\n draft.tweens.push(...charge(context, 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 = [cue(0.32, 'eject_casing', { from: 'chambers', down: false })]\n if (kind !== 'one_by_one') events.push(cue(0.7, 'move_in', { from: 'chambers' }))\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, both cases drop, two shells go in and the barrels close: 1.2 s. */\nconst breakReload = (): Draft => ({\n tweens: [turn('barrels', 'z', 0, 0.2, 0, -0.5), turn('barrels', 'z', 1.0, 0.15, -0.5, 0)],\n events: [cue(0.25, 'eject_casing', { from: 'breech', down: false }), cue(0.65, 'move_in', { from: 'breech' })],\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: [],\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 if (family === 'pump' && parts.pump) draft.tweens.push(move('pump', 'x', 0.88, 0.05, 0, PUMP_TRAVEL), move('pump', 'x', 0.94, 0.05, PUMP_TRAVEL, 0))\n else if (family === 'lever' && parts.lever) draft.tweens.push(turn('lever', 'z', 0.87, 0.06, 0, LEVER_TURN), turn('lever', 'z', 0.94, 0.06, LEVER_TURN, 0))\n else if (parts.bolt) draft.tweens.push(move('bolt', 'x', 0.88, 0.07, 0, strokeOf(parts)), move('bolt', 'x', 0.95, 0.04, strokeOf(parts), 0))\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: [],\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: [], 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'), cue(0.6, 'seat_tube')],\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')],\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: [cue(0.3, 'breech_round')],\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()\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/** 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 })], 0.24)\n if (family === 'bolt' || family === 'semiint') return composeClip('feed', [], [cue(0, 'move_in', { from: 'topLoad' })], 0.24)\n if (isTube(context)) return composeClip('feed', [], [cue(0, 'move_in', { from: 'loadPort' })], 0.24)\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 selector or safety lever flicks over: on turns it down, off brings it back. The gallery draws the lever and does not move it. */\nexport function safetyClips(context: ClipContext): AnimationClipSpec[] {\n if (!context.parts.safety) return []\n return [composeClip('safety_on', [turn('safety', 'z', 0, 0.12, 0, -0.6)]), composeClip('safety_off', [turn('safety', 'z', 0, 0.12, -0.6, 0)]), composeClip('mode', [turn('safety', 'z', 0, 0.07, 0, 0.4), turn('safety', 'z', 0.07, 0.07, 0.4, 0)])]\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-interactables-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 type { 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 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 }): 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 spot = new THREE.SpotLight(0xfff1d0, LIGHT_INTENSITY, attachment.light?.range ?? DEFAULT_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","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-interactables-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 * 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 { AttachmentDef, FittedAttachment } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../index'\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}\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, 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 '../index'\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 './index'\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 './index'\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 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 = kit.group()\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 = kit.group()\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 = kit.group()\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 { ModelKit } from '../models/kit'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\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\nexport interface Effects {\n /** The muzzle flash at `position` pointing along `orientation`, with six puffs of smoke. */\n muzzleFlash(position: THREE_NS.Vector3, orientation: THREE_NS.Quaternion, size: number): void\n /** A puff that rises, grows and fades. */\n smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void\n update(dt: number): void\n dispose(): void\n}\n\nconst FLASH_SECONDS = 0.055\n\n/** The gallery's muzzle flash: a cone, four small cones and a core, additive, over 55 ms, with a short light. */\nexport function createEffects(kit: ModelKit, scene: THREE_NS.Object3D, particles: Particles, random: () => number): Effects {\n const { THREE, M } = kit\n const light = new THREE.PointLight(0xffb060, 0, 3, 2)\n scene.add(light)\n let flash: { group: THREE_NS.Group; age: number } | null = null\n\n const buildFlash = (size: number): THREE_NS.Group => {\n const group = new THREE.Group()\n const cone = new THREE.Mesh(new THREE.ConeGeometry(0.013 * size, 0.085 * size, 10, 1, true), M.flashA)\n cone.rotation.z = -PI / 2\n cone.position.x = 0.042 * size\n group.add(cone)\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + random() * 0.6\n const spike = new THREE.Mesh(new THREE.ConeGeometry(0.005 * size, 0.04 * size, 6), M.flashA)\n spike.position.set(0.012 * size, Math.cos(angle) * 0.016 * size, Math.sin(angle) * 0.016 * size)\n spike.rotation.set(angle, 0, 0)\n spike.rotateZ(-PI / 2)\n group.add(spike)\n }\n const core = new THREE.Mesh(new THREE.SphereGeometry(0.016 * size, 12, 8), M.flashB)\n core.position.x = 0.008 * size\n group.add(core)\n return group\n }\n\n const endFlash = (): void => {\n if (!flash) return\n flash.group.removeFromParent()\n flash.group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n flash = null\n light.intensity = 0\n }\n\n const effects: Effects = {\n muzzleFlash(position, orientation, size) {\n endFlash()\n const group = buildFlash(size)\n group.position.copy(position)\n group.quaternion.copy(orientation)\n group.rotateX(random() * PI)\n scene.add(group)\n flash = { group, age: 0 }\n light.position.copy(position)\n light.intensity = 4 * size\n light.distance = 2 * size\n for (let i = 0; i < 6; i++) {\n const velocity = new THREE.Vector3(0.15 + random() * 0.35, 0.03 + random() * 0.12, (random() - 0.5) * 0.14).applyQuaternion(orientation)\n effects.smoke(position, velocity, 0.013 * size, 1.3 + random() * 0.6, 0.45)\n }\n },\n smoke(position, velocity, size, life, opacity) {\n const puff = new THREE.Mesh(new THREE.SphereGeometry(size, 10, 8), M.smokeP.clone())\n puff.position.copy(position)\n particles.spawn(puff, velocity, { gravity: -0.08, life, fadeFrom: opacity, grow: 2.1, drag: 2.2, radius: -1, ownsGeometry: true })\n },\n update(dt) {\n if (!flash) return\n flash.age += dt\n flash.group.scale.setScalar(0.6 + Math.min(1, flash.age / FLASH_SECONDS) * 0.9)\n if (flash.age >= FLASH_SECONDS) endFlash()\n },\n dispose() {\n endFlash()\n light.removeFromParent()\n light.dispose()\n },\n }\n return effects\n}\n","import type * as THREE_NS from '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}\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\nconst spread = (context: HeavyContext, x: number, y: number, z: number): THREE_NS.Vector3 =>\n new context.kit.THREE.Vector3((context.random() - 0.5) * x, (context.random() - 0.5) * y, (context.random() - 0.5) * z)\n\n/** The gallery's `flameBit` and `smokeBit`, which the rocket's backblast and the flame jet share. */\nfunction createBits(context: HeavyContext): { flame(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number): void; smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void; dispose(): void } {\n const { kit, particles, random } = context\n const { THREE } = kit\n const palette = flameMaterials(kit)\n return {\n flame(position, velocity, size, life) {\n const bit = new THREE.Mesh(new THREE.IcosahedronGeometry(size, 1), (palette[Math.floor(random() * 4)] as THREE_NS.Material).clone())\n bit.position.copy(position)\n bit.rotation.set(random() * 3, random() * 3, 0)\n particles.spawn(bit, velocity, { gravity: -1.4, life, fadeFrom: 0.9, grow: 2.2, drag: 1.4, radius: -1, spin: new THREE.Vector3(3, 4, 2), ownsGeometry: true })\n },\n smoke(position, velocity, size, life, opacity) {\n context.effects.smoke(position, velocity, size, life, opacity)\n },\n dispose: () => palette.forEach((material) => material.dispose()),\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): void {\n const { kit, scene, parts, random } = context\n const { THREE } = kit\n const bits = createBits(context)\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 for (let i = 0; i < 26; i++) bits.smoke(rear.clone(), forward.clone().multiplyScalar(-(1.5 + random() * 3)).add(spread(context, 1.4, 0.8, 1.4)), 0.03 + random() * 0.03, 1.8 + random() * 1.4, 0.5)\n for (let i = 0; i < 14; i++) bits.flame(rear.clone(), forward.clone().multiplyScalar(-(2 + random() * 2)).add(spread(context, 1, 0.6, 1)), 0.02, 0.25)\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 light = new THREE.PointLight(0xff9a40, 3, 2.5)\n rocket.add(light)\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 exhaust.scale.set(1, 0.6 + random() * 0.8, 1)\n if (random() < 0.9) bits.smoke(rocket.position.clone().addScaledVector(forward, -0.12), spread(context, 0.1, 0, 0.1).setY(0.05), 0.02 + random() * 0.015, 2.2, 0.5)\n },\n () => {\n rocket.removeFromParent()\n exhaust.geometry.dispose()\n ;(exhaust.material as THREE_NS.Material).dispose()\n light.dispose()\n bits.dispose()\n },\n )\n}\n\n/** A second of flame from the nozzle: bits of fire thrown forward and up, smoke downwind 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 bits = createBits(context)\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const count = Math.floor(dt * 420 * scale)\n for (let i = 0; i < count; i++) {\n const speed = (2.2 + random() * 1.1) * scale\n bits.flame(muzzle.clone().addScaledVector(forward, random() * speed * Math.min(dt, 0.3)), forward.clone().multiplyScalar(speed).add(new THREE.Vector3((random() - 0.5) * 0.35, (random() - 0.3) * 0.3, (random() - 0.5) * 0.35)), 0.02 + random() * 0.022, 0.4 + random() * 0.35)\n }\n if (random() < 0.5) bits.smoke(muzzle.clone().addScaledVector(forward, 1.1 * scale + random() * 0.4), new THREE.Vector3(forward.x * 0.6, 0.35, forward.z * 0.6), 0.03, 1.6, 0.4)\n if (random() < 0.18) {\n const droplet = new THREE.Mesh(new THREE.SphereGeometry(0.006, 6, 4), new THREE.MeshBasicMaterial({ color: 0xff7a22 }))\n droplet.position.copy(muzzle).addScaledVector(forward, 0.3 + random() * 0.5)\n particles.spawn(droplet, forward.clone().multiplyScalar(1.2 * scale).add(new THREE.Vector3(0, 0.2, 0)), { life: 3, radius: 0.003, ownsGeometry: true, onGround: (position) => groundFire(context, bits, position) })\n }\n bits.dispose()\n}\n\n/** Three small flames where a burning droplet landed, flickering for four seconds and smoking. */\nfunction groundFire(context: HeavyContext, bits: ReturnType<typeof createBits>, position: THREE_NS.Vector3): void {\n const { kit, scene, random } = 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 = flameMaterials(kit)\n const flames = [0, 1, 2].map((index) => {\n const flame = new THREE.Mesh(new THREE.ConeGeometry(0.02, 0.07, 6), (materials[index % 2] as THREE_NS.Material).clone())\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) bits.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 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","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}\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 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). */\n onBounce?: (kind: ParticleKind) => 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\nexport function createParticles(THREE: Three, scene: THREE_NS.Object3D, groundAt: (x: number, z: number) => number): Particles {\n let list: Particle[] = []\n const remove = (particle: Particle): void => {\n particle.object.removeFromParent()\n if (particle.ownsGeometry) disposeOwned(particle.object)\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 bounces: 0,\n })\n const oldest = list[0]\n if (list.length > 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 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)\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 { 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 { 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 /** 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 model: WeaponModel\n /** How much the model is scaled down to sit in the hands. */\n readonly holderScale: number\n readonly lengthMetres: number\n readonly caseType: CaseType\n readonly kit: ModelKit\n readonly cartridge: { dims: CartridgeDims; shape: CartridgeShape } | 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}\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 type * as THREE_NS from 'three'\nimport type { AnimationEventSpec } from '@adatechnology/game-contracts'\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 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) effects.muzzleFlash(positionOf(parts.muzzle), root.getWorldQuaternion(new THREE.Quaternion()), session.def.action.kind === 'launcher' ? 2.2 : FLASH_BY_CASE[session.caseType])\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 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 shell.removeFromParent()\n })\n }\n}\n","import type { HostEvent, HostTool } 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 /** 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 /** 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 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 })\n return {\n handle(event, tool) {\n if (event.type === 'explosion') 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 layers,\n get inHand() {\n return model.inHand ?? box.inHand\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, PartShape, PartSpec, TestableItem, Vec3 } from '@adatechnology/game-contracts'\nimport type { ExplosiveDef } from '@adatechnology/game-weapons'\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}\n\n// The game's drum (jogo.js addExplo 68141: radius 0.3, height 0.9); the P13 cylinder and the car tank are real measures.\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: { shape: { kind: 'cylinder', radius: 0.15, height: 0.48 }, position: [0, 0.24, 0], color: 0xcfd3d8 },\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/** The part of a world explosive: the energy, the reach and the chain of the explosive def, which is what `explosivePart` of game-destruction builds. */\nconst explosivePart = (def: ExplosiveDef, shape: WorldShape): PartSpec => ({\n id: 'tank',\n material: 'steel',\n shape: shape.shape,\n position: shape.position,\n ...SHELL,\n explodes: { energy: def.energy, radius: def.injuryRadius, ...(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/** 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): TestableItem | undefined => {\n const shape = SHAPES[def.id]\n if (!shape) return undefined\n const spec: DestructibleSpec = { name, parts: [explosivePart(def, shape)], joints: [], tags: ['explosive'] }\n return {\n id: `${WORLD_EXPLOSIVE_PREFIX}${def.id}`,\n name,\n build: (THREE: unknown) => {\n const group = new (THREE as typeof THREE_NS).Group()\n group.add(meshOf(THREE as typeof THREE_NS, shape))\n return group\n },\n spec,\n }\n}\n"],"mappings":"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","names":["handled","scope","metal","sound","createRng","muzzleEnergy","box","box","box","PI","box","box","box","PI","round","box","box","round","PI","box","box","box","PI","slide","metal","box","PI","box","slide","PI","box","metal","box","box","box","PI","box","box","box","PI","box","box","box","PI","box","box","box","createRng","caliberOf","muzzleEnergy","createRng","muzzleEnergy","PI","slide","box","box","box","DEFAULT_RANGE","box","box","box","catenary","createCord","swivel","box","slide","move","PI","PI","PI","round","PI","HAND_OFFSET","fittedOf","move","createRng","muzzleEnergy","box","SHAPES"]}
|