@adatechnology/game-weapons-three 0.1.1 → 0.2.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 +447 -9
- package/dist/index.global.js +10633 -1011
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +4218 -80
- package/dist/index.js.map +1 -1
- package/package.json +7 -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/audio.ts","../src/audio/mechanical-sounds.ts","../src/audio/shot-sound.ts","../src/box-fx.ts","../src/fx/layers.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/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/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/rifle-fittings.ts","../src/models/rifle-forend.ts","../src/models/rifle-controls.ts","../src/models/rifle-stock.ts","../src/models/rifle.ts","../src/props.ts","../src/fx/viewmodel.ts","../src/animation/clip-builder.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/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, 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 { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { ARCHETYPE_MODELS, hasWeaponModel } from './models'\nimport { BODY_ACTIONS, buildModeledProp, buildProp, 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}\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// three 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]\nconst COUNTER_Z = [-1, 5.5]\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, 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\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 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 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 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\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 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 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 ],\n area: (): ModuleArea => ({\n placements: weaponsLayout(weaponIds, pitchOf).filter((placement) => !placement.item.startsWith(WORLD_EXPLOSIVE_PREFIX) || worldExplosiveIds.has(placement.item)),\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 ],\n layers: (): ModuleLayer[] => (['muzzle_flash', 'casings', 'magazines'] as const).map((id) => ({ id, name: text.layers[id] })),\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 ],\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 ...(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 offBench = lent.bench?.onChange((change: BenchChange) => {\n if (change.kind === 'layer') {\n 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 offBench?.()\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n host = 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// 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\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 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 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 { 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}\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 = '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 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 and the muzzle flash. */\nexport interface FxLayers {\n casings: boolean\n magazines: boolean\n muzzleFlash: boolean\n}\n\nexport const createLayers = (): FxLayers => ({ casings: true, magazines: true, muzzleFlash: true })\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 { buildBullpup } from './bullpup'\nimport { modelKit } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildLauncher } from './launcher'\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' | '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 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 return { id, root, inner: built.group, parts: built.parts }\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}\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 { 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 { 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'] 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 { scope } from './details'\nimport type { RifleContext } from './rifle-context'\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) scope(kit, group, o.scope, 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) {\n const bx = x1 + (L - x1) * 0.45\n cylinderX(group, 0.008, 0.02, M.dark, bx + 0.04, by - 0.012, 0, 12)\n for (const side of [-1, 1]) {\n const leg = kit.pivot(group, bx + 0.04, by - 0.012, 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 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 * as THREE from 'three'\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, cylinderX, cylinderZ } = kit\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 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 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 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 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 { 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 scale = o.brake === 2 ? 3.2 : 2.0\n const brakeLength = o.brake === 2 ? 0.12 : 0.06\n heatify(parts.glow, cylinderX(group, r * scale, brakeLength, M.dark, L - brakeLength / 2, by, 0, o.brake === 2 ? 8 : 16))\n for (let i = 0; i < 3; i++) box(group, brakeLength * 0.16, r * scale * 1.3, r * scale * 2.2, M.hole, L - brakeLength * 0.25 - i * brakeLength * 0.25, by, 0)\n } else if (!o.noFH) {\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 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 buildStock(context, magazineX)\n buildFittings(context, gripX)\n const { barrelY: by, receiverWidth: wR } = context\n const ejectX = receiverEnd - (options.ejectBack || 0.07)\n const ejectY = options.ar ? receiverHeight * 0.2 : by\n parts.muzzle = kit.mark(group, length + 0.01, by, 0)\n parts.eject = kit.mark(group, ejectX, ejectY, wR / 2 + 0.006)\n parts.loadPort = kit.mark(group, receiverEnd - 0.05, -receiverHeight / 2 - 0.004, 0)\n parts.topLoad = kit.mark(group, ejectX, receiverHeight / 2 + 0.004, 0)\n parts.family = familyOf(options)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\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'\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): THREE_NS.Group | undefined {\n const model = buildWeaponModelById(THREE, def.id)\n if (!model) return undefined\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/** 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 { HostEvent, HostTool, ToolClipPlayer } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, CaliberDef, 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 { 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}\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 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 = 'weapon-viewmodel'\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.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 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 }\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 player = createToolClipPlayer({\n clips: buildToolClips({ parts: model.parts, family: model.parts.family, caseType: session.caseType, reloadFamily }),\n rig: createModelRig(model),\n onEvent: createClipEventHandler(world, session),\n repeatInterval: () => (rpm > 0 ? 60 / rpm : 0.1),\n })\n applyCondition(kit, model, condition)\n lastAmmo = options.tool?.().ammo ?? 0\n return true\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): void => {\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() })\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)\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' } : step)\n },\n update(dt) {\n if (session) {\n place()\n player?.update(dt)\n const tool = options.tool?.()\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 { 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\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)]\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 { 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 ]\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, ReloadStageId, 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 default:\n return undefined\n }\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 { 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}\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\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 (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 })\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":["scope","metal","sound","createRng","muzzleEnergy","box","box","PI","box","box","box","PI","round","box","box","round","box","box","PI","slide","metal","box","PI","box","slide","PI","box","metal","box","PI","box","box","box","PI","box","box","box","createRng","caliberOf","muzzleEnergy","createRng","muzzleEnergy","PI","PI","PI","round","PI","HAND_OFFSET","createRng","muzzleEnergy","box","SHAPES"]}
|