@adatechnology/game-vehicles 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,70 +1,1056 @@
1
+ import * as three from 'three';
2
+ import { MeshStandardMaterial, Vector3, BufferGeometry, Object3D, Mesh, Material, Vector2, Box3, Matrix4, Group, ColorRepresentation, CanvasTexture, MeshBasicMaterial, Color, Texture, SpriteMaterial, Sprite, Raycaster } from 'three';
1
3
  import { MaterialId, Vec3, JointKind, ToolKind, DeferredQueue, DestructibleImpl, AnimationClipSpec, IgnitionRules, DestructionEvent, ObjectState, Enclosure } from '@adatechnology/game-contracts';
2
4
 
3
- /**
4
- * Light mode ("lite"): the same vehicles with fewer triangles, for a whole street of them. Port of the `[LOD]` hooks of the team's Frota Leve
5
- * (frota-leve.js lines 21-65, 232-257, 1205-1221, 14155-14170). Every number is a setting; with `on` false nothing changes, so every golden
6
- * of the full-detail build stays byte for byte the same.
7
- */
5
+ /** Armoured vehicle details (plating, hatches, add-on armour) and the applyArmor helper. */
8
6
 
9
- interface LodSettings {
10
- /** Light mode is active for the builds that run now. Set by `kit.build(key, state, zones, { lod: true })`. */
11
- on: boolean;
12
- /** Fraction of the segments three's own generators keep (cylinders, spheres, tori, lathes, tubes, extrusions, circles, rings). */
13
- segmentFraction: number;
14
- /** Rounding rings of a rounded box (the full build uses 3). */
15
- roundingRings: number;
16
- /** Multiplier of the maximum edge length when subdividing a mesh (bigger triangles). */
17
- subdivisionFactor: number;
18
- /** A box with an edge under this, or a rounding radius under 1.2 cm, is drawn as a plain 12-triangle box. */
19
- flatBoxEdge: number;
20
- /** Fewest segments of a superellipse loft. */
21
- minLoftSegments: number;
22
- /** Fraction of a loft's segments. */
23
- loftSegmentFraction: number;
24
- /** Fewest stations of a resampled loft. */
25
- minStations: number;
26
- /** Fraction of the stations of a resampled loft. */
27
- stationFraction: number;
28
- /** Multiplier of the grid cell size of grilles and side grilles. */
29
- gridFactor: number;
30
- /** Materials (by name in `kit.materials`) whose meshes are never seen from outside and are left out in light mode. */
31
- hiddenMaterials: readonly string[];
7
+ declare function installArmor(kit: Kit): {
8
+ STEEL_MATERIAL: MeshStandardMaterial;
9
+ PLATE_MATERIALS: MeshStandardMaterial[];
10
+ jerryCan: (c: BuildContext, x: number, y: number, z: number, col: string) => void;
11
+ applyArmor: (c: BuildContext) => void;
12
+ };
13
+
14
+ /** A cut for `geo.cut`: `sel(normal, centre)` picks the triangles, `sdf(x, y, z)` < 0 is removed, the removed pieces with a `tag` come back in `.cut[tag]`. */
15
+ type CutTest = {
16
+ sel?: ((n: Vector3, ce: Vector3) => boolean) | null;
17
+ sdf: (x: number, y: number, z: number) => number;
18
+ tag?: string;
19
+ /** a box (in the frame of the geometry) that holds every point with sdf < 0 */
20
+ bounds?: {
21
+ lo: number[];
22
+ hi: number[];
23
+ };
24
+ /** how the removed pieces are smoothed: 'none', 'later' (a crease task) or right away */
25
+ pieces?: string;
26
+ };
27
+ type Rgb = {
28
+ r: number;
29
+ g: number;
30
+ b: number;
31
+ };
32
+ /** A station of a loft: centre x and y, width, height and the superellipse power. */
33
+ type LoftStation = {
34
+ x: number;
35
+ y: number;
36
+ w: number;
37
+ h: number;
38
+ p?: number;
39
+ };
40
+ type HullSpec = {
41
+ n?: number;
42
+ L: number;
43
+ p?: number;
44
+ beam(t: number): number;
45
+ keel(t: number): number;
46
+ sheer(t: number): number;
47
+ };
48
+ /** A corner of a path ([x, y, radius]) or an arc ({ arc: [cx, cy, r, from, to, clockwise] }). */
49
+ type PathItem = {
50
+ readonly arc?: readonly [number, number, number, number, number, boolean?];
51
+ readonly [i: number]: number;
52
+ };
53
+ type TaperSpec = {
54
+ sx?: number | null;
55
+ sz?: number | null;
56
+ shift?: number;
57
+ };
58
+ type TumbleSpec = {
59
+ belt: number;
60
+ top: number;
61
+ k: number;
62
+ };
63
+ declare function installGeometry(kit: Kit): {
64
+ roundedBoxGeometry: (w: number, h: number, d: number, r: number) => three.BoxGeometry;
65
+ taper: (geo: BufferGeometry, t: TaperSpec) => void;
66
+ subdivide: (geo: BufferGeometry, maxLen: number) => BufferGeometry<three.NormalBufferAttributes>;
67
+ crease: (geo: BufferGeometry, deg: number) => BufferGeometry<three.NormalBufferAttributes>;
68
+ creaseTask: (geo: BufferGeometry, deg: number) => {
69
+ geo: BufferGeometry<three.NormalBufferAttributes>;
70
+ step: (deadline: number) => boolean;
71
+ };
72
+ refreshBounds: (geo: BufferGeometry) => void;
73
+ pathShape: (items: readonly PathItem[]) => three.Shape;
74
+ tumble: (geo: BufferGeometry, T: TumbleSpec | null | undefined) => void;
75
+ loftGeometry: (st: readonly LoftStation[], seg: number, pw: number, colorFn?: ((x: number, y: number, z: number, s: LoftStation) => Rgb) | null) => BufferGeometry<three.NormalBufferAttributes>;
76
+ hullGeometry: (o: HullSpec, colorFn?: ((x: number, y: number, z: number) => Rgb) | null) => BufferGeometry<three.NormalBufferAttributes>;
77
+ cutGeometry: (geo: BufferGeometry, tests: readonly CutTest[]) => {
78
+ geo: BufferGeometry;
79
+ cut: Record<string, BufferGeometry>;
80
+ tasks: Record<string, ReturnType<(geo: BufferGeometry, deg: number) => {
81
+ geo: BufferGeometry<three.NormalBufferAttributes>;
82
+ step: (deadline: number) => boolean;
83
+ }>>;
84
+ };
85
+ mergeGeometries: (list: readonly BufferGeometry[]) => BufferGeometry<three.NormalBufferAttributes>;
86
+ uvProject: (geo: BufferGeometry, axes?: string) => number;
87
+ };
88
+
89
+ /** Shared materials, studio environment map, paint colours and text textures. */
90
+
91
+ /** Options of `kit.makeMaterial`: the parameters of a `MeshStandardMaterial`, and `noEnv` to keep the studio environment map off a metallic one. */
92
+ type MaterialOptions = three.MeshStandardMaterialParameters & {
93
+ noEnv?: boolean;
94
+ };
95
+ /** Options of `kit.textTexture` (and of `c.text`): canvas size, background, the blue band of a plate, text colour, size share, weight and font. */
96
+ interface TextTextureOptions {
97
+ w?: number;
98
+ h?: number;
99
+ bg?: string;
100
+ band?: string;
101
+ fg?: string;
102
+ size?: number;
103
+ weight?: string;
104
+ font?: string;
105
+ [option: string]: unknown;
32
106
  }
33
- declare const defaultLodSettings: LodSettings;
34
- /** The settings the kit starts with: the defaults, overridden by the options. */
35
- declare function createLod(options?: Partial<LodSettings>): LodSettings;
36
- /**
37
- * A copy of the three.js namespace whose geometry generators take fewer segments while `lod.on` is true (and whose canvas textures come out in
38
- * sRGB when three has colour management). With `lod.on` false every generator passes its arguments through untouched.
39
- */
40
- declare function wrapThreeForLod(TH: any, lod: LodSettings): any;
107
+ declare function installMaterials(kit: Kit): {
108
+ RUST: three.Color;
109
+ cache: Record<string, three.MeshStandardMaterial>;
110
+ studioEnvironment: () => three.CubeTexture;
111
+ makeMaterial: (color: three.ColorRepresentation, o?: MaterialOptions) => three.MeshStandardMaterial;
112
+ makeFlatMaterial: (color: three.ColorRepresentation, o?: MaterialOptions) => three.MeshStandardMaterial;
113
+ DOUBLE_SIDE: 2;
114
+ toColor: (hex: three.ColorRepresentation) => three.Color;
115
+ MATERIALS: {
116
+ trim: three.MeshStandardMaterial;
117
+ rubber: three.MeshStandardMaterial;
118
+ chrome: three.MeshStandardMaterial;
119
+ steel: three.MeshStandardMaterial;
120
+ glass: three.MeshStandardMaterial;
121
+ tint: three.MeshStandardMaterial;
122
+ rearTint: three.MeshStandardMaterial;
123
+ glassDark: three.MeshStandardMaterial;
124
+ armorGlass: three.MeshStandardMaterial;
125
+ glassEdge: three.MeshStandardMaterial;
126
+ lens: three.MeshStandardMaterial;
127
+ lensRed: three.MeshStandardMaterial;
128
+ lensAmber: three.MeshStandardMaterial;
129
+ housing: three.MeshStandardMaterial;
130
+ reflector: three.MeshStandardMaterial;
131
+ reflectorLit: three.MeshStandardMaterial;
132
+ hole: three.MeshStandardMaterial;
133
+ dark: three.MeshStandardMaterial;
134
+ head: three.MeshStandardMaterial;
135
+ led: three.MeshStandardMaterial;
136
+ tail: three.MeshStandardMaterial;
137
+ amber: three.MeshStandardMaterial;
138
+ rev: three.MeshStandardMaterial;
139
+ blue: three.MeshStandardMaterial;
140
+ green: three.MeshStandardMaterial;
141
+ broken: three.MeshStandardMaterial;
142
+ bulbBroken: three.MeshStandardMaterial;
143
+ wood: three.MeshStandardMaterial;
144
+ leather: three.MeshStandardMaterial;
145
+ seat: three.MeshStandardMaterial;
146
+ alu: three.MeshStandardMaterial;
147
+ carpet: three.MeshStandardMaterial;
148
+ plastic: three.MeshStandardMaterial;
149
+ headliner: three.MeshStandardMaterial;
150
+ gauge: three.MeshStandardMaterial;
151
+ screen: three.MeshStandardMaterial;
152
+ bay: three.MeshStandardMaterial;
153
+ hoodLiner: three.MeshStandardMaterial;
154
+ block: three.MeshStandardMaterial;
155
+ cover: three.MeshStandardMaterial;
156
+ radiator: three.MeshStandardMaterial;
157
+ yellow: three.MeshStandardMaterial;
158
+ capBlue: three.MeshStandardMaterial;
159
+ postRed: three.MeshStandardMaterial;
160
+ postBlack: three.MeshStandardMaterial;
161
+ coolant: three.MeshStandardMaterial;
162
+ coolantLiq: three.MeshStandardMaterial;
163
+ washer: three.MeshStandardMaterial;
164
+ hv: three.MeshStandardMaterial;
165
+ hose: three.MeshStandardMaterial;
166
+ };
167
+ paintColor: (hex: three.ColorRepresentation, st: string) => three.Color;
168
+ texCache: Record<string, three.CanvasTexture>;
169
+ textTexture: (text: string, o?: TextTextureOptions) => three.CanvasTexture;
170
+ };
41
171
 
42
- /** Smoke, fire and dust puffs handed to the host's effects world instead of the kit's own sprites. */
43
- /** What `EffectSink.play` of `game-contracts` takes, as a structural type: this package does not depend on the contracts layer. */
44
- interface ParticleEffectRequest {
45
- readonly effect: string;
46
- readonly point: [number, number, number];
47
- readonly values: Readonly<Record<string, number>>;
172
+ /** How a pane is made: its material, outline and seat on the body (side windows), the uv aspect, where its part sits and how far it reaches. */
173
+ type GlassOptions = {
174
+ reuv?: boolean;
175
+ uvAxes?: string;
176
+ mat?: Material;
177
+ outline?: Vector2[] | null;
178
+ side?: number;
179
+ Wg?: number;
180
+ T?: TumbleSpec | null;
181
+ zpos?: number;
182
+ aspect?: number;
183
+ pos?: Vector3;
184
+ reach?: number;
185
+ };
186
+ type PaneLook = {
187
+ type?: string;
188
+ mat?: Material;
189
+ see?: boolean;
190
+ };
191
+ /** A windshield or rear window between the base point `pb` and the top `pt` of its pillar line (`kit.quadDef`). */
192
+ type GlassQuad = {
193
+ pb: number[];
194
+ pt: number[];
195
+ L: number;
196
+ u: number[];
197
+ n: number[];
198
+ ins: number;
199
+ b: number[];
200
+ t: number[];
201
+ hb: number;
202
+ ht: number;
203
+ which: string;
204
+ bev: number;
205
+ Wg: number;
206
+ T: TumbleSpec | null | undefined;
207
+ };
208
+ declare function installGlass(kit: Kit): {
209
+ paneSeals: WeakMap<Object3D<three.Object3DEventMap>, Mesh<BufferGeometry<three.NormalBufferAttributes>, Material | Material[], three.Object3DEventMap>>;
210
+ };
211
+
212
+ /** What a builder declares about a zone (`c.zone(...)`): new fields, or `remove`; `objs` are parts by label or kind, lamps or objects. */
213
+ /** A zone as `c.zone` declares or refines it: any field of a zone, plus remove, replace, fit and the objects it holds. */
214
+ type ZoneDef = Partial<DamageZone> & {
215
+ id: string;
216
+ remove?: boolean;
217
+ replace?: boolean;
218
+ fit?: boolean;
219
+ objs?: unknown[];
220
+ };
221
+ declare function installZoneDerive(kit: Kit): {
222
+ parseDir: (d: unknown) => Vector3 | null;
223
+ resolveObjs: (c: BuildContext, list: readonly unknown[] | null | undefined, z: Pick<DamageZone, "lights" | "glass" | "wheels">) => Object3D<three.Object3DEventMap>[];
224
+ deriveZones: (c: BuildContext) => DamageZone[];
225
+ carMap: (c: BuildContext, list: DamageZone[]) => void;
226
+ zonesOf: (c: BuildContext) => any;
227
+ ownerOf: (c: BuildContext, o: Object3D | null | undefined) => DamageZone | null;
228
+ };
229
+
230
+ /** A zone box in `c.vehicle` coordinates. */
231
+ interface ZoneBox {
232
+ x0: number;
233
+ x1: number;
234
+ y0: number;
235
+ y1: number;
236
+ z0: number;
237
+ z1: number;
48
238
  }
49
- /** The host's effects world as far as the puffs need it (`EffectSink` of `game-contracts` fits). */
50
- interface ParticleEffects {
51
- play(request: ParticleEffectRequest): unknown;
239
+ /** What `normalizeBox` reads: `[x0, x1, y0, y1, z0, z1]`, a `ZoneBox` or a three.js `Box3`. */
240
+ type ZoneBoxInput = readonly number[] | ZoneBox | Box3;
241
+ declare function installZoneCore(kit: Kit): {
242
+ BANDS: {
243
+ id: string;
244
+ name: string;
245
+ min: number;
246
+ health: number;
247
+ color: string;
248
+ }[];
249
+ bandOf: (h: number | null | undefined) => number;
250
+ ZONE_WEIGHTS: Record<string, number>;
251
+ ZONE_EFFECTS: Record<string, string[]>;
252
+ zoneFx: (z: DamageZone, b: number) => any;
253
+ normalizeBox: (b: ZoneBoxInput | null | undefined) => ZoneBox | null;
254
+ boxLo: (B: ZoneBox, a: number) => number;
255
+ boxHi: (B: ZoneBox, a: number) => number;
256
+ boxContains: (B: ZoneBox, x: number, y: number, z: number, e: number) => boolean;
257
+ boxCenter: (B: ZoneBox) => Vector3;
258
+ boxVolume: (B: ZoneBox) => number;
259
+ boxDistance: (B: ZoneBox, p: Vector3) => number;
260
+ boxIntersects: (B: ZoneBox, b3: Box3) => boolean;
261
+ worldInverseOf: (c: BuildContext) => Matrix4;
262
+ localBox: (c: BuildContext, o: Object3D, inv?: Matrix4 | null) => Box3;
263
+ slug: (s: unknown) => string;
264
+ wheelInfo: (c: BuildContext) => {
265
+ list: Object3D<three.Object3DEventMap>[];
266
+ xf: number;
267
+ xr: number;
268
+ rf: number;
269
+ rr: number;
270
+ } | null;
271
+ partsOf: (c: BuildContext, kind: string) => VehiclePart[];
272
+ lightCenter: (c: BuildContext, L: VehicleLamp, inv: Matrix4) => Vector3;
273
+ lightBoxOf: (c: BuildContext, L: VehicleLamp, inv: Matrix4) => Box3;
274
+ hideObj: (c: BuildContext, o: Object3D | null | undefined) => void;
275
+ shown: (c: BuildContext, o: Object3D | null | undefined) => boolean;
276
+ };
277
+
278
+ /** A part's label: a text, or `{ key }` (the text of `parts.<key>`), or `{ key, label }` (the given text, keeping the key). */
279
+ type LabelArgument = string | {
280
+ key?: string;
281
+ label?: string;
282
+ };
283
+ /** Where a builder puts a new mesh: its parent (default `c.vehicle`). */
284
+ interface ParentOption {
285
+ parent?: Object3D | null;
52
286
  }
287
+ declare function installContext(kit: Kit): {
288
+ resolveLabel: (l: LabelArgument) => {
289
+ label: string;
290
+ key?: string;
291
+ };
292
+ BuildContext: {
293
+ new (state: string, seed?: number): {
294
+ [key: string]: any;
295
+ root: Group;
296
+ vehicle: Group;
297
+ effects: Group;
298
+ state: string;
299
+ glass: Mesh[];
300
+ deform: Mesh[];
301
+ wheels: Object3D[];
302
+ parts: VehiclePart[];
303
+ lights: VehicleLamp[];
304
+ spin: VehicleSpin[];
305
+ emitters: VehicleEmitter[];
306
+ log: unknown[];
307
+ paints: Set<Material>;
308
+ seatTops: {
309
+ x: number;
310
+ y: number;
311
+ z: number;
312
+ w: number;
313
+ l: number;
314
+ }[];
315
+ flipped: boolean;
316
+ rollState: RollState | null;
317
+ quads: GlassQuad[];
318
+ zoneDefs: ZoneDef[];
319
+ flying?: FlyingPiece[];
320
+ /** How far each wheel drops when the zones are applied (flat tyre, broken rim), to settle the body on them. */
321
+ zoneDrops: {
322
+ x: number;
323
+ z: number;
324
+ d: number;
325
+ }[];
326
+ time: number;
327
+ rand: () => number;
328
+ add(geo: BufferGeometry, mat: Material | Material[], x?: number, y?: number, z?: number, parent?: Object3D | null): Mesh;
329
+ /** Paint material; `meta.matte` (or `o.matte`) gives a matte finish to everything, including parts created later (damage, hood). */
330
+ paint(hex: ColorRepresentation, o?: MaterialOptions & {
331
+ matte?: boolean;
332
+ }): MeshStandardMaterial;
333
+ roundBox(w: number, h: number, d: number, r: number, mat: Material | Material[], x?: number, y?: number, z?: number, o?: ParentOption & {
334
+ taper?: Parameters<(geo: BufferGeometry, t: TaperSpec) => void>[1];
335
+ sub?: number;
336
+ def?: boolean;
337
+ rot?: readonly number[];
338
+ }): Mesh;
339
+ cylinder(r1: number, r2: number, h: number, mat: Material | Material[], x?: number, y?: number, z?: number, axis?: string | null, o?: ParentOption & {
340
+ seg?: number;
341
+ open?: boolean;
342
+ }): Mesh;
343
+ sphere(r: number, mat: Material | Material[], x?: number, y?: number, z?: number, sx?: number, sy?: number, sz?: number, o?: ParentOption & {
344
+ ws?: number;
345
+ hs?: number;
346
+ tl?: number;
347
+ }): Mesh;
348
+ rod(a: Vector3, b: Vector3, r: number, mat: Material | Material[], o?: ParentOption & {
349
+ r2?: number;
350
+ seg?: number;
351
+ }): Mesh;
352
+ tube(pts: readonly (Vector3 | readonly number[])[], r: number, mat: Material | Material[], o?: ParentOption & {
353
+ closed?: boolean;
354
+ seg?: number;
355
+ rs?: number;
356
+ }): Mesh;
357
+ text(txt: string, w: number, h: number, x?: number, y?: number, z?: number, face?: string, o?: ParentOption & TextTextureOptions & {
358
+ glow?: ColorRepresentation;
359
+ }): Mesh;
360
+ plate(x: number, y: number, z: number, face?: string, txt?: string): Mesh;
361
+ part(kind: string, label: LabelArgument, obj: Object3D | null, pos: Vector3 | readonly number[], reach?: number, o?: Record<string, unknown>): VehiclePart;
362
+ wheel(x: number, z: number, r: number, w: number, o?: {
363
+ y?: number;
364
+ rimR?: number;
365
+ lugs?: boolean;
366
+ chevron?: boolean;
367
+ rim?: Material;
368
+ spokes?: number;
369
+ spokeMat?: Material;
370
+ noPart?: boolean;
371
+ label?: LabelArgument;
372
+ }): Group;
373
+ /** Point in `c.vehicle` coordinates to effects-group coordinates (vehicle world, ground y = 0). */
374
+ toEffects(p: Vector3): Vector3;
375
+ dirToEffects(d: Vector3): Vector3;
376
+ /** Declares or refines a damage zone: `c.zone(id, label, box, parts, options)`. Pass `label === false` to remove an auto-derived zone. */
377
+ zone(id: string, label: string | false | null | undefined, box?: ZoneBoxInput | null, parts?: Object3D | VehicleLamp | readonly (Object3D | VehicleLamp)[] | null, o?: Record<string, unknown>): ZoneDef;
378
+ };
379
+ };
380
+ };
53
381
 
54
- /**
55
- * Damageable parts: what a bullet, a bat or a crash can hurt on a built vehicle, as boxes. Port of `coletarDanificaveis` and `tipoDaZona`
56
- * (frota-leve.js 14391-14405), driven by the zones the kit already derives, so it works for any vehicle of any pack.
57
- */
382
+ /** A body shell (`kit.shell`): the side profile, its width, the wheel arches ([x, y, r]), the holes cut in it and the tumble of the sides. */
383
+ type ShellSpec = {
384
+ items: readonly PathItem[];
385
+ W: number;
386
+ arches?: readonly number[][] | null;
387
+ bottomY?: number;
388
+ bev?: number | null;
389
+ sub?: number;
390
+ T?: TumbleSpec | null;
391
+ holes?: readonly CutTest[] | null;
392
+ archInner?: number | null;
393
+ mat?: Material;
394
+ col?: ColorRepresentation;
395
+ };
396
+ /** The greenhouse of a car: belt and roof heights, the rear and front pillar feet and tops, the pillars between windows and the width. */
397
+ type Greenhouse = {
398
+ belt: number;
399
+ roof: number;
400
+ rb: number;
401
+ rt: number;
402
+ fb: number;
403
+ ft: number;
404
+ pillars: readonly number[];
405
+ Wg: number;
406
+ };
407
+ declare function installBody(kit: Kit): {
408
+ halfAt: (Wg: number, T: TumbleSpec | null | undefined, y: number) => number;
409
+ shell: (c: BuildContext, o: ShellSpec) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material | Material[], three.Object3DEventMap>;
410
+ autoWindows: (gh: Greenhouse) => number[][][];
411
+ profX: (items: readonly PathItem[], y: number, front: boolean) => number;
412
+ _sr: three.Raycaster;
413
+ };
58
414
 
59
- type DamageableMaterial = 'metal' | 'glass' | 'rubber' | 'fuel';
60
- type DamageableSide = 'center' | 'left' | 'right';
61
- /** What a zone is, by type: the material it is made of and the part name a game shows. */
62
- interface DamageableKind {
63
- material: DamageableMaterial;
64
- part: string;
65
- }
66
- /** Zone type (and, for some, `fxKey` or `sub`) to material and part. A game replaces or adds entries with `kit.damageableKinds`. */
67
- declare const defaultDamageableKinds: Record<string, DamageableKind>;
415
+ /** The rounding of `makeWarp`: where the front and rear start (xF, xR) and how long they bend (Lf, Lr), the half width, the bow and pinch of each end, the side curve (belt, ys, yb, kt, kb) and the drop of the nose. */
416
+ type WarpOptions = {
417
+ xF: number;
418
+ xR: number;
419
+ Lf: number;
420
+ Lr: number;
421
+ hw: number;
422
+ bowF: number;
423
+ bowR: number;
424
+ pinF: number;
425
+ pinR: number;
426
+ belt: number;
427
+ ys: number;
428
+ yb: number;
429
+ kt: number;
430
+ kb: number;
431
+ dropF?: number;
432
+ dropY?: number;
433
+ };
434
+ /** A point warp: (x, y, z) to [x, y, z]. */
435
+ type WarpFn = (x: number, y: number, z: number) => number[];
436
+ /** A loft station of `smoothLoft`: [x, top, bottom, width, exponent?, z centre?]. */
437
+ type LoftRow = readonly number[];
438
+ type SmoothLoftOptions = {
439
+ smooth?: number;
440
+ seg?: number;
441
+ axis?: string;
442
+ p?: number;
443
+ crease?: number;
444
+ };
445
+ declare function installWarp(kit: Kit): {
446
+ makeWarp: (o: WarpOptions) => {
447
+ (x: number, y: number, z: number): number[];
448
+ sec: (y: number) => number;
449
+ };
450
+ applyWarp: (c: BuildContext, Wf: WarpFn) => void;
451
+ resample: (st: readonly (readonly (number | null | undefined)[])[], n: number) => number[][];
452
+ smoothLoft: (st: readonly LoftRow[], o?: SmoothLoftOptions | null) => three.BufferGeometry<three.NormalBufferAttributes>;
453
+ };
454
+
455
+ /** The generic car builder: shell, glasshouse, lights, wheels, interior and engine bay in one call. */
456
+
457
+ type WheelOptions = Parameters<BuildContext['wheel']>[4] & {
458
+ track?: number;
459
+ };
460
+ /** A wheel of `kit.car`: [x, radius, width, options]. */
461
+ type CarWheel = readonly [number, number, number, WheelOptions?];
462
+ type LampSpec = {
463
+ style?: string;
464
+ w?: number;
465
+ h?: number;
466
+ y?: number;
467
+ in?: number;
468
+ yaw?: number;
469
+ dx?: number;
470
+ mat?: Material;
471
+ wrap?: boolean;
472
+ };
473
+ type GrilleSpec = {
474
+ style?: string;
475
+ w?: number;
476
+ h?: number;
477
+ y?: number;
478
+ emblem?: boolean;
479
+ };
480
+ /** The spec of `kit.car` (see the comment above it). */
481
+ type CarSpec = {
482
+ W: number;
483
+ gh: Greenhouse & {
484
+ k: number;
485
+ r1?: number;
486
+ r2?: number;
487
+ };
488
+ col: ColorRepresentation;
489
+ roofCol?: ColorRepresentation;
490
+ mirrorCol?: ColorRepresentation;
491
+ lower: readonly PathItem[];
492
+ noseY: number;
493
+ tailY: number;
494
+ bottomY: number;
495
+ arches?: readonly number[][] | null;
496
+ interior?: false | Record<string, unknown> | null;
497
+ hood?: boolean | {
498
+ motor?: string;
499
+ front?: number;
500
+ } | null;
501
+ wheels?: readonly CarWheel[];
502
+ holes?: readonly CutTest[];
503
+ bed?: unknown;
504
+ under?: boolean;
505
+ motor?: string;
506
+ spareUnder?: boolean;
507
+ warp?: WarpOptions | WarpFn | null;
508
+ bodyBumper?: boolean;
509
+ headMat?: Material;
510
+ headW?: number;
511
+ headH?: number;
512
+ headY?: number;
513
+ hl?: LampSpec | null;
514
+ grille?: false | GrilleSpec | null;
515
+ noGrille?: boolean;
516
+ tailW?: number;
517
+ tailH?: number;
518
+ tailLightY?: number;
519
+ tl?: LampSpec | null;
520
+ seams?: readonly number[];
521
+ handles?: readonly number[];
522
+ plateRearY?: number;
523
+ noAntenna?: boolean;
524
+ track?: number;
525
+ noRadiator?: boolean;
526
+ tankLabel?: LabelArgument;
527
+ };
528
+ /** The underbody of `kit.underbody`: width, bottom height, the wheels, the motor and a spare wheel under the rear. */
529
+ type UnderbodySpec = {
530
+ W: number;
531
+ bottomY: number;
532
+ wheels: readonly CarWheel[];
533
+ motor?: string;
534
+ spare?: boolean;
535
+ };
536
+ declare function installCar(kit: Kit): {};
537
+
538
+ declare function installDamagePanels(kit: Kit): {
539
+ panelBand: (c: BuildContext, z: DamageZone, b: number, dirty: Set<Object3D>) => void;
540
+ roofOff: (c: BuildContext, z: DamageZone, inv: Matrix4) => void;
541
+ tailOff: (c: BuildContext, z: DamageZone, inv: Matrix4) => void;
542
+ followersIn: (c: BuildContext, z: DamageZone, inv: Matrix4) => Object3D<three.Object3DEventMap>[];
543
+ windowsOver: (c: BuildContext, z: DamageZone, inv: Matrix4) => Mesh<three.BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap>[];
544
+ doorGap: (c: BuildContext, z: DamageZone, b: number, cands: Object3D[]) => void;
545
+ mirrorHang: (c: BuildContext, z: DamageZone, ang: number) => void;
546
+ doorHang: (c: BuildContext, z: DamageZone, dirty: Set<Object3D>, inv: Matrix4) => void;
547
+ lidHang: (c: BuildContext, z: DamageZone, dirty: Set<Object3D>) => void;
548
+ flapHang: (c: BuildContext, z: DamageZone, dirty: Set<Object3D>) => void;
549
+ };
550
+
551
+ /** Per-zone damage for separate parts: lights, wheels, glass, internals, rotors and landing gear. */
552
+
553
+ declare function installDamageParts(kit: Kit): {
554
+ glassPt: (c: BuildContext, g: Mesh, rnd: () => number) => Vector3;
555
+ glassIn: (c: BuildContext, g: Mesh) => Vector3;
556
+ glassBand: (c: BuildContext, z: DamageZone, g: Mesh, b: number) => void;
557
+ crackLensCache: Map<Material, Material>;
558
+ crackTextureCache: null;
559
+ crackTexture: () => CanvasTexture;
560
+ crackLens: (mat: Material) => Material;
561
+ lightBand: (c: BuildContext, z: DamageZone, Lt: VehicleLamp | null | undefined, b: number) => void;
562
+ tireMeshes: (w: Object3D) => Mesh[];
563
+ flattenTire: (w: Object3D, k: number) => void;
564
+ wheelBand: (c: BuildContext, z: DamageZone, w: Object3D | null | undefined, b: number) => void;
565
+ gearBand: (c: BuildContext, z: DamageZone, b: number) => void;
566
+ internalBand: (c: BuildContext, z: DamageZone, b: number) => void;
567
+ hoodBand: (c: BuildContext, z: DamageZone, b: number, dirty: Set<Object3D>) => void;
568
+ bumperBand: (c: BuildContext, z: DamageZone, b: number, dirty: Set<Object3D>) => void;
569
+ partBand: (c: BuildContext, z: DamageZone, b: number, dirty: Set<Object3D>) => void;
570
+ bendAft: (c: BuildContext, z: DamageZone, kx: number, ky: number, ang: number, dirty: Set<Object3D>) => void;
571
+ };
572
+
573
+ /** Fuel tank explosion, fireball, flying debris and burnt-out state. */
574
+
575
+ declare function installExplosion(kit: Kit): {
576
+ BURNT: MeshStandardMaterial[];
577
+ BURNT_RUB: MeshStandardMaterial;
578
+ boomMat: (hex: ColorRepresentation, op: number, add?: boolean) => MeshBasicMaterial;
579
+ enginePos: (c: BuildContext) => any;
580
+ fling: (c: BuildContext, obj: Object3D, v: Vector3, w: Vector3) => FlyingPiece | null;
581
+ burnAll: (c: BuildContext) => void;
582
+ bigBoomFx: (c: BuildContext) => void;
583
+ detonate: (c: BuildContext) => void;
584
+ tickBoom: (c: BuildContext, dt: number) => void;
585
+ tickFlying: (c: BuildContext, dt: number) => void;
586
+ };
587
+
588
+ /** A lobe of a puddle's outline: its angle, width, how far it reaches and when it stops growing. */
589
+ type PuddleLobe = {
590
+ a: number;
591
+ w: number;
592
+ amp: number;
593
+ stop: number;
594
+ };
595
+ /** A puddle on the ground (`puddle`): its mesh, age, final radius, centre, outline lobes and noise, and the oil drop, crown, gasoline haze and rim it may have. */
596
+ type Puddle = {
597
+ kind: string;
598
+ m: Mesh<BufferGeometry, MeshStandardMaterial>;
599
+ t: number;
600
+ max: number;
601
+ x0: number;
602
+ z0: number;
603
+ lobes: PuddleLobe[];
604
+ nz: (x: number, y: number) => number;
605
+ ph: number;
606
+ R?: Float32Array;
607
+ rim?: Mesh<BufferGeometry, MeshBasicMaterial>;
608
+ drop?: Mesh;
609
+ dy0?: number;
610
+ crown?: Mesh<BufferGeometry, MeshStandardMaterial>;
611
+ phase?: number;
612
+ haze?: Mesh<BufferGeometry, MeshBasicMaterial>;
613
+ fire?: boolean;
614
+ };
615
+ /** A fluid type after `defineFluid`: the definition with its key and both colours. */
616
+ type ResolvedFluid = FluidDefinition & {
617
+ key: string;
618
+ freshC: Color;
619
+ dryC: Color;
620
+ dryTime: number;
621
+ roughFresh: number;
622
+ roughDry: number;
623
+ metalFresh: number;
624
+ metalDry: number;
625
+ };
626
+ /** A splat on the body (`kit.splat`) with its trickle. */
627
+ type Splat = {
628
+ kind: string;
629
+ def: ResolvedFluid;
630
+ grp: Group;
631
+ mat: MeshStandardMaterial;
632
+ drip: Mesh;
633
+ r: number;
634
+ t: number;
635
+ onGlass: boolean;
636
+ Lmax: number;
637
+ off: number[];
638
+ len: number;
639
+ w0: number;
640
+ };
641
+ declare function installFluids(kit: Kit): {
642
+ _fr: three.Raycaster;
643
+ buildDrip: (f: Splat, L: number) => void;
644
+ DOWNHILL: Vector3;
645
+ PN: number;
646
+ puddleGeometry: () => BufferGeometry<three.NormalBufferAttributes>;
647
+ rimGeometry: () => BufferGeometry<three.NormalBufferAttributes>;
648
+ puddle: (c: BuildContext, kind: string, pLocal: Vector3, maxR: number) => Puddle;
649
+ shapePuddle: (f: Puddle) => number;
650
+ updateFluids: (c: BuildContext, dt: number) => void;
651
+ };
652
+
653
+ /** The material of a pane with cracks drawn on it. A host warms its program at load with any texture: the first crack is in the middle of a blast. */
654
+ declare function crackedGlassMaterial(THREE: Three, texture: Texture): MeshStandardMaterial;
655
+ /** What `crackLight` reads of a lamp the kit drew (`c.lights`) and of its vehicle. */
656
+ type LampMesh = Mesh;
657
+ type CrackedLamp = {
658
+ lens: LampMesh[];
659
+ inner: LampMesh[];
660
+ halo?: Array<{
661
+ visible: boolean;
662
+ }>;
663
+ group: Object3D | null;
664
+ tint: string;
665
+ broken: unknown;
666
+ cracked?: boolean;
667
+ dark?: boolean;
668
+ };
669
+ declare function installGlassDamage(kit: Kit): {
670
+ glassUV: (c: BuildContext, msh: Mesh, pLocal: Vector3) => number[];
671
+ drawWeb: (x: CanvasRenderingContext2D, cx: number, cy: number, s: number, ax: number, rnd: () => number) => void;
672
+ crackGlass: (c: BuildContext, msh: Mesh, p: Vector3, force: number, sc?: number | null) => void;
673
+ glassRim: (geo: BufferGeometry, rnd: () => number) => BufferGeometry<three.NormalBufferAttributes> | null;
674
+ shatterGlass: (c: BuildContext, msh: Mesh, force: number, dir: Vector3) => void;
675
+ hitGlass: (c: BuildContext, msh: Mesh | null | undefined, p: Vector3, dir: Vector3, force: number) => void;
676
+ breakLight: (c: BuildContext, L: VehicleLamp | null | undefined, dir: Vector3) => void;
677
+ crackLight: (c: BuildContext, L: CrackedLamp, dir: Vector3, pierced: boolean) => void;
678
+ };
679
+
680
+ /** Hoods, engine bays and hinge helpers. */
681
+
682
+ /** The engine bay of `kit.engineBay`: firewall and front x, half width, floor and free height, motor, axle x, paint, and the labels and views of the bay. */
683
+ type EngineBaySpec = {
684
+ x0: number;
685
+ x1: number;
686
+ zw: number;
687
+ floor: number;
688
+ top: number;
689
+ motor?: string;
690
+ axle?: number;
691
+ col?: ColorRepresentation;
692
+ label?: LabelArgument;
693
+ turbo?: boolean;
694
+ view?: unknown;
695
+ };
696
+ declare function installHood(kit: Kit): {};
697
+
698
+ /** The dent of one impact: point, direction into the body, radius, depth, ripple phase and the body centre it never crosses. */
699
+ type DentSpot = {
700
+ p: Vector3;
701
+ dir: Vector3;
702
+ R: number;
703
+ depth: number;
704
+ ph: number;
705
+ C: Vector3;
706
+ };
707
+ declare function installImpact(kit: Kit): {
708
+ dentField: (v: Vector3, H: DentSpot) => number;
709
+ hangBumper: (c: BuildContext, o: Mesh | null | undefined, p: Vector3) => void;
710
+ tankFuel: (c: BuildContext, pt: {
711
+ label?: string;
712
+ fuel?: string;
713
+ }) => "diesel" | "gasoline" | null;
714
+ hurtEngine: (c: BuildContext, h: number) => void;
715
+ igniteFuel: (c: BuildContext, pd: Puddle | null | undefined) => void;
716
+ applyPart: (c: BuildContext, pt: VehiclePart, force: number, dir: Vector3, p: Vector3) => any;
717
+ SCRATCH_MATERIAL: MeshStandardMaterial;
718
+ SOOT_MATERIAL: MeshStandardMaterial;
719
+ _ray: three.Raycaster;
720
+ findSurface: (c: BuildContext, p: Vector3, dir: Vector3) => {
721
+ p: Vector3;
722
+ n: Vector3;
723
+ obj: Object3D<three.Object3DEventMap>;
724
+ } | null;
725
+ scratches: (c: BuildContext, p: Vector3, dir: Vector3, force: number) => void;
726
+ impact: (c: BuildContext, p: Vector3, dir: Vector3, force: number, opts?: ImpactOptions | null) => VehiclePart[];
727
+ _pr: three.Raycaster;
728
+ probe: (c: BuildContext, o: Vector3, d: Vector3, far: number) => {
729
+ p: Vector3;
730
+ obj: Object3D<three.Object3DEventMap>;
731
+ } | null;
732
+ zoneImpact: (c: BuildContext, zone: string, force: number) => VehiclePart[];
733
+ };
734
+
735
+ /** Cabin interior: seats, steering wheel, dashboard and bus rows. */
736
+
737
+ /** A seat (`kit.seat`): width, seat height, length, backrest, lean, places on a bench, facing (+1 forward), material, headrest, sideways face and the parent it hangs from. */
738
+ type SeatOptions = {
739
+ w?: number;
740
+ h?: number;
741
+ len?: number;
742
+ back?: number;
743
+ lean?: number;
744
+ n?: number;
745
+ dir?: number;
746
+ mat?: Material;
747
+ headrest?: boolean;
748
+ face?: string;
749
+ parent?: Object3D | null;
750
+ };
751
+ /** A dashboard (`kit.dashboard`): front edge x, top y, width, depth, height, driver z, material, top material and the screen. */
752
+ type DashboardOptions = {
753
+ x: number;
754
+ y: number;
755
+ w: number;
756
+ d?: number;
757
+ h?: number;
758
+ drv?: number | null;
759
+ mat?: Material;
760
+ top?: Material;
761
+ screen?: boolean;
762
+ };
763
+ /** A car cabin (`kit.interior`), see the comment above it. */
764
+ type InteriorOptions = {
765
+ x0: number;
766
+ ft: number;
767
+ rb: number;
768
+ rt: number;
769
+ roof: number;
770
+ belt: number;
771
+ floor: number;
772
+ zIn: number;
773
+ zRoof?: number;
774
+ zSeat?: number;
775
+ seatH?: number;
776
+ rows?: number;
777
+ col?: ColorRepresentation;
778
+ trim?: ColorRepresentation;
779
+ drive?: number;
780
+ front?: string;
781
+ xFront?: number;
782
+ xRear?: number;
783
+ noConsole?: boolean;
784
+ };
785
+ /** Bus rows (`kit.busRows`), see the comment above it. */
786
+ type BusRowsOptions = {
787
+ x0: number;
788
+ x1: number;
789
+ pitch?: number;
790
+ floor: number;
791
+ zIn: number;
792
+ aisle?: number;
793
+ col?: ColorRepresentation;
794
+ seatH?: number;
795
+ ceil?: number;
796
+ poles?: boolean;
797
+ rails?: boolean;
798
+ mat?: Material;
799
+ };
800
+ declare function installInterior(kit: Kit): {
801
+ consoleBox: (c: BuildContext, x: number, fl: number, h: number, mat: MeshStandardMaterial) => void;
802
+ };
803
+
804
+ /** Where a lamp or a grille sits and how big it is (`c.vehicle` coordinates, metres); `side` +1 right, -1 left (default: the sign of `z`). */
805
+ type LampPlacement = {
806
+ x: number;
807
+ y: number;
808
+ z: number;
809
+ w?: number;
810
+ h?: number;
811
+ d?: number;
812
+ side?: number;
813
+ label?: string;
814
+ noPart?: boolean;
815
+ reach?: number;
816
+ halo?: boolean;
817
+ };
818
+ type HeadlightOptions = LampPlacement & {
819
+ style?: 'round' | 'dround' | 'rect' | 'slim' | 'split' | 'wedge' | 'ledbar' | 'truck';
820
+ yaw?: number;
821
+ /** the material that glows (default `MATERIALS.head`) */
822
+ mat?: MeshStandardMaterial;
823
+ lens?: MeshStandardMaterial;
824
+ };
825
+ type TaillightOptions = LampPlacement & {
826
+ style?: 'wrap' | 'bar' | 'vertical' | 'L' | 'round2';
827
+ /** length of the wrap-around */
828
+ wrap?: number;
829
+ };
830
+ type GrilleOptions = {
831
+ x: number;
832
+ y: number;
833
+ z?: number;
834
+ w?: number;
835
+ h?: number;
836
+ style?: 'bars' | 'mesh' | 'big' | 'seven' | 'closed' | 'truck';
837
+ col?: ColorRepresentation;
838
+ emblem?: boolean;
839
+ };
840
+ declare function installLights(kit: Kit): {
841
+ lampGroup: (c: BuildContext, x: number, y: number, z: number, rotY: number) => three.Group<three.Object3DEventMap>;
842
+ gm: (g: Object3D, geo: BufferGeometry, mat: Material, x?: number, y?: number, z?: number) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material, three.Object3DEventMap>;
843
+ wedgeY: (geo: BufferGeometry, w: number, s: number, k: number) => BufferGeometry<three.NormalBufferAttributes>;
844
+ haloTex: null;
845
+ glowTexture: () => CanvasTexture;
846
+ haloMats: Record<string, SpriteMaterial>;
847
+ halo: (parent: Object3D, x: number, y: number, z: number, size: number, hex: string, op: number) => Sprite;
848
+ lampKit: (g: Object3D, d: number, inner: Object3D[], lens: Object3D[], lensMat: MeshStandardMaterial, refl?: MeshStandardMaterial) => {
849
+ housing: (w: number, h: number, y?: number, z?: number, geoFn?: (geo: BufferGeometry) => void) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material, three.Object3DEventMap>;
850
+ lens: (w: number, h: number, y?: number, z?: number, geoFn?: (geo: BufferGeometry) => void) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material, three.Object3DEventMap>;
851
+ glow: (geo: BufferGeometry, mat: MeshStandardMaterial, x: number, y: number, z: number) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material, three.Object3DEventMap>;
852
+ proj: (y: number, z: number, r: number, mat: MeshStandardMaterial) => three.Mesh<BufferGeometry<three.NormalBufferAttributes>, Material, three.Object3DEventMap>;
853
+ };
854
+ };
855
+
856
+ /** What a particle may override: colour, variant (`red`, `white`...), opacity, size, life, growth, material, rest height. */
857
+ type SpawnOptions = {
858
+ col?: ColorRepresentation;
859
+ variant?: string;
860
+ op?: number;
861
+ s?: number;
862
+ life?: number;
863
+ grow?: number;
864
+ nofog?: boolean;
865
+ mat?: Material;
866
+ r?: number;
867
+ floor?: number;
868
+ };
869
+ /** A burst of particles: the spawn options plus a main direction, speed, spread and how far from the point they start. */
870
+ type BurstOptions = SpawnOptions & {
871
+ dir?: Vector3;
872
+ speed?: number;
873
+ spread?: number;
874
+ jitter?: number;
875
+ };
876
+ declare function installParticles(kit: Kit): {
877
+ PARTICLE_LIMIT: number;
878
+ PARTICLE_GEOMETRIES: Record<string, BufferGeometry<three.NormalBufferAttributes>>;
879
+ PARTICLE_MATERIALS: Record<string, Material>;
880
+ valueNoise: (seed: number) => (x: number, y: number) => number;
881
+ puffTexture: (seed: number, fire: boolean) => CanvasTexture;
882
+ puffMaterial: (fire: boolean, col: ColorRepresentation, op: number) => any;
883
+ SPRITE_TYPES: Record<string, number>;
884
+ PUFF_COLORS: Record<string, [string, number]>;
885
+ WIND: Vector3;
886
+ PARTICLE_LIFE: Record<string, number>;
887
+ TRANSIENT_TYPES: Record<string, number>;
888
+ killParticle: (c: BuildContext, i: number) => void;
889
+ _q: three.Quaternion;
890
+ _z: Vector3;
891
+ _t: Vector3;
892
+ tickParticles: (c: BuildContext, dt: number) => void;
893
+ burst: (c: BuildContext, type: string, pFx: Vector3, n: number, o?: BurstOptions | null) => void;
894
+ exhaustLook: (h: number) => (string | number)[];
895
+ tickEmit: (c: BuildContext, dt: number) => void;
896
+ };
897
+
898
+ declare function installRollover(kit: Kit): {
899
+ rollMeshes: (c: BuildContext) => {
900
+ list: RollMesh[];
901
+ thin: RollMesh[];
902
+ };
903
+ convexHull: (pts: number[][]) => number[][];
904
+ rollContact: (c: BuildContext, A: RollState, q: readonly number[]) => void;
905
+ exactMinY: (c: BuildContext, list: readonly RollMesh[]) => number;
906
+ finishRoll: (c: BuildContext) => void;
907
+ tickRoll: (c: BuildContext, dt: number) => void;
908
+ };
909
+
910
+ declare function installScenarios(kit: Kit): {
911
+ BODY_TYPES: {
912
+ panel: number;
913
+ door: number;
914
+ roof: number;
915
+ lid: number;
916
+ hood: number;
917
+ bumper: number;
918
+ };
919
+ };
920
+
921
+ /** Per-frame update loop for particles, fluids, spinning parts and rollover. */
922
+
923
+ declare function installTick(kit: Kit): {};
924
+
925
+ declare function installTrucks(kit: Kit): {};
926
+
927
+ declare function installWheels(kit: Kit): {};
928
+
929
+ declare function installZoneApply(kit: Kit): {
930
+ fadePaint: (c: BuildContext) => void;
931
+ abandonFx: (c: BuildContext) => void;
932
+ burntFx: (c: BuildContext) => void;
933
+ settleDrops: (c: BuildContext) => void;
934
+ };
935
+
936
+ declare function installZoneAuto(kit: Kit): {
937
+ autoZones: (c: BuildContext) => DamageZone[];
938
+ };
939
+
940
+ /** A mesh a decal ray can hit: the mesh itself, or a proxy of a heavy one that holds only the triangles of the zone's region. */
941
+ type DecalCandidate = Mesh & {
942
+ proxyOf?: Mesh;
943
+ kept?: Uint32Array;
944
+ keptBox?: Float32Array;
945
+ keptBlocks?: Float32Array;
946
+ };
947
+ /** A point of the bodywork found by the rays (`c.vehicle` coordinates) and the mesh under it. */
948
+ type SurfacePoint = {
949
+ p: Vector3;
950
+ n: Vector3;
951
+ obj?: Object3D;
952
+ };
953
+ /** How many marks of each kind `zoneDecals` puts on a zone. */
954
+ type DecalCounts = {
955
+ fine?: number;
956
+ deep?: number;
957
+ chip?: number;
958
+ rust?: number;
959
+ tear?: number;
960
+ ding?: number;
961
+ soot?: number;
962
+ crater?: number;
963
+ };
964
+ declare function installZoneDecals(kit: Kit): {
965
+ dmat: (hex: string, o: MaterialOptions) => MeshStandardMaterial;
966
+ DAMAGE_MATERIALS: Record<string, MeshStandardMaterial>;
967
+ _zq: three.Quaternion;
968
+ _zq2: three.Quaternion;
969
+ _zz: Vector3;
970
+ orientDecal: (m: Object3D, p: Vector3, n: Vector3, ang: number) => void;
971
+ decalMesh: (c: BuildContext, geo: BufferGeometry, mat: MeshStandardMaterial, p: Vector3, n: Vector3, ang: number, obj?: Object3D | null) => Mesh<BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap>;
972
+ blobGeometry: (r: number, rnd: () => number, jag?: boolean, ell?: number) => three.ShapeGeometry;
973
+ tearDecal: (c: BuildContext, p: Vector3, n: Vector3, r: number, rnd: () => number, obj: Object3D | null | undefined) => Mesh<BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap>;
974
+ _zr: Raycaster;
975
+ zoneCands: (c: BuildContext, z: DamageZone, inv: Matrix4, glassToo?: boolean) => DecalCandidate[];
976
+ _dsetC: WeakMap<Mesh<BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap>[], Set<Object3D<three.Object3DEventMap>>>;
977
+ skinOK: (c: BuildContext, z: DamageZone, o: SceneNode, ow: DamageZone | null | undefined) => boolean;
978
+ axisOf: (d: Vector3) => 0 | 1 | 2;
979
+ zoneSurf: (c: BuildContext, z: DamageZone, n: number, rnd: () => number, cands: DecalCandidate[], o?: {
980
+ u0?: number;
981
+ u1?: number;
982
+ } | null) => SurfacePoint[];
983
+ _rt: Raycaster;
984
+ scratchPath: (c: BuildContext, s: SurfacePoint, len: number, ang: number, cands: DecalCandidate[], B: ZoneBox | null | undefined) => SurfacePoint[] | null;
985
+ ribbonGeo: (pts: SurfacePoint[], wd: number, lift: number) => BufferGeometry<three.NormalBufferAttributes>;
986
+ scratchDecal: (c: BuildContext, s: SurfacePoint, len: number, wd: number, mat: MeshStandardMaterial, ang: number, cands: DecalCandidate[], B: ZoneBox | null | undefined, pts?: SurfacePoint[] | null) => Mesh<BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap> | null;
987
+ zoneDecals: (c: BuildContext, z: DamageZone, spec: DecalCounts, cands: DecalCandidate[]) => SurfacePoint[];
988
+ };
989
+
990
+ /** A mesh a zone dents, and whether it is the vehicle's shell (`c.deform`). */
991
+ type DentTarget = {
992
+ o: Mesh;
993
+ deform: boolean;
994
+ };
995
+ /** A dent: centre (`u`, `v`, absolute tangent coordinates), radii (`ru`, `rv`, metres), depth and the phase of its ripple. */
996
+ type Dent = {
997
+ u: number;
998
+ v: number;
999
+ ru: number;
1000
+ rv: number;
1001
+ depth: number;
1002
+ ph: number;
1003
+ };
1004
+ type DentOptions = {
1005
+ /** a crease along the panel: its `v`, width and depth */
1006
+ crease?: {
1007
+ v: number;
1008
+ w: number;
1009
+ depth: number;
1010
+ } | null;
1011
+ /** how close to the zone's edge the dent fades, as a share of it */
1012
+ edge?: number;
1013
+ /** the meshes to dent (default: `dentTargets`) */
1014
+ targets?: DentTarget[];
1015
+ noSub?: boolean;
1016
+ /** the longest edge after subdividing, metres */
1017
+ sub?: number;
1018
+ /** moves a point already dented by `f` */
1019
+ extra?: (p: Vector3, f: number) => void;
1020
+ /** moves any point of the mesh; answers whether it moved */
1021
+ extraAll?: (p: Vector3) => boolean;
1022
+ };
1023
+ /** A piece `cutPanel` made: the whole mesh (`whole`), a cut piece hung on the vehicle (`mesh`), or a cut whose piece was dropped (`cut` alone). */
1024
+ type PanelPiece = {
1025
+ mesh?: Mesh;
1026
+ whole?: boolean;
1027
+ cut?: boolean;
1028
+ };
1029
+ type CutPanelOptions = {
1030
+ anyN?: boolean;
1031
+ pieceTasks?: Map<Mesh, {
1032
+ geo: BufferGeometry;
1033
+ step: (deadline: number) => boolean;
1034
+ }>;
1035
+ };
1036
+ declare function installZoneDent(kit: Kit): {
1037
+ sm: (t: number) => number;
1038
+ subdivIn: (geo: BufferGeometry, rel: Matrix4, B: ZoneBox, maxLen: number) => BufferGeometry<three.NormalBufferAttributes>;
1039
+ dentTargets: (c: BuildContext, z: DamageZone, inv: Matrix4) => DentTarget[];
1040
+ zoneDent: (c: BuildContext, z: DamageZone, dents: Dent[], dirty: Set<Object3D>, opt?: DentOptions | null) => {
1041
+ field: (p: Vector3) => number;
1042
+ moved: Object3D<three.Object3DEventMap>[];
1043
+ ax: number[];
1044
+ a: number;
1045
+ cu: number;
1046
+ cv: number;
1047
+ hu: number;
1048
+ hv: number;
1049
+ outer: number;
1050
+ };
1051
+ cutPanel: (c: BuildContext, z: DamageZone, rect: number[], keep: boolean, dirty: Set<Object3D>, o?: CutPanelOptions | null) => PanelPiece[];
1052
+ pivotOf: (c: BuildContext, objs: readonly (Object3D | null | undefined)[], at: Vector3) => three.Group<three.Object3DEventMap>;
1053
+ };
68
1054
 
69
1055
  var plate = {
70
1056
  band: "BRAZIL"
@@ -295,7 +1281,7 @@ type PartialLocaleStrings = {
295
1281
  [K in keyof LocaleStrings]?: Partial<LocaleStrings[K]>;
296
1282
  };
297
1283
  /** Registers (or extends) a locale under a code such as `es` or `pt-BR`. Missing keys fall back to English. */
298
- declare function registerLocale(code: string, strings: PartialLocaleStrings | Record<string, any>): void;
1284
+ declare function registerLocale(code: string, strings: PartialLocaleStrings | Record<string, unknown>): void;
299
1285
  /** Codes of the registered locales. */
300
1286
  declare function listLocales(): string[];
301
1287
  /**
@@ -312,6 +1298,134 @@ type Translate = (key: string, vars?: Record<string, unknown>) => string;
312
1298
  * `{side}` (feminine word) and `{sideM}` (masculine word), so one template reads right in languages with grammatical gender.
313
1299
  */
314
1300
  declare function createTranslate(strings: LocaleStrings): Translate;
1301
+ /** Regular expressions that recognise a part by its label when no `key` was given. Built from the `matchers` of the string table. */
1302
+ interface Matchers {
1303
+ windshield: RegExp;
1304
+ rear: RegExp;
1305
+ side: RegExp;
1306
+ tank: RegExp;
1307
+ diesel: RegExp;
1308
+ fuel: RegExp;
1309
+ /** Zone ids that already start like a glass id, so no `glass_` prefix is added. */
1310
+ glassId: RegExp;
1311
+ }
1312
+ declare function createMatchers(strings: LocaleStrings): Matchers;
1313
+
1314
+ /** Pure helpers shared by every module. They never touch three.js. */
1315
+ /** Deterministic hash of three numbers to [0, 1). */
1316
+ declare function hash(a: number, b: number, c: number): number;
1317
+ declare function clamp(v: number, a: number, b: number): number;
1318
+ /** Smoothstep on [0, 1]. */
1319
+ declare function smooth(t: number): number;
1320
+ /** Mulberry32 pseudo random generator. The same seed always gives the same sequence. */
1321
+ declare function rng(seed: number): () => number;
1322
+ /** FNV-1a hash of a string, used to derive seeds from vehicle keys and zone ids. */
1323
+ declare function strHash(s: string): number;
1324
+
1325
+ /** The three.js namespace the host passes (typed by `@types/three`; the package binds to no version at runtime). */
1326
+ type Three = typeof three;
1327
+ /** The helpers the modules share through `kit._`: what each `install*` puts there. */
1328
+ type KitShared = ReturnType<typeof installContext> & ReturnType<typeof installArmor> & ReturnType<typeof installBody> & ReturnType<typeof installCar> & ReturnType<typeof installDamagePanels> & ReturnType<typeof installDamageParts> & ReturnType<typeof installExplosion> & ReturnType<typeof installFluids> & ReturnType<typeof installGeometry> & ReturnType<typeof installGlassDamage> & ReturnType<typeof installGlass> & ReturnType<typeof installHood> & ReturnType<typeof installImpact> & ReturnType<typeof installInterior> & ReturnType<typeof installLights> & ReturnType<typeof installMaterials> & ReturnType<typeof installParticles> & ReturnType<typeof installRollover> & ReturnType<typeof installScenarios> & ReturnType<typeof installTick> & ReturnType<typeof installTrucks> & ReturnType<typeof installWarp> & ReturnType<typeof installWheels> & ReturnType<typeof installZoneApply> & ReturnType<typeof installZoneAuto> & ReturnType<typeof installZoneCore> & ReturnType<typeof installZoneDecals> & ReturnType<typeof installZoneDent> & ReturnType<typeof installZoneDerive>;
1329
+ /**
1330
+ * Internal shape of the kit while the modules are installing. Modules attach the public API to it (`kit.x = ...`)
1331
+ * and share helpers through `kit._`. The public, typed view of the same object is `VehicleKit` in `api.ts`.
1332
+ */
1333
+ interface Kit {
1334
+ THREE: Three;
1335
+ V3: Three['Vector3'];
1336
+ PI: number;
1337
+ /** The page's document (the canvases of the glass, lamp and smoke textures); a host with no DOM never draws them. */
1338
+ document: Document;
1339
+ strings: ReturnType<typeof resolveStrings>;
1340
+ t: (key: string, vars?: Record<string, unknown>) => string;
1341
+ matchers: ReturnType<typeof createMatchers>;
1342
+ hash: typeof hash;
1343
+ clamp: typeof clamp;
1344
+ smooth: typeof smooth;
1345
+ /** Helpers shared between modules (not public). */
1346
+ _: KitShared;
1347
+ [key: string]: any;
1348
+ }
1349
+ /** The object a vehicle is built in (`kit.build` returns it): the groups, the parts, the zones and the builders `add`, `roundBox`, `part`, ... */
1350
+ type BuildContext = InstanceType<KitShared['BuildContext']>;
1351
+ /**
1352
+ * A node of a vehicle's scene graph as the modules read it while they walk it (`traverse`): any `Object3D`, with what a mesh, a sprite or
1353
+ * a group adds there when it is one. The modules check the flags (`isMesh`, `isSprite`) before they touch the mesh fields.
1354
+ */
1355
+ type SceneNode = Object3D & {
1356
+ geometry?: BufferGeometry;
1357
+ material?: Material;
1358
+ morphTargetInfluences?: number[];
1359
+ isMesh?: boolean;
1360
+ isSprite?: boolean;
1361
+ isGroup?: boolean;
1362
+ isInstancedMesh?: boolean;
1363
+ isSkinnedMesh?: boolean;
1364
+ isLight?: boolean;
1365
+ isPoints?: boolean;
1366
+ isLine?: boolean;
1367
+ };
1368
+
1369
+ /**
1370
+ * Light mode ("lite"): the same vehicles with fewer triangles, for a whole street of them. Port of the `[LOD]` hooks of the team's Frota Leve
1371
+ * (frota-leve.js lines 21-65, 232-257, 1205-1221, 14155-14170). Every number is a setting; with `on` false nothing changes, so every golden
1372
+ * of the full-detail build stays byte for byte the same.
1373
+ */
1374
+
1375
+ interface LodSettings {
1376
+ /** Light mode is active for the builds that run now. Set by `kit.build(key, state, zones, { lod: true })`. */
1377
+ on: boolean;
1378
+ /** Fraction of the segments three's own generators keep (cylinders, spheres, tori, lathes, tubes, extrusions, circles, rings). */
1379
+ segmentFraction: number;
1380
+ /** Rounding rings of a rounded box (the full build uses 3). */
1381
+ roundingRings: number;
1382
+ /** Multiplier of the maximum edge length when subdividing a mesh (bigger triangles). */
1383
+ subdivisionFactor: number;
1384
+ /** A box with an edge under this, or a rounding radius under 1.2 cm, is drawn as a plain 12-triangle box. */
1385
+ flatBoxEdge: number;
1386
+ /** Fewest segments of a superellipse loft. */
1387
+ minLoftSegments: number;
1388
+ /** Fraction of a loft's segments. */
1389
+ loftSegmentFraction: number;
1390
+ /** Fewest stations of a resampled loft. */
1391
+ minStations: number;
1392
+ /** Fraction of the stations of a resampled loft. */
1393
+ stationFraction: number;
1394
+ /** Multiplier of the grid cell size of grilles and side grilles. */
1395
+ gridFactor: number;
1396
+ /** Materials (by name in `kit.materials`) whose meshes are never seen from outside and are left out in light mode. */
1397
+ hiddenMaterials: readonly string[];
1398
+ }
1399
+ declare const defaultLodSettings: LodSettings;
1400
+ /** The settings the kit starts with: the defaults, overridden by the options. */
1401
+ declare function createLod(options?: Partial<LodSettings>): LodSettings;
1402
+ /**
1403
+ * A copy of the three.js namespace whose geometry generators take fewer segments while `lod.on` is true (and whose canvas textures come out in
1404
+ * sRGB when three has colour management). With `lod.on` false every generator passes its arguments through untouched.
1405
+ */
1406
+ declare function wrapThreeForLod(TH: Three, lod: LodSettings): Three;
1407
+
1408
+ /** Smoke, fire and dust puffs handed to the host's effects world instead of the kit's own sprites. */
1409
+ /** What `EffectSink.play` of `game-contracts` takes, as a structural type: this package does not depend on the contracts layer. */
1410
+ interface ParticleEffectRequest {
1411
+ readonly effect: string;
1412
+ readonly point: [number, number, number];
1413
+ readonly values: Readonly<Record<string, number>>;
1414
+ }
1415
+ /** The host's effects world as far as the puffs need it (`EffectSink` of `game-contracts` fits). */
1416
+ interface ParticleEffects {
1417
+ play(request: ParticleEffectRequest): unknown;
1418
+ }
1419
+
1420
+ type DamageableMaterial = 'metal' | 'glass' | 'rubber' | 'fuel';
1421
+ type DamageableSide = 'center' | 'left' | 'right';
1422
+ /** What a zone is, by type: the material it is made of and the part name a game shows. */
1423
+ interface DamageableKind {
1424
+ material: DamageableMaterial;
1425
+ part: string;
1426
+ }
1427
+ /** Zone type (and, for some, `fxKey` or `sub`) to material and part. A game replaces or adds entries with `kit.damageableKinds`. */
1428
+ declare const defaultDamageableKinds: Record<string, DamageableKind>;
315
1429
 
316
1430
  /**
317
1431
  * Public types of `@adatechnology/game-vehicles`.
@@ -337,8 +1451,10 @@ interface Band {
337
1451
  /** CSS colour used by the UI widgets. */
338
1452
  color: string;
339
1453
  }
340
- /** Where a vehicle is built: the context returned by {@link VehicleKit.build}. */
341
- interface VehicleContext {
1454
+ /** Where a vehicle is built: the context returned by {@link VehicleKit.build}, with the builders of {@link BuildContext}. */
1455
+ type VehicleContext = BuildContext & VehicleContextFields;
1456
+ /** The fields of a built vehicle's context. */
1457
+ interface VehicleContextFields {
342
1458
  /** Add this to the scene. */
343
1459
  root: ThreeObject;
344
1460
  /** The vehicle itself (a child of `root`); zones, parts and meshes live here. */
@@ -375,8 +1491,11 @@ interface VehicleMeta {
375
1491
  bodyKind?: 'box' | 'body';
376
1492
  exhaust?: ThreeVector | false;
377
1493
  exhaustDir?: ThreeVector;
378
- /** Replaces the default armour (state `modified`). */
379
- armor?: (c: VehicleContext, kit: VehicleKit) => void;
1494
+ /**
1495
+ * Replaces the default armour (state `modified`). A few fleet vehicles write their protection level here as text (`'III'`) while they
1496
+ * build and set the builder afterwards.
1497
+ */
1498
+ armor?: ((c: VehicleContext, kit: VehicleKit) => void) | string;
380
1499
  [key: string]: any;
381
1500
  }
382
1501
  interface VehicleSpec {
@@ -410,6 +1529,77 @@ type PartLabel = string | {
410
1529
  key: string;
411
1530
  label?: string;
412
1531
  };
1532
+ /** A mesh the rollover rests on, with its matrix into the vehicle frame (`rollMeshes`). */
1533
+ interface RollMesh {
1534
+ o: Mesh;
1535
+ M: Matrix4;
1536
+ }
1537
+ /** A rollover in progress (`kit.roll`): time and duration, side, the support hull S ([y, z]), the contact point and the fall target. */
1538
+ interface RollState {
1539
+ t: number;
1540
+ dur: number;
1541
+ s: number;
1542
+ S: number[][];
1543
+ last: number;
1544
+ cz: number;
1545
+ target: number;
1546
+ x: number;
1547
+ L: number;
1548
+ bounce: number;
1549
+ cen: number[];
1550
+ hitAt: readonly number[] | null;
1551
+ hits: number;
1552
+ thin: RollMesh[];
1553
+ y0: number;
1554
+ /** State a plugin keeps on the rollover (the fleet's military group marks its own handling). */
1555
+ [extra: string]: unknown;
1556
+ }
1557
+ /** A part thrown by an explosion (`fling`): its holder, linear and angular velocity, radius, whether it landed and how long it keeps burning. */
1558
+ interface FlyingPiece {
1559
+ o: Group;
1560
+ v: Vector3;
1561
+ w: Vector3;
1562
+ r: number;
1563
+ landed: boolean;
1564
+ trail: number;
1565
+ }
1566
+ /** A part turning on its own every frame (a wheel, a rotor, a propeller): `v` radians per second about `axis`, slowing by `decay` per second. */
1567
+ interface VehicleSpin {
1568
+ o: Object3D;
1569
+ axis: 'x' | 'y' | 'z';
1570
+ v: number;
1571
+ decay?: number;
1572
+ /** a road wheel, turned by the vehicle's speed */
1573
+ track?: boolean;
1574
+ /** a per-frame hook disguised as a spin (its `o.rotation` getter runs code), not a real part */
1575
+ hook?: boolean;
1576
+ }
1577
+ /** A continuous source of smoke or fire (`kit.addEmitter`): where (`c.vehicle`, or the vehicle world with `world`), how many puffs a second. */
1578
+ interface VehicleEmitter {
1579
+ p: Vector3;
1580
+ kind: string;
1581
+ world: boolean;
1582
+ rate: number;
1583
+ acc: number;
1584
+ s: number;
1585
+ dir: Vector3 | null;
1586
+ gap: number;
1587
+ }
1588
+ /** A lamp the kit drew (`c.lights`): its group, the lens and the inner meshes (bulb, reflector), its tint and what happened to it. */
1589
+ interface VehicleLamp {
1590
+ group: ThreeObject | null;
1591
+ lens: ThreeObject[];
1592
+ inner: ThreeObject[];
1593
+ kind: string;
1594
+ tint: string;
1595
+ /** broken; `'gone'` once the whole unit came off */
1596
+ broken: boolean | 'gone';
1597
+ cracked?: boolean;
1598
+ dark?: boolean;
1599
+ /** The additive halo sprites of the lamp, hidden when it breaks. */
1600
+ halo?: ThreeObject[];
1601
+ [extra: string]: unknown;
1602
+ }
413
1603
  /** A damage zone of a built vehicle. */
414
1604
  interface DamageZone {
415
1605
  id: string;
@@ -421,13 +1611,25 @@ interface DamageZone {
421
1611
  health: number;
422
1612
  band: number;
423
1613
  internal?: boolean;
424
- owned?: boolean;
1614
+ /** The objects of the vehicle the zone holds (resolved when the zones are derived). */
1615
+ owned: ThreeObject[];
1616
+ /** The lamps, panes and wheels the zone holds. */
1617
+ lights: VehicleLamp[];
1618
+ glass: ThreeObject[];
1619
+ wheels: ThreeObject[];
425
1620
  tags: string[];
426
1621
  /** `[xMin, xMax, zMin, zMax]` rectangle on the top-down damage map. */
427
1622
  map: [number, number, number, number];
428
- box: ThreeObject;
1623
+ /** The zone's box in `c.vehicle` coordinates. */
1624
+ box: ZoneBox;
429
1625
  /** Overrides the id used to seed the random damage (keeps the output of an earlier pack identical). */
430
1626
  seedId?: string;
1627
+ /** What the zone is (`panel`, `door`, `glass`, `light`, `wheel`, `internal`...). */
1628
+ type: string;
1629
+ /** The internal system an internal zone stands for (`engine`, `fuel_tank`, `underbody`...). */
1630
+ sub?: string;
1631
+ /** The effects key (sounds, labels) when it differs from the id. */
1632
+ fxKey?: string;
431
1633
  [key: string]: any;
432
1634
  }
433
1635
  /** Health per zone id (0..100) and scenario flags. */
@@ -608,6 +1810,10 @@ interface ParticleMaterials {
608
1810
  interface ImpactOptions {
609
1811
  /** Do not leave a stain. */
610
1812
  noStain?: boolean;
1813
+ /** No sparks, scrap or splashes. */
1814
+ noFx?: boolean;
1815
+ /** Deepest dent in metres (the default comes from the width and the force). */
1816
+ maxDepth?: number;
611
1817
  [key: string]: any;
612
1818
  }
613
1819
  interface SplatOptions {
@@ -631,6 +1837,11 @@ interface ZoneDamageEntry {
631
1837
  name: string;
632
1838
  damage: number;
633
1839
  }
1840
+ /** What `zoneDamageAt` returns: the id of the zone hit and the damage it spread to every zone near the point. */
1841
+ interface ZoneDamageResult {
1842
+ main: string | null;
1843
+ list: ZoneDamageEntry[];
1844
+ }
634
1845
  interface DamageMapOptions {
635
1846
  /** Id of the selected zone. */
636
1847
  selected?: string;
@@ -716,8 +1927,12 @@ interface VehicleKit {
716
1927
  zoneScenario(c: VehicleContext, idOrName: string): ScenarioResult;
717
1928
  zoneOverall(c: VehicleContext): OverallHealth;
718
1929
  zoneAt(c: VehicleContext, point: ThreeVector, object?: ThreeObject): DamageZone | null;
719
- zoneDamageAt(c: VehicleContext, point: ThreeVector, dir: ThreeVector, force: number, object?: ThreeObject): ZoneDamageEntry[];
720
- zonePoint(c: VehicleContext, zone: DamageZone): ThreeVector;
1930
+ zoneDamageAt(c: VehicleContext, point: ThreeVector, dir: ThreeVector, force: number, object?: ThreeObject): ZoneDamageResult;
1931
+ /** Point and direction of an impact on one side (`front`, `rear`, `left` or `right`), in vehicle coordinates. */
1932
+ zonePoint(c: VehicleContext, side: 'front' | 'rear' | 'left' | 'right' | string): {
1933
+ p: Vector3;
1934
+ dir: Vector3;
1935
+ };
721
1936
  zoneImpact(c: VehicleContext, side: 'front' | 'rear' | 'left' | 'right' | string, force: number): unknown;
722
1937
  impact(c: VehicleContext, point: ThreeVector, dir: ThreeVector, force: number, options?: ImpactOptions): unknown[];
723
1938
  splat(c: VehicleContext, point: ThreeVector, normal: ThreeVector, radius: number, options?: SplatOptions): {
@@ -776,17 +1991,6 @@ declare function legacyGlassId(key: string | null, label: string, side: number,
776
1991
  /** Original id of a light zone: `farol_e`, `lanterna_c`, `farol_d_2`... */
777
1992
  declare function legacyLightId(kind: string, side: string, index: number): string;
778
1993
 
779
- /** Pure helpers shared by every module. They never touch three.js. */
780
- /** Deterministic hash of three numbers to [0, 1). */
781
- declare function hash(a: number, b: number, c: number): number;
782
- declare function clamp(v: number, a: number, b: number): number;
783
- /** Smoothstep on [0, 1]. */
784
- declare function smooth(t: number): number;
785
- /** Mulberry32 pseudo random generator. The same seed always gives the same sequence. */
786
- declare function rng(seed: number): () => number;
787
- /** FNV-1a hash of a string, used to derive seeds from vehicle keys and zone ids. */
788
- declare function strHash(s: string): number;
789
-
790
1994
  /**
791
1995
  * Armour levels of a vehicle, after NIJ 0108: the level says which rounds the glass and the steel stop, and how many hits they take
792
1996
  * before they give. Every number is configurable: a game passes its own table in `VehicleDestructibleOptions.armourLevels`.
@@ -806,7 +2010,7 @@ type ArmourLevel = {
806
2010
  declare const ARMOUR_LEVELS: Readonly<Record<ArmourLevelId, ArmourLevel>>;
807
2011
  /** The level a vehicle has: the host's option, else its spec (`armor`), else III for the old `armored`/`bullet` flags, else none. */
808
2012
  declare function armourLevelOf(meta: {
809
- armor?: string;
2013
+ armor?: unknown;
810
2014
  armored?: boolean;
811
2015
  bullet?: boolean;
812
2016
  }, option?: ArmourLevelId | null): ArmourLevelId | null;
@@ -839,7 +2043,7 @@ interface PartDef {
839
2043
  /** The damage zone this part is, when it is one. */
840
2044
  zoneId?: string;
841
2045
  /** The panes of a glass part no damage zone claims. */
842
- panes?: any[];
2046
+ panes?: Mesh[];
843
2047
  /** Fluid held, in litres. */
844
2048
  contains?: {
845
2049
  fluid: string;
@@ -913,21 +2117,13 @@ interface CreaseQueue {
913
2117
  */
914
2118
  declare function createCreaseQueue(): CreaseQueue;
915
2119
 
916
- /**
917
- * `createVehicleDestructible`: a vehicle that follows the destruction contract of `@adatechnology/game-contracts` and brings its own rules.
918
- * Every damage zone and mechanical part is a part with a material, hits become events (dent, hole, crack, fracture, detach, leak, ignite,
919
- * melt, explode), joints come apart by wear, by a wrench or by breaking, and the hidden mechanics change how the vehicle drives.
920
- *
921
- * It depends on the contracts only (types) and on the kit it is given: not on the default destruction world.
922
- */
923
-
924
2120
  interface VehicleDestructibleOptions {
925
2121
  /** Object id the host gives (`DestructibleImpl.id`). Default: the vehicle key. */
926
2122
  id?: string;
927
2123
  /** Display name. Default: the vehicle name. */
928
2124
  name?: string;
929
2125
  /** Object whose space `describe()` answers in (the wrapper the host placed the vehicle in). Default: `c.root`. */
930
- frame?: any;
2126
+ frame?: unknown;
931
2127
  /** Tow hitch: the option wins over the spec flag, the spec flag over the seeded choice. */
932
2128
  hitch?: boolean;
933
2129
  /** Do not create or move any mesh (logic only, for servers and tests that need no scene). */
@@ -1024,7 +2220,7 @@ interface VehicleItemOptions {
1024
2220
  }
1025
2221
  interface VehicleItem {
1026
2222
  /** Add this to the scene: origin at the centre of the footprint on the floor, front facing +z. */
1027
- root: any;
2223
+ root: Group;
1028
2224
  /** The built vehicle inside it. */
1029
2225
  vehicle: VehicleContext;
1030
2226
  }
@@ -1104,7 +2300,7 @@ interface CabinSource {
1104
2300
  }
1105
2301
  interface CabinEnclosureOptions {
1106
2302
  /** The object the destructible answers in (its `frame` option, where the host placed the vehicle): the holes of `state()` are in its space. Default `vehicle.root`. */
1107
- readonly frame?: any;
2303
+ readonly frame?: unknown;
1108
2304
  /** Gaps of the shut doors and vents, share per second of the smoke pressing on the closed shell (default {@link CABIN_LEAK}). */
1109
2305
  readonly leak?: number;
1110
2306
  /** How open a door or lid has to be (share of its full swing) to count as open (default 0.06: ajar). */
@@ -1122,9 +2318,4 @@ declare function swingOf(vehicle: VehicleContext, partId: string): number;
1122
2318
  */
1123
2319
  declare function cabinEnclosure(source: CabinSource, options?: CabinEnclosureOptions): Enclosure | null;
1124
2320
 
1125
- /** Glass cracks, shattering and tempered or laminated breakage textures. */
1126
-
1127
- /** The material of a pane with cracks drawn on it. A host warms its program at load with any texture: the first crack is in the middle of a blast. */
1128
- declare function crackedGlassMaterial(THREE: any, texture: unknown): any;
1129
-
1130
- export { ARMOUR_LEVELS, type ArmourLevel, type ArmourLevelId, type Band, type BandId, type BandIndex, type BandOverride, type BuildFunction, type BuildOptions, type BuildState, type BuildZoneState, CABIN_LEAK, CRASH_RULES, type CabinBox, type CabinEnclosureOptions, type CabinSource, type CrashOptions, type CrashResult, type CrashRules, type CreaseQueue, type CreaseWork, type DamageMapOptions, type DamageZone, type Damageable, type DamageableKind, type DamageableMaterial, type DamageableSide, type DriveReport, type ExplodeOptions, type FlagEffect, type FluidDefinition, type HeadlightLens, type ImpactOptions, JOINT_RULES, type JointDef, type KitConfiguration, type KitInternals, type KitTexts, LEGACY_STATES, LEGACY_ZONE_IDS, type LocalBox, type LocaleStrings, type LodSettings, type OverallHealth, type PartDef, type PartLabel, type PartRole, type PartialLocaleStrings, type ParticleEffectRequest, type ParticleEffects, type ParticleMaterials, type Plugin, type ResolvedConfiguration, SEED_SALTS, type ScenarioContext, type ScenarioDefinition, type ScenarioResult, type SplatOptions, type ThreeObject, type ThreeVector, type Translate, type UiHelpers, type VehicleContext, type VehicleDestructible, type VehicleDestructibleOptions, type VehicleItem, type VehicleItemOptions, type VehicleKit, type VehicleKitOptions, type VehicleMeta, type VehicleModel, type VehiclePart, type VehicleSpec, type VehicleStatus, type ZoneDamageEntry, type ZoneEffect, type ZoneState, armourLevelOf, buildVehicleItem, buildVehicleModel, cabinBoxOf, cabinEnclosure, clamp, crackedGlassMaterial, crashDeltaV, crashVehicle, createCreaseQueue, createLod, createTranslate, createVehicleDestructible, createVehicleKit, defaultDamageableKinds, defaultLodSettings, format, hash, legacyGlassId, legacyLightId, legacyZoneId, listLocales, registerLegacySeeds, registerLocale, resolveStrings, rng, smooth, strHash, swingOf, wrapThreeForLod };
2321
+ export { ARMOUR_LEVELS, type ArmourLevel, type ArmourLevelId, type Band, type BandId, type BandIndex, type BandOverride, type BuildFunction, type BuildOptions, type BuildState, type BuildZoneState, type BusRowsOptions, CABIN_LEAK, CRASH_RULES, type CabinBox, type CabinEnclosureOptions, type CabinSource, type CarSpec, type CarWheel, type CrashOptions, type CrashResult, type CrashRules, type CreaseQueue, type CreaseWork, type CutTest, type DamageMapOptions, type DamageZone, type Damageable, type DamageableKind, type DamageableMaterial, type DamageableSide, type DashboardOptions, type DriveReport, type EngineBaySpec, type ExplodeOptions, type FlagEffect, type FluidDefinition, type GlassOptions, type GlassQuad, type Greenhouse, type GrilleOptions, type HeadlightLens, type HeadlightOptions, type ImpactOptions, type InteriorOptions, JOINT_RULES, type JointDef, type KitConfiguration, type KitInternals, type KitTexts, LEGACY_STATES, LEGACY_ZONE_IDS, type LabelArgument, type LocalBox, type LocaleStrings, type LodSettings, type LoftRow, type LoftStation, type OverallHealth, type PaneLook, type PartDef, type PartLabel, type PartRole, type PartialLocaleStrings, type ParticleEffectRequest, type ParticleEffects, type ParticleMaterials, type PathItem, type Plugin, type Puddle, type PuddleLobe, type ResolvedConfiguration, SEED_SALTS, type ScenarioContext, type ScenarioDefinition, type ScenarioResult, type SceneNode, type SeatOptions, type ShellSpec, type SmoothLoftOptions, type Splat, type SplatOptions, type TaillightOptions, type ThreeObject, type ThreeVector, type Translate, type TumbleSpec, type UiHelpers, type UnderbodySpec, type VehicleContext, type VehicleDestructible, type VehicleDestructibleOptions, type VehicleItem, type VehicleItemOptions, type VehicleKit, type VehicleKitOptions, type VehicleMeta, type VehicleModel, type VehiclePart, type VehicleSpec, type VehicleStatus, type WarpFn, type WarpOptions, type ZoneDamageEntry, type ZoneDef, type ZoneEffect, type ZoneState, armourLevelOf, buildVehicleItem, buildVehicleModel, cabinBoxOf, cabinEnclosure, clamp, crackedGlassMaterial, crashDeltaV, crashVehicle, createCreaseQueue, createLod, createTranslate, createVehicleDestructible, createVehicleKit, defaultDamageableKinds, defaultLodSettings, format, hash, legacyGlassId, legacyLightId, legacyZoneId, listLocales, registerLegacySeeds, registerLocale, resolveStrings, rng, smooth, strHash, swingOf, wrapThreeForLod };