quake2ts 0.0.174 → 0.0.176

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 (42) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +3 -3
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs.map +1 -1
  5. package/packages/client/dist/esm/index.js.map +1 -1
  6. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  7. package/packages/engine/dist/browser/index.global.js +8 -8
  8. package/packages/engine/dist/browser/index.global.js.map +1 -1
  9. package/packages/engine/dist/cjs/index.cjs +64 -3
  10. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  11. package/packages/engine/dist/esm/index.js +64 -3
  12. package/packages/engine/dist/esm/index.js.map +1 -1
  13. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  14. package/packages/engine/dist/types/assets/bsp.d.ts +18 -0
  15. package/packages/engine/dist/types/assets/bsp.d.ts.map +1 -1
  16. package/packages/engine/dist/types/render/bsp/geometry.d.ts +4 -1
  17. package/packages/engine/dist/types/render/bsp/geometry.d.ts.map +1 -1
  18. package/packages/game/dist/browser/index.global.js +2 -2
  19. package/packages/game/dist/browser/index.global.js.map +1 -1
  20. package/packages/game/dist/cjs/index.cjs +120 -70
  21. package/packages/game/dist/cjs/index.cjs.map +1 -1
  22. package/packages/game/dist/esm/index.js +120 -70
  23. package/packages/game/dist/esm/index.js.map +1 -1
  24. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  25. package/packages/game/dist/types/combat/damage.d.ts +2 -2
  26. package/packages/game/dist/types/combat/damage.d.ts.map +1 -1
  27. package/packages/game/dist/types/combat/specialDamage.d.ts.map +1 -1
  28. package/packages/game/dist/types/combat/weapons/firing.d.ts.map +1 -1
  29. package/packages/game/dist/types/entities/monsters/attack.d.ts.map +1 -1
  30. package/packages/game/dist/types/entities/monsters/berserk.d.ts.map +1 -1
  31. package/packages/game/dist/types/entities/monsters/mutant.d.ts.map +1 -1
  32. package/packages/game/dist/types/entities/monsters/parasite.d.ts.map +1 -1
  33. package/packages/game/dist/types/entities/projectiles/rocket.d.ts.map +1 -1
  34. package/packages/game/dist/types/entities/projectiles.d.ts.map +1 -1
  35. package/packages/game/dist/types/index.d.ts +2 -0
  36. package/packages/game/dist/types/index.d.ts.map +1 -1
  37. package/packages/game/dist/types/inventory/playerInventory.d.ts +3 -1
  38. package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
  39. package/packages/server/dist/index.cjs +38 -24
  40. package/packages/server/dist/index.d.cts +5 -6
  41. package/packages/server/dist/index.d.ts +5 -6
  42. package/packages/server/dist/index.js +38 -24
@@ -1367,7 +1367,8 @@ function pickupArmor(inventory, item, time) {
1367
1367
  }
1368
1368
  return false;
1369
1369
  }
1370
- function pickupPowerup(inventory, item, time) {
1370
+ function pickupPowerup(client, item, time) {
1371
+ const inventory = client.inventory;
1371
1372
  let powerupId = null;
1372
1373
  let icon = "";
1373
1374
  switch (item.id) {
@@ -1391,13 +1392,19 @@ function pickupPowerup(inventory, item, time) {
1391
1392
  powerupId = "enviro_suit" /* EnviroSuit */;
1392
1393
  icon = "p_envirosuit";
1393
1394
  break;
1395
+ case "item_double":
1396
+ powerupId = "double_damage" /* DoubleDamage */;
1397
+ icon = "p_double";
1398
+ break;
1394
1399
  }
1395
1400
  if (powerupId) {
1396
1401
  const expiresAt = inventory.powerups.get(powerupId);
1397
- if (expiresAt && expiresAt > time) {
1398
- inventory.powerups.set(powerupId, expiresAt + item.timer);
1399
- } else {
1400
- inventory.powerups.set(powerupId, time + item.timer);
1402
+ const newExpiresAt = expiresAt && expiresAt > time ? expiresAt + item.timer * 1e3 : time + item.timer * 1e3;
1403
+ inventory.powerups.set(powerupId, newExpiresAt);
1404
+ if (powerupId === "quad" /* QuadDamage */) {
1405
+ client.quad_time = newExpiresAt / 1e3;
1406
+ } else if (powerupId === "double_damage" /* DoubleDamage */) {
1407
+ client.double_time = newExpiresAt / 1e3;
1401
1408
  }
1402
1409
  setPickup(inventory, icon, time);
1403
1410
  return true;
@@ -4392,7 +4399,7 @@ function createPowerupPickupEntity(game, powerupItem) {
4392
4399
  if (!other || !other.client) {
4393
4400
  return;
4394
4401
  }
4395
- if (pickupPowerup(other.client.inventory, powerupItem, game.time * 1e3)) {
4402
+ if (pickupPowerup(other.client, powerupItem, game.time * 1e3)) {
4396
4403
  game.sound?.(other, 0, "items/pkup.wav", 1, 1, 0);
4397
4404
  game.centerprintf?.(other, `You got the ${powerupItem.name}`);
4398
4405
  self.solid = 0 /* Not */;
@@ -4894,6 +4901,23 @@ var EntityDamageFlags = /* @__PURE__ */ ((EntityDamageFlags2) => {
4894
4901
  EntityDamageFlags2[EntityDamageFlags2["NO_DAMAGE_EFFECTS"] = 8] = "NO_DAMAGE_EFFECTS";
4895
4902
  return EntityDamageFlags2;
4896
4903
  })(EntityDamageFlags || {});
4904
+ function getDamageModifier(attacker, time) {
4905
+ if (!attacker) {
4906
+ return 1;
4907
+ }
4908
+ const client = attacker.client;
4909
+ if (!client) {
4910
+ return 1;
4911
+ }
4912
+ let modifier = 1;
4913
+ if (client.quad_time && client.quad_time > time) {
4914
+ modifier *= 4;
4915
+ }
4916
+ if (client.double_time && client.double_time > time) {
4917
+ modifier *= 2;
4918
+ }
4919
+ return modifier;
4920
+ }
4897
4921
  function applyKnockback(targ, attacker, dir, knockback, dflags) {
4898
4922
  const hasNoKnockback = hasAnyDamageFlag(dflags, 8 /* NO_KNOCKBACK */) || ((targ.flags ?? 0) & 4 /* NO_KNOCKBACK */) !== 0;
4899
4923
  if (hasNoKnockback || knockback === 0) {
@@ -4936,22 +4960,25 @@ function targetCenter(ent) {
4936
4960
  }
4937
4961
  return ent.origin;
4938
4962
  }
4939
- function T_Damage(targ, inflictor, attacker, dir, point, normal, damage, knockback, dflags, mod, multicast) {
4940
- if (!targ.takedamage || damage <= 0) {
4963
+ function T_Damage(targ, inflictor, attacker, dir, point, normal, damage, knockback, dflags, mod, time, multicast) {
4964
+ if (!targ.takedamage) {
4941
4965
  return null;
4942
4966
  }
4943
- const protectedByGod = !hasAnyDamageFlag(dflags, 32 /* NO_PROTECTION */) && ((targ.flags ?? 0) & 1 /* GODMODE */) !== 0;
4967
+ const modifier = getDamageModifier(attacker, time);
4968
+ const modifiedDamage = damage * modifier;
4969
+ const modifiedKnockback = knockback * modifier;
4970
+ const protectedByGod = !hasAnyDamageFlag(dflags, 32 /* NO_PROTECTION */) && ((targ.flags ?? 0) & 1 /* GODMODE */) !== 0 && modifiedDamage > 0;
4944
4971
  if (protectedByGod) {
4945
4972
  return {
4946
4973
  take: 0,
4947
4974
  psave: 0,
4948
- asave: damage,
4975
+ asave: modifiedDamage,
4949
4976
  knocked: { x: 0, y: 0, z: 0 },
4950
4977
  killed: false
4951
4978
  };
4952
4979
  }
4953
- const knocked = applyKnockback(targ, attacker, dir, knockback, dflags);
4954
- const [take, psave, asave, remainingCells, remainingArmor] = applyProtection(targ, point, normal, damage, dflags);
4980
+ const knocked = applyKnockback(targ, attacker, dir, modifiedKnockback, dflags);
4981
+ const [take, psave, asave, remainingCells, remainingArmor] = applyProtection(targ, point, normal, modifiedDamage, dflags);
4955
4982
  if (targ.powerArmor && remainingCells !== void 0) {
4956
4983
  targ.powerArmor.cellCount = remainingCells;
4957
4984
  }
@@ -4980,7 +5007,7 @@ function T_Damage(targ, inflictor, attacker, dir, point, normal, damage, knockba
4980
5007
  }
4981
5008
  return { take: actualTake, psave, asave, knocked, killed, remainingCells, remainingArmor };
4982
5009
  }
4983
- function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, dflags, mod, options = {}, multicast) {
5010
+ function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, dflags, mod, time, options = {}, multicast) {
4984
5011
  const hits = [];
4985
5012
  const inflictorCenter = targetCenter(inflictor);
4986
5013
  const canDamage = options.canDamage ?? (() => true);
@@ -5000,7 +5027,7 @@ function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, d
5000
5027
  }
5001
5028
  const adjustedDamage = ent === attacker ? points * 0.5 : points;
5002
5029
  const dir = normalizeVec3(subtractVec3(ent.origin, inflictorCenter));
5003
- const result = T_Damage(ent, inflictor, attacker, dir, entCenter, dir, adjustedDamage, adjustedDamage, dflags | 1 /* RADIUS */, mod, multicast);
5030
+ const result = T_Damage(ent, inflictor, attacker, dir, entCenter, dir, adjustedDamage, adjustedDamage, dflags | 1 /* RADIUS */, mod, time, multicast);
5004
5031
  hits.push({ target: ent, result, appliedDamage: adjustedDamage });
5005
5032
  }
5006
5033
  return hits;
@@ -5349,6 +5376,7 @@ function fire_hit(self, aim, damage, kick, context) {
5349
5376
  kick,
5350
5377
  0 /* NONE */,
5351
5378
  0 /* UNKNOWN */,
5379
+ context.timeSeconds,
5352
5380
  context.multicast.bind(context)
5353
5381
  );
5354
5382
  return true;
@@ -5431,7 +5459,7 @@ function berserk_attack_slam(self, context) {
5431
5459
  const points = Math.max(1, damage * amount * amount);
5432
5460
  const k = kick * amount * amount;
5433
5461
  const dir = normalizeVec3(subtractVec3(ent.origin, tr.endpos));
5434
- T_Damage(ent, self, self, dir, ent.origin, dir, points, k, 1 /* RADIUS */, 0 /* UNKNOWN */, context.multicast.bind(context));
5462
+ T_Damage(ent, self, self, dir, ent.origin, dir, points, k, 1 /* RADIUS */, 0 /* UNKNOWN */, context.timeSeconds, context.multicast.bind(context));
5435
5463
  if (ent.client) {
5436
5464
  const currentVel = { ...ent.velocity };
5437
5465
  currentVel.z = Math.max(270, currentVel.z);
@@ -5708,11 +5736,12 @@ function createRocket(sys, owner, start, dir, damage, radiusDamage, speed, flash
5708
5736
  0,
5709
5737
  0 /* NONE */,
5710
5738
  8 /* ROCKET */,
5739
+ sys.timeSeconds,
5711
5740
  sys.multicast.bind(sys)
5712
5741
  );
5713
5742
  }
5714
5743
  const entities = sys.findByRadius(self.origin, 120);
5715
- T_RadiusDamage(entities, self, self.owner, radiusDamage, self.owner, 120, 0 /* NONE */, 9 /* R_SPLASH */, {}, sys.multicast.bind(sys));
5744
+ T_RadiusDamage(entities, self, self.owner, radiusDamage, self.owner, 120, 0 /* NONE */, 9 /* R_SPLASH */, sys.timeSeconds, {}, sys.multicast.bind(sys));
5716
5745
  sys.multicast(self.origin, 2 /* Phs */, ServerCommand.temp_entity, TempEntity.ROCKET_EXPLOSION, self.origin);
5717
5746
  sys.free(self);
5718
5747
  };
@@ -5732,7 +5761,7 @@ function createGrenade(sys, owner, start, dir, damage, speed) {
5732
5761
  grenade.maxs = { x: 4, y: 4, z: 4 };
5733
5762
  const explode = (self) => {
5734
5763
  const entities = sys.findByRadius(self.origin, 120);
5735
- T_RadiusDamage(entities, self, self.owner, damage, self.owner, 120, 0 /* NONE */, 6 /* GRENADE */, {}, sys.multicast.bind(sys));
5764
+ T_RadiusDamage(entities, self, self.owner, damage, self.owner, 120, 0 /* NONE */, 6 /* GRENADE */, sys.timeSeconds, {}, sys.multicast.bind(sys));
5736
5765
  sys.multicast(self.origin, 2 /* Phs */, ServerCommand.temp_entity, TempEntity.GRENADE_EXPLOSION, self.origin);
5737
5766
  sys.free(self);
5738
5767
  };
@@ -5778,6 +5807,7 @@ function createBlasterBolt(sys, owner, start, dir, damage, speed, mod) {
5778
5807
  // Kick
5779
5808
  0 /* NONE */,
5780
5809
  mod,
5810
+ sys.timeSeconds,
5781
5811
  sys.multicast.bind(sys)
5782
5812
  );
5783
5813
  } else {
@@ -5832,6 +5862,7 @@ function fireBfgPiercingLaser(sys, bfg, target, damage) {
5832
5862
  // kick
5833
5863
  4 /* ENERGY */,
5834
5864
  12 /* BFG_LASER */,
5865
+ sys.timeSeconds,
5835
5866
  sys.multicast.bind(sys)
5836
5867
  );
5837
5868
  }
@@ -5917,6 +5948,7 @@ function bfgExplode(self, sys) {
5917
5948
  0,
5918
5949
  4 /* ENERGY */,
5919
5950
  14 /* BFG_EFFECT */,
5951
+ sys.timeSeconds,
5920
5952
  sys.multicast.bind(sys)
5921
5953
  );
5922
5954
  }
@@ -5960,6 +5992,7 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5960
5992
  0,
5961
5993
  4 /* ENERGY */,
5962
5994
  13 /* BFG_BLAST */,
5995
+ sys.timeSeconds,
5963
5996
  sys.multicast.bind(sys)
5964
5997
  );
5965
5998
  }
@@ -5973,6 +6006,7 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5973
6006
  100,
5974
6007
  4 /* ENERGY */,
5975
6008
  13 /* BFG_BLAST */,
6009
+ sys.timeSeconds,
5976
6010
  {},
5977
6011
  sys.multicast.bind(sys)
5978
6012
  );
@@ -6030,7 +6064,8 @@ function monster_fire_bullet_v2(self, start, dir, damage, kick, hspread, vspread
6030
6064
  damage,
6031
6065
  kick,
6032
6066
  16 /* BULLET */ | 2 /* NO_ARMOR */,
6033
- mod
6067
+ mod,
6068
+ context.timeSeconds
6034
6069
  );
6035
6070
  }
6036
6071
  var monster_fire_bullet = monster_fire_bullet_v2;
@@ -6066,7 +6101,8 @@ function monster_fire_railgun(self, start, aim, damage, kick, flashtype, context
6066
6101
  damage,
6067
6102
  kick,
6068
6103
  4 /* ENERGY */ | 2 /* NO_ARMOR */,
6069
- 11 /* RAILGUN */
6104
+ 11 /* RAILGUN */,
6105
+ context.timeSeconds
6070
6106
  );
6071
6107
  }
6072
6108
  }
@@ -6090,7 +6126,8 @@ function monster_fire_hit(self, aim, damage, kick, context) {
6090
6126
  damage,
6091
6127
  kick,
6092
6128
  0,
6093
- 0 /* UNKNOWN */
6129
+ 0 /* UNKNOWN */,
6130
+ context.timeSeconds
6094
6131
  );
6095
6132
  return true;
6096
6133
  }
@@ -6104,7 +6141,7 @@ function dabeam_update(self, context) {
6104
6141
  const end = addVec3(start, scaleVec3(self.movedir, 2048));
6105
6142
  const tr = context.trace(start, end, ZERO_VEC3, ZERO_VEC3, self, CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER | CONTENTS_DEADMONSTER);
6106
6143
  if (self.dmg > 0 && tr.ent && tr.ent.takedamage && tr.ent !== self.owner) {
6107
- T_Damage(tr.ent, self, self.owner, self.movedir, tr.endpos, ZERO_VEC3, self.dmg, 0, 4 /* ENERGY */, 31 /* TARGET_LASER */);
6144
+ T_Damage(tr.ent, self, self.owner, self.movedir, tr.endpos, ZERO_VEC3, self.dmg, 0, 4 /* ENERGY */, 31 /* TARGET_LASER */, context.timeSeconds);
6108
6145
  }
6109
6146
  if (tr.ent && tr.ent.solid === 3 /* Bsp */) {
6110
6147
  context.multicast(tr.endpos, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.LASER_SPARKS, 10, tr.endpos, tr.plane?.normal || ZERO_VEC3, self.skin);
@@ -6457,7 +6494,7 @@ function brain_tounge_attack(self, context) {
6457
6494
  context.engine.sound?.(self, 0, "brain/brnatck3.wav", 1, 1, 0);
6458
6495
  context.multicast(self.origin, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.PARASITE_ATTACK, self, start, end);
6459
6496
  const dir = subtractVec3(start, end);
6460
- T_Damage(self.enemy, self, self, dir, self.enemy.origin, ZERO_VEC3, 5, 0, 0, 37 /* BRAINTENTACLE */);
6497
+ T_Damage(self.enemy, self, self, dir, self.enemy.origin, ZERO_VEC3, 5, 0, 0, 37 /* BRAINTENTACLE */, context.timeSeconds);
6461
6498
  self.origin = { ...self.origin, z: self.origin.z + 1 };
6462
6499
  const forward = angleVectors(self.angles).forward;
6463
6500
  self.enemy.velocity = scaleVec3(forward, -1200);
@@ -7688,7 +7725,8 @@ function flyer_slash(self, context) {
7688
7725
  damage,
7689
7726
  5,
7690
7727
  2 /* NO_ARMOR */,
7691
- 0 /* UNKNOWN */
7728
+ 0 /* UNKNOWN */,
7729
+ context.timeSeconds
7692
7730
  );
7693
7731
  }
7694
7732
  }
@@ -7868,7 +7906,7 @@ function gladiator_melee(self, context) {
7868
7906
  z: self.origin.z + (self.viewheight || 0)
7869
7907
  };
7870
7908
  const dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
7871
- T_Damage(self.enemy, self, self, dir, self.origin, { x: 0, y: 0, z: 0 }, 20, 10, 0, 0 /* UNKNOWN */);
7909
+ T_Damage(self.enemy, self, self, dir, self.origin, { x: 0, y: 0, z: 0 }, 20, 10, 0, 0 /* UNKNOWN */, context.timeSeconds);
7872
7910
  }
7873
7911
  function gladiator_fire_railgun(self, context) {
7874
7912
  if (!self.enemy) return;
@@ -9393,7 +9431,8 @@ function mutant_swing(self, damage, context) {
9393
9431
  damage,
9394
9432
  0,
9395
9433
  0,
9396
- 0 /* UNKNOWN */
9434
+ 0 /* UNKNOWN */,
9435
+ context.timeSeconds
9397
9436
  );
9398
9437
  }
9399
9438
  function mutant_hit_right(self, context) {
@@ -9430,7 +9469,8 @@ function mutant_jump_touch(self, other, plane, surf) {
9430
9469
  50,
9431
9470
  0,
9432
9471
  0,
9433
- 0 /* UNKNOWN */
9472
+ 0 /* UNKNOWN */,
9473
+ 0
9434
9474
  );
9435
9475
  }
9436
9476
  if (!other || !other.takedamage && other.solid !== 0 /* Not */) {
@@ -9865,7 +9905,8 @@ function parasite_drain_attack(self, context) {
9865
9905
  damage,
9866
9906
  0,
9867
9907
  8 /* NO_KNOCKBACK */,
9868
- 0 /* UNKNOWN */
9908
+ 0 /* UNKNOWN */,
9909
+ context.timeSeconds
9869
9910
  );
9870
9911
  if (self.health < self.max_health) {
9871
9912
  self.health += damage;
@@ -12526,8 +12567,8 @@ var EnvironmentalFlags = /* @__PURE__ */ ((EnvironmentalFlags2) => {
12526
12567
  EnvironmentalFlags2[EnvironmentalFlags2["IMMUNE_SLIME"] = 4] = "IMMUNE_SLIME";
12527
12568
  return EnvironmentalFlags2;
12528
12569
  })(EnvironmentalFlags || {});
12529
- function applyDamageEvent(target, amount, mod) {
12530
- return T_Damage(target, null, null, ZERO2, target.origin, ZERO2, amount, 0, 2 /* NO_ARMOR */, mod);
12570
+ function applyDamageEvent(target, amount, mod, time) {
12571
+ return T_Damage(target, null, null, ZERO2, target.origin, ZERO2, amount, 0, 2 /* NO_ARMOR */, mod, time);
12531
12572
  }
12532
12573
  function applyEnvironmentalDamage(target, nowMs) {
12533
12574
  const events = [];
@@ -12542,7 +12583,7 @@ function applyEnvironmentalDamage(target, nowMs) {
12542
12583
  if (target.airFinished < nowMs && target.painDebounceTime <= nowMs) {
12543
12584
  const elapsedSeconds = Math.floor((nowMs - target.airFinished) / 1e3);
12544
12585
  const amount = Math.min(15, 2 + 2 * elapsedSeconds);
12545
- const result = applyDamageEvent(target, amount, 17 /* WATER */);
12586
+ const result = applyDamageEvent(target, amount, 17 /* WATER */, nowMs / 1e3);
12546
12587
  target.painDebounceTime = nowMs + 1e3;
12547
12588
  events.push({ mod: 17 /* WATER */, amount, result });
12548
12589
  }
@@ -12556,12 +12597,12 @@ function applyEnvironmentalDamage(target, nowMs) {
12556
12597
  if (target.damageDebounceTime <= nowMs) {
12557
12598
  if ((target.watertype & CONTENTS_LAVA) !== 0 && (flags & 2 /* IMMUNE_LAVA */) === 0) {
12558
12599
  const amount = 10 * target.waterlevel;
12559
- const result = applyDamageEvent(target, amount, 19 /* LAVA */);
12600
+ const result = applyDamageEvent(target, amount, 19 /* LAVA */, nowMs / 1e3);
12560
12601
  target.damageDebounceTime = nowMs + 100;
12561
12602
  events.push({ mod: 19 /* LAVA */, amount, result });
12562
12603
  } else if ((target.watertype & CONTENTS_SLIME) !== 0 && (flags & 4 /* IMMUNE_SLIME */) === 0) {
12563
12604
  const amount = 4 * target.waterlevel;
12564
- const result = applyDamageEvent(target, amount, 18 /* SLIME */);
12605
+ const result = applyDamageEvent(target, amount, 18 /* SLIME */, nowMs / 1e3);
12565
12606
  target.damageDebounceTime = nowMs + 100;
12566
12607
  events.push({ mod: 18 /* SLIME */, amount, result });
12567
12608
  }
@@ -12629,7 +12670,8 @@ function applyFallingDamage(target, context) {
12629
12670
  result.damage,
12630
12671
  0,
12631
12672
  2 /* NO_ARMOR */,
12632
- 23 /* FALLING */
12673
+ 23 /* FALLING */,
12674
+ 0
12633
12675
  );
12634
12676
  }
12635
12677
  return result;
@@ -12639,7 +12681,7 @@ function applyCrushDamage(crusher, target, options = {}) {
12639
12681
  const gibDamage = options.gibDamage ?? 100;
12640
12682
  const baseDamage = options.baseDamage ?? crusher.dmg ?? 10;
12641
12683
  const amount = !target.isMonster && !target.isClient ? nonLivingDamage : target.health < 1 ? gibDamage : baseDamage;
12642
- const result = T_Damage(target, crusher, crusher, ZERO2, target.origin, ZERO2, amount, 1, 0 /* NONE */, 20 /* CRUSH */);
12684
+ const result = T_Damage(target, crusher, crusher, ZERO2, target.origin, ZERO2, amount, 1, 0 /* NONE */, 20 /* CRUSH */, 0);
12643
12685
  return { amount, result };
12644
12686
  }
12645
12687
  function absoluteBounds(ent) {
@@ -12669,7 +12711,7 @@ function killBox(teleporter, targets, options = {}) {
12669
12711
  if (!boxesIntersect(teleBounds, absoluteBounds(target))) {
12670
12712
  continue;
12671
12713
  }
12672
- const result = T_Damage(target, teleporter, teleporter, ZERO2, target.origin, ZERO2, 1e5, 0, 32 /* NO_PROTECTION */, mod);
12714
+ const result = T_Damage(target, teleporter, teleporter, ZERO2, target.origin, ZERO2, 1e5, 0, 32 /* NO_PROTECTION */, mod, 0);
12673
12715
  events.push({ target, result });
12674
12716
  if (!result || !result.killed || target.health > 0) {
12675
12717
  cleared = false;
@@ -12916,6 +12958,45 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12916
12958
  entities.beginFrame(startTimeMs / 1e3);
12917
12959
  entities.runFrame();
12918
12960
  };
12961
+ const runPlayerMove = (player, command) => {
12962
+ const pcmd = {
12963
+ forwardmove: command.forwardmove,
12964
+ sidemove: command.sidemove,
12965
+ upmove: command.upmove,
12966
+ buttons: command.buttons,
12967
+ msec: command.msec,
12968
+ angles: command.angles
12969
+ };
12970
+ const playerState = {
12971
+ origin: player.origin,
12972
+ velocity: player.velocity,
12973
+ onGround: false,
12974
+ // This will be calculated by pmove
12975
+ waterLevel: player.waterlevel,
12976
+ // Pass waterlevel
12977
+ mins: player.mins,
12978
+ maxs: player.maxs,
12979
+ damageAlpha: 0,
12980
+ damageIndicators: [],
12981
+ viewAngles: player.angles,
12982
+ blend: [0, 0, 0, 0]
12983
+ };
12984
+ const traceAdapter = (start, end) => {
12985
+ const result = trace(start, player.mins, player.maxs, end, player, 268435457);
12986
+ return {
12987
+ fraction: result.fraction,
12988
+ endpos: result.endpos,
12989
+ allsolid: result.allsolid,
12990
+ startsolid: result.startsolid,
12991
+ planeNormal: result.plane?.normal
12992
+ };
12993
+ };
12994
+ const pointContentsAdapter = (point) => pointcontents(point);
12995
+ const newState = applyPmove(playerState, pcmd, traceAdapter, pointContentsAdapter);
12996
+ player.origin = newState.origin;
12997
+ player.velocity = newState.velocity;
12998
+ player.angles = newState.viewAngles;
12999
+ };
12919
13000
  return {
12920
13001
  init(startTimeMs) {
12921
13002
  resetState(startTimeMs);
@@ -12955,45 +13036,14 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12955
13036
  origin = { ...player.origin };
12956
13037
  return player;
12957
13038
  },
13039
+ clientThink(ent, cmd) {
13040
+ runPlayerMove(ent, cmd);
13041
+ },
12958
13042
  frame(step, command) {
12959
13043
  const context = frameLoop.advance(step);
12960
13044
  const player = entities.find((e) => e.classname === "player");
12961
13045
  if (command && player) {
12962
- const pcmd = {
12963
- forwardmove: command.forwardmove,
12964
- sidemove: command.sidemove,
12965
- upmove: command.upmove,
12966
- buttons: command.buttons,
12967
- msec: command.msec,
12968
- angles: command.angles
12969
- };
12970
- const playerState = {
12971
- origin: player.origin,
12972
- velocity: player.velocity,
12973
- onGround: false,
12974
- waterLevel: 0,
12975
- mins: player.mins,
12976
- maxs: player.maxs,
12977
- damageAlpha: 0,
12978
- damageIndicators: [],
12979
- viewAngles: player.angles,
12980
- blend: [0, 0, 0, 0]
12981
- };
12982
- const traceAdapter = (start, end) => {
12983
- const result = trace(start, player.mins, player.maxs, end, player, 268435457);
12984
- return {
12985
- fraction: result.fraction,
12986
- endpos: result.endpos,
12987
- allsolid: result.allsolid,
12988
- startsolid: result.startsolid,
12989
- planeNormal: result.plane?.normal
12990
- };
12991
- };
12992
- const pointContentsAdapter = (point) => pointcontents(point);
12993
- const newState = applyPmove(playerState, pcmd, traceAdapter, pointContentsAdapter);
12994
- player.origin = newState.origin;
12995
- player.velocity = newState.velocity;
12996
- player.angles = newState.viewAngles;
13046
+ runPlayerMove(player, command);
12997
13047
  }
12998
13048
  return snapshot(context.frame);
12999
13049
  },