quake2ts 0.0.7 → 0.0.39

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 (177) hide show
  1. package/README.md +425 -0
  2. package/apps/viewer/dist/browser/index.global.js +1 -1
  3. package/apps/viewer/dist/browser/index.global.js.map +1 -1
  4. package/apps/viewer/dist/cjs/index.cjs +2097 -295
  5. package/apps/viewer/dist/cjs/index.cjs.map +1 -1
  6. package/apps/viewer/dist/esm/index.js +2097 -295
  7. package/apps/viewer/dist/esm/index.js.map +1 -1
  8. package/apps/viewer/dist/tsconfig.tsbuildinfo +1 -1
  9. package/apps/viewer/dist/types/index.d.ts +1 -1
  10. package/package.json +1 -1
  11. package/packages/client/dist/browser/index.global.js +1 -1
  12. package/packages/client/dist/browser/index.global.js.map +1 -1
  13. package/packages/client/dist/cjs/index.cjs +1200 -13
  14. package/packages/client/dist/cjs/index.cjs.map +1 -1
  15. package/packages/client/dist/esm/index.js +1186 -12
  16. package/packages/client/dist/esm/index.js.map +1 -1
  17. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  18. package/packages/client/dist/types/index.d.ts +14 -6
  19. package/packages/client/dist/types/index.d.ts.map +1 -1
  20. package/packages/client/dist/types/input/bindings.d.ts +18 -0
  21. package/packages/client/dist/types/input/bindings.d.ts.map +1 -0
  22. package/packages/client/dist/types/input/command-buffer.d.ts +15 -0
  23. package/packages/client/dist/types/input/command-buffer.d.ts.map +1 -0
  24. package/packages/client/dist/types/input/controller.d.ts +125 -0
  25. package/packages/client/dist/types/input/controller.d.ts.map +1 -0
  26. package/packages/client/dist/types/prediction.d.ts +38 -0
  27. package/packages/client/dist/types/prediction.d.ts.map +1 -0
  28. package/packages/client/dist/types/view-effects.d.ts +41 -0
  29. package/packages/client/dist/types/view-effects.d.ts.map +1 -0
  30. package/packages/engine/dist/browser/index.global.js +257 -1
  31. package/packages/engine/dist/browser/index.global.js.map +1 -1
  32. package/packages/engine/dist/cjs/index.cjs +2408 -2
  33. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  34. package/packages/engine/dist/esm/index.js +2340 -2
  35. package/packages/engine/dist/esm/index.js.map +1 -1
  36. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  37. package/packages/engine/dist/types/assets/animation.d.ts +33 -0
  38. package/packages/engine/dist/types/assets/animation.d.ts.map +1 -0
  39. package/packages/engine/dist/types/assets/audio.d.ts +21 -0
  40. package/packages/engine/dist/types/assets/audio.d.ts.map +1 -0
  41. package/packages/engine/dist/types/assets/bsp.d.ts +1 -1
  42. package/packages/engine/dist/types/assets/bsp.d.ts.map +1 -1
  43. package/packages/engine/dist/types/assets/ingestion.d.ts +31 -0
  44. package/packages/engine/dist/types/assets/ingestion.d.ts.map +1 -1
  45. package/packages/engine/dist/types/assets/manager.d.ts +43 -0
  46. package/packages/engine/dist/types/assets/manager.d.ts.map +1 -0
  47. package/packages/engine/dist/types/assets/md3.d.ts +69 -0
  48. package/packages/engine/dist/types/assets/md3.d.ts.map +1 -0
  49. package/packages/engine/dist/types/assets/ogg.d.ts +12 -0
  50. package/packages/engine/dist/types/assets/ogg.d.ts.map +1 -0
  51. package/packages/engine/dist/types/assets/pakIndexStore.d.ts +19 -0
  52. package/packages/engine/dist/types/assets/pakIndexStore.d.ts.map +1 -0
  53. package/packages/engine/dist/types/assets/pakValidation.d.ts +28 -0
  54. package/packages/engine/dist/types/assets/pakValidation.d.ts.map +1 -0
  55. package/packages/engine/dist/types/assets/pcx.d.ts +13 -0
  56. package/packages/engine/dist/types/assets/pcx.d.ts.map +1 -0
  57. package/packages/engine/dist/types/assets/texture.d.ts +29 -0
  58. package/packages/engine/dist/types/assets/texture.d.ts.map +1 -0
  59. package/packages/engine/dist/types/assets/wal.d.ts +21 -0
  60. package/packages/engine/dist/types/assets/wal.d.ts.map +1 -0
  61. package/packages/engine/dist/types/assets/wav.d.ts +11 -0
  62. package/packages/engine/dist/types/assets/wav.d.ts.map +1 -0
  63. package/packages/engine/dist/types/audio/api.d.ts +29 -0
  64. package/packages/engine/dist/types/audio/api.d.ts.map +1 -0
  65. package/packages/engine/dist/types/audio/channels.d.ts +15 -0
  66. package/packages/engine/dist/types/audio/channels.d.ts.map +1 -0
  67. package/packages/engine/dist/types/audio/constants.d.ts +24 -0
  68. package/packages/engine/dist/types/audio/constants.d.ts.map +1 -0
  69. package/packages/engine/dist/types/audio/context.d.ts +67 -0
  70. package/packages/engine/dist/types/audio/context.d.ts.map +1 -0
  71. package/packages/engine/dist/types/audio/music.d.ts +42 -0
  72. package/packages/engine/dist/types/audio/music.d.ts.map +1 -0
  73. package/packages/engine/dist/types/audio/precache.d.ts +28 -0
  74. package/packages/engine/dist/types/audio/precache.d.ts.map +1 -0
  75. package/packages/engine/dist/types/audio/registry.d.ts +13 -0
  76. package/packages/engine/dist/types/audio/registry.d.ts.map +1 -0
  77. package/packages/engine/dist/types/audio/spatialization.d.ts +14 -0
  78. package/packages/engine/dist/types/audio/spatialization.d.ts.map +1 -0
  79. package/packages/engine/dist/types/audio/system.d.ts +101 -0
  80. package/packages/engine/dist/types/audio/system.d.ts.map +1 -0
  81. package/packages/engine/dist/types/configstrings.d.ts +1 -0
  82. package/packages/engine/dist/types/configstrings.d.ts.map +1 -1
  83. package/packages/engine/dist/types/index.d.ts +26 -1
  84. package/packages/engine/dist/types/index.d.ts.map +1 -1
  85. package/packages/engine/dist/types/render/bspPipeline.d.ts +42 -0
  86. package/packages/engine/dist/types/render/bspPipeline.d.ts.map +1 -0
  87. package/packages/engine/dist/types/render/bspTraversal.d.ts +11 -0
  88. package/packages/engine/dist/types/render/bspTraversal.d.ts.map +1 -0
  89. package/packages/engine/dist/types/render/culling.d.ts +8 -0
  90. package/packages/engine/dist/types/render/culling.d.ts.map +1 -0
  91. package/packages/engine/dist/types/render/md2Pipeline.d.ts +51 -0
  92. package/packages/engine/dist/types/render/md2Pipeline.d.ts.map +1 -0
  93. package/packages/engine/dist/types/render/resources.d.ts +10 -0
  94. package/packages/engine/dist/types/render/resources.d.ts.map +1 -1
  95. package/packages/engine/dist/types/render/skybox.d.ts +26 -0
  96. package/packages/engine/dist/types/render/skybox.d.ts.map +1 -0
  97. package/packages/game/dist/browser/index.global.js +1 -1
  98. package/packages/game/dist/browser/index.global.js.map +1 -1
  99. package/packages/game/dist/cjs/index.cjs +2926 -116
  100. package/packages/game/dist/cjs/index.cjs.map +1 -1
  101. package/packages/game/dist/esm/index.js +2863 -115
  102. package/packages/game/dist/esm/index.js.map +1 -1
  103. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  104. package/packages/game/dist/types/ai/constants.d.ts +13 -0
  105. package/packages/game/dist/types/ai/constants.d.ts.map +1 -0
  106. package/packages/game/dist/types/ai/index.d.ts +4 -0
  107. package/packages/game/dist/types/ai/index.d.ts.map +1 -0
  108. package/packages/game/dist/types/ai/movement.d.ts +20 -0
  109. package/packages/game/dist/types/ai/movement.d.ts.map +1 -0
  110. package/packages/game/dist/types/ai/perception.d.ts +21 -0
  111. package/packages/game/dist/types/ai/perception.d.ts.map +1 -0
  112. package/packages/game/dist/types/checksum.d.ts +3 -0
  113. package/packages/game/dist/types/checksum.d.ts.map +1 -0
  114. package/packages/game/dist/types/combat/armor.d.ts +39 -0
  115. package/packages/game/dist/types/combat/armor.d.ts.map +1 -0
  116. package/packages/game/dist/types/combat/damage.d.ts +52 -0
  117. package/packages/game/dist/types/combat/damage.d.ts.map +1 -0
  118. package/packages/game/dist/types/combat/damageFlags.d.ts +15 -0
  119. package/packages/game/dist/types/combat/damageFlags.d.ts.map +1 -0
  120. package/packages/game/dist/types/combat/damageMods.d.ts +79 -0
  121. package/packages/game/dist/types/combat/damageMods.d.ts.map +1 -0
  122. package/packages/game/dist/types/combat/index.d.ts +6 -0
  123. package/packages/game/dist/types/combat/index.d.ts.map +1 -0
  124. package/packages/game/dist/types/combat/specialDamage.d.ts +88 -0
  125. package/packages/game/dist/types/combat/specialDamage.d.ts.map +1 -0
  126. package/packages/game/dist/types/entities/entity.d.ts +46 -2
  127. package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
  128. package/packages/game/dist/types/entities/index.d.ts +6 -2
  129. package/packages/game/dist/types/entities/index.d.ts.map +1 -1
  130. package/packages/game/dist/types/entities/pool.d.ts +9 -0
  131. package/packages/game/dist/types/entities/pool.d.ts.map +1 -1
  132. package/packages/game/dist/types/entities/spawn.d.ts +27 -0
  133. package/packages/game/dist/types/entities/spawn.d.ts.map +1 -0
  134. package/packages/game/dist/types/entities/system.d.ts +32 -1
  135. package/packages/game/dist/types/entities/system.d.ts.map +1 -1
  136. package/packages/game/dist/types/entities/thinkScheduler.d.ts +6 -0
  137. package/packages/game/dist/types/entities/thinkScheduler.d.ts.map +1 -1
  138. package/packages/game/dist/types/entities/triggers.d.ts +3 -0
  139. package/packages/game/dist/types/entities/triggers.d.ts.map +1 -0
  140. package/packages/game/dist/types/entities/utils.d.ts +4 -0
  141. package/packages/game/dist/types/entities/utils.d.ts.map +1 -0
  142. package/packages/game/dist/types/index.d.ts +5 -0
  143. package/packages/game/dist/types/index.d.ts.map +1 -1
  144. package/packages/game/dist/types/inventory/ammo.d.ts +17 -0
  145. package/packages/game/dist/types/inventory/ammo.d.ts.map +1 -0
  146. package/packages/game/dist/types/inventory/index.d.ts +2 -0
  147. package/packages/game/dist/types/inventory/index.d.ts.map +1 -0
  148. package/packages/game/dist/types/level.d.ts +1 -0
  149. package/packages/game/dist/types/level.d.ts.map +1 -1
  150. package/packages/game/dist/types/save/index.d.ts +4 -0
  151. package/packages/game/dist/types/save/index.d.ts.map +1 -0
  152. package/packages/game/dist/types/save/rerelease.d.ts +25 -0
  153. package/packages/game/dist/types/save/rerelease.d.ts.map +1 -0
  154. package/packages/game/dist/types/save/save.d.ts +49 -0
  155. package/packages/game/dist/types/save/save.d.ts.map +1 -0
  156. package/packages/game/dist/types/save/storage.d.ts +37 -0
  157. package/packages/game/dist/types/save/storage.d.ts.map +1 -0
  158. package/packages/shared/dist/browser/index.global.js +1 -1
  159. package/packages/shared/dist/browser/index.global.js.map +1 -1
  160. package/packages/shared/dist/cjs/index.cjs +638 -9
  161. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  162. package/packages/shared/dist/esm/index.js +616 -9
  163. package/packages/shared/dist/esm/index.js.map +1 -1
  164. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  165. package/packages/shared/dist/types/bsp/collision.d.ts +56 -0
  166. package/packages/shared/dist/types/bsp/collision.d.ts.map +1 -1
  167. package/packages/shared/dist/types/bsp/contents.d.ts +1 -0
  168. package/packages/shared/dist/types/bsp/contents.d.ts.map +1 -1
  169. package/packages/shared/dist/types/index.d.ts +2 -0
  170. package/packages/shared/dist/types/index.d.ts.map +1 -1
  171. package/packages/shared/dist/types/math/random.d.ts +11 -0
  172. package/packages/shared/dist/types/math/random.d.ts.map +1 -1
  173. package/packages/shared/dist/types/protocol/contracts.d.ts +17 -0
  174. package/packages/shared/dist/types/protocol/contracts.d.ts.map +1 -0
  175. package/packages/shared/dist/types/protocol/usercmd.d.ts +30 -0
  176. package/packages/shared/dist/types/protocol/usercmd.d.ts.map +1 -0
  177. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -1,28 +1,717 @@
1
1
  // ../../packages/client/dist/esm/index.js
2
+ var ZERO_VEC3 = { x: 0, y: 0, z: 0 };
3
+ var DEG_TO_RAD = Math.PI / 180;
4
+ function addVec3(a, b) {
5
+ return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
6
+ }
7
+ function scaleVec3(a, scalar) {
8
+ return { x: a.x * scalar, y: a.y * scalar, z: a.z * scalar };
9
+ }
10
+ function dotVec3(a, b) {
11
+ return a.x * b.x + a.y * b.y + a.z * b.z;
12
+ }
13
+ function lengthSquaredVec3(a) {
14
+ return dotVec3(a, a);
15
+ }
16
+ function lengthVec3(a) {
17
+ return Math.sqrt(lengthSquaredVec3(a));
18
+ }
19
+ function normalizeVec3(a) {
20
+ const len = lengthVec3(a);
21
+ return len === 0 ? a : scaleVec3(a, 1 / len);
22
+ }
23
+ var PITCH = 0;
24
+ var YAW = 1;
25
+ var ROLL = 2;
26
+ var DEG2RAD_FACTOR = Math.PI / 180;
27
+ var RAD2DEG_FACTOR = 180 / Math.PI;
28
+ function axisComponent(vec, axis) {
29
+ switch (axis) {
30
+ case PITCH:
31
+ return vec.x;
32
+ case YAW:
33
+ return vec.y;
34
+ case ROLL:
35
+ default:
36
+ return vec.z;
37
+ }
38
+ }
39
+ function degToRad(degrees) {
40
+ return degrees * DEG2RAD_FACTOR;
41
+ }
42
+ function angleMod(angle) {
43
+ const value = angle % 360;
44
+ return value < 0 ? 360 + value : value;
45
+ }
46
+ function angleVectors(angles) {
47
+ const yaw = degToRad(axisComponent(angles, YAW));
48
+ const pitch = degToRad(axisComponent(angles, PITCH));
49
+ const roll = degToRad(axisComponent(angles, ROLL));
50
+ const sy = Math.sin(yaw);
51
+ const cy = Math.cos(yaw);
52
+ const sp = Math.sin(pitch);
53
+ const cp = Math.cos(pitch);
54
+ const sr = Math.sin(roll);
55
+ const cr = Math.cos(roll);
56
+ const forward = {
57
+ x: cp * cy,
58
+ y: cp * sy,
59
+ z: -sp
60
+ };
61
+ const right = {
62
+ x: -sr * sp * cy - cr * -sy,
63
+ y: -sr * sp * sy - cr * cy,
64
+ z: -sr * cp
65
+ };
66
+ const up = {
67
+ x: cr * sp * cy - sr * -sy,
68
+ y: cr * sp * sy - sr * cy,
69
+ z: cr * cp
70
+ };
71
+ return { forward, right, up };
72
+ }
73
+ var CONTENTS_SOLID = 1 << 0;
74
+ var CONTENTS_WINDOW = 1 << 1;
75
+ var CONTENTS_AUX = 1 << 2;
76
+ var CONTENTS_LAVA = 1 << 3;
77
+ var CONTENTS_SLIME = 1 << 4;
78
+ var CONTENTS_WATER = 1 << 5;
79
+ var CONTENTS_MIST = 1 << 6;
80
+ var CONTENTS_NO_WATERJUMP = 1 << 13;
81
+ var CONTENTS_PROJECTILECLIP = 1 << 14;
82
+ var CONTENTS_AREAPORTAL = 1 << 15;
83
+ var CONTENTS_PLAYERCLIP = 1 << 16;
84
+ var CONTENTS_MONSTERCLIP = 1 << 17;
85
+ var CONTENTS_CURRENT_0 = 1 << 18;
86
+ var CONTENTS_CURRENT_90 = 1 << 19;
87
+ var CONTENTS_CURRENT_180 = 1 << 20;
88
+ var CONTENTS_CURRENT_270 = 1 << 21;
89
+ var CONTENTS_CURRENT_UP = 1 << 22;
90
+ var CONTENTS_CURRENT_DOWN = 1 << 23;
91
+ var CONTENTS_ORIGIN = 1 << 24;
92
+ var CONTENTS_MONSTER = 1 << 25;
93
+ var CONTENTS_DEADMONSTER = 1 << 26;
94
+ var CONTENTS_DETAIL = 1 << 27;
95
+ var CONTENTS_TRANSLUCENT = 1 << 28;
96
+ var CONTENTS_LADDER = 1 << 29;
97
+ var CONTENTS_PLAYER = 1 << 30;
98
+ var CONTENTS_PROJECTILE = 1 << 31;
99
+ var SURF_LIGHT = 1 << 0;
100
+ var SURF_SLICK = 1 << 1;
101
+ var SURF_SKY = 1 << 2;
102
+ var SURF_WARP = 1 << 3;
103
+ var SURF_TRANS33 = 1 << 4;
104
+ var SURF_TRANS66 = 1 << 5;
105
+ var SURF_FLOWING = 1 << 6;
106
+ var SURF_NODRAW = 1 << 7;
107
+ var SURF_ALPHATEST = 1 << 25;
108
+ var SURF_N64_UV = 1 << 28;
109
+ var SURF_N64_SCROLL_X = 1 << 29;
110
+ var SURF_N64_SCROLL_Y = 1 << 30;
111
+ var SURF_N64_SCROLL_FLIP = 1 << 31;
112
+ var MASK_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
113
+ var MASK_PLAYERSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
114
+ var MASK_DEADSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
115
+ var MASK_MONSTERSOLID = CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
116
+ var MASK_WATER = CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME;
117
+ var MASK_OPAQUE = CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA;
118
+ var MASK_SHOT = CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER | CONTENTS_WINDOW | CONTENTS_DEADMONSTER;
119
+ var MASK_CURRENT = CONTENTS_CURRENT_0 | CONTENTS_CURRENT_90 | CONTENTS_CURRENT_180 | CONTENTS_CURRENT_270 | CONTENTS_CURRENT_UP | CONTENTS_CURRENT_DOWN;
120
+ var MASK_BLOCK_SIGHT = CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_MONSTER | CONTENTS_PLAYER;
121
+ var MASK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
122
+ var MASK_LADDER_NAV_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
123
+ var MASK_WALK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTERCLIP;
124
+ var MASK_PROJECTILE = MASK_SHOT | CONTENTS_PROJECTILECLIP;
125
+ var MAX_CHECKCOUNT = Number.MAX_SAFE_INTEGER - 1;
126
+ var MAX_CLIENTS = 256;
127
+ var MAX_LIGHTSTYLES = 256;
128
+ var MAX_MODELS = 8192;
129
+ var MAX_SOUNDS = 2048;
130
+ var MAX_IMAGES = 512;
131
+ var MAX_ITEMS = 256;
132
+ var MAX_GENERAL = MAX_CLIENTS * 2;
133
+ var MAX_SHADOW_LIGHTS = 256;
134
+ var MAX_WHEEL_ITEMS = 32;
135
+ var ConfigStringIndex = ((ConfigStringIndex22) => {
136
+ ConfigStringIndex22[ConfigStringIndex22["Name"] = 0] = "Name";
137
+ ConfigStringIndex22[ConfigStringIndex22["CdTrack"] = 1] = "CdTrack";
138
+ ConfigStringIndex22[ConfigStringIndex22["Sky"] = 2] = "Sky";
139
+ ConfigStringIndex22[ConfigStringIndex22["SkyAxis"] = 3] = "SkyAxis";
140
+ ConfigStringIndex22[ConfigStringIndex22["SkyRotate"] = 4] = "SkyRotate";
141
+ ConfigStringIndex22[ConfigStringIndex22["StatusBar"] = 5] = "StatusBar";
142
+ ConfigStringIndex22[ConfigStringIndex22["AirAccel"] = 59] = "AirAccel";
143
+ ConfigStringIndex22[ConfigStringIndex22["MaxClients"] = 60] = "MaxClients";
144
+ ConfigStringIndex22[ConfigStringIndex22["MapChecksum"] = 61] = "MapChecksum";
145
+ ConfigStringIndex22[ConfigStringIndex22["Models"] = 62] = "Models";
146
+ ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS] = "Sounds";
147
+ ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS] = "Images";
148
+ ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES] = "Lights";
149
+ ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES] = "ShadowLights";
150
+ ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS] = "Items";
151
+ ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS] = "PlayerSkins";
152
+ ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS] = "General";
153
+ ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL] = "WheelWeapons";
154
+ ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS] = "WheelAmmo";
155
+ ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS] = "WheelPowerups";
156
+ ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS] = "CdLoopCount";
157
+ ConfigStringIndex22[ConfigStringIndex22["GameStyle"] = ConfigStringIndex22.CdLoopCount + 1] = "GameStyle";
158
+ ConfigStringIndex22[ConfigStringIndex22["MaxConfigStrings"] = ConfigStringIndex22.GameStyle + 1] = "MaxConfigStrings";
159
+ return ConfigStringIndex22;
160
+ })(ConfigStringIndex || {});
161
+ var MAX_CONFIGSTRINGS = ConfigStringIndex.MaxConfigStrings;
162
+ var WaterLevel = /* @__PURE__ */ ((WaterLevel3) => {
163
+ WaterLevel3[WaterLevel3["None"] = 0] = "None";
164
+ WaterLevel3[WaterLevel3["Feet"] = 1] = "Feet";
165
+ WaterLevel3[WaterLevel3["Waist"] = 2] = "Waist";
166
+ WaterLevel3[WaterLevel3["Under"] = 3] = "Under";
167
+ return WaterLevel3;
168
+ })(WaterLevel || {});
169
+ var PmFlag = /* @__PURE__ */ ((PmFlag2) => {
170
+ PmFlag2[PmFlag2["Ducked"] = 1] = "Ducked";
171
+ PmFlag2[PmFlag2["JumpHeld"] = 2] = "JumpHeld";
172
+ PmFlag2[PmFlag2["OnGround"] = 4] = "OnGround";
173
+ PmFlag2[PmFlag2["TimeWaterJump"] = 8] = "TimeWaterJump";
174
+ PmFlag2[PmFlag2["TimeLand"] = 16] = "TimeLand";
175
+ PmFlag2[PmFlag2["TimeTeleport"] = 32] = "TimeTeleport";
176
+ PmFlag2[PmFlag2["NoPositionalPrediction"] = 64] = "NoPositionalPrediction";
177
+ PmFlag2[PmFlag2["OnLadder"] = 128] = "OnLadder";
178
+ PmFlag2[PmFlag2["NoAngularPrediction"] = 256] = "NoAngularPrediction";
179
+ PmFlag2[PmFlag2["IgnorePlayerCollision"] = 512] = "IgnorePlayerCollision";
180
+ PmFlag2[PmFlag2["TimeTrick"] = 1024] = "TimeTrick";
181
+ return PmFlag2;
182
+ })(PmFlag || {});
183
+ function hasPmFlag(flags, flag) {
184
+ return (flags & flag) !== 0;
185
+ }
186
+ var PmType = /* @__PURE__ */ ((PmType2) => {
187
+ PmType2[PmType2["Normal"] = 0] = "Normal";
188
+ PmType2[PmType2["Grapple"] = 1] = "Grapple";
189
+ PmType2[PmType2["NoClip"] = 2] = "NoClip";
190
+ PmType2[PmType2["Spectator"] = 3] = "Spectator";
191
+ PmType2[PmType2["Dead"] = 4] = "Dead";
192
+ PmType2[PmType2["Gib"] = 5] = "Gib";
193
+ PmType2[PmType2["Freeze"] = 6] = "Freeze";
194
+ return PmType2;
195
+ })(PmType || {});
196
+ var PlayerButton = /* @__PURE__ */ ((PlayerButton2) => {
197
+ PlayerButton2[PlayerButton2["None"] = 0] = "None";
198
+ PlayerButton2[PlayerButton2["Attack"] = 1] = "Attack";
199
+ PlayerButton2[PlayerButton2["Use"] = 2] = "Use";
200
+ PlayerButton2[PlayerButton2["Holster"] = 4] = "Holster";
201
+ PlayerButton2[PlayerButton2["Jump"] = 8] = "Jump";
202
+ PlayerButton2[PlayerButton2["Crouch"] = 16] = "Crouch";
203
+ PlayerButton2[PlayerButton2["Any"] = 128] = "Any";
204
+ return PlayerButton2;
205
+ })(PlayerButton || {});
206
+ function applyPmoveFriction(params) {
207
+ const {
208
+ velocity,
209
+ frametime,
210
+ onGround,
211
+ groundIsSlick,
212
+ onLadder,
213
+ waterlevel,
214
+ pmFriction,
215
+ pmStopSpeed,
216
+ pmWaterFriction
217
+ } = params;
218
+ const speed = lengthVec3(velocity);
219
+ if (speed < 1) {
220
+ return { x: 0, y: 0, z: velocity.z };
221
+ }
222
+ let drop = 0;
223
+ if (onGround && !groundIsSlick || onLadder) {
224
+ const control = speed < pmStopSpeed ? pmStopSpeed : speed;
225
+ const friction = pmFriction;
226
+ drop += control * friction * frametime;
227
+ }
228
+ if (waterlevel > 0 && !onLadder) {
229
+ drop += speed * pmWaterFriction * waterlevel * frametime;
230
+ }
231
+ let newspeed = speed - drop;
232
+ if (newspeed < 0) {
233
+ newspeed = 0;
234
+ }
235
+ if (newspeed === speed) {
236
+ return velocity;
237
+ }
238
+ const scale = newspeed / speed;
239
+ return scaleVec3(velocity, scale);
240
+ }
241
+ function applyPmoveAccelerate(params) {
242
+ const { velocity, wishdir, wishspeed, accel, frametime } = params;
243
+ const currentSpeed = dotVec3(velocity, wishdir);
244
+ const addSpeed = wishspeed - currentSpeed;
245
+ if (addSpeed <= 0) {
246
+ return velocity;
247
+ }
248
+ let accelSpeed = accel * frametime * wishspeed;
249
+ if (accelSpeed > addSpeed) {
250
+ accelSpeed = addSpeed;
251
+ }
252
+ return {
253
+ x: velocity.x + wishdir.x * accelSpeed,
254
+ y: velocity.y + wishdir.y * accelSpeed,
255
+ z: velocity.z + wishdir.z * accelSpeed
256
+ };
257
+ }
258
+ function applyPmoveAirAccelerate(params) {
259
+ const { velocity, wishdir, wishspeed, accel, frametime } = params;
260
+ const wishspd = Math.min(wishspeed, 30);
261
+ const currentSpeed = dotVec3(velocity, wishdir);
262
+ const addSpeed = wishspd - currentSpeed;
263
+ if (addSpeed <= 0) {
264
+ return velocity;
265
+ }
266
+ let accelSpeed = accel * wishspeed * frametime;
267
+ if (accelSpeed > addSpeed) {
268
+ accelSpeed = addSpeed;
269
+ }
270
+ return {
271
+ x: velocity.x + wishdir.x * accelSpeed,
272
+ y: velocity.y + wishdir.y * accelSpeed,
273
+ z: velocity.z + wishdir.z * accelSpeed
274
+ };
275
+ }
276
+ function buildAirGroundWish(params) {
277
+ const { forward, right, cmd, maxSpeed } = params;
278
+ let wishvel = {
279
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
280
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
281
+ z: 0
282
+ };
283
+ let wishspeed = lengthVec3(wishvel);
284
+ if (wishspeed > maxSpeed) {
285
+ const scale = maxSpeed / wishspeed;
286
+ wishvel = scaleVec3(wishvel, scale);
287
+ wishspeed = maxSpeed;
288
+ }
289
+ return {
290
+ wishdir: wishspeed === 0 ? wishvel : normalizeVec3(wishvel),
291
+ wishspeed
292
+ };
293
+ }
294
+ function buildWaterWish(params) {
295
+ const { forward, right, cmd, maxSpeed } = params;
296
+ let wishvel = {
297
+ x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
298
+ y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
299
+ z: 0
300
+ };
301
+ if (cmd.upmove > 10) {
302
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
303
+ } else if (cmd.upmove < -10) {
304
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
305
+ } else {
306
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: 10 });
307
+ }
308
+ let wishspeed = lengthVec3(wishvel);
309
+ if (wishspeed > maxSpeed) {
310
+ const scale = maxSpeed / wishspeed;
311
+ wishvel = scaleVec3(wishvel, scale);
312
+ wishspeed = maxSpeed;
313
+ }
314
+ wishspeed *= 0.5;
315
+ return {
316
+ wishdir: wishspeed === 0 ? wishvel : normalizeVec3(wishvel),
317
+ wishspeed
318
+ };
319
+ }
320
+ var WATERJUMP_CLEAR = 8 | 16 | 32 | 1024;
321
+ function addAngles(cmdAngles, deltaAngles) {
322
+ return {
323
+ x: cmdAngles.x + deltaAngles.x,
324
+ y: cmdAngles.y + deltaAngles.y,
325
+ z: cmdAngles.z + deltaAngles.z
326
+ };
327
+ }
328
+ function clampPitch(pitch) {
329
+ if (pitch > 89 && pitch < 180) {
330
+ return 89;
331
+ }
332
+ if (pitch < 271 && pitch >= 180) {
333
+ return 271;
334
+ }
335
+ return pitch;
336
+ }
337
+ function clampViewAngles(params) {
338
+ const { pmFlags, cmdAngles, deltaAngles } = params;
339
+ let viewangles;
340
+ if ((pmFlags & 32) !== 0) {
341
+ viewangles = {
342
+ x: 0,
343
+ y: cmdAngles.y + deltaAngles.y,
344
+ z: 0
345
+ };
346
+ } else {
347
+ viewangles = addAngles(cmdAngles, deltaAngles);
348
+ viewangles = { ...viewangles, x: clampPitch(viewangles.x) };
349
+ }
350
+ const vectors = angleVectors(viewangles);
351
+ return { viewangles, ...vectors };
352
+ }
353
+ var DEFAULTS = {
354
+ pmFriction: 6,
355
+ pmStopSpeed: 100,
356
+ pmAccelerate: 10,
357
+ pmAirAccelerate: 1,
358
+ pmWaterAccelerate: 4,
359
+ pmWaterFriction: 1,
360
+ pmMaxSpeed: 300,
361
+ pmDuckSpeed: 100,
362
+ pmWaterSpeed: 400,
363
+ groundIsSlick: false
364
+ };
365
+ var DEFAULT_GRAVITY = 800;
366
+ var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
367
+ var MSEC_MAX = 250;
368
+ function defaultPredictionState() {
369
+ return {
370
+ origin: ZERO_VEC32,
371
+ velocity: ZERO_VEC32,
372
+ viewangles: ZERO_VEC32,
373
+ pmFlags: PmFlag.OnGround,
374
+ pmType: PmType.Normal,
375
+ waterlevel: WaterLevel.None,
376
+ gravity: DEFAULT_GRAVITY,
377
+ deltaAngles: ZERO_VEC32
378
+ };
379
+ }
380
+ function normalizeState(state) {
381
+ if (!state) return defaultPredictionState();
382
+ return {
383
+ ...defaultPredictionState(),
384
+ ...state,
385
+ origin: { ...state.origin },
386
+ velocity: { ...state.velocity },
387
+ viewangles: { ...state.viewangles },
388
+ deltaAngles: state.deltaAngles ? { ...state.deltaAngles } : ZERO_VEC32
389
+ };
390
+ }
391
+ function lerp(a, b, t) {
392
+ return a + (b - a) * t;
393
+ }
394
+ function lerpAngle(a, b, t) {
395
+ let delta = angleMod(b - a);
396
+ if (delta > 180) {
397
+ delta -= 360;
398
+ }
399
+ return angleMod(a + delta * t);
400
+ }
401
+ function interpolatePredictionState(previous, latest, alpha) {
402
+ const clamped = Math.max(0, Math.min(alpha, 1));
403
+ return {
404
+ origin: {
405
+ x: lerp(previous.origin.x, latest.origin.x, clamped),
406
+ y: lerp(previous.origin.y, latest.origin.y, clamped),
407
+ z: lerp(previous.origin.z, latest.origin.z, clamped)
408
+ },
409
+ velocity: {
410
+ x: lerp(previous.velocity.x, latest.velocity.x, clamped),
411
+ y: lerp(previous.velocity.y, latest.velocity.y, clamped),
412
+ z: lerp(previous.velocity.z, latest.velocity.z, clamped)
413
+ },
414
+ viewangles: {
415
+ x: lerpAngle(previous.viewangles.x, latest.viewangles.x, clamped),
416
+ y: lerpAngle(previous.viewangles.y, latest.viewangles.y, clamped),
417
+ z: lerpAngle(previous.viewangles.z, latest.viewangles.z, clamped)
418
+ },
419
+ pmFlags: latest.pmFlags,
420
+ pmType: latest.pmType,
421
+ waterlevel: latest.waterlevel,
422
+ gravity: latest.gravity,
423
+ deltaAngles: latest.deltaAngles
424
+ };
425
+ }
426
+ function simulateCommand(state, cmd, settings) {
427
+ const frametime = Math.min(Math.max(cmd.msec, 0), MSEC_MAX) / 1e3;
428
+ const onGround = hasPmFlag(state.pmFlags, PmFlag.OnGround);
429
+ const onLadder = hasPmFlag(state.pmFlags, PmFlag.OnLadder);
430
+ let velocity = applyPmoveFriction({
431
+ velocity: state.velocity,
432
+ frametime,
433
+ onGround,
434
+ groundIsSlick: settings.groundIsSlick,
435
+ onLadder,
436
+ waterlevel: state.waterlevel,
437
+ pmFriction: settings.pmFriction,
438
+ pmStopSpeed: settings.pmStopSpeed,
439
+ pmWaterFriction: settings.pmWaterFriction
440
+ });
441
+ const { viewangles, forward, right } = clampViewAngles({
442
+ pmFlags: state.pmFlags,
443
+ cmdAngles: cmd.angles,
444
+ deltaAngles: state.deltaAngles ?? ZERO_VEC32
445
+ });
446
+ const wish = state.waterlevel > WaterLevel.None ? buildWaterWish({ forward, right, cmd, maxSpeed: settings.pmWaterSpeed }) : buildAirGroundWish({ forward, right, cmd, maxSpeed: settings.pmMaxSpeed });
447
+ if (state.waterlevel > WaterLevel.None) {
448
+ velocity = applyPmoveAccelerate({
449
+ velocity,
450
+ wishdir: wish.wishdir,
451
+ wishspeed: wish.wishspeed,
452
+ accel: settings.pmWaterAccelerate,
453
+ frametime
454
+ });
455
+ } else if (onGround || onLadder) {
456
+ const maxSpeed = hasPmFlag(state.pmFlags, PmFlag.Ducked) ? settings.pmDuckSpeed : settings.pmMaxSpeed;
457
+ const clampedWish = wish.wishspeed > maxSpeed ? {
458
+ wishdir: wish.wishdir,
459
+ wishspeed: maxSpeed
460
+ } : wish;
461
+ velocity = applyPmoveAccelerate({
462
+ velocity,
463
+ wishdir: clampedWish.wishdir,
464
+ wishspeed: clampedWish.wishspeed,
465
+ accel: settings.pmAccelerate,
466
+ frametime
467
+ });
468
+ } else {
469
+ velocity = applyPmoveAirAccelerate({
470
+ velocity,
471
+ wishdir: wish.wishdir,
472
+ wishspeed: wish.wishspeed,
473
+ accel: settings.pmAirAccelerate,
474
+ frametime
475
+ });
476
+ velocity = { ...velocity, z: velocity.z - state.gravity * frametime };
477
+ }
478
+ const originDelta = scaleVec3(velocity, frametime);
479
+ const origin = addVec3(state.origin, originDelta);
480
+ return {
481
+ ...state,
482
+ origin,
483
+ velocity,
484
+ viewangles
485
+ };
486
+ }
487
+ var ClientPrediction = class {
488
+ constructor(settings = {}) {
489
+ this.baseFrame = {
490
+ frame: 0,
491
+ timeMs: 0,
492
+ state: defaultPredictionState()
493
+ };
494
+ this.commands = [];
495
+ this.predicted = defaultPredictionState();
496
+ this.settings = { ...DEFAULTS, ...settings };
497
+ this.predicted = this.baseFrame.state ?? defaultPredictionState();
498
+ }
499
+ setAuthoritative(frame) {
500
+ const normalized = normalizeState(frame.state);
501
+ this.baseFrame = { ...frame, state: normalized };
502
+ this.commands = this.commands.filter((cmd) => (cmd.serverFrame ?? Number.MAX_SAFE_INTEGER) > frame.frame);
503
+ return this.recompute();
504
+ }
505
+ enqueueCommand(cmd) {
506
+ this.commands.push(cmd);
507
+ return this.recompute();
508
+ }
509
+ getPredictedState() {
510
+ return this.predicted;
511
+ }
512
+ recompute() {
513
+ let state = normalizeState(this.baseFrame.state);
514
+ for (const cmd of this.commands) {
515
+ state = simulateCommand(state, cmd, this.settings);
516
+ }
517
+ this.predicted = state;
518
+ return state;
519
+ }
520
+ };
521
+ var DEFAULT_SETTINGS = {
522
+ runPitch: 2e-3,
523
+ runRoll: 5e-3,
524
+ bobUp: 5e-3,
525
+ bobPitch: 2e-3,
526
+ bobRoll: 2e-3,
527
+ maxBobHeight: 6,
528
+ maxBobAngle: 1.2
529
+ };
530
+ function clampViewOffset(offset) {
531
+ return {
532
+ x: Math.max(-14, Math.min(14, offset.x)),
533
+ y: Math.max(-14, Math.min(14, offset.y)),
534
+ z: Math.max(-22, Math.min(30, offset.z))
535
+ };
536
+ }
537
+ function computeBobMove(xyspeed, onGround, frameTimeMs) {
538
+ if (!onGround) return 0;
539
+ if (xyspeed > 210) return frameTimeMs / 400;
540
+ if (xyspeed > 100) return frameTimeMs / 800;
541
+ return frameTimeMs / 1600;
542
+ }
543
+ function computeBobValues(previousBobTime, xyspeed, pmFlags, onGround, frameTimeMs) {
544
+ if (xyspeed < 5) {
545
+ return { bobTime: 0, bobCycle: 0, bobCycleRun: 0, bobFracSin: 0 };
546
+ }
547
+ const bobMove = computeBobMove(xyspeed, onGround, frameTimeMs);
548
+ const bobTimeRun = previousBobTime + bobMove;
549
+ const crouched = hasPmFlag(pmFlags, PmFlag.Ducked) && onGround;
550
+ const bobTime = crouched ? bobTimeRun * 4 : bobTimeRun;
551
+ return {
552
+ bobTime: bobTimeRun,
553
+ bobCycle: Math.floor(bobTime),
554
+ bobCycleRun: Math.floor(bobTimeRun),
555
+ bobFracSin: Math.abs(Math.sin(bobTime * Math.PI))
556
+ };
557
+ }
558
+ var ViewEffects = class {
559
+ constructor(settings = {}) {
560
+ this.bobTime = 0;
561
+ this.bobCycle = 0;
562
+ this.bobCycleRun = 0;
563
+ this.bobFracSin = 0;
564
+ this.settings = { ...DEFAULT_SETTINGS, ...settings };
565
+ }
566
+ addKick(kick) {
567
+ if (kick.durationMs <= 0) return;
568
+ this.kick = { ...kick, remainingMs: kick.durationMs };
569
+ }
570
+ get last() {
571
+ return this.lastSample;
572
+ }
573
+ sample(state, frameTimeMs) {
574
+ const { forward, right } = angleVectors(
575
+ clampViewAngles({ pmFlags: state.pmFlags, cmdAngles: state.viewangles, deltaAngles: state.deltaAngles ?? ZERO_VEC3 }).viewangles
576
+ );
577
+ const xyspeed = Math.sqrt(state.velocity.x * state.velocity.x + state.velocity.y * state.velocity.y);
578
+ const onGround = hasPmFlag(state.pmFlags, PmFlag.OnGround);
579
+ const bobValues = computeBobValues(this.bobTime, xyspeed, state.pmFlags, onGround, frameTimeMs);
580
+ this.bobTime = bobValues.bobTime;
581
+ this.bobCycle = bobValues.bobCycle;
582
+ this.bobCycleRun = bobValues.bobCycleRun;
583
+ this.bobFracSin = bobValues.bobFracSin;
584
+ let pitchTilt = dotVec3(state.velocity, forward) * this.settings.runPitch;
585
+ let rollTilt = dotVec3(state.velocity, right) * this.settings.runRoll;
586
+ let pitchDelta = this.bobFracSin * this.settings.bobPitch * xyspeed;
587
+ let rollDelta = this.bobFracSin * this.settings.bobRoll * xyspeed;
588
+ if (hasPmFlag(state.pmFlags, PmFlag.Ducked) && onGround) {
589
+ pitchDelta *= 6;
590
+ rollDelta *= 6;
591
+ }
592
+ pitchTilt += Math.min(pitchDelta, this.settings.maxBobAngle);
593
+ rollDelta = Math.min(rollDelta, this.settings.maxBobAngle);
594
+ if (this.bobCycle & 1) rollDelta = -rollDelta;
595
+ rollTilt += rollDelta;
596
+ const bobHeight = Math.min(this.bobFracSin * xyspeed * this.settings.bobUp, this.settings.maxBobHeight);
597
+ let kickPitch = 0;
598
+ let kickRoll = 0;
599
+ if (this.kick && this.kick.remainingMs > 0) {
600
+ const ratio = Math.max(0, Math.min(1, this.kick.remainingMs / this.kick.durationMs));
601
+ kickPitch += ratio * this.kick.pitch;
602
+ kickRoll += ratio * this.kick.roll;
603
+ this.kick.remainingMs = Math.max(0, this.kick.remainingMs - frameTimeMs);
604
+ if (this.kick.remainingMs === 0) this.kick = void 0;
605
+ }
606
+ const angles = { x: pitchTilt + kickPitch, y: 0, z: rollTilt + kickRoll };
607
+ const offset = { x: 0, y: 0, z: bobHeight };
608
+ const sample = {
609
+ angles,
610
+ offset: clampViewOffset(offset),
611
+ bobCycle: this.bobCycle,
612
+ bobCycleRun: this.bobCycleRun,
613
+ bobFracSin: this.bobFracSin,
614
+ xyspeed
615
+ };
616
+ this.lastSample = sample;
617
+ return sample;
618
+ }
619
+ };
620
+ function normalizeCommand(command) {
621
+ return command.trim().toLowerCase();
622
+ }
623
+ var InputAction = /* @__PURE__ */ ((InputAction2) => {
624
+ InputAction2["Forward"] = "+forward";
625
+ InputAction2["Back"] = "+back";
626
+ InputAction2["MoveLeft"] = "+moveleft";
627
+ InputAction2["MoveRight"] = "+moveright";
628
+ InputAction2["MoveUp"] = "+moveup";
629
+ InputAction2["MoveDown"] = "+movedown";
630
+ InputAction2["Jump"] = "+jump";
631
+ InputAction2["Crouch"] = "+crouch";
632
+ InputAction2["Attack"] = "+attack";
633
+ InputAction2["Use"] = "+use";
634
+ InputAction2["Holster"] = "+holster";
635
+ InputAction2["TurnLeft"] = "+left";
636
+ InputAction2["TurnRight"] = "+right";
637
+ InputAction2["LookUp"] = "+lookup";
638
+ InputAction2["LookDown"] = "+lookdown";
639
+ InputAction2["SpeedModifier"] = "+speed";
640
+ InputAction2["Zoom"] = "+zoom";
641
+ return InputAction2;
642
+ })(InputAction || {});
643
+ var BUTTON_ACTIONS = {
644
+ [
645
+ "+attack"
646
+ /* Attack */
647
+ ]: PlayerButton.Attack,
648
+ [
649
+ "+use"
650
+ /* Use */
651
+ ]: PlayerButton.Use,
652
+ [
653
+ "+holster"
654
+ /* Holster */
655
+ ]: PlayerButton.Holster,
656
+ [
657
+ "+jump"
658
+ /* Jump */
659
+ ]: PlayerButton.Jump,
660
+ [
661
+ "+crouch"
662
+ /* Crouch */
663
+ ]: PlayerButton.Crouch
664
+ };
665
+ var ACTION_LOOKUP = new Map(
666
+ Object.values(InputAction).map((action) => [normalizeCommand(action), action])
667
+ );
2
668
  function createClient(imports) {
669
+ const prediction = new ClientPrediction();
670
+ const view = new ViewEffects();
3
671
  let latestFrame;
672
+ let lastRendered;
673
+ let lastView;
4
674
  return {
5
675
  init(initial) {
6
676
  latestFrame = initial;
677
+ if (initial?.state) {
678
+ prediction.setAuthoritative(initial);
679
+ }
7
680
  void imports.engine.trace({ x: 0, y: 0, z: 0 }, { x: 1, y: 0, z: 0 });
8
681
  },
9
- predict(next) {
10
- const { origin, velocity } = next;
11
- return {
12
- origin: {
13
- x: origin.x + velocity.x,
14
- y: origin.y + velocity.y,
15
- z: origin.z + velocity.z
16
- },
17
- velocity
18
- };
682
+ predict(command) {
683
+ return prediction.enqueueCommand(command);
19
684
  },
20
685
  render(sample) {
21
- latestFrame = sample.latest ?? latestFrame;
686
+ if (sample.latest?.state) {
687
+ prediction.setAuthoritative(sample.latest);
688
+ latestFrame = sample.latest;
689
+ }
690
+ if (sample.previous?.state && sample.latest?.state) {
691
+ lastRendered = interpolatePredictionState(sample.previous.state, sample.latest.state, sample.alpha);
692
+ } else {
693
+ lastRendered = sample.latest?.state ?? sample.previous?.state ?? prediction.getPredictedState();
694
+ }
695
+ const frameTimeMs = sample.latest && sample.previous ? Math.max(0, sample.latest.timeMs - sample.previous.timeMs) : 0;
696
+ lastView = view.sample(lastRendered, frameTimeMs);
697
+ void imports;
22
698
  void sample;
23
699
  },
24
700
  shutdown() {
25
701
  latestFrame = void 0;
702
+ lastRendered = void 0;
703
+ },
704
+ get prediction() {
705
+ return prediction;
706
+ },
707
+ get lastRendered() {
708
+ return lastRendered;
709
+ },
710
+ get view() {
711
+ return view;
712
+ },
713
+ get lastView() {
714
+ return lastView;
26
715
  }
27
716
  };
28
717
  }
@@ -155,71 +844,72 @@ var EngineHost = class {
155
844
  return this.loop.isRunning();
156
845
  }
157
846
  };
158
- var DEG_TO_RAD = Math.PI / 180;
159
- var DEG2RAD_FACTOR = Math.PI / 180;
160
- var RAD2DEG_FACTOR = 180 / Math.PI;
161
- var CONTENTS_SOLID = 1 << 0;
162
- var CONTENTS_WINDOW = 1 << 1;
163
- var CONTENTS_AUX = 1 << 2;
164
- var CONTENTS_LAVA = 1 << 3;
165
- var CONTENTS_SLIME = 1 << 4;
166
- var CONTENTS_WATER = 1 << 5;
167
- var CONTENTS_MIST = 1 << 6;
168
- var CONTENTS_NO_WATERJUMP = 1 << 13;
169
- var CONTENTS_PROJECTILECLIP = 1 << 14;
170
- var CONTENTS_AREAPORTAL = 1 << 15;
171
- var CONTENTS_PLAYERCLIP = 1 << 16;
172
- var CONTENTS_MONSTERCLIP = 1 << 17;
173
- var CONTENTS_CURRENT_0 = 1 << 18;
174
- var CONTENTS_CURRENT_90 = 1 << 19;
175
- var CONTENTS_CURRENT_180 = 1 << 20;
176
- var CONTENTS_CURRENT_270 = 1 << 21;
177
- var CONTENTS_CURRENT_UP = 1 << 22;
178
- var CONTENTS_CURRENT_DOWN = 1 << 23;
179
- var CONTENTS_ORIGIN = 1 << 24;
180
- var CONTENTS_MONSTER = 1 << 25;
181
- var CONTENTS_DEADMONSTER = 1 << 26;
182
- var CONTENTS_DETAIL = 1 << 27;
183
- var CONTENTS_TRANSLUCENT = 1 << 28;
184
- var CONTENTS_LADDER = 1 << 29;
185
- var CONTENTS_PLAYER = 1 << 30;
186
- var CONTENTS_PROJECTILE = 1 << 31;
187
- var SURF_LIGHT = 1 << 0;
188
- var SURF_SLICK = 1 << 1;
189
- var SURF_SKY = 1 << 2;
190
- var SURF_WARP = 1 << 3;
191
- var SURF_TRANS33 = 1 << 4;
192
- var SURF_TRANS66 = 1 << 5;
193
- var SURF_FLOWING = 1 << 6;
194
- var SURF_NODRAW = 1 << 7;
195
- var SURF_ALPHATEST = 1 << 25;
196
- var SURF_N64_UV = 1 << 28;
197
- var SURF_N64_SCROLL_X = 1 << 29;
198
- var SURF_N64_SCROLL_Y = 1 << 30;
199
- var SURF_N64_SCROLL_FLIP = 1 << 31;
200
- var MASK_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
201
- var MASK_PLAYERSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
202
- var MASK_DEADSOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
203
- var MASK_MONSTERSOLID = CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_PLAYER;
204
- var MASK_WATER = CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME;
205
- var MASK_OPAQUE = CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA;
206
- var MASK_SHOT = CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER | CONTENTS_WINDOW | CONTENTS_DEADMONSTER;
207
- var MASK_CURRENT = CONTENTS_CURRENT_0 | CONTENTS_CURRENT_90 | CONTENTS_CURRENT_180 | CONTENTS_CURRENT_270 | CONTENTS_CURRENT_UP | CONTENTS_CURRENT_DOWN;
208
- var MASK_BLOCK_SIGHT = CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_MONSTER | CONTENTS_PLAYER;
209
- var MASK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW;
210
- var MASK_LADDER_NAV_SOLID = CONTENTS_SOLID | CONTENTS_WINDOW;
211
- var MASK_WALK_NAV_SOLID = CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTERCLIP;
212
- var MASK_PROJECTILE = MASK_SHOT | CONTENTS_PROJECTILECLIP;
213
- var MAX_CLIENTS = 256;
214
- var MAX_LIGHTSTYLES = 256;
215
- var MAX_MODELS = 8192;
216
- var MAX_SOUNDS = 2048;
217
- var MAX_IMAGES = 512;
218
- var MAX_ITEMS = 256;
219
- var MAX_GENERAL = MAX_CLIENTS * 2;
220
- var MAX_SHADOW_LIGHTS = 256;
221
- var MAX_WHEEL_ITEMS = 32;
222
- var ConfigStringIndex = ((ConfigStringIndex22) => {
847
+ var DEG_TO_RAD2 = Math.PI / 180;
848
+ var DEG2RAD_FACTOR2 = Math.PI / 180;
849
+ var RAD2DEG_FACTOR2 = 180 / Math.PI;
850
+ var CONTENTS_SOLID2 = 1 << 0;
851
+ var CONTENTS_WINDOW2 = 1 << 1;
852
+ var CONTENTS_AUX2 = 1 << 2;
853
+ var CONTENTS_LAVA2 = 1 << 3;
854
+ var CONTENTS_SLIME2 = 1 << 4;
855
+ var CONTENTS_WATER2 = 1 << 5;
856
+ var CONTENTS_MIST2 = 1 << 6;
857
+ var CONTENTS_NO_WATERJUMP2 = 1 << 13;
858
+ var CONTENTS_PROJECTILECLIP2 = 1 << 14;
859
+ var CONTENTS_AREAPORTAL2 = 1 << 15;
860
+ var CONTENTS_PLAYERCLIP2 = 1 << 16;
861
+ var CONTENTS_MONSTERCLIP2 = 1 << 17;
862
+ var CONTENTS_CURRENT_02 = 1 << 18;
863
+ var CONTENTS_CURRENT_902 = 1 << 19;
864
+ var CONTENTS_CURRENT_1802 = 1 << 20;
865
+ var CONTENTS_CURRENT_2702 = 1 << 21;
866
+ var CONTENTS_CURRENT_UP2 = 1 << 22;
867
+ var CONTENTS_CURRENT_DOWN2 = 1 << 23;
868
+ var CONTENTS_ORIGIN2 = 1 << 24;
869
+ var CONTENTS_MONSTER2 = 1 << 25;
870
+ var CONTENTS_DEADMONSTER2 = 1 << 26;
871
+ var CONTENTS_DETAIL2 = 1 << 27;
872
+ var CONTENTS_TRANSLUCENT2 = 1 << 28;
873
+ var CONTENTS_LADDER2 = 1 << 29;
874
+ var CONTENTS_PLAYER2 = 1 << 30;
875
+ var CONTENTS_PROJECTILE2 = 1 << 31;
876
+ var SURF_LIGHT2 = 1 << 0;
877
+ var SURF_SLICK2 = 1 << 1;
878
+ var SURF_SKY2 = 1 << 2;
879
+ var SURF_WARP2 = 1 << 3;
880
+ var SURF_TRANS332 = 1 << 4;
881
+ var SURF_TRANS662 = 1 << 5;
882
+ var SURF_FLOWING2 = 1 << 6;
883
+ var SURF_NODRAW2 = 1 << 7;
884
+ var SURF_ALPHATEST2 = 1 << 25;
885
+ var SURF_N64_UV2 = 1 << 28;
886
+ var SURF_N64_SCROLL_X2 = 1 << 29;
887
+ var SURF_N64_SCROLL_Y2 = 1 << 30;
888
+ var SURF_N64_SCROLL_FLIP2 = 1 << 31;
889
+ var MASK_SOLID2 = CONTENTS_SOLID2 | CONTENTS_WINDOW2;
890
+ var MASK_PLAYERSOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
891
+ var MASK_DEADSOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2;
892
+ var MASK_MONSTERSOLID2 = CONTENTS_SOLID2 | CONTENTS_MONSTERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
893
+ var MASK_WATER2 = CONTENTS_WATER2 | CONTENTS_LAVA2 | CONTENTS_SLIME2;
894
+ var MASK_OPAQUE2 = CONTENTS_SOLID2 | CONTENTS_SLIME2 | CONTENTS_LAVA2;
895
+ var MASK_SHOT2 = CONTENTS_SOLID2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2 | CONTENTS_WINDOW2 | CONTENTS_DEADMONSTER2;
896
+ var MASK_CURRENT2 = CONTENTS_CURRENT_02 | CONTENTS_CURRENT_902 | CONTENTS_CURRENT_1802 | CONTENTS_CURRENT_2702 | CONTENTS_CURRENT_UP2 | CONTENTS_CURRENT_DOWN2;
897
+ var MASK_BLOCK_SIGHT2 = CONTENTS_SOLID2 | CONTENTS_LAVA2 | CONTENTS_SLIME2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
898
+ var MASK_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2;
899
+ var MASK_LADDER_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_WINDOW2;
900
+ var MASK_WALK_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTERCLIP2;
901
+ var MASK_PROJECTILE2 = MASK_SHOT2 | CONTENTS_PROJECTILECLIP2;
902
+ var MAX_CHECKCOUNT2 = Number.MAX_SAFE_INTEGER - 1;
903
+ var MAX_CLIENTS2 = 256;
904
+ var MAX_LIGHTSTYLES2 = 256;
905
+ var MAX_MODELS2 = 8192;
906
+ var MAX_SOUNDS2 = 2048;
907
+ var MAX_IMAGES2 = 512;
908
+ var MAX_ITEMS2 = 256;
909
+ var MAX_GENERAL2 = MAX_CLIENTS2 * 2;
910
+ var MAX_SHADOW_LIGHTS2 = 256;
911
+ var MAX_WHEEL_ITEMS2 = 32;
912
+ var ConfigStringIndex2 = ((ConfigStringIndex22) => {
223
913
  ConfigStringIndex22[ConfigStringIndex22["Name"] = 0] = "Name";
224
914
  ConfigStringIndex22[ConfigStringIndex22["CdTrack"] = 1] = "CdTrack";
225
915
  ConfigStringIndex22[ConfigStringIndex22["Sky"] = 2] = "Sky";
@@ -230,23 +920,23 @@ var ConfigStringIndex = ((ConfigStringIndex22) => {
230
920
  ConfigStringIndex22[ConfigStringIndex22["MaxClients"] = 60] = "MaxClients";
231
921
  ConfigStringIndex22[ConfigStringIndex22["MapChecksum"] = 61] = "MapChecksum";
232
922
  ConfigStringIndex22[ConfigStringIndex22["Models"] = 62] = "Models";
233
- ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS] = "Sounds";
234
- ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS] = "Images";
235
- ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES] = "Lights";
236
- ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES] = "ShadowLights";
237
- ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS] = "Items";
238
- ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS] = "PlayerSkins";
239
- ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS] = "General";
240
- ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL] = "WheelWeapons";
241
- ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS] = "WheelAmmo";
242
- ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS] = "WheelPowerups";
243
- ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS] = "CdLoopCount";
923
+ ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS2] = "Sounds";
924
+ ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS2] = "Images";
925
+ ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES2] = "Lights";
926
+ ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES2] = "ShadowLights";
927
+ ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS2] = "Items";
928
+ ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS2] = "PlayerSkins";
929
+ ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS2] = "General";
930
+ ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL2] = "WheelWeapons";
931
+ ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS2] = "WheelAmmo";
932
+ ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS2] = "WheelPowerups";
933
+ ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS2] = "CdLoopCount";
244
934
  ConfigStringIndex22[ConfigStringIndex22["GameStyle"] = ConfigStringIndex22.CdLoopCount + 1] = "GameStyle";
245
935
  ConfigStringIndex22[ConfigStringIndex22["MaxConfigStrings"] = ConfigStringIndex22.GameStyle + 1] = "MaxConfigStrings";
246
936
  return ConfigStringIndex22;
247
- })(ConfigStringIndex || {});
248
- var MAX_CONFIGSTRINGS = ConfigStringIndex.MaxConfigStrings;
249
- var WATERJUMP_CLEAR = 8 | 16 | 32 | 1024;
937
+ })(ConfigStringIndex2 || {});
938
+ var MAX_CONFIGSTRINGS2 = ConfigStringIndex2.MaxConfigStrings;
939
+ var WATERJUMP_CLEAR2 = 8 | 16 | 32 | 1024;
250
940
  var EngineRuntime = class {
251
941
  constructor(engine, host) {
252
942
  this.engine = engine;
@@ -285,102 +975,357 @@ function createCrcTable() {
285
975
  for (let j = 0; j < 8; j += 1) {
286
976
  crc = (crc & 1) !== 0 ? 3988292384 ^ crc >>> 1 : crc >>> 1;
287
977
  }
288
- table[i] = crc >>> 0;
978
+ table[i] = crc >>> 0;
979
+ }
980
+ return table;
981
+ }
982
+ var CRC_TABLE = createCrcTable();
983
+ var RERELEASE_KNOWN_PAKS = Object.freeze([
984
+ // Base campaign
985
+ { name: "pak0.pak", checksum: 2378051181, description: "Base game assets" },
986
+ { name: "pak0.pak@baseq2", checksum: 2378051181, description: "Base game assets (baseq2)" },
987
+ // Mission packs bundled with the rerelease
988
+ { name: "pak0.pak@rogue", checksum: 3373211245, description: "Ground Zero (rogue) mission pack" },
989
+ { name: "pak0.pak@xatrix", checksum: 1358269824, description: "The Reckoning (xatrix) mission pack" }
990
+ ]);
991
+ var HEADER_SIZE2 = 17 * 4;
992
+ var FLOAT_BYTES = 4;
993
+ var STRIDE = 7 * FLOAT_BYTES;
994
+ var BSP_VERTEX_LAYOUT = [
995
+ // Position
996
+ { index: 0, size: 3, type: 5126, stride: STRIDE, offset: 0 },
997
+ // Diffuse UV
998
+ { index: 1, size: 2, type: 5126, stride: STRIDE, offset: 3 * FLOAT_BYTES },
999
+ // Lightmap UV
1000
+ { index: 2, size: 2, type: 5126, stride: STRIDE, offset: 5 * FLOAT_BYTES }
1001
+ ];
1002
+ var SKYBOX_POSITIONS = new Float32Array([
1003
+ // Front
1004
+ -1,
1005
+ -1,
1006
+ 1,
1007
+ 1,
1008
+ -1,
1009
+ 1,
1010
+ 1,
1011
+ 1,
1012
+ 1,
1013
+ -1,
1014
+ -1,
1015
+ 1,
1016
+ 1,
1017
+ 1,
1018
+ 1,
1019
+ -1,
1020
+ 1,
1021
+ 1,
1022
+ // Back
1023
+ -1,
1024
+ -1,
1025
+ -1,
1026
+ -1,
1027
+ 1,
1028
+ -1,
1029
+ 1,
1030
+ 1,
1031
+ -1,
1032
+ -1,
1033
+ -1,
1034
+ -1,
1035
+ 1,
1036
+ 1,
1037
+ -1,
1038
+ 1,
1039
+ -1,
1040
+ -1,
1041
+ // Left
1042
+ -1,
1043
+ -1,
1044
+ -1,
1045
+ -1,
1046
+ -1,
1047
+ 1,
1048
+ -1,
1049
+ 1,
1050
+ 1,
1051
+ -1,
1052
+ -1,
1053
+ -1,
1054
+ -1,
1055
+ 1,
1056
+ 1,
1057
+ -1,
1058
+ 1,
1059
+ -1,
1060
+ // Right
1061
+ 1,
1062
+ -1,
1063
+ -1,
1064
+ 1,
1065
+ 1,
1066
+ -1,
1067
+ 1,
1068
+ 1,
1069
+ 1,
1070
+ 1,
1071
+ -1,
1072
+ -1,
1073
+ 1,
1074
+ 1,
1075
+ 1,
1076
+ 1,
1077
+ -1,
1078
+ 1,
1079
+ // Top
1080
+ -1,
1081
+ 1,
1082
+ -1,
1083
+ -1,
1084
+ 1,
1085
+ 1,
1086
+ 1,
1087
+ 1,
1088
+ 1,
1089
+ -1,
1090
+ 1,
1091
+ -1,
1092
+ 1,
1093
+ 1,
1094
+ 1,
1095
+ 1,
1096
+ 1,
1097
+ -1,
1098
+ // Bottom
1099
+ -1,
1100
+ -1,
1101
+ -1,
1102
+ 1,
1103
+ -1,
1104
+ -1,
1105
+ 1,
1106
+ -1,
1107
+ 1,
1108
+ -1,
1109
+ -1,
1110
+ -1,
1111
+ 1,
1112
+ -1,
1113
+ 1,
1114
+ -1,
1115
+ -1,
1116
+ 1
1117
+ ]);
1118
+ function createEngine(imports) {
1119
+ return {
1120
+ init() {
1121
+ void imports.trace({ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 });
1122
+ },
1123
+ shutdown() {
1124
+ },
1125
+ createMainLoop(callbacks, options) {
1126
+ return new FixedTimestepLoop(callbacks, options);
1127
+ }
1128
+ };
1129
+ }
1130
+
1131
+ // ../../packages/game/dist/esm/index.js
1132
+ var ZERO_VEC33 = { x: 0, y: 0, z: 0 };
1133
+ var DEG_TO_RAD3 = Math.PI / 180;
1134
+ var DEG2RAD_FACTOR3 = Math.PI / 180;
1135
+ var RAD2DEG_FACTOR3 = 180 / Math.PI;
1136
+ var STATE_SIZE = 624;
1137
+ var MIDDLE_WORD = 397;
1138
+ var MATRIX_A = 2567483615;
1139
+ var UPPER_MASK = 2147483648;
1140
+ var LOWER_MASK = 2147483647;
1141
+ var TWO_POW_32 = 4294967296;
1142
+ var MersenneTwister19937 = class {
1143
+ constructor(seed = 5489) {
1144
+ this.state = new Uint32Array(STATE_SIZE);
1145
+ this.index = STATE_SIZE;
1146
+ this.seed(seed);
1147
+ }
1148
+ seed(seed) {
1149
+ this.state[0] = seed >>> 0;
1150
+ for (let i = 1; i < STATE_SIZE; i++) {
1151
+ const prev = this.state[i - 1] ^ this.state[i - 1] >>> 30;
1152
+ const next = Math.imul(prev >>> 0, 1812433253) + i;
1153
+ this.state[i] = next >>> 0;
1154
+ }
1155
+ this.index = STATE_SIZE;
1156
+ }
1157
+ nextUint32() {
1158
+ if (this.index >= STATE_SIZE) {
1159
+ this.twist();
1160
+ }
1161
+ let y = this.state[this.index++];
1162
+ y ^= y >>> 11;
1163
+ y ^= y << 7 & 2636928640;
1164
+ y ^= y << 15 & 4022730752;
1165
+ y ^= y >>> 18;
1166
+ return y >>> 0;
1167
+ }
1168
+ twist() {
1169
+ for (let i = 0; i < STATE_SIZE; i++) {
1170
+ const y = this.state[i] & UPPER_MASK | this.state[(i + 1) % STATE_SIZE] & LOWER_MASK;
1171
+ let next = this.state[(i + MIDDLE_WORD) % STATE_SIZE] ^ y >>> 1;
1172
+ if ((y & 1) !== 0) {
1173
+ next ^= MATRIX_A;
1174
+ }
1175
+ this.state[i] = next >>> 0;
1176
+ }
1177
+ this.index = 0;
1178
+ }
1179
+ getState() {
1180
+ return {
1181
+ index: this.index,
1182
+ state: Array.from(this.state)
1183
+ };
1184
+ }
1185
+ setState(snapshot) {
1186
+ if (snapshot.state.length !== STATE_SIZE) {
1187
+ throw new Error(`Expected ${STATE_SIZE} MT state values, received ${snapshot.state.length}`);
1188
+ }
1189
+ this.index = snapshot.index;
1190
+ this.state = Uint32Array.from(snapshot.state, (value) => value >>> 0);
1191
+ }
1192
+ };
1193
+ var RandomGenerator = class {
1194
+ constructor(options = {}) {
1195
+ this.mt = new MersenneTwister19937(options.seed);
1196
+ }
1197
+ /** Uniform float in [0, 1). */
1198
+ frandom() {
1199
+ return this.mt.nextUint32() / TWO_POW_32;
1200
+ }
1201
+ /** Uniform float in [min, max). */
1202
+ frandomRange(minInclusive, maxExclusive) {
1203
+ return minInclusive + (maxExclusive - minInclusive) * this.frandom();
1204
+ }
1205
+ /** Uniform float in [0, max). */
1206
+ frandomMax(maxExclusive) {
1207
+ return this.frandomRange(0, maxExclusive);
1208
+ }
1209
+ /** Uniform float in [-1, 1). */
1210
+ crandom() {
1211
+ return this.frandomRange(-1, 1);
1212
+ }
1213
+ /** Uniform float in (-1, 1). */
1214
+ crandomOpen() {
1215
+ const epsilon = Number.EPSILON;
1216
+ return this.frandomRange(-1 + epsilon, 1);
1217
+ }
1218
+ /** Raw uint32 sample. */
1219
+ irandomUint32() {
1220
+ return this.mt.nextUint32();
1221
+ }
1222
+ /** Uniform integer in [min, max). */
1223
+ irandomRange(minInclusive, maxExclusive) {
1224
+ if (maxExclusive - minInclusive <= 1) {
1225
+ return minInclusive;
1226
+ }
1227
+ const span = maxExclusive - minInclusive;
1228
+ const limit = TWO_POW_32 - TWO_POW_32 % span;
1229
+ let sample;
1230
+ do {
1231
+ sample = this.mt.nextUint32();
1232
+ } while (sample >= limit);
1233
+ return minInclusive + sample % span;
1234
+ }
1235
+ /** Uniform integer in [0, max). */
1236
+ irandom(maxExclusive) {
1237
+ if (maxExclusive <= 0) {
1238
+ return 0;
1239
+ }
1240
+ return this.irandomRange(0, maxExclusive);
289
1241
  }
290
- return table;
291
- }
292
- var CRC_TABLE = createCrcTable();
293
- var HEADER_SIZE2 = 17 * 4;
294
- var FLOAT_BYTES = 4;
295
- var STRIDE = 7 * FLOAT_BYTES;
296
- var BSP_VERTEX_LAYOUT = [
297
- // Position
298
- { index: 0, size: 3, type: 5126, stride: STRIDE, offset: 0 },
299
- // Diffuse UV
300
- { index: 1, size: 2, type: 5126, stride: STRIDE, offset: 3 * FLOAT_BYTES },
301
- // Lightmap UV
302
- { index: 2, size: 2, type: 5126, stride: STRIDE, offset: 5 * FLOAT_BYTES }
303
- ];
304
- function createEngine(imports) {
305
- return {
306
- init() {
307
- void imports.trace({ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 });
308
- },
309
- shutdown() {
310
- },
311
- createMainLoop(callbacks, options) {
312
- return new FixedTimestepLoop(callbacks, options);
1242
+ /** Uniform time in milliseconds [min, max). */
1243
+ randomTimeRange(minMs, maxMs) {
1244
+ if (maxMs <= minMs) {
1245
+ return minMs;
313
1246
  }
314
- };
1247
+ return this.irandomRange(minMs, maxMs);
1248
+ }
1249
+ /** Uniform time in milliseconds [0, max). */
1250
+ randomTime(maxMs) {
1251
+ return this.irandom(maxMs);
1252
+ }
1253
+ randomIndex(container) {
1254
+ return this.irandom(container.length);
1255
+ }
1256
+ getState() {
1257
+ return { mt: this.mt.getState() };
1258
+ }
1259
+ setState(snapshot) {
1260
+ this.mt.setState(snapshot.mt);
1261
+ }
1262
+ };
1263
+ function createRandomGenerator(options) {
1264
+ return new RandomGenerator(options);
315
1265
  }
316
-
317
- // ../../packages/game/dist/esm/index.js
318
- var ZERO_VEC3 = { x: 0, y: 0, z: 0 };
319
- var DEG_TO_RAD2 = Math.PI / 180;
320
- var DEG2RAD_FACTOR2 = Math.PI / 180;
321
- var RAD2DEG_FACTOR2 = 180 / Math.PI;
322
- var CONTENTS_SOLID2 = 1 << 0;
323
- var CONTENTS_WINDOW2 = 1 << 1;
324
- var CONTENTS_AUX2 = 1 << 2;
325
- var CONTENTS_LAVA2 = 1 << 3;
326
- var CONTENTS_SLIME2 = 1 << 4;
327
- var CONTENTS_WATER2 = 1 << 5;
328
- var CONTENTS_MIST2 = 1 << 6;
329
- var CONTENTS_NO_WATERJUMP2 = 1 << 13;
330
- var CONTENTS_PROJECTILECLIP2 = 1 << 14;
331
- var CONTENTS_AREAPORTAL2 = 1 << 15;
332
- var CONTENTS_PLAYERCLIP2 = 1 << 16;
333
- var CONTENTS_MONSTERCLIP2 = 1 << 17;
334
- var CONTENTS_CURRENT_02 = 1 << 18;
335
- var CONTENTS_CURRENT_902 = 1 << 19;
336
- var CONTENTS_CURRENT_1802 = 1 << 20;
337
- var CONTENTS_CURRENT_2702 = 1 << 21;
338
- var CONTENTS_CURRENT_UP2 = 1 << 22;
339
- var CONTENTS_CURRENT_DOWN2 = 1 << 23;
340
- var CONTENTS_ORIGIN2 = 1 << 24;
341
- var CONTENTS_MONSTER2 = 1 << 25;
342
- var CONTENTS_DEADMONSTER2 = 1 << 26;
343
- var CONTENTS_DETAIL2 = 1 << 27;
344
- var CONTENTS_TRANSLUCENT2 = 1 << 28;
345
- var CONTENTS_LADDER2 = 1 << 29;
346
- var CONTENTS_PLAYER2 = 1 << 30;
347
- var CONTENTS_PROJECTILE2 = 1 << 31;
348
- var SURF_LIGHT2 = 1 << 0;
349
- var SURF_SLICK2 = 1 << 1;
350
- var SURF_SKY2 = 1 << 2;
351
- var SURF_WARP2 = 1 << 3;
352
- var SURF_TRANS332 = 1 << 4;
353
- var SURF_TRANS662 = 1 << 5;
354
- var SURF_FLOWING2 = 1 << 6;
355
- var SURF_NODRAW2 = 1 << 7;
356
- var SURF_ALPHATEST2 = 1 << 25;
357
- var SURF_N64_UV2 = 1 << 28;
358
- var SURF_N64_SCROLL_X2 = 1 << 29;
359
- var SURF_N64_SCROLL_Y2 = 1 << 30;
360
- var SURF_N64_SCROLL_FLIP2 = 1 << 31;
361
- var MASK_SOLID2 = CONTENTS_SOLID2 | CONTENTS_WINDOW2;
362
- var MASK_PLAYERSOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
363
- var MASK_DEADSOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2;
364
- var MASK_MONSTERSOLID2 = CONTENTS_SOLID2 | CONTENTS_MONSTERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
365
- var MASK_WATER2 = CONTENTS_WATER2 | CONTENTS_LAVA2 | CONTENTS_SLIME2;
366
- var MASK_OPAQUE2 = CONTENTS_SOLID2 | CONTENTS_SLIME2 | CONTENTS_LAVA2;
367
- var MASK_SHOT2 = CONTENTS_SOLID2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2 | CONTENTS_WINDOW2 | CONTENTS_DEADMONSTER2;
368
- var MASK_CURRENT2 = CONTENTS_CURRENT_02 | CONTENTS_CURRENT_902 | CONTENTS_CURRENT_1802 | CONTENTS_CURRENT_2702 | CONTENTS_CURRENT_UP2 | CONTENTS_CURRENT_DOWN2;
369
- var MASK_BLOCK_SIGHT2 = CONTENTS_SOLID2 | CONTENTS_LAVA2 | CONTENTS_SLIME2 | CONTENTS_MONSTER2 | CONTENTS_PLAYER2;
370
- var MASK_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2;
371
- var MASK_LADDER_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_WINDOW2;
372
- var MASK_WALK_NAV_SOLID2 = CONTENTS_SOLID2 | CONTENTS_PLAYERCLIP2 | CONTENTS_WINDOW2 | CONTENTS_MONSTERCLIP2;
373
- var MASK_PROJECTILE2 = MASK_SHOT2 | CONTENTS_PROJECTILECLIP2;
374
- var MAX_CLIENTS2 = 256;
375
- var MAX_LIGHTSTYLES2 = 256;
376
- var MAX_MODELS2 = 8192;
377
- var MAX_SOUNDS2 = 2048;
378
- var MAX_IMAGES2 = 512;
379
- var MAX_ITEMS2 = 256;
380
- var MAX_GENERAL2 = MAX_CLIENTS2 * 2;
381
- var MAX_SHADOW_LIGHTS2 = 256;
382
- var MAX_WHEEL_ITEMS2 = 32;
383
- var ConfigStringIndex2 = ((ConfigStringIndex22) => {
1266
+ var CONTENTS_SOLID3 = 1 << 0;
1267
+ var CONTENTS_WINDOW3 = 1 << 1;
1268
+ var CONTENTS_AUX3 = 1 << 2;
1269
+ var CONTENTS_LAVA3 = 1 << 3;
1270
+ var CONTENTS_SLIME3 = 1 << 4;
1271
+ var CONTENTS_WATER3 = 1 << 5;
1272
+ var CONTENTS_MIST3 = 1 << 6;
1273
+ var CONTENTS_NO_WATERJUMP3 = 1 << 13;
1274
+ var CONTENTS_PROJECTILECLIP3 = 1 << 14;
1275
+ var CONTENTS_AREAPORTAL3 = 1 << 15;
1276
+ var CONTENTS_PLAYERCLIP3 = 1 << 16;
1277
+ var CONTENTS_MONSTERCLIP3 = 1 << 17;
1278
+ var CONTENTS_CURRENT_03 = 1 << 18;
1279
+ var CONTENTS_CURRENT_903 = 1 << 19;
1280
+ var CONTENTS_CURRENT_1803 = 1 << 20;
1281
+ var CONTENTS_CURRENT_2703 = 1 << 21;
1282
+ var CONTENTS_CURRENT_UP3 = 1 << 22;
1283
+ var CONTENTS_CURRENT_DOWN3 = 1 << 23;
1284
+ var CONTENTS_ORIGIN3 = 1 << 24;
1285
+ var CONTENTS_MONSTER3 = 1 << 25;
1286
+ var CONTENTS_DEADMONSTER3 = 1 << 26;
1287
+ var CONTENTS_DETAIL3 = 1 << 27;
1288
+ var CONTENTS_TRANSLUCENT3 = 1 << 28;
1289
+ var CONTENTS_LADDER3 = 1 << 29;
1290
+ var CONTENTS_PLAYER3 = 1 << 30;
1291
+ var CONTENTS_PROJECTILE3 = 1 << 31;
1292
+ var SURF_LIGHT3 = 1 << 0;
1293
+ var SURF_SLICK3 = 1 << 1;
1294
+ var SURF_SKY3 = 1 << 2;
1295
+ var SURF_WARP3 = 1 << 3;
1296
+ var SURF_TRANS333 = 1 << 4;
1297
+ var SURF_TRANS663 = 1 << 5;
1298
+ var SURF_FLOWING3 = 1 << 6;
1299
+ var SURF_NODRAW3 = 1 << 7;
1300
+ var SURF_ALPHATEST3 = 1 << 25;
1301
+ var SURF_N64_UV3 = 1 << 28;
1302
+ var SURF_N64_SCROLL_X3 = 1 << 29;
1303
+ var SURF_N64_SCROLL_Y3 = 1 << 30;
1304
+ var SURF_N64_SCROLL_FLIP3 = 1 << 31;
1305
+ var MASK_SOLID3 = CONTENTS_SOLID3 | CONTENTS_WINDOW3;
1306
+ var MASK_PLAYERSOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
1307
+ var MASK_DEADSOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3;
1308
+ var MASK_MONSTERSOLID3 = CONTENTS_SOLID3 | CONTENTS_MONSTERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
1309
+ var MASK_WATER3 = CONTENTS_WATER3 | CONTENTS_LAVA3 | CONTENTS_SLIME3;
1310
+ var MASK_OPAQUE3 = CONTENTS_SOLID3 | CONTENTS_SLIME3 | CONTENTS_LAVA3;
1311
+ var MASK_SHOT3 = CONTENTS_SOLID3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3 | CONTENTS_WINDOW3 | CONTENTS_DEADMONSTER3;
1312
+ var MASK_CURRENT3 = CONTENTS_CURRENT_03 | CONTENTS_CURRENT_903 | CONTENTS_CURRENT_1803 | CONTENTS_CURRENT_2703 | CONTENTS_CURRENT_UP3 | CONTENTS_CURRENT_DOWN3;
1313
+ var MASK_BLOCK_SIGHT3 = CONTENTS_SOLID3 | CONTENTS_LAVA3 | CONTENTS_SLIME3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
1314
+ var MASK_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3;
1315
+ var MASK_LADDER_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_WINDOW3;
1316
+ var MASK_WALK_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTERCLIP3;
1317
+ var MASK_PROJECTILE3 = MASK_SHOT3 | CONTENTS_PROJECTILECLIP3;
1318
+ var MAX_CHECKCOUNT3 = Number.MAX_SAFE_INTEGER - 1;
1319
+ var MAX_CLIENTS3 = 256;
1320
+ var MAX_LIGHTSTYLES3 = 256;
1321
+ var MAX_MODELS3 = 8192;
1322
+ var MAX_SOUNDS3 = 2048;
1323
+ var MAX_IMAGES3 = 512;
1324
+ var MAX_ITEMS3 = 256;
1325
+ var MAX_GENERAL3 = MAX_CLIENTS3 * 2;
1326
+ var MAX_SHADOW_LIGHTS3 = 256;
1327
+ var MAX_WHEEL_ITEMS3 = 32;
1328
+ var ConfigStringIndex3 = ((ConfigStringIndex22) => {
384
1329
  ConfigStringIndex22[ConfigStringIndex22["Name"] = 0] = "Name";
385
1330
  ConfigStringIndex22[ConfigStringIndex22["CdTrack"] = 1] = "CdTrack";
386
1331
  ConfigStringIndex22[ConfigStringIndex22["Sky"] = 2] = "Sky";
@@ -391,27 +1336,28 @@ var ConfigStringIndex2 = ((ConfigStringIndex22) => {
391
1336
  ConfigStringIndex22[ConfigStringIndex22["MaxClients"] = 60] = "MaxClients";
392
1337
  ConfigStringIndex22[ConfigStringIndex22["MapChecksum"] = 61] = "MapChecksum";
393
1338
  ConfigStringIndex22[ConfigStringIndex22["Models"] = 62] = "Models";
394
- ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS2] = "Sounds";
395
- ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS2] = "Images";
396
- ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES2] = "Lights";
397
- ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES2] = "ShadowLights";
398
- ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS2] = "Items";
399
- ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS2] = "PlayerSkins";
400
- ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS2] = "General";
401
- ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL2] = "WheelWeapons";
402
- ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS2] = "WheelAmmo";
403
- ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS2] = "WheelPowerups";
404
- ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS2] = "CdLoopCount";
1339
+ ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS3] = "Sounds";
1340
+ ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS3] = "Images";
1341
+ ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES3] = "Lights";
1342
+ ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES3] = "ShadowLights";
1343
+ ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS3] = "Items";
1344
+ ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS3] = "PlayerSkins";
1345
+ ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS3] = "General";
1346
+ ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL3] = "WheelWeapons";
1347
+ ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS3] = "WheelAmmo";
1348
+ ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS3] = "WheelPowerups";
1349
+ ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS3] = "CdLoopCount";
405
1350
  ConfigStringIndex22[ConfigStringIndex22["GameStyle"] = ConfigStringIndex22.CdLoopCount + 1] = "GameStyle";
406
1351
  ConfigStringIndex22[ConfigStringIndex22["MaxConfigStrings"] = ConfigStringIndex22.GameStyle + 1] = "MaxConfigStrings";
407
1352
  return ConfigStringIndex22;
408
- })(ConfigStringIndex2 || {});
409
- var MAX_CONFIGSTRINGS2 = ConfigStringIndex2.MaxConfigStrings;
410
- var WATERJUMP_CLEAR2 = 8 | 16 | 32 | 1024;
411
- var ZERO = { ...ZERO_VEC3 };
1353
+ })(ConfigStringIndex3 || {});
1354
+ var MAX_CONFIGSTRINGS3 = ConfigStringIndex3.MaxConfigStrings;
1355
+ var WATERJUMP_CLEAR3 = 8 | 16 | 32 | 1024;
1356
+ var ZERO = { ...ZERO_VEC33 };
412
1357
  function copyVec3() {
413
1358
  return { ...ZERO };
414
1359
  }
1360
+ var DEFAULT_MONSTER_INFO = Object.freeze({ aiflags: 0 });
415
1361
  var Entity = class {
416
1362
  constructor(index) {
417
1363
  this.inUse = false;
@@ -420,17 +1366,20 @@ var Entity = class {
420
1366
  this.linkNext = null;
421
1367
  this.classname = "";
422
1368
  this.spawnflags = 0;
1369
+ this.inventory = {};
423
1370
  this.origin = copyVec3();
424
1371
  this.old_origin = copyVec3();
425
1372
  this.velocity = copyVec3();
426
1373
  this.avelocity = copyVec3();
427
1374
  this.angles = copyVec3();
1375
+ this.viewheight = 0;
428
1376
  this.mins = copyVec3();
429
1377
  this.maxs = copyVec3();
430
1378
  this.size = copyVec3();
431
1379
  this.mass = 0;
432
1380
  this.gravity = 1;
433
1381
  this.movetype = 0;
1382
+ this.movedir = copyVec3();
434
1383
  this.modelindex = 0;
435
1384
  this.frame = 0;
436
1385
  this.skin = 0;
@@ -440,20 +1389,35 @@ var Entity = class {
440
1389
  this.max_health = 0;
441
1390
  this.takedamage = false;
442
1391
  this.dmg = 0;
1392
+ this.speed = 0;
443
1393
  this.deadflag = 0;
1394
+ this.count = 0;
1395
+ this.wait = 0;
1396
+ this.delay = 0;
1397
+ this.timestamp = 0;
1398
+ this.sounds = 0;
1399
+ this.noise_index = 0;
1400
+ this.fly_sound_debounce_time = 0;
444
1401
  this.enemy = null;
445
1402
  this.movetarget = null;
1403
+ this.target_ent = null;
446
1404
  this.goalentity = null;
447
1405
  this.ideal_yaw = 0;
448
1406
  this.yaw_speed = 0;
1407
+ this.search_time = 0;
1408
+ this.attack_finished_time = 0;
1409
+ this.pain_finished_time = 0;
1410
+ this.trail_time = 0;
449
1411
  this.groundentity = null;
450
1412
  this.groundentity_linkcount = 0;
451
1413
  this.waterlevel = 0;
452
1414
  this.watertype = 0;
453
1415
  this.nextthink = 0;
1416
+ this.activator = null;
454
1417
  this.solid = 0;
455
1418
  this.flags = 0;
456
1419
  this.svflags = 0;
1420
+ this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
457
1421
  this.index = index;
458
1422
  }
459
1423
  reset() {
@@ -465,19 +1429,26 @@ var Entity = class {
465
1429
  this.spawnflags = 0;
466
1430
  this.target = void 0;
467
1431
  this.targetname = void 0;
1432
+ this.killtarget = void 0;
468
1433
  this.team = void 0;
469
1434
  this.message = void 0;
1435
+ this.pathtarget = void 0;
1436
+ this.model = void 0;
1437
+ this.item = void 0;
1438
+ this.inventory = {};
470
1439
  this.origin = copyVec3();
471
1440
  this.old_origin = copyVec3();
472
1441
  this.velocity = copyVec3();
473
1442
  this.avelocity = copyVec3();
474
1443
  this.angles = copyVec3();
1444
+ this.viewheight = 0;
475
1445
  this.mins = copyVec3();
476
1446
  this.maxs = copyVec3();
477
1447
  this.size = copyVec3();
478
1448
  this.mass = 0;
479
1449
  this.gravity = 1;
480
1450
  this.movetype = 0;
1451
+ this.movedir = copyVec3();
481
1452
  this.modelindex = 0;
482
1453
  this.frame = 0;
483
1454
  this.skin = 0;
@@ -487,12 +1458,25 @@ var Entity = class {
487
1458
  this.max_health = 0;
488
1459
  this.takedamage = false;
489
1460
  this.dmg = 0;
1461
+ this.speed = 0;
490
1462
  this.deadflag = 0;
1463
+ this.count = 0;
1464
+ this.wait = 0;
1465
+ this.delay = 0;
1466
+ this.timestamp = 0;
1467
+ this.sounds = 0;
1468
+ this.noise_index = 0;
1469
+ this.fly_sound_debounce_time = 0;
491
1470
  this.enemy = null;
492
1471
  this.movetarget = null;
1472
+ this.target_ent = null;
493
1473
  this.goalentity = null;
494
1474
  this.ideal_yaw = 0;
495
1475
  this.yaw_speed = 0;
1476
+ this.search_time = 0;
1477
+ this.attack_finished_time = 0;
1478
+ this.pain_finished_time = 0;
1479
+ this.trail_time = 0;
496
1480
  this.groundentity = null;
497
1481
  this.groundentity_linkcount = 0;
498
1482
  this.waterlevel = 0;
@@ -503,11 +1487,80 @@ var Entity = class {
503
1487
  this.use = void 0;
504
1488
  this.pain = void 0;
505
1489
  this.die = void 0;
1490
+ this.activator = null;
506
1491
  this.solid = 0;
507
1492
  this.flags = 0;
508
1493
  this.svflags = 0;
1494
+ this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
509
1495
  }
510
1496
  };
1497
+ var ENTITY_FIELD_METADATA = [
1498
+ { name: "classname", type: "string", save: true },
1499
+ { name: "spawnflags", type: "int", save: true },
1500
+ { name: "target", type: "string", save: true },
1501
+ { name: "targetname", type: "string", save: true },
1502
+ { name: "killtarget", type: "string", save: true },
1503
+ { name: "team", type: "string", save: true },
1504
+ { name: "message", type: "string", save: true },
1505
+ { name: "pathtarget", type: "string", save: true },
1506
+ { name: "model", type: "string", save: true },
1507
+ { name: "item", type: "string", save: true },
1508
+ { name: "inventory", type: "inventory", save: true },
1509
+ { name: "origin", type: "vec3", save: true },
1510
+ { name: "old_origin", type: "vec3", save: true },
1511
+ { name: "velocity", type: "vec3", save: true },
1512
+ { name: "avelocity", type: "vec3", save: true },
1513
+ { name: "angles", type: "vec3", save: true },
1514
+ { name: "viewheight", type: "int", save: true },
1515
+ { name: "mins", type: "vec3", save: true },
1516
+ { name: "maxs", type: "vec3", save: true },
1517
+ { name: "size", type: "vec3", save: true },
1518
+ { name: "mass", type: "int", save: true },
1519
+ { name: "gravity", type: "float", save: true },
1520
+ { name: "movetype", type: "int", save: true },
1521
+ { name: "movedir", type: "vec3", save: true },
1522
+ { name: "modelindex", type: "int", save: true },
1523
+ { name: "frame", type: "int", save: true },
1524
+ { name: "skin", type: "int", save: true },
1525
+ { name: "effects", type: "int", save: true },
1526
+ { name: "renderfx", type: "int", save: true },
1527
+ { name: "health", type: "int", save: true },
1528
+ { name: "max_health", type: "int", save: true },
1529
+ { name: "takedamage", type: "boolean", save: true },
1530
+ { name: "dmg", type: "int", save: true },
1531
+ { name: "speed", type: "float", save: true },
1532
+ { name: "deadflag", type: "int", save: true },
1533
+ { name: "count", type: "int", save: true },
1534
+ { name: "wait", type: "float", save: true },
1535
+ { name: "delay", type: "float", save: true },
1536
+ { name: "timestamp", type: "float", save: true },
1537
+ { name: "sounds", type: "int", save: true },
1538
+ { name: "noise_index", type: "int", save: true },
1539
+ { name: "fly_sound_debounce_time", type: "float", save: true },
1540
+ { name: "enemy", type: "entity", save: true },
1541
+ { name: "movetarget", type: "entity", save: true },
1542
+ { name: "target_ent", type: "entity", save: true },
1543
+ { name: "goalentity", type: "entity", save: true },
1544
+ { name: "ideal_yaw", type: "float", save: true },
1545
+ { name: "yaw_speed", type: "float", save: true },
1546
+ { name: "search_time", type: "float", save: true },
1547
+ { name: "attack_finished_time", type: "float", save: true },
1548
+ { name: "pain_finished_time", type: "float", save: true },
1549
+ { name: "trail_time", type: "float", save: true },
1550
+ { name: "groundentity", type: "entity", save: true },
1551
+ { name: "groundentity_linkcount", type: "int", save: true },
1552
+ { name: "waterlevel", type: "int", save: true },
1553
+ { name: "watertype", type: "int", save: true },
1554
+ { name: "nextthink", type: "float", save: true },
1555
+ { name: "solid", type: "int", save: true },
1556
+ { name: "flags", type: "int", save: true },
1557
+ { name: "svflags", type: "int", save: true },
1558
+ { name: "think", type: "callback", save: false },
1559
+ { name: "touch", type: "callback", save: false },
1560
+ { name: "use", type: "callback", save: false },
1561
+ { name: "pain", type: "callback", save: false },
1562
+ { name: "die", type: "callback", save: false }
1563
+ ];
511
1564
  var MAX_EDICTS = 2048;
512
1565
  var WORLD_INDEX = 0;
513
1566
  var EntityPool = class {
@@ -579,6 +1632,17 @@ var EntityPool = class {
579
1632
  entity.freePending = true;
580
1633
  this.pendingFree.push(entity.index);
581
1634
  }
1635
+ freeImmediate(entity) {
1636
+ if (entity.index === WORLD_INDEX) {
1637
+ throw new Error("Cannot free world entity");
1638
+ }
1639
+ if (!entity.inUse) {
1640
+ return;
1641
+ }
1642
+ this.unlink(entity);
1643
+ entity.reset();
1644
+ this.freeList.push(entity.index);
1645
+ }
582
1646
  flushFreeList() {
583
1647
  if (this.pendingFree.length === 0) {
584
1648
  return;
@@ -590,6 +1654,69 @@ var EntityPool = class {
590
1654
  }
591
1655
  this.pendingFree.length = 0;
592
1656
  }
1657
+ createSnapshot() {
1658
+ const activeOrder = Array.from(this, (entity) => entity.index);
1659
+ return {
1660
+ capacity: this.entities.length,
1661
+ activeOrder,
1662
+ freeList: [...this.freeList],
1663
+ pendingFree: [...this.pendingFree]
1664
+ };
1665
+ }
1666
+ restore(snapshot) {
1667
+ if (snapshot.capacity !== this.entities.length) {
1668
+ throw new Error(`Snapshot capacity ${snapshot.capacity} does not match pool capacity ${this.entities.length}`);
1669
+ }
1670
+ const seen = /* @__PURE__ */ new Set();
1671
+ const noteIndex = (index, label) => {
1672
+ if (index < 0 || index >= this.entities.length) {
1673
+ throw new Error(`Invalid entity index ${index} in ${label}`);
1674
+ }
1675
+ if (seen.has(index)) {
1676
+ throw new Error(`Duplicate entity index ${index} in snapshot`);
1677
+ }
1678
+ seen.add(index);
1679
+ };
1680
+ for (const index of snapshot.activeOrder) {
1681
+ noteIndex(index, "activeOrder");
1682
+ }
1683
+ for (const index of snapshot.freeList) {
1684
+ noteIndex(index, "freeList");
1685
+ }
1686
+ for (const index of snapshot.pendingFree) {
1687
+ noteIndex(index, "pendingFree");
1688
+ }
1689
+ this.activeHead = null;
1690
+ this.freeList.length = 0;
1691
+ this.pendingFree.length = 0;
1692
+ for (const entity of this.entities) {
1693
+ entity.reset();
1694
+ }
1695
+ for (let i = snapshot.activeOrder.length - 1; i >= 0; i -= 1) {
1696
+ const entity = this.entities[snapshot.activeOrder[i]];
1697
+ entity.inUse = true;
1698
+ this.link(entity);
1699
+ }
1700
+ for (const index of snapshot.pendingFree) {
1701
+ const entity = this.entities[index];
1702
+ entity.inUse = false;
1703
+ entity.freePending = true;
1704
+ entity.linkNext = null;
1705
+ entity.linkPrevious = null;
1706
+ this.pendingFree.push(index);
1707
+ }
1708
+ for (const index of snapshot.freeList) {
1709
+ const entity = this.entities[index];
1710
+ entity.inUse = false;
1711
+ entity.freePending = false;
1712
+ entity.linkNext = null;
1713
+ entity.linkPrevious = null;
1714
+ this.freeList.push(index);
1715
+ }
1716
+ if (!snapshot.activeOrder.includes(WORLD_INDEX)) {
1717
+ throw new Error("Snapshot must include the world entity as active");
1718
+ }
1719
+ }
593
1720
  link(entity) {
594
1721
  entity.linkNext = this.activeHead;
595
1722
  if (this.activeHead) {
@@ -631,6 +1758,19 @@ var ThinkScheduler = class {
631
1758
  }
632
1759
  }
633
1760
  }
1761
+ snapshot() {
1762
+ return this.queue.map(({ time, entity }) => ({ time, entityIndex: entity.index }));
1763
+ }
1764
+ restore(entries, resolver) {
1765
+ this.queue.length = 0;
1766
+ for (const entry of entries) {
1767
+ const entity = resolver(entry.entityIndex);
1768
+ if (!entity) {
1769
+ continue;
1770
+ }
1771
+ this.schedule(entity, entry.time);
1772
+ }
1773
+ }
634
1774
  runDueThinks(currentTimeSeconds) {
635
1775
  while (this.queue.length > 0) {
636
1776
  const next = this.queue[0];
@@ -669,8 +1809,41 @@ function computeBounds(entity) {
669
1809
  function boundsIntersect(a, b) {
670
1810
  return !(a.min.x > b.max.x || a.max.x < b.min.x || a.min.y > b.max.y || a.max.y < b.min.y || a.min.z > b.max.z || a.max.z < b.min.z);
671
1811
  }
1812
+ var SERIALIZABLE_FIELDS = ENTITY_FIELD_METADATA.filter(
1813
+ (field) => field.save
1814
+ );
1815
+ var DESCRIPTORS = new Map(SERIALIZABLE_FIELDS.map((descriptor) => [descriptor.name, descriptor]));
1816
+ function serializeVec3(vec) {
1817
+ return [vec.x, vec.y, vec.z];
1818
+ }
1819
+ function deserializeVec3(value) {
1820
+ const vec = value;
1821
+ if (!Array.isArray(vec) || vec.length !== 3) {
1822
+ throw new Error("Invalid vec3 serialization");
1823
+ }
1824
+ const [x, y, z] = vec;
1825
+ return { x, y, z };
1826
+ }
1827
+ function assignField(entity, name, value) {
1828
+ entity[name] = value;
1829
+ }
1830
+ function serializeInventory(inventory) {
1831
+ return { ...inventory };
1832
+ }
1833
+ function deserializeInventory(value) {
1834
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
1835
+ throw new Error("Invalid inventory serialization");
1836
+ }
1837
+ const parsed = {};
1838
+ for (const [key, entry] of Object.entries(value)) {
1839
+ parsed[key] = Number(entry);
1840
+ }
1841
+ return parsed;
1842
+ }
672
1843
  var EntitySystem = class {
673
1844
  constructor(maxEntities) {
1845
+ this.targetNameIndex = /* @__PURE__ */ new Map();
1846
+ this.random = createRandomGenerator();
674
1847
  this.currentTimeSeconds = 0;
675
1848
  this.pool = new EntityPool(maxEntities);
676
1849
  this.thinkScheduler = new ThinkScheduler();
@@ -689,24 +1862,179 @@ var EntitySystem = class {
689
1862
  callback(entity);
690
1863
  }
691
1864
  }
692
- spawn() {
693
- return this.pool.spawn();
1865
+ spawn() {
1866
+ return this.pool.spawn();
1867
+ }
1868
+ free(entity) {
1869
+ this.unregisterTarget(entity);
1870
+ this.thinkScheduler.cancel(entity);
1871
+ this.pool.deferFree(entity);
1872
+ }
1873
+ freeImmediate(entity) {
1874
+ this.unregisterTarget(entity);
1875
+ this.thinkScheduler.cancel(entity);
1876
+ this.pool.freeImmediate(entity);
1877
+ }
1878
+ scheduleThink(entity, nextThinkSeconds) {
1879
+ this.thinkScheduler.schedule(entity, nextThinkSeconds);
1880
+ }
1881
+ beginFrame(timeSeconds) {
1882
+ this.currentTimeSeconds = timeSeconds;
1883
+ }
1884
+ finalizeSpawn(entity) {
1885
+ if (!entity.inUse || entity.freePending) {
1886
+ return;
1887
+ }
1888
+ this.registerTarget(entity);
1889
+ }
1890
+ findByClassname(classname) {
1891
+ const matches = [];
1892
+ for (const entity of this.pool) {
1893
+ if (entity.classname === classname && entity.inUse && !entity.freePending) {
1894
+ matches.push(entity);
1895
+ }
1896
+ }
1897
+ return matches;
1898
+ }
1899
+ findByTargetName(targetname) {
1900
+ const matches = this.targetNameIndex.get(targetname);
1901
+ if (!matches) {
1902
+ return [];
1903
+ }
1904
+ return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
694
1905
  }
695
- free(entity) {
696
- this.thinkScheduler.cancel(entity);
697
- this.pool.deferFree(entity);
1906
+ pickTarget(targetname) {
1907
+ if (!targetname) {
1908
+ return null;
1909
+ }
1910
+ const matches = this.findByTargetName(targetname);
1911
+ if (matches.length === 0) {
1912
+ return null;
1913
+ }
1914
+ const choice = this.random.randomIndex(matches);
1915
+ return matches[choice] ?? null;
698
1916
  }
699
- scheduleThink(entity, nextThinkSeconds) {
700
- this.thinkScheduler.schedule(entity, nextThinkSeconds);
1917
+ killBox(entity) {
1918
+ const targetBounds = computeBounds(entity);
1919
+ for (const other of this.pool) {
1920
+ if (other === entity || other === this.pool.world) {
1921
+ continue;
1922
+ }
1923
+ if (!other.inUse || other.freePending || other.solid === 0) {
1924
+ continue;
1925
+ }
1926
+ if (other.svflags & 2) {
1927
+ continue;
1928
+ }
1929
+ if (!boundsIntersect(targetBounds, computeBounds(other))) {
1930
+ continue;
1931
+ }
1932
+ other.health = 0;
1933
+ other.deadflag = 2;
1934
+ this.free(other);
1935
+ }
701
1936
  }
702
- beginFrame(timeSeconds) {
703
- this.currentTimeSeconds = timeSeconds;
1937
+ useTargets(entity, activator = null) {
1938
+ if (entity.delay > 0) {
1939
+ const delayed = this.spawn();
1940
+ delayed.classname = "DelayedUse";
1941
+ delayed.target = entity.target;
1942
+ delayed.killtarget = entity.killtarget;
1943
+ delayed.message = entity.message;
1944
+ delayed.think = (self) => {
1945
+ this.useTargetsImmediate(self, activator ?? entity);
1946
+ this.free(self);
1947
+ };
1948
+ this.scheduleThink(delayed, this.currentTimeSeconds + entity.delay);
1949
+ return;
1950
+ }
1951
+ this.useTargetsImmediate(entity, activator ?? entity);
704
1952
  }
705
1953
  runFrame() {
706
1954
  this.thinkScheduler.runDueThinks(this.currentTimeSeconds);
707
1955
  this.runTouches();
708
1956
  this.pool.flushFreeList();
709
1957
  }
1958
+ createSnapshot() {
1959
+ const entities = [];
1960
+ for (const entity of this.pool) {
1961
+ const fields = {};
1962
+ for (const descriptor of SERIALIZABLE_FIELDS) {
1963
+ const value = entity[descriptor.name];
1964
+ switch (descriptor.type) {
1965
+ case "vec3":
1966
+ fields[descriptor.name] = serializeVec3(value);
1967
+ break;
1968
+ case "entity":
1969
+ fields[descriptor.name] = value?.index ?? null;
1970
+ break;
1971
+ case "inventory":
1972
+ fields[descriptor.name] = serializeInventory(value);
1973
+ break;
1974
+ default:
1975
+ fields[descriptor.name] = value ?? null;
1976
+ break;
1977
+ }
1978
+ }
1979
+ entities.push({
1980
+ index: entity.index,
1981
+ fields
1982
+ });
1983
+ }
1984
+ return {
1985
+ timeSeconds: this.currentTimeSeconds,
1986
+ pool: this.pool.createSnapshot(),
1987
+ entities,
1988
+ thinks: this.thinkScheduler.snapshot()
1989
+ };
1990
+ }
1991
+ restore(snapshot) {
1992
+ this.currentTimeSeconds = snapshot.timeSeconds;
1993
+ this.pool.restore(snapshot.pool);
1994
+ const indexToEntity = /* @__PURE__ */ new Map();
1995
+ for (const entity of this.pool) {
1996
+ indexToEntity.set(entity.index, entity);
1997
+ }
1998
+ const pendingEntityRefs = [];
1999
+ for (const serialized of snapshot.entities) {
2000
+ const entity = indexToEntity.get(serialized.index);
2001
+ if (!entity) {
2002
+ continue;
2003
+ }
2004
+ for (const [name, value] of Object.entries(serialized.fields)) {
2005
+ const descriptor = DESCRIPTORS.get(name);
2006
+ if (!descriptor || value === void 0) {
2007
+ continue;
2008
+ }
2009
+ switch (descriptor.type) {
2010
+ case "vec3":
2011
+ assignField(entity, name, deserializeVec3(value));
2012
+ break;
2013
+ case "entity":
2014
+ pendingEntityRefs.push({
2015
+ entity,
2016
+ name: descriptor.name,
2017
+ targetIndex: value
2018
+ });
2019
+ break;
2020
+ case "inventory":
2021
+ assignField(entity, name, deserializeInventory(value));
2022
+ break;
2023
+ case "boolean":
2024
+ assignField(entity, name, Boolean(value));
2025
+ break;
2026
+ default:
2027
+ assignField(entity, name, value);
2028
+ break;
2029
+ }
2030
+ }
2031
+ }
2032
+ for (const ref of pendingEntityRefs) {
2033
+ const target = ref.targetIndex === null ? null : indexToEntity.get(ref.targetIndex) ?? null;
2034
+ assignField(ref.entity, ref.name, target);
2035
+ }
2036
+ this.thinkScheduler.restore(snapshot.thinks, (index) => indexToEntity.get(index));
2037
+ }
710
2038
  runTouches() {
711
2039
  const world = this.pool.world;
712
2040
  const activeEntities = [];
@@ -714,7 +2042,7 @@ var EntitySystem = class {
714
2042
  if (entity === world) {
715
2043
  continue;
716
2044
  }
717
- if (!entity.inUse || entity.freePending) {
2045
+ if (!entity.inUse || entity.freePending || entity.solid === 0) {
718
2046
  continue;
719
2047
  }
720
2048
  activeEntities.push(entity);
@@ -743,7 +2071,97 @@ var EntitySystem = class {
743
2071
  }
744
2072
  }
745
2073
  }
2074
+ registerTarget(entity) {
2075
+ if (!entity.targetname) {
2076
+ return;
2077
+ }
2078
+ let bucket = this.targetNameIndex.get(entity.targetname);
2079
+ if (!bucket) {
2080
+ bucket = /* @__PURE__ */ new Set();
2081
+ this.targetNameIndex.set(entity.targetname, bucket);
2082
+ }
2083
+ bucket.add(entity);
2084
+ }
2085
+ unregisterTarget(entity) {
2086
+ if (!entity.targetname) {
2087
+ return;
2088
+ }
2089
+ const bucket = this.targetNameIndex.get(entity.targetname);
2090
+ if (!bucket) {
2091
+ return;
2092
+ }
2093
+ bucket.delete(entity);
2094
+ if (bucket.size === 0) {
2095
+ this.targetNameIndex.delete(entity.targetname);
2096
+ }
2097
+ }
2098
+ useTargetsImmediate(entity, activator) {
2099
+ if (entity.target) {
2100
+ for (const target of this.findByTargetName(entity.target)) {
2101
+ if (target === entity) {
2102
+ continue;
2103
+ }
2104
+ target.use?.(target, entity, activator);
2105
+ }
2106
+ }
2107
+ if (entity.killtarget) {
2108
+ for (const victim of this.findByTargetName(entity.killtarget)) {
2109
+ if (victim === entity) {
2110
+ continue;
2111
+ }
2112
+ this.free(victim);
2113
+ }
2114
+ }
2115
+ }
2116
+ };
2117
+ var FRAME_TIME_SECONDS = 1 / 40;
2118
+ var TRIGGER_SPAWNFLAGS = {
2119
+ Monster: 1 << 0,
2120
+ NotPlayer: 1 << 1,
2121
+ Triggered: 1 << 2,
2122
+ Toggle: 1 << 3,
2123
+ Latched: 1 << 4,
2124
+ Clip: 1 << 5
746
2125
  };
2126
+ var RELAY_SPAWNFLAGS = {
2127
+ NoSound: 1 << 0
2128
+ };
2129
+ var COUNTER_SPAWNFLAGS = {
2130
+ NoMessage: 1 << 0
2131
+ };
2132
+ var PUSH_SPAWNFLAGS = {
2133
+ Once: 1 << 0,
2134
+ Plus: 1 << 1,
2135
+ Silent: 1 << 2,
2136
+ StartOff: 1 << 3,
2137
+ Clip: 1 << 4
2138
+ };
2139
+ var HURT_SPAWNFLAGS = {
2140
+ StartOff: 1 << 0,
2141
+ Toggle: 1 << 1,
2142
+ Silent: 1 << 2,
2143
+ NoProtection: 1 << 3,
2144
+ Slow: 1 << 4,
2145
+ NoPlayers: 1 << 5,
2146
+ NoMonsters: 1 << 6,
2147
+ Clip: 1 << 7
2148
+ };
2149
+ var TELEPORT_SPAWNFLAGS = {
2150
+ StartOn: 1 << 3
2151
+ };
2152
+ var GRAVITY_SPAWNFLAGS = {
2153
+ Toggle: 1 << 0,
2154
+ StartOff: 1 << 1,
2155
+ Clip: 1 << 2
2156
+ };
2157
+ var MONSTERJUMP_SPAWNFLAGS = {
2158
+ Toggle: 1 << 0,
2159
+ StartOff: 1 << 1,
2160
+ Clip: 1 << 2
2161
+ };
2162
+ var FIELD_LOOKUP = new Map(
2163
+ ENTITY_FIELD_METADATA.map((field) => [field.name, field])
2164
+ );
747
2165
  var orderedStageNames = [
748
2166
  "prep",
749
2167
  "simulate",
@@ -876,8 +2294,391 @@ var LevelClock = class {
876
2294
  get current() {
877
2295
  return this.state;
878
2296
  }
2297
+ restore(state) {
2298
+ this.state = { ...state };
2299
+ }
879
2300
  };
880
- var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
2301
+ var FL_NOVISIBLE = 1 << 24;
2302
+ var SPAWNFLAG_MONSTER_AMBUSH = 1 << 0;
2303
+ var SAVE_FORMAT_VERSION = 1;
2304
+ var MIN_SUPPORTED_VERSION = 1;
2305
+ function ensureObject(value, label) {
2306
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2307
+ throw new Error(`${label} must be an object`);
2308
+ }
2309
+ return value;
2310
+ }
2311
+ function ensureNumber(value, label) {
2312
+ if (typeof value !== "number" || !Number.isFinite(value)) {
2313
+ throw new Error(`${label} must be a finite number`);
2314
+ }
2315
+ return value;
2316
+ }
2317
+ function ensureNumberOrDefault(value, label, defaultValue) {
2318
+ if (value === void 0) {
2319
+ return defaultValue;
2320
+ }
2321
+ return ensureNumber(value, label);
2322
+ }
2323
+ function ensureString(value, label) {
2324
+ if (typeof value !== "string") {
2325
+ throw new Error(`${label} must be a string`);
2326
+ }
2327
+ return value;
2328
+ }
2329
+ function ensureNumberArray(value, label) {
2330
+ if (!Array.isArray(value)) {
2331
+ throw new Error(`${label} must be an array`);
2332
+ }
2333
+ for (const element of value) {
2334
+ ensureNumber(element, `${label} element`);
2335
+ }
2336
+ return value;
2337
+ }
2338
+ function parseLevelState(raw) {
2339
+ if (raw === void 0) {
2340
+ return { frameNumber: 0, timeSeconds: 0, previousTimeSeconds: 0, deltaSeconds: 0 };
2341
+ }
2342
+ const level = ensureObject(raw, "level");
2343
+ return {
2344
+ frameNumber: ensureNumberOrDefault(level.frameNumber, "level.frameNumber", 0),
2345
+ timeSeconds: ensureNumberOrDefault(level.timeSeconds, "level.timeSeconds", 0),
2346
+ previousTimeSeconds: ensureNumberOrDefault(level.previousTimeSeconds, "level.previousTimeSeconds", 0),
2347
+ deltaSeconds: ensureNumberOrDefault(level.deltaSeconds, "level.deltaSeconds", 0)
2348
+ };
2349
+ }
2350
+ function parseRngState(raw) {
2351
+ if (raw === void 0) {
2352
+ return new RandomGenerator().getState();
2353
+ }
2354
+ const rng = ensureObject(raw, "rng");
2355
+ const mt = ensureObject(rng.mt, "rng.mt");
2356
+ const state = ensureNumberArray(mt.state, "rng.mt.state");
2357
+ return {
2358
+ mt: {
2359
+ index: ensureNumber(mt.index, "rng.mt.index"),
2360
+ state
2361
+ }
2362
+ };
2363
+ }
2364
+ function parseThinkEntries(raw) {
2365
+ if (raw === void 0) {
2366
+ return [];
2367
+ }
2368
+ if (!Array.isArray(raw)) {
2369
+ throw new Error("thinks must be an array");
2370
+ }
2371
+ return raw.map((entry, idx) => {
2372
+ const think = ensureObject(entry, `thinks[${idx}]`);
2373
+ return {
2374
+ time: ensureNumber(think.time, `thinks[${idx}].time`),
2375
+ entityIndex: ensureNumber(think.entityIndex, `thinks[${idx}].entityIndex`)
2376
+ };
2377
+ });
2378
+ }
2379
+ function parseEntityFields(raw) {
2380
+ if (raw === void 0) {
2381
+ return {};
2382
+ }
2383
+ const fields = ensureObject(raw, "entity.fields");
2384
+ const parsed = {};
2385
+ for (const [name, value] of Object.entries(fields)) {
2386
+ if (value === null) {
2387
+ parsed[name] = null;
2388
+ continue;
2389
+ }
2390
+ switch (typeof value) {
2391
+ case "number":
2392
+ case "string":
2393
+ case "boolean":
2394
+ parsed[name] = value;
2395
+ break;
2396
+ default: {
2397
+ if (!Array.isArray(value)) {
2398
+ const object = ensureObject(value, name);
2399
+ const inventory = {};
2400
+ for (const [entryName, entryValue] of Object.entries(object)) {
2401
+ inventory[entryName] = ensureNumber(entryValue, `${name}.${entryName}`);
2402
+ }
2403
+ parsed[name] = inventory;
2404
+ break;
2405
+ }
2406
+ if (Array.isArray(value) && value.length === 3) {
2407
+ const [x, y, z] = value;
2408
+ parsed[name] = [
2409
+ ensureNumber(x, `${name}[0]`),
2410
+ ensureNumber(y, `${name}[1]`),
2411
+ ensureNumber(z, `${name}[2]`)
2412
+ ];
2413
+ break;
2414
+ }
2415
+ throw new Error(`Unsupported entity field value for ${name}`);
2416
+ }
2417
+ }
2418
+ }
2419
+ return parsed;
2420
+ }
2421
+ function parseEntities(raw) {
2422
+ if (!Array.isArray(raw)) {
2423
+ throw new Error("entities must be an array");
2424
+ }
2425
+ return raw.map((entry, idx) => {
2426
+ const entity = ensureObject(entry, `entities[${idx}]`);
2427
+ return {
2428
+ index: ensureNumber(entity.index, `entities[${idx}].index`),
2429
+ fields: parseEntityFields(entity.fields)
2430
+ };
2431
+ });
2432
+ }
2433
+ function parsePool(raw) {
2434
+ const pool = ensureObject(raw, "pool");
2435
+ return {
2436
+ capacity: ensureNumber(pool.capacity, "pool.capacity"),
2437
+ activeOrder: ensureNumberArray(pool.activeOrder, "pool.activeOrder"),
2438
+ freeList: ensureNumberArray(pool.freeList, "pool.freeList"),
2439
+ pendingFree: ensureNumberArray(pool.pendingFree, "pool.pendingFree")
2440
+ };
2441
+ }
2442
+ function parseEntitySnapshot(raw) {
2443
+ const snapshot = ensureObject(raw, "entities");
2444
+ return {
2445
+ timeSeconds: ensureNumber(snapshot.timeSeconds, "entities.timeSeconds"),
2446
+ pool: parsePool(snapshot.pool),
2447
+ entities: parseEntities(snapshot.entities),
2448
+ thinks: parseThinkEntries(snapshot.thinks)
2449
+ };
2450
+ }
2451
+ function parseCvars(raw) {
2452
+ if (raw === void 0) {
2453
+ return [];
2454
+ }
2455
+ if (!Array.isArray(raw)) {
2456
+ throw new Error("cvars must be an array");
2457
+ }
2458
+ return raw.map((entry, idx) => {
2459
+ const cvar = ensureObject(entry, `cvars[${idx}]`);
2460
+ return {
2461
+ name: ensureString(cvar.name, `cvars[${idx}].name`),
2462
+ value: ensureString(cvar.value, `cvars[${idx}].value`),
2463
+ flags: ensureNumber(cvar.flags, `cvars[${idx}].flags`)
2464
+ };
2465
+ });
2466
+ }
2467
+ function parseConfigstrings(raw) {
2468
+ if (raw === void 0) {
2469
+ return [];
2470
+ }
2471
+ if (!Array.isArray(raw)) {
2472
+ throw new Error("configstrings must be an array");
2473
+ }
2474
+ return raw.map((value, idx) => ensureString(value, `configstrings[${idx}]`));
2475
+ }
2476
+ function parseGameState(raw) {
2477
+ if (raw === void 0) {
2478
+ return {};
2479
+ }
2480
+ return ensureObject(raw, "gameState");
2481
+ }
2482
+ function parseSaveFile(serialized, options = {}) {
2483
+ const { allowNewerVersion = true } = options;
2484
+ const raw = typeof serialized === "string" ? JSON.parse(serialized) : serialized;
2485
+ const save = ensureObject(raw, "save");
2486
+ const versionValue = save.version ?? SAVE_FORMAT_VERSION;
2487
+ const version = ensureNumber(versionValue, "version");
2488
+ if (version < MIN_SUPPORTED_VERSION) {
2489
+ throw new Error(`Unsupported save version ${version}`);
2490
+ }
2491
+ if (version > SAVE_FORMAT_VERSION && !allowNewerVersion) {
2492
+ throw new Error(`Save version ${version} is newer than supported ${SAVE_FORMAT_VERSION}`);
2493
+ }
2494
+ return {
2495
+ version,
2496
+ timestamp: ensureNumber(save.timestamp, "timestamp"),
2497
+ map: ensureString(save.map, "map"),
2498
+ difficulty: ensureNumber(save.difficulty, "difficulty"),
2499
+ playtimeSeconds: ensureNumber(save.playtimeSeconds, "playtimeSeconds"),
2500
+ gameState: parseGameState(save.gameState),
2501
+ level: parseLevelState(save.level),
2502
+ rng: parseRngState(save.rng),
2503
+ entities: parseEntitySnapshot(save.entities),
2504
+ cvars: parseCvars(save.cvars),
2505
+ configstrings: parseConfigstrings(save.configstrings)
2506
+ };
2507
+ }
2508
+ var TEXT_ENCODER_CTOR = globalThis.TextEncoder;
2509
+ function cloneSave(save) {
2510
+ return parseSaveFile({ ...save }, { allowNewerVersion: true });
2511
+ }
2512
+ function estimateSizeBytes(save) {
2513
+ if (TEXT_ENCODER_CTOR) {
2514
+ const encoder = new TEXT_ENCODER_CTOR();
2515
+ return encoder.encode(JSON.stringify(save)).length;
2516
+ }
2517
+ return JSON.stringify(save).length;
2518
+ }
2519
+ var MemorySaveAdapter = class {
2520
+ constructor() {
2521
+ this.records = /* @__PURE__ */ new Map();
2522
+ }
2523
+ async init() {
2524
+ return Promise.resolve();
2525
+ }
2526
+ async put(record) {
2527
+ const copy = {
2528
+ id: record.id,
2529
+ metadata: { ...record.metadata },
2530
+ save: cloneSave(record.save)
2531
+ };
2532
+ this.records.set(record.id, copy);
2533
+ }
2534
+ async get(id) {
2535
+ const record = this.records.get(id);
2536
+ if (!record) {
2537
+ return null;
2538
+ }
2539
+ return {
2540
+ id: record.id,
2541
+ metadata: { ...record.metadata },
2542
+ save: cloneSave(record.save)
2543
+ };
2544
+ }
2545
+ async delete(id) {
2546
+ return this.records.delete(id);
2547
+ }
2548
+ async list() {
2549
+ return Array.from(this.records.values()).map((record) => ({
2550
+ id: record.id,
2551
+ metadata: { ...record.metadata },
2552
+ save: cloneSave(record.save)
2553
+ }));
2554
+ }
2555
+ };
2556
+ var IndexedDbSaveAdapter = class {
2557
+ constructor(indexedDB2, dbName, storeName) {
2558
+ this.indexedDB = indexedDB2;
2559
+ this.dbName = dbName;
2560
+ this.storeName = storeName;
2561
+ this.db = null;
2562
+ }
2563
+ async init() {
2564
+ if (this.db) {
2565
+ return;
2566
+ }
2567
+ this.db = await new Promise((resolve, reject) => {
2568
+ const request = this.indexedDB.open(this.dbName, 1);
2569
+ request.onupgradeneeded = () => {
2570
+ request.result.createObjectStore(this.storeName, { keyPath: "id" });
2571
+ };
2572
+ request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
2573
+ request.onsuccess = () => resolve(request.result);
2574
+ });
2575
+ }
2576
+ async runTransaction(mode, operation) {
2577
+ await this.init();
2578
+ const database = this.db;
2579
+ return new Promise((resolve, reject) => {
2580
+ const transaction = database.transaction(this.storeName, mode);
2581
+ const store = transaction.objectStore(this.storeName);
2582
+ const request = operation(store);
2583
+ request.onsuccess = () => resolve(request.result);
2584
+ request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
2585
+ });
2586
+ }
2587
+ async put(record) {
2588
+ await this.runTransaction("readwrite", (store) => store.put(record));
2589
+ }
2590
+ async get(id) {
2591
+ const record = await this.runTransaction("readonly", (store) => store.get(id));
2592
+ if (!record) {
2593
+ return null;
2594
+ }
2595
+ return {
2596
+ id: record.id,
2597
+ metadata: { ...record.metadata },
2598
+ save: cloneSave(record.save)
2599
+ };
2600
+ }
2601
+ async delete(id) {
2602
+ const existing = await this.get(id);
2603
+ if (!existing) {
2604
+ return false;
2605
+ }
2606
+ await this.runTransaction("readwrite", (store) => store.delete(id));
2607
+ return true;
2608
+ }
2609
+ async list() {
2610
+ const all = await this.runTransaction("readonly", (store) => store.getAll());
2611
+ return all.map((record) => ({
2612
+ id: record.id,
2613
+ metadata: { ...record.metadata },
2614
+ save: cloneSave(record.save)
2615
+ }));
2616
+ }
2617
+ };
2618
+ var _SaveStorage = class _SaveStorage2 {
2619
+ constructor(options = {}) {
2620
+ const { dbName = _SaveStorage2.DEFAULT_DB_NAME, storeName = _SaveStorage2.DEFAULT_STORE } = options;
2621
+ const indexedDBFactory = options.indexedDB ?? globalThis.indexedDB;
2622
+ if (indexedDBFactory) {
2623
+ this.adapter = new IndexedDbSaveAdapter(indexedDBFactory, dbName, storeName);
2624
+ } else {
2625
+ this.adapter = new MemorySaveAdapter();
2626
+ }
2627
+ }
2628
+ async save(slotId, save, options = {}) {
2629
+ const normalized = cloneSave(save);
2630
+ const metadata = {
2631
+ id: slotId,
2632
+ name: options.name ?? slotId,
2633
+ map: normalized.map,
2634
+ difficulty: normalized.difficulty,
2635
+ playtimeSeconds: normalized.playtimeSeconds,
2636
+ timestamp: normalized.timestamp,
2637
+ version: normalized.version,
2638
+ bytes: estimateSizeBytes(normalized)
2639
+ };
2640
+ await this.adapter.init();
2641
+ await this.adapter.put({ id: slotId, metadata, save: normalized });
2642
+ return metadata;
2643
+ }
2644
+ async load(slotId, options = {}) {
2645
+ await this.adapter.init();
2646
+ const record = await this.adapter.get(slotId);
2647
+ if (!record) {
2648
+ throw new Error(`Save slot ${slotId} not found`);
2649
+ }
2650
+ return parseSaveFile(record.save, options);
2651
+ }
2652
+ async delete(slotId) {
2653
+ await this.adapter.init();
2654
+ return this.adapter.delete(slotId);
2655
+ }
2656
+ async list() {
2657
+ await this.adapter.init();
2658
+ const records = await this.adapter.list();
2659
+ return records.map((record) => ({ ...record.metadata })).sort((a, b) => b.timestamp - a.timestamp || a.id.localeCompare(b.id));
2660
+ }
2661
+ async quickSave(save) {
2662
+ return this.save(_SaveStorage2.QUICK_SLOT, save, { name: "Quick Save" });
2663
+ }
2664
+ async quickLoad(options = {}) {
2665
+ return this.load(_SaveStorage2.QUICK_SLOT, options);
2666
+ }
2667
+ };
2668
+ _SaveStorage.DEFAULT_DB_NAME = "quake2ts-saves";
2669
+ _SaveStorage.DEFAULT_STORE = "saves";
2670
+ _SaveStorage.QUICK_SLOT = "quicksave";
2671
+ var AmmoType = /* @__PURE__ */ ((AmmoType2) => {
2672
+ AmmoType2[AmmoType2["Bullets"] = 0] = "Bullets";
2673
+ AmmoType2[AmmoType2["Shells"] = 1] = "Shells";
2674
+ AmmoType2[AmmoType2["Rockets"] = 2] = "Rockets";
2675
+ AmmoType2[AmmoType2["Grenades"] = 3] = "Grenades";
2676
+ AmmoType2[AmmoType2["Cells"] = 4] = "Cells";
2677
+ AmmoType2[AmmoType2["Slugs"] = 5] = "Slugs";
2678
+ return AmmoType2;
2679
+ })(AmmoType || {});
2680
+ var AMMO_TYPE_COUNT = Object.keys(AmmoType).length / 2;
2681
+ var ZERO_VEC322 = { x: 0, y: 0, z: 0 };
881
2682
  function createGame(engine, options) {
882
2683
  const gravity = options.gravity;
883
2684
  const levelClock = new LevelClock();
@@ -900,8 +2701,8 @@ function createGame(engine, options) {
900
2701
  };
901
2702
  entities.runFrame();
902
2703
  });
903
- let origin = { ...ZERO_VEC32 };
904
- let velocity = { ...ZERO_VEC32 };
2704
+ let origin = { ...ZERO_VEC322 };
2705
+ let velocity = { ...ZERO_VEC322 };
905
2706
  const snapshot = (frame) => ({
906
2707
  frame,
907
2708
  timeMs: frameLoop.time,
@@ -919,8 +2720,8 @@ function createGame(engine, options) {
919
2720
  const resetState = (startTimeMs) => {
920
2721
  frameLoop.reset(startTimeMs);
921
2722
  levelClock.start(startTimeMs);
922
- origin = { ...ZERO_VEC32 };
923
- velocity = { ...ZERO_VEC32 };
2723
+ origin = { ...ZERO_VEC322 };
2724
+ velocity = { ...ZERO_VEC322 };
924
2725
  entities.beginFrame(startTimeMs / 1e3);
925
2726
  entities.runFrame();
926
2727
  };
@@ -943,72 +2744,73 @@ function createGame(engine, options) {
943
2744
  }
944
2745
 
945
2746
  // ../../packages/shared/dist/esm/index.js
946
- var ZERO_VEC33 = { x: 0, y: 0, z: 0 };
947
- var DEG_TO_RAD3 = Math.PI / 180;
948
- var DEG2RAD_FACTOR3 = Math.PI / 180;
949
- var RAD2DEG_FACTOR3 = 180 / Math.PI;
950
- var CONTENTS_SOLID3 = 1 << 0;
951
- var CONTENTS_WINDOW3 = 1 << 1;
952
- var CONTENTS_AUX3 = 1 << 2;
953
- var CONTENTS_LAVA3 = 1 << 3;
954
- var CONTENTS_SLIME3 = 1 << 4;
955
- var CONTENTS_WATER3 = 1 << 5;
956
- var CONTENTS_MIST3 = 1 << 6;
957
- var CONTENTS_NO_WATERJUMP3 = 1 << 13;
958
- var CONTENTS_PROJECTILECLIP3 = 1 << 14;
959
- var CONTENTS_AREAPORTAL3 = 1 << 15;
960
- var CONTENTS_PLAYERCLIP3 = 1 << 16;
961
- var CONTENTS_MONSTERCLIP3 = 1 << 17;
962
- var CONTENTS_CURRENT_03 = 1 << 18;
963
- var CONTENTS_CURRENT_903 = 1 << 19;
964
- var CONTENTS_CURRENT_1803 = 1 << 20;
965
- var CONTENTS_CURRENT_2703 = 1 << 21;
966
- var CONTENTS_CURRENT_UP3 = 1 << 22;
967
- var CONTENTS_CURRENT_DOWN3 = 1 << 23;
968
- var CONTENTS_ORIGIN3 = 1 << 24;
969
- var CONTENTS_MONSTER3 = 1 << 25;
970
- var CONTENTS_DEADMONSTER3 = 1 << 26;
971
- var CONTENTS_DETAIL3 = 1 << 27;
972
- var CONTENTS_TRANSLUCENT3 = 1 << 28;
973
- var CONTENTS_LADDER3 = 1 << 29;
974
- var CONTENTS_PLAYER3 = 1 << 30;
975
- var CONTENTS_PROJECTILE3 = 1 << 31;
976
- var SURF_LIGHT3 = 1 << 0;
977
- var SURF_SLICK3 = 1 << 1;
978
- var SURF_SKY3 = 1 << 2;
979
- var SURF_WARP3 = 1 << 3;
980
- var SURF_TRANS333 = 1 << 4;
981
- var SURF_TRANS663 = 1 << 5;
982
- var SURF_FLOWING3 = 1 << 6;
983
- var SURF_NODRAW3 = 1 << 7;
984
- var SURF_ALPHATEST3 = 1 << 25;
985
- var SURF_N64_UV3 = 1 << 28;
986
- var SURF_N64_SCROLL_X3 = 1 << 29;
987
- var SURF_N64_SCROLL_Y3 = 1 << 30;
988
- var SURF_N64_SCROLL_FLIP3 = 1 << 31;
989
- var MASK_SOLID3 = CONTENTS_SOLID3 | CONTENTS_WINDOW3;
990
- var MASK_PLAYERSOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
991
- var MASK_DEADSOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3;
992
- var MASK_MONSTERSOLID3 = CONTENTS_SOLID3 | CONTENTS_MONSTERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
993
- var MASK_WATER3 = CONTENTS_WATER3 | CONTENTS_LAVA3 | CONTENTS_SLIME3;
994
- var MASK_OPAQUE3 = CONTENTS_SOLID3 | CONTENTS_SLIME3 | CONTENTS_LAVA3;
995
- var MASK_SHOT3 = CONTENTS_SOLID3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3 | CONTENTS_WINDOW3 | CONTENTS_DEADMONSTER3;
996
- var MASK_CURRENT3 = CONTENTS_CURRENT_03 | CONTENTS_CURRENT_903 | CONTENTS_CURRENT_1803 | CONTENTS_CURRENT_2703 | CONTENTS_CURRENT_UP3 | CONTENTS_CURRENT_DOWN3;
997
- var MASK_BLOCK_SIGHT3 = CONTENTS_SOLID3 | CONTENTS_LAVA3 | CONTENTS_SLIME3 | CONTENTS_MONSTER3 | CONTENTS_PLAYER3;
998
- var MASK_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3;
999
- var MASK_LADDER_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_WINDOW3;
1000
- var MASK_WALK_NAV_SOLID3 = CONTENTS_SOLID3 | CONTENTS_PLAYERCLIP3 | CONTENTS_WINDOW3 | CONTENTS_MONSTERCLIP3;
1001
- var MASK_PROJECTILE3 = MASK_SHOT3 | CONTENTS_PROJECTILECLIP3;
1002
- var MAX_CLIENTS3 = 256;
1003
- var MAX_LIGHTSTYLES3 = 256;
1004
- var MAX_MODELS3 = 8192;
1005
- var MAX_SOUNDS3 = 2048;
1006
- var MAX_IMAGES3 = 512;
1007
- var MAX_ITEMS3 = 256;
1008
- var MAX_GENERAL3 = MAX_CLIENTS3 * 2;
1009
- var MAX_SHADOW_LIGHTS3 = 256;
1010
- var MAX_WHEEL_ITEMS3 = 32;
1011
- var ConfigStringIndex3 = ((ConfigStringIndex22) => {
2747
+ var ZERO_VEC34 = { x: 0, y: 0, z: 0 };
2748
+ var DEG_TO_RAD4 = Math.PI / 180;
2749
+ var DEG2RAD_FACTOR4 = Math.PI / 180;
2750
+ var RAD2DEG_FACTOR4 = 180 / Math.PI;
2751
+ var CONTENTS_SOLID4 = 1 << 0;
2752
+ var CONTENTS_WINDOW4 = 1 << 1;
2753
+ var CONTENTS_AUX4 = 1 << 2;
2754
+ var CONTENTS_LAVA4 = 1 << 3;
2755
+ var CONTENTS_SLIME4 = 1 << 4;
2756
+ var CONTENTS_WATER4 = 1 << 5;
2757
+ var CONTENTS_MIST4 = 1 << 6;
2758
+ var CONTENTS_NO_WATERJUMP4 = 1 << 13;
2759
+ var CONTENTS_PROJECTILECLIP4 = 1 << 14;
2760
+ var CONTENTS_AREAPORTAL4 = 1 << 15;
2761
+ var CONTENTS_PLAYERCLIP4 = 1 << 16;
2762
+ var CONTENTS_MONSTERCLIP4 = 1 << 17;
2763
+ var CONTENTS_CURRENT_04 = 1 << 18;
2764
+ var CONTENTS_CURRENT_904 = 1 << 19;
2765
+ var CONTENTS_CURRENT_1804 = 1 << 20;
2766
+ var CONTENTS_CURRENT_2704 = 1 << 21;
2767
+ var CONTENTS_CURRENT_UP4 = 1 << 22;
2768
+ var CONTENTS_CURRENT_DOWN4 = 1 << 23;
2769
+ var CONTENTS_ORIGIN4 = 1 << 24;
2770
+ var CONTENTS_MONSTER4 = 1 << 25;
2771
+ var CONTENTS_DEADMONSTER4 = 1 << 26;
2772
+ var CONTENTS_DETAIL4 = 1 << 27;
2773
+ var CONTENTS_TRANSLUCENT4 = 1 << 28;
2774
+ var CONTENTS_LADDER4 = 1 << 29;
2775
+ var CONTENTS_PLAYER4 = 1 << 30;
2776
+ var CONTENTS_PROJECTILE4 = 1 << 31;
2777
+ var SURF_LIGHT4 = 1 << 0;
2778
+ var SURF_SLICK4 = 1 << 1;
2779
+ var SURF_SKY4 = 1 << 2;
2780
+ var SURF_WARP4 = 1 << 3;
2781
+ var SURF_TRANS334 = 1 << 4;
2782
+ var SURF_TRANS664 = 1 << 5;
2783
+ var SURF_FLOWING4 = 1 << 6;
2784
+ var SURF_NODRAW4 = 1 << 7;
2785
+ var SURF_ALPHATEST4 = 1 << 25;
2786
+ var SURF_N64_UV4 = 1 << 28;
2787
+ var SURF_N64_SCROLL_X4 = 1 << 29;
2788
+ var SURF_N64_SCROLL_Y4 = 1 << 30;
2789
+ var SURF_N64_SCROLL_FLIP4 = 1 << 31;
2790
+ var MASK_SOLID4 = CONTENTS_SOLID4 | CONTENTS_WINDOW4;
2791
+ var MASK_PLAYERSOLID4 = CONTENTS_SOLID4 | CONTENTS_PLAYERCLIP4 | CONTENTS_WINDOW4 | CONTENTS_MONSTER4 | CONTENTS_PLAYER4;
2792
+ var MASK_DEADSOLID4 = CONTENTS_SOLID4 | CONTENTS_PLAYERCLIP4 | CONTENTS_WINDOW4;
2793
+ var MASK_MONSTERSOLID4 = CONTENTS_SOLID4 | CONTENTS_MONSTERCLIP4 | CONTENTS_WINDOW4 | CONTENTS_MONSTER4 | CONTENTS_PLAYER4;
2794
+ var MASK_WATER4 = CONTENTS_WATER4 | CONTENTS_LAVA4 | CONTENTS_SLIME4;
2795
+ var MASK_OPAQUE4 = CONTENTS_SOLID4 | CONTENTS_SLIME4 | CONTENTS_LAVA4;
2796
+ var MASK_SHOT4 = CONTENTS_SOLID4 | CONTENTS_MONSTER4 | CONTENTS_PLAYER4 | CONTENTS_WINDOW4 | CONTENTS_DEADMONSTER4;
2797
+ var MASK_CURRENT4 = CONTENTS_CURRENT_04 | CONTENTS_CURRENT_904 | CONTENTS_CURRENT_1804 | CONTENTS_CURRENT_2704 | CONTENTS_CURRENT_UP4 | CONTENTS_CURRENT_DOWN4;
2798
+ var MASK_BLOCK_SIGHT4 = CONTENTS_SOLID4 | CONTENTS_LAVA4 | CONTENTS_SLIME4 | CONTENTS_MONSTER4 | CONTENTS_PLAYER4;
2799
+ var MASK_NAV_SOLID4 = CONTENTS_SOLID4 | CONTENTS_PLAYERCLIP4 | CONTENTS_WINDOW4;
2800
+ var MASK_LADDER_NAV_SOLID4 = CONTENTS_SOLID4 | CONTENTS_WINDOW4;
2801
+ var MASK_WALK_NAV_SOLID4 = CONTENTS_SOLID4 | CONTENTS_PLAYERCLIP4 | CONTENTS_WINDOW4 | CONTENTS_MONSTERCLIP4;
2802
+ var MASK_PROJECTILE4 = MASK_SHOT4 | CONTENTS_PROJECTILECLIP4;
2803
+ var MAX_CHECKCOUNT4 = Number.MAX_SAFE_INTEGER - 1;
2804
+ var MAX_CLIENTS4 = 256;
2805
+ var MAX_LIGHTSTYLES4 = 256;
2806
+ var MAX_MODELS4 = 8192;
2807
+ var MAX_SOUNDS4 = 2048;
2808
+ var MAX_IMAGES4 = 512;
2809
+ var MAX_ITEMS4 = 256;
2810
+ var MAX_GENERAL4 = MAX_CLIENTS4 * 2;
2811
+ var MAX_SHADOW_LIGHTS4 = 256;
2812
+ var MAX_WHEEL_ITEMS4 = 32;
2813
+ var ConfigStringIndex4 = ((ConfigStringIndex22) => {
1012
2814
  ConfigStringIndex22[ConfigStringIndex22["Name"] = 0] = "Name";
1013
2815
  ConfigStringIndex22[ConfigStringIndex22["CdTrack"] = 1] = "CdTrack";
1014
2816
  ConfigStringIndex22[ConfigStringIndex22["Sky"] = 2] = "Sky";
@@ -1019,23 +2821,23 @@ var ConfigStringIndex3 = ((ConfigStringIndex22) => {
1019
2821
  ConfigStringIndex22[ConfigStringIndex22["MaxClients"] = 60] = "MaxClients";
1020
2822
  ConfigStringIndex22[ConfigStringIndex22["MapChecksum"] = 61] = "MapChecksum";
1021
2823
  ConfigStringIndex22[ConfigStringIndex22["Models"] = 62] = "Models";
1022
- ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS3] = "Sounds";
1023
- ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS3] = "Images";
1024
- ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES3] = "Lights";
1025
- ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES3] = "ShadowLights";
1026
- ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS3] = "Items";
1027
- ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS3] = "PlayerSkins";
1028
- ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS3] = "General";
1029
- ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL3] = "WheelWeapons";
1030
- ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS3] = "WheelAmmo";
1031
- ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS3] = "WheelPowerups";
1032
- ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS3] = "CdLoopCount";
2824
+ ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS4] = "Sounds";
2825
+ ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS4] = "Images";
2826
+ ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES4] = "Lights";
2827
+ ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES4] = "ShadowLights";
2828
+ ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS4] = "Items";
2829
+ ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS4] = "PlayerSkins";
2830
+ ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS4] = "General";
2831
+ ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL4] = "WheelWeapons";
2832
+ ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS4] = "WheelAmmo";
2833
+ ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS4] = "WheelPowerups";
2834
+ ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS4] = "CdLoopCount";
1033
2835
  ConfigStringIndex22[ConfigStringIndex22["GameStyle"] = ConfigStringIndex22.CdLoopCount + 1] = "GameStyle";
1034
2836
  ConfigStringIndex22[ConfigStringIndex22["MaxConfigStrings"] = ConfigStringIndex22.GameStyle + 1] = "MaxConfigStrings";
1035
2837
  return ConfigStringIndex22;
1036
- })(ConfigStringIndex3 || {});
1037
- var MAX_CONFIGSTRINGS3 = ConfigStringIndex3.MaxConfigStrings;
1038
- var WATERJUMP_CLEAR3 = 8 | 16 | 32 | 1024;
2838
+ })(ConfigStringIndex4 || {});
2839
+ var MAX_CONFIGSTRINGS4 = ConfigStringIndex4.MaxConfigStrings;
2840
+ var WATERJUMP_CLEAR4 = 8 | 16 | 32 | 1024;
1039
2841
 
1040
2842
  // src/index.ts
1041
2843
  function bootstrapViewer() {
@@ -1048,8 +2850,8 @@ function bootstrapViewer() {
1048
2850
  trace(start, end) {
1049
2851
  return { start, end, fraction: 1 };
1050
2852
  }
1051
- }, { gravity: ZERO_VEC33 });
1052
- const client = createClient({ engine: { trace: () => ({ start: ZERO_VEC33, end: ZERO_VEC33, fraction: 1 }) } });
2853
+ }, { gravity: ZERO_VEC34 });
2854
+ const client = createClient({ engine: { trace: () => ({ start: ZERO_VEC34, end: ZERO_VEC34, fraction: 1 }) } });
1053
2855
  const runtime = createEngineRuntime(engine, game, client);
1054
2856
  runtime.start();
1055
2857
  return { engine, game, client, runtime };