quake2ts 0.0.291 → 0.0.293

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 (47) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +13 -13
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +2 -0
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +2 -0
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/engine/dist/browser/index.global.js +1 -1
  10. package/packages/engine/dist/browser/index.global.js.map +1 -1
  11. package/packages/engine/dist/cjs/index.cjs +1 -0
  12. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  13. package/packages/engine/dist/esm/index.js +1 -0
  14. package/packages/engine/dist/esm/index.js.map +1 -1
  15. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  16. package/packages/game/dist/browser/index.global.js +4 -3
  17. package/packages/game/dist/browser/index.global.js.map +1 -1
  18. package/packages/game/dist/cjs/index.cjs +229 -32
  19. package/packages/game/dist/cjs/index.cjs.map +1 -1
  20. package/packages/game/dist/esm/index.js +229 -32
  21. package/packages/game/dist/esm/index.js.map +1 -1
  22. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  23. package/packages/game/dist/types/entities/entity.d.ts +1 -0
  24. package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
  25. package/packages/game/dist/types/entities/gibs.d.ts +2 -0
  26. package/packages/game/dist/types/entities/gibs.d.ts.map +1 -1
  27. package/packages/game/dist/types/entities/system.d.ts +7 -0
  28. package/packages/game/dist/types/entities/system.d.ts.map +1 -1
  29. package/packages/game/dist/types/entities/targets.d.ts.map +1 -1
  30. package/packages/game/dist/types/imports.d.ts +1 -0
  31. package/packages/game/dist/types/imports.d.ts.map +1 -1
  32. package/packages/game/dist/types/index.d.ts +2 -0
  33. package/packages/game/dist/types/index.d.ts.map +1 -1
  34. package/packages/game/dist/types/save/rerelease.d.ts.map +1 -1
  35. package/packages/game/dist/types/save/save.d.ts.map +1 -1
  36. package/packages/server/dist/index.cjs +4 -1
  37. package/packages/server/dist/index.js +4 -1
  38. package/packages/shared/dist/browser/index.global.js +1 -1
  39. package/packages/shared/dist/browser/index.global.js.map +1 -1
  40. package/packages/shared/dist/cjs/index.cjs +1 -0
  41. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  42. package/packages/shared/dist/esm/index.js +1 -0
  43. package/packages/shared/dist/esm/index.js.map +1 -1
  44. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  45. package/packages/shared/dist/types/protocol/configstrings.d.ts +1 -0
  46. package/packages/shared/dist/types/protocol/configstrings.d.ts.map +1 -1
  47. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -835,6 +835,7 @@ var init_esm = __esm({
835
835
  ConfigStringIndex2[ConfigStringIndex2["SkyAxis"] = 3] = "SkyAxis";
836
836
  ConfigStringIndex2[ConfigStringIndex2["SkyRotate"] = 4] = "SkyRotate";
837
837
  ConfigStringIndex2[ConfigStringIndex2["StatusBar"] = 5] = "StatusBar";
838
+ ConfigStringIndex2[ConfigStringIndex2["HealthBarName"] = 55] = "HealthBarName";
838
839
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_N64_PHYSICS"] = 56] = "CONFIG_N64_PHYSICS";
839
840
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_CTF_TEAMS"] = 57] = "CONFIG_CTF_TEAMS";
840
841
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_COOP_RESPAWN_STRING"] = 58] = "CONFIG_COOP_RESPAWN_STRING";
@@ -2593,6 +2594,7 @@ var Entity = class {
2593
2594
  this.renderfx = 0;
2594
2595
  this.health = 0;
2595
2596
  this.max_health = 0;
2597
+ this.spawn_count = 0;
2596
2598
  this.takedamage = false;
2597
2599
  this.dmg = 0;
2598
2600
  this.radius_dmg = 0;
@@ -2742,6 +2744,7 @@ var Entity = class {
2742
2744
  this.renderfx = 0;
2743
2745
  this.health = 0;
2744
2746
  this.max_health = 0;
2747
+ this.spawn_count = 0;
2745
2748
  this.takedamage = false;
2746
2749
  this.dmg = 0;
2747
2750
  this.speed = 0;
@@ -2835,6 +2838,7 @@ var ENTITY_FIELD_METADATA = [
2835
2838
  { name: "renderfx", type: "int", save: true },
2836
2839
  { name: "health", type: "int", save: true },
2837
2840
  { name: "max_health", type: "int", save: true },
2841
+ { name: "spawn_count", type: "int", save: true },
2838
2842
  { name: "takedamage", type: "boolean", save: true },
2839
2843
  { name: "dmg", type: "int", save: true },
2840
2844
  { name: "speed", type: "float", save: true },
@@ -4024,6 +4028,7 @@ var EntitySystem = class {
4024
4028
  this.random = createRandomGenerator();
4025
4029
  this.currentTimeSeconds = 0;
4026
4030
  this.frameNumber = 0;
4031
+ this.spawnCount = 0;
4027
4032
  // Persistent state for cross-level logic
4028
4033
  this.crossLevelFlags = 0;
4029
4034
  this.crossUnitFlags = 0;
@@ -4062,6 +4067,8 @@ var EntitySystem = class {
4062
4067
  unicast: () => {
4063
4068
  },
4064
4069
  configstring: () => {
4070
+ },
4071
+ serverCommand: () => {
4065
4072
  }
4066
4073
  };
4067
4074
  this.imports = { ...defaultImports, ...imports };
@@ -4083,6 +4090,10 @@ var EntitySystem = class {
4083
4090
  sound2EntityFrame: 0,
4084
4091
  sightClient: null
4085
4092
  };
4093
+ this.level = {
4094
+ next_auto_save: 0,
4095
+ health_bar_entities: [null, null, null, null]
4096
+ };
4086
4097
  }
4087
4098
  get rng() {
4088
4099
  return this.random;
@@ -4131,6 +4142,8 @@ var EntitySystem = class {
4131
4142
  }
4132
4143
  spawn() {
4133
4144
  const ent = this.pool.spawn();
4145
+ this.spawnCount++;
4146
+ ent.spawn_count = this.spawnCount;
4134
4147
  ent.timestamp = this.currentTimeSeconds;
4135
4148
  return ent;
4136
4149
  }
@@ -4362,13 +4375,22 @@ var EntitySystem = class {
4362
4375
  sightClientIndex: this.targetAwareness.sightClient?.index ?? null
4363
4376
  },
4364
4377
  crossLevelFlags: this.crossLevelFlags,
4365
- crossUnitFlags: this.crossUnitFlags
4378
+ crossUnitFlags: this.crossUnitFlags,
4379
+ level: {
4380
+ next_auto_save: this.level.next_auto_save,
4381
+ health_bar_entities: [null, null, null, null]
4382
+ // Transient
4383
+ }
4366
4384
  };
4367
4385
  }
4368
4386
  restore(snapshot, callbackRegistry) {
4369
4387
  this.currentTimeSeconds = snapshot.timeSeconds;
4370
4388
  this.crossLevelFlags = snapshot.crossLevelFlags ?? 0;
4371
4389
  this.crossUnitFlags = snapshot.crossUnitFlags ?? 0;
4390
+ if (snapshot.level) {
4391
+ this.level = { ...snapshot.level };
4392
+ this.level.health_bar_entities = [null, null, null, null];
4393
+ }
4372
4394
  this.pool.restore(snapshot.pool);
4373
4395
  const indexToEntity = /* @__PURE__ */ new Map();
4374
4396
  for (const entity of this.pool) {
@@ -5760,6 +5782,82 @@ function registerTargetSpawns(registry) {
5760
5782
  entity.movedir = { x: start, y: end, z: slope };
5761
5783
  }
5762
5784
  });
5785
+ registry.register("target_music", (entity, { entities, keyValues }) => {
5786
+ entity.sounds = keyValues.sounds ? parseInt(keyValues.sounds) : 0;
5787
+ entity.use = (self) => {
5788
+ entities.imports.configstring(ConfigStringIndex.CdTrack, `${self.sounds}`);
5789
+ };
5790
+ });
5791
+ registry.register("target_autosave", (entity, context) => {
5792
+ entity.use = (self) => {
5793
+ const saveTime = 60;
5794
+ if (context.entities.timeSeconds - context.entities.level.next_auto_save > saveTime) {
5795
+ context.entities.imports.serverCommand("autosave\n");
5796
+ context.entities.level.next_auto_save = context.entities.timeSeconds;
5797
+ }
5798
+ };
5799
+ });
5800
+ registry.register("target_healthbar", (entity, { entities, warn, free }) => {
5801
+ entity.use = (self) => {
5802
+ const target = entities.pickTarget(self.target);
5803
+ if (!target || self.health !== target.spawn_count) {
5804
+ if (target) {
5805
+ warn(`${self.classname}: target ${target.classname} changed from what it used to be`);
5806
+ } else {
5807
+ warn(`${self.classname}: no target`);
5808
+ }
5809
+ entities.free(self);
5810
+ return;
5811
+ }
5812
+ const level = entities.level;
5813
+ let found = false;
5814
+ for (let i = 0; i < 4; i++) {
5815
+ if (!level.health_bar_entities[i]) {
5816
+ self.enemy = target;
5817
+ level.health_bar_entities[i] = self;
5818
+ entities.imports.configstring(ConfigStringIndex.HealthBarName, self.message || "");
5819
+ found = true;
5820
+ break;
5821
+ }
5822
+ }
5823
+ if (!found) {
5824
+ warn(`${self.classname}: too many health bars`);
5825
+ entities.free(self);
5826
+ }
5827
+ };
5828
+ entity.think = (self) => {
5829
+ const target = entities.pickTarget(self.target);
5830
+ if (!target || !(target.svflags & 4 /* Monster */)) {
5831
+ if (target) {
5832
+ warn(`${self.classname}: target ${target.classname} does not appear to be a monster`);
5833
+ }
5834
+ entities.free(self);
5835
+ return;
5836
+ }
5837
+ const level = entities.level;
5838
+ if (level.health_bar_entities) {
5839
+ let registered = false;
5840
+ for (let i = 0; i < 4; i++) {
5841
+ if (level.health_bar_entities[i] === self) {
5842
+ registered = true;
5843
+ break;
5844
+ }
5845
+ }
5846
+ if (!registered) {
5847
+ for (let i = 0; i < 4; i++) {
5848
+ if (!level.health_bar_entities[i]) {
5849
+ level.health_bar_entities[i] = self;
5850
+ entities.imports.configstring(ConfigStringIndex.HealthBarName, self.message || "");
5851
+ break;
5852
+ }
5853
+ }
5854
+ }
5855
+ }
5856
+ self.health = target.spawn_count;
5857
+ self.nextthink = entities.timeSeconds + 0.1;
5858
+ };
5859
+ entity.nextthink = entities.timeSeconds + 0.1;
5860
+ });
5763
5861
  }
5764
5862
 
5765
5863
  // src/entities/triggers.ts
@@ -7545,40 +7643,80 @@ init_esm();
7545
7643
  // src/entities/gibs.ts
7546
7644
  init_esm();
7547
7645
  var random3 = createRandomGenerator();
7646
+ var GIB_ORGANIC = 0;
7548
7647
  var GIB_METALLIC = 1;
7549
7648
  var GIB_DEBRIS = 2;
7550
- function spawnGib(sys, origin, damage, model, type) {
7649
+ function velocityForDamage(damage) {
7650
+ let x = 100 * random3.crandom();
7651
+ let y = 100 * random3.crandom();
7652
+ let z = 200 + 100 * random3.frandom();
7653
+ if (damage < 50) {
7654
+ x *= 0.7;
7655
+ y *= 0.7;
7656
+ z *= 0.7;
7657
+ } else {
7658
+ x *= 1.2;
7659
+ y *= 1.2;
7660
+ z *= 1.2;
7661
+ }
7662
+ return { x, y, z };
7663
+ }
7664
+ function clipGibVelocity(ent) {
7665
+ let { x, y, z } = ent.velocity;
7666
+ if (x < -300) x = -300;
7667
+ else if (x > 300) x = 300;
7668
+ if (y < -300) y = -300;
7669
+ else if (y > 300) y = 300;
7670
+ if (z < 200) z = 200;
7671
+ else if (z > 500) z = 500;
7672
+ ent.velocity = { x, y, z };
7673
+ }
7674
+ function gib_touch(self, other, plane, surf, sys) {
7675
+ if (!self.groundentity) return;
7676
+ self.touch = void 0;
7677
+ if (plane) {
7678
+ sys.sound(self, 0, "misc/fhit3.wav", 1, 1, 0);
7679
+ }
7680
+ }
7681
+ function spawnGib(sys, origin, damage, model, type = GIB_ORGANIC) {
7551
7682
  const gib = sys.spawn();
7552
7683
  gib.classname = "gib";
7553
7684
  gib.origin = {
7554
- x: origin.x + (random3.frandom() - 0.5) * 20,
7555
- y: origin.y + (random3.frandom() - 0.5) * 20,
7556
- z: origin.z + (random3.frandom() - 0.5) * 20
7557
- };
7558
- gib.velocity = {
7559
- x: (random3.frandom() - 0.5) * 300,
7560
- y: (random3.frandom() - 0.5) * 300,
7561
- z: 200 + random3.frandom() * 100
7685
+ x: origin.x + random3.crandom() * 20,
7686
+ y: origin.y + random3.crandom() * 20,
7687
+ z: origin.z + random3.crandom() * 20
7562
7688
  };
7563
- gib.movetype = 9 /* Bounce */;
7564
- gib.solid = 0 /* Not */;
7565
- gib.clipmask = 1;
7566
- gib.avelocity = {
7567
- x: random3.crandom() * 600,
7568
- y: random3.crandom() * 600,
7569
- z: random3.crandom() * 600
7570
- };
7571
- const defaultModels = [
7572
- "models/objects/gibs/bone/tris.md2",
7573
- "models/objects/gibs/meat/tris.md2",
7574
- "models/objects/gibs/sm_meat/tris.md2"
7575
- ];
7576
- const modelName = model || defaultModels[Math.floor(random3.frandom() * defaultModels.length)];
7689
+ const modelName = model || "models/objects/gibs/sm_meat/tris.md2";
7577
7690
  gib.modelindex = sys.modelIndex(modelName);
7578
7691
  gib.mins = { x: -2, y: -2, z: -2 };
7579
7692
  gib.maxs = { x: 2, y: 2, z: 2 };
7580
- if (type && type & GIB_METALLIC) {
7693
+ gib.solid = 0 /* Not */;
7694
+ gib.takedamage = true;
7695
+ gib.die = (self, inflictor, attacker, dmg, point, mod) => {
7696
+ sys.free(self);
7697
+ };
7698
+ gib.clipmask = 1;
7699
+ let vscale = 1;
7700
+ if (type === GIB_ORGANIC) {
7701
+ gib.movetype = 7 /* Toss */;
7702
+ gib.touch = (self, other, plane, surf) => gib_touch(self, other, plane, surf, sys);
7703
+ vscale = 0.5;
7704
+ } else {
7705
+ gib.movetype = 9 /* Bounce */;
7706
+ vscale = 1;
7581
7707
  }
7708
+ const vd = velocityForDamage(damage);
7709
+ gib.velocity = {
7710
+ x: vd.x * vscale,
7711
+ y: vd.y * vscale,
7712
+ z: vd.z * vscale
7713
+ };
7714
+ clipGibVelocity(gib);
7715
+ gib.avelocity = {
7716
+ x: random3.frandom() * 600,
7717
+ y: random3.frandom() * 600,
7718
+ z: random3.frandom() * 600
7719
+ };
7582
7720
  gib.think = (self) => {
7583
7721
  sys.free(self);
7584
7722
  };
@@ -7586,13 +7724,58 @@ function spawnGib(sys, origin, damage, model, type) {
7586
7724
  sys.finalizeSpawn(gib);
7587
7725
  return gib;
7588
7726
  }
7727
+ function spawnHead(sys, origin, damage) {
7728
+ const head = sys.spawn();
7729
+ let gibname;
7730
+ if (random3.irandom(2) === 1) {
7731
+ gibname = "models/objects/gibs/head2/tris.md2";
7732
+ head.skin = 1;
7733
+ } else {
7734
+ gibname = "models/objects/gibs/skull/tris.md2";
7735
+ head.skin = 0;
7736
+ }
7737
+ head.frame = 0;
7738
+ head.modelindex = sys.modelIndex(gibname);
7739
+ head.mins = { x: -16, y: -16, z: 0 };
7740
+ head.maxs = { x: 16, y: 16, z: 16 };
7741
+ head.origin = {
7742
+ x: origin.x,
7743
+ y: origin.y,
7744
+ z: origin.z + 32
7745
+ };
7746
+ head.solid = 0 /* Not */;
7747
+ head.takedamage = true;
7748
+ head.die = (self, inflictor, attacker, dmg, point, mod) => {
7749
+ sys.free(self);
7750
+ };
7751
+ let vscale = 0.5;
7752
+ head.movetype = 7 /* Toss */;
7753
+ head.touch = (self, other, plane, surf) => gib_touch(self, other, plane, surf, sys);
7754
+ const vd = velocityForDamage(damage);
7755
+ head.velocity = {
7756
+ x: vd.x * vscale,
7757
+ y: vd.y * vscale,
7758
+ z: vd.z * vscale
7759
+ };
7760
+ clipGibVelocity(head);
7761
+ head.avelocity = { x: 0, y: random3.crandom() * 600, z: 0 };
7762
+ head.think = (self) => {
7763
+ sys.free(self);
7764
+ };
7765
+ sys.scheduleThink(head, sys.timeSeconds + 10 + random3.frandom() * 10);
7766
+ sys.finalizeSpawn(head);
7767
+ return head;
7768
+ }
7589
7769
  function throwGibs(sys, origin, damageOrDefs) {
7590
7770
  if (typeof damageOrDefs === "number") {
7591
7771
  const damage = damageOrDefs;
7592
- const count = 4 + Math.floor(random3.frandom() * 4);
7593
- for (let i = 0; i < count; i++) {
7594
- spawnGib(sys, origin, damage);
7595
- }
7772
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7773
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7774
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7775
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7776
+ spawnGib(sys, origin, damage, "models/objects/gibs/meat/tris.md2", GIB_ORGANIC);
7777
+ spawnGib(sys, origin, damage, "models/objects/gibs/bone/tris.md2", GIB_ORGANIC);
7778
+ spawnHead(sys, origin, damage);
7596
7779
  } else {
7597
7780
  const defs = damageOrDefs;
7598
7781
  for (const def of defs) {
@@ -18009,7 +18192,11 @@ function parseEntitySnapshot(raw) {
18009
18192
  thinks: parseThinkEntries(snapshot.thinks),
18010
18193
  awareness: parseAwareness(snapshot.awareness),
18011
18194
  crossLevelFlags: ensureNumberOrDefault(snapshot.crossLevelFlags, "entities.crossLevelFlags", 0),
18012
- crossUnitFlags: ensureNumberOrDefault(snapshot.crossUnitFlags, "entities.crossUnitFlags", 0)
18195
+ crossUnitFlags: ensureNumberOrDefault(snapshot.crossUnitFlags, "entities.crossUnitFlags", 0),
18196
+ level: {
18197
+ next_auto_save: 0,
18198
+ health_bar_entities: [null, null, null, null]
18199
+ }
18013
18200
  };
18014
18201
  }
18015
18202
  function parseCvars(raw) {
@@ -18373,7 +18560,11 @@ function buildEntitySnapshot(entities, levelTimeSeconds, capacityHint) {
18373
18560
  thinks: [],
18374
18561
  awareness: dummyAwareness,
18375
18562
  crossLevelFlags: 0,
18376
- crossUnitFlags: 0
18563
+ crossUnitFlags: 0,
18564
+ level: {
18565
+ next_auto_save: 0,
18566
+ health_bar_entities: [null, null, null, null]
18567
+ }
18377
18568
  };
18378
18569
  }
18379
18570
  function buildLevelState(level) {
@@ -19284,6 +19475,8 @@ function createGame(imports, engine, options) {
19284
19475
  });
19285
19476
  const configstring = imports.configstring || (() => {
19286
19477
  });
19478
+ const serverCommand = imports.serverCommand || (() => {
19479
+ });
19287
19480
  const linkentity = imports.linkentity;
19288
19481
  const wrappedLinkEntity = (ent) => {
19289
19482
  ent.absmin = {
@@ -19307,7 +19500,8 @@ function createGame(imports, engine, options) {
19307
19500
  linkentity: wrappedLinkEntity,
19308
19501
  multicast,
19309
19502
  unicast,
19310
- configstring
19503
+ configstring,
19504
+ serverCommand
19311
19505
  };
19312
19506
  const entities = new EntitySystem(engine, systemImports, gravity, void 0, void 0, deathmatch);
19313
19507
  entities._game = {
@@ -19575,6 +19769,9 @@ function createGame(imports, engine, options) {
19575
19769
  configstring(index, value) {
19576
19770
  configstring(index, value);
19577
19771
  },
19772
+ serverCommand(cmd) {
19773
+ serverCommand(cmd);
19774
+ },
19578
19775
  get time() {
19579
19776
  return levelClock.current.timeSeconds;
19580
19777
  },