quake2ts 0.0.187 → 0.0.188

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.
@@ -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
  }
@@ -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);