quake2ts 0.0.298 → 0.0.301

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 (44) hide show
  1. package/package.json +1 -1
  2. package/packages/cgame/dist/index.cjs +52 -1
  3. package/packages/cgame/dist/index.cjs.map +1 -1
  4. package/packages/cgame/dist/index.d.cts +7 -0
  5. package/packages/cgame/dist/index.d.ts +7 -0
  6. package/packages/cgame/dist/index.js +53 -2
  7. package/packages/cgame/dist/index.js.map +1 -1
  8. package/packages/client/dist/browser/index.global.js +13 -13
  9. package/packages/client/dist/browser/index.global.js.map +1 -1
  10. package/packages/client/dist/cjs/index.cjs +166 -10
  11. package/packages/client/dist/cjs/index.cjs.map +1 -1
  12. package/packages/client/dist/esm/index.js +161 -5
  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/cgameBridge.d.ts.map +1 -1
  16. package/packages/client/dist/types/index.d.ts.map +1 -1
  17. package/packages/client/dist/types/input/controller.d.ts +1 -0
  18. package/packages/client/dist/types/input/controller.d.ts.map +1 -1
  19. package/packages/client/dist/types/net/connection.d.ts +3 -0
  20. package/packages/client/dist/types/net/connection.d.ts.map +1 -1
  21. package/packages/client/dist/types/ui/demo-controls.d.ts +11 -0
  22. package/packages/client/dist/types/ui/demo-controls.d.ts.map +1 -0
  23. package/packages/engine/dist/browser/index.global.js.map +1 -1
  24. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  25. package/packages/engine/dist/esm/index.js.map +1 -1
  26. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  27. package/packages/game/dist/browser/index.global.js +4 -4
  28. package/packages/game/dist/browser/index.global.js.map +1 -1
  29. package/packages/game/dist/cjs/index.cjs +17 -10
  30. package/packages/game/dist/cjs/index.cjs.map +1 -1
  31. package/packages/game/dist/esm/index.js +17 -10
  32. package/packages/game/dist/esm/index.js.map +1 -1
  33. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  34. package/packages/game/dist/types/entities/gibs.d.ts +1 -1
  35. package/packages/game/dist/types/entities/gibs.d.ts.map +1 -1
  36. package/packages/server/dist/index.cjs +9 -2
  37. package/packages/server/dist/index.js +9 -2
  38. package/packages/shared/dist/browser/index.global.js.map +1 -1
  39. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  40. package/packages/shared/dist/esm/index.js.map +1 -1
  41. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  42. package/packages/shared/dist/types/protocol/usercmd.d.ts +3 -0
  43. package/packages/shared/dist/types/protocol/usercmd.d.ts.map +1 -1
  44. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -17,6 +17,9 @@ interface CGameImport {
17
17
  TagFree(ptr: unknown): void;
18
18
  FreeTags(tag: number): void;
19
19
  cvar(name: string, value: string, flags: number): unknown;
20
+ Cvar_Get(name: string, value: string, flags: number): {
21
+ value: number;
22
+ };
20
23
  cvar_set(name: string, value: string): void;
21
24
  cvar_forceset(name: string, value: string): void;
22
25
  CL_FrameValid(): boolean;
@@ -119,9 +122,13 @@ declare class ClientPrediction {
119
122
  private baseFrame;
120
123
  private commands;
121
124
  private predicted;
125
+ private predictionError;
122
126
  constructor(trace: PmoveTraceFn, pointContents: (p: Vec3) => number, settings?: Partial<PredictionSettings>);
123
127
  setAuthoritative(frame: GameFrameResult<PredictionState>): PredictionState;
128
+ getPredictionError(): Vec3;
129
+ decayError(frametime: number): void;
124
130
  enqueueCommand(cmd: UserCommand): PredictionState;
131
+ getCommand(sequence: number): UserCommand | undefined;
125
132
  getPredictedState(): PredictionState;
126
133
  private recompute;
127
134
  }
@@ -17,6 +17,9 @@ interface CGameImport {
17
17
  TagFree(ptr: unknown): void;
18
18
  FreeTags(tag: number): void;
19
19
  cvar(name: string, value: string, flags: number): unknown;
20
+ Cvar_Get(name: string, value: string, flags: number): {
21
+ value: number;
22
+ };
20
23
  cvar_set(name: string, value: string): void;
21
24
  cvar_forceset(name: string, value: string): void;
22
25
  CL_FrameValid(): boolean;
@@ -119,9 +122,13 @@ declare class ClientPrediction {
119
122
  private baseFrame;
120
123
  private commands;
121
124
  private predicted;
125
+ private predictionError;
122
126
  constructor(trace: PmoveTraceFn, pointContents: (p: Vec3) => number, settings?: Partial<PredictionSettings>);
123
127
  setAuthoritative(frame: GameFrameResult<PredictionState>): PredictionState;
128
+ getPredictionError(): Vec3;
129
+ decayError(frametime: number): void;
124
130
  enqueueCommand(cmd: UserCommand): PredictionState;
131
+ getCommand(sequence: number): UserCommand | undefined;
125
132
  getPredictedState(): PredictionState;
126
133
  private recompute;
127
134
  }
@@ -1,4 +1,4 @@
1
- import { angleVectors, clampViewAngles, ZERO_VEC3, hasPmFlag, PmFlag, dotVec3, PmType, WaterLevel, angleMod, applyPmove, PlayerStat, PowerupId, G_GetPowerupStat, WEAPON_WHEEL_ORDER, WEAPON_AMMO_MAP, G_GetAmmoStat, ConfigStringIndex, MAX_MODELS, MAX_SOUNDS, MAX_IMAGES } from '@quake2ts/shared';
1
+ import { angleVectors, clampViewAngles, ZERO_VEC3, hasPmFlag, PmFlag, dotVec3, PmType, WaterLevel, subtractVec3, lengthVec3, scaleVec3, angleMod, applyPmove, PlayerStat, PowerupId, G_GetPowerupStat, WEAPON_WHEEL_ORDER, WEAPON_AMMO_MAP, G_GetAmmoStat, ConfigStringIndex, MAX_MODELS, MAX_SOUNDS, MAX_IMAGES } from '@quake2ts/shared';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
4
  var __export = (target, all) => {
@@ -928,6 +928,7 @@ var DEFAULTS = {
928
928
  };
929
929
  var DEFAULT_GRAVITY = 800;
930
930
  var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
931
+ var CMD_BACKUP = 64;
931
932
  function defaultPredictionState() {
932
933
  return {
933
934
  origin: ZERO_VEC32,
@@ -1056,6 +1057,7 @@ var ClientPrediction = class {
1056
1057
  };
1057
1058
  this.commands = [];
1058
1059
  this.predicted = defaultPredictionState();
1060
+ this.predictionError = ZERO_VEC32;
1059
1061
  this.settings = { ...DEFAULTS, ...settings };
1060
1062
  this.trace = trace;
1061
1063
  this.pointContents = pointContents;
@@ -1063,14 +1065,57 @@ var ClientPrediction = class {
1063
1065
  }
1064
1066
  setAuthoritative(frame) {
1065
1067
  const normalized = normalizeState(frame.state);
1068
+ if (frame.frame <= this.baseFrame.frame) {
1069
+ return this.predicted;
1070
+ }
1071
+ let predictedAtFrame;
1072
+ const relevantCommands = this.commands.filter((c) => c.sequence <= frame.frame && c.sequence > this.baseFrame.frame);
1073
+ if (relevantCommands.length > 0 || this.baseFrame.frame === frame.frame) {
1074
+ let tempState = normalizeState(this.baseFrame.state);
1075
+ for (const cmd of relevantCommands) {
1076
+ tempState = simulateCommand(tempState, cmd, this.settings, this.trace, this.pointContents);
1077
+ }
1078
+ predictedAtFrame = tempState;
1079
+ }
1080
+ if (predictedAtFrame) {
1081
+ const error = subtractVec3(predictedAtFrame.origin, normalized.origin);
1082
+ const errorLen = lengthVec3(error);
1083
+ if (errorLen > 10) {
1084
+ this.predictionError = ZERO_VEC32;
1085
+ } else if (errorLen > 0.1) {
1086
+ this.predictionError = error;
1087
+ } else {
1088
+ this.predictionError = ZERO_VEC32;
1089
+ }
1090
+ } else {
1091
+ this.predictionError = ZERO_VEC32;
1092
+ }
1066
1093
  this.baseFrame = { ...frame, state: normalized };
1067
- this.commands = this.commands.filter((cmd) => (cmd.serverFrame ?? Number.MAX_SAFE_INTEGER) > frame.frame);
1094
+ this.commands = this.commands.filter((cmd) => cmd.sequence > frame.frame);
1068
1095
  return this.recompute();
1069
1096
  }
1097
+ getPredictionError() {
1098
+ return this.predictionError;
1099
+ }
1100
+ // Decay error over time - usually called once per client frame
1101
+ decayError(frametime) {
1102
+ const len2 = lengthVec3(this.predictionError);
1103
+ if (len2 > 0) {
1104
+ const decay = len2 * 10 * frametime;
1105
+ const scale2 = Math.max(0, len2 - decay) / len2;
1106
+ this.predictionError = scaleVec3(this.predictionError, scale2);
1107
+ }
1108
+ }
1070
1109
  enqueueCommand(cmd) {
1071
1110
  this.commands.push(cmd);
1111
+ if (this.commands.length > CMD_BACKUP) {
1112
+ this.commands.shift();
1113
+ }
1072
1114
  return this.recompute();
1073
1115
  }
1116
+ getCommand(sequence) {
1117
+ return this.commands.find((c) => c.sequence === sequence);
1118
+ }
1074
1119
  getPredictedState() {
1075
1120
  return this.predicted;
1076
1121
  }
@@ -1086,6 +1131,7 @@ var ClientPrediction = class {
1086
1131
 
1087
1132
  // src/index.ts
1088
1133
  var cgi2 = null;
1134
+ var cg_predict = null;
1089
1135
  function Init() {
1090
1136
  if (!cgi2) {
1091
1137
  console.error("CGame Init: cgame imports not set");
@@ -1093,6 +1139,8 @@ function Init() {
1093
1139
  }
1094
1140
  cgi2.Com_Print("===== CGame Initialization =====\n");
1095
1141
  CG_InitScreen(cgi2);
1142
+ cg_predict = cgi2.Cvar_Get("cg_predict", "1", 0);
1143
+ cgi2.Cvar_Get("cg_showmiss", "0", 0);
1096
1144
  cgi2.Com_Print("CGame initialized\n");
1097
1145
  }
1098
1146
  function Shutdown() {
@@ -1154,6 +1202,9 @@ function Pmove(pmove) {
1154
1202
  if (!pm || !pm.s || !pm.cmd || !cgi2) {
1155
1203
  return;
1156
1204
  }
1205
+ if (cg_predict && cg_predict.value === 0) {
1206
+ return;
1207
+ }
1157
1208
  const traceAdapter = (start, end, mins, maxs) => {
1158
1209
  const zero2 = { x: 0, y: 0, z: 0 };
1159
1210
  return cgi2.PM_Trace(