quake2ts 0.0.167 → 0.0.169

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.
@@ -1415,6 +1415,10 @@ var Entity = class {
1415
1415
  this.max_health = 0;
1416
1416
  this.takedamage = false;
1417
1417
  this.dmg = 0;
1418
+ this.radius_dmg = 0;
1419
+ // Damage amount for radius damage (used by BFG, rockets, etc.)
1420
+ this.dmg_radius = 0;
1421
+ // Radius for damage effects
1418
1422
  this.speed = 0;
1419
1423
  this.accel = 0;
1420
1424
  this.decel = 0;
@@ -2768,7 +2772,7 @@ function deserializeInventory(value) {
2768
2772
  return parsed;
2769
2773
  }
2770
2774
  var EntitySystem = class {
2771
- constructor(engine, imports, gravity, maxEntities, callbackRegistry) {
2775
+ constructor(engine, imports, gravity, maxEntities, callbackRegistry, deathmatch) {
2772
2776
  this.targetNameIndex = /* @__PURE__ */ new Map();
2773
2777
  this.random = createRandomGenerator();
2774
2778
  this.currentTimeSeconds = 0;
@@ -2776,6 +2780,7 @@ var EntitySystem = class {
2776
2780
  this.pool = new EntityPool(maxEntities);
2777
2781
  this.thinkScheduler = new ThinkScheduler();
2778
2782
  this.engine = engine;
2783
+ this.deathmatch = deathmatch ?? false;
2779
2784
  this.imports = imports || {
2780
2785
  trace: () => ({
2781
2786
  allsolid: false,
@@ -5587,58 +5592,211 @@ function createBlasterBolt(sys, owner, start, dir, damage, speed, mod) {
5587
5592
  };
5588
5593
  sys.finalizeSpawn(bolt);
5589
5594
  }
5595
+ function fireBfgPiercingLaser(sys, bfg, target, damage) {
5596
+ const start = { ...bfg.origin };
5597
+ const targetCenter2 = {
5598
+ x: (target.absmin.x + target.absmax.x) * 0.5,
5599
+ y: (target.absmin.y + target.absmax.y) * 0.5,
5600
+ z: (target.absmin.z + target.absmax.z) * 0.5
5601
+ };
5602
+ const dir = normalizeVec3(subtractVec3(targetCenter2, start));
5603
+ const end = {
5604
+ x: start.x + dir.x * 2048,
5605
+ y: start.y + dir.y * 2048,
5606
+ z: start.z + dir.z * 2048
5607
+ };
5608
+ const MAX_PIERCE = 16;
5609
+ const pierced = [];
5610
+ const piercedSolidities = [];
5611
+ let currentStart = { ...start };
5612
+ try {
5613
+ for (let i = 0; i < MAX_PIERCE; i++) {
5614
+ const tr = sys.trace(
5615
+ currentStart,
5616
+ null,
5617
+ null,
5618
+ end,
5619
+ bfg,
5620
+ CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER | CONTENTS_DEADMONSTER
5621
+ );
5622
+ if (!tr.ent || tr.fraction >= 1) {
5623
+ break;
5624
+ }
5625
+ if (tr.ent.takedamage && tr.ent !== bfg.owner) {
5626
+ T_Damage(
5627
+ tr.ent,
5628
+ bfg,
5629
+ bfg.owner,
5630
+ dir,
5631
+ tr.endpos,
5632
+ ZERO_VEC3,
5633
+ damage,
5634
+ 1,
5635
+ // kick
5636
+ 4 /* ENERGY */,
5637
+ 12 /* BFG_LASER */,
5638
+ sys.multicast.bind(sys)
5639
+ );
5640
+ }
5641
+ if (!(tr.ent.svflags & 4 /* Monster */) && !tr.ent.client && tr.ent.classname !== "misc_explobox") {
5642
+ break;
5643
+ }
5644
+ pierced.push(tr.ent);
5645
+ piercedSolidities.push(tr.ent.solid);
5646
+ tr.ent.solid = 0 /* Not */;
5647
+ currentStart = { ...tr.endpos };
5648
+ }
5649
+ const finalTrace = sys.trace(start, null, null, end, bfg, CONTENTS_SOLID);
5650
+ sys.multicast(
5651
+ bfg.origin,
5652
+ 2 /* Phs */,
5653
+ ServerCommand.temp_entity,
5654
+ TempEntity.BFG_LASER,
5655
+ start,
5656
+ finalTrace.endpos
5657
+ );
5658
+ } finally {
5659
+ for (let i = 0; i < pierced.length; i++) {
5660
+ pierced[i].solid = piercedSolidities[i];
5661
+ }
5662
+ }
5663
+ }
5664
+ function bfgThink(self, sys) {
5665
+ const dmg = sys.deathmatch ? 5 : 10;
5666
+ const nearbyEntities = sys.findByRadius(self.origin, 256);
5667
+ for (const ent of nearbyEntities) {
5668
+ if (ent === self || ent === self.owner) {
5669
+ continue;
5670
+ }
5671
+ if (!ent.takedamage) {
5672
+ continue;
5673
+ }
5674
+ if (!(ent.svflags & 4 /* Monster */) && !ent.client && ent.classname !== "misc_explobox") {
5675
+ continue;
5676
+ }
5677
+ const point = {
5678
+ x: (ent.absmin.x + ent.absmax.x) * 0.5,
5679
+ y: (ent.absmin.y + ent.absmax.y) * 0.5,
5680
+ z: (ent.absmin.z + ent.absmax.z) * 0.5
5681
+ };
5682
+ const sightTrace = sys.trace(self.origin, null, null, point, null, MASK_SOLID);
5683
+ if (sightTrace.fraction < 1) {
5684
+ continue;
5685
+ }
5686
+ fireBfgPiercingLaser(sys, self, ent, dmg);
5687
+ }
5688
+ sys.scheduleThink(self, sys.timeSeconds + 0.1);
5689
+ }
5690
+ function bfgExplode(self, sys) {
5691
+ if (self.frame === void 0 || self.frame < 0) {
5692
+ self.frame = 0;
5693
+ }
5694
+ if (self.frame === 0) {
5695
+ const entities = sys.findByRadius(self.origin, self.dmg_radius || 100);
5696
+ for (const ent of entities) {
5697
+ if (!ent.takedamage) continue;
5698
+ if (ent === self.owner) continue;
5699
+ if (!(ent.svflags & 4 /* Monster */) && !ent.client && ent.classname !== "misc_explobox") {
5700
+ continue;
5701
+ }
5702
+ const centroid = {
5703
+ x: (ent.absmin.x + ent.absmax.x) * 0.5,
5704
+ y: (ent.absmin.y + ent.absmax.y) * 0.5,
5705
+ z: (ent.absmin.z + ent.absmax.z) * 0.5
5706
+ };
5707
+ const delta = subtractVec3(self.origin, centroid);
5708
+ const dist = lengthVec3(delta);
5709
+ const dmgRadius = self.dmg_radius || 100;
5710
+ const points = (self.radius_dmg || 200) * (1 - Math.sqrt(dist / dmgRadius));
5711
+ if (points > 0) {
5712
+ T_Damage(
5713
+ ent,
5714
+ self,
5715
+ self.owner,
5716
+ self.velocity,
5717
+ centroid,
5718
+ ZERO_VEC3,
5719
+ Math.floor(points),
5720
+ 0,
5721
+ 4 /* ENERGY */,
5722
+ 14 /* BFG_EFFECT */,
5723
+ sys.multicast.bind(sys)
5724
+ );
5725
+ }
5726
+ }
5727
+ }
5728
+ self.frame++;
5729
+ if (self.frame >= 5) {
5730
+ sys.free(self);
5731
+ return;
5732
+ }
5733
+ sys.scheduleThink(self, sys.timeSeconds + 0.1);
5734
+ }
5590
5735
  function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5591
5736
  const bfgBall = sys.spawn();
5592
- bfgBall.classname = "bfg_ball";
5737
+ bfgBall.classname = "bfg blast";
5593
5738
  bfgBall.owner = owner;
5594
5739
  bfgBall.origin = { ...start };
5595
5740
  bfgBall.velocity = { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed };
5596
5741
  bfgBall.movetype = 8 /* FlyMissile */;
5597
5742
  bfgBall.clipmask = 268566530;
5598
5743
  bfgBall.solid = 2 /* BoundingBox */;
5599
- bfgBall.modelindex = sys.modelIndex("models/objects/bfgball/tris.md2");
5744
+ bfgBall.modelindex = sys.modelIndex("sprites/s_bfg1.sp2");
5745
+ bfgBall.svflags = 128 /* Projectile */;
5746
+ bfgBall.radius_dmg = damage;
5747
+ bfgBall.dmg_radius = damageRadius;
5600
5748
  bfgBall.mins = { x: -10, y: -10, z: -10 };
5601
5749
  bfgBall.maxs = { x: 10, y: 10, z: 10 };
5602
5750
  bfgBall.touch = (self, other, plane, surf) => {
5603
5751
  if (other === self.owner) {
5604
5752
  return;
5605
5753
  }
5606
- const entities = sys.findByRadius(self.origin, damageRadius);
5607
- T_RadiusDamage(entities, self, self.owner, damage, self.owner, damageRadius, 0 /* NONE */, 13 /* BFG_BLAST */, {}, sys.multicast.bind(sys));
5608
- sys.multicast(self.origin, 2 /* Phs */, ServerCommand.temp_entity, TempEntity.BFG_EXPLOSION, self.origin);
5609
- if (self.owner) {
5610
- const targets = sys.findByRadius(self.origin, 1e3);
5611
- const playerOrigin = self.owner.origin;
5612
- for (const target of targets) {
5613
- if (target === self.owner || !target.takedamage) continue;
5614
- const tr = sys.trace(playerOrigin, null, null, target.origin, self.owner, 1 | 2);
5615
- if (tr.ent !== target && tr.fraction < 1) {
5616
- continue;
5617
- }
5618
- const dir2 = normalizeVec3(subtractVec3(target.origin, self.origin));
5619
- let laserDamage = 10;
5620
- T_Damage(
5621
- target,
5622
- self,
5623
- self.owner,
5624
- dir2,
5625
- target.origin,
5626
- ZERO_VEC3,
5627
- laserDamage,
5628
- 10,
5629
- 4 /* ENERGY */,
5630
- 12 /* BFG_LASER */,
5631
- sys.multicast.bind(sys)
5632
- );
5633
- sys.multicast(self.origin, 2 /* Phs */, ServerCommand.temp_entity, TempEntity.BFG_LASER, playerOrigin, target.origin);
5634
- }
5754
+ if (other && other.takedamage) {
5755
+ T_Damage(
5756
+ other,
5757
+ self,
5758
+ self.owner,
5759
+ self.velocity,
5760
+ self.origin,
5761
+ plane ? plane.normal : ZERO_VEC3,
5762
+ 200,
5763
+ 0,
5764
+ 4 /* ENERGY */,
5765
+ 13 /* BFG_BLAST */,
5766
+ sys.multicast.bind(sys)
5767
+ );
5635
5768
  }
5636
- sys.free(self);
5637
- };
5638
- bfgBall.think = (self) => {
5639
- self.nextthink = sys.timeSeconds + 0.1;
5640
- };
5641
- sys.scheduleThink(bfgBall, sys.timeSeconds + 0.1);
5769
+ const entities = sys.findByRadius(self.origin, 100);
5770
+ T_RadiusDamage(
5771
+ entities,
5772
+ self,
5773
+ self.owner,
5774
+ 200,
5775
+ other,
5776
+ 100,
5777
+ 4 /* ENERGY */,
5778
+ 13 /* BFG_BLAST */,
5779
+ {},
5780
+ sys.multicast.bind(sys)
5781
+ );
5782
+ sys.multicast(
5783
+ self.origin,
5784
+ 2 /* Phs */,
5785
+ ServerCommand.temp_entity,
5786
+ TempEntity.BFG_BIGEXPLOSION,
5787
+ self.origin
5788
+ );
5789
+ self.solid = 0 /* Not */;
5790
+ self.touch = void 0;
5791
+ self.velocity = ZERO_VEC3;
5792
+ self.modelindex = sys.modelIndex("sprites/s_bfg3.sp2");
5793
+ self.frame = 0;
5794
+ self.enemy = other;
5795
+ self.think = (self2, context) => bfgExplode(self2, context);
5796
+ sys.scheduleThink(self, sys.timeSeconds + 0.1);
5797
+ };
5798
+ bfgBall.think = (self, context) => bfgThink(self, context);
5799
+ sys.scheduleThink(bfgBall, sys.timeSeconds + 0.016);
5642
5800
  sys.finalizeSpawn(bfgBall);
5643
5801
  }
5644
5802
 
@@ -12458,7 +12616,7 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12458
12616
  z: ent.origin.z + ent.maxs.z
12459
12617
  };
12460
12618
  };
12461
- const entities = new EntitySystem(engine, { trace, pointcontents, linkentity, multicast, unicast }, gravity);
12619
+ const entities = new EntitySystem(engine, { trace, pointcontents, linkentity, multicast, unicast }, gravity, void 0, void 0, deathmatch);
12462
12620
  frameLoop.addStage("prep", (context) => {
12463
12621
  levelClock.tick(context);
12464
12622
  entities.beginFrame(levelClock.current.timeSeconds);