quake2ts 0.0.187 → 0.0.189

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 (67) hide show
  1. package/package.json +1 -1
  2. package/packages/cgame/dist/index.cjs +256 -0
  3. package/packages/cgame/dist/index.cjs.map +1 -0
  4. package/packages/cgame/dist/index.d.cts +101 -0
  5. package/packages/cgame/dist/index.d.ts +99 -1
  6. package/packages/cgame/dist/index.js +250 -28
  7. package/packages/cgame/dist/index.js.map +1 -0
  8. package/packages/client/dist/browser/index.global.js +5 -5
  9. package/packages/client/dist/browser/index.global.js.map +1 -1
  10. package/packages/client/dist/cjs/index.cjs +34 -0
  11. package/packages/client/dist/cjs/index.cjs.map +1 -1
  12. package/packages/client/dist/esm/index.js +48 -14
  13. package/packages/client/dist/esm/index.js.map +1 -1
  14. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  15. package/packages/engine/dist/browser/index.global.js +9 -9
  16. package/packages/engine/dist/browser/index.global.js.map +1 -1
  17. package/packages/engine/dist/cjs/index.cjs +17 -0
  18. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  19. package/packages/engine/dist/esm/index.js +17 -0
  20. package/packages/engine/dist/esm/index.js.map +1 -1
  21. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  22. package/packages/game/dist/browser/index.global.js +2 -2
  23. package/packages/game/dist/browser/index.global.js.map +1 -1
  24. package/packages/game/dist/cjs/index.cjs +202 -161
  25. package/packages/game/dist/cjs/index.cjs.map +1 -1
  26. package/packages/game/dist/esm/index.js +202 -161
  27. package/packages/game/dist/esm/index.js.map +1 -1
  28. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  29. package/packages/game/dist/types/entities/pool.d.ts +1 -0
  30. package/packages/game/dist/types/entities/pool.d.ts.map +1 -1
  31. package/packages/game/dist/types/entities/system.d.ts +2 -1
  32. package/packages/game/dist/types/entities/system.d.ts.map +1 -1
  33. package/packages/game/dist/types/imports.d.ts +1 -0
  34. package/packages/game/dist/types/imports.d.ts.map +1 -1
  35. package/packages/game/dist/types/index.d.ts +1 -1
  36. package/packages/game/dist/types/index.d.ts.map +1 -1
  37. package/packages/game/dist/types/inventory/ammo.d.ts +2 -24
  38. package/packages/game/dist/types/inventory/ammo.d.ts.map +1 -1
  39. package/packages/game/dist/types/inventory/playerInventory.d.ts +2 -47
  40. package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
  41. package/packages/game/dist/types/physics/collision.d.ts.map +1 -1
  42. package/packages/server/dist/index.cjs +19 -1
  43. package/packages/server/dist/index.d.cts +1 -0
  44. package/packages/server/dist/index.d.ts +1 -0
  45. package/packages/server/dist/index.js +20 -2
  46. package/packages/shared/dist/browser/index.global.js +1 -1
  47. package/packages/shared/dist/browser/index.global.js.map +1 -1
  48. package/packages/shared/dist/cjs/index.cjs +153 -0
  49. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  50. package/packages/shared/dist/esm/index.js +142 -0
  51. package/packages/shared/dist/esm/index.js.map +1 -1
  52. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  53. package/packages/shared/dist/types/index.d.ts +1 -0
  54. package/packages/shared/dist/types/index.d.ts.map +1 -1
  55. package/packages/shared/dist/types/items/ammo.d.ts +33 -0
  56. package/packages/shared/dist/types/items/ammo.d.ts.map +1 -0
  57. package/packages/shared/dist/types/items/index.d.ts +7 -0
  58. package/packages/shared/dist/types/items/index.d.ts.map +1 -0
  59. package/packages/shared/dist/types/items/powerups.d.ts +31 -0
  60. package/packages/shared/dist/types/items/powerups.d.ts.map +1 -0
  61. package/packages/shared/dist/types/items/weapons.d.ts +25 -0
  62. package/packages/shared/dist/types/items/weapons.d.ts.map +1 -0
  63. package/packages/shared/dist/types/protocol/index.d.ts +2 -0
  64. package/packages/shared/dist/types/protocol/index.d.ts.map +1 -1
  65. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
  66. package/packages/cgame/dist/index.d.mts +0 -3
  67. package/packages/cgame/dist/index.mjs +0 -7
@@ -817,6 +817,80 @@ var applyPmove = (state, cmd, trace, pointContents2) => {
817
817
  velocity: finalVelocity
818
818
  };
819
819
  };
820
+ var WeaponId = /* @__PURE__ */ ((WeaponId22) => {
821
+ WeaponId22["Blaster"] = "blaster";
822
+ WeaponId22["Shotgun"] = "shotgun";
823
+ WeaponId22["SuperShotgun"] = "super_shotgun";
824
+ WeaponId22["Machinegun"] = "machinegun";
825
+ WeaponId22["Chaingun"] = "chaingun";
826
+ WeaponId22["GrenadeLauncher"] = "grenade_launcher";
827
+ WeaponId22["RocketLauncher"] = "rocket_launcher";
828
+ WeaponId22["HyperBlaster"] = "hyperblaster";
829
+ WeaponId22["Railgun"] = "railgun";
830
+ WeaponId22["BFG10K"] = "bfg10k";
831
+ WeaponId22["Grapple"] = "grapple";
832
+ WeaponId22["ChainFist"] = "chainfist";
833
+ WeaponId22["EtfRifle"] = "etf_rifle";
834
+ WeaponId22["ProxLauncher"] = "prox_launcher";
835
+ WeaponId22["IonRipper"] = "ionripper";
836
+ WeaponId22["PlasmaBeam"] = "plasmabeam";
837
+ WeaponId22["Phalanx"] = "phalanx";
838
+ WeaponId22["Disruptor"] = "disruptor";
839
+ return WeaponId22;
840
+ })(WeaponId || {});
841
+ var AmmoType = /* @__PURE__ */ ((AmmoType22) => {
842
+ AmmoType22[AmmoType22["Bullets"] = 0] = "Bullets";
843
+ AmmoType22[AmmoType22["Shells"] = 1] = "Shells";
844
+ AmmoType22[AmmoType22["Rockets"] = 2] = "Rockets";
845
+ AmmoType22[AmmoType22["Grenades"] = 3] = "Grenades";
846
+ AmmoType22[AmmoType22["Cells"] = 4] = "Cells";
847
+ AmmoType22[AmmoType22["Slugs"] = 5] = "Slugs";
848
+ AmmoType22[AmmoType22["Trap"] = 6] = "Trap";
849
+ AmmoType22[AmmoType22["Tesla"] = 7] = "Tesla";
850
+ AmmoType22[AmmoType22["MagSlugs"] = 8] = "MagSlugs";
851
+ AmmoType22[AmmoType22["Flechettes"] = 9] = "Flechettes";
852
+ AmmoType22[AmmoType22["Prox"] = 10] = "Prox";
853
+ AmmoType22[AmmoType22["Nuke"] = 11] = "Nuke";
854
+ AmmoType22[AmmoType22["Rounds"] = 12] = "Rounds";
855
+ return AmmoType22;
856
+ })(AmmoType || {});
857
+ var AMMO_TYPE_COUNT = Object.keys(AmmoType).length / 2;
858
+ var AmmoItemId = /* @__PURE__ */ ((AmmoItemId22) => {
859
+ AmmoItemId22["Shells"] = "ammo_shells";
860
+ AmmoItemId22["Bullets"] = "ammo_bullets";
861
+ AmmoItemId22["Rockets"] = "ammo_rockets";
862
+ AmmoItemId22["Grenades"] = "ammo_grenades";
863
+ AmmoItemId22["Cells"] = "ammo_cells";
864
+ AmmoItemId22["Slugs"] = "ammo_slugs";
865
+ return AmmoItemId22;
866
+ })(AmmoItemId || {});
867
+ var PowerupId = /* @__PURE__ */ ((PowerupId22) => {
868
+ PowerupId22["QuadDamage"] = "quad";
869
+ PowerupId22["Invulnerability"] = "invulnerability";
870
+ PowerupId22["EnviroSuit"] = "enviro_suit";
871
+ PowerupId22["Rebreather"] = "rebreather";
872
+ PowerupId22["Silencer"] = "silencer";
873
+ PowerupId22["PowerScreen"] = "power_screen";
874
+ PowerupId22["PowerShield"] = "power_shield";
875
+ PowerupId22["QuadFire"] = "quad_fire";
876
+ PowerupId22["Invisibility"] = "invisibility";
877
+ PowerupId22["Bandolier"] = "bandolier";
878
+ PowerupId22["AmmoPack"] = "ammo_pack";
879
+ PowerupId22["IRGoggles"] = "ir_goggles";
880
+ PowerupId22["DoubleDamage"] = "double_damage";
881
+ PowerupId22["SphereVengeance"] = "sphere_vengeance";
882
+ PowerupId22["SphereHunter"] = "sphere_hunter";
883
+ PowerupId22["SphereDefender"] = "sphere_defender";
884
+ PowerupId22["Doppelganger"] = "doppelganger";
885
+ PowerupId22["TagToken"] = "tag_token";
886
+ PowerupId22["TechResistance"] = "tech_resistance";
887
+ PowerupId22["TechStrength"] = "tech_strength";
888
+ PowerupId22["TechHaste"] = "tech_haste";
889
+ PowerupId22["TechRegeneration"] = "tech_regeneration";
890
+ PowerupId22["Flashlight"] = "flashlight";
891
+ PowerupId22["Compass"] = "compass";
892
+ return PowerupId22;
893
+ })(PowerupId || {});
820
894
 
821
895
  // src/combat/damageFlags.ts
822
896
  var DamageFlags = /* @__PURE__ */ ((DamageFlags2) => {
@@ -930,39 +1004,13 @@ function applyPowerArmor(damage, flags, hitPoint, _hitNormal, state, options = {
930
1004
  }
931
1005
 
932
1006
  // src/inventory/ammo.ts
933
- var AmmoType = /* @__PURE__ */ ((AmmoType3) => {
934
- AmmoType3[AmmoType3["Bullets"] = 0] = "Bullets";
935
- AmmoType3[AmmoType3["Shells"] = 1] = "Shells";
936
- AmmoType3[AmmoType3["Rockets"] = 2] = "Rockets";
937
- AmmoType3[AmmoType3["Grenades"] = 3] = "Grenades";
938
- AmmoType3[AmmoType3["Cells"] = 4] = "Cells";
939
- AmmoType3[AmmoType3["Slugs"] = 5] = "Slugs";
940
- AmmoType3[AmmoType3["Trap"] = 6] = "Trap";
941
- AmmoType3[AmmoType3["Tesla"] = 7] = "Tesla";
942
- AmmoType3[AmmoType3["MagSlugs"] = 8] = "MagSlugs";
943
- AmmoType3[AmmoType3["Flechettes"] = 9] = "Flechettes";
944
- AmmoType3[AmmoType3["Prox"] = 10] = "Prox";
945
- AmmoType3[AmmoType3["Nuke"] = 11] = "Nuke";
946
- AmmoType3[AmmoType3["Rounds"] = 12] = "Rounds";
947
- return AmmoType3;
948
- })(AmmoType || {});
949
- var AMMO_TYPE_COUNT = Object.keys(AmmoType).length / 2;
950
- var AmmoItemId = /* @__PURE__ */ ((AmmoItemId4) => {
951
- AmmoItemId4["Shells"] = "ammo_shells";
952
- AmmoItemId4["Bullets"] = "ammo_bullets";
953
- AmmoItemId4["Rockets"] = "ammo_rockets";
954
- AmmoItemId4["Grenades"] = "ammo_grenades";
955
- AmmoItemId4["Cells"] = "ammo_cells";
956
- AmmoItemId4["Slugs"] = "ammo_slugs";
957
- return AmmoItemId4;
958
- })(AmmoItemId || {});
959
1007
  var AMMO_ITEM_DEFINITIONS = {
960
- ["ammo_shells" /* Shells */]: { id: "ammo_shells" /* Shells */, ammoType: 1 /* Shells */, quantity: 10, weaponAmmo: false },
961
- ["ammo_bullets" /* Bullets */]: { id: "ammo_bullets" /* Bullets */, ammoType: 0 /* Bullets */, quantity: 50, weaponAmmo: false },
962
- ["ammo_rockets" /* Rockets */]: { id: "ammo_rockets" /* Rockets */, ammoType: 2 /* Rockets */, quantity: 5, weaponAmmo: false },
963
- ["ammo_grenades" /* Grenades */]: { id: "ammo_grenades" /* Grenades */, ammoType: 3 /* Grenades */, quantity: 5, weaponAmmo: true },
964
- ["ammo_cells" /* Cells */]: { id: "ammo_cells" /* Cells */, ammoType: 4 /* Cells */, quantity: 50, weaponAmmo: false },
965
- ["ammo_slugs" /* Slugs */]: { id: "ammo_slugs" /* Slugs */, ammoType: 5 /* Slugs */, quantity: 10, weaponAmmo: false }
1008
+ [AmmoItemId.Shells]: { id: AmmoItemId.Shells, ammoType: AmmoType.Shells, quantity: 10, weaponAmmo: false },
1009
+ [AmmoItemId.Bullets]: { id: AmmoItemId.Bullets, ammoType: AmmoType.Bullets, quantity: 50, weaponAmmo: false },
1010
+ [AmmoItemId.Rockets]: { id: AmmoItemId.Rockets, ammoType: AmmoType.Rockets, quantity: 5, weaponAmmo: false },
1011
+ [AmmoItemId.Grenades]: { id: AmmoItemId.Grenades, ammoType: AmmoType.Grenades, quantity: 5, weaponAmmo: true },
1012
+ [AmmoItemId.Cells]: { id: AmmoItemId.Cells, ammoType: AmmoType.Cells, quantity: 50, weaponAmmo: false },
1013
+ [AmmoItemId.Slugs]: { id: AmmoItemId.Slugs, ammoType: AmmoType.Slugs, quantity: 10, weaponAmmo: false }
966
1014
  };
967
1015
  function getAmmoItemDefinition(id) {
968
1016
  return AMMO_ITEM_DEFINITIONS[id];
@@ -978,9 +1026,9 @@ function createAmmoInventory(caps = createBaseAmmoCaps(), seed) {
978
1026
  }
979
1027
  function createBaseAmmoCaps() {
980
1028
  const caps = Array(AMMO_TYPE_COUNT).fill(50);
981
- caps[0 /* Bullets */] = 200;
982
- caps[1 /* Shells */] = 100;
983
- caps[4 /* Cells */] = 200;
1029
+ caps[AmmoType.Bullets] = 200;
1030
+ caps[AmmoType.Shells] = 100;
1031
+ caps[AmmoType.Cells] = 200;
984
1032
  return caps;
985
1033
  }
986
1034
  function clampAmmoCounts(counts, caps) {
@@ -1013,54 +1061,6 @@ function pickupAmmo(inventory, itemId, options = {}) {
1013
1061
  }
1014
1062
 
1015
1063
  // src/inventory/playerInventory.ts
1016
- var WeaponId = /* @__PURE__ */ ((WeaponId3) => {
1017
- WeaponId3["Blaster"] = "blaster";
1018
- WeaponId3["Shotgun"] = "shotgun";
1019
- WeaponId3["SuperShotgun"] = "super_shotgun";
1020
- WeaponId3["Machinegun"] = "machinegun";
1021
- WeaponId3["Chaingun"] = "chaingun";
1022
- WeaponId3["GrenadeLauncher"] = "grenade_launcher";
1023
- WeaponId3["RocketLauncher"] = "rocket_launcher";
1024
- WeaponId3["HyperBlaster"] = "hyperblaster";
1025
- WeaponId3["Railgun"] = "railgun";
1026
- WeaponId3["BFG10K"] = "bfg10k";
1027
- WeaponId3["Grapple"] = "grapple";
1028
- WeaponId3["ChainFist"] = "chainfist";
1029
- WeaponId3["EtfRifle"] = "etf_rifle";
1030
- WeaponId3["ProxLauncher"] = "prox_launcher";
1031
- WeaponId3["IonRipper"] = "ionripper";
1032
- WeaponId3["PlasmaBeam"] = "plasmabeam";
1033
- WeaponId3["Phalanx"] = "phalanx";
1034
- WeaponId3["Disruptor"] = "disruptor";
1035
- return WeaponId3;
1036
- })(WeaponId || {});
1037
- var PowerupId = /* @__PURE__ */ ((PowerupId3) => {
1038
- PowerupId3["QuadDamage"] = "quad";
1039
- PowerupId3["Invulnerability"] = "invulnerability";
1040
- PowerupId3["EnviroSuit"] = "enviro_suit";
1041
- PowerupId3["Rebreather"] = "rebreather";
1042
- PowerupId3["Silencer"] = "silencer";
1043
- PowerupId3["PowerScreen"] = "power_screen";
1044
- PowerupId3["PowerShield"] = "power_shield";
1045
- PowerupId3["QuadFire"] = "quad_fire";
1046
- PowerupId3["Invisibility"] = "invisibility";
1047
- PowerupId3["Bandolier"] = "bandolier";
1048
- PowerupId3["AmmoPack"] = "ammo_pack";
1049
- PowerupId3["IRGoggles"] = "ir_goggles";
1050
- PowerupId3["DoubleDamage"] = "double_damage";
1051
- PowerupId3["SphereVengeance"] = "sphere_vengeance";
1052
- PowerupId3["SphereHunter"] = "sphere_hunter";
1053
- PowerupId3["SphereDefender"] = "sphere_defender";
1054
- PowerupId3["Doppelganger"] = "doppelganger";
1055
- PowerupId3["TagToken"] = "tag_token";
1056
- PowerupId3["TechResistance"] = "tech_resistance";
1057
- PowerupId3["TechStrength"] = "tech_strength";
1058
- PowerupId3["TechHaste"] = "tech_haste";
1059
- PowerupId3["TechRegeneration"] = "tech_regeneration";
1060
- PowerupId3["Flashlight"] = "flashlight";
1061
- PowerupId3["Compass"] = "compass";
1062
- return PowerupId3;
1063
- })(PowerupId || {});
1064
1064
  var KeyId = /* @__PURE__ */ ((KeyId2) => {
1065
1065
  KeyId2["Blue"] = "blue";
1066
1066
  KeyId2["Red"] = "red";
@@ -1210,27 +1210,27 @@ function pickupPowerup(client, item, time) {
1210
1210
  let icon = "";
1211
1211
  switch (item.id) {
1212
1212
  case "item_quad":
1213
- powerupId = "quad" /* QuadDamage */;
1213
+ powerupId = PowerupId.QuadDamage;
1214
1214
  icon = "p_quad";
1215
1215
  break;
1216
1216
  case "item_invulnerability":
1217
- powerupId = "invulnerability" /* Invulnerability */;
1217
+ powerupId = PowerupId.Invulnerability;
1218
1218
  icon = "p_invulnerability";
1219
1219
  break;
1220
1220
  case "item_silencer":
1221
- powerupId = "silencer" /* Silencer */;
1221
+ powerupId = PowerupId.Silencer;
1222
1222
  icon = "p_silencer";
1223
1223
  break;
1224
1224
  case "item_rebreather":
1225
- powerupId = "rebreather" /* Rebreather */;
1225
+ powerupId = PowerupId.Rebreather;
1226
1226
  icon = "p_rebreather";
1227
1227
  break;
1228
1228
  case "item_enviro":
1229
- powerupId = "enviro_suit" /* EnviroSuit */;
1229
+ powerupId = PowerupId.EnviroSuit;
1230
1230
  icon = "p_envirosuit";
1231
1231
  break;
1232
1232
  case "item_double":
1233
- powerupId = "double_damage" /* DoubleDamage */;
1233
+ powerupId = PowerupId.DoubleDamage;
1234
1234
  icon = "p_double";
1235
1235
  break;
1236
1236
  }
@@ -1238,9 +1238,9 @@ function pickupPowerup(client, item, time) {
1238
1238
  const expiresAt = inventory.powerups.get(powerupId);
1239
1239
  const newExpiresAt = expiresAt && expiresAt > time ? expiresAt + item.timer * 1e3 : time + item.timer * 1e3;
1240
1240
  inventory.powerups.set(powerupId, newExpiresAt);
1241
- if (powerupId === "quad" /* QuadDamage */) {
1241
+ if (powerupId === PowerupId.QuadDamage) {
1242
1242
  client.quad_time = newExpiresAt / 1e3;
1243
- } else if (powerupId === "double_damage" /* DoubleDamage */) {
1243
+ } else if (powerupId === PowerupId.DoubleDamage) {
1244
1244
  client.double_time = newExpiresAt / 1e3;
1245
1245
  }
1246
1246
  setPickup(inventory, icon, time);
@@ -1509,10 +1509,10 @@ var Entity = class {
1509
1509
  return {
1510
1510
  type,
1511
1511
  get cellCount() {
1512
- return ammo.counts[4 /* Cells */] || 0;
1512
+ return ammo.counts[AmmoType.Cells] || 0;
1513
1513
  },
1514
1514
  set cellCount(v) {
1515
- ammo.counts[4 /* Cells */] = v;
1515
+ ammo.counts[AmmoType.Cells] = v;
1516
1516
  },
1517
1517
  angles: this.angles,
1518
1518
  origin: this.origin,
@@ -2208,15 +2208,16 @@ function checkTriggers(ent, system) {
2208
2208
  if (ent.movetype === 0 /* None */) {
2209
2209
  return;
2210
2210
  }
2211
- system.forEachEntity((other) => {
2212
- if (other === ent) return;
2213
- if (other.solid !== 1 /* Trigger */) return;
2214
- if (!other.touch) return;
2215
- if (ent.absmax.x < other.absmin.x || ent.absmin.x > other.absmax.x) return;
2216
- if (ent.absmax.y < other.absmin.y || ent.absmin.y > other.absmax.y) return;
2217
- if (ent.absmax.z < other.absmin.z || ent.absmin.z > other.absmax.z) return;
2211
+ const candidates = system.findInBox(ent.absmin, ent.absmax);
2212
+ for (const other of candidates) {
2213
+ if (other === ent) continue;
2214
+ if (other.solid !== 1 /* Trigger */) continue;
2215
+ if (!other.touch) continue;
2216
+ if (ent.absmax.x < other.absmin.x || ent.absmin.x > other.absmax.x) continue;
2217
+ if (ent.absmax.y < other.absmin.y || ent.absmin.y > other.absmax.y) continue;
2218
+ if (ent.absmax.z < other.absmin.z || ent.absmin.z > other.absmax.z) continue;
2218
2219
  other.touch(other, ent);
2219
- });
2220
+ }
2220
2221
  }
2221
2222
 
2222
2223
  // src/physics/movement.ts
@@ -2536,6 +2537,9 @@ var EntityPool = class {
2536
2537
  }
2537
2538
  return count;
2538
2539
  }
2540
+ getByIndex(index) {
2541
+ return this.entities[index];
2542
+ }
2539
2543
  [Symbol.iterator]() {
2540
2544
  let current = this.activeHead;
2541
2545
  return {
@@ -2797,7 +2801,7 @@ var EntitySystem = class {
2797
2801
  this.thinkScheduler = new ThinkScheduler();
2798
2802
  this.engine = engine;
2799
2803
  this.deathmatch = deathmatch ?? false;
2800
- this.imports = imports || {
2804
+ const defaultImports = {
2801
2805
  trace: () => ({
2802
2806
  allsolid: false,
2803
2807
  startsolid: false,
@@ -2821,11 +2825,14 @@ var EntitySystem = class {
2821
2825
  z: ent.origin.z + ent.maxs.z
2822
2826
  };
2823
2827
  },
2828
+ areaEdicts: () => null,
2829
+ // Default to null to signal fallback
2824
2830
  multicast: () => {
2825
2831
  },
2826
2832
  unicast: () => {
2827
2833
  }
2828
2834
  };
2835
+ this.imports = { ...defaultImports, ...imports };
2829
2836
  this.gravity = gravity || { x: 0, y: 0, z: 0 };
2830
2837
  this.callbackToName = /* @__PURE__ */ new Map();
2831
2838
  if (callbackRegistry) {
@@ -2943,14 +2950,37 @@ var EntitySystem = class {
2943
2950
  }
2944
2951
  return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
2945
2952
  }
2953
+ findInBox(mins, maxs) {
2954
+ const indices = this.imports.areaEdicts(mins, maxs);
2955
+ if (indices === null) {
2956
+ const results2 = [];
2957
+ const bounds = { min: mins, max: maxs };
2958
+ for (const entity of this.pool) {
2959
+ if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) continue;
2960
+ if (boundsIntersect(bounds, computeBounds(entity))) {
2961
+ results2.push(entity);
2962
+ }
2963
+ }
2964
+ return results2;
2965
+ }
2966
+ const results = [];
2967
+ for (const index of indices) {
2968
+ const entity = this.pool.getByIndex(index);
2969
+ if (entity && entity.inUse && !entity.freePending) {
2970
+ results.push(entity);
2971
+ }
2972
+ }
2973
+ return results;
2974
+ }
2946
2975
  findByRadius(origin, radius) {
2976
+ const mins = { x: origin.x - radius, y: origin.y - radius, z: origin.z - radius };
2977
+ const maxs = { x: origin.x + radius, y: origin.y + radius, z: origin.z + radius };
2978
+ const candidates = this.findInBox(mins, maxs);
2947
2979
  const matches = [];
2948
- for (const entity of this.pool) {
2949
- if (entity.inUse && !entity.freePending) {
2950
- const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
2951
- if (distance2 <= radius) {
2952
- matches.push(entity);
2953
- }
2980
+ for (const entity of candidates) {
2981
+ const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
2982
+ if (distance2 <= radius) {
2983
+ matches.push(entity);
2954
2984
  }
2955
2985
  }
2956
2986
  return matches;
@@ -3160,35 +3190,19 @@ var EntitySystem = class {
3160
3190
  const world = this.pool.world;
3161
3191
  const activeEntities = [];
3162
3192
  for (const entity of this.pool) {
3163
- if (entity === world) {
3164
- continue;
3165
- }
3166
- if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) {
3167
- continue;
3168
- }
3193
+ if (entity === world) continue;
3194
+ if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) continue;
3169
3195
  activeEntities.push(entity);
3170
3196
  }
3171
- for (let i = 0; i < activeEntities.length; i += 1) {
3172
- const first = activeEntities[i];
3173
- let firstBounds = null;
3174
- for (let j = i + 1; j < activeEntities.length; j += 1) {
3175
- const second = activeEntities[j];
3176
- if (!first.touch && !second.touch) {
3177
- continue;
3178
- }
3179
- if (!firstBounds) {
3180
- firstBounds = computeBounds(first);
3181
- }
3197
+ for (const first of activeEntities) {
3198
+ const candidates = this.findInBox(first.absmin, first.absmax);
3199
+ const firstBounds = computeBounds(first);
3200
+ for (const second of candidates) {
3201
+ if (first === second) continue;
3202
+ if (!first.touch) continue;
3182
3203
  const secondBounds = computeBounds(second);
3183
- if (!boundsIntersect(firstBounds, secondBounds)) {
3184
- continue;
3185
- }
3186
- if (first.touch) {
3187
- first.touch(first, second);
3188
- }
3189
- if (second.touch) {
3190
- second.touch(second, first);
3191
- }
3204
+ if (!boundsIntersect(firstBounds, secondBounds)) continue;
3205
+ first.touch(first, second);
3192
3206
  }
3193
3207
  }
3194
3208
  }
@@ -3918,7 +3932,7 @@ function chaingunThink(player, sys) {
3918
3932
  if (!player.client) {
3919
3933
  return;
3920
3934
  }
3921
- const weaponState = getWeaponState(player.client.weaponStates, "chaingun" /* Chaingun */);
3935
+ const weaponState = getWeaponState(player.client.weaponStates, WeaponId.Chaingun);
3922
3936
  if (!(player.client.buttons & BUTTON_ATTACK) && weaponState.spinupCount && weaponState.spinupCount > 0) {
3923
3937
  sys.sound(player, 0, "weapons/chngnd1a.wav", 1, 0, 0);
3924
3938
  weaponState.spinupCount = 0;
@@ -3931,7 +3945,7 @@ var WEAPON_ITEMS = {
3931
3945
  type: "weapon",
3932
3946
  id: "weapon_blaster",
3933
3947
  name: "Blaster",
3934
- weaponId: "blaster" /* Blaster */,
3948
+ weaponId: WeaponId.Blaster,
3935
3949
  ammoType: null,
3936
3950
  initialAmmo: 0,
3937
3951
  pickupAmmo: 0,
@@ -3941,8 +3955,8 @@ var WEAPON_ITEMS = {
3941
3955
  type: "weapon",
3942
3956
  id: "weapon_shotgun",
3943
3957
  name: "Shotgun",
3944
- weaponId: "shotgun" /* Shotgun */,
3945
- ammoType: 1 /* Shells */,
3958
+ weaponId: WeaponId.Shotgun,
3959
+ ammoType: AmmoType.Shells,
3946
3960
  initialAmmo: 10,
3947
3961
  pickupAmmo: 10,
3948
3962
  fireRate: 1
@@ -3951,8 +3965,8 @@ var WEAPON_ITEMS = {
3951
3965
  type: "weapon",
3952
3966
  id: "weapon_supershotgun",
3953
3967
  name: "Super Shotgun",
3954
- weaponId: "super_shotgun" /* SuperShotgun */,
3955
- ammoType: 1 /* Shells */,
3968
+ weaponId: WeaponId.SuperShotgun,
3969
+ ammoType: AmmoType.Shells,
3956
3970
  initialAmmo: 10,
3957
3971
  pickupAmmo: 10,
3958
3972
  fireRate: 1
@@ -3961,8 +3975,8 @@ var WEAPON_ITEMS = {
3961
3975
  type: "weapon",
3962
3976
  id: "weapon_machinegun",
3963
3977
  name: "Machinegun",
3964
- weaponId: "machinegun" /* Machinegun */,
3965
- ammoType: 0 /* Bullets */,
3978
+ weaponId: WeaponId.Machinegun,
3979
+ ammoType: AmmoType.Bullets,
3966
3980
  initialAmmo: 50,
3967
3981
  pickupAmmo: 50,
3968
3982
  fireRate: 0.1,
@@ -3972,8 +3986,8 @@ var WEAPON_ITEMS = {
3972
3986
  type: "weapon",
3973
3987
  id: "weapon_chaingun",
3974
3988
  name: "Chaingun",
3975
- weaponId: "chaingun" /* Chaingun */,
3976
- ammoType: 0 /* Bullets */,
3989
+ weaponId: WeaponId.Chaingun,
3990
+ ammoType: AmmoType.Bullets,
3977
3991
  initialAmmo: 50,
3978
3992
  pickupAmmo: 50,
3979
3993
  fireRate: 0.1
@@ -3982,8 +3996,8 @@ var WEAPON_ITEMS = {
3982
3996
  type: "weapon",
3983
3997
  id: "weapon_grenadelauncher",
3984
3998
  name: "Grenade Launcher",
3985
- weaponId: "grenade_launcher" /* GrenadeLauncher */,
3986
- ammoType: 3 /* Grenades */,
3999
+ weaponId: WeaponId.GrenadeLauncher,
4000
+ ammoType: AmmoType.Grenades,
3987
4001
  initialAmmo: 10,
3988
4002
  pickupAmmo: 10,
3989
4003
  fireRate: 1
@@ -3992,8 +4006,8 @@ var WEAPON_ITEMS = {
3992
4006
  type: "weapon",
3993
4007
  id: "weapon_rocketlauncher",
3994
4008
  name: "Rocket Launcher",
3995
- weaponId: "rocket_launcher" /* RocketLauncher */,
3996
- ammoType: 2 /* Rockets */,
4009
+ weaponId: WeaponId.RocketLauncher,
4010
+ ammoType: AmmoType.Rockets,
3997
4011
  initialAmmo: 5,
3998
4012
  pickupAmmo: 5,
3999
4013
  fireRate: 1
@@ -4002,8 +4016,8 @@ var WEAPON_ITEMS = {
4002
4016
  type: "weapon",
4003
4017
  id: "weapon_hyperblaster",
4004
4018
  name: "HyperBlaster",
4005
- weaponId: "hyperblaster" /* HyperBlaster */,
4006
- ammoType: 4 /* Cells */,
4019
+ weaponId: WeaponId.HyperBlaster,
4020
+ ammoType: AmmoType.Cells,
4007
4021
  initialAmmo: 50,
4008
4022
  pickupAmmo: 50,
4009
4023
  fireRate: 0.1
@@ -4012,8 +4026,8 @@ var WEAPON_ITEMS = {
4012
4026
  type: "weapon",
4013
4027
  id: "weapon_railgun",
4014
4028
  name: "Railgun",
4015
- weaponId: "railgun" /* Railgun */,
4016
- ammoType: 5 /* Slugs */,
4029
+ weaponId: WeaponId.Railgun,
4030
+ ammoType: AmmoType.Slugs,
4017
4031
  initialAmmo: 10,
4018
4032
  pickupAmmo: 10,
4019
4033
  fireRate: 1.5
@@ -4022,8 +4036,8 @@ var WEAPON_ITEMS = {
4022
4036
  type: "weapon",
4023
4037
  id: "weapon_bfg",
4024
4038
  name: "BFG10K",
4025
- weaponId: "bfg10k" /* BFG10K */,
4026
- ammoType: 4 /* Cells */,
4039
+ weaponId: WeaponId.BFG10K,
4040
+ ammoType: AmmoType.Cells,
4027
4041
  initialAmmo: 50,
4028
4042
  pickupAmmo: 50,
4029
4043
  fireRate: 1
@@ -12853,13 +12867,29 @@ var WEAPONS = {
12853
12867
 
12854
12868
  // src/index.ts
12855
12869
  var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
12856
- function createGame({ trace, pointcontents, multicast, unicast }, engine, options) {
12870
+ function createGame(imports, engine, options) {
12857
12871
  const gravity = options.gravity;
12858
12872
  const deathmatch = options.deathmatch ?? false;
12859
12873
  const levelClock = new LevelClock();
12860
12874
  const frameLoop = new GameFrameLoop();
12861
12875
  const rng = options.random ?? new RandomGenerator();
12862
- const linkentity = (ent) => {
12876
+ const trace = imports.trace || (() => ({
12877
+ allsolid: false,
12878
+ startsolid: false,
12879
+ fraction: 1,
12880
+ endpos: { x: 0, y: 0, z: 0 },
12881
+ plane: null,
12882
+ surfaceFlags: 0,
12883
+ contents: 0,
12884
+ ent: null
12885
+ }));
12886
+ const pointcontents = imports.pointcontents || (() => 0);
12887
+ const multicast = imports.multicast || (() => {
12888
+ });
12889
+ const unicast = imports.unicast || (() => {
12890
+ });
12891
+ const linkentity = imports.linkentity;
12892
+ const wrappedLinkEntity = (ent) => {
12863
12893
  ent.absmin = {
12864
12894
  x: ent.origin.x + ent.mins.x,
12865
12895
  y: ent.origin.y + ent.mins.y,
@@ -12870,8 +12900,19 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12870
12900
  y: ent.origin.y + ent.maxs.y,
12871
12901
  z: ent.origin.z + ent.maxs.z
12872
12902
  };
12903
+ if (linkentity) {
12904
+ linkentity(ent);
12905
+ }
12906
+ };
12907
+ const systemImports = {
12908
+ ...imports,
12909
+ trace,
12910
+ pointcontents,
12911
+ linkentity: wrappedLinkEntity,
12912
+ multicast,
12913
+ unicast
12873
12914
  };
12874
- const entities = new EntitySystem(engine, { trace, pointcontents, linkentity, multicast, unicast }, gravity, void 0, void 0, deathmatch);
12915
+ const entities = new EntitySystem(engine, systemImports, gravity, void 0, void 0, deathmatch);
12875
12916
  frameLoop.addStage("prep", (context) => {
12876
12917
  levelClock.tick(context);
12877
12918
  entities.beginFrame(levelClock.current.timeSeconds);
@@ -12895,20 +12936,20 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12895
12936
  const blend = [0, 0, 0, 0];
12896
12937
  if (!player || !player.client) return blend;
12897
12938
  const inventory = player.client.inventory;
12898
- if (inventory.powerups.has("quad" /* QuadDamage */)) {
12939
+ if (inventory.powerups.has(PowerupId.QuadDamage)) {
12899
12940
  blend[2] = 1;
12900
12941
  blend[3] = 0.08;
12901
12942
  }
12902
- if (inventory.powerups.has("invulnerability" /* Invulnerability */)) {
12943
+ if (inventory.powerups.has(PowerupId.Invulnerability)) {
12903
12944
  blend[0] = 1;
12904
12945
  blend[1] = 1;
12905
12946
  blend[3] = 0.08;
12906
12947
  }
12907
- if (inventory.powerups.has("enviro_suit" /* EnviroSuit */)) {
12948
+ if (inventory.powerups.has(PowerupId.EnviroSuit)) {
12908
12949
  blend[1] = 1;
12909
12950
  blend[3] = 0.08;
12910
12951
  }
12911
- if (inventory.powerups.has("rebreather" /* Rebreather */)) {
12952
+ if (inventory.powerups.has(PowerupId.Rebreather)) {
12912
12953
  blend[0] = 0.4;
12913
12954
  blend[1] = 1;
12914
12955
  blend[2] = 0.4;