quake2ts 0.0.7

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 (149) hide show
  1. package/apps/viewer/dist/browser/index.global.js +2 -0
  2. package/apps/viewer/dist/browser/index.global.js.map +1 -0
  3. package/apps/viewer/dist/cjs/index.cjs +1087 -0
  4. package/apps/viewer/dist/cjs/index.cjs.map +1 -0
  5. package/apps/viewer/dist/esm/index.js +1060 -0
  6. package/apps/viewer/dist/esm/index.js.map +1 -0
  7. package/apps/viewer/dist/tsconfig.tsbuildinfo +1 -0
  8. package/apps/viewer/dist/types/index.d.ts +7 -0
  9. package/apps/viewer/dist/types/index.d.ts.map +1 -0
  10. package/package.json +107 -0
  11. package/packages/client/dist/browser/index.global.js +2 -0
  12. package/packages/client/dist/browser/index.global.js.map +1 -0
  13. package/packages/client/dist/cjs/index.cjs +57 -0
  14. package/packages/client/dist/cjs/index.cjs.map +1 -0
  15. package/packages/client/dist/esm/index.js +32 -0
  16. package/packages/client/dist/esm/index.js.map +1 -0
  17. package/packages/client/dist/tsconfig.tsbuildinfo +1 -0
  18. package/packages/client/dist/types/index.d.ts +14 -0
  19. package/packages/client/dist/types/index.d.ts.map +1 -0
  20. package/packages/engine/dist/browser/index.global.js +2 -0
  21. package/packages/engine/dist/browser/index.global.js.map +1 -0
  22. package/packages/engine/dist/cjs/index.cjs +1823 -0
  23. package/packages/engine/dist/cjs/index.cjs.map +1 -0
  24. package/packages/engine/dist/esm/index.js +1764 -0
  25. package/packages/engine/dist/esm/index.js.map +1 -0
  26. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -0
  27. package/packages/engine/dist/types/assets/browserIngestion.d.ts +7 -0
  28. package/packages/engine/dist/types/assets/browserIngestion.d.ts.map +1 -0
  29. package/packages/engine/dist/types/assets/bsp.d.ts +157 -0
  30. package/packages/engine/dist/types/assets/bsp.d.ts.map +1 -0
  31. package/packages/engine/dist/types/assets/cache.d.ts +17 -0
  32. package/packages/engine/dist/types/assets/cache.d.ts.map +1 -0
  33. package/packages/engine/dist/types/assets/ingestion.d.ts +31 -0
  34. package/packages/engine/dist/types/assets/ingestion.d.ts.map +1 -0
  35. package/packages/engine/dist/types/assets/md2.d.ts +73 -0
  36. package/packages/engine/dist/types/assets/md2.d.ts.map +1 -0
  37. package/packages/engine/dist/types/assets/pak.d.ts +28 -0
  38. package/packages/engine/dist/types/assets/pak.d.ts.map +1 -0
  39. package/packages/engine/dist/types/assets/vfs.d.ts +23 -0
  40. package/packages/engine/dist/types/assets/vfs.d.ts.map +1 -0
  41. package/packages/engine/dist/types/configstrings.d.ts +34 -0
  42. package/packages/engine/dist/types/configstrings.d.ts.map +1 -0
  43. package/packages/engine/dist/types/cvars.d.ts +43 -0
  44. package/packages/engine/dist/types/cvars.d.ts.map +1 -0
  45. package/packages/engine/dist/types/host.d.ts +42 -0
  46. package/packages/engine/dist/types/host.d.ts.map +1 -0
  47. package/packages/engine/dist/types/index.d.ts +37 -0
  48. package/packages/engine/dist/types/index.d.ts.map +1 -0
  49. package/packages/engine/dist/types/loop.d.ts +40 -0
  50. package/packages/engine/dist/types/loop.d.ts.map +1 -0
  51. package/packages/engine/dist/types/render/bsp.d.ts +49 -0
  52. package/packages/engine/dist/types/render/bsp.d.ts.map +1 -0
  53. package/packages/engine/dist/types/render/context.d.ts +36 -0
  54. package/packages/engine/dist/types/render/context.d.ts.map +1 -0
  55. package/packages/engine/dist/types/render/resources.d.ts +56 -0
  56. package/packages/engine/dist/types/render/resources.d.ts.map +1 -0
  57. package/packages/engine/dist/types/render/shaderProgram.d.ts +18 -0
  58. package/packages/engine/dist/types/render/shaderProgram.d.ts.map +1 -0
  59. package/packages/engine/dist/types/runtime.d.ts +15 -0
  60. package/packages/engine/dist/types/runtime.d.ts.map +1 -0
  61. package/packages/game/dist/browser/index.global.js +2 -0
  62. package/packages/game/dist/browser/index.global.js.map +1 -0
  63. package/packages/game/dist/cjs/index.cjs +758 -0
  64. package/packages/game/dist/cjs/index.cjs.map +1 -0
  65. package/packages/game/dist/esm/index.js +725 -0
  66. package/packages/game/dist/esm/index.js.map +1 -0
  67. package/packages/game/dist/tsconfig.tsbuildinfo +1 -0
  68. package/packages/game/dist/types/entities/entity.d.ts +92 -0
  69. package/packages/game/dist/types/entities/entity.d.ts.map +1 -0
  70. package/packages/game/dist/types/entities/index.d.ts +3 -0
  71. package/packages/game/dist/types/entities/index.d.ts.map +1 -0
  72. package/packages/game/dist/types/entities/pool.d.ts +18 -0
  73. package/packages/game/dist/types/entities/pool.d.ts.map +1 -0
  74. package/packages/game/dist/types/entities/system.d.ts +18 -0
  75. package/packages/game/dist/types/entities/system.d.ts.map +1 -0
  76. package/packages/game/dist/types/entities/thinkScheduler.d.ts +8 -0
  77. package/packages/game/dist/types/entities/thinkScheduler.d.ts.map +1 -0
  78. package/packages/game/dist/types/index.d.ts +26 -0
  79. package/packages/game/dist/types/index.d.ts.map +1 -0
  80. package/packages/game/dist/types/level.d.ts +14 -0
  81. package/packages/game/dist/types/level.d.ts.map +1 -0
  82. package/packages/game/dist/types/loop.d.ts +29 -0
  83. package/packages/game/dist/types/loop.d.ts.map +1 -0
  84. package/packages/shared/dist/browser/index.global.js +2 -0
  85. package/packages/shared/dist/browser/index.global.js.map +1 -0
  86. package/packages/shared/dist/cjs/index.cjs +2793 -0
  87. package/packages/shared/dist/cjs/index.cjs.map +1 -0
  88. package/packages/shared/dist/esm/index.js +2594 -0
  89. package/packages/shared/dist/esm/index.js.map +1 -0
  90. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -0
  91. package/packages/shared/dist/types/bsp/collision.d.ts +112 -0
  92. package/packages/shared/dist/types/bsp/collision.d.ts.map +1 -0
  93. package/packages/shared/dist/types/bsp/contents.d.ts +71 -0
  94. package/packages/shared/dist/types/bsp/contents.d.ts.map +1 -0
  95. package/packages/shared/dist/types/index.d.ts +25 -0
  96. package/packages/shared/dist/types/index.d.ts.map +1 -0
  97. package/packages/shared/dist/types/math/angles.d.ts +17 -0
  98. package/packages/shared/dist/types/math/angles.d.ts.map +1 -0
  99. package/packages/shared/dist/types/math/color.d.ts +12 -0
  100. package/packages/shared/dist/types/math/color.d.ts.map +1 -0
  101. package/packages/shared/dist/types/math/random.d.ts +48 -0
  102. package/packages/shared/dist/types/math/random.d.ts.map +1 -0
  103. package/packages/shared/dist/types/math/vec3.d.ts +76 -0
  104. package/packages/shared/dist/types/math/vec3.d.ts.map +1 -0
  105. package/packages/shared/dist/types/pmove/categorize.d.ts +36 -0
  106. package/packages/shared/dist/types/pmove/categorize.d.ts.map +1 -0
  107. package/packages/shared/dist/types/pmove/constants.d.ts +75 -0
  108. package/packages/shared/dist/types/pmove/constants.d.ts.map +1 -0
  109. package/packages/shared/dist/types/pmove/currents.d.ts +58 -0
  110. package/packages/shared/dist/types/pmove/currents.d.ts.map +1 -0
  111. package/packages/shared/dist/types/pmove/dimensions.d.ts +14 -0
  112. package/packages/shared/dist/types/pmove/dimensions.d.ts.map +1 -0
  113. package/packages/shared/dist/types/pmove/duck.d.ts +39 -0
  114. package/packages/shared/dist/types/pmove/duck.d.ts.map +1 -0
  115. package/packages/shared/dist/types/pmove/fly.d.ts +34 -0
  116. package/packages/shared/dist/types/pmove/fly.d.ts.map +1 -0
  117. package/packages/shared/dist/types/pmove/jump.d.ts +26 -0
  118. package/packages/shared/dist/types/pmove/jump.d.ts.map +1 -0
  119. package/packages/shared/dist/types/pmove/move.d.ts +58 -0
  120. package/packages/shared/dist/types/pmove/move.d.ts.map +1 -0
  121. package/packages/shared/dist/types/pmove/pmove.d.ts +36 -0
  122. package/packages/shared/dist/types/pmove/pmove.d.ts.map +1 -0
  123. package/packages/shared/dist/types/pmove/slide.d.ts +63 -0
  124. package/packages/shared/dist/types/pmove/slide.d.ts.map +1 -0
  125. package/packages/shared/dist/types/pmove/snap.d.ts +40 -0
  126. package/packages/shared/dist/types/pmove/snap.d.ts.map +1 -0
  127. package/packages/shared/dist/types/pmove/special.d.ts +39 -0
  128. package/packages/shared/dist/types/pmove/special.d.ts.map +1 -0
  129. package/packages/shared/dist/types/pmove/stuck.d.ts +21 -0
  130. package/packages/shared/dist/types/pmove/stuck.d.ts.map +1 -0
  131. package/packages/shared/dist/types/pmove/types.d.ts +48 -0
  132. package/packages/shared/dist/types/pmove/types.d.ts.map +1 -0
  133. package/packages/shared/dist/types/pmove/view.d.ts +19 -0
  134. package/packages/shared/dist/types/pmove/view.d.ts.map +1 -0
  135. package/packages/shared/dist/types/pmove/water.d.ts +21 -0
  136. package/packages/shared/dist/types/pmove/water.d.ts.map +1 -0
  137. package/packages/shared/dist/types/protocol/configstrings.d.ts +51 -0
  138. package/packages/shared/dist/types/protocol/configstrings.d.ts.map +1 -0
  139. package/packages/shared/dist/types/protocol/cvar.d.ts +15 -0
  140. package/packages/shared/dist/types/protocol/cvar.d.ts.map +1 -0
  141. package/packages/tools/dist/browser/index.global.js +2 -0
  142. package/packages/tools/dist/browser/index.global.js.map +1 -0
  143. package/packages/tools/dist/cjs/index.cjs +33 -0
  144. package/packages/tools/dist/cjs/index.cjs.map +1 -0
  145. package/packages/tools/dist/esm/index.js +8 -0
  146. package/packages/tools/dist/esm/index.js.map +1 -0
  147. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -0
  148. package/packages/tools/dist/types/index.d.ts +7 -0
  149. package/packages/tools/dist/types/index.d.ts.map +1 -0
@@ -0,0 +1,2594 @@
1
+ // src/math/vec3.ts
2
+ var ZERO_VEC3 = { x: 0, y: 0, z: 0 };
3
+ var STOP_EPSILON = 0.1;
4
+ var DEG_TO_RAD = Math.PI / 180;
5
+ function addVec3(a, b) {
6
+ return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
7
+ }
8
+ function subtractVec3(a, b) {
9
+ return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
10
+ }
11
+ function multiplyVec3(a, b) {
12
+ return { x: a.x * b.x, y: a.y * b.y, z: a.z * b.z };
13
+ }
14
+ function scaleVec3(a, scalar) {
15
+ return { x: a.x * scalar, y: a.y * scalar, z: a.z * scalar };
16
+ }
17
+ function negateVec3(a) {
18
+ return scaleVec3(a, -1);
19
+ }
20
+ function dotVec3(a, b) {
21
+ return a.x * b.x + a.y * b.y + a.z * b.z;
22
+ }
23
+ function crossVec3(a, b) {
24
+ return {
25
+ x: a.y * b.z - a.z * b.y,
26
+ y: a.z * b.x - a.x * b.z,
27
+ z: a.x * b.y - a.y * b.x
28
+ };
29
+ }
30
+ function lengthSquaredVec3(a) {
31
+ return dotVec3(a, a);
32
+ }
33
+ function lengthVec3(a) {
34
+ return Math.sqrt(lengthSquaredVec3(a));
35
+ }
36
+ function normalizeVec3(a) {
37
+ const len = lengthVec3(a);
38
+ return len === 0 ? a : scaleVec3(a, 1 / len);
39
+ }
40
+ function projectPointOnPlane(point, normal) {
41
+ const invDenom = 1 / dotVec3(normal, normal);
42
+ const d = dotVec3(normal, point) * invDenom;
43
+ return subtractVec3(point, scaleVec3(normal, invDenom * d));
44
+ }
45
+ function perpendicularVec3(src) {
46
+ let pos = 0;
47
+ let minElement = Math.abs(src.x);
48
+ if (Math.abs(src.y) < minElement) {
49
+ pos = 1;
50
+ minElement = Math.abs(src.y);
51
+ }
52
+ if (Math.abs(src.z) < minElement) {
53
+ pos = 2;
54
+ }
55
+ const axis = pos === 0 ? { x: 1, y: 0, z: 0 } : pos === 1 ? { x: 0, y: 1, z: 0 } : { x: 0, y: 0, z: 1 };
56
+ return normalizeVec3(projectPointOnPlane(axis, src));
57
+ }
58
+ function closestPointToBox(point, mins, maxs) {
59
+ return {
60
+ x: point.x < mins.x ? mins.x : point.x > maxs.x ? maxs.x : point.x,
61
+ y: point.y < mins.y ? mins.y : point.y > maxs.y ? maxs.y : point.y,
62
+ z: point.z < mins.z ? mins.z : point.z > maxs.z ? maxs.z : point.z
63
+ };
64
+ }
65
+ function distanceBetweenBoxesSquared(aMins, aMaxs, bMins, bMaxs) {
66
+ let lengthSq = 0;
67
+ if (aMaxs.x < bMins.x) {
68
+ const d = aMaxs.x - bMins.x;
69
+ lengthSq += d * d;
70
+ } else if (aMins.x > bMaxs.x) {
71
+ const d = aMins.x - bMaxs.x;
72
+ lengthSq += d * d;
73
+ }
74
+ if (aMaxs.y < bMins.y) {
75
+ const d = aMaxs.y - bMins.y;
76
+ lengthSq += d * d;
77
+ } else if (aMins.y > bMaxs.y) {
78
+ const d = aMins.y - bMaxs.y;
79
+ lengthSq += d * d;
80
+ }
81
+ if (aMaxs.z < bMins.z) {
82
+ const d = aMaxs.z - bMins.z;
83
+ lengthSq += d * d;
84
+ } else if (aMins.z > bMaxs.z) {
85
+ const d = aMins.z - bMaxs.z;
86
+ lengthSq += d * d;
87
+ }
88
+ return lengthSq;
89
+ }
90
+ function createEmptyBounds3() {
91
+ return {
92
+ mins: { x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
93
+ maxs: { x: Number.NEGATIVE_INFINITY, y: Number.NEGATIVE_INFINITY, z: Number.NEGATIVE_INFINITY }
94
+ };
95
+ }
96
+ function addPointToBounds(point, bounds) {
97
+ return {
98
+ mins: {
99
+ x: Math.min(bounds.mins.x, point.x),
100
+ y: Math.min(bounds.mins.y, point.y),
101
+ z: Math.min(bounds.mins.z, point.z)
102
+ },
103
+ maxs: {
104
+ x: Math.max(bounds.maxs.x, point.x),
105
+ y: Math.max(bounds.maxs.y, point.y),
106
+ z: Math.max(bounds.maxs.z, point.z)
107
+ }
108
+ };
109
+ }
110
+ function boxesIntersect(a, b) {
111
+ return a.mins.x <= b.maxs.x && a.maxs.x >= b.mins.x && a.mins.y <= b.maxs.y && a.maxs.y >= b.mins.y && a.mins.z <= b.maxs.z && a.maxs.z >= b.mins.z;
112
+ }
113
+ function clipVelocityVec3(inVel, normal, overbounce) {
114
+ const backoff = dotVec3(inVel, normal) * overbounce;
115
+ let outX = inVel.x - normal.x * backoff;
116
+ let outY = inVel.y - normal.y * backoff;
117
+ let outZ = inVel.z - normal.z * backoff;
118
+ if (outX > -STOP_EPSILON && outX < STOP_EPSILON) {
119
+ outX = 0;
120
+ }
121
+ if (outY > -STOP_EPSILON && outY < STOP_EPSILON) {
122
+ outY = 0;
123
+ }
124
+ if (outZ > -STOP_EPSILON && outZ < STOP_EPSILON) {
125
+ outZ = 0;
126
+ }
127
+ return { x: outX, y: outY, z: outZ };
128
+ }
129
+ function clipVelocityAgainstPlanes(velocity, planes, overbounce, primalVelocity) {
130
+ if (planes.length === 0) {
131
+ return velocity;
132
+ }
133
+ let working = velocity;
134
+ for (let i = 0; i < planes.length; i++) {
135
+ working = clipVelocityVec3(working, planes[i], overbounce);
136
+ let j = 0;
137
+ for (; j < planes.length; j++) {
138
+ if (j === i) {
139
+ continue;
140
+ }
141
+ if (dotVec3(working, planes[j]) < 0) {
142
+ break;
143
+ }
144
+ }
145
+ if (j === planes.length) {
146
+ if (primalVelocity && dotVec3(working, primalVelocity) <= 0) {
147
+ return ZERO_VEC3;
148
+ }
149
+ return working;
150
+ }
151
+ }
152
+ if (planes.length === 2) {
153
+ const dir = crossVec3(planes[0], planes[1]);
154
+ const d = dotVec3(dir, velocity);
155
+ const creaseVelocity = scaleVec3(dir, d);
156
+ if (primalVelocity && dotVec3(creaseVelocity, primalVelocity) <= 0) {
157
+ return ZERO_VEC3;
158
+ }
159
+ return creaseVelocity;
160
+ }
161
+ if (primalVelocity && dotVec3(working, primalVelocity) <= 0) {
162
+ return ZERO_VEC3;
163
+ }
164
+ return ZERO_VEC3;
165
+ }
166
+ function slideClipVelocityVec3(inVel, normal, overbounce) {
167
+ return clipVelocityVec3(inVel, normal, overbounce);
168
+ }
169
+ function projectSourceVec3(point, distance, forward, right) {
170
+ return {
171
+ x: point.x + forward.x * distance.x + right.x * distance.y,
172
+ y: point.y + forward.y * distance.x + right.y * distance.y,
173
+ z: point.z + forward.z * distance.x + right.z * distance.y + distance.z
174
+ };
175
+ }
176
+ function projectSourceVec3WithUp(point, distance, forward, right, up) {
177
+ return {
178
+ x: point.x + forward.x * distance.x + right.x * distance.y + up.x * distance.z,
179
+ y: point.y + forward.y * distance.x + right.y * distance.y + up.y * distance.z,
180
+ z: point.z + forward.z * distance.x + right.z * distance.y + up.z * distance.z
181
+ };
182
+ }
183
+ function slerpVec3(from, to, t) {
184
+ const dot = dotVec3(from, to);
185
+ let aFactor;
186
+ let bFactor;
187
+ if (Math.abs(dot) > 0.9995) {
188
+ aFactor = 1 - t;
189
+ bFactor = t;
190
+ } else {
191
+ const ang = Math.acos(dot);
192
+ const sinOmega = Math.sin(ang);
193
+ const sinAOmega = Math.sin((1 - t) * ang);
194
+ const sinBOmega = Math.sin(t * ang);
195
+ aFactor = sinAOmega / sinOmega;
196
+ bFactor = sinBOmega / sinOmega;
197
+ }
198
+ return {
199
+ x: from.x * aFactor + to.x * bFactor,
200
+ y: from.y * aFactor + to.y * bFactor,
201
+ z: from.z * aFactor + to.z * bFactor
202
+ };
203
+ }
204
+ function concatRotationMatrices(a, b) {
205
+ const row = (rowIndex) => [
206
+ a[rowIndex][0] * b[0][0] + a[rowIndex][1] * b[1][0] + a[rowIndex][2] * b[2][0],
207
+ a[rowIndex][0] * b[0][1] + a[rowIndex][1] * b[1][1] + a[rowIndex][2] * b[2][1],
208
+ a[rowIndex][0] * b[0][2] + a[rowIndex][1] * b[1][2] + a[rowIndex][2] * b[2][2]
209
+ ];
210
+ const result = [row(0), row(1), row(2)];
211
+ return result;
212
+ }
213
+ function rotatePointAroundVector(dir, point, degrees) {
214
+ const axisLength = lengthVec3(dir);
215
+ if (axisLength === 0) {
216
+ return point;
217
+ }
218
+ const vf = normalizeVec3(dir);
219
+ const vr = perpendicularVec3(vf);
220
+ const vup = crossVec3(vr, vf);
221
+ const m = [
222
+ [vr.x, vup.x, vf.x],
223
+ [vr.y, vup.y, vf.y],
224
+ [vr.z, vup.z, vf.z]
225
+ ];
226
+ const im = [
227
+ [m[0][0], m[1][0], m[2][0]],
228
+ [m[0][1], m[1][1], m[2][1]],
229
+ [m[0][2], m[1][2], m[2][2]]
230
+ ];
231
+ const radians = degrees * DEG_TO_RAD;
232
+ const cos = Math.cos(radians);
233
+ const sin = Math.sin(radians);
234
+ const zrot = [
235
+ [cos, sin, 0],
236
+ [-sin, cos, 0],
237
+ [0, 0, 1]
238
+ ];
239
+ const rot = concatRotationMatrices(concatRotationMatrices(m, zrot), im);
240
+ return {
241
+ x: rot[0][0] * point.x + rot[0][1] * point.y + rot[0][2] * point.z,
242
+ y: rot[1][0] * point.x + rot[1][1] * point.y + rot[1][2] * point.z,
243
+ z: rot[2][0] * point.x + rot[2][1] * point.y + rot[2][2] * point.z
244
+ };
245
+ }
246
+
247
+ // src/math/angles.ts
248
+ var PITCH = 0;
249
+ var YAW = 1;
250
+ var ROLL = 2;
251
+ var DEG2RAD_FACTOR = Math.PI / 180;
252
+ var RAD2DEG_FACTOR = 180 / Math.PI;
253
+ function axisComponent(vec, axis) {
254
+ switch (axis) {
255
+ case PITCH:
256
+ return vec.x;
257
+ case YAW:
258
+ return vec.y;
259
+ case ROLL:
260
+ default:
261
+ return vec.z;
262
+ }
263
+ }
264
+ function degToRad(degrees) {
265
+ return degrees * DEG2RAD_FACTOR;
266
+ }
267
+ function radToDeg(radians) {
268
+ return radians * RAD2DEG_FACTOR;
269
+ }
270
+ function lerpAngle(from, to, frac) {
271
+ let target = to;
272
+ if (target - from > 180) {
273
+ target -= 360;
274
+ } else if (target - from < -180) {
275
+ target += 360;
276
+ }
277
+ return from + frac * (target - from);
278
+ }
279
+ function angleMod(angle) {
280
+ const value = angle % 360;
281
+ return value < 0 ? 360 + value : value;
282
+ }
283
+ function angleVectors(angles) {
284
+ const yaw = degToRad(axisComponent(angles, YAW));
285
+ const pitch = degToRad(axisComponent(angles, PITCH));
286
+ const roll = degToRad(axisComponent(angles, ROLL));
287
+ const sy = Math.sin(yaw);
288
+ const cy = Math.cos(yaw);
289
+ const sp = Math.sin(pitch);
290
+ const cp = Math.cos(pitch);
291
+ const sr = Math.sin(roll);
292
+ const cr = Math.cos(roll);
293
+ const forward = {
294
+ x: cp * cy,
295
+ y: cp * sy,
296
+ z: -sp
297
+ };
298
+ const right = {
299
+ x: -sr * sp * cy - cr * -sy,
300
+ y: -sr * sp * sy - cr * cy,
301
+ z: -sr * cp
302
+ };
303
+ const up = {
304
+ x: cr * sp * cy - sr * -sy,
305
+ y: cr * sp * sy - sr * cy,
306
+ z: cr * cp
307
+ };
308
+ return { forward, right, up };
309
+ }
310
+ function vectorToYaw(vec) {
311
+ const pitch = axisComponent(vec, PITCH);
312
+ const yawAxis = axisComponent(vec, YAW);
313
+ if (pitch === 0) {
314
+ if (yawAxis === 0) {
315
+ return 0;
316
+ }
317
+ return yawAxis > 0 ? 90 : 270;
318
+ }
319
+ const yaw = radToDeg(Math.atan2(yawAxis, pitch));
320
+ return yaw < 0 ? yaw + 360 : yaw;
321
+ }
322
+ function vectorToAngles(vec) {
323
+ const x = vec.x;
324
+ const y = vec.y;
325
+ const z = vec.z;
326
+ if (y === 0 && x === 0) {
327
+ return { x: z > 0 ? -90 : -270, y: 0, z: 0 };
328
+ }
329
+ let yaw;
330
+ if (x) {
331
+ yaw = radToDeg(Math.atan2(y, x));
332
+ } else if (y > 0) {
333
+ yaw = 90;
334
+ } else {
335
+ yaw = 270;
336
+ }
337
+ if (yaw < 0) {
338
+ yaw += 360;
339
+ }
340
+ const forward = Math.sqrt(x * x + y * y);
341
+ let pitch = radToDeg(Math.atan2(z, forward));
342
+ if (pitch < 0) {
343
+ pitch += 360;
344
+ }
345
+ return { x: -pitch, y: yaw, z: 0 };
346
+ }
347
+
348
+ // src/math/color.ts
349
+ function addBlendColor(r, g, b, a, current) {
350
+ if (a <= 0) {
351
+ return current;
352
+ }
353
+ const oldR = current[0];
354
+ const oldG = current[1];
355
+ const oldB = current[2];
356
+ const oldA = current[3];
357
+ const a2 = oldA + (1 - oldA) * a;
358
+ if (a2 <= 0) {
359
+ return [0, 0, 0, 0];
360
+ }
361
+ const a3 = oldA / a2;
362
+ const newR = oldR * a3 + r * (1 - a3);
363
+ const newG = oldG * a3 + g * (1 - a3);
364
+ const newB = oldB * a3 + b * (1 - a3);
365
+ return [newR, newG, newB, a2];
366
+ }
367
+
368
+ // src/math/random.ts
369
+ var STATE_SIZE = 624;
370
+ var MIDDLE_WORD = 397;
371
+ var MATRIX_A = 2567483615;
372
+ var UPPER_MASK = 2147483648;
373
+ var LOWER_MASK = 2147483647;
374
+ var TWO_POW_32 = 4294967296;
375
+ var MersenneTwister19937 = class {
376
+ constructor(seed = 5489) {
377
+ this.state = new Uint32Array(STATE_SIZE);
378
+ this.index = STATE_SIZE;
379
+ this.seed(seed);
380
+ }
381
+ seed(seed) {
382
+ this.state[0] = seed >>> 0;
383
+ for (let i = 1; i < STATE_SIZE; i++) {
384
+ const prev = this.state[i - 1] ^ this.state[i - 1] >>> 30;
385
+ const next = Math.imul(prev >>> 0, 1812433253) + i;
386
+ this.state[i] = next >>> 0;
387
+ }
388
+ this.index = STATE_SIZE;
389
+ }
390
+ nextUint32() {
391
+ if (this.index >= STATE_SIZE) {
392
+ this.twist();
393
+ }
394
+ let y = this.state[this.index++];
395
+ y ^= y >>> 11;
396
+ y ^= y << 7 & 2636928640;
397
+ y ^= y << 15 & 4022730752;
398
+ y ^= y >>> 18;
399
+ return y >>> 0;
400
+ }
401
+ twist() {
402
+ for (let i = 0; i < STATE_SIZE; i++) {
403
+ const y = this.state[i] & UPPER_MASK | this.state[(i + 1) % STATE_SIZE] & LOWER_MASK;
404
+ let next = this.state[(i + MIDDLE_WORD) % STATE_SIZE] ^ y >>> 1;
405
+ if ((y & 1) !== 0) {
406
+ next ^= MATRIX_A;
407
+ }
408
+ this.state[i] = next >>> 0;
409
+ }
410
+ this.index = 0;
411
+ }
412
+ };
413
+ var RandomGenerator = class {
414
+ constructor(options = {}) {
415
+ this.mt = new MersenneTwister19937(options.seed);
416
+ }
417
+ /** Uniform float in [0, 1). */
418
+ frandom() {
419
+ return this.mt.nextUint32() / TWO_POW_32;
420
+ }
421
+ /** Uniform float in [min, max). */
422
+ frandomRange(minInclusive, maxExclusive) {
423
+ return minInclusive + (maxExclusive - minInclusive) * this.frandom();
424
+ }
425
+ /** Uniform float in [0, max). */
426
+ frandomMax(maxExclusive) {
427
+ return this.frandomRange(0, maxExclusive);
428
+ }
429
+ /** Uniform float in [-1, 1). */
430
+ crandom() {
431
+ return this.frandomRange(-1, 1);
432
+ }
433
+ /** Uniform float in (-1, 1). */
434
+ crandomOpen() {
435
+ const epsilon = Number.EPSILON;
436
+ return this.frandomRange(-1 + epsilon, 1);
437
+ }
438
+ /** Raw uint32 sample. */
439
+ irandomUint32() {
440
+ return this.mt.nextUint32();
441
+ }
442
+ /** Uniform integer in [min, max). */
443
+ irandomRange(minInclusive, maxExclusive) {
444
+ if (maxExclusive - minInclusive <= 1) {
445
+ return minInclusive;
446
+ }
447
+ const span = maxExclusive - minInclusive;
448
+ const limit = TWO_POW_32 - TWO_POW_32 % span;
449
+ let sample;
450
+ do {
451
+ sample = this.mt.nextUint32();
452
+ } while (sample >= limit);
453
+ return minInclusive + sample % span;
454
+ }
455
+ /** Uniform integer in [0, max). */
456
+ irandom(maxExclusive) {
457
+ if (maxExclusive <= 0) {
458
+ return 0;
459
+ }
460
+ return this.irandomRange(0, maxExclusive);
461
+ }
462
+ /** Uniform time in milliseconds [min, max). */
463
+ randomTimeRange(minMs, maxMs) {
464
+ if (maxMs <= minMs) {
465
+ return minMs;
466
+ }
467
+ return this.irandomRange(minMs, maxMs);
468
+ }
469
+ /** Uniform time in milliseconds [0, max). */
470
+ randomTime(maxMs) {
471
+ return this.irandom(maxMs);
472
+ }
473
+ randomIndex(container) {
474
+ return this.irandom(container.length);
475
+ }
476
+ };
477
+ function createRandomGenerator(options) {
478
+ return new RandomGenerator(options);
479
+ }
480
+
481
+ // src/bsp/contents.ts
482
+ var CONTENTS_NONE = 0;
483
+ var CONTENTS_SOLID = 1 << 0;
484
+ var CONTENTS_WINDOW = 1 << 1;
485
+ var CONTENTS_AUX = 1 << 2;
486
+ var CONTENTS_LAVA = 1 << 3;
487
+ var CONTENTS_SLIME = 1 << 4;
488
+ var CONTENTS_WATER = 1 << 5;
489
+ var CONTENTS_MIST = 1 << 6;
490
+ var CONTENTS_NO_WATERJUMP = 1 << 13;
491
+ var CONTENTS_PROJECTILECLIP = 1 << 14;
492
+ var CONTENTS_AREAPORTAL = 1 << 15;
493
+ var CONTENTS_PLAYERCLIP = 1 << 16;
494
+ var CONTENTS_MONSTERCLIP = 1 << 17;
495
+ var CONTENTS_CURRENT_0 = 1 << 18;
496
+ var CONTENTS_CURRENT_90 = 1 << 19;
497
+ var CONTENTS_CURRENT_180 = 1 << 20;
498
+ var CONTENTS_CURRENT_270 = 1 << 21;
499
+ var CONTENTS_CURRENT_UP = 1 << 22;
500
+ var CONTENTS_CURRENT_DOWN = 1 << 23;
501
+ var CONTENTS_ORIGIN = 1 << 24;
502
+ var CONTENTS_MONSTER = 1 << 25;
503
+ var CONTENTS_DEADMONSTER = 1 << 26;
504
+ var CONTENTS_DETAIL = 1 << 27;
505
+ var CONTENTS_TRANSLUCENT = 1 << 28;
506
+ var CONTENTS_LADDER = 1 << 29;
507
+ var CONTENTS_PLAYER = 1 << 30;
508
+ var CONTENTS_PROJECTILE = 1 << 31;
509
+ var LAST_VISIBLE_CONTENTS = CONTENTS_MIST;
510
+ var SURF_NONE = 0;
511
+ var SURF_LIGHT = 1 << 0;
512
+ var SURF_SLICK = 1 << 1;
513
+ var SURF_SKY = 1 << 2;
514
+ var SURF_WARP = 1 << 3;
515
+ var SURF_TRANS33 = 1 << 4;
516
+ var SURF_TRANS66 = 1 << 5;
517
+ var SURF_FLOWING = 1 << 6;
518
+ var SURF_NODRAW = 1 << 7;
519
+ var SURF_ALPHATEST = 1 << 25;
520
+ var SURF_N64_UV = 1 << 28;
521
+ var SURF_N64_SCROLL_X = 1 << 29;
522
+ var SURF_N64_SCROLL_Y = 1 << 30;
523
+ var SURF_N64_SCROLL_FLIP = 1 << 31;
524
+ var MASK_ALL = 4294967295;
525
+ var MASK_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
526
+ var MASK_PLAYERSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
527
+ var MASK_DEADSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
528
+ var MASK_MONSTERSOLID = CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
529
+ var MASK_WATER = CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME;
530
+ var MASK_OPAQUE = CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA;
531
+ var MASK_SHOT = CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER | CONTENTS_WINDOW | CONTENTS_DEADMONSTER;
532
+ var MASK_CURRENT = CONTENTS_CURRENT_0 | CONTENTS_CURRENT_90 | CONTENTS_CURRENT_180 | CONTENTS_CURRENT_270 | CONTENTS_CURRENT_UP | CONTENTS_CURRENT_DOWN;
533
+ var MASK_BLOCK_SIGHT = CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_MONSTER | CONTENTS_PLAYER;
534
+ var MASK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
535
+ var MASK_LADDER_NAV_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
536
+ var MASK_WALK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTERCLIP;
537
+ var MASK_PROJECTILE = MASK_SHOT | CONTENTS_PROJECTILECLIP;
538
+ function hasAllContents(mask, flags) {
539
+ return (mask & flags) === flags;
540
+ }
541
+ function hasAnyContents(mask, flags) {
542
+ return (mask & flags) !== 0;
543
+ }
544
+ function addContents(mask, flags) {
545
+ return mask | flags;
546
+ }
547
+ function removeContents(mask, flags) {
548
+ return mask & ~flags;
549
+ }
550
+ function hasSurfaceFlags(surface, flags) {
551
+ return (surface & flags) === flags;
552
+ }
553
+ function combineSurfaceFlags(...flags) {
554
+ let mask = SURF_NONE;
555
+ for (const flag of flags) {
556
+ mask |= flag;
557
+ }
558
+ return mask;
559
+ }
560
+
561
+ // src/bsp/collision.ts
562
+ var PlaneSide = /* @__PURE__ */ ((PlaneSide2) => {
563
+ PlaneSide2[PlaneSide2["FRONT"] = 1] = "FRONT";
564
+ PlaneSide2[PlaneSide2["BACK"] = 2] = "BACK";
565
+ PlaneSide2[PlaneSide2["CROSS"] = 3] = "CROSS";
566
+ return PlaneSide2;
567
+ })(PlaneSide || {});
568
+ var DIST_EPSILON = 0.03125;
569
+ function buildCollisionModel(lumps) {
570
+ const planes = lumps.planes.map((plane) => ({
571
+ ...plane,
572
+ signbits: computePlaneSignBits(plane.normal)
573
+ }));
574
+ const nodes = lumps.nodes.map((node) => ({
575
+ plane: planes[node.planenum],
576
+ children: node.children
577
+ }));
578
+ const brushes = lumps.brushes.map((brush) => {
579
+ const sides = lumps.brushSides.slice(brush.firstSide, brush.firstSide + brush.numSides).map((side) => ({
580
+ plane: planes[side.planenum],
581
+ surfaceFlags: side.surfaceFlags
582
+ }));
583
+ return {
584
+ contents: brush.contents,
585
+ sides,
586
+ checkcount: 0
587
+ };
588
+ });
589
+ const leaves = lumps.leaves.map((leaf) => ({
590
+ contents: leaf.contents,
591
+ cluster: leaf.cluster,
592
+ area: leaf.area,
593
+ firstLeafBrush: leaf.firstLeafBrush,
594
+ numLeafBrushes: leaf.numLeafBrushes
595
+ }));
596
+ const bmodels = lumps.bmodels.map((model) => ({
597
+ mins: model.mins,
598
+ maxs: model.maxs,
599
+ origin: model.origin,
600
+ headnode: model.headnode
601
+ }));
602
+ return {
603
+ planes,
604
+ nodes,
605
+ leaves,
606
+ brushes,
607
+ leafBrushes: lumps.leafBrushes,
608
+ bmodels
609
+ };
610
+ }
611
+ function computePlaneSignBits(normal) {
612
+ let bits = 0;
613
+ if (normal.x < 0) bits |= 1;
614
+ if (normal.y < 0) bits |= 2;
615
+ if (normal.z < 0) bits |= 4;
616
+ return bits;
617
+ }
618
+ function planeDistanceToPoint(plane, point) {
619
+ return plane.normal.x * point.x + plane.normal.y * point.y + plane.normal.z * point.z - plane.dist;
620
+ }
621
+ function pointOnPlaneSide(plane, point, epsilon = 0) {
622
+ const dist = planeDistanceToPoint(plane, point);
623
+ if (dist > epsilon) {
624
+ return 1 /* FRONT */;
625
+ }
626
+ if (dist < -epsilon) {
627
+ return 2 /* BACK */;
628
+ }
629
+ return 3 /* CROSS */;
630
+ }
631
+ function boxOnPlaneSide(mins, maxs, plane, epsilon = 0) {
632
+ let dist1;
633
+ let dist2;
634
+ switch (plane.signbits) {
635
+ case 0:
636
+ dist1 = plane.normal.x * maxs.x + plane.normal.y * maxs.y + plane.normal.z * maxs.z;
637
+ dist2 = plane.normal.x * mins.x + plane.normal.y * mins.y + plane.normal.z * mins.z;
638
+ break;
639
+ case 1:
640
+ dist1 = plane.normal.x * mins.x + plane.normal.y * maxs.y + plane.normal.z * maxs.z;
641
+ dist2 = plane.normal.x * maxs.x + plane.normal.y * mins.y + plane.normal.z * mins.z;
642
+ break;
643
+ case 2:
644
+ dist1 = plane.normal.x * maxs.x + plane.normal.y * mins.y + plane.normal.z * maxs.z;
645
+ dist2 = plane.normal.x * mins.x + plane.normal.y * maxs.y + plane.normal.z * mins.z;
646
+ break;
647
+ case 3:
648
+ dist1 = plane.normal.x * mins.x + plane.normal.y * mins.y + plane.normal.z * maxs.z;
649
+ dist2 = plane.normal.x * maxs.x + plane.normal.y * maxs.y + plane.normal.z * mins.z;
650
+ break;
651
+ case 4:
652
+ dist1 = plane.normal.x * maxs.x + plane.normal.y * maxs.y + plane.normal.z * mins.z;
653
+ dist2 = plane.normal.x * mins.x + plane.normal.y * mins.y + plane.normal.z * maxs.z;
654
+ break;
655
+ case 5:
656
+ dist1 = plane.normal.x * mins.x + plane.normal.y * maxs.y + plane.normal.z * mins.z;
657
+ dist2 = plane.normal.x * maxs.x + plane.normal.y * mins.y + plane.normal.z * maxs.z;
658
+ break;
659
+ case 6:
660
+ dist1 = plane.normal.x * maxs.x + plane.normal.y * mins.y + plane.normal.z * mins.z;
661
+ dist2 = plane.normal.x * mins.x + plane.normal.y * maxs.y + plane.normal.z * maxs.z;
662
+ break;
663
+ default:
664
+ dist1 = plane.normal.x * mins.x + plane.normal.y * mins.y + plane.normal.z * mins.z;
665
+ dist2 = plane.normal.x * maxs.x + plane.normal.y * maxs.y + plane.normal.z * maxs.z;
666
+ break;
667
+ }
668
+ let sides = 0;
669
+ if (dist1 - plane.dist >= -epsilon) sides = 1 /* FRONT */;
670
+ if (dist2 - plane.dist <= epsilon) sides |= 2 /* BACK */;
671
+ return sides;
672
+ }
673
+ function pointInsideBrush(point, brush, epsilon = DIST_EPSILON) {
674
+ for (const side of brush.sides) {
675
+ const dist = planeDistanceToPoint(side.plane, point);
676
+ if (dist > epsilon) {
677
+ return false;
678
+ }
679
+ }
680
+ return true;
681
+ }
682
+ function testBoxInBrush(origin, mins, maxs, brush) {
683
+ for (const side of brush.sides) {
684
+ const offset = side.plane.normal.x * (side.plane.normal.x < 0 ? maxs.x : mins.x) + side.plane.normal.y * (side.plane.normal.y < 0 ? maxs.y : mins.y) + side.plane.normal.z * (side.plane.normal.z < 0 ? maxs.z : mins.z);
685
+ const dist = side.plane.dist - offset;
686
+ const d1 = origin.x * side.plane.normal.x + origin.y * side.plane.normal.y + origin.z * side.plane.normal.z - dist;
687
+ if (d1 > 0) {
688
+ return { startsolid: false, allsolid: false, contents: 0 };
689
+ }
690
+ }
691
+ return { startsolid: true, allsolid: true, contents: brush.contents };
692
+ }
693
+ function clipBoxToBrush({ start, end, mins, maxs, brush, trace }) {
694
+ if (brush.sides.length === 0) return;
695
+ const isPoint = mins.x === 0 && mins.y === 0 && mins.z === 0 && maxs.x === 0 && maxs.y === 0 && maxs.z === 0;
696
+ let enterfrac = -1;
697
+ let leavefrac = 1;
698
+ let clipplane = null;
699
+ let leadside = null;
700
+ let getout = false;
701
+ let startout = false;
702
+ for (const side of brush.sides) {
703
+ const { plane } = side;
704
+ let dist = plane.dist;
705
+ if (!isPoint) {
706
+ const ofsX = plane.normal.x < 0 ? maxs.x : mins.x;
707
+ const ofsY = plane.normal.y < 0 ? maxs.y : mins.y;
708
+ const ofsZ = plane.normal.z < 0 ? maxs.z : mins.z;
709
+ dist -= plane.normal.x * ofsX + plane.normal.y * ofsY + plane.normal.z * ofsZ;
710
+ }
711
+ const d1 = start.x * plane.normal.x + start.y * plane.normal.y + start.z * plane.normal.z - dist;
712
+ const d2 = end.x * plane.normal.x + end.y * plane.normal.y + end.z * plane.normal.z - dist;
713
+ if (d2 > 0) getout = true;
714
+ if (d1 > 0) startout = true;
715
+ if (d1 > 0 && d2 >= d1) {
716
+ return;
717
+ }
718
+ if (d1 <= 0 && d2 <= 0) {
719
+ continue;
720
+ }
721
+ if (d1 > d2) {
722
+ const f = (d1 - DIST_EPSILON) / (d1 - d2);
723
+ if (f > enterfrac) {
724
+ enterfrac = f;
725
+ clipplane = plane;
726
+ leadside = side;
727
+ }
728
+ } else {
729
+ const f = (d1 + DIST_EPSILON) / (d1 - d2);
730
+ if (f < leavefrac) leavefrac = f;
731
+ }
732
+ }
733
+ if (!startout) {
734
+ trace.startsolid = true;
735
+ if (!getout) trace.allsolid = true;
736
+ return;
737
+ }
738
+ if (enterfrac < leavefrac && enterfrac > -1 && enterfrac < trace.fraction) {
739
+ trace.fraction = enterfrac < 0 ? 0 : enterfrac;
740
+ trace.plane = clipplane;
741
+ trace.contents = brush.contents;
742
+ trace.surfaceFlags = leadside?.surfaceFlags ?? 0;
743
+ }
744
+ }
745
+ function createDefaultTrace() {
746
+ return {
747
+ fraction: 1,
748
+ plane: null,
749
+ contents: 0,
750
+ surfaceFlags: 0,
751
+ startsolid: false,
752
+ allsolid: false
753
+ };
754
+ }
755
+
756
+ // src/protocol/cvar.ts
757
+ var CvarFlags = /* @__PURE__ */ ((CvarFlags2) => {
758
+ CvarFlags2[CvarFlags2["None"] = 0] = "None";
759
+ CvarFlags2[CvarFlags2["Archive"] = 1] = "Archive";
760
+ CvarFlags2[CvarFlags2["UserInfo"] = 2] = "UserInfo";
761
+ CvarFlags2[CvarFlags2["ServerInfo"] = 4] = "ServerInfo";
762
+ CvarFlags2[CvarFlags2["Latch"] = 8] = "Latch";
763
+ CvarFlags2[CvarFlags2["Cheat"] = 16] = "Cheat";
764
+ return CvarFlags2;
765
+ })(CvarFlags || {});
766
+
767
+ // src/protocol/configstrings.ts
768
+ var MAX_STRING_CHARS = 1024;
769
+ var MAX_STRING_TOKENS = 80;
770
+ var MAX_TOKEN_CHARS = 512;
771
+ var MAX_QPATH = 64;
772
+ var MAX_OSPATH = 128;
773
+ var MAX_CLIENTS = 256;
774
+ var MAX_EDICTS = 8192;
775
+ var MAX_LIGHTSTYLES = 256;
776
+ var MAX_MODELS = 8192;
777
+ var MAX_SOUNDS = 2048;
778
+ var MAX_IMAGES = 512;
779
+ var MAX_ITEMS = 256;
780
+ var MAX_GENERAL = MAX_CLIENTS * 2;
781
+ var MAX_SHADOW_LIGHTS = 256;
782
+ var MAX_WHEEL_ITEMS = 32;
783
+ var CS_MAX_STRING_LENGTH = 96;
784
+ var CS_MAX_STRING_LENGTH_OLD = 64;
785
+ var ConfigStringIndex = ((ConfigStringIndex2) => {
786
+ ConfigStringIndex2[ConfigStringIndex2["Name"] = 0] = "Name";
787
+ ConfigStringIndex2[ConfigStringIndex2["CdTrack"] = 1] = "CdTrack";
788
+ ConfigStringIndex2[ConfigStringIndex2["Sky"] = 2] = "Sky";
789
+ ConfigStringIndex2[ConfigStringIndex2["SkyAxis"] = 3] = "SkyAxis";
790
+ ConfigStringIndex2[ConfigStringIndex2["SkyRotate"] = 4] = "SkyRotate";
791
+ ConfigStringIndex2[ConfigStringIndex2["StatusBar"] = 5] = "StatusBar";
792
+ ConfigStringIndex2[ConfigStringIndex2["AirAccel"] = 59] = "AirAccel";
793
+ ConfigStringIndex2[ConfigStringIndex2["MaxClients"] = 60] = "MaxClients";
794
+ ConfigStringIndex2[ConfigStringIndex2["MapChecksum"] = 61] = "MapChecksum";
795
+ ConfigStringIndex2[ConfigStringIndex2["Models"] = 62] = "Models";
796
+ ConfigStringIndex2[ConfigStringIndex2["Sounds"] = 62 /* Models */ + MAX_MODELS] = "Sounds";
797
+ ConfigStringIndex2[ConfigStringIndex2["Images"] = ConfigStringIndex2.Sounds + MAX_SOUNDS] = "Images";
798
+ ConfigStringIndex2[ConfigStringIndex2["Lights"] = ConfigStringIndex2.Images + MAX_IMAGES] = "Lights";
799
+ ConfigStringIndex2[ConfigStringIndex2["ShadowLights"] = ConfigStringIndex2.Lights + MAX_LIGHTSTYLES] = "ShadowLights";
800
+ ConfigStringIndex2[ConfigStringIndex2["Items"] = ConfigStringIndex2.ShadowLights + MAX_SHADOW_LIGHTS] = "Items";
801
+ ConfigStringIndex2[ConfigStringIndex2["PlayerSkins"] = ConfigStringIndex2.Items + MAX_ITEMS] = "PlayerSkins";
802
+ ConfigStringIndex2[ConfigStringIndex2["General"] = ConfigStringIndex2.PlayerSkins + MAX_CLIENTS] = "General";
803
+ ConfigStringIndex2[ConfigStringIndex2["WheelWeapons"] = ConfigStringIndex2.General + MAX_GENERAL] = "WheelWeapons";
804
+ ConfigStringIndex2[ConfigStringIndex2["WheelAmmo"] = ConfigStringIndex2.WheelWeapons + MAX_WHEEL_ITEMS] = "WheelAmmo";
805
+ ConfigStringIndex2[ConfigStringIndex2["WheelPowerups"] = ConfigStringIndex2.WheelAmmo + MAX_WHEEL_ITEMS] = "WheelPowerups";
806
+ ConfigStringIndex2[ConfigStringIndex2["CdLoopCount"] = ConfigStringIndex2.WheelPowerups + MAX_WHEEL_ITEMS] = "CdLoopCount";
807
+ ConfigStringIndex2[ConfigStringIndex2["GameStyle"] = ConfigStringIndex2.CdLoopCount + 1] = "GameStyle";
808
+ ConfigStringIndex2[ConfigStringIndex2["MaxConfigStrings"] = ConfigStringIndex2.GameStyle + 1] = "MaxConfigStrings";
809
+ return ConfigStringIndex2;
810
+ })(ConfigStringIndex || {});
811
+ var MAX_CONFIGSTRINGS = ConfigStringIndex.MaxConfigStrings;
812
+ function configStringSize(index) {
813
+ if (index >= 5 /* StatusBar */ && index < 59 /* AirAccel */) {
814
+ return CS_MAX_STRING_LENGTH * (59 /* AirAccel */ - index);
815
+ }
816
+ if (index >= ConfigStringIndex.General && index < ConfigStringIndex.WheelWeapons) {
817
+ return CS_MAX_STRING_LENGTH * (ConfigStringIndex.MaxConfigStrings - index);
818
+ }
819
+ return CS_MAX_STRING_LENGTH;
820
+ }
821
+
822
+ // src/pmove/constants.ts
823
+ var WaterLevel = /* @__PURE__ */ ((WaterLevel3) => {
824
+ WaterLevel3[WaterLevel3["None"] = 0] = "None";
825
+ WaterLevel3[WaterLevel3["Feet"] = 1] = "Feet";
826
+ WaterLevel3[WaterLevel3["Waist"] = 2] = "Waist";
827
+ WaterLevel3[WaterLevel3["Under"] = 3] = "Under";
828
+ return WaterLevel3;
829
+ })(WaterLevel || {});
830
+ function isAtLeastWaistDeep(level) {
831
+ return level >= 2 /* Waist */;
832
+ }
833
+ function isUnderwater(level) {
834
+ return level === 3 /* Under */;
835
+ }
836
+ var PmFlag = /* @__PURE__ */ ((PmFlag2) => {
837
+ PmFlag2[PmFlag2["Ducked"] = 1] = "Ducked";
838
+ PmFlag2[PmFlag2["JumpHeld"] = 2] = "JumpHeld";
839
+ PmFlag2[PmFlag2["OnGround"] = 4] = "OnGround";
840
+ PmFlag2[PmFlag2["TimeWaterJump"] = 8] = "TimeWaterJump";
841
+ PmFlag2[PmFlag2["TimeLand"] = 16] = "TimeLand";
842
+ PmFlag2[PmFlag2["TimeTeleport"] = 32] = "TimeTeleport";
843
+ PmFlag2[PmFlag2["NoPositionalPrediction"] = 64] = "NoPositionalPrediction";
844
+ PmFlag2[PmFlag2["OnLadder"] = 128] = "OnLadder";
845
+ PmFlag2[PmFlag2["NoAngularPrediction"] = 256] = "NoAngularPrediction";
846
+ PmFlag2[PmFlag2["IgnorePlayerCollision"] = 512] = "IgnorePlayerCollision";
847
+ PmFlag2[PmFlag2["TimeTrick"] = 1024] = "TimeTrick";
848
+ return PmFlag2;
849
+ })(PmFlag || {});
850
+ function hasPmFlag(flags, flag) {
851
+ return (flags & flag) !== 0;
852
+ }
853
+ function addPmFlag(flags, flag) {
854
+ return flags | flag;
855
+ }
856
+ function removePmFlag(flags, flag) {
857
+ return flags & ~flag;
858
+ }
859
+ var PmType = /* @__PURE__ */ ((PmType2) => {
860
+ PmType2[PmType2["Normal"] = 0] = "Normal";
861
+ PmType2[PmType2["Grapple"] = 1] = "Grapple";
862
+ PmType2[PmType2["NoClip"] = 2] = "NoClip";
863
+ PmType2[PmType2["Spectator"] = 3] = "Spectator";
864
+ PmType2[PmType2["Dead"] = 4] = "Dead";
865
+ PmType2[PmType2["Gib"] = 5] = "Gib";
866
+ PmType2[PmType2["Freeze"] = 6] = "Freeze";
867
+ return PmType2;
868
+ })(PmType || {});
869
+ var PlayerButton = /* @__PURE__ */ ((PlayerButton2) => {
870
+ PlayerButton2[PlayerButton2["None"] = 0] = "None";
871
+ PlayerButton2[PlayerButton2["Attack"] = 1] = "Attack";
872
+ PlayerButton2[PlayerButton2["Use"] = 2] = "Use";
873
+ PlayerButton2[PlayerButton2["Holster"] = 4] = "Holster";
874
+ PlayerButton2[PlayerButton2["Jump"] = 8] = "Jump";
875
+ PlayerButton2[PlayerButton2["Crouch"] = 16] = "Crouch";
876
+ PlayerButton2[PlayerButton2["Any"] = 128] = "Any";
877
+ return PlayerButton2;
878
+ })(PlayerButton || {});
879
+
880
+ // src/pmove/pmove.ts
881
+ function applyPmoveFriction(params) {
882
+ const {
883
+ velocity,
884
+ frametime,
885
+ onGround,
886
+ groundIsSlick,
887
+ onLadder,
888
+ waterlevel,
889
+ pmFriction,
890
+ pmStopSpeed,
891
+ pmWaterFriction
892
+ } = params;
893
+ const speed = lengthVec3(velocity);
894
+ if (speed < 1) {
895
+ return { x: 0, y: 0, z: velocity.z };
896
+ }
897
+ let drop = 0;
898
+ if (onGround && !groundIsSlick || onLadder) {
899
+ const control = speed < pmStopSpeed ? pmStopSpeed : speed;
900
+ const friction = pmFriction;
901
+ drop += control * friction * frametime;
902
+ }
903
+ if (waterlevel > 0 && !onLadder) {
904
+ drop += speed * pmWaterFriction * waterlevel * frametime;
905
+ }
906
+ let newspeed = speed - drop;
907
+ if (newspeed < 0) {
908
+ newspeed = 0;
909
+ }
910
+ if (newspeed === speed) {
911
+ return velocity;
912
+ }
913
+ const scale = newspeed / speed;
914
+ return scaleVec3(velocity, scale);
915
+ }
916
+ function applyPmoveAccelerate(params) {
917
+ const { velocity, wishdir, wishspeed, accel, frametime } = params;
918
+ const currentSpeed = dotVec3(velocity, wishdir);
919
+ const addSpeed = wishspeed - currentSpeed;
920
+ if (addSpeed <= 0) {
921
+ return velocity;
922
+ }
923
+ let accelSpeed = accel * frametime * wishspeed;
924
+ if (accelSpeed > addSpeed) {
925
+ accelSpeed = addSpeed;
926
+ }
927
+ return {
928
+ x: velocity.x + wishdir.x * accelSpeed,
929
+ y: velocity.y + wishdir.y * accelSpeed,
930
+ z: velocity.z + wishdir.z * accelSpeed
931
+ };
932
+ }
933
+ function applyPmoveAirAccelerate(params) {
934
+ const { velocity, wishdir, wishspeed, accel, frametime } = params;
935
+ const wishspd = Math.min(wishspeed, 30);
936
+ const currentSpeed = dotVec3(velocity, wishdir);
937
+ const addSpeed = wishspd - currentSpeed;
938
+ if (addSpeed <= 0) {
939
+ return velocity;
940
+ }
941
+ let accelSpeed = accel * wishspeed * frametime;
942
+ if (accelSpeed > addSpeed) {
943
+ accelSpeed = addSpeed;
944
+ }
945
+ return {
946
+ x: velocity.x + wishdir.x * accelSpeed,
947
+ y: velocity.y + wishdir.y * accelSpeed,
948
+ z: velocity.z + wishdir.z * accelSpeed
949
+ };
950
+ }
951
+ function pmoveCmdScale(cmd, maxSpeed) {
952
+ const forward = Math.abs(cmd.forwardmove);
953
+ const side = Math.abs(cmd.sidemove);
954
+ const up = Math.abs(cmd.upmove);
955
+ const max = Math.max(forward, side, up);
956
+ if (max === 0) {
957
+ return 0;
958
+ }
959
+ const total = Math.sqrt(cmd.forwardmove * cmd.forwardmove + cmd.sidemove * cmd.sidemove + cmd.upmove * cmd.upmove);
960
+ return maxSpeed * max / (127 * total);
961
+ }
962
+ function buildAirGroundWish(params) {
963
+ const { forward, right, cmd, maxSpeed } = params;
964
+ let wishvel = {
965
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
966
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
967
+ z: 0
968
+ };
969
+ let wishspeed = lengthVec3(wishvel);
970
+ if (wishspeed > maxSpeed) {
971
+ const scale = maxSpeed / wishspeed;
972
+ wishvel = scaleVec3(wishvel, scale);
973
+ wishspeed = maxSpeed;
974
+ }
975
+ return {
976
+ wishdir: wishspeed === 0 ? wishvel : normalizeVec3(wishvel),
977
+ wishspeed
978
+ };
979
+ }
980
+ function buildWaterWish(params) {
981
+ const { forward, right, cmd, maxSpeed } = params;
982
+ let wishvel = {
983
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
984
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
985
+ z: 0
986
+ };
987
+ if (cmd.upmove > 10) {
988
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
989
+ } else if (cmd.upmove < -10) {
990
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
991
+ } else {
992
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: 10 });
993
+ }
994
+ let wishspeed = lengthVec3(wishvel);
995
+ if (wishspeed > maxSpeed) {
996
+ const scale = maxSpeed / wishspeed;
997
+ wishvel = scaleVec3(wishvel, scale);
998
+ wishspeed = maxSpeed;
999
+ }
1000
+ wishspeed *= 0.5;
1001
+ return {
1002
+ wishdir: wishspeed === 0 ? wishvel : normalizeVec3(wishvel),
1003
+ wishspeed
1004
+ };
1005
+ }
1006
+
1007
+ // src/pmove/slide.ts
1008
+ var DEFAULT_MAX_CLIP_PLANES = 5;
1009
+ var DEFAULT_MAX_BUMPS = 4;
1010
+ var DEFAULT_STEP_SIZE = 18;
1011
+ var MIN_STEP_NORMAL = 0.7;
1012
+ var SLIDEMOVE_BLOCKED_FLOOR = 1;
1013
+ var SLIDEMOVE_BLOCKED_WALL = 2;
1014
+ function resolveSlideMove(initialVelocity, planesEncountered, overbounce, maxClipPlanes = DEFAULT_MAX_CLIP_PLANES, primalVelocity = initialVelocity) {
1015
+ if (planesEncountered.length === 0) {
1016
+ return { velocity: initialVelocity, planes: [], stopped: false };
1017
+ }
1018
+ const planes = [];
1019
+ let velocity = initialVelocity;
1020
+ for (const plane of planesEncountered) {
1021
+ if (planes.length >= maxClipPlanes) {
1022
+ return { velocity: ZERO_VEC3, planes, stopped: true };
1023
+ }
1024
+ const duplicate = planes.find((existing) => dotVec3(existing, plane) > 0.99);
1025
+ if (duplicate) {
1026
+ continue;
1027
+ }
1028
+ planes.push(plane);
1029
+ let clipped;
1030
+ let i = 0;
1031
+ for (; i < planes.length; i++) {
1032
+ const candidate = clipVelocityVec3(velocity, planes[i], overbounce);
1033
+ let j = 0;
1034
+ for (; j < planes.length; j++) {
1035
+ if (j === i) continue;
1036
+ if (dotVec3(candidate, planes[j]) < 0) break;
1037
+ }
1038
+ if (j === planes.length) {
1039
+ clipped = candidate;
1040
+ break;
1041
+ }
1042
+ }
1043
+ if (clipped) {
1044
+ velocity = clipped;
1045
+ } else {
1046
+ if (planes.length !== 2) {
1047
+ return { velocity: ZERO_VEC3, planes, stopped: true };
1048
+ }
1049
+ const dir = crossVec3(planes[0], planes[1]);
1050
+ const d = dotVec3(dir, velocity);
1051
+ velocity = scaleVec3(dir, d);
1052
+ }
1053
+ if (dotVec3(velocity, primalVelocity) <= 0) {
1054
+ return { velocity: ZERO_VEC3, planes, stopped: true };
1055
+ }
1056
+ }
1057
+ const stopped = velocity.x === 0 && velocity.y === 0 && velocity.z === 0;
1058
+ return { velocity, planes, stopped };
1059
+ }
1060
+ function slideMove(params) {
1061
+ const {
1062
+ origin: initialOrigin,
1063
+ velocity: initialVelocity,
1064
+ frametime,
1065
+ overbounce,
1066
+ trace,
1067
+ maxBumps = DEFAULT_MAX_BUMPS,
1068
+ maxClipPlanes = DEFAULT_MAX_CLIP_PLANES,
1069
+ mins,
1070
+ maxs,
1071
+ hasTime = false
1072
+ } = params;
1073
+ let origin = initialOrigin;
1074
+ let velocity = initialVelocity;
1075
+ const planes = [];
1076
+ const primalVelocity = initialVelocity;
1077
+ let timeLeft = frametime;
1078
+ let blocked = 0;
1079
+ for (let bump = 0; bump < maxBumps; bump++) {
1080
+ if (velocity.x === 0 && velocity.y === 0 && velocity.z === 0) {
1081
+ break;
1082
+ }
1083
+ const end = addVec3(origin, scaleVec3(velocity, timeLeft));
1084
+ const tr = trace(origin, end, mins, maxs);
1085
+ if (tr.allsolid) {
1086
+ const velocity2 = hasTime ? primalVelocity : ZERO_VEC3;
1087
+ return { origin: tr.endpos, velocity: velocity2, planes, stopped: true, blocked };
1088
+ }
1089
+ if (tr.startsolid) {
1090
+ const velocity2 = hasTime ? primalVelocity : ZERO_VEC3;
1091
+ return { origin: tr.endpos, velocity: velocity2, planes, stopped: true, blocked };
1092
+ }
1093
+ if (tr.fraction > 0) {
1094
+ origin = tr.endpos;
1095
+ }
1096
+ if (tr.fraction === 1) {
1097
+ break;
1098
+ }
1099
+ if (!tr.planeNormal) {
1100
+ const velocity2 = hasTime ? primalVelocity : ZERO_VEC3;
1101
+ return { origin, velocity: velocity2, planes, stopped: true, blocked };
1102
+ }
1103
+ if (tr.planeNormal.z > 0.7) {
1104
+ blocked |= SLIDEMOVE_BLOCKED_FLOOR;
1105
+ }
1106
+ if (tr.planeNormal.z === 0) {
1107
+ blocked |= SLIDEMOVE_BLOCKED_WALL;
1108
+ }
1109
+ planes.push(tr.planeNormal);
1110
+ timeLeft -= timeLeft * tr.fraction;
1111
+ const resolved = resolveSlideMove(velocity, planes, overbounce, maxClipPlanes, primalVelocity);
1112
+ velocity = resolved.velocity;
1113
+ planes.splice(0, planes.length, ...resolved.planes);
1114
+ if (primalVelocity.z > 0 && velocity.z < 0) {
1115
+ velocity = { ...velocity, z: 0 };
1116
+ }
1117
+ if (resolved.stopped) {
1118
+ const velocityOut2 = hasTime ? primalVelocity : velocity;
1119
+ return { origin, velocity: velocityOut2, planes, stopped: true, blocked };
1120
+ }
1121
+ }
1122
+ const velocityOut = hasTime ? primalVelocity : velocity;
1123
+ return { origin, velocity: velocityOut, planes, stopped: velocityOut.x === 0 && velocityOut.y === 0 && velocityOut.z === 0, blocked };
1124
+ }
1125
+ function stepSlideMove(params) {
1126
+ const { mins, maxs, stepSize = DEFAULT_STEP_SIZE, ...rest } = params;
1127
+ const startOrigin = params.origin;
1128
+ const startVelocity = params.velocity;
1129
+ const downResult = slideMove({ ...rest, mins, maxs });
1130
+ const upTarget = addVec3(startOrigin, { x: 0, y: 0, z: stepSize });
1131
+ const upTrace = rest.trace(startOrigin, upTarget, mins, maxs);
1132
+ if (upTrace.allsolid) {
1133
+ return { ...downResult, stepped: false, stepHeight: 0 };
1134
+ }
1135
+ const actualStep = upTrace.endpos.z - startOrigin.z;
1136
+ const steppedResult = slideMove({ ...rest, origin: upTrace.endpos, velocity: startVelocity, mins, maxs });
1137
+ const pushDownTarget = addVec3(steppedResult.origin, { x: 0, y: 0, z: -actualStep });
1138
+ const downTrace = rest.trace(steppedResult.origin, pushDownTarget, mins, maxs);
1139
+ let steppedOrigin = steppedResult.origin;
1140
+ let stepNormal = downTrace.planeNormal;
1141
+ if (!downTrace.allsolid) {
1142
+ steppedOrigin = downTrace.endpos;
1143
+ }
1144
+ const planarDistanceSquared = (a, b) => (a.x - b.x) ** 2 + (a.y - b.y) ** 2;
1145
+ const downDist = planarDistanceSquared(downResult.origin, startOrigin);
1146
+ const upDist = planarDistanceSquared(steppedOrigin, startOrigin);
1147
+ if (downDist > upDist || stepNormal && stepNormal.z < MIN_STEP_NORMAL) {
1148
+ return { ...downResult, stepped: false, stepHeight: 0 };
1149
+ }
1150
+ const steppedVelocity = { ...steppedResult.velocity, z: downResult.velocity.z };
1151
+ const steppedBlocked = steppedResult.blocked;
1152
+ const stopped = steppedVelocity.x === 0 && steppedVelocity.y === 0 && steppedVelocity.z === 0;
1153
+ return {
1154
+ origin: steppedOrigin,
1155
+ velocity: steppedVelocity,
1156
+ planes: steppedResult.planes,
1157
+ blocked: steppedBlocked,
1158
+ stopped,
1159
+ stepped: true,
1160
+ stepHeight: actualStep,
1161
+ stepNormal
1162
+ };
1163
+ }
1164
+
1165
+ // src/pmove/stuck.ts
1166
+ var AXES = ["x", "y", "z"];
1167
+ var SIDE_CHECKS = [
1168
+ { normal: [0, 0, 1], mins: [-1, -1, 0], maxs: [1, 1, 0] },
1169
+ { normal: [0, 0, -1], mins: [-1, -1, 0], maxs: [1, 1, 0] },
1170
+ { normal: [1, 0, 0], mins: [0, -1, -1], maxs: [0, 1, 1] },
1171
+ { normal: [-1, 0, 0], mins: [0, -1, -1], maxs: [0, 1, 1] },
1172
+ { normal: [0, 1, 0], mins: [-1, 0, -1], maxs: [1, 0, 1] },
1173
+ { normal: [0, -1, 0], mins: [-1, 0, -1], maxs: [1, 0, 1] }
1174
+ ];
1175
+ var ZERO_VEC = { x: 0, y: 0, z: 0 };
1176
+ function cloneMutable(vec) {
1177
+ return { x: vec.x, y: vec.y, z: vec.z };
1178
+ }
1179
+ function tupleToVec3(tuple) {
1180
+ return { x: tuple[0], y: tuple[1], z: tuple[2] };
1181
+ }
1182
+ function adjustAxis(vec, axis, delta) {
1183
+ if (delta === 0) return;
1184
+ switch (axis) {
1185
+ case "x":
1186
+ vec.x += delta;
1187
+ break;
1188
+ case "y":
1189
+ vec.y += delta;
1190
+ break;
1191
+ case "z":
1192
+ vec.z += delta;
1193
+ break;
1194
+ }
1195
+ }
1196
+ function setAxis(vec, axis, value) {
1197
+ switch (axis) {
1198
+ case "x":
1199
+ vec.x = value;
1200
+ break;
1201
+ case "y":
1202
+ vec.y = value;
1203
+ break;
1204
+ case "z":
1205
+ vec.z = value;
1206
+ break;
1207
+ }
1208
+ }
1209
+ function axisValue(vec, axis) {
1210
+ switch (axis) {
1211
+ case "x":
1212
+ return vec.x;
1213
+ case "y":
1214
+ return vec.y;
1215
+ case "z":
1216
+ default:
1217
+ return vec.z;
1218
+ }
1219
+ }
1220
+ function boundValue(code, axis, mins, maxs) {
1221
+ if (code === -1) {
1222
+ return axisValue(mins, axis);
1223
+ }
1224
+ if (code === 1) {
1225
+ return axisValue(maxs, axis);
1226
+ }
1227
+ return 0;
1228
+ }
1229
+ function applySideOffset(base, side, mins, maxs) {
1230
+ const result = cloneMutable(base);
1231
+ for (let i = 0; i < AXES.length; i++) {
1232
+ const axis = AXES[i];
1233
+ const normal = side.normal[i];
1234
+ if (normal < 0) {
1235
+ adjustAxis(result, axis, axisValue(mins, axis));
1236
+ } else if (normal > 0) {
1237
+ adjustAxis(result, axis, axisValue(maxs, axis));
1238
+ }
1239
+ }
1240
+ return result;
1241
+ }
1242
+ function buildSideBounds(side, mins, maxs) {
1243
+ const localMins = cloneMutable(ZERO_VEC);
1244
+ const localMaxs = cloneMutable(ZERO_VEC);
1245
+ for (let i = 0; i < AXES.length; i++) {
1246
+ const axis = AXES[i];
1247
+ setAxis(localMins, axis, boundValue(side.mins[i], axis, mins, maxs));
1248
+ setAxis(localMaxs, axis, boundValue(side.maxs[i], axis, mins, maxs));
1249
+ }
1250
+ return { mins: localMins, maxs: localMaxs };
1251
+ }
1252
+ function addEpsilon(source, axis, direction) {
1253
+ if (!axis || direction === 0) {
1254
+ return source;
1255
+ }
1256
+ const clone = cloneMutable(source);
1257
+ adjustAxis(clone, axis, direction);
1258
+ return clone;
1259
+ }
1260
+ function addEpsilonImmutable(vec, axis, direction) {
1261
+ if (!axis || direction === 0) {
1262
+ return vec;
1263
+ }
1264
+ switch (axis) {
1265
+ case "x":
1266
+ return { ...vec, x: vec.x + direction };
1267
+ case "y":
1268
+ return { ...vec, y: vec.y + direction };
1269
+ case "z":
1270
+ default:
1271
+ return { ...vec, z: vec.z + direction };
1272
+ }
1273
+ }
1274
+ function fixStuckObjectGeneric(params) {
1275
+ const { origin, mins, maxs, trace } = params;
1276
+ const initial = trace(origin, mins, maxs, origin);
1277
+ if (!initial.startsolid) {
1278
+ return { result: "good-position", origin: { ...origin } };
1279
+ }
1280
+ const candidates = [];
1281
+ for (let i = 0; i < SIDE_CHECKS.length; i++) {
1282
+ const side = SIDE_CHECKS[i];
1283
+ const { mins: localMins, maxs: localMaxs } = buildSideBounds(side, mins, maxs);
1284
+ let start = applySideOffset(origin, side, mins, maxs);
1285
+ let tr = trace(start, localMins, localMaxs, start);
1286
+ let epsilonAxis;
1287
+ let epsilonDir = 0;
1288
+ if (tr.startsolid) {
1289
+ for (let axisIndex = 0; axisIndex < AXES.length; axisIndex++) {
1290
+ if (side.normal[axisIndex] !== 0) {
1291
+ continue;
1292
+ }
1293
+ const axis = AXES[axisIndex];
1294
+ let epsilonStart = cloneMutable(start);
1295
+ adjustAxis(epsilonStart, axis, 1);
1296
+ tr = trace(epsilonStart, localMins, localMaxs, epsilonStart);
1297
+ if (!tr.startsolid) {
1298
+ start = epsilonStart;
1299
+ epsilonAxis = axis;
1300
+ epsilonDir = 1;
1301
+ break;
1302
+ }
1303
+ epsilonStart = cloneMutable(start);
1304
+ adjustAxis(epsilonStart, axis, -1);
1305
+ tr = trace(epsilonStart, localMins, localMaxs, epsilonStart);
1306
+ if (!tr.startsolid) {
1307
+ start = epsilonStart;
1308
+ epsilonAxis = axis;
1309
+ epsilonDir = -1;
1310
+ break;
1311
+ }
1312
+ }
1313
+ }
1314
+ if (tr.startsolid) {
1315
+ continue;
1316
+ }
1317
+ const otherSide = SIDE_CHECKS[i ^ 1];
1318
+ let oppositeStart = applySideOffset(origin, otherSide, mins, maxs);
1319
+ oppositeStart = addEpsilon(oppositeStart, epsilonAxis, epsilonDir);
1320
+ tr = trace(start, localMins, localMaxs, oppositeStart);
1321
+ if (tr.startsolid) {
1322
+ continue;
1323
+ }
1324
+ const normal = tupleToVec3(side.normal);
1325
+ const end = addVec3(tr.endpos ?? oppositeStart, scaleVec3(normal, 0.125));
1326
+ const delta = subtractVec3(end, oppositeStart);
1327
+ let newOrigin = addVec3(origin, delta);
1328
+ newOrigin = addEpsilonImmutable(newOrigin, epsilonAxis, epsilonDir);
1329
+ const validation = trace(newOrigin, mins, maxs, newOrigin);
1330
+ if (validation.startsolid) {
1331
+ continue;
1332
+ }
1333
+ candidates.push({ origin: newOrigin, distance: lengthSquaredVec3(delta) });
1334
+ }
1335
+ if (candidates.length === 0) {
1336
+ return { result: "no-good-position", origin: { ...origin } };
1337
+ }
1338
+ candidates.sort((a, b) => a.distance - b.distance);
1339
+ return { result: "fixed", origin: { ...candidates[0].origin } };
1340
+ }
1341
+
1342
+ // src/pmove/currents.ts
1343
+ var DEFAULT_GROUND_CURRENT_SCALE = 100;
1344
+ var DEFAULT_FORWARD_LADDER_CLAMP = 200;
1345
+ var DEFAULT_SIDE_LADDER_CLAMP = 150;
1346
+ var LADDER_HORIZONTAL_CAP = 25;
1347
+ var LADDER_ASCEND_PITCH_THRESHOLD = 15;
1348
+ var LADDER_TRACE_DISTANCE = 1;
1349
+ var UP_VECTOR = { x: 0, y: 0, z: 1 };
1350
+ var DEFAULT_TRACE = (_, end) => ({
1351
+ fraction: 1,
1352
+ endpos: end,
1353
+ allsolid: false,
1354
+ startsolid: false
1355
+ });
1356
+ function currentVectorFromContents(contents) {
1357
+ let x = 0;
1358
+ let y = 0;
1359
+ let z = 0;
1360
+ if (contents & CONTENTS_CURRENT_0) {
1361
+ x += 1;
1362
+ }
1363
+ if (contents & CONTENTS_CURRENT_90) {
1364
+ y += 1;
1365
+ }
1366
+ if (contents & CONTENTS_CURRENT_180) {
1367
+ x -= 1;
1368
+ }
1369
+ if (contents & CONTENTS_CURRENT_270) {
1370
+ y -= 1;
1371
+ }
1372
+ if (contents & CONTENTS_CURRENT_UP) {
1373
+ z += 1;
1374
+ }
1375
+ if (contents & CONTENTS_CURRENT_DOWN) {
1376
+ z -= 1;
1377
+ }
1378
+ if (x === 0 && y === 0 && z === 0) {
1379
+ return ZERO_VEC3;
1380
+ }
1381
+ return { x, y, z };
1382
+ }
1383
+ function waterCurrentVelocity(params) {
1384
+ const { watertype, waterlevel, onGround, waterSpeed } = params;
1385
+ if ((watertype & MASK_CURRENT) === 0) {
1386
+ return ZERO_VEC3;
1387
+ }
1388
+ const direction = currentVectorFromContents(watertype);
1389
+ if (direction === ZERO_VEC3) {
1390
+ return ZERO_VEC3;
1391
+ }
1392
+ let scale = waterSpeed;
1393
+ if (waterlevel === 1 /* Feet */ && onGround) {
1394
+ scale *= 0.5;
1395
+ }
1396
+ return scaleVec3(direction, scale);
1397
+ }
1398
+ function groundCurrentVelocity(params) {
1399
+ const { groundContents, scale = DEFAULT_GROUND_CURRENT_SCALE } = params;
1400
+ const direction = currentVectorFromContents(groundContents);
1401
+ if (direction === ZERO_VEC3) {
1402
+ return ZERO_VEC3;
1403
+ }
1404
+ return scaleVec3(direction, scale);
1405
+ }
1406
+ function applyPmoveAddCurrents(params) {
1407
+ const {
1408
+ wishVelocity,
1409
+ onLadder,
1410
+ onGround,
1411
+ waterlevel,
1412
+ watertype,
1413
+ groundContents,
1414
+ cmd,
1415
+ viewPitch,
1416
+ maxSpeed,
1417
+ ladderMod,
1418
+ waterSpeed,
1419
+ forward,
1420
+ origin,
1421
+ mins,
1422
+ maxs,
1423
+ trace = DEFAULT_TRACE
1424
+ } = params;
1425
+ let adjusted = wishVelocity;
1426
+ if (onLadder) {
1427
+ adjusted = applyLadderAdjustments({
1428
+ wishVelocity: adjusted,
1429
+ cmd,
1430
+ waterlevel,
1431
+ viewPitch,
1432
+ maxSpeed,
1433
+ ladderMod,
1434
+ onGround,
1435
+ forward,
1436
+ origin,
1437
+ mins,
1438
+ maxs,
1439
+ trace
1440
+ });
1441
+ }
1442
+ const waterVelocity = waterCurrentVelocity({ watertype, waterlevel, onGround, waterSpeed });
1443
+ if (waterVelocity !== ZERO_VEC3) {
1444
+ adjusted = addVec3(adjusted, waterVelocity);
1445
+ }
1446
+ if (onGround) {
1447
+ const groundVelocity = groundCurrentVelocity({ groundContents });
1448
+ if (groundVelocity !== ZERO_VEC3) {
1449
+ adjusted = addVec3(adjusted, groundVelocity);
1450
+ }
1451
+ }
1452
+ return adjusted;
1453
+ }
1454
+ function applyLadderAdjustments(params) {
1455
+ const { wishVelocity, cmd, waterlevel, viewPitch, maxSpeed, ladderMod, onGround, forward, origin, mins, maxs, trace } = params;
1456
+ const buttons = cmd.buttons ?? 0;
1457
+ let adjusted = { ...wishVelocity };
1458
+ if ((buttons & (8 /* Jump */ | 16 /* Crouch */)) !== 0) {
1459
+ const ladderSpeed = isAtLeastWaistDeep(waterlevel) ? maxSpeed : DEFAULT_FORWARD_LADDER_CLAMP;
1460
+ adjusted = {
1461
+ ...adjusted,
1462
+ z: buttons & 8 /* Jump */ ? ladderSpeed : -ladderSpeed
1463
+ };
1464
+ } else if (cmd.forwardmove) {
1465
+ const clamped = clamp(cmd.forwardmove, -DEFAULT_FORWARD_LADDER_CLAMP, DEFAULT_FORWARD_LADDER_CLAMP);
1466
+ if (cmd.forwardmove > 0) {
1467
+ const climb = viewPitch < LADDER_ASCEND_PITCH_THRESHOLD ? clamped : -clamped;
1468
+ adjusted = { ...adjusted, z: climb };
1469
+ } else {
1470
+ if (!onGround) {
1471
+ adjusted = { ...adjusted, x: 0, y: 0 };
1472
+ }
1473
+ adjusted = { ...adjusted, z: clamped };
1474
+ }
1475
+ } else {
1476
+ adjusted = { ...adjusted, z: 0 };
1477
+ }
1478
+ if (!onGround) {
1479
+ if (cmd.sidemove) {
1480
+ let sideSpeed = clamp(cmd.sidemove, -DEFAULT_SIDE_LADDER_CLAMP, DEFAULT_SIDE_LADDER_CLAMP);
1481
+ if (waterlevel < 2 /* Waist */) {
1482
+ sideSpeed *= ladderMod;
1483
+ }
1484
+ const flatForward = normalizeVec3({ x: forward.x, y: forward.y, z: 0 });
1485
+ if (flatForward.x !== 0 || flatForward.y !== 0) {
1486
+ const spot = addVec3(origin, scaleVec3(flatForward, LADDER_TRACE_DISTANCE));
1487
+ const tr = trace(origin, spot, mins, maxs);
1488
+ if (tr.fraction !== 1 && !tr.allsolid && tr.contents !== void 0 && (tr.contents & CONTENTS_LADDER) !== 0 && tr.planeNormal) {
1489
+ const right = crossVec3(tr.planeNormal, UP_VECTOR);
1490
+ adjusted = { ...adjusted, x: 0, y: 0 };
1491
+ adjusted = addVec3(adjusted, scaleVec3(right, -sideSpeed));
1492
+ }
1493
+ }
1494
+ } else {
1495
+ adjusted = {
1496
+ ...adjusted,
1497
+ x: clampHorizontal(adjusted.x),
1498
+ y: clampHorizontal(adjusted.y)
1499
+ };
1500
+ }
1501
+ }
1502
+ return adjusted;
1503
+ }
1504
+ function clamp(value, min, max) {
1505
+ return Math.max(min, Math.min(max, value));
1506
+ }
1507
+ function clampHorizontal(value) {
1508
+ if (value < -LADDER_HORIZONTAL_CAP) {
1509
+ return -LADDER_HORIZONTAL_CAP;
1510
+ }
1511
+ if (value > LADDER_HORIZONTAL_CAP) {
1512
+ return LADDER_HORIZONTAL_CAP;
1513
+ }
1514
+ return value;
1515
+ }
1516
+
1517
+ // src/pmove/fly.ts
1518
+ var FLY_FRICTION_MULTIPLIER = 1.5;
1519
+ var BUTTON_VERTICAL_SCALE = 0.5;
1520
+ var DEFAULT_OVERBOUNCE = 1.01;
1521
+ function applyPmoveFlyMove(params) {
1522
+ const {
1523
+ origin,
1524
+ cmd,
1525
+ frametime,
1526
+ pmFriction,
1527
+ pmStopSpeed,
1528
+ pmMaxSpeed,
1529
+ pmAccelerate,
1530
+ pmWaterSpeed,
1531
+ doclip,
1532
+ forward,
1533
+ right,
1534
+ mins,
1535
+ maxs,
1536
+ trace,
1537
+ overbounce = DEFAULT_OVERBOUNCE,
1538
+ stepSize,
1539
+ maxBumps,
1540
+ maxClipPlanes
1541
+ } = params;
1542
+ let velocity = applyFlyFriction({ velocity: params.velocity, pmFriction, pmStopSpeed, frametime });
1543
+ const wishdirVelocity = buildFlyWishVelocity({
1544
+ cmd,
1545
+ forward,
1546
+ right,
1547
+ pmMaxSpeed,
1548
+ pmWaterSpeed
1549
+ });
1550
+ if (wishdirVelocity.wishspeed > 0) {
1551
+ velocity = applyPmoveAccelerate({
1552
+ velocity,
1553
+ wishdir: wishdirVelocity.wishdir,
1554
+ wishspeed: wishdirVelocity.accelSpeed,
1555
+ accel: pmAccelerate,
1556
+ frametime
1557
+ });
1558
+ }
1559
+ if (!doclip) {
1560
+ const originDelta = scaleVec3(velocity, frametime);
1561
+ const nextOrigin = addVec3(origin, originDelta);
1562
+ return {
1563
+ origin: nextOrigin,
1564
+ velocity,
1565
+ planes: [],
1566
+ blocked: 0,
1567
+ stopped: velocity.x === 0 && velocity.y === 0 && velocity.z === 0,
1568
+ stepped: false,
1569
+ stepHeight: 0
1570
+ };
1571
+ }
1572
+ if (!trace || !mins || !maxs) {
1573
+ throw new Error("applyPmoveFlyMove: doclip=true requires trace/mins/maxs");
1574
+ }
1575
+ return stepSlideMove({
1576
+ origin,
1577
+ velocity,
1578
+ frametime,
1579
+ overbounce,
1580
+ trace,
1581
+ mins,
1582
+ maxs,
1583
+ stepSize,
1584
+ maxBumps,
1585
+ maxClipPlanes
1586
+ });
1587
+ }
1588
+ function applyFlyFriction(params) {
1589
+ const { velocity, pmFriction, pmStopSpeed, frametime } = params;
1590
+ const speed = lengthVec3(velocity);
1591
+ if (speed < 1) {
1592
+ return { x: 0, y: 0, z: 0 };
1593
+ }
1594
+ const friction = pmFriction * FLY_FRICTION_MULTIPLIER;
1595
+ const control = speed < pmStopSpeed ? pmStopSpeed : speed;
1596
+ const drop = control * friction * frametime;
1597
+ let newspeed = speed - drop;
1598
+ if (newspeed < 0) {
1599
+ newspeed = 0;
1600
+ }
1601
+ if (newspeed === speed) {
1602
+ return velocity;
1603
+ }
1604
+ return scaleVec3(velocity, newspeed / speed);
1605
+ }
1606
+ function buildFlyWishVelocity(params) {
1607
+ const { cmd, forward, right, pmMaxSpeed, pmWaterSpeed } = params;
1608
+ const forwardNorm = normalizeVec3(forward);
1609
+ const rightNorm = normalizeVec3(right);
1610
+ const wishvel = {
1611
+ x: forwardNorm.x * cmd.forwardmove + rightNorm.x * cmd.sidemove,
1612
+ y: forwardNorm.y * cmd.forwardmove + rightNorm.y * cmd.sidemove,
1613
+ z: forwardNorm.z * cmd.forwardmove + rightNorm.z * cmd.sidemove
1614
+ };
1615
+ let adjusted = wishvel;
1616
+ const buttons = cmd.buttons ?? 0;
1617
+ if (buttons & 8 /* Jump */) {
1618
+ adjusted = addVec3(adjusted, { x: 0, y: 0, z: pmWaterSpeed * BUTTON_VERTICAL_SCALE });
1619
+ }
1620
+ if (buttons & 16 /* Crouch */) {
1621
+ adjusted = addVec3(adjusted, { x: 0, y: 0, z: -pmWaterSpeed * BUTTON_VERTICAL_SCALE });
1622
+ }
1623
+ let wishspeed = lengthVec3(adjusted);
1624
+ let wishdir = wishspeed === 0 ? { x: 0, y: 0, z: 0 } : normalizeVec3(adjusted);
1625
+ if (wishspeed > pmMaxSpeed) {
1626
+ const scale = pmMaxSpeed / wishspeed;
1627
+ adjusted = scaleVec3(adjusted, scale);
1628
+ wishspeed = pmMaxSpeed;
1629
+ wishdir = wishspeed === 0 ? { x: 0, y: 0, z: 0 } : normalizeVec3(adjusted);
1630
+ }
1631
+ const accelSpeed = wishspeed * 2;
1632
+ return { wishdir, wishspeed, accelSpeed };
1633
+ }
1634
+
1635
+ // src/pmove/water.ts
1636
+ function getWaterLevel(params) {
1637
+ const { origin, mins, viewheight, pointContents } = params;
1638
+ const sample2 = viewheight - mins.z;
1639
+ const sample1 = sample2 / 2;
1640
+ const point = {
1641
+ x: origin.x,
1642
+ y: origin.y,
1643
+ z: origin.z + mins.z + 1
1644
+ };
1645
+ let contents = pointContents(point);
1646
+ if ((contents & MASK_WATER) === 0) {
1647
+ return { waterlevel: 0 /* None */, watertype: CONTENTS_NONE };
1648
+ }
1649
+ const watertype = contents;
1650
+ let waterlevel = 1 /* Feet */;
1651
+ let point2 = { x: point.x, y: point.y, z: origin.z + mins.z + sample1 };
1652
+ contents = pointContents(point2);
1653
+ if ((contents & MASK_WATER) !== 0) {
1654
+ waterlevel = 2 /* Waist */;
1655
+ let point3 = { x: point.x, y: point.y, z: origin.z + mins.z + sample2 };
1656
+ contents = pointContents(point3);
1657
+ if ((contents & MASK_WATER) !== 0) {
1658
+ waterlevel = 3 /* Under */;
1659
+ }
1660
+ }
1661
+ return { waterlevel, watertype };
1662
+ }
1663
+
1664
+ // src/pmove/jump.ts
1665
+ var DEFAULT_JUMP_HEIGHT = 270;
1666
+ function hasButton(buttons, button) {
1667
+ return (buttons & button) !== 0;
1668
+ }
1669
+ function checkJump(params) {
1670
+ const { pmFlags, pmType, buttons, waterlevel, onGround, velocity, jumpHeight = DEFAULT_JUMP_HEIGHT } = params;
1671
+ if (pmFlags & 16 /* TimeLand */) {
1672
+ return { pmFlags, onGround, velocity, jumpSound: false, jumped: false };
1673
+ }
1674
+ const holdingJump = hasButton(buttons, 8 /* Jump */);
1675
+ let nextFlags = pmFlags;
1676
+ let nextOnGround = onGround;
1677
+ let jumpSound = false;
1678
+ let jumped = false;
1679
+ let nextVelocity = velocity;
1680
+ if (!holdingJump) {
1681
+ nextFlags = removePmFlag(nextFlags, 2 /* JumpHeld */);
1682
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1683
+ }
1684
+ if (hasPmJumpHold(nextFlags)) {
1685
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1686
+ }
1687
+ if (pmType === 4 /* Dead */) {
1688
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1689
+ }
1690
+ if (waterlevel >= 2 /* Waist */) {
1691
+ nextOnGround = false;
1692
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1693
+ }
1694
+ if (!nextOnGround) {
1695
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1696
+ }
1697
+ nextFlags = addPmFlag(nextFlags, 2 /* JumpHeld */);
1698
+ nextFlags = removePmFlag(nextFlags, 4 /* OnGround */);
1699
+ nextOnGround = false;
1700
+ jumpSound = true;
1701
+ jumped = true;
1702
+ const z = velocity.z + jumpHeight;
1703
+ const finalZ = z < jumpHeight ? jumpHeight : z;
1704
+ nextVelocity = { ...velocity, z: finalZ };
1705
+ return { pmFlags: nextFlags, onGround: nextOnGround, velocity: nextVelocity, jumpSound, jumped };
1706
+ }
1707
+ function hasPmJumpHold(flags) {
1708
+ return (flags & 2 /* JumpHeld */) !== 0;
1709
+ }
1710
+
1711
+ // src/pmove/dimensions.ts
1712
+ function createVec3(x, y, z) {
1713
+ return { x, y, z };
1714
+ }
1715
+ function computePlayerDimensions(pmType, pmFlags) {
1716
+ const minsBase = createVec3(-16, -16, 0);
1717
+ const maxsBase = createVec3(16, 16, 16);
1718
+ if (pmType === 5 /* Gib */) {
1719
+ return {
1720
+ mins: minsBase,
1721
+ maxs: maxsBase,
1722
+ viewheight: 8
1723
+ };
1724
+ }
1725
+ const ducked = pmType === 4 /* Dead */ || (pmFlags & 1 /* Ducked */) !== 0;
1726
+ const mins = createVec3(minsBase.x, minsBase.y, -24);
1727
+ const maxs = createVec3(maxsBase.x, maxsBase.y, ducked ? 4 : 32);
1728
+ return {
1729
+ mins,
1730
+ maxs,
1731
+ viewheight: ducked ? -2 : 22
1732
+ };
1733
+ }
1734
+
1735
+ // src/pmove/duck.ts
1736
+ var CROUCH_MAX_Z = 4;
1737
+ var STAND_MAX_Z = 32;
1738
+ var ABOVE_WATER_OFFSET = 8;
1739
+ function checkDuckState(params) {
1740
+ const { pmType } = params;
1741
+ if (pmType === 5 /* Gib */) {
1742
+ const dims2 = computePlayerDimensions(pmType, params.pmFlags);
1743
+ return { pmFlags: params.pmFlags, ducked: hasPmFlag(params.pmFlags, 1 /* Ducked */), changed: false, ...dims2 };
1744
+ }
1745
+ let flags = params.pmFlags;
1746
+ let changed = false;
1747
+ if (pmType === 4 /* Dead */) {
1748
+ if (!hasPmFlag(flags, 1 /* Ducked */)) {
1749
+ flags = addPmFlag(flags, 1 /* Ducked */);
1750
+ changed = true;
1751
+ }
1752
+ } else if (shouldDuck(params)) {
1753
+ if (!hasPmFlag(flags, 1 /* Ducked */) && !isDuckBlocked(params)) {
1754
+ flags = addPmFlag(flags, 1 /* Ducked */);
1755
+ changed = true;
1756
+ }
1757
+ } else if (hasPmFlag(flags, 1 /* Ducked */) && !isStandBlocked(params)) {
1758
+ flags = removePmFlag(flags, 1 /* Ducked */);
1759
+ changed = true;
1760
+ }
1761
+ const dims = computePlayerDimensions(pmType, flags);
1762
+ const ducked = pmType === 4 /* Dead */ || hasPmFlag(flags, 1 /* Ducked */);
1763
+ return { pmFlags: flags, ducked, changed, ...dims };
1764
+ }
1765
+ function shouldDuck(params) {
1766
+ if ((params.buttons & 16 /* Crouch */) === 0) {
1767
+ return false;
1768
+ }
1769
+ if (params.onLadder || params.n64Physics) {
1770
+ return false;
1771
+ }
1772
+ if (params.hasGroundEntity) {
1773
+ return true;
1774
+ }
1775
+ if (params.waterlevel <= 1 /* Feet */ && !isAboveWater(params)) {
1776
+ return true;
1777
+ }
1778
+ return false;
1779
+ }
1780
+ function isDuckBlocked(params) {
1781
+ const trace = params.trace({
1782
+ start: params.origin,
1783
+ end: params.origin,
1784
+ mins: params.mins,
1785
+ maxs: withZ(params.maxs, CROUCH_MAX_Z),
1786
+ mask: MASK_SOLID
1787
+ });
1788
+ return trace.allsolid;
1789
+ }
1790
+ function isStandBlocked(params) {
1791
+ const trace = params.trace({
1792
+ start: params.origin,
1793
+ end: params.origin,
1794
+ mins: params.mins,
1795
+ maxs: withZ(params.maxs, STAND_MAX_Z),
1796
+ mask: MASK_SOLID
1797
+ });
1798
+ return trace.allsolid;
1799
+ }
1800
+ function isAboveWater(params) {
1801
+ const below = { x: params.origin.x, y: params.origin.y, z: params.origin.z - ABOVE_WATER_OFFSET };
1802
+ const solidTrace = params.trace({
1803
+ start: params.origin,
1804
+ end: below,
1805
+ mins: params.mins,
1806
+ maxs: params.maxs,
1807
+ mask: MASK_SOLID
1808
+ });
1809
+ if (solidTrace.fraction < 1) {
1810
+ return false;
1811
+ }
1812
+ const waterTrace = params.trace({
1813
+ start: params.origin,
1814
+ end: below,
1815
+ mins: params.mins,
1816
+ maxs: params.maxs,
1817
+ mask: MASK_WATER
1818
+ });
1819
+ return waterTrace.fraction < 1;
1820
+ }
1821
+ function withZ(vec, z) {
1822
+ return { x: vec.x, y: vec.y, z };
1823
+ }
1824
+
1825
+ // src/pmove/categorize.ts
1826
+ var GROUND_PROBE_DISTANCE = 0.25;
1827
+ var LADDER_BYPASS_VELOCITY = 180;
1828
+ var TRICK_VELOCITY_THRESHOLD = 100;
1829
+ var SLANTED_NORMAL_THRESHOLD = 0.7;
1830
+ var TRICK_NORMAL_THRESHOLD = 0.9;
1831
+ var TRICK_PM_TIME = 64;
1832
+ var LAND_PM_TIME = 128;
1833
+ var IMPACT_CLIP_OVERBOUNCE = 1.01;
1834
+ var WATERJUMP_CLEAR = 8 /* TimeWaterJump */ | 16 /* TimeLand */ | 32 /* TimeTeleport */ | 1024 /* TimeTrick */;
1835
+ function categorizePosition(params) {
1836
+ const {
1837
+ pmType,
1838
+ n64Physics,
1839
+ velocity,
1840
+ startVelocity,
1841
+ origin,
1842
+ mins,
1843
+ maxs,
1844
+ viewheight,
1845
+ trace,
1846
+ pointContents
1847
+ } = params;
1848
+ let pmFlags = params.pmFlags;
1849
+ let pmTime = params.pmTime;
1850
+ let impactDelta;
1851
+ let onGround = hasPmFlag(pmFlags, 4 /* OnGround */);
1852
+ let groundTrace;
1853
+ let groundContents = CONTENTS_NONE;
1854
+ const forceAirborne = velocity.z > LADDER_BYPASS_VELOCITY || pmType === 1 /* Grapple */;
1855
+ if (forceAirborne) {
1856
+ pmFlags = removePmFlag(pmFlags, 4 /* OnGround */);
1857
+ onGround = false;
1858
+ } else {
1859
+ const end = { x: origin.x, y: origin.y, z: origin.z - GROUND_PROBE_DISTANCE };
1860
+ const traceResult = trace(origin, end, mins, maxs);
1861
+ groundTrace = traceResult;
1862
+ groundContents = traceResult.contents ?? CONTENTS_NONE;
1863
+ const planeNormal = traceResult.planeNormal;
1864
+ let slantedGround = traceResult.fraction < 1 && !!planeNormal && planeNormal.z < SLANTED_NORMAL_THRESHOLD;
1865
+ if (slantedGround && planeNormal) {
1866
+ const slantEnd = addVec3(origin, planeNormal);
1867
+ const slantTrace = trace(origin, slantEnd, mins, maxs);
1868
+ if (slantTrace.fraction < 1 && !slantTrace.startsolid) {
1869
+ slantedGround = false;
1870
+ }
1871
+ }
1872
+ if (traceResult.fraction === 1 || !planeNormal || slantedGround && !traceResult.startsolid) {
1873
+ pmFlags = removePmFlag(pmFlags, 4 /* OnGround */);
1874
+ onGround = false;
1875
+ } else {
1876
+ onGround = true;
1877
+ if (hasPmFlag(pmFlags, 8 /* TimeWaterJump */)) {
1878
+ pmFlags &= ~WATERJUMP_CLEAR;
1879
+ pmTime = 0;
1880
+ }
1881
+ const wasOnGround = hasPmFlag(pmFlags, 4 /* OnGround */);
1882
+ if (!wasOnGround) {
1883
+ if (!n64Physics && velocity.z >= TRICK_VELOCITY_THRESHOLD && planeNormal.z >= TRICK_NORMAL_THRESHOLD && !hasPmFlag(pmFlags, 1 /* Ducked */)) {
1884
+ pmFlags = addPmFlag(pmFlags, 1024 /* TimeTrick */);
1885
+ pmTime = TRICK_PM_TIME;
1886
+ }
1887
+ const clipped = clipVelocityVec3(velocity, planeNormal, IMPACT_CLIP_OVERBOUNCE);
1888
+ impactDelta = startVelocity.z - clipped.z;
1889
+ }
1890
+ pmFlags = addPmFlag(pmFlags, 4 /* OnGround */);
1891
+ if (!wasOnGround && (n64Physics || hasPmFlag(pmFlags, 1 /* Ducked */))) {
1892
+ pmFlags = addPmFlag(pmFlags, 16 /* TimeLand */);
1893
+ pmTime = LAND_PM_TIME;
1894
+ }
1895
+ }
1896
+ }
1897
+ const { waterlevel, watertype } = getWaterLevel({
1898
+ origin,
1899
+ mins,
1900
+ viewheight,
1901
+ pointContents
1902
+ });
1903
+ return {
1904
+ pmFlags,
1905
+ pmTime,
1906
+ onGround: hasPmFlag(pmFlags, 4 /* OnGround */),
1907
+ groundTrace,
1908
+ groundContents,
1909
+ waterlevel,
1910
+ watertype,
1911
+ impactDelta
1912
+ };
1913
+ }
1914
+
1915
+ // src/pmove/move.ts
1916
+ var DEFAULT_AIR_ACCELERATE = 1;
1917
+ var WATER_DRIFT_SPEED = 60;
1918
+ var DEFAULT_STEP_OVERBOUNCE = 1.01;
1919
+ function applyPmoveAirMove(params) {
1920
+ const {
1921
+ origin,
1922
+ frametime,
1923
+ mins,
1924
+ maxs,
1925
+ trace,
1926
+ overbounce = DEFAULT_STEP_OVERBOUNCE,
1927
+ stepSize,
1928
+ maxBumps,
1929
+ maxClipPlanes,
1930
+ hasTime,
1931
+ forward,
1932
+ right,
1933
+ cmd,
1934
+ pmFlags,
1935
+ onGround,
1936
+ gravity,
1937
+ pmType,
1938
+ pmAccelerate,
1939
+ pmAirAccelerate = DEFAULT_AIR_ACCELERATE,
1940
+ pmMaxSpeed,
1941
+ pmDuckSpeed,
1942
+ onLadder,
1943
+ waterlevel,
1944
+ watertype,
1945
+ groundContents,
1946
+ viewPitch,
1947
+ ladderMod,
1948
+ pmWaterSpeed
1949
+ } = params;
1950
+ let velocity = { ...params.velocity };
1951
+ let wishvel = buildPlanarWishVelocity(forward, right, cmd);
1952
+ wishvel = applyPmoveAddCurrents({
1953
+ wishVelocity: wishvel,
1954
+ onLadder,
1955
+ onGround,
1956
+ waterlevel,
1957
+ watertype,
1958
+ groundContents,
1959
+ cmd,
1960
+ viewPitch,
1961
+ maxSpeed: hasPmFlag(pmFlags, 1 /* Ducked */) ? pmDuckSpeed : pmMaxSpeed,
1962
+ ladderMod,
1963
+ waterSpeed: pmWaterSpeed,
1964
+ forward,
1965
+ origin,
1966
+ mins,
1967
+ maxs,
1968
+ trace
1969
+ });
1970
+ const ducked = hasPmFlag(pmFlags, 1 /* Ducked */);
1971
+ const maxSpeed = ducked ? pmDuckSpeed : pmMaxSpeed;
1972
+ let wishdir = wishvel;
1973
+ let wishspeed = lengthVec3(wishdir);
1974
+ if (wishspeed !== 0) {
1975
+ wishdir = normalizeVec3(wishdir);
1976
+ }
1977
+ if (wishspeed > maxSpeed) {
1978
+ const scale = maxSpeed / wishspeed;
1979
+ wishvel = scaleVec3(wishvel, scale);
1980
+ wishspeed = maxSpeed;
1981
+ if (wishspeed !== 0) {
1982
+ wishdir = normalizeVec3(wishvel);
1983
+ }
1984
+ }
1985
+ if (onLadder) {
1986
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmAccelerate, frametime });
1987
+ if (Math.abs(wishvel.z) < Number.EPSILON) {
1988
+ velocity = dampVerticalVelocity(velocity, gravity, frametime);
1989
+ }
1990
+ return runStepSlideMove({
1991
+ origin,
1992
+ velocity,
1993
+ frametime,
1994
+ mins,
1995
+ maxs,
1996
+ trace,
1997
+ overbounce,
1998
+ stepSize,
1999
+ maxBumps,
2000
+ maxClipPlanes,
2001
+ hasTime
2002
+ });
2003
+ }
2004
+ if (onGround) {
2005
+ velocity = { ...velocity, z: 0 };
2006
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmAccelerate, frametime });
2007
+ if (gravity > 0) {
2008
+ velocity = { ...velocity, z: 0 };
2009
+ } else {
2010
+ velocity = { ...velocity, z: velocity.z - gravity * frametime };
2011
+ }
2012
+ if (velocity.x === 0 && velocity.y === 0) {
2013
+ return {
2014
+ origin,
2015
+ velocity,
2016
+ planes: [],
2017
+ blocked: 0,
2018
+ stopped: true,
2019
+ stepped: false,
2020
+ stepHeight: 0
2021
+ };
2022
+ }
2023
+ return runStepSlideMove({
2024
+ origin,
2025
+ velocity,
2026
+ frametime,
2027
+ mins,
2028
+ maxs,
2029
+ trace,
2030
+ overbounce,
2031
+ stepSize,
2032
+ maxBumps,
2033
+ maxClipPlanes,
2034
+ hasTime
2035
+ });
2036
+ }
2037
+ if (pmAirAccelerate > 0) {
2038
+ velocity = applyPmoveAirAccelerate({
2039
+ velocity,
2040
+ wishdir,
2041
+ wishspeed,
2042
+ accel: pmAirAccelerate,
2043
+ frametime
2044
+ });
2045
+ } else {
2046
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: DEFAULT_AIR_ACCELERATE, frametime });
2047
+ }
2048
+ if (pmType !== 1 /* Grapple */) {
2049
+ velocity = { ...velocity, z: velocity.z - gravity * frametime };
2050
+ }
2051
+ return runStepSlideMove({
2052
+ origin,
2053
+ velocity,
2054
+ frametime,
2055
+ mins,
2056
+ maxs,
2057
+ trace,
2058
+ overbounce,
2059
+ stepSize,
2060
+ maxBumps,
2061
+ maxClipPlanes,
2062
+ hasTime
2063
+ });
2064
+ }
2065
+ function applyPmoveWaterMove(params) {
2066
+ const {
2067
+ origin,
2068
+ frametime,
2069
+ mins,
2070
+ maxs,
2071
+ trace,
2072
+ overbounce = DEFAULT_STEP_OVERBOUNCE,
2073
+ stepSize,
2074
+ maxBumps,
2075
+ maxClipPlanes,
2076
+ hasTime,
2077
+ forward,
2078
+ right,
2079
+ cmd,
2080
+ pmFlags,
2081
+ onGround,
2082
+ pmMaxSpeed,
2083
+ pmDuckSpeed,
2084
+ pmWaterAccelerate,
2085
+ pmWaterSpeed,
2086
+ onLadder,
2087
+ watertype,
2088
+ groundContents,
2089
+ waterlevel,
2090
+ viewPitch,
2091
+ ladderMod
2092
+ } = params;
2093
+ let velocity = { ...params.velocity };
2094
+ let wishvel = buildFullWishVelocity(forward, right, cmd);
2095
+ if (isIdleInWater(cmd, onGround)) {
2096
+ wishvel = { ...wishvel, z: wishvel.z - WATER_DRIFT_SPEED };
2097
+ } else {
2098
+ if (hasButton2(cmd, 16 /* Crouch */)) {
2099
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: -pmWaterSpeed * 0.5 });
2100
+ } else if (hasButton2(cmd, 8 /* Jump */)) {
2101
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: pmWaterSpeed * 0.5 });
2102
+ }
2103
+ }
2104
+ wishvel = applyPmoveAddCurrents({
2105
+ wishVelocity: wishvel,
2106
+ onLadder,
2107
+ onGround,
2108
+ waterlevel,
2109
+ watertype,
2110
+ groundContents,
2111
+ cmd,
2112
+ viewPitch,
2113
+ maxSpeed: hasPmFlag(pmFlags, 1 /* Ducked */) ? pmDuckSpeed : pmMaxSpeed,
2114
+ ladderMod,
2115
+ waterSpeed: pmWaterSpeed,
2116
+ forward,
2117
+ origin,
2118
+ mins,
2119
+ maxs,
2120
+ trace
2121
+ });
2122
+ let wishdir = wishvel;
2123
+ let wishspeed = lengthVec3(wishdir);
2124
+ if (wishspeed !== 0) {
2125
+ wishdir = normalizeVec3(wishdir);
2126
+ }
2127
+ if (wishspeed > pmMaxSpeed) {
2128
+ const scale = pmMaxSpeed / wishspeed;
2129
+ wishvel = scaleVec3(wishvel, scale);
2130
+ wishspeed = pmMaxSpeed;
2131
+ if (wishspeed !== 0) {
2132
+ wishdir = normalizeVec3(wishvel);
2133
+ }
2134
+ }
2135
+ wishspeed *= 0.5;
2136
+ const ducked = hasPmFlag(pmFlags, 1 /* Ducked */);
2137
+ if (ducked && wishspeed > pmDuckSpeed) {
2138
+ const scale = pmDuckSpeed / wishspeed;
2139
+ wishvel = scaleVec3(wishvel, scale);
2140
+ wishspeed = pmDuckSpeed;
2141
+ if (wishspeed !== 0) {
2142
+ wishdir = normalizeVec3(wishvel);
2143
+ }
2144
+ }
2145
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmWaterAccelerate, frametime });
2146
+ return runStepSlideMove({
2147
+ origin,
2148
+ velocity,
2149
+ frametime,
2150
+ mins,
2151
+ maxs,
2152
+ trace,
2153
+ overbounce,
2154
+ stepSize,
2155
+ maxBumps,
2156
+ maxClipPlanes,
2157
+ hasTime
2158
+ });
2159
+ }
2160
+ function buildPlanarWishVelocity(forward, right, cmd) {
2161
+ return {
2162
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
2163
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
2164
+ z: 0
2165
+ };
2166
+ }
2167
+ function buildFullWishVelocity(forward, right, cmd) {
2168
+ return {
2169
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
2170
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
2171
+ z: forward.z * cmd.forwardmove + right.z * cmd.sidemove
2172
+ };
2173
+ }
2174
+ function hasButton2(cmd, button) {
2175
+ return (cmd.buttons ?? 0) & button ? true : false;
2176
+ }
2177
+ function isIdleInWater(cmd, onGround) {
2178
+ const noMove = cmd.forwardmove === 0 && cmd.sidemove === 0;
2179
+ const noButtons = (cmd.buttons ?? 0) & (8 /* Jump */ | 16 /* Crouch */) ? false : true;
2180
+ return noMove && noButtons && !onGround;
2181
+ }
2182
+ function dampVerticalVelocity(velocity, gravity, frametime) {
2183
+ let z = velocity.z;
2184
+ const delta = gravity * frametime;
2185
+ if (z > 0) {
2186
+ z -= delta;
2187
+ if (z < 0) {
2188
+ z = 0;
2189
+ }
2190
+ } else {
2191
+ z += delta;
2192
+ if (z > 0) {
2193
+ z = 0;
2194
+ }
2195
+ }
2196
+ return { ...velocity, z };
2197
+ }
2198
+ function runStepSlideMove(params) {
2199
+ const { origin, velocity, frametime, mins, maxs, trace, overbounce = DEFAULT_STEP_OVERBOUNCE, stepSize, maxBumps, maxClipPlanes, hasTime } = params;
2200
+ return stepSlideMove({
2201
+ origin,
2202
+ velocity,
2203
+ frametime,
2204
+ trace,
2205
+ mins,
2206
+ maxs,
2207
+ overbounce,
2208
+ stepSize,
2209
+ maxBumps,
2210
+ maxClipPlanes,
2211
+ hasTime
2212
+ });
2213
+ }
2214
+
2215
+ // src/pmove/special.ts
2216
+ var LADDER_TRACE_DISTANCE2 = 1;
2217
+ var WATERJUMP_FORWARD_CHECK = 40;
2218
+ var WATERJUMP_FORWARD_SPEED = 50;
2219
+ var WATERJUMP_UPWARD_SPEED = 350;
2220
+ var WATERJUMP_PM_TIME = 2048;
2221
+ var WATERJUMP_SIM_STEP = 0.1;
2222
+ var WATERJUMP_BASE_GRAVITY = 800;
2223
+ var WATERJUMP_MAX_STEPS = 50;
2224
+ var GROUND_NORMAL_THRESHOLD = 0.7;
2225
+ var WATERJUMP_STEP_TOLERANCE = 18;
2226
+ var DEFAULT_OVERBOUNCE2 = 1.01;
2227
+ var WATERJUMP_DOWN_PROBE = 2;
2228
+ function checkSpecialMovement(params) {
2229
+ const {
2230
+ pmFlags: initialFlags,
2231
+ pmTime: initialPmTime,
2232
+ waterlevel,
2233
+ watertype,
2234
+ gravity,
2235
+ cmd,
2236
+ forward,
2237
+ origin,
2238
+ velocity: initialVelocity,
2239
+ mins,
2240
+ maxs,
2241
+ viewheight,
2242
+ trace,
2243
+ pointContents,
2244
+ onGround,
2245
+ overbounce = DEFAULT_OVERBOUNCE2,
2246
+ stepSize = WATERJUMP_STEP_TOLERANCE,
2247
+ maxBumps,
2248
+ maxClipPlanes
2249
+ } = params;
2250
+ if (initialPmTime > 0) {
2251
+ return { pmFlags: initialFlags, pmTime: initialPmTime, velocity: initialVelocity, performedWaterJump: false };
2252
+ }
2253
+ let pmFlags = removePmFlag(initialFlags, 128 /* OnLadder */);
2254
+ let pmTime = initialPmTime;
2255
+ let velocity = initialVelocity;
2256
+ const flatforward = normalizeVec3({ x: forward.x, y: forward.y, z: 0 });
2257
+ const hasForward = lengthSquaredVec3(flatforward) > 0;
2258
+ if (waterlevel < 2 /* Waist */ && hasForward) {
2259
+ const ladderEnd = addVec3(origin, scaleVec3(flatforward, LADDER_TRACE_DISTANCE2));
2260
+ const ladderTrace = trace(origin, ladderEnd, mins, maxs);
2261
+ const contents = ladderTrace.contents ?? CONTENTS_NONE;
2262
+ if (ladderTrace.fraction < 1 && (contents & CONTENTS_LADDER) !== 0) {
2263
+ pmFlags = addPmFlag(pmFlags, 128 /* OnLadder */);
2264
+ }
2265
+ }
2266
+ if (gravity === 0) {
2267
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2268
+ }
2269
+ if (((cmd.buttons ?? 0) & 8 /* Jump */) === 0 && cmd.forwardmove <= 0) {
2270
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2271
+ }
2272
+ if (waterlevel !== 2 /* Waist */) {
2273
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2274
+ }
2275
+ if ((watertype & CONTENTS_NO_WATERJUMP) !== 0) {
2276
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2277
+ }
2278
+ if (!hasForward) {
2279
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2280
+ }
2281
+ const forwardCheckEnd = addVec3(origin, scaleVec3(flatforward, WATERJUMP_FORWARD_CHECK));
2282
+ const forwardTrace = trace(origin, forwardCheckEnd, mins, maxs);
2283
+ if (forwardTrace.fraction === 1 || !forwardTrace.planeNormal || forwardTrace.planeNormal.z >= GROUND_NORMAL_THRESHOLD) {
2284
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2285
+ }
2286
+ let simVelocity = {
2287
+ x: flatforward.x * WATERJUMP_FORWARD_SPEED,
2288
+ y: flatforward.y * WATERJUMP_FORWARD_SPEED,
2289
+ z: WATERJUMP_UPWARD_SPEED
2290
+ };
2291
+ let simOrigin = origin;
2292
+ let hasTime = true;
2293
+ const stepCount = computeWaterJumpSteps(gravity);
2294
+ for (let i = 0; i < stepCount; i++) {
2295
+ simVelocity = { x: simVelocity.x, y: simVelocity.y, z: simVelocity.z - gravity * WATERJUMP_SIM_STEP };
2296
+ if (simVelocity.z < 0) {
2297
+ hasTime = false;
2298
+ }
2299
+ const move = stepSlideMove({
2300
+ origin: simOrigin,
2301
+ velocity: simVelocity,
2302
+ frametime: WATERJUMP_SIM_STEP,
2303
+ trace,
2304
+ mins,
2305
+ maxs,
2306
+ overbounce,
2307
+ stepSize,
2308
+ maxBumps,
2309
+ maxClipPlanes,
2310
+ hasTime
2311
+ });
2312
+ simOrigin = move.origin;
2313
+ simVelocity = move.velocity;
2314
+ }
2315
+ const downEnd = addVec3(simOrigin, { x: 0, y: 0, z: -WATERJUMP_DOWN_PROBE });
2316
+ const downTrace = trace(simOrigin, downEnd, mins, maxs);
2317
+ if (downTrace.fraction === 1 || !downTrace.planeNormal || downTrace.planeNormal.z < GROUND_NORMAL_THRESHOLD || downTrace.endpos.z < origin.z) {
2318
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2319
+ }
2320
+ if (onGround && Math.abs(origin.z - downTrace.endpos.z) <= stepSize) {
2321
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2322
+ }
2323
+ const landingWater = getWaterLevel({ origin: downTrace.endpos, mins, viewheight, pointContents });
2324
+ if (landingWater.waterlevel >= 2 /* Waist */) {
2325
+ return { pmFlags, pmTime, velocity, performedWaterJump: false };
2326
+ }
2327
+ pmFlags = addPmFlag(pmFlags, 8 /* TimeWaterJump */);
2328
+ pmTime = WATERJUMP_PM_TIME;
2329
+ velocity = {
2330
+ x: flatforward.x * WATERJUMP_FORWARD_SPEED,
2331
+ y: flatforward.y * WATERJUMP_FORWARD_SPEED,
2332
+ z: WATERJUMP_UPWARD_SPEED
2333
+ };
2334
+ return { pmFlags, pmTime, velocity, performedWaterJump: true };
2335
+ }
2336
+ function computeWaterJumpSteps(gravity) {
2337
+ if (gravity === 0) {
2338
+ return 0;
2339
+ }
2340
+ const scaled = Math.floor(10 * (WATERJUMP_BASE_GRAVITY / gravity));
2341
+ if (scaled <= 0) {
2342
+ return 0;
2343
+ }
2344
+ return Math.min(WATERJUMP_MAX_STEPS, scaled);
2345
+ }
2346
+
2347
+ // src/pmove/snap.ts
2348
+ var SNAP_OFFSETS = [0, -1, 1];
2349
+ function goodPosition(params) {
2350
+ const { origin, mins, maxs, trace } = params;
2351
+ const result = trace(origin, origin, mins, maxs);
2352
+ return result.allsolid ? false : true;
2353
+ }
2354
+ function snapPosition(params) {
2355
+ const { origin, velocity, mins, maxs, previousOrigin, trace } = params;
2356
+ if (goodPosition({ origin, mins, maxs, trace })) {
2357
+ return { origin: { ...origin }, velocity: { ...velocity }, resolution: "unchanged" };
2358
+ }
2359
+ const fix = fixStuckObjectGeneric({
2360
+ origin,
2361
+ mins,
2362
+ maxs,
2363
+ trace: (start, localMins, localMaxs, end) => trace(start, end, localMins, localMaxs)
2364
+ });
2365
+ if (fix.result === "fixed" || fix.result === "good-position") {
2366
+ return { origin: fix.origin, velocity: { ...velocity }, resolution: "fixed" };
2367
+ }
2368
+ return { origin: { ...previousOrigin }, velocity: { ...velocity }, resolution: "reverted" };
2369
+ }
2370
+ function initialSnapPosition(params) {
2371
+ const { origin, mins, maxs, trace } = params;
2372
+ for (const oz of SNAP_OFFSETS) {
2373
+ for (const oy of SNAP_OFFSETS) {
2374
+ for (const ox of SNAP_OFFSETS) {
2375
+ const candidate = { x: origin.x + ox, y: origin.y + oy, z: origin.z + oz };
2376
+ if (goodPosition({ origin: candidate, mins, maxs, trace })) {
2377
+ const snapped = ox !== 0 || oy !== 0 || oz !== 0;
2378
+ return { origin: candidate, snapped };
2379
+ }
2380
+ }
2381
+ }
2382
+ }
2383
+ return { origin: { ...origin }, snapped: false };
2384
+ }
2385
+
2386
+ // src/pmove/view.ts
2387
+ function addAngles(cmdAngles, deltaAngles) {
2388
+ return {
2389
+ x: cmdAngles.x + deltaAngles.x,
2390
+ y: cmdAngles.y + deltaAngles.y,
2391
+ z: cmdAngles.z + deltaAngles.z
2392
+ };
2393
+ }
2394
+ function clampPitch(pitch) {
2395
+ if (pitch > 89 && pitch < 180) {
2396
+ return 89;
2397
+ }
2398
+ if (pitch < 271 && pitch >= 180) {
2399
+ return 271;
2400
+ }
2401
+ return pitch;
2402
+ }
2403
+ function clampViewAngles(params) {
2404
+ const { pmFlags, cmdAngles, deltaAngles } = params;
2405
+ let viewangles;
2406
+ if ((pmFlags & 32 /* TimeTeleport */) !== 0) {
2407
+ viewangles = {
2408
+ x: 0,
2409
+ y: cmdAngles.y + deltaAngles.y,
2410
+ z: 0
2411
+ };
2412
+ } else {
2413
+ viewangles = addAngles(cmdAngles, deltaAngles);
2414
+ viewangles = { ...viewangles, x: clampPitch(viewangles.x) };
2415
+ }
2416
+ const vectors = angleVectors(viewangles);
2417
+ return { viewangles, ...vectors };
2418
+ }
2419
+ export {
2420
+ CONTENTS_AREAPORTAL,
2421
+ CONTENTS_AUX,
2422
+ CONTENTS_CURRENT_0,
2423
+ CONTENTS_CURRENT_180,
2424
+ CONTENTS_CURRENT_270,
2425
+ CONTENTS_CURRENT_90,
2426
+ CONTENTS_CURRENT_DOWN,
2427
+ CONTENTS_CURRENT_UP,
2428
+ CONTENTS_DEADMONSTER,
2429
+ CONTENTS_DETAIL,
2430
+ CONTENTS_LADDER,
2431
+ CONTENTS_LAVA,
2432
+ CONTENTS_MIST,
2433
+ CONTENTS_MONSTER,
2434
+ CONTENTS_MONSTERCLIP,
2435
+ CONTENTS_NONE,
2436
+ CONTENTS_NO_WATERJUMP,
2437
+ CONTENTS_ORIGIN,
2438
+ CONTENTS_PLAYER,
2439
+ CONTENTS_PLAYERCLIP,
2440
+ CONTENTS_PROJECTILE,
2441
+ CONTENTS_PROJECTILECLIP,
2442
+ CONTENTS_SLIME,
2443
+ CONTENTS_SOLID,
2444
+ CONTENTS_TRANSLUCENT,
2445
+ CONTENTS_WATER,
2446
+ CONTENTS_WINDOW,
2447
+ CS_MAX_STRING_LENGTH,
2448
+ CS_MAX_STRING_LENGTH_OLD,
2449
+ ConfigStringIndex,
2450
+ CvarFlags,
2451
+ DIST_EPSILON,
2452
+ LAST_VISIBLE_CONTENTS,
2453
+ MASK_ALL,
2454
+ MASK_BLOCK_SIGHT,
2455
+ MASK_CURRENT,
2456
+ MASK_DEADSOLID,
2457
+ MASK_LADDER_NAV_SOLID,
2458
+ MASK_MONSTERSOLID,
2459
+ MASK_NAV_SOLID,
2460
+ MASK_OPAQUE,
2461
+ MASK_PLAYERSOLID,
2462
+ MASK_PROJECTILE,
2463
+ MASK_SHOT,
2464
+ MASK_SOLID,
2465
+ MASK_WALK_NAV_SOLID,
2466
+ MASK_WATER,
2467
+ MAX_CLIENTS,
2468
+ MAX_CONFIGSTRINGS,
2469
+ MAX_EDICTS,
2470
+ MAX_GENERAL,
2471
+ MAX_IMAGES,
2472
+ MAX_ITEMS,
2473
+ MAX_LIGHTSTYLES,
2474
+ MAX_MODELS,
2475
+ MAX_OSPATH,
2476
+ MAX_QPATH,
2477
+ MAX_SHADOW_LIGHTS,
2478
+ MAX_SOUNDS,
2479
+ MAX_STRING_CHARS,
2480
+ MAX_STRING_TOKENS,
2481
+ MAX_TOKEN_CHARS,
2482
+ MAX_WHEEL_ITEMS,
2483
+ MersenneTwister19937,
2484
+ PITCH,
2485
+ PlaneSide,
2486
+ PlayerButton,
2487
+ PmFlag,
2488
+ PmType,
2489
+ ROLL,
2490
+ RandomGenerator,
2491
+ SLIDEMOVE_BLOCKED_FLOOR,
2492
+ SLIDEMOVE_BLOCKED_WALL,
2493
+ STOP_EPSILON,
2494
+ SURF_ALPHATEST,
2495
+ SURF_FLOWING,
2496
+ SURF_LIGHT,
2497
+ SURF_N64_SCROLL_FLIP,
2498
+ SURF_N64_SCROLL_X,
2499
+ SURF_N64_SCROLL_Y,
2500
+ SURF_N64_UV,
2501
+ SURF_NODRAW,
2502
+ SURF_NONE,
2503
+ SURF_SKY,
2504
+ SURF_SLICK,
2505
+ SURF_TRANS33,
2506
+ SURF_TRANS66,
2507
+ SURF_WARP,
2508
+ WaterLevel,
2509
+ YAW,
2510
+ ZERO_VEC3,
2511
+ addBlendColor,
2512
+ addContents,
2513
+ addPmFlag,
2514
+ addPointToBounds,
2515
+ addVec3,
2516
+ angleMod,
2517
+ angleVectors,
2518
+ applyPmoveAccelerate,
2519
+ applyPmoveAddCurrents,
2520
+ applyPmoveAirAccelerate,
2521
+ applyPmoveAirMove,
2522
+ applyPmoveFlyMove,
2523
+ applyPmoveFriction,
2524
+ applyPmoveWaterMove,
2525
+ boxOnPlaneSide,
2526
+ boxesIntersect,
2527
+ buildAirGroundWish,
2528
+ buildCollisionModel,
2529
+ buildWaterWish,
2530
+ categorizePosition,
2531
+ checkDuckState,
2532
+ checkJump,
2533
+ checkSpecialMovement,
2534
+ clampViewAngles,
2535
+ clipBoxToBrush,
2536
+ clipVelocityAgainstPlanes,
2537
+ clipVelocityVec3,
2538
+ closestPointToBox,
2539
+ combineSurfaceFlags,
2540
+ computePlaneSignBits,
2541
+ computePlayerDimensions,
2542
+ concatRotationMatrices,
2543
+ configStringSize,
2544
+ createDefaultTrace,
2545
+ createEmptyBounds3,
2546
+ createRandomGenerator,
2547
+ crossVec3,
2548
+ currentVectorFromContents,
2549
+ degToRad,
2550
+ distanceBetweenBoxesSquared,
2551
+ dotVec3,
2552
+ fixStuckObjectGeneric,
2553
+ getWaterLevel,
2554
+ goodPosition,
2555
+ groundCurrentVelocity,
2556
+ hasAllContents,
2557
+ hasAnyContents,
2558
+ hasPmFlag,
2559
+ hasSurfaceFlags,
2560
+ initialSnapPosition,
2561
+ isAtLeastWaistDeep,
2562
+ isUnderwater,
2563
+ lengthSquaredVec3,
2564
+ lengthVec3,
2565
+ lerpAngle,
2566
+ multiplyVec3,
2567
+ negateVec3,
2568
+ normalizeVec3,
2569
+ perpendicularVec3,
2570
+ planeDistanceToPoint,
2571
+ pmoveCmdScale,
2572
+ pointInsideBrush,
2573
+ pointOnPlaneSide,
2574
+ projectPointOnPlane,
2575
+ projectSourceVec3,
2576
+ projectSourceVec3WithUp,
2577
+ radToDeg,
2578
+ removeContents,
2579
+ removePmFlag,
2580
+ resolveSlideMove,
2581
+ rotatePointAroundVector,
2582
+ scaleVec3,
2583
+ slerpVec3,
2584
+ slideClipVelocityVec3,
2585
+ slideMove,
2586
+ snapPosition,
2587
+ stepSlideMove,
2588
+ subtractVec3,
2589
+ testBoxInBrush,
2590
+ vectorToAngles,
2591
+ vectorToYaw,
2592
+ waterCurrentVelocity
2593
+ };
2594
+ //# sourceMappingURL=index.js.map