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.
@@ -2374,15 +2374,16 @@ function checkTriggers(ent, system) {
2374
2374
  if (ent.movetype === 0 /* None */) {
2375
2375
  return;
2376
2376
  }
2377
- system.forEachEntity((other) => {
2378
- if (other === ent) return;
2379
- if (other.solid !== 1 /* Trigger */) return;
2380
- if (!other.touch) return;
2381
- if (ent.absmax.x < other.absmin.x || ent.absmin.x > other.absmax.x) return;
2382
- if (ent.absmax.y < other.absmin.y || ent.absmin.y > other.absmax.y) return;
2383
- if (ent.absmax.z < other.absmin.z || ent.absmin.z > other.absmax.z) return;
2377
+ const candidates = system.findInBox(ent.absmin, ent.absmax);
2378
+ for (const other of candidates) {
2379
+ if (other === ent) continue;
2380
+ if (other.solid !== 1 /* Trigger */) continue;
2381
+ if (!other.touch) continue;
2382
+ if (ent.absmax.x < other.absmin.x || ent.absmin.x > other.absmax.x) continue;
2383
+ if (ent.absmax.y < other.absmin.y || ent.absmin.y > other.absmax.y) continue;
2384
+ if (ent.absmax.z < other.absmin.z || ent.absmin.z > other.absmax.z) continue;
2384
2385
  other.touch(other, ent);
2385
- });
2386
+ }
2386
2387
  }
2387
2388
 
2388
2389
  // src/physics/movement.ts
@@ -2702,6 +2703,9 @@ var EntityPool = class {
2702
2703
  }
2703
2704
  return count;
2704
2705
  }
2706
+ getByIndex(index) {
2707
+ return this.entities[index];
2708
+ }
2705
2709
  [Symbol.iterator]() {
2706
2710
  let current = this.activeHead;
2707
2711
  return {
@@ -2963,7 +2967,7 @@ var EntitySystem = class {
2963
2967
  this.thinkScheduler = new ThinkScheduler();
2964
2968
  this.engine = engine;
2965
2969
  this.deathmatch = deathmatch ?? false;
2966
- this.imports = imports || {
2970
+ const defaultImports = {
2967
2971
  trace: () => ({
2968
2972
  allsolid: false,
2969
2973
  startsolid: false,
@@ -2987,11 +2991,14 @@ var EntitySystem = class {
2987
2991
  z: ent.origin.z + ent.maxs.z
2988
2992
  };
2989
2993
  },
2994
+ areaEdicts: () => null,
2995
+ // Default to null to signal fallback
2990
2996
  multicast: () => {
2991
2997
  },
2992
2998
  unicast: () => {
2993
2999
  }
2994
3000
  };
3001
+ this.imports = { ...defaultImports, ...imports };
2995
3002
  this.gravity = gravity || { x: 0, y: 0, z: 0 };
2996
3003
  this.callbackToName = /* @__PURE__ */ new Map();
2997
3004
  if (callbackRegistry) {
@@ -3109,14 +3116,37 @@ var EntitySystem = class {
3109
3116
  }
3110
3117
  return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
3111
3118
  }
3119
+ findInBox(mins, maxs) {
3120
+ const indices = this.imports.areaEdicts(mins, maxs);
3121
+ if (indices === null) {
3122
+ const results2 = [];
3123
+ const bounds = { min: mins, max: maxs };
3124
+ for (const entity of this.pool) {
3125
+ if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) continue;
3126
+ if (boundsIntersect(bounds, computeBounds(entity))) {
3127
+ results2.push(entity);
3128
+ }
3129
+ }
3130
+ return results2;
3131
+ }
3132
+ const results = [];
3133
+ for (const index of indices) {
3134
+ const entity = this.pool.getByIndex(index);
3135
+ if (entity && entity.inUse && !entity.freePending) {
3136
+ results.push(entity);
3137
+ }
3138
+ }
3139
+ return results;
3140
+ }
3112
3141
  findByRadius(origin, radius) {
3142
+ const mins = { x: origin.x - radius, y: origin.y - radius, z: origin.z - radius };
3143
+ const maxs = { x: origin.x + radius, y: origin.y + radius, z: origin.z + radius };
3144
+ const candidates = this.findInBox(mins, maxs);
3113
3145
  const matches = [];
3114
- for (const entity of this.pool) {
3115
- if (entity.inUse && !entity.freePending) {
3116
- const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
3117
- if (distance2 <= radius) {
3118
- matches.push(entity);
3119
- }
3146
+ for (const entity of candidates) {
3147
+ const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
3148
+ if (distance2 <= radius) {
3149
+ matches.push(entity);
3120
3150
  }
3121
3151
  }
3122
3152
  return matches;
@@ -3326,35 +3356,19 @@ var EntitySystem = class {
3326
3356
  const world = this.pool.world;
3327
3357
  const activeEntities = [];
3328
3358
  for (const entity of this.pool) {
3329
- if (entity === world) {
3330
- continue;
3331
- }
3332
- if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) {
3333
- continue;
3334
- }
3359
+ if (entity === world) continue;
3360
+ if (!entity.inUse || entity.freePending || entity.solid === 0 /* Not */) continue;
3335
3361
  activeEntities.push(entity);
3336
3362
  }
3337
- for (let i = 0; i < activeEntities.length; i += 1) {
3338
- const first = activeEntities[i];
3339
- let firstBounds = null;
3340
- for (let j = i + 1; j < activeEntities.length; j += 1) {
3341
- const second = activeEntities[j];
3342
- if (!first.touch && !second.touch) {
3343
- continue;
3344
- }
3345
- if (!firstBounds) {
3346
- firstBounds = computeBounds(first);
3347
- }
3363
+ for (const first of activeEntities) {
3364
+ const candidates = this.findInBox(first.absmin, first.absmax);
3365
+ const firstBounds = computeBounds(first);
3366
+ for (const second of candidates) {
3367
+ if (first === second) continue;
3368
+ if (!first.touch) continue;
3348
3369
  const secondBounds = computeBounds(second);
3349
- if (!boundsIntersect(firstBounds, secondBounds)) {
3350
- continue;
3351
- }
3352
- if (first.touch) {
3353
- first.touch(first, second);
3354
- }
3355
- if (second.touch) {
3356
- second.touch(second, first);
3357
- }
3370
+ if (!boundsIntersect(firstBounds, secondBounds)) continue;
3371
+ first.touch(first, second);
3358
3372
  }
3359
3373
  }
3360
3374
  }
@@ -13019,13 +13033,29 @@ var WEAPONS = {
13019
13033
 
13020
13034
  // src/index.ts
13021
13035
  var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
13022
- function createGame({ trace, pointcontents, multicast, unicast }, engine, options) {
13036
+ function createGame(imports, engine, options) {
13023
13037
  const gravity = options.gravity;
13024
13038
  const deathmatch = options.deathmatch ?? false;
13025
13039
  const levelClock = new LevelClock();
13026
13040
  const frameLoop = new GameFrameLoop();
13027
13041
  const rng = options.random ?? new RandomGenerator();
13028
- const linkentity = (ent) => {
13042
+ const trace = imports.trace || (() => ({
13043
+ allsolid: false,
13044
+ startsolid: false,
13045
+ fraction: 1,
13046
+ endpos: { x: 0, y: 0, z: 0 },
13047
+ plane: null,
13048
+ surfaceFlags: 0,
13049
+ contents: 0,
13050
+ ent: null
13051
+ }));
13052
+ const pointcontents = imports.pointcontents || (() => 0);
13053
+ const multicast = imports.multicast || (() => {
13054
+ });
13055
+ const unicast = imports.unicast || (() => {
13056
+ });
13057
+ const linkentity = imports.linkentity;
13058
+ const wrappedLinkEntity = (ent) => {
13029
13059
  ent.absmin = {
13030
13060
  x: ent.origin.x + ent.mins.x,
13031
13061
  y: ent.origin.y + ent.mins.y,
@@ -13036,8 +13066,19 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
13036
13066
  y: ent.origin.y + ent.maxs.y,
13037
13067
  z: ent.origin.z + ent.maxs.z
13038
13068
  };
13069
+ if (linkentity) {
13070
+ linkentity(ent);
13071
+ }
13072
+ };
13073
+ const systemImports = {
13074
+ ...imports,
13075
+ trace,
13076
+ pointcontents,
13077
+ linkentity: wrappedLinkEntity,
13078
+ multicast,
13079
+ unicast
13039
13080
  };
13040
- const entities = new EntitySystem(engine, { trace, pointcontents, linkentity, multicast, unicast }, gravity, void 0, void 0, deathmatch);
13081
+ const entities = new EntitySystem(engine, systemImports, gravity, void 0, void 0, deathmatch);
13041
13082
  frameLoop.addStage("prep", (context) => {
13042
13083
  levelClock.tick(context);
13043
13084
  entities.beginFrame(levelClock.current.timeSeconds);