quake2ts 0.0.408 → 0.0.410

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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +16 -16
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +463 -74
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +463 -74
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/client/dist/types/demo/handler.d.ts +3 -0
  10. package/packages/client/dist/types/demo/handler.d.ts.map +1 -1
  11. package/packages/client/dist/types/effects-system.d.ts +17 -0
  12. package/packages/client/dist/types/effects-system.d.ts.map +1 -0
  13. package/packages/client/dist/types/index.d.ts +2 -0
  14. package/packages/client/dist/types/index.d.ts.map +1 -1
  15. package/packages/client/dist/types/net/connection.d.ts +21 -4
  16. package/packages/client/dist/types/net/connection.d.ts.map +1 -1
  17. package/packages/engine/dist/browser/index.global.js +14 -14
  18. package/packages/engine/dist/browser/index.global.js.map +1 -1
  19. package/packages/engine/dist/cjs/index.cjs +91 -7
  20. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  21. package/packages/engine/dist/esm/index.js +90 -7
  22. package/packages/engine/dist/esm/index.js.map +1 -1
  23. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  24. package/packages/engine/dist/types/assets/headlessLoader.d.ts +11 -0
  25. package/packages/engine/dist/types/assets/headlessLoader.d.ts.map +1 -0
  26. package/packages/engine/dist/types/index.d.ts +1 -1
  27. package/packages/engine/dist/types/index.d.ts.map +1 -1
  28. package/packages/engine/dist/types/render/bsp/generator.d.ts +25 -0
  29. package/packages/engine/dist/types/render/bsp/generator.d.ts.map +1 -0
  30. package/packages/engine/dist/types/render/bsp/geometry.d.ts.map +1 -1
  31. package/packages/engine/dist/types/render/camera.d.ts +11 -0
  32. package/packages/engine/dist/types/render/camera.d.ts.map +1 -1
  33. package/packages/engine/dist/types/render/cameraController.d.ts +23 -0
  34. package/packages/engine/dist/types/render/cameraController.d.ts.map +1 -0
  35. package/packages/engine/dist/types/render/debug.d.ts +20 -0
  36. package/packages/engine/dist/types/render/debug.d.ts.map +1 -0
  37. package/packages/engine/dist/types/render/options.d.ts +9 -0
  38. package/packages/engine/dist/types/render/options.d.ts.map +1 -0
  39. package/packages/engine/dist/types/render/renderer.d.ts +4 -1
  40. package/packages/engine/dist/types/render/renderer.d.ts.map +1 -1
  41. package/packages/engine/dist/types/render/types.d.ts +22 -0
  42. package/packages/engine/dist/types/render/types.d.ts.map +1 -0
  43. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
@@ -1915,6 +1915,7 @@ var DEG_TO_RAD = Math.PI / 180;
1915
1915
  var DEG2RAD_FACTOR = Math.PI / 180;
1916
1916
  var RAD2DEG_FACTOR = 180 / Math.PI;
1917
1917
  var DEG2RAD = DEG2RAD_FACTOR;
1918
+ var RAD2DEG = RAD2DEG_FACTOR;
1918
1919
  var ANORMS = [
1919
1920
  [-0.525731, 0, 0.850651],
1920
1921
  [-0.442863, 0.238856, 0.864188],
@@ -2255,72 +2256,72 @@ var ServerCommand = /* @__PURE__ */ ((ServerCommand22) => {
2255
2256
  ServerCommand22[ServerCommand22["achievement"] = 33] = "achievement";
2256
2257
  return ServerCommand22;
2257
2258
  })(ServerCommand || {});
2258
- var TempEntity = /* @__PURE__ */ ((TempEntity2) => {
2259
- TempEntity2[TempEntity2["GUNSHOT"] = 0] = "GUNSHOT";
2260
- TempEntity2[TempEntity2["BLOOD"] = 1] = "BLOOD";
2261
- TempEntity2[TempEntity2["BLASTER"] = 2] = "BLASTER";
2262
- TempEntity2[TempEntity2["RAILTRAIL"] = 3] = "RAILTRAIL";
2263
- TempEntity2[TempEntity2["SHOTGUN"] = 4] = "SHOTGUN";
2264
- TempEntity2[TempEntity2["EXPLOSION1"] = 5] = "EXPLOSION1";
2265
- TempEntity2[TempEntity2["EXPLOSION2"] = 6] = "EXPLOSION2";
2266
- TempEntity2[TempEntity2["ROCKET_EXPLOSION"] = 7] = "ROCKET_EXPLOSION";
2267
- TempEntity2[TempEntity2["GRENADE_EXPLOSION"] = 8] = "GRENADE_EXPLOSION";
2268
- TempEntity2[TempEntity2["SPARKS"] = 9] = "SPARKS";
2269
- TempEntity2[TempEntity2["SPLASH"] = 10] = "SPLASH";
2270
- TempEntity2[TempEntity2["BUBBLETRAIL"] = 11] = "BUBBLETRAIL";
2271
- TempEntity2[TempEntity2["SCREEN_SPARKS"] = 12] = "SCREEN_SPARKS";
2272
- TempEntity2[TempEntity2["SHIELD_SPARKS"] = 13] = "SHIELD_SPARKS";
2273
- TempEntity2[TempEntity2["BULLET_SPARKS"] = 14] = "BULLET_SPARKS";
2274
- TempEntity2[TempEntity2["LASER_SPARKS"] = 15] = "LASER_SPARKS";
2275
- TempEntity2[TempEntity2["PARASITE_ATTACK"] = 16] = "PARASITE_ATTACK";
2276
- TempEntity2[TempEntity2["ROCKET_EXPLOSION_WATER"] = 17] = "ROCKET_EXPLOSION_WATER";
2277
- TempEntity2[TempEntity2["GRENADE_EXPLOSION_WATER"] = 18] = "GRENADE_EXPLOSION_WATER";
2278
- TempEntity2[TempEntity2["MEDIC_CABLE_ATTACK"] = 19] = "MEDIC_CABLE_ATTACK";
2279
- TempEntity2[TempEntity2["BFG_EXPLOSION"] = 20] = "BFG_EXPLOSION";
2280
- TempEntity2[TempEntity2["BFG_BIGEXPLOSION"] = 21] = "BFG_BIGEXPLOSION";
2281
- TempEntity2[TempEntity2["BOSSTPORT"] = 22] = "BOSSTPORT";
2282
- TempEntity2[TempEntity2["BFG_LASER"] = 23] = "BFG_LASER";
2283
- TempEntity2[TempEntity2["GRAPPLE_CABLE"] = 24] = "GRAPPLE_CABLE";
2284
- TempEntity2[TempEntity2["WELDING_SPARKS"] = 25] = "WELDING_SPARKS";
2285
- TempEntity2[TempEntity2["GREENBLOOD"] = 26] = "GREENBLOOD";
2286
- TempEntity2[TempEntity2["BLUEHYPERBLASTER"] = 27] = "BLUEHYPERBLASTER";
2287
- TempEntity2[TempEntity2["PLASMA_EXPLOSION"] = 28] = "PLASMA_EXPLOSION";
2288
- TempEntity2[TempEntity2["TUNNEL_SPARKS"] = 29] = "TUNNEL_SPARKS";
2289
- TempEntity2[TempEntity2["BLASTER2"] = 30] = "BLASTER2";
2290
- TempEntity2[TempEntity2["RAILTRAIL2"] = 31] = "RAILTRAIL2";
2291
- TempEntity2[TempEntity2["FLAME"] = 32] = "FLAME";
2292
- TempEntity2[TempEntity2["LIGHTNING"] = 33] = "LIGHTNING";
2293
- TempEntity2[TempEntity2["DEBUGTRAIL"] = 34] = "DEBUGTRAIL";
2294
- TempEntity2[TempEntity2["PLAIN_EXPLOSION"] = 35] = "PLAIN_EXPLOSION";
2295
- TempEntity2[TempEntity2["FLASHLIGHT"] = 36] = "FLASHLIGHT";
2296
- TempEntity2[TempEntity2["FORCEWALL"] = 37] = "FORCEWALL";
2297
- TempEntity2[TempEntity2["HEATBEAM"] = 38] = "HEATBEAM";
2298
- TempEntity2[TempEntity2["MONSTER_HEATBEAM"] = 39] = "MONSTER_HEATBEAM";
2299
- TempEntity2[TempEntity2["STEAM"] = 40] = "STEAM";
2300
- TempEntity2[TempEntity2["BUBBLETRAIL2"] = 41] = "BUBBLETRAIL2";
2301
- TempEntity2[TempEntity2["MOREBLOOD"] = 42] = "MOREBLOOD";
2302
- TempEntity2[TempEntity2["HEATBEAM_SPARKS"] = 43] = "HEATBEAM_SPARKS";
2303
- TempEntity2[TempEntity2["HEATBEAM_STEAM"] = 44] = "HEATBEAM_STEAM";
2304
- TempEntity2[TempEntity2["CHAINFIST_SMOKE"] = 45] = "CHAINFIST_SMOKE";
2305
- TempEntity2[TempEntity2["ELECTRIC_SPARKS"] = 46] = "ELECTRIC_SPARKS";
2306
- TempEntity2[TempEntity2["TRACKER_EXPLOSION"] = 47] = "TRACKER_EXPLOSION";
2307
- TempEntity2[TempEntity2["TELEPORT_EFFECT"] = 48] = "TELEPORT_EFFECT";
2308
- TempEntity2[TempEntity2["DBALL_GOAL"] = 49] = "DBALL_GOAL";
2309
- TempEntity2[TempEntity2["WIDOWBEAMOUT"] = 50] = "WIDOWBEAMOUT";
2310
- TempEntity2[TempEntity2["NUKEBLAST"] = 51] = "NUKEBLAST";
2311
- TempEntity2[TempEntity2["WIDOWSPLASH"] = 52] = "WIDOWSPLASH";
2312
- TempEntity2[TempEntity2["EXPLOSION1_BIG"] = 53] = "EXPLOSION1_BIG";
2313
- TempEntity2[TempEntity2["EXPLOSION1_NP"] = 54] = "EXPLOSION1_NP";
2314
- TempEntity2[TempEntity2["FLECHETTE"] = 55] = "FLECHETTE";
2315
- TempEntity2[TempEntity2["BLUEHYPERBLASTER_KEX"] = 56] = "BLUEHYPERBLASTER_KEX";
2316
- TempEntity2[TempEntity2["BFG_ZAP"] = 57] = "BFG_ZAP";
2317
- TempEntity2[TempEntity2["BERSERK_SLAM"] = 58] = "BERSERK_SLAM";
2318
- TempEntity2[TempEntity2["GRAPPLE_CABLE_2"] = 59] = "GRAPPLE_CABLE_2";
2319
- TempEntity2[TempEntity2["POWER_SPLASH"] = 60] = "POWER_SPLASH";
2320
- TempEntity2[TempEntity2["LIGHTNING_BEAM"] = 61] = "LIGHTNING_BEAM";
2321
- TempEntity2[TempEntity2["EXPLOSION1_NL"] = 62] = "EXPLOSION1_NL";
2322
- TempEntity2[TempEntity2["EXPLOSION2_NL"] = 63] = "EXPLOSION2_NL";
2323
- return TempEntity2;
2259
+ var TempEntity = /* @__PURE__ */ ((TempEntity22) => {
2260
+ TempEntity22[TempEntity22["GUNSHOT"] = 0] = "GUNSHOT";
2261
+ TempEntity22[TempEntity22["BLOOD"] = 1] = "BLOOD";
2262
+ TempEntity22[TempEntity22["BLASTER"] = 2] = "BLASTER";
2263
+ TempEntity22[TempEntity22["RAILTRAIL"] = 3] = "RAILTRAIL";
2264
+ TempEntity22[TempEntity22["SHOTGUN"] = 4] = "SHOTGUN";
2265
+ TempEntity22[TempEntity22["EXPLOSION1"] = 5] = "EXPLOSION1";
2266
+ TempEntity22[TempEntity22["EXPLOSION2"] = 6] = "EXPLOSION2";
2267
+ TempEntity22[TempEntity22["ROCKET_EXPLOSION"] = 7] = "ROCKET_EXPLOSION";
2268
+ TempEntity22[TempEntity22["GRENADE_EXPLOSION"] = 8] = "GRENADE_EXPLOSION";
2269
+ TempEntity22[TempEntity22["SPARKS"] = 9] = "SPARKS";
2270
+ TempEntity22[TempEntity22["SPLASH"] = 10] = "SPLASH";
2271
+ TempEntity22[TempEntity22["BUBBLETRAIL"] = 11] = "BUBBLETRAIL";
2272
+ TempEntity22[TempEntity22["SCREEN_SPARKS"] = 12] = "SCREEN_SPARKS";
2273
+ TempEntity22[TempEntity22["SHIELD_SPARKS"] = 13] = "SHIELD_SPARKS";
2274
+ TempEntity22[TempEntity22["BULLET_SPARKS"] = 14] = "BULLET_SPARKS";
2275
+ TempEntity22[TempEntity22["LASER_SPARKS"] = 15] = "LASER_SPARKS";
2276
+ TempEntity22[TempEntity22["PARASITE_ATTACK"] = 16] = "PARASITE_ATTACK";
2277
+ TempEntity22[TempEntity22["ROCKET_EXPLOSION_WATER"] = 17] = "ROCKET_EXPLOSION_WATER";
2278
+ TempEntity22[TempEntity22["GRENADE_EXPLOSION_WATER"] = 18] = "GRENADE_EXPLOSION_WATER";
2279
+ TempEntity22[TempEntity22["MEDIC_CABLE_ATTACK"] = 19] = "MEDIC_CABLE_ATTACK";
2280
+ TempEntity22[TempEntity22["BFG_EXPLOSION"] = 20] = "BFG_EXPLOSION";
2281
+ TempEntity22[TempEntity22["BFG_BIGEXPLOSION"] = 21] = "BFG_BIGEXPLOSION";
2282
+ TempEntity22[TempEntity22["BOSSTPORT"] = 22] = "BOSSTPORT";
2283
+ TempEntity22[TempEntity22["BFG_LASER"] = 23] = "BFG_LASER";
2284
+ TempEntity22[TempEntity22["GRAPPLE_CABLE"] = 24] = "GRAPPLE_CABLE";
2285
+ TempEntity22[TempEntity22["WELDING_SPARKS"] = 25] = "WELDING_SPARKS";
2286
+ TempEntity22[TempEntity22["GREENBLOOD"] = 26] = "GREENBLOOD";
2287
+ TempEntity22[TempEntity22["BLUEHYPERBLASTER"] = 27] = "BLUEHYPERBLASTER";
2288
+ TempEntity22[TempEntity22["PLASMA_EXPLOSION"] = 28] = "PLASMA_EXPLOSION";
2289
+ TempEntity22[TempEntity22["TUNNEL_SPARKS"] = 29] = "TUNNEL_SPARKS";
2290
+ TempEntity22[TempEntity22["BLASTER2"] = 30] = "BLASTER2";
2291
+ TempEntity22[TempEntity22["RAILTRAIL2"] = 31] = "RAILTRAIL2";
2292
+ TempEntity22[TempEntity22["FLAME"] = 32] = "FLAME";
2293
+ TempEntity22[TempEntity22["LIGHTNING"] = 33] = "LIGHTNING";
2294
+ TempEntity22[TempEntity22["DEBUGTRAIL"] = 34] = "DEBUGTRAIL";
2295
+ TempEntity22[TempEntity22["PLAIN_EXPLOSION"] = 35] = "PLAIN_EXPLOSION";
2296
+ TempEntity22[TempEntity22["FLASHLIGHT"] = 36] = "FLASHLIGHT";
2297
+ TempEntity22[TempEntity22["FORCEWALL"] = 37] = "FORCEWALL";
2298
+ TempEntity22[TempEntity22["HEATBEAM"] = 38] = "HEATBEAM";
2299
+ TempEntity22[TempEntity22["MONSTER_HEATBEAM"] = 39] = "MONSTER_HEATBEAM";
2300
+ TempEntity22[TempEntity22["STEAM"] = 40] = "STEAM";
2301
+ TempEntity22[TempEntity22["BUBBLETRAIL2"] = 41] = "BUBBLETRAIL2";
2302
+ TempEntity22[TempEntity22["MOREBLOOD"] = 42] = "MOREBLOOD";
2303
+ TempEntity22[TempEntity22["HEATBEAM_SPARKS"] = 43] = "HEATBEAM_SPARKS";
2304
+ TempEntity22[TempEntity22["HEATBEAM_STEAM"] = 44] = "HEATBEAM_STEAM";
2305
+ TempEntity22[TempEntity22["CHAINFIST_SMOKE"] = 45] = "CHAINFIST_SMOKE";
2306
+ TempEntity22[TempEntity22["ELECTRIC_SPARKS"] = 46] = "ELECTRIC_SPARKS";
2307
+ TempEntity22[TempEntity22["TRACKER_EXPLOSION"] = 47] = "TRACKER_EXPLOSION";
2308
+ TempEntity22[TempEntity22["TELEPORT_EFFECT"] = 48] = "TELEPORT_EFFECT";
2309
+ TempEntity22[TempEntity22["DBALL_GOAL"] = 49] = "DBALL_GOAL";
2310
+ TempEntity22[TempEntity22["WIDOWBEAMOUT"] = 50] = "WIDOWBEAMOUT";
2311
+ TempEntity22[TempEntity22["NUKEBLAST"] = 51] = "NUKEBLAST";
2312
+ TempEntity22[TempEntity22["WIDOWSPLASH"] = 52] = "WIDOWSPLASH";
2313
+ TempEntity22[TempEntity22["EXPLOSION1_BIG"] = 53] = "EXPLOSION1_BIG";
2314
+ TempEntity22[TempEntity22["EXPLOSION1_NP"] = 54] = "EXPLOSION1_NP";
2315
+ TempEntity22[TempEntity22["FLECHETTE"] = 55] = "FLECHETTE";
2316
+ TempEntity22[TempEntity22["BLUEHYPERBLASTER_KEX"] = 56] = "BLUEHYPERBLASTER_KEX";
2317
+ TempEntity22[TempEntity22["BFG_ZAP"] = 57] = "BFG_ZAP";
2318
+ TempEntity22[TempEntity22["BERSERK_SLAM"] = 58] = "BERSERK_SLAM";
2319
+ TempEntity22[TempEntity22["GRAPPLE_CABLE_2"] = 59] = "GRAPPLE_CABLE_2";
2320
+ TempEntity22[TempEntity22["POWER_SPLASH"] = 60] = "POWER_SPLASH";
2321
+ TempEntity22[TempEntity22["LIGHTNING_BEAM"] = 61] = "LIGHTNING_BEAM";
2322
+ TempEntity22[TempEntity22["EXPLOSION1_NL"] = 62] = "EXPLOSION1_NL";
2323
+ TempEntity22[TempEntity22["EXPLOSION2_NL"] = 63] = "EXPLOSION2_NL";
2324
+ return TempEntity22;
2324
2325
  })(TempEntity || {});
2325
2326
  var AMMO_MAX = 12;
2326
2327
  var NUM_BITS_FOR_AMMO = 9;
@@ -3131,6 +3132,43 @@ var BSP_VERTEX_LAYOUT = [
3131
3132
  { index: 2, size: 2, type: 5126, stride: STRIDE, offset: 5 * FLOAT_BYTES }
3132
3133
  ];
3133
3134
  var MAX_DLIGHTS = 32;
3135
+ var DynamicLightManager = class {
3136
+ constructor() {
3137
+ this.lights = [];
3138
+ }
3139
+ /**
3140
+ * Adds a dynamic light or updates an existing one with the same key.
3141
+ */
3142
+ addLight(dlight, time) {
3143
+ if (dlight.key !== void 0) {
3144
+ const index = this.lights.findIndex((l) => l.key === dlight.key);
3145
+ if (index !== -1) {
3146
+ this.lights[index] = dlight;
3147
+ return;
3148
+ }
3149
+ }
3150
+ this.lights.push(dlight);
3151
+ }
3152
+ /**
3153
+ * Clears all lights (e.g., map change).
3154
+ */
3155
+ clear() {
3156
+ this.lights = [];
3157
+ }
3158
+ /**
3159
+ * Updates the list of active lights, removing expired ones.
3160
+ * @param time Current game time in seconds.
3161
+ */
3162
+ update(time) {
3163
+ this.lights = this.lights.filter((l) => l.die > time);
3164
+ }
3165
+ /**
3166
+ * Returns the current list of active lights.
3167
+ */
3168
+ getActiveLights() {
3169
+ return this.lights;
3170
+ }
3171
+ };
3134
3172
  var BSP_SURFACE_FRAGMENT_SOURCE = `#version 300 es
3135
3173
  precision highp float;
3136
3174
 
@@ -3438,15 +3476,21 @@ var Camera = class {
3438
3476
  return this._position;
3439
3477
  }
3440
3478
  set position(value) {
3441
- vec3_exports.copy(this._position, value);
3442
- this._dirty = true;
3479
+ if (!vec3_exports.equals(this._position, value)) {
3480
+ vec3_exports.copy(this._position, value);
3481
+ this._dirty = true;
3482
+ this.triggerMoveEvent();
3483
+ }
3443
3484
  }
3444
3485
  get angles() {
3445
3486
  return this._angles;
3446
3487
  }
3447
3488
  set angles(value) {
3448
- vec3_exports.copy(this._angles, value);
3449
- this._dirty = true;
3489
+ if (!vec3_exports.equals(this._angles, value)) {
3490
+ vec3_exports.copy(this._angles, value);
3491
+ this._dirty = true;
3492
+ this.triggerMoveEvent();
3493
+ }
3450
3494
  }
3451
3495
  get bobAngles() {
3452
3496
  return this._bobAngles;
@@ -3490,6 +3534,47 @@ var Camera = class {
3490
3534
  this._aspect = value;
3491
3535
  this._dirty = true;
3492
3536
  }
3537
+ // API Methods
3538
+ setPosition(x, y, z) {
3539
+ const newPos = vec3_exports.fromValues(x, y, z);
3540
+ if (!vec3_exports.equals(this._position, newPos)) {
3541
+ vec3_exports.copy(this._position, newPos);
3542
+ this._dirty = true;
3543
+ this.triggerMoveEvent();
3544
+ }
3545
+ }
3546
+ setRotation(pitch, yaw, roll) {
3547
+ const newAngles = vec3_exports.fromValues(pitch, yaw, roll);
3548
+ if (!vec3_exports.equals(this._angles, newAngles)) {
3549
+ vec3_exports.copy(this._angles, newAngles);
3550
+ this._dirty = true;
3551
+ this.triggerMoveEvent();
3552
+ }
3553
+ }
3554
+ setFov(fov) {
3555
+ this.fov = fov;
3556
+ }
3557
+ setAspectRatio(aspect) {
3558
+ this.aspect = aspect;
3559
+ }
3560
+ lookAt(target) {
3561
+ const direction = vec3_exports.create();
3562
+ vec3_exports.subtract(direction, target, this._position);
3563
+ const len2 = vec3_exports.length(direction);
3564
+ if (len2 < 1e-3) return;
3565
+ const yaw = Math.atan2(direction[1], direction[0]) * RAD2DEG;
3566
+ const hyp = Math.hypot(direction[0], direction[1]);
3567
+ const pitch = -Math.atan2(direction[2], hyp) * RAD2DEG;
3568
+ this.setRotation(pitch, yaw, 0);
3569
+ }
3570
+ triggerMoveEvent() {
3571
+ if (this.onCameraMove) {
3572
+ this.onCameraMove({
3573
+ position: vec3_exports.clone(this._position),
3574
+ angles: vec3_exports.clone(this._angles)
3575
+ });
3576
+ }
3577
+ }
3493
3578
  get viewMatrix() {
3494
3579
  this.updateMatrices();
3495
3580
  return this._viewMatrix;
@@ -3565,11 +3650,8 @@ var Camera = class {
3565
3650
  vec3_exports.transformMat4(rotatedPosQuake, negativePosition, rotationQuake);
3566
3651
  const translationGl = vec3_exports.fromValues(
3567
3652
  rotatedPosQuake[1] || 0,
3568
- // Y in Quake -> X in WebGL (negation already applied above)
3569
3653
  rotatedPosQuake[2] || 0,
3570
- // Z in Quake -> Y in WebGL
3571
3654
  rotatedPosQuake[0] || 0
3572
- // X in Quake -> Z in WebGL (negation already applied above)
3573
3655
  );
3574
3656
  mat4_exports.copy(this._viewMatrix, rotationGl);
3575
3657
  this._viewMatrix[12] = translationGl[0];
@@ -9930,6 +10012,73 @@ var ClientCommand = /* @__PURE__ */ ((ClientCommand2) => {
9930
10012
  ClientCommand2[ClientCommand2["stringcmd"] = 4] = "stringcmd";
9931
10013
  return ClientCommand2;
9932
10014
  })(ClientCommand || {});
10015
+ var TempEntity2 = /* @__PURE__ */ ((TempEntity22) => {
10016
+ TempEntity22[TempEntity22["GUNSHOT"] = 0] = "GUNSHOT";
10017
+ TempEntity22[TempEntity22["BLOOD"] = 1] = "BLOOD";
10018
+ TempEntity22[TempEntity22["BLASTER"] = 2] = "BLASTER";
10019
+ TempEntity22[TempEntity22["RAILTRAIL"] = 3] = "RAILTRAIL";
10020
+ TempEntity22[TempEntity22["SHOTGUN"] = 4] = "SHOTGUN";
10021
+ TempEntity22[TempEntity22["EXPLOSION1"] = 5] = "EXPLOSION1";
10022
+ TempEntity22[TempEntity22["EXPLOSION2"] = 6] = "EXPLOSION2";
10023
+ TempEntity22[TempEntity22["ROCKET_EXPLOSION"] = 7] = "ROCKET_EXPLOSION";
10024
+ TempEntity22[TempEntity22["GRENADE_EXPLOSION"] = 8] = "GRENADE_EXPLOSION";
10025
+ TempEntity22[TempEntity22["SPARKS"] = 9] = "SPARKS";
10026
+ TempEntity22[TempEntity22["SPLASH"] = 10] = "SPLASH";
10027
+ TempEntity22[TempEntity22["BUBBLETRAIL"] = 11] = "BUBBLETRAIL";
10028
+ TempEntity22[TempEntity22["SCREEN_SPARKS"] = 12] = "SCREEN_SPARKS";
10029
+ TempEntity22[TempEntity22["SHIELD_SPARKS"] = 13] = "SHIELD_SPARKS";
10030
+ TempEntity22[TempEntity22["BULLET_SPARKS"] = 14] = "BULLET_SPARKS";
10031
+ TempEntity22[TempEntity22["LASER_SPARKS"] = 15] = "LASER_SPARKS";
10032
+ TempEntity22[TempEntity22["PARASITE_ATTACK"] = 16] = "PARASITE_ATTACK";
10033
+ TempEntity22[TempEntity22["ROCKET_EXPLOSION_WATER"] = 17] = "ROCKET_EXPLOSION_WATER";
10034
+ TempEntity22[TempEntity22["GRENADE_EXPLOSION_WATER"] = 18] = "GRENADE_EXPLOSION_WATER";
10035
+ TempEntity22[TempEntity22["MEDIC_CABLE_ATTACK"] = 19] = "MEDIC_CABLE_ATTACK";
10036
+ TempEntity22[TempEntity22["BFG_EXPLOSION"] = 20] = "BFG_EXPLOSION";
10037
+ TempEntity22[TempEntity22["BFG_BIGEXPLOSION"] = 21] = "BFG_BIGEXPLOSION";
10038
+ TempEntity22[TempEntity22["BOSSTPORT"] = 22] = "BOSSTPORT";
10039
+ TempEntity22[TempEntity22["BFG_LASER"] = 23] = "BFG_LASER";
10040
+ TempEntity22[TempEntity22["GRAPPLE_CABLE"] = 24] = "GRAPPLE_CABLE";
10041
+ TempEntity22[TempEntity22["WELDING_SPARKS"] = 25] = "WELDING_SPARKS";
10042
+ TempEntity22[TempEntity22["GREENBLOOD"] = 26] = "GREENBLOOD";
10043
+ TempEntity22[TempEntity22["BLUEHYPERBLASTER"] = 27] = "BLUEHYPERBLASTER";
10044
+ TempEntity22[TempEntity22["PLASMA_EXPLOSION"] = 28] = "PLASMA_EXPLOSION";
10045
+ TempEntity22[TempEntity22["TUNNEL_SPARKS"] = 29] = "TUNNEL_SPARKS";
10046
+ TempEntity22[TempEntity22["BLASTER2"] = 30] = "BLASTER2";
10047
+ TempEntity22[TempEntity22["RAILTRAIL2"] = 31] = "RAILTRAIL2";
10048
+ TempEntity22[TempEntity22["FLAME"] = 32] = "FLAME";
10049
+ TempEntity22[TempEntity22["LIGHTNING"] = 33] = "LIGHTNING";
10050
+ TempEntity22[TempEntity22["DEBUGTRAIL"] = 34] = "DEBUGTRAIL";
10051
+ TempEntity22[TempEntity22["PLAIN_EXPLOSION"] = 35] = "PLAIN_EXPLOSION";
10052
+ TempEntity22[TempEntity22["FLASHLIGHT"] = 36] = "FLASHLIGHT";
10053
+ TempEntity22[TempEntity22["FORCEWALL"] = 37] = "FORCEWALL";
10054
+ TempEntity22[TempEntity22["HEATBEAM"] = 38] = "HEATBEAM";
10055
+ TempEntity22[TempEntity22["MONSTER_HEATBEAM"] = 39] = "MONSTER_HEATBEAM";
10056
+ TempEntity22[TempEntity22["STEAM"] = 40] = "STEAM";
10057
+ TempEntity22[TempEntity22["BUBBLETRAIL2"] = 41] = "BUBBLETRAIL2";
10058
+ TempEntity22[TempEntity22["MOREBLOOD"] = 42] = "MOREBLOOD";
10059
+ TempEntity22[TempEntity22["HEATBEAM_SPARKS"] = 43] = "HEATBEAM_SPARKS";
10060
+ TempEntity22[TempEntity22["HEATBEAM_STEAM"] = 44] = "HEATBEAM_STEAM";
10061
+ TempEntity22[TempEntity22["CHAINFIST_SMOKE"] = 45] = "CHAINFIST_SMOKE";
10062
+ TempEntity22[TempEntity22["ELECTRIC_SPARKS"] = 46] = "ELECTRIC_SPARKS";
10063
+ TempEntity22[TempEntity22["TRACKER_EXPLOSION"] = 47] = "TRACKER_EXPLOSION";
10064
+ TempEntity22[TempEntity22["TELEPORT_EFFECT"] = 48] = "TELEPORT_EFFECT";
10065
+ TempEntity22[TempEntity22["DBALL_GOAL"] = 49] = "DBALL_GOAL";
10066
+ TempEntity22[TempEntity22["WIDOWBEAMOUT"] = 50] = "WIDOWBEAMOUT";
10067
+ TempEntity22[TempEntity22["NUKEBLAST"] = 51] = "NUKEBLAST";
10068
+ TempEntity22[TempEntity22["WIDOWSPLASH"] = 52] = "WIDOWSPLASH";
10069
+ TempEntity22[TempEntity22["EXPLOSION1_BIG"] = 53] = "EXPLOSION1_BIG";
10070
+ TempEntity22[TempEntity22["EXPLOSION1_NP"] = 54] = "EXPLOSION1_NP";
10071
+ TempEntity22[TempEntity22["FLECHETTE"] = 55] = "FLECHETTE";
10072
+ TempEntity22[TempEntity22["BLUEHYPERBLASTER_KEX"] = 56] = "BLUEHYPERBLASTER_KEX";
10073
+ TempEntity22[TempEntity22["BFG_ZAP"] = 57] = "BFG_ZAP";
10074
+ TempEntity22[TempEntity22["BERSERK_SLAM"] = 58] = "BERSERK_SLAM";
10075
+ TempEntity22[TempEntity22["GRAPPLE_CABLE_2"] = 59] = "GRAPPLE_CABLE_2";
10076
+ TempEntity22[TempEntity22["POWER_SPLASH"] = 60] = "POWER_SPLASH";
10077
+ TempEntity22[TempEntity22["LIGHTNING_BEAM"] = 61] = "LIGHTNING_BEAM";
10078
+ TempEntity22[TempEntity22["EXPLOSION1_NL"] = 62] = "EXPLOSION1_NL";
10079
+ TempEntity22[TempEntity22["EXPLOSION2_NL"] = 63] = "EXPLOSION2_NL";
10080
+ return TempEntity22;
10081
+ })(TempEntity2 || {});
9933
10082
  var CMD_BACKUP = 64;
9934
10083
  var MZ_BLASTER = 0;
9935
10084
  var MZ_MACHINEGUN = 1;
@@ -9943,6 +10092,7 @@ var MZ_GRENADE = 8;
9943
10092
  var MZ_SSHOTGUN = 11;
9944
10093
  var MZ_BFG = 12;
9945
10094
  var MZ_HYPERBLASTER = 13;
10095
+ var MZ_BLUEHYPERBLASTER = 17;
9946
10096
  function readUint16LE(stats, startIndex, byteOffset) {
9947
10097
  const elementIndex = Math.floor(byteOffset / 2);
9948
10098
  const isOdd = byteOffset % 2 !== 0;
@@ -11689,6 +11839,9 @@ var ClientNetworkHandler = class {
11689
11839
  }
11690
11840
  }
11691
11841
  onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) {
11842
+ if (this.callbacks?.onTempEntity) {
11843
+ this.callbacks.onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt);
11844
+ }
11692
11845
  }
11693
11846
  onLayout(layout) {
11694
11847
  }
@@ -11696,8 +11849,14 @@ var ClientNetworkHandler = class {
11696
11849
  this.inventory = [...inventory];
11697
11850
  }
11698
11851
  onMuzzleFlash(ent, weapon) {
11852
+ if (this.callbacks?.onMuzzleFlash) {
11853
+ this.callbacks.onMuzzleFlash(ent, weapon);
11854
+ }
11699
11855
  }
11700
11856
  onMuzzleFlash2(ent, weapon) {
11857
+ if (this.callbacks?.onMuzzleFlash2) {
11858
+ this.callbacks.onMuzzleFlash2(ent, weapon);
11859
+ }
11701
11860
  }
11702
11861
  onMuzzleFlash3(ent, weapon) {
11703
11862
  const isLocalPlayer = ent === this.playerNum + 1;
@@ -13205,6 +13364,7 @@ var MultiplayerConnection = class {
13205
13364
  this.levelName = "";
13206
13365
  this.configStrings = /* @__PURE__ */ new Map();
13207
13366
  this.baselines = /* @__PURE__ */ new Map();
13367
+ this.entities = /* @__PURE__ */ new Map();
13208
13368
  this.challenge = 0;
13209
13369
  this.connectPacketCount = 0;
13210
13370
  this.connectPacketTime = 0;
@@ -13235,6 +13395,9 @@ var MultiplayerConnection = class {
13235
13395
  setDemoRecorder(recorder) {
13236
13396
  this.demoRecorder = recorder;
13237
13397
  }
13398
+ setEffectSystem(system) {
13399
+ this.effectSystem = system;
13400
+ }
13238
13401
  async connectToServer(address, port) {
13239
13402
  const url = `ws://${address}:${port}`;
13240
13403
  return this.connect(url);
@@ -13270,6 +13433,7 @@ var MultiplayerConnection = class {
13270
13433
  cleanup() {
13271
13434
  this.configStrings.clear();
13272
13435
  this.baselines.clear();
13436
+ this.entities.clear();
13273
13437
  this.commandHistory = [];
13274
13438
  this.latestServerFrame = 0;
13275
13439
  this.parser = null;
@@ -13404,6 +13568,13 @@ var MultiplayerConnection = class {
13404
13568
  if (frame.serverFrame > this.latestServerFrame) {
13405
13569
  this.latestServerFrame = frame.serverFrame;
13406
13570
  }
13571
+ const packetEntities = frame.packetEntities;
13572
+ if (!packetEntities.delta) {
13573
+ this.entities.clear();
13574
+ }
13575
+ for (const ent of packetEntities.entities) {
13576
+ this.entities.set(ent.number, ent);
13577
+ }
13407
13578
  if (this.prediction && frame.playerState) {
13408
13579
  const ps = frame.playerState;
13409
13580
  const predState = {
@@ -13432,15 +13603,29 @@ var MultiplayerConnection = class {
13432
13603
  onSound(flags, soundNum, volume, attenuation, offset, ent, pos) {
13433
13604
  }
13434
13605
  onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) {
13606
+ if (this.effectSystem) {
13607
+ const time = Date.now() / 1e3;
13608
+ this.effectSystem.onTempEntity(type, pos, time);
13609
+ }
13435
13610
  }
13436
13611
  onLayout(layout) {
13437
13612
  }
13438
13613
  onInventory(inventory) {
13439
13614
  }
13440
13615
  onMuzzleFlash(ent, weapon) {
13616
+ if (this.effectSystem) {
13617
+ const time = Date.now() / 1e3;
13618
+ this.effectSystem.onMuzzleFlash(ent, weapon, time);
13619
+ }
13441
13620
  }
13442
13621
  onMuzzleFlash2(ent, weapon) {
13443
13622
  }
13623
+ onMuzzleFlash3(ent, weapon) {
13624
+ if (this.effectSystem) {
13625
+ const time = Date.now() / 1e3;
13626
+ this.effectSystem.onMuzzleFlash(ent, weapon, time);
13627
+ }
13628
+ }
13444
13629
  onDisconnect() {
13445
13630
  this.disconnect();
13446
13631
  }
@@ -13448,6 +13633,31 @@ var MultiplayerConnection = class {
13448
13633
  }
13449
13634
  onDownload(size, percent, data) {
13450
13635
  }
13636
+ // New handlers stubs
13637
+ onSplitClient(clientNum) {
13638
+ }
13639
+ onConfigBlast(index, data) {
13640
+ }
13641
+ onSpawnBaselineBlast(entity) {
13642
+ }
13643
+ onLevelRestart() {
13644
+ }
13645
+ onDamage(indicators) {
13646
+ }
13647
+ onLocPrint(flags, base, args) {
13648
+ }
13649
+ onFog(data) {
13650
+ }
13651
+ onWaitingForPlayers(count) {
13652
+ }
13653
+ onBotChat(msg) {
13654
+ }
13655
+ onPoi(flags, pos) {
13656
+ }
13657
+ onHelpPath(pos) {
13658
+ }
13659
+ onAchievement(id) {
13660
+ }
13451
13661
  };
13452
13662
 
13453
13663
  // src/ui/demo-controls.ts
@@ -13595,6 +13805,152 @@ function processEntityEffects(entity, dlights, time) {
13595
13805
  }
13596
13806
  }
13597
13807
 
13808
+ // src/effects-system.ts
13809
+ var copyVec3 = (v) => ({ x: v.x, y: v.y, z: v.z });
13810
+ var vectorMA = (start, scale3, dir) => ({
13811
+ x: start.x + dir.x * scale3,
13812
+ y: start.y + dir.y * scale3,
13813
+ z: start.z + dir.z * scale3
13814
+ });
13815
+ var ClientEffectSystem = class {
13816
+ constructor(dlightManager, engine, entityProvider) {
13817
+ this.dlightManager = dlightManager;
13818
+ this.engine = engine;
13819
+ this.entityProvider = entityProvider;
13820
+ }
13821
+ // Helper to add dlight
13822
+ addLight(key, origin, color, radius, minLight, time) {
13823
+ this.dlightManager.addLight({
13824
+ key,
13825
+ origin: copyVec3(origin),
13826
+ color,
13827
+ intensity: radius,
13828
+ minLight,
13829
+ die: time
13830
+ }, 0);
13831
+ }
13832
+ playSound(pos, ent, soundName, vol = 1, attn = 1) {
13833
+ if (!this.engine.audio) return;
13834
+ const index = this.engine.audio.soundindex(soundName);
13835
+ if (index === 0) return;
13836
+ if (pos) {
13837
+ this.engine.audio.positioned_sound(pos, index, vol, attn);
13838
+ } else {
13839
+ this.engine.audio.sound(ent, 0, index, vol, attn, 0);
13840
+ }
13841
+ }
13842
+ onMuzzleFlash(entNum, weapon, time) {
13843
+ const ent = this.entityProvider.getEntity(entNum);
13844
+ if (!ent) return;
13845
+ const origin = { x: ent.origin.x, y: ent.origin.y, z: ent.origin.z };
13846
+ const angles = { x: ent.angles.x, y: ent.angles.y, z: ent.angles.z };
13847
+ const vectors = angleVectors(angles);
13848
+ let flashOrigin = vectorMA(origin, 18, vectors.forward);
13849
+ flashOrigin = vectorMA(flashOrigin, 16, vectors.right);
13850
+ const silenced = (weapon & 128) !== 0;
13851
+ weapon &= ~128;
13852
+ let radius = silenced ? 100 + Math.random() * 31 : 200 + Math.random() * 31;
13853
+ const minLight = 32;
13854
+ const duration = 0.1;
13855
+ const die = time + duration;
13856
+ const volume = silenced ? 0.2 : 1;
13857
+ let color = { x: 1, y: 1, z: 0 };
13858
+ switch (weapon) {
13859
+ case MZ_BLASTER:
13860
+ case MZ_HYPERBLASTER:
13861
+ case MZ_MACHINEGUN:
13862
+ case MZ_SHOTGUN:
13863
+ case MZ_SSHOTGUN:
13864
+ case MZ_CHAINGUN1:
13865
+ case MZ_CHAINGUN2:
13866
+ case MZ_CHAINGUN3:
13867
+ color = { x: 1, y: 1, z: 0 };
13868
+ break;
13869
+ case MZ_BLUEHYPERBLASTER:
13870
+ color = { x: 0, y: 0, z: 1 };
13871
+ break;
13872
+ case MZ_RAILGUN:
13873
+ color = { x: 0.5, y: 0.5, z: 1 };
13874
+ break;
13875
+ case MZ_ROCKET:
13876
+ case MZ_GRENADE:
13877
+ color = { x: 1, y: 0.5, z: 0.2 };
13878
+ break;
13879
+ case MZ_BFG:
13880
+ color = { x: 0, y: 1, z: 0 };
13881
+ break;
13882
+ }
13883
+ this.addLight(entNum, flashOrigin, color, radius, minLight, die);
13884
+ let soundName = "";
13885
+ switch (weapon) {
13886
+ case MZ_BLASTER:
13887
+ soundName = "weapons/blastf1a.wav";
13888
+ break;
13889
+ case MZ_SHOTGUN:
13890
+ soundName = "weapons/shotgf1b.wav";
13891
+ break;
13892
+ case MZ_SSHOTGUN:
13893
+ soundName = "weapons/sshotf1b.wav";
13894
+ break;
13895
+ case MZ_MACHINEGUN:
13896
+ soundName = `weapons/machgf${Math.floor(Math.random() * 5) + 1}b.wav`;
13897
+ break;
13898
+ case MZ_RAILGUN:
13899
+ soundName = "weapons/railgf1a.wav";
13900
+ break;
13901
+ case MZ_ROCKET:
13902
+ soundName = "weapons/rocklf1a.wav";
13903
+ break;
13904
+ case MZ_GRENADE:
13905
+ soundName = "weapons/grenlf1a.wav";
13906
+ break;
13907
+ case MZ_BFG:
13908
+ soundName = "weapons/bfg__f1y.wav";
13909
+ break;
13910
+ case MZ_HYPERBLASTER:
13911
+ soundName = "weapons/hyprbf1a.wav";
13912
+ break;
13913
+ case MZ_BLUEHYPERBLASTER:
13914
+ soundName = "weapons/hyprbf1a.wav";
13915
+ break;
13916
+ case MZ_CHAINGUN1:
13917
+ case MZ_CHAINGUN2:
13918
+ case MZ_CHAINGUN3:
13919
+ soundName = `weapons/machgf${Math.floor(Math.random() * 5) + 1}b.wav`;
13920
+ break;
13921
+ }
13922
+ if (soundName) {
13923
+ this.playSound(null, entNum, soundName, volume, 1);
13924
+ }
13925
+ }
13926
+ onTempEntity(type, pos, time) {
13927
+ switch (type) {
13928
+ case TempEntity2.EXPLOSION1:
13929
+ case TempEntity2.EXPLOSION1_BIG:
13930
+ case TempEntity2.EXPLOSION1_NP:
13931
+ case TempEntity2.ROCKET_EXPLOSION:
13932
+ case TempEntity2.GRENADE_EXPLOSION:
13933
+ case TempEntity2.ROCKET_EXPLOSION_WATER:
13934
+ case TempEntity2.GRENADE_EXPLOSION_WATER:
13935
+ {
13936
+ const color = { x: 1, y: 0.5, z: 0.2 };
13937
+ const duration = 0.5;
13938
+ this.addLight(void 0, pos, color, 300, 0, time + duration);
13939
+ this.playSound(pos, 0, "weapons/rocklx1a.wav", 1, 0.5);
13940
+ }
13941
+ break;
13942
+ case TempEntity2.BFG_EXPLOSION:
13943
+ case TempEntity2.BFG_BIGEXPLOSION:
13944
+ {
13945
+ const color = { x: 0, y: 1, z: 0 };
13946
+ this.addLight(void 0, pos, color, 300, 0, time + 0.5);
13947
+ this.playSound(pos, 0, "weapons/bfg__x1b.wav", 1, 0.5);
13948
+ }
13949
+ break;
13950
+ }
13951
+ }
13952
+ };
13953
+
13598
13954
  // src/input/bindings.ts
13599
13955
  var DEFAULT_BINDINGS = [
13600
13956
  { code: "KeyW", command: "+forward" },
@@ -14253,6 +14609,23 @@ function createClient(imports) {
14253
14609
  const demoHandler = new ClientNetworkHandler(imports);
14254
14610
  const demoRecorder = new DemoRecorder();
14255
14611
  demoHandler.setView(view);
14612
+ const dlightManager = new DynamicLightManager();
14613
+ const entityProvider = {
14614
+ getEntity(entNum) {
14615
+ if (isDemoPlaying) {
14616
+ return demoHandler.entities.get(entNum);
14617
+ } else {
14618
+ if (multiplayer.isConnected()) {
14619
+ return multiplayer.entities.get(entNum);
14620
+ }
14621
+ }
14622
+ return void 0;
14623
+ },
14624
+ getPlayerNum() {
14625
+ return multiplayer.playerNum;
14626
+ }
14627
+ };
14628
+ const effectSystem = new ClientEffectSystem(dlightManager, imports.engine, entityProvider);
14256
14629
  let isDemoPlaying = false;
14257
14630
  let currentDemoName = null;
14258
14631
  let clientMode = 0 /* Normal */;
@@ -14315,6 +14688,7 @@ function createClient(imports) {
14315
14688
  }
14316
14689
  });
14317
14690
  multiplayer.setDemoRecorder(demoRecorder);
14691
+ multiplayer.setEffectSystem(effectSystem);
14318
14692
  const multiplayerFactory = new MultiplayerMenuFactory(menuSystem, multiplayer);
14319
14693
  demoHandler.setCallbacks({
14320
14694
  onCenterPrint: (msg) => cg.ParseCenterPrint(msg, 0, false),
@@ -14329,6 +14703,19 @@ function createClient(imports) {
14329
14703
  } else {
14330
14704
  demoPlayback.setFrameDuration(100);
14331
14705
  }
14706
+ },
14707
+ // New hooks for effects
14708
+ onMuzzleFlash: (ent, weapon) => {
14709
+ const time = demoPlayback.getCurrentTime() / 1e3;
14710
+ effectSystem.onMuzzleFlash(ent, weapon, time);
14711
+ },
14712
+ onMuzzleFlash2: (ent, weapon) => {
14713
+ },
14714
+ onTempEntity: (type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) => {
14715
+ const time = demoPlayback.getCurrentTime() / 1e3;
14716
+ if (pos) {
14717
+ effectSystem.onTempEntity(type, pos, time);
14718
+ }
14332
14719
  }
14333
14720
  });
14334
14721
  demoPlayback.setHandler(demoHandler);
@@ -14442,6 +14829,7 @@ function createClient(imports) {
14442
14829
  const clientExports = {
14443
14830
  loadingScreen,
14444
14831
  errorDialog,
14832
+ dlightManager,
14445
14833
  init(initial) {
14446
14834
  this.Init(initial);
14447
14835
  },
@@ -14640,8 +15028,9 @@ function createClient(imports) {
14640
15028
  const frameTimeMs = sample.latest && sample.previous ? Math.max(0, sample.latest.timeMs - sample.previous.timeMs) : 0;
14641
15029
  lastView = view.sample(lastRendered, frameTimeMs);
14642
15030
  const command = {};
14643
- const dlights = [];
14644
15031
  const timeSeconds = sample.nowMs / 1e3;
15032
+ dlightManager.update(timeSeconds);
15033
+ const dlights = [...dlightManager.getActiveLights()];
14645
15034
  for (const ent of currentPacketEntities) {
14646
15035
  processEntityEffects(ent, dlights, timeSeconds);
14647
15036
  }