quake2ts 0.0.193 → 0.0.195

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 (40) hide show
  1. package/package.json +1 -1
  2. package/packages/cgame/dist/index.cjs +769 -103
  3. package/packages/cgame/dist/index.cjs.map +1 -1
  4. package/packages/cgame/dist/index.d.cts +83 -2
  5. package/packages/cgame/dist/index.d.ts +83 -2
  6. package/packages/cgame/dist/index.js +766 -105
  7. package/packages/cgame/dist/index.js.map +1 -1
  8. package/packages/client/dist/browser/index.global.js +5 -5
  9. package/packages/client/dist/browser/index.global.js.map +1 -1
  10. package/packages/client/dist/cjs/index.cjs +56 -502
  11. package/packages/client/dist/cjs/index.cjs.map +1 -1
  12. package/packages/client/dist/esm/index.js +55 -497
  13. package/packages/client/dist/esm/index.js.map +1 -1
  14. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  15. package/packages/client/dist/types/demo/handler.d.ts +1 -1
  16. package/packages/client/dist/types/demo/handler.d.ts.map +1 -1
  17. package/packages/client/dist/types/index.d.ts +4 -5
  18. package/packages/client/dist/types/index.d.ts.map +1 -1
  19. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  20. package/packages/game/dist/browser/index.global.js +2 -2
  21. package/packages/game/dist/browser/index.global.js.map +1 -1
  22. package/packages/game/dist/cjs/index.cjs +14 -2
  23. package/packages/game/dist/cjs/index.cjs.map +1 -1
  24. package/packages/game/dist/esm/index.js +14 -2
  25. package/packages/game/dist/esm/index.js.map +1 -1
  26. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  27. package/packages/game/dist/types/index.d.ts +5 -0
  28. package/packages/game/dist/types/index.d.ts.map +1 -1
  29. package/packages/server/dist/index.cjs +7 -1
  30. package/packages/server/dist/index.js +7 -1
  31. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  32. package/packages/shared/dist/types/protocol/player-state.d.ts +5 -0
  33. package/packages/shared/dist/types/protocol/player-state.d.ts.map +1 -1
  34. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
  35. package/packages/client/dist/types/prediction.d.ts +0 -51
  36. package/packages/client/dist/types/prediction.d.ts.map +0 -1
  37. package/packages/client/dist/types/view-effects.d.ts +0 -41
  38. package/packages/client/dist/types/view-effects.d.ts.map +0 -1
  39. package/packages/client/dist/types/view.d.ts +0 -4
  40. package/packages/client/dist/types/view.d.ts.map +0 -1
@@ -2,6 +2,12 @@
2
2
 
3
3
  var shared = require('@quake2ts/shared');
4
4
 
5
+ var __defProp = Object.defineProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
5
11
  // src/hud/crosshair.ts
6
12
  var crosshairPic = null;
7
13
  var crosshairColor = [1, 1, 1, 1];
@@ -110,7 +116,7 @@ var Init_Damage = (cgi3) => {
110
116
  }
111
117
  };
112
118
  var Draw_Damage = (cgi3, ps, width, height) => {
113
- if (!ps.damage_yaw && !ps.damage_pitch && !ps.damage_alpha) {
119
+ if ((!ps.damageAlpha || ps.damageAlpha <= 0) && (!ps.damageIndicators || ps.damageIndicators.length === 0)) {
114
120
  return;
115
121
  }
116
122
  };
@@ -212,87 +218,35 @@ var Draw_Number = (cgi3, x, y, value, pics, width, color) => {
212
218
  const digit = parseInt(s[i]);
213
219
  const pic = pics[digit];
214
220
  if (pic) {
215
- {
221
+ if (color) {
222
+ cgi3.SCR_DrawColorPic(x + i * width, y, pic, { x: color[0], y: color[1], z: color[2] }, color[3]);
223
+ } else {
216
224
  cgi3.SCR_DrawPic(x + i * width, y, pic);
217
225
  }
218
226
  }
219
227
  }
220
228
  };
221
- var WEAPON_ICON_MAP = {
222
- [shared.WeaponId.Blaster]: "w_blaster",
223
- [shared.WeaponId.Shotgun]: "w_shotgun",
224
- [shared.WeaponId.SuperShotgun]: "w_sshotgun",
225
- [shared.WeaponId.Machinegun]: "w_machinegun",
226
- [shared.WeaponId.Chaingun]: "w_chaingun",
227
- [shared.WeaponId.GrenadeLauncher]: "w_glauncher",
228
- [shared.WeaponId.RocketLauncher]: "w_rlauncher",
229
- [shared.WeaponId.HyperBlaster]: "w_hyperblaster",
230
- [shared.WeaponId.Railgun]: "w_railgun",
231
- [shared.WeaponId.BFG10K]: "w_bfg",
232
- [shared.WeaponId.Grapple]: "w_grapple",
233
- [shared.WeaponId.ChainFist]: "w_chainfist",
234
- [shared.WeaponId.EtfRifle]: "w_etf_rifle",
235
- [shared.WeaponId.ProxLauncher]: "w_prox_launcher",
236
- [shared.WeaponId.IonRipper]: "w_ionripper",
237
- [shared.WeaponId.PlasmaBeam]: "w_plasmabeam",
238
- [shared.WeaponId.Phalanx]: "w_phalanx",
239
- [shared.WeaponId.Disruptor]: "w_disruptor"
240
- };
241
- var KEY_ICON_MAP = {
242
- "blue": "k_bluekey",
243
- "red": "k_redkey",
244
- "green": "k_security",
245
- "yellow": "k_pyramid"
246
- };
247
- var Draw_StatusBar = (cgi3, client, health, armor, ammo, hudNumberPics2, numberWidth2, timeMs, layout) => {
229
+ var Draw_StatusBar = (cgi3, ps, hudNumberPics2, numberWidth2, timeMs, layout) => {
230
+ const health = ps.stats[shared.PlayerStat.STAT_HEALTH] || 0;
231
+ const armor = ps.stats[shared.PlayerStat.STAT_ARMOR] || 0;
232
+ const ammo = ps.stats[shared.PlayerStat.STAT_AMMO] ? shared.G_GetAmmoStat(ps.stats[shared.PlayerStat.STAT_AMMO]) : 0;
233
+ ps.stats[shared.PlayerStat.STAT_ARMOR_ICON] || 0;
234
+ ps.stats[shared.PlayerStat.STAT_AMMO_ICON] || 0;
235
+ let healthColor = void 0;
236
+ if (health <= 25) {
237
+ {
238
+ healthColor = [1, 0, 0, 1];
239
+ }
240
+ }
248
241
  if (hudNumberPics2.length > 0) {
249
- Draw_Number(cgi3, layout.HEALTH_X, layout.HEALTH_Y, health, hudNumberPics2, numberWidth2);
242
+ Draw_Number(cgi3, layout.HEALTH_X, layout.HEALTH_Y, health, hudNumberPics2, numberWidth2, healthColor);
250
243
  Draw_Number(cgi3, layout.ARMOR_X, layout.ARMOR_Y, armor, hudNumberPics2, numberWidth2);
251
244
  Draw_Number(cgi3, layout.AMMO_X, layout.AMMO_Y, ammo, hudNumberPics2, numberWidth2);
252
245
  }
253
- const armorItem = client.inventory.armor;
254
- if (armorItem && armorItem.armorCount > 0) {
255
- const iconName = `i_${armorItem.armorType}armor`;
256
- const icon = iconPics.get(iconName);
246
+ if (ps.pickupIcon) {
247
+ const icon = cgi3.Draw_RegisterPic(ps.pickupIcon);
257
248
  if (icon) {
258
- cgi3.SCR_DrawPic(layout.ARMOR_X - 24, layout.ARMOR_Y - 2, icon);
259
- }
260
- }
261
- const currentWeapon = client.inventory.currentWeapon;
262
- if (currentWeapon) {
263
- const iconName = WEAPON_ICON_MAP[currentWeapon];
264
- if (iconName) {
265
- const icon = iconPics.get(iconName);
266
- if (icon) {
267
- cgi3.SCR_DrawPic(layout.WEAPON_ICON_X, layout.WEAPON_ICON_Y, icon);
268
- }
269
- }
270
- }
271
- const keys = Array.from(client.inventory.keys).sort();
272
- let keyY = layout.WEAPON_ICON_Y - 150 * layout.scale;
273
- for (const key of keys) {
274
- const iconName = KEY_ICON_MAP[key];
275
- if (iconName) {
276
- const icon = iconPics.get(iconName);
277
- if (icon) {
278
- const size = cgi3.Draw_GetPicSize(icon);
279
- cgi3.SCR_DrawPic(layout.WEAPON_ICON_X, keyY, icon);
280
- keyY += size.height + 2;
281
- }
282
- }
283
- }
284
- let powerupX = layout.POWERUP_X;
285
- for (const [powerup, expiresAt] of Array.from(client.inventory.powerups.entries())) {
286
- if (expiresAt && expiresAt > timeMs) {
287
- const iconName = `p_${powerup}`;
288
- const icon = iconPics.get(iconName);
289
- if (icon) {
290
- const size = cgi3.Draw_GetPicSize(icon);
291
- cgi3.SCR_DrawPic(powerupX, layout.POWERUP_Y, icon);
292
- const remainingSeconds = Math.ceil((expiresAt - timeMs) / 1e3);
293
- Draw_Number(cgi3, powerupX + size.width + 2, layout.POWERUP_Y, remainingSeconds, hudNumberPics2, numberWidth2);
294
- powerupX -= size.width + numberWidth2 * remainingSeconds.toString().length + 8;
295
- }
249
+ cgi3.SCR_DrawPic(layout.WEAPON_ICON_X, layout.WEAPON_ICON_Y, icon);
296
250
  }
297
251
  }
298
252
  };
@@ -303,26 +257,26 @@ var REFERENCE_HEIGHT = 480;
303
257
  var getHudLayout = (width, height) => {
304
258
  const scaleX = width / REFERENCE_WIDTH;
305
259
  const scaleY = height / REFERENCE_HEIGHT;
306
- const scale = Math.min(scaleX, scaleY);
260
+ const scale2 = Math.min(scaleX, scaleY);
307
261
  return {
308
262
  // Status bar numbers - Anchored Bottom-Left / Center / Right
309
- HEALTH_X: 100 * scale,
310
- HEALTH_Y: height - (REFERENCE_HEIGHT - 450) * scale,
311
- ARMOR_X: 200 * scale,
312
- ARMOR_Y: height - (REFERENCE_HEIGHT - 450) * scale,
313
- AMMO_X: width - (REFERENCE_WIDTH - 540) * scale,
263
+ HEALTH_X: 100 * scale2,
264
+ HEALTH_Y: height - (REFERENCE_HEIGHT - 450) * scale2,
265
+ ARMOR_X: 200 * scale2,
266
+ ARMOR_Y: height - (REFERENCE_HEIGHT - 450) * scale2,
267
+ AMMO_X: width - (REFERENCE_WIDTH - 540) * scale2,
314
268
  // Anchor right? 540 is near right (640)
315
- AMMO_Y: height - (REFERENCE_HEIGHT - 450) * scale,
269
+ AMMO_Y: height - (REFERENCE_HEIGHT - 450) * scale2,
316
270
  // Center print messages - Center
317
271
  CENTER_PRINT_X: width / 2,
318
- CENTER_PRINT_Y: 100 * scale,
272
+ CENTER_PRINT_Y: 100 * scale2,
319
273
  // Top anchor
320
274
  // Weapon and powerup icons
321
- WEAPON_ICON_X: 10 * scale,
322
- WEAPON_ICON_Y: height - (REFERENCE_HEIGHT - 450) * scale,
323
- POWERUP_X: width - (REFERENCE_WIDTH - 610) * scale,
324
- POWERUP_Y: height - (REFERENCE_HEIGHT - 450) * scale,
325
- scale
275
+ WEAPON_ICON_X: 10 * scale2,
276
+ WEAPON_ICON_Y: height - (REFERENCE_HEIGHT - 450) * scale2,
277
+ POWERUP_X: width - (REFERENCE_WIDTH - 610) * scale2,
278
+ POWERUP_Y: height - (REFERENCE_HEIGHT - 450) * scale2,
279
+ scale: scale2
326
280
  };
327
281
  };
328
282
 
@@ -354,7 +308,7 @@ function CG_TouchPics() {
354
308
  Init_Icons(cgi);
355
309
  Init_Damage(cgi);
356
310
  }
357
- function CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps) {
311
+ function CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale2, playernum, ps) {
358
312
  if (!cgi) {
359
313
  console.error("CG_DrawHUD: cgame imports not initialized");
360
314
  return;
@@ -362,19 +316,7 @@ function CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps) {
362
316
  const timeMs = cgi.CL_ClientTime();
363
317
  const layout = getHudLayout(hud_vrect.width, hud_vrect.height);
364
318
  Draw_Blends(cgi, ps, hud_vrect.width, hud_vrect.height);
365
- const tempClientState = {
366
- inventory: {
367
- armor: null,
368
- // TODO: Map from ps.stats
369
- powerups: /* @__PURE__ */ new Map(),
370
- // TODO: Map from ps.stats
371
- keys: /* @__PURE__ */ new Set(),
372
- // TODO: Map from ps.stats
373
- currentWeapon: void 0
374
- // TODO: Map from ps.stats/gunindex
375
- }
376
- };
377
- Draw_StatusBar(cgi, tempClientState, 100, 0, 0, hudNumberPics, numberWidth, timeMs, layout);
319
+ Draw_StatusBar(cgi, ps, hudNumberPics, numberWidth, timeMs, layout);
378
320
  Draw_Pickup(cgi, ps, hud_vrect.width, hud_vrect.height);
379
321
  Draw_Damage(cgi, ps, hud_vrect.width, hud_vrect.height);
380
322
  if (ps.centerPrint) {
@@ -391,6 +333,725 @@ function CG_GetMessageSystem() {
391
333
  return messageSystem;
392
334
  }
393
335
 
336
+ // ../../node_modules/.pnpm/gl-matrix@3.4.4/node_modules/gl-matrix/esm/common.js
337
+ var EPSILON = 1e-6;
338
+ var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
339
+ var RANDOM = Math.random;
340
+ function round(a) {
341
+ if (a >= 0) return Math.round(a);
342
+ return a % 0.5 === 0 ? Math.floor(a) : Math.round(a);
343
+ }
344
+
345
+ // ../../node_modules/.pnpm/gl-matrix@3.4.4/node_modules/gl-matrix/esm/vec3.js
346
+ var vec3_exports = {};
347
+ __export(vec3_exports, {
348
+ add: () => add,
349
+ angle: () => angle,
350
+ bezier: () => bezier,
351
+ ceil: () => ceil,
352
+ clone: () => clone,
353
+ copy: () => copy,
354
+ create: () => create,
355
+ cross: () => cross,
356
+ dist: () => dist,
357
+ distance: () => distance,
358
+ div: () => div,
359
+ divide: () => divide,
360
+ dot: () => dot,
361
+ equals: () => equals,
362
+ exactEquals: () => exactEquals,
363
+ floor: () => floor,
364
+ forEach: () => forEach,
365
+ fromValues: () => fromValues,
366
+ hermite: () => hermite,
367
+ inverse: () => inverse,
368
+ len: () => len,
369
+ length: () => length,
370
+ lerp: () => lerp,
371
+ max: () => max,
372
+ min: () => min,
373
+ mul: () => mul,
374
+ multiply: () => multiply,
375
+ negate: () => negate,
376
+ normalize: () => normalize,
377
+ random: () => random,
378
+ rotateX: () => rotateX,
379
+ rotateY: () => rotateY,
380
+ rotateZ: () => rotateZ,
381
+ round: () => round2,
382
+ scale: () => scale,
383
+ scaleAndAdd: () => scaleAndAdd,
384
+ set: () => set,
385
+ slerp: () => slerp,
386
+ sqrDist: () => sqrDist,
387
+ sqrLen: () => sqrLen,
388
+ squaredDistance: () => squaredDistance,
389
+ squaredLength: () => squaredLength,
390
+ str: () => str,
391
+ sub: () => sub,
392
+ subtract: () => subtract,
393
+ transformMat3: () => transformMat3,
394
+ transformMat4: () => transformMat4,
395
+ transformQuat: () => transformQuat,
396
+ zero: () => zero
397
+ });
398
+ function create() {
399
+ var out = new ARRAY_TYPE(3);
400
+ if (ARRAY_TYPE != Float32Array) {
401
+ out[0] = 0;
402
+ out[1] = 0;
403
+ out[2] = 0;
404
+ }
405
+ return out;
406
+ }
407
+ function clone(a) {
408
+ var out = new ARRAY_TYPE(3);
409
+ out[0] = a[0];
410
+ out[1] = a[1];
411
+ out[2] = a[2];
412
+ return out;
413
+ }
414
+ function length(a) {
415
+ var x = a[0];
416
+ var y = a[1];
417
+ var z = a[2];
418
+ return Math.sqrt(x * x + y * y + z * z);
419
+ }
420
+ function fromValues(x, y, z) {
421
+ var out = new ARRAY_TYPE(3);
422
+ out[0] = x;
423
+ out[1] = y;
424
+ out[2] = z;
425
+ return out;
426
+ }
427
+ function copy(out, a) {
428
+ out[0] = a[0];
429
+ out[1] = a[1];
430
+ out[2] = a[2];
431
+ return out;
432
+ }
433
+ function set(out, x, y, z) {
434
+ out[0] = x;
435
+ out[1] = y;
436
+ out[2] = z;
437
+ return out;
438
+ }
439
+ function add(out, a, b) {
440
+ out[0] = a[0] + b[0];
441
+ out[1] = a[1] + b[1];
442
+ out[2] = a[2] + b[2];
443
+ return out;
444
+ }
445
+ function subtract(out, a, b) {
446
+ out[0] = a[0] - b[0];
447
+ out[1] = a[1] - b[1];
448
+ out[2] = a[2] - b[2];
449
+ return out;
450
+ }
451
+ function multiply(out, a, b) {
452
+ out[0] = a[0] * b[0];
453
+ out[1] = a[1] * b[1];
454
+ out[2] = a[2] * b[2];
455
+ return out;
456
+ }
457
+ function divide(out, a, b) {
458
+ out[0] = a[0] / b[0];
459
+ out[1] = a[1] / b[1];
460
+ out[2] = a[2] / b[2];
461
+ return out;
462
+ }
463
+ function ceil(out, a) {
464
+ out[0] = Math.ceil(a[0]);
465
+ out[1] = Math.ceil(a[1]);
466
+ out[2] = Math.ceil(a[2]);
467
+ return out;
468
+ }
469
+ function floor(out, a) {
470
+ out[0] = Math.floor(a[0]);
471
+ out[1] = Math.floor(a[1]);
472
+ out[2] = Math.floor(a[2]);
473
+ return out;
474
+ }
475
+ function min(out, a, b) {
476
+ out[0] = Math.min(a[0], b[0]);
477
+ out[1] = Math.min(a[1], b[1]);
478
+ out[2] = Math.min(a[2], b[2]);
479
+ return out;
480
+ }
481
+ function max(out, a, b) {
482
+ out[0] = Math.max(a[0], b[0]);
483
+ out[1] = Math.max(a[1], b[1]);
484
+ out[2] = Math.max(a[2], b[2]);
485
+ return out;
486
+ }
487
+ function round2(out, a) {
488
+ out[0] = round(a[0]);
489
+ out[1] = round(a[1]);
490
+ out[2] = round(a[2]);
491
+ return out;
492
+ }
493
+ function scale(out, a, b) {
494
+ out[0] = a[0] * b;
495
+ out[1] = a[1] * b;
496
+ out[2] = a[2] * b;
497
+ return out;
498
+ }
499
+ function scaleAndAdd(out, a, b, scale2) {
500
+ out[0] = a[0] + b[0] * scale2;
501
+ out[1] = a[1] + b[1] * scale2;
502
+ out[2] = a[2] + b[2] * scale2;
503
+ return out;
504
+ }
505
+ function distance(a, b) {
506
+ var x = b[0] - a[0];
507
+ var y = b[1] - a[1];
508
+ var z = b[2] - a[2];
509
+ return Math.sqrt(x * x + y * y + z * z);
510
+ }
511
+ function squaredDistance(a, b) {
512
+ var x = b[0] - a[0];
513
+ var y = b[1] - a[1];
514
+ var z = b[2] - a[2];
515
+ return x * x + y * y + z * z;
516
+ }
517
+ function squaredLength(a) {
518
+ var x = a[0];
519
+ var y = a[1];
520
+ var z = a[2];
521
+ return x * x + y * y + z * z;
522
+ }
523
+ function negate(out, a) {
524
+ out[0] = -a[0];
525
+ out[1] = -a[1];
526
+ out[2] = -a[2];
527
+ return out;
528
+ }
529
+ function inverse(out, a) {
530
+ out[0] = 1 / a[0];
531
+ out[1] = 1 / a[1];
532
+ out[2] = 1 / a[2];
533
+ return out;
534
+ }
535
+ function normalize(out, a) {
536
+ var x = a[0];
537
+ var y = a[1];
538
+ var z = a[2];
539
+ var len2 = x * x + y * y + z * z;
540
+ if (len2 > 0) {
541
+ len2 = 1 / Math.sqrt(len2);
542
+ }
543
+ out[0] = a[0] * len2;
544
+ out[1] = a[1] * len2;
545
+ out[2] = a[2] * len2;
546
+ return out;
547
+ }
548
+ function dot(a, b) {
549
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
550
+ }
551
+ function cross(out, a, b) {
552
+ var ax = a[0], ay = a[1], az = a[2];
553
+ var bx = b[0], by = b[1], bz = b[2];
554
+ out[0] = ay * bz - az * by;
555
+ out[1] = az * bx - ax * bz;
556
+ out[2] = ax * by - ay * bx;
557
+ return out;
558
+ }
559
+ function lerp(out, a, b, t) {
560
+ var ax = a[0];
561
+ var ay = a[1];
562
+ var az = a[2];
563
+ out[0] = ax + t * (b[0] - ax);
564
+ out[1] = ay + t * (b[1] - ay);
565
+ out[2] = az + t * (b[2] - az);
566
+ return out;
567
+ }
568
+ function slerp(out, a, b, t) {
569
+ var angle2 = Math.acos(Math.min(Math.max(dot(a, b), -1), 1));
570
+ var sinTotal = Math.sin(angle2);
571
+ var ratioA = Math.sin((1 - t) * angle2) / sinTotal;
572
+ var ratioB = Math.sin(t * angle2) / sinTotal;
573
+ out[0] = ratioA * a[0] + ratioB * b[0];
574
+ out[1] = ratioA * a[1] + ratioB * b[1];
575
+ out[2] = ratioA * a[2] + ratioB * b[2];
576
+ return out;
577
+ }
578
+ function hermite(out, a, b, c, d, t) {
579
+ var factorTimes2 = t * t;
580
+ var factor1 = factorTimes2 * (2 * t - 3) + 1;
581
+ var factor2 = factorTimes2 * (t - 2) + t;
582
+ var factor3 = factorTimes2 * (t - 1);
583
+ var factor4 = factorTimes2 * (3 - 2 * t);
584
+ out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
585
+ out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
586
+ out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
587
+ return out;
588
+ }
589
+ function bezier(out, a, b, c, d, t) {
590
+ var inverseFactor = 1 - t;
591
+ var inverseFactorTimesTwo = inverseFactor * inverseFactor;
592
+ var factorTimes2 = t * t;
593
+ var factor1 = inverseFactorTimesTwo * inverseFactor;
594
+ var factor2 = 3 * t * inverseFactorTimesTwo;
595
+ var factor3 = 3 * factorTimes2 * inverseFactor;
596
+ var factor4 = factorTimes2 * t;
597
+ out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
598
+ out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
599
+ out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
600
+ return out;
601
+ }
602
+ function random(out, scale2) {
603
+ scale2 = scale2 === void 0 ? 1 : scale2;
604
+ var r = RANDOM() * 2 * Math.PI;
605
+ var z = RANDOM() * 2 - 1;
606
+ var zScale = Math.sqrt(1 - z * z) * scale2;
607
+ out[0] = Math.cos(r) * zScale;
608
+ out[1] = Math.sin(r) * zScale;
609
+ out[2] = z * scale2;
610
+ return out;
611
+ }
612
+ function transformMat4(out, a, m) {
613
+ var x = a[0], y = a[1], z = a[2];
614
+ var w = m[3] * x + m[7] * y + m[11] * z + m[15];
615
+ w = w || 1;
616
+ out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
617
+ out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
618
+ out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
619
+ return out;
620
+ }
621
+ function transformMat3(out, a, m) {
622
+ var x = a[0], y = a[1], z = a[2];
623
+ out[0] = x * m[0] + y * m[3] + z * m[6];
624
+ out[1] = x * m[1] + y * m[4] + z * m[7];
625
+ out[2] = x * m[2] + y * m[5] + z * m[8];
626
+ return out;
627
+ }
628
+ function transformQuat(out, a, q) {
629
+ var qx = q[0], qy = q[1], qz = q[2], qw = q[3];
630
+ var vx = a[0], vy = a[1], vz = a[2];
631
+ var tx = qy * vz - qz * vy;
632
+ var ty = qz * vx - qx * vz;
633
+ var tz = qx * vy - qy * vx;
634
+ tx = tx + tx;
635
+ ty = ty + ty;
636
+ tz = tz + tz;
637
+ out[0] = vx + qw * tx + qy * tz - qz * ty;
638
+ out[1] = vy + qw * ty + qz * tx - qx * tz;
639
+ out[2] = vz + qw * tz + qx * ty - qy * tx;
640
+ return out;
641
+ }
642
+ function rotateX(out, a, b, rad) {
643
+ var p = [], r = [];
644
+ p[0] = a[0] - b[0];
645
+ p[1] = a[1] - b[1];
646
+ p[2] = a[2] - b[2];
647
+ r[0] = p[0];
648
+ r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);
649
+ r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad);
650
+ out[0] = r[0] + b[0];
651
+ out[1] = r[1] + b[1];
652
+ out[2] = r[2] + b[2];
653
+ return out;
654
+ }
655
+ function rotateY(out, a, b, rad) {
656
+ var p = [], r = [];
657
+ p[0] = a[0] - b[0];
658
+ p[1] = a[1] - b[1];
659
+ p[2] = a[2] - b[2];
660
+ r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);
661
+ r[1] = p[1];
662
+ r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad);
663
+ out[0] = r[0] + b[0];
664
+ out[1] = r[1] + b[1];
665
+ out[2] = r[2] + b[2];
666
+ return out;
667
+ }
668
+ function rotateZ(out, a, b, rad) {
669
+ var p = [], r = [];
670
+ p[0] = a[0] - b[0];
671
+ p[1] = a[1] - b[1];
672
+ p[2] = a[2] - b[2];
673
+ r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);
674
+ r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);
675
+ r[2] = p[2];
676
+ out[0] = r[0] + b[0];
677
+ out[1] = r[1] + b[1];
678
+ out[2] = r[2] + b[2];
679
+ return out;
680
+ }
681
+ function angle(a, b) {
682
+ var ax = a[0], ay = a[1], az = a[2], bx = b[0], by = b[1], bz = b[2], mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)), cosine = mag && dot(a, b) / mag;
683
+ return Math.acos(Math.min(Math.max(cosine, -1), 1));
684
+ }
685
+ function zero(out) {
686
+ out[0] = 0;
687
+ out[1] = 0;
688
+ out[2] = 0;
689
+ return out;
690
+ }
691
+ function str(a) {
692
+ return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")";
693
+ }
694
+ function exactEquals(a, b) {
695
+ return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
696
+ }
697
+ function equals(a, b) {
698
+ var a0 = a[0], a1 = a[1], a2 = a[2];
699
+ var b0 = b[0], b1 = b[1], b2 = b[2];
700
+ return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2));
701
+ }
702
+ var sub = subtract;
703
+ var mul = multiply;
704
+ var div = divide;
705
+ var dist = distance;
706
+ var sqrDist = squaredDistance;
707
+ var len = length;
708
+ var sqrLen = squaredLength;
709
+ var forEach = (function() {
710
+ var vec = create();
711
+ return function(a, stride, offset, count, fn, arg) {
712
+ var i, l;
713
+ if (!stride) {
714
+ stride = 3;
715
+ }
716
+ if (!offset) {
717
+ offset = 0;
718
+ }
719
+ if (count) {
720
+ l = Math.min(count * stride + offset, a.length);
721
+ } else {
722
+ l = a.length;
723
+ }
724
+ for (i = offset; i < l; i += stride) {
725
+ vec[0] = a[i];
726
+ vec[1] = a[i + 1];
727
+ vec[2] = a[i + 2];
728
+ fn(vec, vec, arg);
729
+ a[i] = vec[0];
730
+ a[i + 1] = vec[1];
731
+ a[i + 2] = vec[2];
732
+ }
733
+ return a;
734
+ };
735
+ })();
736
+
737
+ // src/view/camera.ts
738
+ var toGlMatrixVec3 = (v) => {
739
+ return vec3_exports.fromValues(v.x, v.y, v.z);
740
+ };
741
+ var updateCamera = (camera, viewSample) => {
742
+ camera.bobAngles = toGlMatrixVec3(viewSample.angles);
743
+ camera.bobOffset = toGlMatrixVec3(viewSample.offset);
744
+ };
745
+ var DEFAULT_SETTINGS = {
746
+ runPitch: 2e-3,
747
+ runRoll: 0.01,
748
+ // Changed from 0.005 to match Quake 2 slope (2.0 / 200.0)
749
+ bobUp: 5e-3,
750
+ bobPitch: 2e-3,
751
+ bobRoll: 2e-3,
752
+ maxBobHeight: 6,
753
+ maxBobAngle: 1.2
754
+ };
755
+ function clampViewOffset(offset) {
756
+ return {
757
+ x: Math.max(-14, Math.min(14, offset.x)),
758
+ y: Math.max(-14, Math.min(14, offset.y)),
759
+ z: Math.max(-22, Math.min(30, offset.z))
760
+ };
761
+ }
762
+ function computeBobMove(xyspeed, onGround, frameTimeMs) {
763
+ if (!onGround) return 0;
764
+ if (xyspeed > 210) return frameTimeMs / 400;
765
+ if (xyspeed > 100) return frameTimeMs / 800;
766
+ return frameTimeMs / 1600;
767
+ }
768
+ function computeBobValues(previousBobTime, xyspeed, pmFlags, onGround, frameTimeMs) {
769
+ if (xyspeed < 5) {
770
+ return { bobTime: 0, bobCycle: 0, bobCycleRun: 0, bobFracSin: 0 };
771
+ }
772
+ const bobMove = computeBobMove(xyspeed, onGround, frameTimeMs);
773
+ const bobTimeRun = previousBobTime + bobMove;
774
+ const crouched = shared.hasPmFlag(pmFlags, shared.PmFlag.Ducked) && onGround;
775
+ const bobTime = crouched ? bobTimeRun * 4 : bobTimeRun;
776
+ return {
777
+ bobTime: bobTimeRun,
778
+ bobCycle: Math.floor(bobTime),
779
+ bobCycleRun: Math.floor(bobTimeRun),
780
+ bobFracSin: Math.abs(Math.sin(bobTime * Math.PI))
781
+ };
782
+ }
783
+ var ViewEffects = class {
784
+ constructor(settings = {}) {
785
+ this.bobTime = 0;
786
+ this.bobCycle = 0;
787
+ this.bobCycleRun = 0;
788
+ this.bobFracSin = 0;
789
+ this.settings = { ...DEFAULT_SETTINGS, ...settings };
790
+ }
791
+ addKick(kick) {
792
+ if (kick.durationMs <= 0) return;
793
+ this.kick = { ...kick, remainingMs: kick.durationMs };
794
+ }
795
+ get last() {
796
+ return this.lastSample;
797
+ }
798
+ sample(state, frameTimeMs) {
799
+ const { forward, right } = shared.angleVectors(
800
+ shared.clampViewAngles({ pmFlags: state.pmFlags, cmdAngles: state.viewAngles, deltaAngles: state.deltaAngles ?? shared.ZERO_VEC3 }).viewangles
801
+ );
802
+ const xyspeed = Math.sqrt(state.velocity.x * state.velocity.x + state.velocity.y * state.velocity.y);
803
+ const onGround = shared.hasPmFlag(state.pmFlags, shared.PmFlag.OnGround);
804
+ const bobValues = computeBobValues(this.bobTime, xyspeed, state.pmFlags, onGround, frameTimeMs);
805
+ this.bobTime = bobValues.bobTime;
806
+ this.bobCycle = bobValues.bobCycle;
807
+ this.bobCycleRun = bobValues.bobCycleRun;
808
+ this.bobFracSin = bobValues.bobFracSin;
809
+ let pitchTilt = shared.dotVec3(state.velocity, forward) * this.settings.runPitch;
810
+ const side = shared.dotVec3(state.velocity, right);
811
+ const sign = side < 0 ? -1 : 1;
812
+ const absSide = Math.abs(side);
813
+ let rollTilt = absSide * this.settings.runRoll;
814
+ if (rollTilt > 2) {
815
+ rollTilt = 2;
816
+ }
817
+ rollTilt *= sign;
818
+ let pitchDelta = this.bobFracSin * this.settings.bobPitch * xyspeed;
819
+ let rollDelta = this.bobFracSin * this.settings.bobRoll * xyspeed;
820
+ if (shared.hasPmFlag(state.pmFlags, shared.PmFlag.Ducked) && onGround) {
821
+ pitchDelta *= 6;
822
+ rollDelta *= 6;
823
+ }
824
+ pitchTilt += Math.min(pitchDelta, this.settings.maxBobAngle);
825
+ rollDelta = Math.min(rollDelta, this.settings.maxBobAngle);
826
+ if (this.bobCycle & 1) rollDelta = -rollDelta;
827
+ rollTilt += rollDelta;
828
+ const bobHeight = Math.min(this.bobFracSin * xyspeed * this.settings.bobUp, this.settings.maxBobHeight);
829
+ let kickPitch = 0;
830
+ let kickRoll = 0;
831
+ if (this.kick && this.kick.remainingMs > 0) {
832
+ const ratio = Math.max(0, Math.min(1, this.kick.remainingMs / this.kick.durationMs));
833
+ kickPitch += ratio * this.kick.pitch;
834
+ kickRoll += ratio * this.kick.roll;
835
+ this.kick.remainingMs = Math.max(0, this.kick.remainingMs - frameTimeMs);
836
+ if (this.kick.remainingMs === 0) this.kick = void 0;
837
+ }
838
+ const angles = { x: pitchTilt + kickPitch, y: 0, z: rollTilt + kickRoll };
839
+ const offset = { x: 0, y: 0, z: bobHeight };
840
+ const sample = {
841
+ angles,
842
+ offset: clampViewOffset(offset),
843
+ bobCycle: this.bobCycle,
844
+ bobCycleRun: this.bobCycleRun,
845
+ bobFracSin: this.bobFracSin,
846
+ xyspeed
847
+ };
848
+ this.lastSample = sample;
849
+ return sample;
850
+ }
851
+ };
852
+ var DEFAULTS = {
853
+ pmFriction: 6,
854
+ pmStopSpeed: 100,
855
+ pmAccelerate: 10,
856
+ pmAirAccelerate: 1,
857
+ pmWaterAccelerate: 4,
858
+ pmWaterFriction: 1,
859
+ pmMaxSpeed: 300,
860
+ pmDuckSpeed: 100,
861
+ pmWaterSpeed: 400,
862
+ groundIsSlick: false
863
+ };
864
+ var DEFAULT_GRAVITY = 800;
865
+ var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
866
+ var MSEC_MAX = 250;
867
+ function defaultPredictionState() {
868
+ return {
869
+ origin: ZERO_VEC32,
870
+ velocity: ZERO_VEC32,
871
+ viewAngles: ZERO_VEC32,
872
+ onGround: false,
873
+ // Physics fields
874
+ pmFlags: shared.PmFlag.OnGround,
875
+ pmType: shared.PmType.Normal,
876
+ waterLevel: shared.WaterLevel.None,
877
+ gravity: DEFAULT_GRAVITY,
878
+ deltaAngles: ZERO_VEC32,
879
+ // Bounds
880
+ mins: { x: -16, y: -16, z: -24 },
881
+ maxs: { x: 16, y: 16, z: 32 },
882
+ // Visual/Game fields
883
+ damageAlpha: 0,
884
+ damageIndicators: [],
885
+ blend: [0, 0, 0, 0],
886
+ stats: [],
887
+ kick_angles: ZERO_VEC32,
888
+ gunoffset: ZERO_VEC32,
889
+ gunangles: ZERO_VEC32,
890
+ gunindex: 0,
891
+ // Optional fields
892
+ pickupIcon: void 0,
893
+ centerPrint: void 0,
894
+ notify: void 0,
895
+ client: void 0,
896
+ health: 0,
897
+ armor: 0,
898
+ ammo: 0
899
+ };
900
+ }
901
+ function normalizeState(state) {
902
+ if (!state) return defaultPredictionState();
903
+ return {
904
+ ...defaultPredictionState(),
905
+ ...state,
906
+ origin: { ...state.origin },
907
+ velocity: { ...state.velocity },
908
+ viewAngles: { ...state.viewAngles },
909
+ deltaAngles: state.deltaAngles ? { ...state.deltaAngles } : ZERO_VEC32,
910
+ blend: state.blend ? [...state.blend] : [0, 0, 0, 0],
911
+ damageIndicators: state.damageIndicators ? [...state.damageIndicators] : [],
912
+ stats: state.stats ? [...state.stats] : []
913
+ };
914
+ }
915
+ function lerp2(a, b, t) {
916
+ return a + (b - a) * t;
917
+ }
918
+ function lerpAngle(a, b, t) {
919
+ let delta = shared.angleMod(b - a);
920
+ if (delta > 180) {
921
+ delta -= 360;
922
+ }
923
+ return shared.angleMod(a + delta * t);
924
+ }
925
+ function interpolatePredictionState(previous, latest, alpha) {
926
+ const clamped = Math.max(0, Math.min(alpha, 1));
927
+ return {
928
+ ...latest,
929
+ // Default to latest for discrete fields
930
+ origin: {
931
+ x: lerp2(previous.origin.x, latest.origin.x, clamped),
932
+ y: lerp2(previous.origin.y, latest.origin.y, clamped),
933
+ z: lerp2(previous.origin.z, latest.origin.z, clamped)
934
+ },
935
+ velocity: {
936
+ x: lerp2(previous.velocity.x, latest.velocity.x, clamped),
937
+ y: lerp2(previous.velocity.y, latest.velocity.y, clamped),
938
+ z: lerp2(previous.velocity.z, latest.velocity.z, clamped)
939
+ },
940
+ viewAngles: {
941
+ x: lerpAngle(previous.viewAngles.x, latest.viewAngles.x, clamped),
942
+ y: lerpAngle(previous.viewAngles.y, latest.viewAngles.y, clamped),
943
+ z: lerpAngle(previous.viewAngles.z, latest.viewAngles.z, clamped)
944
+ },
945
+ damageAlpha: lerp2(previous.damageAlpha, latest.damageAlpha, clamped),
946
+ blend: [
947
+ lerp2(previous.blend[0], latest.blend[0], clamped),
948
+ lerp2(previous.blend[1], latest.blend[1], clamped),
949
+ lerp2(previous.blend[2], latest.blend[2], clamped),
950
+ lerp2(previous.blend[3], latest.blend[3], clamped)
951
+ ],
952
+ // Interpolate health/armor for smooth HUD? Usually step.
953
+ health: lerp2(previous.health || 0, latest.health || 0, clamped),
954
+ armor: lerp2(previous.armor || 0, latest.armor || 0, clamped),
955
+ ammo: lerp2(previous.ammo || 0, latest.ammo || 0, clamped)
956
+ };
957
+ }
958
+ function simulateCommand(state, cmd, settings, trace) {
959
+ const frametime = Math.min(Math.max(cmd.msec, 0), MSEC_MAX) / 1e3;
960
+ const onGround = shared.hasPmFlag(state.pmFlags, shared.PmFlag.OnGround);
961
+ const onLadder = shared.hasPmFlag(state.pmFlags, shared.PmFlag.OnLadder);
962
+ let velocity = shared.applyPmoveFriction({
963
+ velocity: state.velocity,
964
+ frametime,
965
+ onGround,
966
+ groundIsSlick: settings.groundIsSlick,
967
+ onLadder,
968
+ waterlevel: state.waterLevel,
969
+ pmFriction: settings.pmFriction,
970
+ pmStopSpeed: settings.pmStopSpeed,
971
+ pmWaterFriction: settings.pmWaterFriction
972
+ });
973
+ const { viewangles, forward, right } = shared.clampViewAngles({
974
+ pmFlags: state.pmFlags,
975
+ cmdAngles: cmd.angles,
976
+ deltaAngles: state.deltaAngles ?? ZERO_VEC32
977
+ });
978
+ const wish = state.waterLevel > shared.WaterLevel.None ? shared.buildWaterWish({ forward, right, cmd, maxSpeed: settings.pmWaterSpeed }) : shared.buildAirGroundWish({ forward, right, cmd, maxSpeed: settings.pmMaxSpeed });
979
+ if (state.waterLevel > shared.WaterLevel.None) {
980
+ velocity = shared.applyPmoveAccelerate({
981
+ velocity,
982
+ wishdir: wish.wishdir,
983
+ wishspeed: wish.wishspeed,
984
+ accel: settings.pmWaterAccelerate,
985
+ frametime
986
+ });
987
+ } else if (onGround || onLadder) {
988
+ const maxSpeed = shared.hasPmFlag(state.pmFlags, shared.PmFlag.Ducked) ? settings.pmDuckSpeed : settings.pmMaxSpeed;
989
+ const clampedWish = wish.wishspeed > maxSpeed ? {
990
+ wishdir: wish.wishdir,
991
+ wishspeed: maxSpeed
992
+ } : wish;
993
+ velocity = shared.applyPmoveAccelerate({
994
+ velocity,
995
+ wishdir: clampedWish.wishdir,
996
+ wishspeed: clampedWish.wishspeed,
997
+ accel: settings.pmAccelerate,
998
+ frametime
999
+ });
1000
+ } else {
1001
+ velocity = shared.applyPmoveAirAccelerate({
1002
+ velocity,
1003
+ wishdir: wish.wishdir,
1004
+ wishspeed: wish.wishspeed,
1005
+ accel: settings.pmAirAccelerate,
1006
+ frametime
1007
+ });
1008
+ velocity = { ...velocity, z: velocity.z - (state.gravity ?? DEFAULT_GRAVITY) * frametime };
1009
+ }
1010
+ const traceResult = trace(state.origin, shared.addVec3(state.origin, shared.scaleVec3(velocity, frametime)));
1011
+ const origin = traceResult.endpos;
1012
+ return {
1013
+ ...state,
1014
+ origin,
1015
+ velocity,
1016
+ viewAngles: viewangles
1017
+ };
1018
+ }
1019
+ var ClientPrediction = class {
1020
+ constructor(trace, settings = {}) {
1021
+ this.baseFrame = {
1022
+ frame: 0,
1023
+ timeMs: 0,
1024
+ state: defaultPredictionState()
1025
+ };
1026
+ this.commands = [];
1027
+ this.predicted = defaultPredictionState();
1028
+ this.settings = { ...DEFAULTS, ...settings };
1029
+ this.trace = trace;
1030
+ this.predicted = this.baseFrame.state ?? defaultPredictionState();
1031
+ }
1032
+ setAuthoritative(frame) {
1033
+ const normalized = normalizeState(frame.state);
1034
+ this.baseFrame = { ...frame, state: normalized };
1035
+ this.commands = this.commands.filter((cmd) => (cmd.serverFrame ?? Number.MAX_SAFE_INTEGER) > frame.frame);
1036
+ return this.recompute();
1037
+ }
1038
+ enqueueCommand(cmd) {
1039
+ this.commands.push(cmd);
1040
+ return this.recompute();
1041
+ }
1042
+ getPredictedState() {
1043
+ return this.predicted;
1044
+ }
1045
+ recompute() {
1046
+ let state = normalizeState(this.baseFrame.state);
1047
+ for (const cmd of this.commands) {
1048
+ state = simulateCommand(state, cmd, this.settings, this.trace);
1049
+ }
1050
+ this.predicted = state;
1051
+ return state;
1052
+ }
1053
+ };
1054
+
394
1055
  // src/index.ts
395
1056
  var cgi2 = null;
396
1057
  function Init() {
@@ -408,8 +1069,8 @@ function Shutdown() {
408
1069
  }
409
1070
  cgi2 = null;
410
1071
  }
411
- function DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps) {
412
- CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps);
1072
+ function DrawHUD(isplit, data, hud_vrect, hud_safe, scale2, playernum, ps) {
1073
+ CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale2, playernum, ps);
413
1074
  }
414
1075
  function TouchPics() {
415
1076
  CG_TouchPics();
@@ -436,10 +1097,10 @@ function Pmove(pmove) {
436
1097
  }
437
1098
  function ParseConfigString(i, s) {
438
1099
  }
439
- function ParseCenterPrint(str, isplit, instant) {
1100
+ function ParseCenterPrint(str2, isplit, instant) {
440
1101
  if (!cgi2) return;
441
1102
  const messageSystem2 = CG_GetMessageSystem();
442
- messageSystem2.setCenterPrint(str, cgi2.CL_ClientTime());
1103
+ messageSystem2.setCenterPrint(str2, cgi2.CL_ClientTime());
443
1104
  }
444
1105
  function NotifyMessage(isplit, msg, is_chat) {
445
1106
  if (!cgi2) return;
@@ -494,6 +1155,11 @@ function GetCGameAPI(imports) {
494
1155
  };
495
1156
  }
496
1157
 
1158
+ exports.ClientPrediction = ClientPrediction;
497
1159
  exports.GetCGameAPI = GetCGameAPI;
1160
+ exports.ViewEffects = ViewEffects;
1161
+ exports.defaultPredictionState = defaultPredictionState;
1162
+ exports.interpolatePredictionState = interpolatePredictionState;
1163
+ exports.updateCamera = updateCamera;
498
1164
  //# sourceMappingURL=index.cjs.map
499
1165
  //# sourceMappingURL=index.cjs.map