quake2ts 0.0.45 → 0.0.47

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 (52) hide show
  1. package/apps/viewer/dist/browser/index.global.js +1 -1
  2. package/apps/viewer/dist/browser/index.global.js.map +1 -1
  3. package/apps/viewer/dist/cjs/index.cjs +14 -3
  4. package/apps/viewer/dist/cjs/index.cjs.map +1 -1
  5. package/apps/viewer/dist/esm/index.js +14 -3
  6. package/apps/viewer/dist/esm/index.js.map +1 -1
  7. package/apps/viewer/dist/tsconfig.tsbuildinfo +1 -1
  8. package/package.json +1 -1
  9. package/packages/client/dist/browser/index.global.js.map +1 -1
  10. package/packages/client/dist/cjs/index.cjs.map +1 -1
  11. package/packages/client/dist/esm/index.js.map +1 -1
  12. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  13. package/packages/engine/dist/browser/index.global.js +69 -10
  14. package/packages/engine/dist/browser/index.global.js.map +1 -1
  15. package/packages/engine/dist/cjs/index.cjs +781 -5
  16. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  17. package/packages/engine/dist/esm/index.js +763 -5
  18. package/packages/engine/dist/esm/index.js.map +1 -1
  19. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  20. package/packages/engine/dist/types/index.d.ts +2 -0
  21. package/packages/engine/dist/types/index.d.ts.map +1 -1
  22. package/packages/engine/dist/types/render/md3Pipeline.d.ts +79 -0
  23. package/packages/engine/dist/types/render/md3Pipeline.d.ts.map +1 -0
  24. package/packages/engine/dist/types/render/particleSystem.d.ts +105 -0
  25. package/packages/engine/dist/types/render/particleSystem.d.ts.map +1 -0
  26. package/packages/game/dist/browser/index.global.js +1 -1
  27. package/packages/game/dist/browser/index.global.js.map +1 -1
  28. package/packages/game/dist/cjs/index.cjs +176 -3
  29. package/packages/game/dist/cjs/index.cjs.map +1 -1
  30. package/packages/game/dist/esm/index.js +172 -3
  31. package/packages/game/dist/esm/index.js.map +1 -1
  32. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  33. package/packages/game/dist/types/ai/constants.d.ts +16 -0
  34. package/packages/game/dist/types/ai/constants.d.ts.map +1 -1
  35. package/packages/game/dist/types/ai/index.d.ts +1 -0
  36. package/packages/game/dist/types/ai/index.d.ts.map +1 -1
  37. package/packages/game/dist/types/ai/targeting.d.ts +25 -0
  38. package/packages/game/dist/types/ai/targeting.d.ts.map +1 -0
  39. package/packages/game/dist/types/entities/entity.d.ts +11 -0
  40. package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
  41. package/packages/shared/dist/browser/index.global.js +1 -1
  42. package/packages/shared/dist/browser/index.global.js.map +1 -1
  43. package/packages/shared/dist/cjs/index.cjs +65 -0
  44. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  45. package/packages/shared/dist/esm/index.js +61 -0
  46. package/packages/shared/dist/esm/index.js.map +1 -1
  47. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  48. package/packages/shared/dist/types/index.d.ts +1 -0
  49. package/packages/shared/dist/types/index.d.ts.map +1 -1
  50. package/packages/shared/dist/types/math/mat4.d.ts +7 -0
  51. package/packages/shared/dist/types/math/mat4.d.ts.map +1 -0
  52. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -408,7 +408,12 @@ var ZERO = { ...ZERO_VEC3 };
408
408
  function copyVec3() {
409
409
  return { ...ZERO };
410
410
  }
411
- var DEFAULT_MONSTER_INFO = Object.freeze({ aiflags: 0 });
411
+ var DEFAULT_MONSTER_INFO = Object.freeze({
412
+ aiflags: 0,
413
+ last_sighting: ZERO,
414
+ trail_time: 0,
415
+ pausetime: 0
416
+ });
412
417
  var Entity = class {
413
418
  constructor(index) {
414
419
  this.inUse = false;
@@ -468,7 +473,9 @@ var Entity = class {
468
473
  this.solid = 0 /* Not */;
469
474
  this.flags = 0;
470
475
  this.svflags = 0;
471
- this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
476
+ this.monsterinfo = { ...DEFAULT_MONSTER_INFO, last_sighting: copyVec3() };
477
+ this.show_hostile = 0;
478
+ this.light_level = 0;
472
479
  this.index = index;
473
480
  }
474
481
  reset() {
@@ -542,7 +549,10 @@ var Entity = class {
542
549
  this.solid = 0 /* Not */;
543
550
  this.flags = 0;
544
551
  this.svflags = 0;
545
- this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
552
+ this.monsterinfo = { ...DEFAULT_MONSTER_INFO, last_sighting: copyVec3() };
553
+ this.combattarget = void 0;
554
+ this.show_hostile = 0;
555
+ this.light_level = 0;
546
556
  }
547
557
  };
548
558
  var ENTITY_FIELD_METADATA = [
@@ -2065,9 +2075,25 @@ var LevelClock = class {
2065
2075
  var RANGE_MELEE = 20;
2066
2076
  var RANGE_NEAR = 440;
2067
2077
  var RANGE_MID = 940;
2078
+ var FL_NOTARGET = 1 << 5;
2068
2079
  var FL_NOVISIBLE = 1 << 24;
2069
2080
  var SPAWNFLAG_MONSTER_AMBUSH = 1 << 0;
2070
2081
  var AIFlags = /* @__PURE__ */ ((AIFlags2) => {
2082
+ AIFlags2[AIFlags2["StandGround"] = 1] = "StandGround";
2083
+ AIFlags2[AIFlags2["TempStandGround"] = 2] = "TempStandGround";
2084
+ AIFlags2[AIFlags2["SoundTarget"] = 4] = "SoundTarget";
2085
+ AIFlags2[AIFlags2["LostSight"] = 8] = "LostSight";
2086
+ AIFlags2[AIFlags2["PursuitLastSeen"] = 16] = "PursuitLastSeen";
2087
+ AIFlags2[AIFlags2["PursueNext"] = 32] = "PursueNext";
2088
+ AIFlags2[AIFlags2["PursueTemp"] = 64] = "PursueTemp";
2089
+ AIFlags2[AIFlags2["HoldFrame"] = 128] = "HoldFrame";
2090
+ AIFlags2[AIFlags2["GoodGuy"] = 256] = "GoodGuy";
2091
+ AIFlags2[AIFlags2["Brutal"] = 512] = "Brutal";
2092
+ AIFlags2[AIFlags2["NoStep"] = 1024] = "NoStep";
2093
+ AIFlags2[AIFlags2["Ducked"] = 2048] = "Ducked";
2094
+ AIFlags2[AIFlags2["CombatPoint"] = 4096] = "CombatPoint";
2095
+ AIFlags2[AIFlags2["Medic"] = 8192] = "Medic";
2096
+ AIFlags2[AIFlags2["Resurrecting"] = 16384] = "Resurrecting";
2071
2097
  AIFlags2[AIFlags2["Pathing"] = 1073741824] = "Pathing";
2072
2098
  return AIFlags2;
2073
2099
  })(AIFlags || {});
@@ -2235,6 +2261,145 @@ function visible(self, other, trace, options) {
2235
2261
  return result.fraction === 1 || result.entity === other;
2236
2262
  }
2237
2263
 
2264
+ // src/ai/targeting.ts
2265
+ function setIdealYawTowards2(self, other) {
2266
+ const delta = {
2267
+ x: other.origin.x - self.origin.x,
2268
+ y: other.origin.y - self.origin.y,
2269
+ z: other.origin.z - self.origin.z
2270
+ };
2271
+ self.ideal_yaw = vectorToYaw(delta);
2272
+ }
2273
+ function faceYawInstantly(self) {
2274
+ self.angles.y = angleMod(self.ideal_yaw);
2275
+ }
2276
+ function huntTarget(self, level) {
2277
+ if (!self.enemy) return;
2278
+ self.goalentity = self.enemy;
2279
+ setIdealYawTowards2(self, self.enemy);
2280
+ faceYawInstantly(self);
2281
+ if ((self.monsterinfo.aiflags & 1 /* StandGround */) !== 0) {
2282
+ self.monsterinfo.stand?.(self);
2283
+ } else {
2284
+ self.monsterinfo.run?.(self);
2285
+ self.attack_finished_time = level.timeSeconds + 1;
2286
+ }
2287
+ }
2288
+ function foundTarget(self, level, options) {
2289
+ if (!self.enemy) return;
2290
+ if ((self.enemy.svflags & 8 /* Player */) !== 0) {
2291
+ level.sightEntity = self;
2292
+ level.sightEntityFrame = level.frameNumber;
2293
+ self.light_level = 128;
2294
+ }
2295
+ self.show_hostile = level.timeSeconds + 1;
2296
+ const lastSighting = self.monsterinfo.last_sighting;
2297
+ lastSighting.x = self.enemy.origin.x;
2298
+ lastSighting.y = self.enemy.origin.y;
2299
+ lastSighting.z = self.enemy.origin.z;
2300
+ self.trail_time = level.timeSeconds;
2301
+ self.monsterinfo.trail_time = level.timeSeconds;
2302
+ if (!self.combattarget) {
2303
+ huntTarget(self, level);
2304
+ return;
2305
+ }
2306
+ const pickTarget = options?.pickTarget;
2307
+ const movetarget = pickTarget?.(self.combattarget) ?? self.enemy;
2308
+ self.goalentity = movetarget;
2309
+ self.movetarget = movetarget;
2310
+ self.combattarget = void 0;
2311
+ self.monsterinfo.aiflags |= 4096 /* CombatPoint */;
2312
+ if (self.movetarget) {
2313
+ self.movetarget.targetname = void 0;
2314
+ }
2315
+ self.monsterinfo.pausetime = 0;
2316
+ self.monsterinfo.run?.(self);
2317
+ }
2318
+ function classifyClientVisibility(self, other, level) {
2319
+ const distance = rangeTo(self, other);
2320
+ const range = classifyRange(distance);
2321
+ const passthrough = (_start, _end, _ignore, _mask) => ({ fraction: 1, entity: other });
2322
+ if (range === "far" /* Far */) return false;
2323
+ if (other.light_level <= 5) return false;
2324
+ if (!visible(self, other, passthrough, { throughGlass: false })) return false;
2325
+ if (range === "near" /* Near */) {
2326
+ return level.timeSeconds <= other.show_hostile || infront(self, other);
2327
+ }
2328
+ if (range === "mid" /* Mid */) {
2329
+ return infront(self, other);
2330
+ }
2331
+ return true;
2332
+ }
2333
+ function updateSoundChase(self, client, level, hearability) {
2334
+ const passthrough = (_start, _end, _ignore, _mask) => ({ fraction: 1, entity: client });
2335
+ if ((self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) !== 0) {
2336
+ if (!visible(self, client, passthrough)) return false;
2337
+ } else if (hearability.canHear && !hearability.canHear(self, client)) {
2338
+ return false;
2339
+ }
2340
+ const delta = subtractVec3(client.origin, self.origin);
2341
+ if (lengthVec3(delta) > 1e3) return false;
2342
+ if (hearability.areasConnected && !hearability.areasConnected(self, client)) return false;
2343
+ self.ideal_yaw = vectorToYaw(delta);
2344
+ faceYawInstantly(self);
2345
+ self.monsterinfo.aiflags |= 4 /* SoundTarget */;
2346
+ self.enemy = client;
2347
+ return true;
2348
+ }
2349
+ function chooseCandidate(self, level) {
2350
+ if (level.sightEntity && level.sightEntityFrame >= level.frameNumber - 1 && (self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) === 0) {
2351
+ if (level.sightEntity.enemy !== self.enemy) {
2352
+ return { candidate: level.sightEntity, heardit: false };
2353
+ }
2354
+ return { candidate: null, heardit: false };
2355
+ }
2356
+ if (level.soundEntity && level.soundEntityFrame >= level.frameNumber - 1) {
2357
+ return { candidate: level.soundEntity, heardit: true };
2358
+ }
2359
+ if (!self.enemy && level.sound2Entity && level.sound2EntityFrame >= level.frameNumber - 1 && (self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) === 0) {
2360
+ return { candidate: level.sound2Entity, heardit: true };
2361
+ }
2362
+ if (level.sightClient) {
2363
+ return { candidate: level.sightClient, heardit: false };
2364
+ }
2365
+ return { candidate: null, heardit: false };
2366
+ }
2367
+ function rejectNotargetEntity(client) {
2368
+ if ((client.flags & FL_NOTARGET) !== 0) return true;
2369
+ if ((client.svflags & 4 /* Monster */) !== 0 && client.enemy) {
2370
+ return (client.enemy.flags & FL_NOTARGET) !== 0;
2371
+ }
2372
+ if (client.enemy && (client.enemy.flags & FL_NOTARGET) !== 0) return true;
2373
+ return false;
2374
+ }
2375
+ function findTarget(self, level, hearability = {}) {
2376
+ if ((self.monsterinfo.aiflags & 256 /* GoodGuy */) !== 0) {
2377
+ if (self.goalentity?.classname === "target_actor") {
2378
+ return false;
2379
+ }
2380
+ return false;
2381
+ }
2382
+ if ((self.monsterinfo.aiflags & 4096 /* CombatPoint */) !== 0) {
2383
+ return false;
2384
+ }
2385
+ const { candidate, heardit } = chooseCandidate(self, level);
2386
+ if (!candidate || !candidate.inUse) return false;
2387
+ if (candidate === self.enemy) return true;
2388
+ if (rejectNotargetEntity(candidate)) return false;
2389
+ if (!heardit) {
2390
+ if (!classifyClientVisibility(self, candidate, level)) return false;
2391
+ self.monsterinfo.aiflags &= ~4 /* SoundTarget */;
2392
+ self.enemy = candidate;
2393
+ } else if (!updateSoundChase(self, candidate, level, hearability)) {
2394
+ return false;
2395
+ }
2396
+ foundTarget(self, level);
2397
+ if ((self.monsterinfo.aiflags & 4 /* SoundTarget */) === 0) {
2398
+ self.monsterinfo.sight?.(self, self.enemy);
2399
+ }
2400
+ return true;
2401
+ }
2402
+
2238
2403
  // src/checksum.ts
2239
2404
  var FNV_OFFSET_BASIS = 2166136261;
2240
2405
  var FNV_PRIME = 16777619;
@@ -3697,6 +3862,7 @@ export {
3697
3862
  EntityDamageFlags,
3698
3863
  EntitySystem,
3699
3864
  EnvironmentalFlags,
3865
+ FL_NOTARGET,
3700
3866
  FL_NOVISIBLE,
3701
3867
  KeyId,
3702
3868
  MoveType,
@@ -3750,6 +3916,8 @@ export {
3750
3916
  damageModName,
3751
3917
  equipArmor,
3752
3918
  facingIdeal,
3919
+ findTarget,
3920
+ foundTarget,
3753
3921
  getAmmoItemDefinition,
3754
3922
  giveAmmo,
3755
3923
  giveAmmoItem,
@@ -3759,6 +3927,7 @@ export {
3759
3927
  hasPowerup,
3760
3928
  hasWeapon,
3761
3929
  hashGameState,
3930
+ huntTarget,
3762
3931
  infront,
3763
3932
  isZeroVector,
3764
3933
  killBox,