@adatechnology/game-weather-three 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,8 +33,9 @@ picture.update(dt)
33
33
  ## Bench
34
34
 
35
35
  `createWeatherTestModule({ visual: createWeatherVisual({ vfx: room.vfx }) })` (the module of `game-weather`) adds the picture to the weather bench: seven layers
36
- (rain curtain, near rain and splashes, mist and ash, sky, lightning, headlights, heat haze; names in pt-BR and en), and a lamp rig (two lamps on a block, the
37
- Workshop's `hlMat` lenses) in front of the camera to show the headlights. `layers: { sky: false }` keeps a room's own sky; the bench's own `fog` layer reaches the
36
+ (rain curtain, near rain and splashes, mist and ash, sky, lightning, headlights, heat haze; names in pt-BR and en), and a lamp rig in front of the camera to show the headlights. The rig's car is not drawn here: pass
37
+ `vehicles: (THREE) => createVehiclesThree(THREE, { kit })` (game-vehicles-three, with the fleet installed) and it builds a fleet car (`rigVehicle`, default
38
+ `midsize_sedan`) under the lamps, so it follows the vehicles SDK; without it the rig has only the lamps and their beams. `layers: { sky: false }` keeps a room's own sky; the bench's own `fog` layer reaches the
38
39
  renderer too. The fog layer gives back the fog the host had when it is switched off.
39
40
 
40
41
  ## Proof
package/dist/index.d.ts CHANGED
@@ -313,9 +313,26 @@ type WeatherVisualOptions = Pick<WeatherRendererOptions, 'profile' | 'random' |
313
313
  readonly vfx?: VfxWorld;
314
314
  /** Where the lamp rig stands (the two headlights of the Workshop's car, to see the beams); `false` leaves it out. Default 2.5 m ahead of the test room camera, lamps toward it. */
315
315
  readonly rig?: readonly [x: number, z: number, turn: number] | false;
316
+ /**
317
+ * The car the lamps are mounted on, built by the vehicles SDK for the host's three.js (`createVehiclesThree` of game-vehicles-three with the fleet installed), so the rig follows the fleet when it
318
+ * changes. Without it the rig has only the lamps and their beams: no car drawn here.
319
+ */
320
+ readonly vehicles?: (THREE: ThreeLib) => RigVehicles;
321
+ /** Fleet id of the rig's car (default `midsize_sedan`). */
322
+ readonly rigVehicle?: string;
316
323
  /** Which layers start on (all do by default); the room that is not about weather starts the sky and the fog off to keep its own look. */
317
324
  readonly layers?: Partial<Record<WeatherLayerId, boolean>>;
318
325
  };
326
+ /** What the rig needs of the vehicles SDK (`VehiclesThree` of game-vehicles-three): a car in the game frame (front on +z, wheels on y = 0) and its length. */
327
+ interface RigVehicles {
328
+ build(key: string, options?: {
329
+ quality?: 'high' | 'lite';
330
+ }): {
331
+ readonly group: THREE_NS.Object3D;
332
+ readonly length: number;
333
+ dispose(): void;
334
+ };
335
+ }
319
336
  /**
320
337
  * The picture of the weather for the weather bench: `createWeatherTestModule({ visual: createWeatherVisual({ vfx: room.vfx }) })`. It draws the weather the bench shows with
321
338
  * `createWeatherRenderer` on the room's scene and camera, switches each part with the bench layers and puts a lamp rig in front of the camera for the headlights.
@@ -328,4 +345,4 @@ type WeatherVisualText = {
328
345
  };
329
346
  declare const weatherVisualTextOf: (locale: string) => WeatherVisualText;
330
347
 
331
- export { ASH, FOG_EXP_FROM, FOG_NEAR, FOG_ZONE_NEAR, type Fog, type FogValues, HEADLIGHTS, HEAT_HAZE, HEAT_HAZE_FRAGMENT, HEAT_HAZE_VERTEX, type HeadlightRules, type Headlights, type HeatHaze, LIGHTNING, type Lightning, MIST, type NearRain, type NearRainOptions, RAIN_CURTAIN, RAIN_CURTAIN_FRAGMENT, RAIN_CURTAIN_FULL_AT, RAIN_CURTAIN_PROFILES, RAIN_CURTAIN_VERTEX, type RainCurtain, type RainCurtainOptions, SKY_DAY, SKY_NIGHT, SPLASH_FROM_MM, type Sky, type ThreeLib, type Vec3, WEATHER_LAYERS, type WeatherLayerId, type WeatherProfileName, type WeatherRenderer, type WeatherRendererOptions, type WeatherSource, type WeatherVisualOptions, type WeatherVisualText, ZONE_FOG_DEFAULTS, ZONE_LIGHT, type ZoneFog, createFog, createHeadlights, createHeatHaze, createLightning, createNearRain, createRainCurtain, createSky, createWeatherRenderer, createWeatherVisual, defaultHeadlightRule, densityForFar, emitAirborne, fogOf, rainCurtainPositions, weatherVisualTextOf };
348
+ export { ASH, FOG_EXP_FROM, FOG_NEAR, FOG_ZONE_NEAR, type Fog, type FogValues, HEADLIGHTS, HEAT_HAZE, HEAT_HAZE_FRAGMENT, HEAT_HAZE_VERTEX, type HeadlightRules, type Headlights, type HeatHaze, LIGHTNING, type Lightning, MIST, type NearRain, type NearRainOptions, RAIN_CURTAIN, RAIN_CURTAIN_FRAGMENT, RAIN_CURTAIN_FULL_AT, RAIN_CURTAIN_PROFILES, RAIN_CURTAIN_VERTEX, type RainCurtain, type RainCurtainOptions, type RigVehicles, SKY_DAY, SKY_NIGHT, SPLASH_FROM_MM, type Sky, type ThreeLib, type Vec3, WEATHER_LAYERS, type WeatherLayerId, type WeatherProfileName, type WeatherRenderer, type WeatherRendererOptions, type WeatherSource, type WeatherVisualOptions, type WeatherVisualText, ZONE_FOG_DEFAULTS, ZONE_LIGHT, type ZoneFog, createFog, createHeadlights, createHeatHaze, createLightning, createNearRain, createRainCurtain, createSky, createWeatherRenderer, createWeatherVisual, defaultHeadlightRule, densityForFar, emitAirborne, fogOf, rainCurtainPositions, weatherVisualTextOf };
@@ -1658,6 +1658,17 @@ var GameWeatherThree = (() => {
1658
1658
  ])
1659
1659
  ]
1660
1660
  };
1661
+ var FUEL_LEAK_ONLY = {
1662
+ id: "fuel_leak_only",
1663
+ pageId: "vazamento",
1664
+ team: "vehicles",
1665
+ budget: { particles: 200, lights: 0 },
1666
+ loop: 11,
1667
+ view: FUEL_LEAK.view,
1668
+ setup: FUEL_LEAK.setup,
1669
+ timeline: [decal(POOL[0], 0, POOL[2], 2.2, 2040368, { grow: 3, life: 60, ar: 0.6, fluid: "oil" })],
1670
+ tick: [emit("drip", "normal", 12, { p: TANK, box: [0.05, 0, 0.05], sp: 0, life: 1, size: 0.03, c0: 5921402, a: 0.9, g: 9.8, fi: 0, gnd: 1 })]
1671
+ };
1661
1672
  var CAR_EXPLOSION = {
1662
1673
  id: "car_explosion",
1663
1674
  pageId: "explosao",
@@ -2011,6 +2022,8 @@ var GameWeatherThree = (() => {
2011
2022
  ];
2012
2023
  var PI = Math.PI;
2013
2024
  var SMOKE = { color: 9079430, width: 10, height: 8, gravity: -0.08, drag: 2.2, growth: 2.1 };
2025
+ var DEFAULT_SMOKE = { puffs: 2, radius: 0.01, opacity: 0.14, life: 0.7, drift: 0.2, rise: 0.06, growth: 2.1, flash: 1 };
2026
+ var DEFAULT_SPREAD = { drift: 0.1, rise: 0.04, side: 0.06 };
2014
2027
  var FLASH_SECONDS = 0.055;
2015
2028
  var FLASH_RAMP = [0.6, 0.9];
2016
2029
  var FLASH_OPACITY = 0.95;
@@ -2018,8 +2031,10 @@ var GameWeatherThree = (() => {
2018
2031
  var FLAME_ADDITIVE = 3;
2019
2032
  var ORIGIN2 = [0, 0, 0];
2020
2033
  var SIZE = variable("size");
2034
+ var FLASH_SCALE = variable("flash");
2035
+ var fallback = (name, defaultValue) => ite(ne(variable(name), void 0), variable(name), defaultValue);
2021
2036
  var wide = (width) => mul(sub(rand(), 0.5), width);
2022
- var puff2 = (point, velocity, world, radius, life, opacity) => mesh({
2037
+ var puff2 = (point, velocity, world, radius, life, opacity, growth = SMOKE.growth) => mesh({
2023
2038
  shape: "sphere",
2024
2039
  p: point,
2025
2040
  v: velocity,
@@ -2034,7 +2049,7 @@ var GameWeatherThree = (() => {
2034
2049
  lit: true,
2035
2050
  g: SMOKE.gravity,
2036
2051
  drag: SMOKE.drag,
2037
- grow: SMOKE.growth
2052
+ grow: growth
2038
2053
  });
2039
2054
  var flameBit = (point, velocity, world, radius, life) => [
2040
2055
  set("bitPoint", point),
@@ -2067,37 +2082,55 @@ var GameWeatherThree = (() => {
2067
2082
  id: "viewmodel_muzzle_flash",
2068
2083
  pageId: "event:viewmodel_muzzle_flash",
2069
2084
  team: "weapons",
2070
- budget: { particles: 12, lights: 1 },
2085
+ budget: { particles: 14, lights: 1 },
2071
2086
  loop: 0.1,
2087
+ setup: [
2088
+ set("size", fallback("size", 1)),
2089
+ set("puffs", fallback("puffs", DEFAULT_SMOKE.puffs)),
2090
+ set("radius", fallback("radius", DEFAULT_SMOKE.radius)),
2091
+ set("opacity", fallback("opacity", DEFAULT_SMOKE.opacity)),
2092
+ set("life", fallback("life", DEFAULT_SMOKE.life)),
2093
+ set("drift", fallback("drift", DEFAULT_SMOKE.drift)),
2094
+ set("rise", fallback("rise", DEFAULT_SMOKE.rise)),
2095
+ set("growth", fallback("growth", DEFAULT_SMOKE.growth)),
2096
+ set("flash", fallback("flash", DEFAULT_SMOKE.flash)),
2097
+ set("driftSpread", fallback("driftSpread", DEFAULT_SPREAD.drift)),
2098
+ set("riseSpread", fallback("riseSpread", DEFAULT_SPREAD.rise)),
2099
+ set("sideSpread", fallback("sideSpread", DEFAULT_SPREAD.side)),
2100
+ set("lifeSpread", ite(ne(variable("lifeSpread"), void 0), variable("lifeSpread"), mul(variable("life"), 0.3)))
2101
+ ],
2072
2102
  timeline: [
2073
2103
  set("angles", []),
2074
2104
  repeat(4, append("angles", add(div(mul(INDEX, PI), 2), mul(rand(), 0.6)))),
2075
2105
  set("roll", mul(rand(), PI)),
2076
- flash(ORIGIN2, 16756832, mul(4, SIZE), FLASH_SECONDS, mul(2, SIZE), true, true),
2077
- flashPiece("cone_open", mul(0.013, SIZE), mul(0.085, SIZE), 10, [mul(0.042, SIZE), 0, 0], [0, 0, -PI / 2], 16757575),
2078
- repeat(
2079
- 4,
2080
- set("angle", pick(variable("angles"), INDEX)),
2081
- flashPiece(
2082
- "cone",
2083
- mul(5e-3, SIZE),
2084
- mul(0.04, SIZE),
2085
- 6,
2086
- [mul(0.012, SIZE), mul(cos(variable("angle")), 0.016, SIZE), mul(sin(variable("angle")), 0.016, SIZE)],
2087
- [variable("angle"), 0, -PI / 2],
2088
- 16757575
2089
- )
2090
- ),
2091
- flashPiece("sphere", mul(0.016, SIZE), void 0, 12, [mul(8e-3, SIZE), 0, 0], [0, 0, 0], 16773568),
2106
+ when(gt(FLASH_SCALE, 0), [
2107
+ flash(ORIGIN2, 16756832, mul(4, SIZE, FLASH_SCALE), FLASH_SECONDS, mul(2, SIZE, FLASH_SCALE), true, true),
2108
+ flashPiece("cone_open", mul(0.013, SIZE, FLASH_SCALE), mul(0.085, SIZE, FLASH_SCALE), 10, [mul(0.042, SIZE, FLASH_SCALE), 0, 0], [0, 0, -PI / 2], 16757575),
2109
+ repeat(
2110
+ 4,
2111
+ set("angle", pick(variable("angles"), INDEX)),
2112
+ flashPiece(
2113
+ "cone",
2114
+ mul(5e-3, SIZE, FLASH_SCALE),
2115
+ mul(0.04, SIZE, FLASH_SCALE),
2116
+ 6,
2117
+ [mul(0.012, SIZE, FLASH_SCALE), mul(cos(variable("angle")), 0.016, SIZE, FLASH_SCALE), mul(sin(variable("angle")), 0.016, SIZE, FLASH_SCALE)],
2118
+ [variable("angle"), 0, -PI / 2],
2119
+ 16757575
2120
+ )
2121
+ ),
2122
+ flashPiece("sphere", mul(0.016, SIZE, FLASH_SCALE), void 0, 12, [mul(8e-3, SIZE, FLASH_SCALE), 0, 0], [0, 0, 0], 16773568)
2123
+ ]),
2092
2124
  repeat(
2093
- 6,
2125
+ variable("puffs"),
2094
2126
  puff2(
2095
2127
  ORIGIN2,
2096
- [add(0.15, mul(rand(), 0.35)), add(0.03, mul(rand(), 0.12)), mul(sub(rand(), 0.5), 0.14)],
2128
+ [add(variable("drift"), mul(rand(), variable("driftSpread"))), add(variable("rise"), mul(rand(), variable("riseSpread"))), mul(sub(rand(), 0.5), variable("sideSpread"))],
2097
2129
  [0, 0, 0],
2098
- mul(0.013, SIZE),
2099
- add(1.3, mul(rand(), 0.6)),
2100
- 0.45
2130
+ mul(variable("radius"), SIZE),
2131
+ add(variable("life"), mul(rand(), variable("lifeSpread"))),
2132
+ variable("opacity"),
2133
+ variable("growth")
2101
2134
  )
2102
2135
  )
2103
2136
  ]
@@ -2151,8 +2184,10 @@ var GameWeatherThree = (() => {
2151
2184
  aliasOf(ENGINE_SMOKE, "vehicle_fire", { params: { id: "condition", options: ["100", "60", "30", "10"], default: 3 }, loop: 12 }),
2152
2185
  /** The exhaust of a car under way: `engine_smoke` in the best condition, for half a second so a moving car asks again. */
2153
2186
  aliasOf(ENGINE_SMOKE, "vehicle_exhaust", { params: { id: "condition", options: ["100", "60", "30", "10"], default: 0 }, loop: 0.5 }),
2154
- /** A hole in the tank: the page's own petrol leak (drips, pool, sparks, fire running to the tank). */
2155
- aliasOf(FUEL_LEAK, "vehicle_leak", {})
2187
+ /** A hole in the tank: the page's petrol leak without the fire and the blast (the pool and the drips). A normal bullet does only this. */
2188
+ aliasOf(FUEL_LEAK_ONLY, "vehicle_leak", {}),
2189
+ /** The leak caught fire (an incendiary or tracer round, a spark, a fire near): the page's whole sequence, the fire running along the pool to the tank and the blast. */
2190
+ aliasOf(FUEL_LEAK, "vehicle_leak_ignited", {})
2156
2191
  ];
2157
2192
  var ALL_EFFECTS = [BLOOD_HIT, HEADSHOT, DISMEMBER, BLOATER_CLOUD, SCREAMER_SHRIEK, CORPSE_DECAY, REANIMATION, EYES_IN_FOG, MUZZLE_FLASH, IMPACT_BY_MATERIAL, PENETRATION, CASINGS_AND_MAGAZINE, MOLOTOV, GRENADE, EXPLOSIVE_BARREL, SHOPFRONT_GLASS, DOOR_STAGES, BUILDING_COLLAPSE, BLOCK_WALL, METAL_DOOR_EFFECT, IRON_RAILING, WOODEN_FENCE, HIT_POINT_BREAKAGE, PRESSURE_CYLINDERS, BUILDING_FIRE, RAIN_AND_PUDDLES, FOG_AND_ASH, SCRAPING_SPARKS, ENGINE_SMOKE, FUEL_LEAK, CAR_EXPLOSION, WINDSHIELD, HEADLIGHTS_IN_RAIN, DAMAGE_AND_BITE, INFECTION_PHASES, PANIC, BLOATER_BLINDNESS, CAMPFIRE, COUGH_AND_BREATH];
2158
2193
  var WORKSHOP_EFFECTS = Object.fromEntries(ALL_EFFECTS.map((effect) => [effect.id, effect]));
@@ -2321,29 +2356,21 @@ var GameWeatherThree = (() => {
2321
2356
  var weatherVisualTextOf = (locale) => TEXTS[locale] ?? TEXTS[locale.split("-")[0] ?? "en"] ?? TEXTS.en;
2322
2357
 
2323
2358
  // src/bench/visual.ts
2359
+ var RIG_VEHICLE = "midsize_sedan";
2324
2360
  var LAYER_ORDER = ["far_rain", "near_rain", "mist", "sky", "lightning", "headlights", "haze"];
2325
2361
  var RIG_DEFAULT = [1.6, -2.5, 0];
2326
- function buildRig(THREE) {
2362
+ function buildRig(THREE, vehicles, key) {
2327
2363
  const group = new THREE.Group();
2328
2364
  group.name = "weather-lamp-rig";
2329
- const body = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.7, 4.2), new THREE.MeshBasicMaterial({ color: 1776928 }));
2330
- body.position.set(0, 0.5, 0);
2331
- const lens2 = new THREE.MeshBasicMaterial({ color: HEADLIGHTS.lens.off });
2332
- const lampGeometry = new THREE.BoxGeometry(0.35, 0.15, 0.05);
2333
- for (const side of [-1, 1]) {
2334
- const lamp = new THREE.Mesh(lampGeometry, lens2);
2335
- lamp.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], 2.11);
2336
- group.add(lamp);
2365
+ const car = vehicles?.build(key, { quality: "lite" });
2366
+ if (car) {
2367
+ car.group.position.z = HEADLIGHTS.lamp[2] + 0.1 - car.length / 2;
2368
+ group.add(car.group);
2337
2369
  }
2338
- group.add(body);
2339
2370
  return {
2340
2371
  group,
2341
- lens: lens2,
2342
2372
  dispose() {
2343
- body.geometry.dispose();
2344
- body.material.dispose();
2345
- lampGeometry.dispose();
2346
- lens2.dispose();
2373
+ car?.dispose();
2347
2374
  }
2348
2375
  };
2349
2376
  }
@@ -2368,19 +2395,19 @@ var GameWeatherThree = (() => {
2368
2395
  ...options.headlights ? { headlights: options.headlights } : {},
2369
2396
  ...options.layers ? { layers: options.layers } : {}
2370
2397
  });
2371
- return attachRig(THREE, host, renderer, options.rig === void 0 ? RIG_DEFAULT : options.rig);
2398
+ return attachRig(THREE, host, renderer, options.rig === void 0 ? RIG_DEFAULT : options.rig, options.vehicles?.(THREE), options.rigVehicle ?? RIG_VEHICLE);
2372
2399
  }
2373
2400
  };
2374
2401
  }
2375
- function attachRig(THREE, host, renderer, place) {
2402
+ function attachRig(THREE, host, renderer, place, vehicles, key) {
2376
2403
  const scene = host.scene;
2377
- const rig = place === false ? void 0 : buildRig(THREE);
2404
+ const rig = place === false ? void 0 : buildRig(THREE, vehicles, key);
2378
2405
  let detach;
2379
2406
  if (rig && place) {
2380
2407
  rig.group.position.set(place[0], 0, place[1]);
2381
2408
  rig.group.rotation.y = place[2];
2382
2409
  scene.add(rig.group);
2383
- detach = renderer.headlights.attach(rig.group, rig.lens);
2410
+ detach = renderer.headlights.attach(rig.group);
2384
2411
  }
2385
2412
  return {
2386
2413
  update: (dt) => renderer.update(dt),