quake2ts 0.0.68 → 0.0.71

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 (54) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +1 -1
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs.map +1 -1
  5. package/packages/client/dist/esm/index.js.map +1 -1
  6. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  7. package/packages/engine/dist/browser/index.global.js +14 -14
  8. package/packages/engine/dist/browser/index.global.js.map +1 -1
  9. package/packages/engine/dist/cjs/index.cjs +84 -0
  10. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  11. package/packages/engine/dist/esm/index.js +81 -0
  12. package/packages/engine/dist/esm/index.js.map +1 -1
  13. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  14. package/packages/engine/dist/types/assets/manager.d.ts +4 -1
  15. package/packages/engine/dist/types/assets/manager.d.ts.map +1 -1
  16. package/packages/engine/dist/types/assets/sprite.d.ts +23 -0
  17. package/packages/engine/dist/types/assets/sprite.d.ts.map +1 -0
  18. package/packages/engine/dist/types/index.d.ts +1 -0
  19. package/packages/engine/dist/types/index.d.ts.map +1 -1
  20. package/packages/game/dist/browser/index.global.js +1 -1
  21. package/packages/game/dist/browser/index.global.js.map +1 -1
  22. package/packages/game/dist/cjs/index.cjs +318 -40
  23. package/packages/game/dist/cjs/index.cjs.map +1 -1
  24. package/packages/game/dist/esm/index.js +318 -40
  25. package/packages/game/dist/esm/index.js.map +1 -1
  26. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  27. package/packages/game/dist/types/combat/weapons/firing.d.ts.map +1 -1
  28. package/packages/game/dist/types/entities/entity.d.ts +9 -1
  29. package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
  30. package/packages/game/dist/types/entities/funcs.d.ts +9 -0
  31. package/packages/game/dist/types/entities/funcs.d.ts.map +1 -0
  32. package/packages/game/dist/types/entities/projectiles.d.ts +2 -0
  33. package/packages/game/dist/types/entities/projectiles.d.ts.map +1 -1
  34. package/packages/game/dist/types/entities/spawn.d.ts.map +1 -1
  35. package/packages/game/dist/types/entities/system.d.ts +2 -0
  36. package/packages/game/dist/types/entities/system.d.ts.map +1 -1
  37. package/packages/game/dist/types/entities/thinkScheduler.d.ts +1 -1
  38. package/packages/game/dist/types/entities/thinkScheduler.d.ts.map +1 -1
  39. package/packages/game/dist/types/imports.d.ts +1 -0
  40. package/packages/game/dist/types/imports.d.ts.map +1 -1
  41. package/packages/game/dist/types/index.d.ts +4 -1
  42. package/packages/game/dist/types/index.d.ts.map +1 -1
  43. package/packages/game/dist/types/physics/movement.d.ts +2 -0
  44. package/packages/game/dist/types/physics/movement.d.ts.map +1 -1
  45. package/packages/shared/dist/browser/index.global.js +1 -1
  46. package/packages/shared/dist/browser/index.global.js.map +1 -1
  47. package/packages/shared/dist/cjs/index.cjs +18 -8
  48. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  49. package/packages/shared/dist/esm/index.js +16 -8
  50. package/packages/shared/dist/esm/index.js.map +1 -1
  51. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  52. package/packages/shared/dist/types/math/vec3.d.ts +2 -0
  53. package/packages/shared/dist/types/math/vec3.d.ts.map +1 -1
  54. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -161,6 +161,12 @@ function lengthSquaredVec3(a) {
161
161
  function lengthVec3(a) {
162
162
  return Math.sqrt(lengthSquaredVec3(a));
163
163
  }
164
+ function distance(a, b) {
165
+ return lengthVec3(subtractVec3(a, b));
166
+ }
167
+ function vec3Equals(a, b) {
168
+ return a.x === b.x && a.y === b.y && a.z === b.z;
169
+ }
164
170
  function normalizeVec3(a) {
165
171
  const len = lengthVec3(a);
166
172
  return len === 0 ? a : scaleVec3(a, 1 / len);
@@ -746,9 +752,13 @@ var Entity = class {
746
752
  this.velocity = copyVec3();
747
753
  this.avelocity = copyVec3();
748
754
  this.angles = copyVec3();
755
+ this.pos1 = copyVec3();
756
+ this.pos2 = copyVec3();
749
757
  this.viewheight = 0;
750
758
  this.mins = copyVec3();
751
759
  this.maxs = copyVec3();
760
+ this.absmin = copyVec3();
761
+ this.absmax = copyVec3();
752
762
  this.size = copyVec3();
753
763
  this.mass = 0;
754
764
  this.gravity = 1;
@@ -770,6 +780,8 @@ var Entity = class {
770
780
  this.wait = 0;
771
781
  this.delay = 0;
772
782
  this.timestamp = 0;
783
+ this.lip = 0;
784
+ this.state = 0;
773
785
  this.sounds = 0;
774
786
  this.noise_index = 0;
775
787
  this.fly_sound_debounce_time = 0;
@@ -820,9 +832,13 @@ var Entity = class {
820
832
  this.velocity = copyVec3();
821
833
  this.avelocity = copyVec3();
822
834
  this.angles = copyVec3();
835
+ this.pos1 = copyVec3();
836
+ this.pos2 = copyVec3();
823
837
  this.viewheight = 0;
824
838
  this.mins = copyVec3();
825
839
  this.maxs = copyVec3();
840
+ this.absmin = copyVec3();
841
+ this.absmax = copyVec3();
826
842
  this.size = copyVec3();
827
843
  this.mass = 0;
828
844
  this.gravity = 1;
@@ -844,6 +860,8 @@ var Entity = class {
844
860
  this.wait = 0;
845
861
  this.delay = 0;
846
862
  this.timestamp = 0;
863
+ this.lip = 0;
864
+ this.state = 0;
847
865
  this.sounds = 0;
848
866
  this.noise_index = 0;
849
867
  this.fly_sound_debounce_time = 0;
@@ -865,6 +883,7 @@ var Entity = class {
865
883
  this.think = void 0;
866
884
  this.touch = void 0;
867
885
  this.use = void 0;
886
+ this.blocked = void 0;
868
887
  this.pain = void 0;
869
888
  this.die = void 0;
870
889
  this.activator = null;
@@ -895,9 +914,13 @@ var ENTITY_FIELD_METADATA = [
895
914
  { name: "velocity", type: "vec3", save: true },
896
915
  { name: "avelocity", type: "vec3", save: true },
897
916
  { name: "angles", type: "vec3", save: true },
917
+ { name: "pos1", type: "vec3", save: true },
918
+ { name: "pos2", type: "vec3", save: true },
898
919
  { name: "viewheight", type: "int", save: true },
899
920
  { name: "mins", type: "vec3", save: true },
900
921
  { name: "maxs", type: "vec3", save: true },
922
+ { name: "absmin", type: "vec3", save: true },
923
+ { name: "absmax", type: "vec3", save: true },
901
924
  { name: "size", type: "vec3", save: true },
902
925
  { name: "mass", type: "int", save: true },
903
926
  { name: "gravity", type: "float", save: true },
@@ -918,6 +941,8 @@ var ENTITY_FIELD_METADATA = [
918
941
  { name: "wait", type: "float", save: true },
919
942
  { name: "delay", type: "float", save: true },
920
943
  { name: "timestamp", type: "float", save: true },
944
+ { name: "lip", type: "int", save: true },
945
+ { name: "state", type: "int", save: true },
921
946
  { name: "sounds", type: "int", save: true },
922
947
  { name: "noise_index", type: "int", save: true },
923
948
  { name: "fly_sound_debounce_time", type: "float", save: true },
@@ -942,6 +967,7 @@ var ENTITY_FIELD_METADATA = [
942
967
  { name: "think", type: "callback", save: false },
943
968
  { name: "touch", type: "callback", save: false },
944
969
  { name: "use", type: "callback", save: false },
970
+ { name: "blocked", type: "callback", save: false },
945
971
  { name: "pain", type: "callback", save: false },
946
972
  { name: "die", type: "callback", save: false }
947
973
  ];
@@ -975,6 +1001,108 @@ function runProjectileMovement(ent, imports, frametime) {
975
1001
  const traceResult = imports.trace(ent.origin, ent.mins, ent.maxs, end, ent, ent.clipmask);
976
1002
  ent.origin = traceResult.endpos;
977
1003
  }
1004
+ function testEntityPosition(ent, imports) {
1005
+ const trace = imports.trace(ent.origin, ent.mins, ent.maxs, ent.origin, ent, ent.clipmask);
1006
+ if (trace.startsolid || trace.allsolid) {
1007
+ return false;
1008
+ }
1009
+ return true;
1010
+ }
1011
+ function runPush(pusher, system, imports, frametime) {
1012
+ const move = {
1013
+ x: pusher.velocity.x * frametime,
1014
+ y: pusher.velocity.y * frametime,
1015
+ z: pusher.velocity.z * frametime
1016
+ };
1017
+ const amove = {
1018
+ x: pusher.avelocity.x * frametime,
1019
+ y: pusher.avelocity.y * frametime,
1020
+ z: pusher.avelocity.z * frametime
1021
+ };
1022
+ const mins = {
1023
+ x: Math.min(pusher.absmin.x, pusher.absmin.x + move.x) - 2,
1024
+ // Expand slightly? Quake2 does 'mins - move - 2' logic implicitly via box check
1025
+ y: Math.min(pusher.absmin.y, pusher.absmin.y + move.y) - 2,
1026
+ z: Math.min(pusher.absmin.z, pusher.absmin.z + move.z) - 2
1027
+ };
1028
+ const maxs = {
1029
+ x: Math.max(pusher.absmax.x, pusher.absmax.x + move.x) + 2,
1030
+ y: Math.max(pusher.absmax.y, pusher.absmax.y + move.y) + 2,
1031
+ z: Math.max(pusher.absmax.z, pusher.absmax.z + move.z) + 2
1032
+ };
1033
+ const pushed = [];
1034
+ pushed.push({
1035
+ ent: pusher,
1036
+ origin: { ...pusher.origin },
1037
+ angles: { ...pusher.angles },
1038
+ ground: pusher.groundentity
1039
+ });
1040
+ pusher.origin = {
1041
+ x: pusher.origin.x + move.x,
1042
+ y: pusher.origin.y + move.y,
1043
+ z: pusher.origin.z + move.z
1044
+ };
1045
+ pusher.angles = {
1046
+ x: pusher.angles.x + amove.x,
1047
+ y: pusher.angles.y + amove.y,
1048
+ z: pusher.angles.z + amove.z
1049
+ };
1050
+ imports.linkentity(pusher);
1051
+ if (!testEntityPosition(pusher, imports)) {
1052
+ pusher.origin = pushed[0].origin;
1053
+ pusher.angles = pushed[0].angles;
1054
+ imports.linkentity(pusher);
1055
+ return false;
1056
+ }
1057
+ const candidates = [];
1058
+ system.forEachEntity((check) => {
1059
+ if (check === pusher) return;
1060
+ if (check.solid === 0 /* Not */ || check.solid === 1 /* Trigger */) return;
1061
+ if (check.absmin.x >= maxs.x || check.absmax.x <= mins.x || check.absmin.y >= maxs.y || check.absmax.y <= mins.y || check.absmin.z >= maxs.z || check.absmax.z <= mins.z) {
1062
+ return;
1063
+ }
1064
+ candidates.push(check);
1065
+ });
1066
+ for (const ent of candidates) {
1067
+ let moveEntity = false;
1068
+ if (ent.groundentity === pusher) {
1069
+ moveEntity = true;
1070
+ } else {
1071
+ if (ent.absmin.x < pusher.absmax.x && ent.absmax.x > pusher.absmin.x && ent.absmin.y < pusher.absmax.y && ent.absmax.y > pusher.absmin.y && ent.absmin.z < pusher.absmax.z && ent.absmax.z > pusher.absmin.z) {
1072
+ moveEntity = true;
1073
+ }
1074
+ }
1075
+ if (moveEntity) {
1076
+ pushed.push({
1077
+ ent,
1078
+ origin: { ...ent.origin },
1079
+ angles: { ...ent.angles },
1080
+ ground: ent.groundentity
1081
+ });
1082
+ ent.origin = {
1083
+ x: ent.origin.x + move.x,
1084
+ y: ent.origin.y + move.y,
1085
+ z: ent.origin.z + move.z
1086
+ };
1087
+ imports.linkentity(ent);
1088
+ if (!testEntityPosition(ent, imports)) {
1089
+ if (pusher.blocked) {
1090
+ pusher.blocked(pusher, ent);
1091
+ }
1092
+ if (ent.solid !== 0 /* Not */ && (!ent.health || ent.health > 0)) {
1093
+ for (let i = pushed.length - 1; i >= 0; i--) {
1094
+ const p = pushed[i];
1095
+ p.ent.origin = p.origin;
1096
+ p.ent.angles = p.angles;
1097
+ p.ent.groundentity = p.ground, imports.linkentity(p.ent);
1098
+ }
1099
+ return false;
1100
+ }
1101
+ }
1102
+ }
1103
+ }
1104
+ return true;
1105
+ }
978
1106
 
979
1107
  // src/entities/pool.ts
980
1108
  var MAX_EDICTS = 2048;
@@ -1189,7 +1317,7 @@ var ThinkScheduler = class {
1189
1317
  this.schedule(entity, entry.time);
1190
1318
  }
1191
1319
  }
1192
- runDueThinks(currentTimeSeconds) {
1320
+ runDueThinks(currentTimeSeconds, context) {
1193
1321
  while (this.queue.length > 0) {
1194
1322
  const next = this.queue[0];
1195
1323
  if (next.time > currentTimeSeconds) {
@@ -1206,7 +1334,7 @@ var ThinkScheduler = class {
1206
1334
  if (entity.nextthink !== time) {
1207
1335
  continue;
1208
1336
  }
1209
- entity.think(entity);
1337
+ entity.think(entity, context);
1210
1338
  }
1211
1339
  }
1212
1340
  };
@@ -1279,7 +1407,19 @@ var EntitySystem = class {
1279
1407
  contents: 0,
1280
1408
  ent: null
1281
1409
  }),
1282
- pointcontents: () => 0
1410
+ pointcontents: () => 0,
1411
+ linkentity: (ent) => {
1412
+ ent.absmin = {
1413
+ x: ent.origin.x + ent.mins.x,
1414
+ y: ent.origin.y + ent.mins.y,
1415
+ z: ent.origin.z + ent.mins.z
1416
+ };
1417
+ ent.absmax = {
1418
+ x: ent.origin.x + ent.maxs.x,
1419
+ y: ent.origin.y + ent.maxs.y,
1420
+ z: ent.origin.z + ent.maxs.z
1421
+ };
1422
+ }
1283
1423
  };
1284
1424
  this.gravity = gravity || { x: 0, y: 0, z: 0 };
1285
1425
  this.callbackToName = /* @__PURE__ */ new Map();
@@ -1329,6 +1469,9 @@ var EntitySystem = class {
1329
1469
  sound(entity, channel, sound, volume, attenuation, timeofs) {
1330
1470
  this.engine.sound?.(entity, channel, sound, volume, attenuation, timeofs);
1331
1471
  }
1472
+ modelIndex(model) {
1473
+ return this.engine.modelIndex?.(model) || 0;
1474
+ }
1332
1475
  scheduleThink(entity, nextThinkSeconds) {
1333
1476
  this.thinkScheduler.schedule(entity, nextThinkSeconds);
1334
1477
  }
@@ -1357,6 +1500,18 @@ var EntitySystem = class {
1357
1500
  }
1358
1501
  return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
1359
1502
  }
1503
+ findByRadius(origin, radius) {
1504
+ const matches = [];
1505
+ for (const entity of this.pool) {
1506
+ if (entity.inUse && !entity.freePending) {
1507
+ const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
1508
+ if (distance2 <= radius) {
1509
+ matches.push(entity);
1510
+ }
1511
+ }
1512
+ }
1513
+ return matches;
1514
+ }
1360
1515
  pickTarget(targetname) {
1361
1516
  if (!targetname) {
1362
1517
  return null;
@@ -1405,7 +1560,7 @@ var EntitySystem = class {
1405
1560
  this.useTargetsImmediate(entity, activator ?? entity);
1406
1561
  }
1407
1562
  runFrame() {
1408
- this.thinkScheduler.runDueThinks(this.currentTimeSeconds);
1563
+ this.thinkScheduler.runDueThinks(this.currentTimeSeconds, this);
1409
1564
  for (const ent of this.pool) {
1410
1565
  if (!ent.inUse || ent.freePending) {
1411
1566
  continue;
@@ -1425,6 +1580,9 @@ var EntitySystem = class {
1425
1580
  runProjectileMovement(ent, this.imports, frametime);
1426
1581
  ent.timestamp = this.currentTimeSeconds;
1427
1582
  break;
1583
+ case 2 /* Push */:
1584
+ runPush(ent, this, this.imports, frametime);
1585
+ break;
1428
1586
  }
1429
1587
  }
1430
1588
  this.runTouches();
@@ -2993,6 +3151,112 @@ function registerItemSpawns(game, registry) {
2993
3151
  }
2994
3152
  }
2995
3153
 
3154
+ // src/entities/funcs.ts
3155
+ function door_blocked(self, other) {
3156
+ if (other && other.takedamage) {
3157
+ const damage = self.dmg || 2;
3158
+ other.health -= damage;
3159
+ }
3160
+ if (self.state === 1 /* Opening */) {
3161
+ self.state = 3 /* Closing */;
3162
+ self.think = door_go_down;
3163
+ } else if (self.state === 3 /* Closing */) {
3164
+ self.state = 1 /* Opening */;
3165
+ self.think = door_go_up;
3166
+ }
3167
+ }
3168
+ function door_go_down(door, context) {
3169
+ if (vec3Equals(door.origin, door.pos1)) {
3170
+ door.state = 2 /* Closed */;
3171
+ door.velocity = { x: 0, y: 0, z: 0 };
3172
+ return;
3173
+ }
3174
+ const move = distance(door.origin, door.pos1);
3175
+ const speed = Math.min(door.speed, move);
3176
+ door.velocity = {
3177
+ x: (door.pos1.x - door.origin.x) / distance(door.pos1, door.origin) * door.speed,
3178
+ y: (door.pos1.y - door.origin.y) / distance(door.pos1, door.origin) * door.speed,
3179
+ z: (door.pos1.z - door.origin.z) / distance(door.pos1, door.origin) * door.speed
3180
+ };
3181
+ if (move <= door.speed * 0.1) {
3182
+ door.velocity = {
3183
+ x: (door.pos1.x - door.origin.x) / 0.1,
3184
+ y: (door.pos1.y - door.origin.y) / 0.1,
3185
+ z: (door.pos1.z - door.origin.z) / 0.1
3186
+ };
3187
+ }
3188
+ context?.scheduleThink(door, context.timeSeconds + 0.1);
3189
+ }
3190
+ function door_go_up(door, context) {
3191
+ if (vec3Equals(door.origin, door.pos2)) {
3192
+ door.state = 0 /* Open */;
3193
+ door.velocity = { x: 0, y: 0, z: 0 };
3194
+ context?.scheduleThink(door, context.timeSeconds + door.wait);
3195
+ door.think = door_go_down;
3196
+ return;
3197
+ }
3198
+ const move = distance(door.origin, door.pos2);
3199
+ door.velocity = {
3200
+ x: (door.pos2.x - door.origin.x) / distance(door.pos2, door.origin) * door.speed,
3201
+ y: (door.pos2.y - door.origin.y) / distance(door.pos2, door.origin) * door.speed,
3202
+ z: (door.pos2.z - door.origin.z) / distance(door.pos2, door.origin) * door.speed
3203
+ };
3204
+ if (move <= door.speed * 0.1) {
3205
+ door.velocity = {
3206
+ x: (door.pos2.x - door.origin.x) / 0.1,
3207
+ y: (door.pos2.y - door.origin.y) / 0.1,
3208
+ z: (door.pos2.z - door.origin.z) / 0.1
3209
+ };
3210
+ }
3211
+ context?.scheduleThink(door, context.timeSeconds + 0.1);
3212
+ }
3213
+ var func_door = (entity, context) => {
3214
+ entity.movedir = setMovedir(entity.angles);
3215
+ if (!entity.speed) {
3216
+ entity.speed = 100;
3217
+ }
3218
+ if (!entity.wait) {
3219
+ entity.wait = 3;
3220
+ }
3221
+ if (!entity.lip) {
3222
+ entity.lip = 8;
3223
+ }
3224
+ if (!entity.dmg) {
3225
+ entity.dmg = 2;
3226
+ }
3227
+ if (!entity.health) {
3228
+ entity.health = 0;
3229
+ }
3230
+ entity.solid = 3 /* Bsp */;
3231
+ entity.movetype = 2 /* Push */;
3232
+ entity.blocked = door_blocked;
3233
+ entity.state = 2 /* Closed */;
3234
+ entity.pos1 = { ...entity.origin };
3235
+ const move = entity.movedir.x * (Math.abs(entity.maxs.x - entity.mins.x) - entity.lip) + entity.movedir.y * (Math.abs(entity.maxs.y - entity.mins.y) - entity.lip) + entity.movedir.z * (Math.abs(entity.maxs.z - entity.mins.z) - entity.lip);
3236
+ entity.pos2 = {
3237
+ x: entity.pos1.x + entity.movedir.x * move,
3238
+ y: entity.pos1.y + entity.movedir.y * move,
3239
+ z: entity.pos1.z + entity.movedir.z * move
3240
+ };
3241
+ entity.use = (self) => {
3242
+ if (self.state !== 2 /* Closed */) return;
3243
+ self.state = 1 /* Opening */;
3244
+ self.think = door_go_up;
3245
+ context.entities.scheduleThink(self, context.entities.timeSeconds + 0.1);
3246
+ };
3247
+ };
3248
+ var func_button = (entity, context) => {
3249
+ entity.solid = 3 /* Bsp */;
3250
+ entity.movetype = 2 /* Push */;
3251
+ entity.use = (self) => {
3252
+ context.entities.useTargets(self, self);
3253
+ };
3254
+ };
3255
+ function registerFuncSpawns(registry) {
3256
+ registry.register("func_door", func_door);
3257
+ registry.register("func_button", func_button);
3258
+ }
3259
+
2996
3260
  // src/entities/spawn.ts
2997
3261
  var FIELD_LOOKUP = new Map(
2998
3262
  ENTITY_FIELD_METADATA.map((field) => [field.name, field])
@@ -3204,6 +3468,7 @@ function registerDefaultSpawns(game, registry) {
3204
3468
  registerTargetSpawns(registry);
3205
3469
  registerMiscSpawns(registry);
3206
3470
  registerItemSpawns(game, registry);
3471
+ registerFuncSpawns(registry);
3207
3472
  }
3208
3473
  function createDefaultSpawnRegistry(game) {
3209
3474
  const registry = new SpawnRegistry();
@@ -3395,19 +3660,19 @@ var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
3395
3660
  })(TraceMask || {});
3396
3661
 
3397
3662
  // src/ai/movement.ts
3398
- function yawVector(yawDegrees, distance) {
3399
- if (distance === 0) {
3663
+ function yawVector(yawDegrees, distance2) {
3664
+ if (distance2 === 0) {
3400
3665
  return { x: 0, y: 0, z: 0 };
3401
3666
  }
3402
3667
  const radians = degToRad(yawDegrees);
3403
3668
  return {
3404
- x: Math.cos(radians) * distance,
3405
- y: Math.sin(radians) * distance,
3669
+ x: Math.cos(radians) * distance2,
3670
+ y: Math.sin(radians) * distance2,
3406
3671
  z: 0
3407
3672
  };
3408
3673
  }
3409
- function walkMove(self, yawDegrees, distance) {
3410
- const delta = yawVector(yawDegrees, distance);
3674
+ function walkMove(self, yawDegrees, distance2) {
3675
+ const delta = yawVector(yawDegrees, distance2);
3411
3676
  const origin = self.origin;
3412
3677
  origin.x += delta.x;
3413
3678
  origin.y += delta.y;
@@ -3440,8 +3705,8 @@ function facingIdeal(self) {
3440
3705
  }
3441
3706
  return !(delta > 45 && delta < 315);
3442
3707
  }
3443
- function ai_move(self, distance) {
3444
- walkMove(self, self.angles.y, distance);
3708
+ function ai_move(self, distance2) {
3709
+ walkMove(self, self.angles.y, distance2);
3445
3710
  }
3446
3711
  function setIdealYawTowards(self, target) {
3447
3712
  if (!target) return;
@@ -3455,40 +3720,40 @@ function setIdealYawTowards(self, target) {
3455
3720
  function ai_stand(self, deltaSeconds) {
3456
3721
  changeYaw(self, deltaSeconds);
3457
3722
  }
3458
- function ai_walk(self, distance, deltaSeconds) {
3723
+ function ai_walk(self, distance2, deltaSeconds) {
3459
3724
  setIdealYawTowards(self, self.goalentity);
3460
3725
  changeYaw(self, deltaSeconds);
3461
- if (distance !== 0) {
3462
- walkMove(self, self.angles.y, distance);
3726
+ if (distance2 !== 0) {
3727
+ walkMove(self, self.angles.y, distance2);
3463
3728
  }
3464
3729
  }
3465
- function ai_turn(self, distance, deltaSeconds) {
3466
- if (distance !== 0) {
3467
- walkMove(self, self.angles.y, distance);
3730
+ function ai_turn(self, distance2, deltaSeconds) {
3731
+ if (distance2 !== 0) {
3732
+ walkMove(self, self.angles.y, distance2);
3468
3733
  }
3469
3734
  changeYaw(self, deltaSeconds);
3470
3735
  }
3471
- function ai_run(self, distance, deltaSeconds) {
3736
+ function ai_run(self, distance2, deltaSeconds) {
3472
3737
  setIdealYawTowards(self, self.enemy ?? self.goalentity);
3473
3738
  changeYaw(self, deltaSeconds);
3474
- if (distance !== 0) {
3475
- walkMove(self, self.angles.y, distance);
3739
+ if (distance2 !== 0) {
3740
+ walkMove(self, self.angles.y, distance2);
3476
3741
  }
3477
3742
  }
3478
- function ai_face(self, enemy, distance, deltaSeconds) {
3743
+ function ai_face(self, enemy, distance2, deltaSeconds) {
3479
3744
  if (enemy) {
3480
3745
  setIdealYawTowards(self, enemy);
3481
3746
  }
3482
3747
  changeYaw(self, deltaSeconds);
3483
- if (distance !== 0) {
3484
- walkMove(self, self.angles.y, distance);
3748
+ if (distance2 !== 0) {
3749
+ walkMove(self, self.angles.y, distance2);
3485
3750
  }
3486
3751
  }
3487
- function ai_charge(self, distance, deltaSeconds) {
3752
+ function ai_charge(self, distance2, deltaSeconds) {
3488
3753
  setIdealYawTowards(self, self.enemy);
3489
3754
  changeYaw(self, deltaSeconds);
3490
- if (distance !== 0) {
3491
- walkMove(self, self.angles.y, distance);
3755
+ if (distance2 !== 0) {
3756
+ walkMove(self, self.angles.y, distance2);
3492
3757
  }
3493
3758
  }
3494
3759
 
@@ -3520,14 +3785,14 @@ function rangeTo(self, other) {
3520
3785
  const distanceSquared = distanceBetweenBoxesSquared(a.mins, a.maxs, b.mins, b.maxs);
3521
3786
  return Math.sqrt(distanceSquared);
3522
3787
  }
3523
- function classifyRange(distance) {
3524
- if (distance <= RANGE_MELEE) {
3788
+ function classifyRange(distance2) {
3789
+ if (distance2 <= RANGE_MELEE) {
3525
3790
  return "melee" /* Melee */;
3526
3791
  }
3527
- if (distance <= RANGE_NEAR) {
3792
+ if (distance2 <= RANGE_NEAR) {
3528
3793
  return "near" /* Near */;
3529
3794
  }
3530
- if (distance <= RANGE_MID) {
3795
+ if (distance2 <= RANGE_MID) {
3531
3796
  return "mid" /* Mid */;
3532
3797
  }
3533
3798
  return "far" /* Far */;
@@ -3607,8 +3872,8 @@ function foundTarget(self, level, options) {
3607
3872
  self.monsterinfo.run?.(self);
3608
3873
  }
3609
3874
  function classifyClientVisibility(self, other, level, trace) {
3610
- const distance = rangeTo(self, other);
3611
- const range = classifyRange(distance);
3875
+ const distance2 = rangeTo(self, other);
3876
+ const range = classifyRange(distance2);
3612
3877
  if (range === "far" /* Far */) return false;
3613
3878
  if (other.light_level <= 5) return false;
3614
3879
  if (!visible(self, other, trace, { throughGlass: false })) return false;
@@ -4495,11 +4760,11 @@ function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, d
4495
4760
  }
4496
4761
  const entCenter = ent.mins && ent.maxs ? closestPointToBox(inflictorCenter, addVec3(ent.origin, ent.mins), addVec3(ent.origin, ent.maxs)) : targetCenter(ent);
4497
4762
  const toTarget = subtractVec3(inflictorCenter, entCenter);
4498
- const distance = lengthVec3(toTarget);
4499
- if (radius > 0 && distance > radius) {
4763
+ const distance2 = lengthVec3(toTarget);
4764
+ if (radius > 0 && distance2 > radius) {
4500
4765
  continue;
4501
4766
  }
4502
- const points = damage - 0.5 * distance;
4767
+ const points = damage - 0.5 * distance2;
4503
4768
  if (points <= 0) {
4504
4769
  continue;
4505
4770
  }
@@ -4923,11 +5188,23 @@ function getWeaponState(playerStates, weaponId) {
4923
5188
 
4924
5189
  // src/index.ts
4925
5190
  var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
4926
- function createGame(imports, engine, options) {
5191
+ function createGame({ trace, pointcontents }, engine, options) {
4927
5192
  const gravity = options.gravity;
4928
5193
  const levelClock = new LevelClock();
4929
5194
  const frameLoop = new GameFrameLoop();
4930
- const entities = new EntitySystem(engine, imports, gravity);
5195
+ const linkentity = (ent) => {
5196
+ ent.absmin = {
5197
+ x: ent.origin.x + ent.mins.x,
5198
+ y: ent.origin.y + ent.mins.y,
5199
+ z: ent.origin.z + ent.mins.z
5200
+ };
5201
+ ent.absmax = {
5202
+ x: ent.origin.x + ent.maxs.x,
5203
+ y: ent.origin.y + ent.maxs.y,
5204
+ z: ent.origin.z + ent.maxs.z
5205
+ };
5206
+ };
5207
+ const entities = new EntitySystem(engine, { trace, pointcontents, linkentity }, gravity);
4931
5208
  frameLoop.addStage("prep", (context) => {
4932
5209
  levelClock.tick(context);
4933
5210
  entities.beginFrame(levelClock.current.timeSeconds);
@@ -5005,7 +5282,7 @@ function createGame(imports, engine, options) {
5005
5282
  };
5006
5283
  const playerState = { origin: player.origin, velocity: player.velocity, onGround: false, waterLevel: 0, mins: player.mins, maxs: player.maxs, damageAlpha: 0, damageIndicators: [], viewAngles: player.angles };
5007
5284
  const traceAdapter = (start, end) => {
5008
- const result = imports.trace(start, player.mins, player.maxs, end, player, 268435457);
5285
+ const result = trace(start, player.mins, player.maxs, end, player, 268435457);
5009
5286
  return {
5010
5287
  fraction: result.fraction,
5011
5288
  endpos: result.endpos,
@@ -5014,7 +5291,7 @@ function createGame(imports, engine, options) {
5014
5291
  planeNormal: result.plane?.normal
5015
5292
  };
5016
5293
  };
5017
- const pointContentsAdapter = (point) => imports.pointcontents(point);
5294
+ const pointContentsAdapter = (point) => pointcontents(point);
5018
5295
  const newState = applyPmove(playerState, pcmd, traceAdapter, pointContentsAdapter);
5019
5296
  player.origin = newState.origin;
5020
5297
  player.velocity = newState.velocity;
@@ -5028,6 +5305,7 @@ function createGame(imports, engine, options) {
5028
5305
  centerprintf(entity, message) {
5029
5306
  engine.centerprintf?.(entity, message);
5030
5307
  },
5308
+ trace,
5031
5309
  get time() {
5032
5310
  return levelClock.current.timeSeconds;
5033
5311
  }