@quake2ts/shared 0.0.1

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 (209) hide show
  1. package/dist/browser/index.global.js +2 -0
  2. package/dist/browser/index.global.js.map +1 -0
  3. package/dist/cjs/index.cjs +6569 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/esm/index.js +6200 -0
  6. package/dist/esm/index.js.map +1 -0
  7. package/dist/tsconfig.tsbuildinfo +1 -0
  8. package/dist/types/audio/constants.d.ts +24 -0
  9. package/dist/types/audio/constants.d.ts.map +1 -0
  10. package/dist/types/bsp/collision.d.ts +201 -0
  11. package/dist/types/bsp/collision.d.ts.map +1 -0
  12. package/dist/types/bsp/contents.d.ts +72 -0
  13. package/dist/types/bsp/contents.d.ts.map +1 -0
  14. package/dist/types/bsp/spatial.d.ts +13 -0
  15. package/dist/types/bsp/spatial.d.ts.map +1 -0
  16. package/dist/types/index.d.ts +38 -0
  17. package/dist/types/index.d.ts.map +1 -0
  18. package/dist/types/inventory-helpers.d.ts +19 -0
  19. package/dist/types/inventory-helpers.d.ts.map +1 -0
  20. package/dist/types/io/binaryStream.d.ts +38 -0
  21. package/dist/types/io/binaryStream.d.ts.map +1 -0
  22. package/dist/types/io/binaryWriter.d.ts +26 -0
  23. package/dist/types/io/binaryWriter.d.ts.map +1 -0
  24. package/dist/types/io/index.d.ts +4 -0
  25. package/dist/types/io/index.d.ts.map +1 -0
  26. package/dist/types/io/messageBuilder.d.ts +21 -0
  27. package/dist/types/io/messageBuilder.d.ts.map +1 -0
  28. package/dist/types/items/ammo.d.ts +40 -0
  29. package/dist/types/items/ammo.d.ts.map +1 -0
  30. package/dist/types/items/index.d.ts +8 -0
  31. package/dist/types/items/index.d.ts.map +1 -0
  32. package/dist/types/items/powerups.d.ts +31 -0
  33. package/dist/types/items/powerups.d.ts.map +1 -0
  34. package/dist/types/items/weaponInfo.d.ts +5 -0
  35. package/dist/types/items/weaponInfo.d.ts.map +1 -0
  36. package/dist/types/items/weapons.d.ts +27 -0
  37. package/dist/types/items/weapons.d.ts.map +1 -0
  38. package/dist/types/math/angles.d.ts +19 -0
  39. package/dist/types/math/angles.d.ts.map +1 -0
  40. package/dist/types/math/anorms.d.ts +2 -0
  41. package/dist/types/math/anorms.d.ts.map +1 -0
  42. package/dist/types/math/color.d.ts +12 -0
  43. package/dist/types/math/color.d.ts.map +1 -0
  44. package/dist/types/math/mat4.d.ts +7 -0
  45. package/dist/types/math/mat4.d.ts.map +1 -0
  46. package/dist/types/math/random.d.ts +60 -0
  47. package/dist/types/math/random.d.ts.map +1 -0
  48. package/dist/types/math/vec3.d.ts +79 -0
  49. package/dist/types/math/vec3.d.ts.map +1 -0
  50. package/dist/types/net/driver.d.ts +10 -0
  51. package/dist/types/net/driver.d.ts.map +1 -0
  52. package/dist/types/net/index.d.ts +3 -0
  53. package/dist/types/net/index.d.ts.map +1 -0
  54. package/dist/types/net/netchan.d.ts +85 -0
  55. package/dist/types/net/netchan.d.ts.map +1 -0
  56. package/dist/types/pmove/apply.d.ts +5 -0
  57. package/dist/types/pmove/apply.d.ts.map +1 -0
  58. package/dist/types/pmove/categorize.d.ts +36 -0
  59. package/dist/types/pmove/categorize.d.ts.map +1 -0
  60. package/dist/types/pmove/config.d.ts +5 -0
  61. package/dist/types/pmove/config.d.ts.map +1 -0
  62. package/dist/types/pmove/constants.d.ts +76 -0
  63. package/dist/types/pmove/constants.d.ts.map +1 -0
  64. package/dist/types/pmove/currents.d.ts +58 -0
  65. package/dist/types/pmove/currents.d.ts.map +1 -0
  66. package/dist/types/pmove/dimensions.d.ts +14 -0
  67. package/dist/types/pmove/dimensions.d.ts.map +1 -0
  68. package/dist/types/pmove/duck.d.ts +39 -0
  69. package/dist/types/pmove/duck.d.ts.map +1 -0
  70. package/dist/types/pmove/fly.d.ts +34 -0
  71. package/dist/types/pmove/fly.d.ts.map +1 -0
  72. package/dist/types/pmove/index.d.ts +18 -0
  73. package/dist/types/pmove/index.d.ts.map +1 -0
  74. package/dist/types/pmove/jump.d.ts +28 -0
  75. package/dist/types/pmove/jump.d.ts.map +1 -0
  76. package/dist/types/pmove/move.d.ts +78 -0
  77. package/dist/types/pmove/move.d.ts.map +1 -0
  78. package/dist/types/pmove/pmove.d.ts +40 -0
  79. package/dist/types/pmove/pmove.d.ts.map +1 -0
  80. package/dist/types/pmove/slide.d.ts +63 -0
  81. package/dist/types/pmove/slide.d.ts.map +1 -0
  82. package/dist/types/pmove/snap.d.ts +40 -0
  83. package/dist/types/pmove/snap.d.ts.map +1 -0
  84. package/dist/types/pmove/special.d.ts +39 -0
  85. package/dist/types/pmove/special.d.ts.map +1 -0
  86. package/dist/types/pmove/stuck.d.ts +21 -0
  87. package/dist/types/pmove/stuck.d.ts.map +1 -0
  88. package/dist/types/pmove/types.d.ts +72 -0
  89. package/dist/types/pmove/types.d.ts.map +1 -0
  90. package/dist/types/pmove/view.d.ts +19 -0
  91. package/dist/types/pmove/view.d.ts.map +1 -0
  92. package/dist/types/pmove/water.d.ts +21 -0
  93. package/dist/types/pmove/water.d.ts.map +1 -0
  94. package/dist/types/protocol/bitpack.d.ts +17 -0
  95. package/dist/types/protocol/bitpack.d.ts.map +1 -0
  96. package/dist/types/protocol/configstrings.d.ts +73 -0
  97. package/dist/types/protocol/configstrings.d.ts.map +1 -0
  98. package/dist/types/protocol/constants.d.ts +36 -0
  99. package/dist/types/protocol/constants.d.ts.map +1 -0
  100. package/dist/types/protocol/contracts.d.ts +17 -0
  101. package/dist/types/protocol/contracts.d.ts.map +1 -0
  102. package/dist/types/protocol/crc.d.ts +5 -0
  103. package/dist/types/protocol/crc.d.ts.map +1 -0
  104. package/dist/types/protocol/cvar.d.ts +15 -0
  105. package/dist/types/protocol/cvar.d.ts.map +1 -0
  106. package/dist/types/protocol/effects.d.ts +33 -0
  107. package/dist/types/protocol/effects.d.ts.map +1 -0
  108. package/dist/types/protocol/entity.d.ts +46 -0
  109. package/dist/types/protocol/entity.d.ts.map +1 -0
  110. package/dist/types/protocol/entityEvent.d.ts +13 -0
  111. package/dist/types/protocol/entityEvent.d.ts.map +1 -0
  112. package/dist/types/protocol/entityState.d.ts +26 -0
  113. package/dist/types/protocol/entityState.d.ts.map +1 -0
  114. package/dist/types/protocol/index.d.ts +19 -0
  115. package/dist/types/protocol/index.d.ts.map +1 -0
  116. package/dist/types/protocol/layout.d.ts +9 -0
  117. package/dist/types/protocol/layout.d.ts.map +1 -0
  118. package/dist/types/protocol/ops.d.ts +44 -0
  119. package/dist/types/protocol/ops.d.ts.map +1 -0
  120. package/dist/types/protocol/player-state.d.ts +40 -0
  121. package/dist/types/protocol/player-state.d.ts.map +1 -0
  122. package/dist/types/protocol/player.d.ts +28 -0
  123. package/dist/types/protocol/player.d.ts.map +1 -0
  124. package/dist/types/protocol/renderFx.d.ts +23 -0
  125. package/dist/types/protocol/renderFx.d.ts.map +1 -0
  126. package/dist/types/protocol/stats.d.ts +61 -0
  127. package/dist/types/protocol/stats.d.ts.map +1 -0
  128. package/dist/types/protocol/tempEntity.d.ts +67 -0
  129. package/dist/types/protocol/tempEntity.d.ts.map +1 -0
  130. package/dist/types/protocol/usercmd.d.ts +33 -0
  131. package/dist/types/protocol/usercmd.d.ts.map +1 -0
  132. package/dist/types/protocol/writeUserCmd.d.ts +4 -0
  133. package/dist/types/protocol/writeUserCmd.d.ts.map +1 -0
  134. package/dist/types/replay/index.d.ts +3 -0
  135. package/dist/types/replay/index.d.ts.map +1 -0
  136. package/dist/types/replay/io.d.ts +7 -0
  137. package/dist/types/replay/io.d.ts.map +1 -0
  138. package/dist/types/replay/schema.d.ts +41 -0
  139. package/dist/types/replay/schema.d.ts.map +1 -0
  140. package/dist/types/testing.d.ts +6 -0
  141. package/dist/types/testing.d.ts.map +1 -0
  142. package/package.json +43 -0
  143. package/src/audio/constants.ts +35 -0
  144. package/src/bsp/collision.ts +1075 -0
  145. package/src/bsp/contents.ts +108 -0
  146. package/src/bsp/spatial.ts +116 -0
  147. package/src/index.ts +37 -0
  148. package/src/inventory-helpers.ts +81 -0
  149. package/src/io/binaryStream.ts +159 -0
  150. package/src/io/binaryWriter.ts +146 -0
  151. package/src/io/index.ts +3 -0
  152. package/src/io/messageBuilder.ts +117 -0
  153. package/src/items/ammo.ts +47 -0
  154. package/src/items/index.ts +8 -0
  155. package/src/items/powerups.ts +32 -0
  156. package/src/items/weaponInfo.ts +45 -0
  157. package/src/items/weapons.ts +28 -0
  158. package/src/math/angles.ts +135 -0
  159. package/src/math/anorms.ts +165 -0
  160. package/src/math/color.ts +42 -0
  161. package/src/math/mat4.ts +58 -0
  162. package/src/math/random.ts +182 -0
  163. package/src/math/vec3.ts +379 -0
  164. package/src/net/driver.ts +9 -0
  165. package/src/net/index.ts +2 -0
  166. package/src/net/netchan.ts +451 -0
  167. package/src/pmove/apply.ts +151 -0
  168. package/src/pmove/categorize.ts +162 -0
  169. package/src/pmove/config.ts +5 -0
  170. package/src/pmove/constants.ts +94 -0
  171. package/src/pmove/currents.ts +287 -0
  172. package/src/pmove/dimensions.ts +40 -0
  173. package/src/pmove/duck.ts +154 -0
  174. package/src/pmove/fly.ts +197 -0
  175. package/src/pmove/index.ts +18 -0
  176. package/src/pmove/jump.ts +92 -0
  177. package/src/pmove/move.ts +527 -0
  178. package/src/pmove/pmove.ts +446 -0
  179. package/src/pmove/slide.ts +267 -0
  180. package/src/pmove/snap.ts +89 -0
  181. package/src/pmove/special.ts +207 -0
  182. package/src/pmove/stuck.ts +258 -0
  183. package/src/pmove/types.ts +82 -0
  184. package/src/pmove/view.ts +57 -0
  185. package/src/pmove/water.ts +56 -0
  186. package/src/protocol/bitpack.ts +139 -0
  187. package/src/protocol/configstrings.ts +104 -0
  188. package/src/protocol/constants.ts +40 -0
  189. package/src/protocol/contracts.ts +149 -0
  190. package/src/protocol/crc.ts +32 -0
  191. package/src/protocol/cvar.ts +15 -0
  192. package/src/protocol/effects.ts +33 -0
  193. package/src/protocol/entity.ts +304 -0
  194. package/src/protocol/entityEvent.ts +14 -0
  195. package/src/protocol/entityState.ts +28 -0
  196. package/src/protocol/index.ts +19 -0
  197. package/src/protocol/layout.ts +9 -0
  198. package/src/protocol/ops.ts +49 -0
  199. package/src/protocol/player-state.ts +51 -0
  200. package/src/protocol/player.ts +165 -0
  201. package/src/protocol/renderFx.ts +22 -0
  202. package/src/protocol/stats.ts +161 -0
  203. package/src/protocol/tempEntity.ts +69 -0
  204. package/src/protocol/usercmd.ts +63 -0
  205. package/src/protocol/writeUserCmd.ts +30 -0
  206. package/src/replay/index.ts +2 -0
  207. package/src/replay/io.ts +37 -0
  208. package/src/replay/schema.ts +42 -0
  209. package/src/testing.ts +200 -0
@@ -0,0 +1,527 @@
1
+ import type { Vec3 } from '../math/vec3.js';
2
+ import { addVec3, lengthVec3, normalizeVec3, scaleVec3 } from '../math/vec3.js';
3
+ import { applyPmoveAccelerate, applyPmoveAirAccelerate } from './pmove.js';
4
+ import { applyPmoveAddCurrents } from './currents.js';
5
+ import { stepSlideMove, type StepSlideMoveOutcome } from './slide.js';
6
+ import type { PmoveCmd, PmoveTraceFn } from './types.js';
7
+ import {
8
+ PmFlag,
9
+ type PmFlags,
10
+ PmType,
11
+ PlayerButton,
12
+ WaterLevel,
13
+ hasPmFlag,
14
+ } from './constants.js';
15
+
16
+ interface BaseMoveParams {
17
+ readonly origin: Vec3;
18
+ readonly velocity: Vec3;
19
+ readonly frametime: number;
20
+ readonly mins: Vec3;
21
+ readonly maxs: Vec3;
22
+ readonly trace: PmoveTraceFn;
23
+ readonly overbounce?: number;
24
+ readonly stepSize?: number;
25
+ readonly maxBumps?: number;
26
+ readonly maxClipPlanes?: number;
27
+ readonly hasTime?: boolean;
28
+ }
29
+
30
+ export interface AirMoveParams extends BaseMoveParams {
31
+ readonly cmd: PmoveCmd;
32
+ readonly forward: Vec3;
33
+ readonly right: Vec3;
34
+ readonly pmFlags: PmFlags;
35
+ readonly onGround: boolean;
36
+ readonly gravity: number;
37
+ readonly pmType: PmType;
38
+ readonly pmAccelerate: number;
39
+ readonly pmAirAccelerate?: number;
40
+ readonly pmMaxSpeed: number;
41
+ readonly pmDuckSpeed: number;
42
+ readonly onLadder: boolean;
43
+ readonly waterlevel: WaterLevel;
44
+ readonly watertype: number;
45
+ readonly groundContents: number;
46
+ readonly viewPitch: number;
47
+ readonly ladderMod: number;
48
+ readonly pmWaterSpeed: number;
49
+ }
50
+
51
+ export interface WaterMoveParams extends BaseMoveParams {
52
+ readonly cmd: PmoveCmd;
53
+ readonly forward: Vec3;
54
+ readonly right: Vec3;
55
+ readonly pmFlags: PmFlags;
56
+ readonly onGround: boolean;
57
+ readonly pmMaxSpeed: number;
58
+ readonly pmDuckSpeed: number;
59
+ readonly pmWaterAccelerate: number;
60
+ readonly pmWaterSpeed: number;
61
+ readonly onLadder: boolean;
62
+ readonly watertype: number;
63
+ readonly groundContents: number;
64
+ readonly waterlevel: WaterLevel;
65
+ readonly viewPitch: number;
66
+ readonly ladderMod: number;
67
+ }
68
+
69
+ export interface WalkMoveParams extends BaseMoveParams {
70
+ readonly cmd: PmoveCmd;
71
+ readonly forward: Vec3;
72
+ readonly right: Vec3;
73
+ readonly pmFlags: PmFlags;
74
+ readonly onGround: boolean;
75
+ readonly gravity: number;
76
+ readonly pmType: PmType;
77
+ readonly pmAccelerate: number;
78
+ readonly pmMaxSpeed: number;
79
+ readonly pmDuckSpeed: number;
80
+ readonly onLadder: boolean;
81
+ readonly waterlevel: WaterLevel;
82
+ readonly watertype: number;
83
+ readonly groundContents: number;
84
+ readonly viewPitch: number;
85
+ readonly ladderMod: number;
86
+ readonly pmWaterSpeed: number;
87
+ }
88
+
89
+ const DEFAULT_AIR_ACCELERATE = 1;
90
+ const WATER_DRIFT_SPEED = 60;
91
+ const DEFAULT_STEP_OVERBOUNCE = 1.01;
92
+
93
+ export function applyPmoveAirMove(params: AirMoveParams): StepSlideMoveOutcome {
94
+ const {
95
+ origin,
96
+ frametime,
97
+ mins,
98
+ maxs,
99
+ trace,
100
+ overbounce = DEFAULT_STEP_OVERBOUNCE,
101
+ stepSize,
102
+ maxBumps,
103
+ maxClipPlanes,
104
+ hasTime,
105
+ forward,
106
+ right,
107
+ cmd,
108
+ pmFlags,
109
+ onGround,
110
+ gravity,
111
+ pmType,
112
+ pmAccelerate,
113
+ pmAirAccelerate = DEFAULT_AIR_ACCELERATE,
114
+ pmMaxSpeed,
115
+ pmDuckSpeed,
116
+ onLadder,
117
+ waterlevel,
118
+ watertype,
119
+ groundContents,
120
+ viewPitch,
121
+ ladderMod,
122
+ pmWaterSpeed,
123
+ } = params;
124
+
125
+ let velocity = { ...params.velocity };
126
+ let wishvel = buildPlanarWishVelocity(forward, right, cmd);
127
+
128
+ wishvel = applyPmoveAddCurrents({
129
+ wishVelocity: wishvel,
130
+ onLadder,
131
+ onGround,
132
+ waterlevel,
133
+ watertype,
134
+ groundContents,
135
+ cmd,
136
+ viewPitch,
137
+ maxSpeed: hasPmFlag(pmFlags, PmFlag.Ducked) ? pmDuckSpeed : pmMaxSpeed,
138
+ ladderMod,
139
+ waterSpeed: pmWaterSpeed,
140
+ forward,
141
+ origin,
142
+ mins,
143
+ maxs,
144
+ trace,
145
+ });
146
+
147
+ const ducked = hasPmFlag(pmFlags, PmFlag.Ducked);
148
+ const maxSpeed = ducked ? pmDuckSpeed : pmMaxSpeed;
149
+
150
+ let wishdir = wishvel;
151
+ let wishspeed = lengthVec3(wishdir);
152
+ if (wishspeed !== 0) {
153
+ wishdir = normalizeVec3(wishdir);
154
+ }
155
+
156
+ if (wishspeed > maxSpeed) {
157
+ const scale = maxSpeed / wishspeed;
158
+ wishvel = scaleVec3(wishvel, scale);
159
+ wishspeed = maxSpeed;
160
+ if (wishspeed !== 0) {
161
+ wishdir = normalizeVec3(wishvel);
162
+ }
163
+ }
164
+
165
+ if (onLadder) {
166
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmAccelerate, frametime });
167
+ if (Math.abs(wishvel.z) < Number.EPSILON) {
168
+ velocity = dampVerticalVelocity(velocity, gravity, frametime);
169
+ }
170
+ return runStepSlideMove({
171
+ origin,
172
+ velocity,
173
+ frametime,
174
+ mins,
175
+ maxs,
176
+ trace,
177
+ overbounce,
178
+ stepSize,
179
+ maxBumps,
180
+ maxClipPlanes,
181
+ hasTime,
182
+ });
183
+ }
184
+
185
+ if (onGround) {
186
+ velocity = { ...velocity, z: 0 };
187
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmAccelerate, frametime });
188
+ if (gravity > 0) {
189
+ velocity = { ...velocity, z: 0 };
190
+ } else {
191
+ velocity = { ...velocity, z: velocity.z - gravity * frametime };
192
+ }
193
+
194
+ if (velocity.x === 0 && velocity.y === 0) {
195
+ return {
196
+ origin,
197
+ velocity,
198
+ planes: [],
199
+ blocked: 0,
200
+ stopped: true,
201
+ stepped: false,
202
+ stepHeight: 0,
203
+ };
204
+ }
205
+
206
+ return runStepSlideMove({
207
+ origin,
208
+ velocity,
209
+ frametime,
210
+ mins,
211
+ maxs,
212
+ trace,
213
+ overbounce,
214
+ stepSize,
215
+ maxBumps,
216
+ maxClipPlanes,
217
+ hasTime,
218
+ });
219
+ }
220
+
221
+ if (pmAirAccelerate > 0) {
222
+ velocity = applyPmoveAirAccelerate({
223
+ velocity,
224
+ wishdir,
225
+ wishspeed,
226
+ accel: pmAirAccelerate,
227
+ frametime,
228
+ });
229
+ } else {
230
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: DEFAULT_AIR_ACCELERATE, frametime });
231
+ }
232
+
233
+ if (pmType !== PmType.Grapple) {
234
+ velocity = { ...velocity, z: velocity.z - gravity * frametime };
235
+ }
236
+
237
+ return runStepSlideMove({
238
+ origin,
239
+ velocity,
240
+ frametime,
241
+ mins,
242
+ maxs,
243
+ trace,
244
+ overbounce,
245
+ stepSize,
246
+ maxBumps,
247
+ maxClipPlanes,
248
+ hasTime,
249
+ });
250
+ }
251
+
252
+ export function applyPmoveWaterMove(params: WaterMoveParams): StepSlideMoveOutcome {
253
+ const {
254
+ origin,
255
+ frametime,
256
+ mins,
257
+ maxs,
258
+ trace,
259
+ overbounce = DEFAULT_STEP_OVERBOUNCE,
260
+ stepSize,
261
+ maxBumps,
262
+ maxClipPlanes,
263
+ hasTime,
264
+ forward,
265
+ right,
266
+ cmd,
267
+ pmFlags,
268
+ onGround,
269
+ pmMaxSpeed,
270
+ pmDuckSpeed,
271
+ pmWaterAccelerate,
272
+ pmWaterSpeed,
273
+ onLadder,
274
+ watertype,
275
+ groundContents,
276
+ waterlevel,
277
+ viewPitch,
278
+ ladderMod,
279
+ } = params;
280
+
281
+ let velocity = { ...params.velocity };
282
+ let wishvel = buildFullWishVelocity(forward, right, cmd);
283
+
284
+ if (isIdleInWater(cmd, onGround)) {
285
+ wishvel = { ...wishvel, z: wishvel.z - WATER_DRIFT_SPEED };
286
+ } else {
287
+ if (hasButton(cmd, PlayerButton.Crouch)) {
288
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: -pmWaterSpeed * 0.5 });
289
+ } else if (hasButton(cmd, PlayerButton.Jump)) {
290
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: pmWaterSpeed * 0.5 });
291
+ }
292
+ }
293
+
294
+ wishvel = applyPmoveAddCurrents({
295
+ wishVelocity: wishvel,
296
+ onLadder,
297
+ onGround,
298
+ waterlevel,
299
+ watertype,
300
+ groundContents,
301
+ cmd,
302
+ viewPitch,
303
+ maxSpeed: hasPmFlag(pmFlags, PmFlag.Ducked) ? pmDuckSpeed : pmMaxSpeed,
304
+ ladderMod,
305
+ waterSpeed: pmWaterSpeed,
306
+ forward,
307
+ origin,
308
+ mins,
309
+ maxs,
310
+ trace,
311
+ });
312
+
313
+ let wishdir = wishvel;
314
+ let wishspeed = lengthVec3(wishdir);
315
+ if (wishspeed !== 0) {
316
+ wishdir = normalizeVec3(wishdir);
317
+ }
318
+
319
+ if (wishspeed > pmMaxSpeed) {
320
+ const scale = pmMaxSpeed / wishspeed;
321
+ wishvel = scaleVec3(wishvel, scale);
322
+ wishspeed = pmMaxSpeed;
323
+ if (wishspeed !== 0) {
324
+ wishdir = normalizeVec3(wishvel);
325
+ }
326
+ }
327
+
328
+ wishspeed *= 0.5;
329
+
330
+ const ducked = hasPmFlag(pmFlags, PmFlag.Ducked);
331
+ if (ducked && wishspeed > pmDuckSpeed) {
332
+ const scale = pmDuckSpeed / wishspeed;
333
+ wishvel = scaleVec3(wishvel, scale);
334
+ wishspeed = pmDuckSpeed;
335
+ if (wishspeed !== 0) {
336
+ wishdir = normalizeVec3(wishvel);
337
+ }
338
+ }
339
+
340
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmWaterAccelerate, frametime });
341
+
342
+ return runStepSlideMove({
343
+ origin,
344
+ velocity,
345
+ frametime,
346
+ mins,
347
+ maxs,
348
+ trace,
349
+ overbounce,
350
+ stepSize,
351
+ maxBumps,
352
+ maxClipPlanes,
353
+ hasTime,
354
+ });
355
+ }
356
+
357
+ export function applyPmoveWalkMove(params: WalkMoveParams): StepSlideMoveOutcome {
358
+ const {
359
+ origin,
360
+ frametime,
361
+ mins,
362
+ maxs,
363
+ trace,
364
+ overbounce = DEFAULT_STEP_OVERBOUNCE,
365
+ stepSize,
366
+ maxBumps,
367
+ maxClipPlanes,
368
+ hasTime,
369
+ forward,
370
+ right,
371
+ cmd,
372
+ pmFlags,
373
+ onGround,
374
+ gravity,
375
+ pmAccelerate,
376
+ pmMaxSpeed,
377
+ pmDuckSpeed,
378
+ onLadder,
379
+ waterlevel,
380
+ watertype,
381
+ groundContents,
382
+ viewPitch,
383
+ ladderMod,
384
+ pmWaterSpeed,
385
+ } = params;
386
+
387
+ let velocity = { ...params.velocity };
388
+ let wishvel = buildPlanarWishVelocity(forward, right, cmd);
389
+
390
+ wishvel = applyPmoveAddCurrents({
391
+ wishVelocity: wishvel,
392
+ onLadder,
393
+ onGround,
394
+ waterlevel,
395
+ watertype,
396
+ groundContents,
397
+ cmd,
398
+ viewPitch,
399
+ maxSpeed: hasPmFlag(pmFlags, PmFlag.Ducked) ? pmDuckSpeed : pmMaxSpeed,
400
+ ladderMod,
401
+ waterSpeed: pmWaterSpeed,
402
+ forward,
403
+ origin,
404
+ mins,
405
+ maxs,
406
+ trace,
407
+ });
408
+
409
+ const ducked = hasPmFlag(pmFlags, PmFlag.Ducked);
410
+ const maxSpeed = ducked ? pmDuckSpeed : pmMaxSpeed;
411
+
412
+ let wishdir = wishvel;
413
+ let wishspeed = lengthVec3(wishdir);
414
+ if (wishspeed !== 0) {
415
+ wishdir = normalizeVec3(wishdir);
416
+ }
417
+
418
+ if (wishspeed > maxSpeed) {
419
+ const scale = maxSpeed / wishspeed;
420
+ wishvel = scaleVec3(wishvel, scale);
421
+ wishspeed = maxSpeed;
422
+ if (wishspeed !== 0) {
423
+ wishdir = normalizeVec3(wishvel);
424
+ }
425
+ }
426
+
427
+ // Ground friction handled by caller (applyPmoveFriction)
428
+
429
+ velocity = { ...velocity, z: 0 };
430
+ velocity = applyPmoveAccelerate({ velocity, wishdir, wishspeed, accel: pmAccelerate, frametime });
431
+
432
+ if (gravity > 0) {
433
+ velocity = { ...velocity, z: 0 };
434
+ } else {
435
+ velocity = { ...velocity, z: velocity.z - gravity * frametime };
436
+ }
437
+
438
+ if (velocity.x === 0 && velocity.y === 0) {
439
+ return {
440
+ origin,
441
+ velocity,
442
+ planes: [],
443
+ blocked: 0,
444
+ stopped: true,
445
+ stepped: false,
446
+ stepHeight: 0,
447
+ };
448
+ }
449
+
450
+ return runStepSlideMove({
451
+ origin,
452
+ velocity,
453
+ frametime,
454
+ mins,
455
+ maxs,
456
+ trace,
457
+ overbounce,
458
+ stepSize,
459
+ maxBumps,
460
+ maxClipPlanes,
461
+ hasTime,
462
+ });
463
+ }
464
+
465
+ function buildPlanarWishVelocity(forward: Vec3, right: Vec3, cmd: PmoveCmd): Vec3 {
466
+ return {
467
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
468
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
469
+ z: 0,
470
+ } satisfies Vec3;
471
+ }
472
+
473
+ function buildFullWishVelocity(forward: Vec3, right: Vec3, cmd: PmoveCmd): Vec3 {
474
+ return {
475
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
476
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
477
+ z: forward.z * cmd.forwardmove + right.z * cmd.sidemove,
478
+ } satisfies Vec3;
479
+ }
480
+
481
+ function hasButton(cmd: PmoveCmd, button: PlayerButton): boolean {
482
+ return (cmd.buttons ?? 0) & button ? true : false;
483
+ }
484
+
485
+ function isIdleInWater(cmd: PmoveCmd, onGround: boolean): boolean {
486
+ const noMove = cmd.forwardmove === 0 && cmd.sidemove === 0;
487
+ const noButtons = (cmd.buttons ?? 0) & (PlayerButton.Jump | PlayerButton.Crouch) ? false : true;
488
+ return noMove && noButtons && !onGround;
489
+ }
490
+
491
+ function dampVerticalVelocity(velocity: Vec3, gravity: number, frametime: number): Vec3 {
492
+ let z = velocity.z;
493
+ const delta = gravity * frametime;
494
+ if (z > 0) {
495
+ z -= delta;
496
+ if (z < 0) {
497
+ z = 0;
498
+ }
499
+ } else {
500
+ z += delta;
501
+ if (z > 0) {
502
+ z = 0;
503
+ }
504
+ }
505
+ return { ...velocity, z };
506
+ }
507
+
508
+ interface StepParams extends BaseMoveParams {
509
+ readonly velocity: Vec3;
510
+ }
511
+
512
+ function runStepSlideMove(params: StepParams): StepSlideMoveOutcome {
513
+ const { origin, velocity, frametime, mins, maxs, trace, overbounce = DEFAULT_STEP_OVERBOUNCE, stepSize, maxBumps, maxClipPlanes, hasTime } = params;
514
+ return stepSlideMove({
515
+ origin,
516
+ velocity,
517
+ frametime,
518
+ trace,
519
+ mins,
520
+ maxs,
521
+ overbounce,
522
+ stepSize,
523
+ maxBumps,
524
+ maxClipPlanes,
525
+ hasTime,
526
+ });
527
+ }