@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,304 @@
1
+ import { BinaryWriter } from '../io/index.js';
2
+ import { EntityState } from './entityState.js';
3
+
4
+ // Constants matching packages/engine/src/demo/parser.ts
5
+ export const U_ORIGIN1 = (1 << 0);
6
+ export const U_ORIGIN2 = (1 << 1);
7
+ export const U_ANGLE2 = (1 << 2);
8
+ export const U_ANGLE3 = (1 << 3);
9
+ export const U_FRAME8 = (1 << 4);
10
+ export const U_EVENT = (1 << 5);
11
+ export const U_REMOVE = (1 << 6);
12
+ export const U_MOREBITS1 = (1 << 7);
13
+
14
+ export const U_NUMBER16 = (1 << 8);
15
+ export const U_ORIGIN3 = (1 << 9);
16
+ export const U_ANGLE1 = (1 << 10);
17
+ export const U_MODEL = (1 << 11);
18
+ export const U_RENDERFX8 = (1 << 12);
19
+ export const U_ALPHA = (1 << 13); // Rerelease: Alpha
20
+ export const U_EFFECTS8 = (1 << 14);
21
+ export const U_MOREBITS2 = (1 << 15);
22
+
23
+ export const U_SKIN8 = (1 << 16);
24
+ export const U_FRAME16 = (1 << 17);
25
+ export const U_RENDERFX16 = (1 << 18);
26
+ export const U_EFFECTS16 = (1 << 19);
27
+ export const U_MODEL2 = (1 << 20); // Rerelease
28
+ export const U_MODEL3 = (1 << 21); // Rerelease
29
+ export const U_MODEL4 = (1 << 22); // Rerelease
30
+ export const U_MOREBITS3 = (1 << 23);
31
+
32
+ export const U_OLDORIGIN = (1 << 24);
33
+ export const U_SKIN16 = (1 << 25);
34
+ export const U_SOUND = (1 << 26);
35
+ export const U_SOLID = (1 << 27);
36
+ export const U_SCALE = (1 << 28); // Rerelease
37
+ export const U_INSTANCE_BITS = (1 << 29); // Rerelease
38
+ export const U_LOOP_VOLUME = (1 << 30); // Rerelease
39
+ export const U_MOREBITS4 = 0x80000000 | 0; // Bit 31 (sign bit)
40
+
41
+ // Rerelease Extension Bits (Byte 5 - High Bits)
42
+ export const U_LOOP_ATTENUATION_HIGH = (1 << 0);
43
+ export const U_OWNER_HIGH = (1 << 1);
44
+ export const U_OLD_FRAME_HIGH = (1 << 2);
45
+
46
+
47
+ // A null state for new entities, used as a baseline for comparison.
48
+ const NULL_STATE: EntityState = {
49
+ number: 0,
50
+ origin: { x: 0, y: 0, z: 0 },
51
+ angles: { x: 0, y: 0, z: 0 },
52
+ modelIndex: 0,
53
+ frame: 0,
54
+ skinNum: 0,
55
+ effects: 0,
56
+ renderfx: 0,
57
+ solid: 0,
58
+ sound: 0,
59
+ event: 0,
60
+ alpha: 0,
61
+ scale: 0,
62
+ instanceBits: 0,
63
+ loopVolume: 0,
64
+ loopAttenuation: 0,
65
+ owner: 0,
66
+ oldFrame: 0,
67
+ modelIndex2: 0,
68
+ modelIndex3: 0,
69
+ modelIndex4: 0
70
+ };
71
+
72
+ /**
73
+ * Writes the remove bit for an entity.
74
+ */
75
+ export function writeRemoveEntity(
76
+ number: number,
77
+ writer: BinaryWriter
78
+ ): void {
79
+ let bits = U_REMOVE;
80
+
81
+ if (number >= 256) {
82
+ bits |= U_NUMBER16;
83
+ }
84
+
85
+ // Determine needed bytes for header (U_NUMBER16 is in bits 8-15)
86
+ if (bits & 0xFF00) {
87
+ bits |= U_MOREBITS1;
88
+ }
89
+
90
+ // Write Header
91
+ writer.writeByte(bits & 0xFF);
92
+ if (bits & U_MOREBITS1) {
93
+ writer.writeByte((bits >> 8) & 0xFF);
94
+ }
95
+
96
+ // Write Number
97
+ if (bits & U_NUMBER16) {
98
+ writer.writeShort(number);
99
+ } else {
100
+ writer.writeByte(number);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Writes the delta between two entity states to a binary writer.
106
+ */
107
+ export function writeDeltaEntity(
108
+ from: EntityState,
109
+ to: EntityState,
110
+ writer: BinaryWriter,
111
+ force: boolean,
112
+ newEntity: boolean
113
+ ): void {
114
+ let bits = 0;
115
+ let bitsHigh = 0;
116
+
117
+ // If this is a new entity, use a null baseline
118
+ if (newEntity) {
119
+ from = NULL_STATE;
120
+ }
121
+
122
+ // --- Compare fields and build the bitmask ---
123
+ if (to.modelIndex !== from.modelIndex || force) {
124
+ bits |= U_MODEL;
125
+ }
126
+ if (to.modelIndex2 !== from.modelIndex2 || force) {
127
+ bits |= U_MODEL2;
128
+ }
129
+ if (to.modelIndex3 !== from.modelIndex3 || force) {
130
+ bits |= U_MODEL3;
131
+ }
132
+ if (to.modelIndex4 !== from.modelIndex4 || force) {
133
+ bits |= U_MODEL4;
134
+ }
135
+
136
+ if (to.origin.x !== from.origin.x || force) {
137
+ bits |= U_ORIGIN1;
138
+ }
139
+ if (to.origin.y !== from.origin.y || force) {
140
+ bits |= U_ORIGIN2;
141
+ }
142
+ if (to.origin.z !== from.origin.z || force) {
143
+ bits |= U_ORIGIN3;
144
+ }
145
+ if (to.angles.x !== from.angles.x || force) {
146
+ bits |= U_ANGLE1;
147
+ }
148
+ if (to.angles.y !== from.angles.y || force) {
149
+ bits |= U_ANGLE2;
150
+ }
151
+ if (to.angles.z !== from.angles.z || force) {
152
+ bits |= U_ANGLE3;
153
+ }
154
+
155
+ if (to.frame !== from.frame || force) {
156
+ if (to.frame >= 256) bits |= U_FRAME16;
157
+ else bits |= U_FRAME8;
158
+ }
159
+
160
+ if (to.skinNum !== from.skinNum || force) {
161
+ if (to.skinNum >= 256) bits |= U_SKIN16;
162
+ else bits |= U_SKIN8;
163
+ }
164
+
165
+ if (to.effects !== from.effects || force) {
166
+ if (to.effects >= 256) bits |= U_EFFECTS16;
167
+ else bits |= U_EFFECTS8;
168
+ }
169
+
170
+ if (to.renderfx !== from.renderfx || force) {
171
+ if (to.renderfx >= 256) bits |= U_RENDERFX16;
172
+ else bits |= U_RENDERFX8;
173
+ }
174
+
175
+ if (to.solid !== from.solid || force) {
176
+ bits |= U_SOLID;
177
+ }
178
+ if (to.sound !== from.sound || force) {
179
+ bits |= U_SOUND;
180
+ }
181
+ if (to.event !== from.event || force) {
182
+ bits |= U_EVENT;
183
+ }
184
+
185
+ // Rerelease Fields
186
+ if ((to.alpha !== from.alpha || force) && to.alpha !== undefined) {
187
+ bits |= U_ALPHA;
188
+ }
189
+ if ((to.scale !== from.scale || force) && to.scale !== undefined) {
190
+ bits |= U_SCALE;
191
+ }
192
+ if ((to.instanceBits !== from.instanceBits || force) && to.instanceBits !== undefined) {
193
+ bits |= U_INSTANCE_BITS;
194
+ }
195
+ if ((to.loopVolume !== from.loopVolume || force) && to.loopVolume !== undefined) {
196
+ bits |= U_LOOP_VOLUME;
197
+ }
198
+
199
+ // High Bits Fields
200
+ if ((to.loopAttenuation !== from.loopAttenuation || force) && to.loopAttenuation !== undefined) {
201
+ bitsHigh |= U_LOOP_ATTENUATION_HIGH;
202
+ }
203
+ if ((to.owner !== from.owner || force) && to.owner !== undefined) {
204
+ bitsHigh |= U_OWNER_HIGH;
205
+ }
206
+ if ((to.oldFrame !== from.oldFrame || force) && to.oldFrame !== undefined) {
207
+ bitsHigh |= U_OLD_FRAME_HIGH;
208
+ }
209
+
210
+
211
+ // Handle entity number
212
+ if (to.number >= 256) {
213
+ bits |= U_NUMBER16;
214
+ }
215
+
216
+ // Determine needed bytes for header
217
+
218
+ // If we have high bits, we set U_MOREBITS4 on the 4th byte
219
+ if (bitsHigh > 0) {
220
+ bits |= U_MOREBITS4;
221
+ }
222
+
223
+ // Now calculate cascading flags
224
+ if (bits & 0xFF000000) { // e.g. U_MOREBITS4 (bit 31) is here
225
+ bits |= U_MOREBITS3;
226
+ }
227
+ if (bits & 0xFFFF0000) { // e.g. U_MOREBITS3 (bit 23) is here
228
+ bits |= U_MOREBITS2;
229
+ }
230
+ if (bits & 0xFFFFFF00) { // e.g. U_MOREBITS2 (bit 15) is here
231
+ bits |= U_MOREBITS1;
232
+ }
233
+
234
+ // Write Header
235
+ writer.writeByte(bits & 0xFF);
236
+
237
+ if (bits & U_MOREBITS1) {
238
+ writer.writeByte((bits >> 8) & 0xFF);
239
+ }
240
+ if (bits & U_MOREBITS2) {
241
+ writer.writeByte((bits >> 16) & 0xFF);
242
+ }
243
+ if (bits & U_MOREBITS3) {
244
+ writer.writeByte((bits >> 24) & 0xFF);
245
+ }
246
+ if (bits & U_MOREBITS4) {
247
+ writer.writeByte(bitsHigh & 0xFF);
248
+ }
249
+
250
+ // Write Number
251
+ if (bits & U_NUMBER16) {
252
+ writer.writeShort(to.number);
253
+ } else {
254
+ writer.writeByte(to.number);
255
+ }
256
+
257
+ // Write Fields in Order (matching NetworkMessageParser.parseDelta)
258
+ if (bits & U_MODEL) writer.writeByte(to.modelIndex);
259
+ if (bits & U_MODEL2) writer.writeByte(to.modelIndex2 ?? 0);
260
+ if (bits & U_MODEL3) writer.writeByte(to.modelIndex3 ?? 0);
261
+ if (bits & U_MODEL4) writer.writeByte(to.modelIndex4 ?? 0);
262
+
263
+ if (bits & U_FRAME8) writer.writeByte(to.frame);
264
+ if (bits & U_FRAME16) writer.writeShort(to.frame);
265
+
266
+ if (bits & U_SKIN8) writer.writeByte(to.skinNum);
267
+ if (bits & U_SKIN16) writer.writeShort(to.skinNum);
268
+
269
+ if (bits & U_EFFECTS8) writer.writeByte(to.effects);
270
+ if (bits & U_EFFECTS16) writer.writeShort(to.effects);
271
+
272
+ if (bits & U_RENDERFX8) writer.writeByte(to.renderfx);
273
+ if (bits & U_RENDERFX16) writer.writeShort(to.renderfx);
274
+
275
+ if (bits & U_ORIGIN1) writer.writeCoord(to.origin.x);
276
+ if (bits & U_ORIGIN2) writer.writeCoord(to.origin.y);
277
+ if (bits & U_ORIGIN3) writer.writeCoord(to.origin.z);
278
+
279
+ if (bits & U_ANGLE1) writer.writeAngle(to.angles.x);
280
+ if (bits & U_ANGLE2) writer.writeAngle(to.angles.y);
281
+ if (bits & U_ANGLE3) writer.writeAngle(to.angles.z);
282
+
283
+ if (bits & U_OLDORIGIN) {
284
+ // Not implemented in EntityState usually, skip or zero
285
+ // writer.writePos(to.old_origin);
286
+ }
287
+
288
+ if (bits & U_SOUND) writer.writeByte(to.sound ?? 0);
289
+
290
+ if (bits & U_EVENT) writer.writeByte(to.event ?? 0);
291
+
292
+ if (bits & U_SOLID) writer.writeShort(to.solid);
293
+
294
+ // Rerelease Fields Writing
295
+ if (bits & U_ALPHA) writer.writeByte(Math.floor((to.alpha ?? 0) * 255));
296
+ if (bits & U_SCALE) writer.writeFloat(to.scale ?? 0);
297
+ if (bits & U_INSTANCE_BITS) writer.writeLong(to.instanceBits ?? 0);
298
+ if (bits & U_LOOP_VOLUME) writer.writeByte(Math.floor((to.loopVolume ?? 0) * 255));
299
+
300
+ // High bits fields
301
+ if (bitsHigh & U_LOOP_ATTENUATION_HIGH) writer.writeByte(Math.floor((to.loopAttenuation ?? 0) * 255));
302
+ if (bitsHigh & U_OWNER_HIGH) writer.writeShort(to.owner ?? 0);
303
+ if (bitsHigh & U_OLD_FRAME_HIGH) writer.writeShort(to.oldFrame ?? 0);
304
+ }
@@ -0,0 +1,14 @@
1
+ export enum EntityEvent {
2
+ None = 0,
3
+ ItemRespawn = 1,
4
+ Footstep = 2,
5
+ FallShort = 3,
6
+ Fall = 4,
7
+ FallFar = 5,
8
+ PlayerTeleport = 6,
9
+ OtherTeleport = 7,
10
+
11
+ // [Paril-KEX]
12
+ OtherFootstep = 8,
13
+ LadderStep = 9,
14
+ }
@@ -0,0 +1,28 @@
1
+ import { Vec3 } from '../math/vec3.js';
2
+
3
+ export interface EntityState {
4
+ readonly number: number;
5
+ readonly origin: Vec3;
6
+ readonly angles: Vec3;
7
+ readonly oldOrigin?: Vec3; // [Paril-KEX] for lerping
8
+ readonly modelIndex: number;
9
+ readonly modelIndex2?: number; // [Paril-KEX]
10
+ readonly modelIndex3?: number; // [Paril-KEX]
11
+ readonly modelIndex4?: number; // [Paril-KEX]
12
+ readonly frame: number;
13
+ readonly skinNum: number;
14
+ readonly effects: number;
15
+ readonly renderfx: number;
16
+ readonly solid: number;
17
+ readonly sound?: number;
18
+ readonly event?: number;
19
+
20
+ // Rerelease fields
21
+ readonly alpha?: number;
22
+ readonly scale?: number;
23
+ readonly instanceBits?: number;
24
+ readonly loopVolume?: number;
25
+ readonly loopAttenuation?: number;
26
+ readonly owner?: number;
27
+ readonly oldFrame?: number;
28
+ }
@@ -0,0 +1,19 @@
1
+
2
+ export * from './configstrings.js';
3
+ export * from './contracts.js';
4
+ export * from './cvar.js';
5
+ export * from './usercmd.js';
6
+ export * from './player-state.js';
7
+ export * from './ops.js';
8
+ export * from './tempEntity.js';
9
+ export * from './constants.js';
10
+ export * from './layout.js';
11
+ export * from './stats.js';
12
+ export * from './writeUserCmd.js';
13
+ export * from './renderFx.js';
14
+ export * from './crc.js';
15
+ export * from './effects.js';
16
+ export * from './entityEvent.js';
17
+ export * from './entity.js';
18
+ export * from './entityState.js';
19
+ export * from './player.js';
@@ -0,0 +1,9 @@
1
+ // Matching rerelease/game.h:1584-1593
2
+ export enum LayoutFlags {
3
+ LAYOUTS_LAYOUT = 1,
4
+ LAYOUTS_INVENTORY = 2,
5
+ LAYOUTS_HIDE_HUD = 4,
6
+ LAYOUTS_INTERMISSION = 8,
7
+ LAYOUTS_HELP = 16,
8
+ LAYOUTS_HIDE_CROSSHAIR = 32
9
+ }
@@ -0,0 +1,49 @@
1
+
2
+ export enum ServerCommand {
3
+ bad = 0,
4
+
5
+ // these ops are known to the game dll
6
+ muzzleflash = 1,
7
+ muzzleflash2 = 2,
8
+ temp_entity = 3,
9
+ layout = 4,
10
+ inventory = 5,
11
+
12
+ // the rest are private to the client and server
13
+ nop = 6,
14
+ disconnect = 7,
15
+ reconnect = 8,
16
+ sound = 9, // <see code>
17
+ print = 10, // [byte] id [string] null terminated string
18
+ stufftext = 11, // [string] stuffed into client's console buffer, should be \n terminated
19
+ serverdata = 12, // [long] protocol ...
20
+ configstring = 13, // [short] [string]
21
+ spawnbaseline = 14,
22
+ centerprint = 15, // [string] to put in center of the screen
23
+ download = 16, // [short] size [size bytes]
24
+ playerinfo = 17, // variable
25
+ packetentities = 18, // [...]
26
+ deltapacketentities = 19, // [...]
27
+ frame = 20,
28
+ splitclient = 21,
29
+ configblast = 22,
30
+ spawnbaselineblast = 23,
31
+ level_restart = 24,
32
+ damage = 25,
33
+ locprint = 26,
34
+ fog = 27,
35
+ waitingforplayers = 28,
36
+ bot_chat = 29,
37
+ poi = 30,
38
+ help_path = 31,
39
+ muzzleflash3 = 32,
40
+ achievement = 33
41
+ }
42
+
43
+ export enum ClientCommand {
44
+ bad = 0,
45
+ nop = 1,
46
+ move = 2, // [[usercmd_t]
47
+ userinfo = 3, // [[userinfo string]
48
+ stringcmd = 4 // [string] message
49
+ }
@@ -0,0 +1,51 @@
1
+
2
+ import { Vec3 } from '../math/vec3.js';
3
+
4
+ import { WaterLevel } from '../pmove/constants.js';
5
+
6
+ export interface DamageIndicator {
7
+ direction: Vec3;
8
+ strength: number;
9
+ }
10
+
11
+ export interface PlayerState {
12
+ origin: Vec3;
13
+ velocity: Vec3;
14
+ viewAngles: Vec3;
15
+ onGround: boolean;
16
+ waterLevel: WaterLevel;
17
+ watertype: number; // Added for correct fluid effects
18
+ mins: Vec3;
19
+ maxs: Vec3;
20
+ damageAlpha: number;
21
+ damageIndicators: DamageIndicator[];
22
+ blend: [number, number, number, number]; // r, g, b, a
23
+ pickupIcon?: string; // Name of the icon to draw (e.g. 'w_railgun')
24
+ centerPrint?: string;
25
+ notify?: string;
26
+
27
+ // Stats array (STAT_HEALTH, STAT_AMMO, etc.)
28
+ stats: number[];
29
+
30
+ // View effects
31
+ kick_angles: Vec3;
32
+ kick_origin: Vec3;
33
+ gunoffset: Vec3;
34
+ gunangles: Vec3;
35
+ gunindex: number;
36
+
37
+ // New fields for Q2 network compatibility
38
+ pm_type: number;
39
+ pm_time: number;
40
+ pm_flags: number;
41
+ gun_frame: number;
42
+ rdflags: number;
43
+ fov: number;
44
+ renderfx: number;
45
+
46
+ // Rerelease fields
47
+ gunskin?: number;
48
+ gunrate?: number;
49
+ damage_blend?: [number, number, number, number];
50
+ team_id?: number;
51
+ }
@@ -0,0 +1,165 @@
1
+ import { BinaryWriter, Vec3 } from '../index.js';
2
+
3
+ export interface ProtocolPlayerState {
4
+ pm_type: number;
5
+ origin: Vec3;
6
+ velocity: Vec3;
7
+ pm_time: number;
8
+ pm_flags: number;
9
+ gravity: number;
10
+ delta_angles: Vec3;
11
+ viewoffset: Vec3;
12
+ viewangles: Vec3;
13
+ kick_angles: Vec3;
14
+ gun_index: number;
15
+ gun_frame: number;
16
+ gun_offset: Vec3;
17
+ gun_angles: Vec3;
18
+ blend: number[]; // [r,g,b,a]
19
+ fov: number;
20
+ rdflags: number;
21
+ stats: number[];
22
+ watertype: number;
23
+
24
+ // Optional / Extension fields if needed
25
+ gunskin?: number;
26
+ gunrate?: number;
27
+ damage_blend?: number[];
28
+ team_id?: number;
29
+ }
30
+
31
+ // Bitflags matching demo/parser.ts
32
+ const PS_M_TYPE = (1 << 0);
33
+ const PS_M_ORIGIN = (1 << 1);
34
+ const PS_M_VELOCITY = (1 << 2);
35
+ const PS_M_TIME = (1 << 3);
36
+ const PS_M_FLAGS = (1 << 4);
37
+ const PS_M_GRAVITY = (1 << 5);
38
+ const PS_M_DELTA_ANGLES = (1 << 6);
39
+ const PS_VIEWOFFSET = (1 << 7);
40
+ const PS_VIEWANGLES = (1 << 8);
41
+ const PS_KICKANGLES = (1 << 9);
42
+ const PS_BLEND = (1 << 10);
43
+ const PS_FOV = (1 << 11);
44
+ const PS_WEAPONINDEX = (1 << 12);
45
+ const PS_WEAPONFRAME = (1 << 13);
46
+ const PS_RDFLAGS = (1 << 14);
47
+ const PS_WATERTYPE = (1 << 15);
48
+
49
+ export function writePlayerState(writer: BinaryWriter, ps: ProtocolPlayerState): void {
50
+ // Determine mask
51
+ let mask = 0;
52
+
53
+ if (ps.pm_type !== 0) mask |= PS_M_TYPE;
54
+ if (ps.origin.x !== 0 || ps.origin.y !== 0 || ps.origin.z !== 0) mask |= PS_M_ORIGIN;
55
+ if (ps.velocity.x !== 0 || ps.velocity.y !== 0 || ps.velocity.z !== 0) mask |= PS_M_VELOCITY;
56
+ if (ps.pm_time !== 0) mask |= PS_M_TIME;
57
+ if (ps.pm_flags !== 0) mask |= PS_M_FLAGS;
58
+ if (ps.gravity !== 0) mask |= PS_M_GRAVITY;
59
+ if (ps.delta_angles.x !== 0 || ps.delta_angles.y !== 0 || ps.delta_angles.z !== 0) mask |= PS_M_DELTA_ANGLES;
60
+ if (ps.viewoffset.x !== 0 || ps.viewoffset.y !== 0 || ps.viewoffset.z !== 0) mask |= PS_VIEWOFFSET;
61
+ if (ps.viewangles.x !== 0 || ps.viewangles.y !== 0 || ps.viewangles.z !== 0) mask |= PS_VIEWANGLES;
62
+ if (ps.kick_angles.x !== 0 || ps.kick_angles.y !== 0 || ps.kick_angles.z !== 0) mask |= PS_KICKANGLES;
63
+ if (ps.gun_index !== 0) mask |= PS_WEAPONINDEX;
64
+
65
+ // Weapon frame includes offset/angles
66
+ if (ps.gun_frame !== 0 ||
67
+ ps.gun_offset.x !== 0 || ps.gun_offset.y !== 0 || ps.gun_offset.z !== 0 ||
68
+ ps.gun_angles.x !== 0 || ps.gun_angles.y !== 0 || ps.gun_angles.z !== 0) {
69
+ mask |= PS_WEAPONFRAME;
70
+ }
71
+
72
+ if (ps.blend && (ps.blend[0] !== 0 || ps.blend[1] !== 0 || ps.blend[2] !== 0 || ps.blend[3] !== 0)) {
73
+ mask |= PS_BLEND;
74
+ }
75
+
76
+ if (ps.fov !== 0) mask |= PS_FOV;
77
+ if (ps.rdflags !== 0) mask |= PS_RDFLAGS;
78
+ if (ps.watertype !== 0) mask |= PS_WATERTYPE;
79
+
80
+ // Stats mask calculation
81
+ let statsMask = 0;
82
+ // Only support first 32 stats for now
83
+ for (let i = 0; i < 32; i++) {
84
+ if (ps.stats[i] && ps.stats[i] !== 0) {
85
+ statsMask |= (1 << i);
86
+ }
87
+ }
88
+
89
+ // Write header
90
+ writer.writeShort(mask);
91
+
92
+ // Write fields
93
+ if (mask & PS_M_TYPE) writer.writeByte(ps.pm_type);
94
+
95
+ if (mask & PS_M_ORIGIN) {
96
+ writer.writeShort(Math.round(ps.origin.x * 8));
97
+ writer.writeShort(Math.round(ps.origin.y * 8));
98
+ writer.writeShort(Math.round(ps.origin.z * 8));
99
+ }
100
+
101
+ if (mask & PS_M_VELOCITY) {
102
+ writer.writeShort(Math.round(ps.velocity.x * 8));
103
+ writer.writeShort(Math.round(ps.velocity.y * 8));
104
+ writer.writeShort(Math.round(ps.velocity.z * 8));
105
+ }
106
+
107
+ if (mask & PS_M_TIME) writer.writeByte(ps.pm_time);
108
+ if (mask & PS_M_FLAGS) writer.writeByte(ps.pm_flags);
109
+ if (mask & PS_M_GRAVITY) writer.writeShort(ps.gravity);
110
+
111
+ if (mask & PS_M_DELTA_ANGLES) {
112
+ writer.writeShort(Math.round(ps.delta_angles.x * (32768 / 180)));
113
+ writer.writeShort(Math.round(ps.delta_angles.y * (32768 / 180)));
114
+ writer.writeShort(Math.round(ps.delta_angles.z * (32768 / 180)));
115
+ }
116
+
117
+ if (mask & PS_VIEWOFFSET) {
118
+ writer.writeChar(Math.round(ps.viewoffset.x * 4));
119
+ writer.writeChar(Math.round(ps.viewoffset.y * 4));
120
+ writer.writeChar(Math.round(ps.viewoffset.z * 4));
121
+ }
122
+
123
+ if (mask & PS_VIEWANGLES) {
124
+ writer.writeAngle16(ps.viewangles.x);
125
+ writer.writeAngle16(ps.viewangles.y);
126
+ writer.writeAngle16(ps.viewangles.z);
127
+ }
128
+
129
+ if (mask & PS_KICKANGLES) {
130
+ writer.writeChar(Math.round(ps.kick_angles.x * 4));
131
+ writer.writeChar(Math.round(ps.kick_angles.y * 4));
132
+ writer.writeChar(Math.round(ps.kick_angles.z * 4));
133
+ }
134
+
135
+ if (mask & PS_WEAPONINDEX) writer.writeByte(ps.gun_index);
136
+
137
+ if (mask & PS_WEAPONFRAME) {
138
+ writer.writeByte(ps.gun_frame);
139
+ writer.writeChar(Math.round(ps.gun_offset.x * 4));
140
+ writer.writeChar(Math.round(ps.gun_offset.y * 4));
141
+ writer.writeChar(Math.round(ps.gun_offset.z * 4));
142
+ writer.writeChar(Math.round(ps.gun_angles.x * 4));
143
+ writer.writeChar(Math.round(ps.gun_angles.y * 4));
144
+ writer.writeChar(Math.round(ps.gun_angles.z * 4));
145
+ }
146
+
147
+ if (mask & PS_BLEND) {
148
+ writer.writeByte(Math.round(ps.blend[0]));
149
+ writer.writeByte(Math.round(ps.blend[1]));
150
+ writer.writeByte(Math.round(ps.blend[2]));
151
+ writer.writeByte(Math.round(ps.blend[3]));
152
+ }
153
+
154
+ if (mask & PS_FOV) writer.writeByte(ps.fov);
155
+ if (mask & PS_RDFLAGS) writer.writeByte(ps.rdflags);
156
+ if (mask & PS_WATERTYPE) writer.writeByte(ps.watertype);
157
+
158
+ // Write Stats
159
+ writer.writeLong(statsMask);
160
+ for (let i = 0; i < 32; i++) {
161
+ if (statsMask & (1 << i)) {
162
+ writer.writeShort(ps.stats[i]);
163
+ }
164
+ }
165
+ }
@@ -0,0 +1,22 @@
1
+ export enum RenderFx {
2
+ MinLight = 1,
3
+ ViewerModel = 2,
4
+ WeaponModel = 4,
5
+ FullBright = 8,
6
+ DepthHack = 16,
7
+ Translucent = 32,
8
+ FrameLerp = 64,
9
+ Beam = 128,
10
+ CustomLight = 256,
11
+ Glow = 512,
12
+ ShellRed = 1024,
13
+ ShellGreen = 2048,
14
+ ShellBlue = 4096,
15
+ IrVisible = 32768,
16
+ ShellDouble = 65536,
17
+ ShellHalfDam = 131072,
18
+ MinLightPlus = 262144,
19
+ ExtraLight = 524288,
20
+ BeamLightning = 1048576,
21
+ Flashlight = 2097152, // 1 << 21
22
+ }