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
@@ -823,6 +823,7 @@ var init_esm = __esm({
823
823
  ConfigStringIndex2[ConfigStringIndex2["SkyAxis"] = 3] = "SkyAxis";
824
824
  ConfigStringIndex2[ConfigStringIndex2["SkyRotate"] = 4] = "SkyRotate";
825
825
  ConfigStringIndex2[ConfigStringIndex2["StatusBar"] = 5] = "StatusBar";
826
+ ConfigStringIndex2[ConfigStringIndex2["HealthBarName"] = 55] = "HealthBarName";
826
827
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_N64_PHYSICS"] = 56] = "CONFIG_N64_PHYSICS";
827
828
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_CTF_TEAMS"] = 57] = "CONFIG_CTF_TEAMS";
828
829
  ConfigStringIndex2[ConfigStringIndex2["CONFIG_COOP_RESPAWN_STRING"] = 58] = "CONFIG_COOP_RESPAWN_STRING";
@@ -2434,6 +2435,7 @@ var Entity = class {
2434
2435
  this.renderfx = 0;
2435
2436
  this.health = 0;
2436
2437
  this.max_health = 0;
2438
+ this.spawn_count = 0;
2437
2439
  this.takedamage = false;
2438
2440
  this.dmg = 0;
2439
2441
  this.radius_dmg = 0;
@@ -2583,6 +2585,7 @@ var Entity = class {
2583
2585
  this.renderfx = 0;
2584
2586
  this.health = 0;
2585
2587
  this.max_health = 0;
2588
+ this.spawn_count = 0;
2586
2589
  this.takedamage = false;
2587
2590
  this.dmg = 0;
2588
2591
  this.speed = 0;
@@ -2676,6 +2679,7 @@ var ENTITY_FIELD_METADATA = [
2676
2679
  { name: "renderfx", type: "int", save: true },
2677
2680
  { name: "health", type: "int", save: true },
2678
2681
  { name: "max_health", type: "int", save: true },
2682
+ { name: "spawn_count", type: "int", save: true },
2679
2683
  { name: "takedamage", type: "boolean", save: true },
2680
2684
  { name: "dmg", type: "int", save: true },
2681
2685
  { name: "speed", type: "float", save: true },
@@ -3865,6 +3869,7 @@ var EntitySystem = class {
3865
3869
  this.random = createRandomGenerator();
3866
3870
  this.currentTimeSeconds = 0;
3867
3871
  this.frameNumber = 0;
3872
+ this.spawnCount = 0;
3868
3873
  // Persistent state for cross-level logic
3869
3874
  this.crossLevelFlags = 0;
3870
3875
  this.crossUnitFlags = 0;
@@ -3903,6 +3908,8 @@ var EntitySystem = class {
3903
3908
  unicast: () => {
3904
3909
  },
3905
3910
  configstring: () => {
3911
+ },
3912
+ serverCommand: () => {
3906
3913
  }
3907
3914
  };
3908
3915
  this.imports = { ...defaultImports, ...imports };
@@ -3924,6 +3931,10 @@ var EntitySystem = class {
3924
3931
  sound2EntityFrame: 0,
3925
3932
  sightClient: null
3926
3933
  };
3934
+ this.level = {
3935
+ next_auto_save: 0,
3936
+ health_bar_entities: [null, null, null, null]
3937
+ };
3927
3938
  }
3928
3939
  get rng() {
3929
3940
  return this.random;
@@ -3972,6 +3983,8 @@ var EntitySystem = class {
3972
3983
  }
3973
3984
  spawn() {
3974
3985
  const ent = this.pool.spawn();
3986
+ this.spawnCount++;
3987
+ ent.spawn_count = this.spawnCount;
3975
3988
  ent.timestamp = this.currentTimeSeconds;
3976
3989
  return ent;
3977
3990
  }
@@ -4203,13 +4216,22 @@ var EntitySystem = class {
4203
4216
  sightClientIndex: this.targetAwareness.sightClient?.index ?? null
4204
4217
  },
4205
4218
  crossLevelFlags: this.crossLevelFlags,
4206
- crossUnitFlags: this.crossUnitFlags
4219
+ crossUnitFlags: this.crossUnitFlags,
4220
+ level: {
4221
+ next_auto_save: this.level.next_auto_save,
4222
+ health_bar_entities: [null, null, null, null]
4223
+ // Transient
4224
+ }
4207
4225
  };
4208
4226
  }
4209
4227
  restore(snapshot, callbackRegistry) {
4210
4228
  this.currentTimeSeconds = snapshot.timeSeconds;
4211
4229
  this.crossLevelFlags = snapshot.crossLevelFlags ?? 0;
4212
4230
  this.crossUnitFlags = snapshot.crossUnitFlags ?? 0;
4231
+ if (snapshot.level) {
4232
+ this.level = { ...snapshot.level };
4233
+ this.level.health_bar_entities = [null, null, null, null];
4234
+ }
4213
4235
  this.pool.restore(snapshot.pool);
4214
4236
  const indexToEntity = /* @__PURE__ */ new Map();
4215
4237
  for (const entity of this.pool) {
@@ -5601,6 +5623,82 @@ function registerTargetSpawns(registry) {
5601
5623
  entity.movedir = { x: start, y: end, z: slope };
5602
5624
  }
5603
5625
  });
5626
+ registry.register("target_music", (entity, { entities, keyValues }) => {
5627
+ entity.sounds = keyValues.sounds ? parseInt(keyValues.sounds) : 0;
5628
+ entity.use = (self) => {
5629
+ entities.imports.configstring(ConfigStringIndex.CdTrack, `${self.sounds}`);
5630
+ };
5631
+ });
5632
+ registry.register("target_autosave", (entity, context) => {
5633
+ entity.use = (self) => {
5634
+ const saveTime = 60;
5635
+ if (context.entities.timeSeconds - context.entities.level.next_auto_save > saveTime) {
5636
+ context.entities.imports.serverCommand("autosave\n");
5637
+ context.entities.level.next_auto_save = context.entities.timeSeconds;
5638
+ }
5639
+ };
5640
+ });
5641
+ registry.register("target_healthbar", (entity, { entities, warn, free }) => {
5642
+ entity.use = (self) => {
5643
+ const target = entities.pickTarget(self.target);
5644
+ if (!target || self.health !== target.spawn_count) {
5645
+ if (target) {
5646
+ warn(`${self.classname}: target ${target.classname} changed from what it used to be`);
5647
+ } else {
5648
+ warn(`${self.classname}: no target`);
5649
+ }
5650
+ entities.free(self);
5651
+ return;
5652
+ }
5653
+ const level = entities.level;
5654
+ let found = false;
5655
+ for (let i = 0; i < 4; i++) {
5656
+ if (!level.health_bar_entities[i]) {
5657
+ self.enemy = target;
5658
+ level.health_bar_entities[i] = self;
5659
+ entities.imports.configstring(ConfigStringIndex.HealthBarName, self.message || "");
5660
+ found = true;
5661
+ break;
5662
+ }
5663
+ }
5664
+ if (!found) {
5665
+ warn(`${self.classname}: too many health bars`);
5666
+ entities.free(self);
5667
+ }
5668
+ };
5669
+ entity.think = (self) => {
5670
+ const target = entities.pickTarget(self.target);
5671
+ if (!target || !(target.svflags & 4 /* Monster */)) {
5672
+ if (target) {
5673
+ warn(`${self.classname}: target ${target.classname} does not appear to be a monster`);
5674
+ }
5675
+ entities.free(self);
5676
+ return;
5677
+ }
5678
+ const level = entities.level;
5679
+ if (level.health_bar_entities) {
5680
+ let registered = false;
5681
+ for (let i = 0; i < 4; i++) {
5682
+ if (level.health_bar_entities[i] === self) {
5683
+ registered = true;
5684
+ break;
5685
+ }
5686
+ }
5687
+ if (!registered) {
5688
+ for (let i = 0; i < 4; i++) {
5689
+ if (!level.health_bar_entities[i]) {
5690
+ level.health_bar_entities[i] = self;
5691
+ entities.imports.configstring(ConfigStringIndex.HealthBarName, self.message || "");
5692
+ break;
5693
+ }
5694
+ }
5695
+ }
5696
+ }
5697
+ self.health = target.spawn_count;
5698
+ self.nextthink = entities.timeSeconds + 0.1;
5699
+ };
5700
+ entity.nextthink = entities.timeSeconds + 0.1;
5701
+ });
5604
5702
  }
5605
5703
 
5606
5704
  // src/entities/triggers.ts
@@ -7386,40 +7484,80 @@ init_esm();
7386
7484
  // src/entities/gibs.ts
7387
7485
  init_esm();
7388
7486
  var random3 = createRandomGenerator();
7487
+ var GIB_ORGANIC = 0;
7389
7488
  var GIB_METALLIC = 1;
7390
7489
  var GIB_DEBRIS = 2;
7391
- function spawnGib(sys, origin, damage, model, type) {
7490
+ function velocityForDamage(damage) {
7491
+ let x = 100 * random3.crandom();
7492
+ let y = 100 * random3.crandom();
7493
+ let z = 200 + 100 * random3.frandom();
7494
+ if (damage < 50) {
7495
+ x *= 0.7;
7496
+ y *= 0.7;
7497
+ z *= 0.7;
7498
+ } else {
7499
+ x *= 1.2;
7500
+ y *= 1.2;
7501
+ z *= 1.2;
7502
+ }
7503
+ return { x, y, z };
7504
+ }
7505
+ function clipGibVelocity(ent) {
7506
+ let { x, y, z } = ent.velocity;
7507
+ if (x < -300) x = -300;
7508
+ else if (x > 300) x = 300;
7509
+ if (y < -300) y = -300;
7510
+ else if (y > 300) y = 300;
7511
+ if (z < 200) z = 200;
7512
+ else if (z > 500) z = 500;
7513
+ ent.velocity = { x, y, z };
7514
+ }
7515
+ function gib_touch(self, other, plane, surf, sys) {
7516
+ if (!self.groundentity) return;
7517
+ self.touch = void 0;
7518
+ if (plane) {
7519
+ sys.sound(self, 0, "misc/fhit3.wav", 1, 1, 0);
7520
+ }
7521
+ }
7522
+ function spawnGib(sys, origin, damage, model, type = GIB_ORGANIC) {
7392
7523
  const gib = sys.spawn();
7393
7524
  gib.classname = "gib";
7394
7525
  gib.origin = {
7395
- x: origin.x + (random3.frandom() - 0.5) * 20,
7396
- y: origin.y + (random3.frandom() - 0.5) * 20,
7397
- z: origin.z + (random3.frandom() - 0.5) * 20
7398
- };
7399
- gib.velocity = {
7400
- x: (random3.frandom() - 0.5) * 300,
7401
- y: (random3.frandom() - 0.5) * 300,
7402
- z: 200 + random3.frandom() * 100
7526
+ x: origin.x + random3.crandom() * 20,
7527
+ y: origin.y + random3.crandom() * 20,
7528
+ z: origin.z + random3.crandom() * 20
7403
7529
  };
7404
- gib.movetype = 9 /* Bounce */;
7405
- gib.solid = 0 /* Not */;
7406
- gib.clipmask = 1;
7407
- gib.avelocity = {
7408
- x: random3.crandom() * 600,
7409
- y: random3.crandom() * 600,
7410
- z: random3.crandom() * 600
7411
- };
7412
- const defaultModels = [
7413
- "models/objects/gibs/bone/tris.md2",
7414
- "models/objects/gibs/meat/tris.md2",
7415
- "models/objects/gibs/sm_meat/tris.md2"
7416
- ];
7417
- const modelName = model || defaultModels[Math.floor(random3.frandom() * defaultModels.length)];
7530
+ const modelName = model || "models/objects/gibs/sm_meat/tris.md2";
7418
7531
  gib.modelindex = sys.modelIndex(modelName);
7419
7532
  gib.mins = { x: -2, y: -2, z: -2 };
7420
7533
  gib.maxs = { x: 2, y: 2, z: 2 };
7421
- if (type && type & GIB_METALLIC) {
7534
+ gib.solid = 0 /* Not */;
7535
+ gib.takedamage = true;
7536
+ gib.die = (self, inflictor, attacker, dmg, point, mod) => {
7537
+ sys.free(self);
7538
+ };
7539
+ gib.clipmask = 1;
7540
+ let vscale = 1;
7541
+ if (type === GIB_ORGANIC) {
7542
+ gib.movetype = 7 /* Toss */;
7543
+ gib.touch = (self, other, plane, surf) => gib_touch(self, other, plane, surf, sys);
7544
+ vscale = 0.5;
7545
+ } else {
7546
+ gib.movetype = 9 /* Bounce */;
7547
+ vscale = 1;
7422
7548
  }
7549
+ const vd = velocityForDamage(damage);
7550
+ gib.velocity = {
7551
+ x: vd.x * vscale,
7552
+ y: vd.y * vscale,
7553
+ z: vd.z * vscale
7554
+ };
7555
+ clipGibVelocity(gib);
7556
+ gib.avelocity = {
7557
+ x: random3.frandom() * 600,
7558
+ y: random3.frandom() * 600,
7559
+ z: random3.frandom() * 600
7560
+ };
7423
7561
  gib.think = (self) => {
7424
7562
  sys.free(self);
7425
7563
  };
@@ -7427,13 +7565,58 @@ function spawnGib(sys, origin, damage, model, type) {
7427
7565
  sys.finalizeSpawn(gib);
7428
7566
  return gib;
7429
7567
  }
7568
+ function spawnHead(sys, origin, damage) {
7569
+ const head = sys.spawn();
7570
+ let gibname;
7571
+ if (random3.irandom(2) === 1) {
7572
+ gibname = "models/objects/gibs/head2/tris.md2";
7573
+ head.skin = 1;
7574
+ } else {
7575
+ gibname = "models/objects/gibs/skull/tris.md2";
7576
+ head.skin = 0;
7577
+ }
7578
+ head.frame = 0;
7579
+ head.modelindex = sys.modelIndex(gibname);
7580
+ head.mins = { x: -16, y: -16, z: 0 };
7581
+ head.maxs = { x: 16, y: 16, z: 16 };
7582
+ head.origin = {
7583
+ x: origin.x,
7584
+ y: origin.y,
7585
+ z: origin.z + 32
7586
+ };
7587
+ head.solid = 0 /* Not */;
7588
+ head.takedamage = true;
7589
+ head.die = (self, inflictor, attacker, dmg, point, mod) => {
7590
+ sys.free(self);
7591
+ };
7592
+ let vscale = 0.5;
7593
+ head.movetype = 7 /* Toss */;
7594
+ head.touch = (self, other, plane, surf) => gib_touch(self, other, plane, surf, sys);
7595
+ const vd = velocityForDamage(damage);
7596
+ head.velocity = {
7597
+ x: vd.x * vscale,
7598
+ y: vd.y * vscale,
7599
+ z: vd.z * vscale
7600
+ };
7601
+ clipGibVelocity(head);
7602
+ head.avelocity = { x: 0, y: random3.crandom() * 600, z: 0 };
7603
+ head.think = (self) => {
7604
+ sys.free(self);
7605
+ };
7606
+ sys.scheduleThink(head, sys.timeSeconds + 10 + random3.frandom() * 10);
7607
+ sys.finalizeSpawn(head);
7608
+ return head;
7609
+ }
7430
7610
  function throwGibs(sys, origin, damageOrDefs) {
7431
7611
  if (typeof damageOrDefs === "number") {
7432
7612
  const damage = damageOrDefs;
7433
- const count = 4 + Math.floor(random3.frandom() * 4);
7434
- for (let i = 0; i < count; i++) {
7435
- spawnGib(sys, origin, damage);
7436
- }
7613
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7614
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7615
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7616
+ spawnGib(sys, origin, damage, "models/objects/gibs/sm_meat/tris.md2", GIB_ORGANIC);
7617
+ spawnGib(sys, origin, damage, "models/objects/gibs/meat/tris.md2", GIB_ORGANIC);
7618
+ spawnGib(sys, origin, damage, "models/objects/gibs/bone/tris.md2", GIB_ORGANIC);
7619
+ spawnHead(sys, origin, damage);
7437
7620
  } else {
7438
7621
  const defs = damageOrDefs;
7439
7622
  for (const def of defs) {
@@ -17850,7 +18033,11 @@ function parseEntitySnapshot(raw) {
17850
18033
  thinks: parseThinkEntries(snapshot.thinks),
17851
18034
  awareness: parseAwareness(snapshot.awareness),
17852
18035
  crossLevelFlags: ensureNumberOrDefault(snapshot.crossLevelFlags, "entities.crossLevelFlags", 0),
17853
- crossUnitFlags: ensureNumberOrDefault(snapshot.crossUnitFlags, "entities.crossUnitFlags", 0)
18036
+ crossUnitFlags: ensureNumberOrDefault(snapshot.crossUnitFlags, "entities.crossUnitFlags", 0),
18037
+ level: {
18038
+ next_auto_save: 0,
18039
+ health_bar_entities: [null, null, null, null]
18040
+ }
17854
18041
  };
17855
18042
  }
17856
18043
  function parseCvars(raw) {
@@ -18214,7 +18401,11 @@ function buildEntitySnapshot(entities, levelTimeSeconds, capacityHint) {
18214
18401
  thinks: [],
18215
18402
  awareness: dummyAwareness,
18216
18403
  crossLevelFlags: 0,
18217
- crossUnitFlags: 0
18404
+ crossUnitFlags: 0,
18405
+ level: {
18406
+ next_auto_save: 0,
18407
+ health_bar_entities: [null, null, null, null]
18408
+ }
18218
18409
  };
18219
18410
  }
18220
18411
  function buildLevelState(level) {
@@ -19125,6 +19316,8 @@ function createGame(imports, engine, options) {
19125
19316
  });
19126
19317
  const configstring = imports.configstring || (() => {
19127
19318
  });
19319
+ const serverCommand = imports.serverCommand || (() => {
19320
+ });
19128
19321
  const linkentity = imports.linkentity;
19129
19322
  const wrappedLinkEntity = (ent) => {
19130
19323
  ent.absmin = {
@@ -19148,7 +19341,8 @@ function createGame(imports, engine, options) {
19148
19341
  linkentity: wrappedLinkEntity,
19149
19342
  multicast,
19150
19343
  unicast,
19151
- configstring
19344
+ configstring,
19345
+ serverCommand
19152
19346
  };
19153
19347
  const entities = new EntitySystem(engine, systemImports, gravity, void 0, void 0, deathmatch);
19154
19348
  entities._game = {
@@ -19416,6 +19610,9 @@ function createGame(imports, engine, options) {
19416
19610
  configstring(index, value) {
19417
19611
  configstring(index, value);
19418
19612
  },
19613
+ serverCommand(cmd) {
19614
+ serverCommand(cmd);
19615
+ },
19419
19616
  get time() {
19420
19617
  return levelClock.current.timeSeconds;
19421
19618
  },