quake2ts 0.0.271 → 0.0.275

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 (46) hide show
  1. package/package.json +1 -1
  2. package/packages/cgame/dist/index.cjs +29 -5
  3. package/packages/cgame/dist/index.cjs.map +1 -1
  4. package/packages/cgame/dist/index.js +30 -6
  5. package/packages/cgame/dist/index.js.map +1 -1
  6. package/packages/client/dist/browser/index.global.js +13 -13
  7. package/packages/client/dist/browser/index.global.js.map +1 -1
  8. package/packages/client/dist/cjs/index.cjs.map +1 -1
  9. package/packages/client/dist/esm/index.js.map +1 -1
  10. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  11. package/packages/engine/dist/browser/index.global.js +6 -6
  12. package/packages/engine/dist/browser/index.global.js.map +1 -1
  13. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  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 +3 -3
  17. package/packages/game/dist/browser/index.global.js.map +1 -1
  18. package/packages/game/dist/cjs/index.cjs +1058 -119
  19. package/packages/game/dist/cjs/index.cjs.map +1 -1
  20. package/packages/game/dist/esm/index.js +1058 -119
  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/monsters/fixbot.d.ts +5 -0
  24. package/packages/game/dist/types/entities/monsters/fixbot.d.ts.map +1 -0
  25. package/packages/game/dist/types/entities/monsters/gekk.d.ts +5 -0
  26. package/packages/game/dist/types/entities/monsters/gekk.d.ts.map +1 -0
  27. package/packages/game/dist/types/entities/monsters/index.d.ts.map +1 -1
  28. package/packages/game/dist/types/entities/playerStats.d.ts.map +1 -1
  29. package/packages/game/dist/types/inventory/playerInventory.d.ts +4 -48
  30. package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
  31. package/packages/server/dist/index.cjs +73 -5
  32. package/packages/server/dist/index.js +73 -5
  33. package/packages/shared/dist/browser/index.global.js +1 -1
  34. package/packages/shared/dist/browser/index.global.js.map +1 -1
  35. package/packages/shared/dist/cjs/index.cjs +47 -4
  36. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  37. package/packages/shared/dist/esm/index.js +45 -4
  38. package/packages/shared/dist/esm/index.js.map +1 -1
  39. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  40. package/packages/shared/dist/types/items/index.d.ts +1 -0
  41. package/packages/shared/dist/types/items/index.d.ts.map +1 -1
  42. package/packages/shared/dist/types/items/weaponInfo.d.ts +5 -0
  43. package/packages/shared/dist/types/items/weaponInfo.d.ts.map +1 -0
  44. package/packages/shared/dist/types/items/weapons.d.ts +8 -7
  45. package/packages/shared/dist/types/items/weapons.d.ts.map +1 -1
  46. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -933,6 +933,33 @@ function setCompressedInteger(stats, startIndex, id, count, bitsPerValue) {
933
933
  const valueToWrite = base & ~mask | count << bitShift & mask;
934
934
  writeUint16LE(stats, startIndex, byteOffset, valueToWrite & 65535);
935
935
  }
936
+ var PowerupId = /* @__PURE__ */ ((PowerupId22) => {
937
+ PowerupId22["QuadDamage"] = "quad";
938
+ PowerupId22["Invulnerability"] = "invulnerability";
939
+ PowerupId22["EnviroSuit"] = "enviro_suit";
940
+ PowerupId22["Rebreather"] = "rebreather";
941
+ PowerupId22["Silencer"] = "silencer";
942
+ PowerupId22["PowerScreen"] = "power_screen";
943
+ PowerupId22["PowerShield"] = "power_shield";
944
+ PowerupId22["QuadFire"] = "quad_fire";
945
+ PowerupId22["Invisibility"] = "invisibility";
946
+ PowerupId22["Bandolier"] = "bandolier";
947
+ PowerupId22["AmmoPack"] = "ammo_pack";
948
+ PowerupId22["IRGoggles"] = "ir_goggles";
949
+ PowerupId22["DoubleDamage"] = "double_damage";
950
+ PowerupId22["SphereVengeance"] = "sphere_vengeance";
951
+ PowerupId22["SphereHunter"] = "sphere_hunter";
952
+ PowerupId22["SphereDefender"] = "sphere_defender";
953
+ PowerupId22["Doppelganger"] = "doppelganger";
954
+ PowerupId22["TagToken"] = "tag_token";
955
+ PowerupId22["TechResistance"] = "tech_resistance";
956
+ PowerupId22["TechStrength"] = "tech_strength";
957
+ PowerupId22["TechHaste"] = "tech_haste";
958
+ PowerupId22["TechRegeneration"] = "tech_regeneration";
959
+ PowerupId22["Flashlight"] = "flashlight";
960
+ PowerupId22["Compass"] = "compass";
961
+ return PowerupId22;
962
+ })(PowerupId || {});
936
963
  var PlayerStat = /* @__PURE__ */ ((PlayerStat2) => {
937
964
  PlayerStat2[PlayerStat2["STAT_HEALTH_ICON"] = 0] = "STAT_HEALTH_ICON";
938
965
  PlayerStat2[PlayerStat2["STAT_HEALTH"] = 1] = "STAT_HEALTH";
@@ -1247,6 +1274,29 @@ var applyPmove = (state, cmd, trace, pointContents2) => {
1247
1274
  velocity: finalVelocity
1248
1275
  };
1249
1276
  };
1277
+ var WeaponId = /* @__PURE__ */ ((WeaponId22) => {
1278
+ WeaponId22["Blaster"] = "blaster";
1279
+ WeaponId22["Shotgun"] = "shotgun";
1280
+ WeaponId22["SuperShotgun"] = "supershotgun";
1281
+ WeaponId22["Machinegun"] = "machinegun";
1282
+ WeaponId22["Chaingun"] = "chaingun";
1283
+ WeaponId22["HandGrenade"] = "grenades";
1284
+ WeaponId22["GrenadeLauncher"] = "grenadelauncher";
1285
+ WeaponId22["RocketLauncher"] = "rocketlauncher";
1286
+ WeaponId22["HyperBlaster"] = "hyperblaster";
1287
+ WeaponId22["Railgun"] = "railgun";
1288
+ WeaponId22["BFG10K"] = "bfg10k";
1289
+ WeaponId22["Grapple"] = "grapple";
1290
+ WeaponId22["ChainFist"] = "chainfist";
1291
+ WeaponId22["EtfRifle"] = "etf_rifle";
1292
+ WeaponId22["ProxLauncher"] = "prox_launcher";
1293
+ WeaponId22["IonRipper"] = "ionripper";
1294
+ WeaponId22["PlasmaBeam"] = "plasmabeam";
1295
+ WeaponId22["Phalanx"] = "phalanx";
1296
+ WeaponId22["Disruptor"] = "disruptor";
1297
+ WeaponId22["Trap"] = "trap";
1298
+ return WeaponId22;
1299
+ })(WeaponId || {});
1250
1300
  var AmmoType = /* @__PURE__ */ ((AmmoType22) => {
1251
1301
  AmmoType22[AmmoType22["Bullets"] = 0] = "Bullets";
1252
1302
  AmmoType22[AmmoType22["Shells"] = 1] = "Shells";
@@ -1280,6 +1330,20 @@ var AmmoItemId = /* @__PURE__ */ ((AmmoItemId22) => {
1280
1330
  AmmoItemId22["Prox"] = "ammo_prox";
1281
1331
  return AmmoItemId22;
1282
1332
  })(AmmoItemId || {});
1333
+ var WEAPON_WHEEL_ORDER = [
1334
+ "blaster",
1335
+ "shotgun",
1336
+ "supershotgun",
1337
+ "machinegun",
1338
+ "chaingun",
1339
+ "grenadelauncher",
1340
+ "rocketlauncher",
1341
+ "grenades",
1342
+ "hyperblaster",
1343
+ "railgun",
1344
+ "bfg10k"
1345
+ /* BFG10K */
1346
+ ];
1283
1347
 
1284
1348
  // src/inventory/ammo.ts
1285
1349
  var AMMO_ITEM_DEFINITIONS = {
@@ -1462,54 +1526,6 @@ function applyPowerArmor(damage, flags, hitPoint, _hitNormal, state, options = {
1462
1526
  }
1463
1527
 
1464
1528
  // src/inventory/playerInventory.ts
1465
- var WeaponId = /* @__PURE__ */ ((WeaponId3) => {
1466
- WeaponId3["Blaster"] = "blaster";
1467
- WeaponId3["Shotgun"] = "shotgun";
1468
- WeaponId3["SuperShotgun"] = "supershotgun";
1469
- WeaponId3["Machinegun"] = "machinegun";
1470
- WeaponId3["Chaingun"] = "chaingun";
1471
- WeaponId3["GrenadeLauncher"] = "grenadelauncher";
1472
- WeaponId3["RocketLauncher"] = "rocketlauncher";
1473
- WeaponId3["HyperBlaster"] = "hyperblaster";
1474
- WeaponId3["Railgun"] = "railgun";
1475
- WeaponId3["BFG10K"] = "bfg10k";
1476
- WeaponId3["HandGrenade"] = "grenades";
1477
- WeaponId3["Grapple"] = "grapple";
1478
- WeaponId3["IonRipper"] = "ionripper";
1479
- WeaponId3["Phalanx"] = "phalanx";
1480
- WeaponId3["Trap"] = "trap";
1481
- WeaponId3["PlasmaBeam"] = "plasmabeam";
1482
- WeaponId3["EtfRifle"] = "etfrifle";
1483
- WeaponId3["ProxLauncher"] = "proxlauncher";
1484
- WeaponId3["ChainFist"] = "chainfist";
1485
- WeaponId3["Disruptor"] = "disruptor";
1486
- return WeaponId3;
1487
- })(WeaponId || {});
1488
- var PowerupId = /* @__PURE__ */ ((PowerupId3) => {
1489
- PowerupId3["QuadDamage"] = "quad";
1490
- PowerupId3["Invulnerability"] = "invulnerability";
1491
- PowerupId3["Silencer"] = "silencer";
1492
- PowerupId3["Rebreather"] = "rebreather";
1493
- PowerupId3["EnviroSuit"] = "enviro";
1494
- PowerupId3["DoubleDamage"] = "double";
1495
- PowerupId3["QuadFire"] = "quadfire";
1496
- PowerupId3["Invisibility"] = "invisibility";
1497
- PowerupId3["Bandolier"] = "bandolier";
1498
- PowerupId3["AmmoPack"] = "pack";
1499
- PowerupId3["IRGoggles"] = "goggles";
1500
- PowerupId3["SphereVengeance"] = "vengeance";
1501
- PowerupId3["SphereHunter"] = "hunter";
1502
- PowerupId3["SphereDefender"] = "defender";
1503
- PowerupId3["Doppelganger"] = "doppelganger";
1504
- PowerupId3["TagToken"] = "tagtoken";
1505
- PowerupId3["TechResistance"] = "tech_resistance";
1506
- PowerupId3["TechStrength"] = "tech_strength";
1507
- PowerupId3["TechHaste"] = "tech_haste";
1508
- PowerupId3["TechRegeneration"] = "tech_regeneration";
1509
- PowerupId3["Flashlight"] = "flashlight";
1510
- PowerupId3["Compass"] = "compass";
1511
- return PowerupId3;
1512
- })(PowerupId || {});
1513
1529
  var KeyId = /* @__PURE__ */ ((KeyId2) => {
1514
1530
  KeyId2["Blue"] = "key_blue";
1515
1531
  KeyId2["Red"] = "key_red";
@@ -1534,7 +1550,7 @@ function createPlayerInventory(init = {}) {
1534
1550
  const ammoCaps = init.ammoCaps;
1535
1551
  const inv = {
1536
1552
  ammo: createAmmoInventory(ammoCaps),
1537
- ownedWeapons: new Set(init.weapons ?? ["blaster" /* Blaster */]),
1553
+ ownedWeapons: new Set(init.weapons ?? [WeaponId.Blaster]),
1538
1554
  armor: null,
1539
1555
  powerups: /* @__PURE__ */ new Map(),
1540
1556
  keys: /* @__PURE__ */ new Set(),
@@ -1548,8 +1564,8 @@ function createPlayerInventory(init = {}) {
1548
1564
  if (init.currentWeapon) {
1549
1565
  inv.currentWeapon = init.currentWeapon;
1550
1566
  } else if (inv.ownedWeapons.size > 0) {
1551
- if (inv.ownedWeapons.has("blaster" /* Blaster */)) inv.currentWeapon = "blaster" /* Blaster */;
1552
- else if (inv.ownedWeapons.has("shotgun" /* Shotgun */)) inv.currentWeapon = "shotgun" /* Shotgun */;
1567
+ if (inv.ownedWeapons.has(WeaponId.Blaster)) inv.currentWeapon = WeaponId.Blaster;
1568
+ else if (inv.ownedWeapons.has(WeaponId.Shotgun)) inv.currentWeapon = WeaponId.Shotgun;
1553
1569
  else inv.currentWeapon = [...inv.ownedWeapons][0];
1554
1570
  }
1555
1571
  return inv;
@@ -1678,27 +1694,27 @@ function pickupPowerup(client, item, time) {
1678
1694
  let icon = "";
1679
1695
  switch (item.id) {
1680
1696
  case "item_quad":
1681
- powerupId = "quad" /* QuadDamage */;
1697
+ powerupId = PowerupId.QuadDamage;
1682
1698
  icon = "p_quad";
1683
1699
  break;
1684
1700
  case "item_invulnerability":
1685
- powerupId = "invulnerability" /* Invulnerability */;
1701
+ powerupId = PowerupId.Invulnerability;
1686
1702
  icon = "p_invulnerability";
1687
1703
  break;
1688
1704
  case "item_silencer":
1689
- powerupId = "silencer" /* Silencer */;
1705
+ powerupId = PowerupId.Silencer;
1690
1706
  icon = "p_silencer";
1691
1707
  break;
1692
1708
  case "item_rebreather":
1693
- powerupId = "rebreather" /* Rebreather */;
1709
+ powerupId = PowerupId.Rebreather;
1694
1710
  icon = "p_rebreather";
1695
1711
  break;
1696
1712
  case "item_enviro":
1697
- powerupId = "enviro" /* EnviroSuit */;
1713
+ powerupId = PowerupId.EnviroSuit;
1698
1714
  icon = "p_envirosuit";
1699
1715
  break;
1700
1716
  case "item_double":
1701
- powerupId = "double" /* DoubleDamage */;
1717
+ powerupId = PowerupId.DoubleDamage;
1702
1718
  icon = "p_double";
1703
1719
  break;
1704
1720
  }
@@ -1706,9 +1722,9 @@ function pickupPowerup(client, item, time) {
1706
1722
  const expiresAt = inventory.powerups.get(powerupId);
1707
1723
  const newExpiresAt = expiresAt && expiresAt > time ? expiresAt + item.timer * 1e3 : time + item.timer * 1e3;
1708
1724
  inventory.powerups.set(powerupId, newExpiresAt);
1709
- if (powerupId === "quad" /* QuadDamage */) {
1725
+ if (powerupId === PowerupId.QuadDamage) {
1710
1726
  client.quad_time = newExpiresAt / 1e3;
1711
- } else if (powerupId === "double" /* DoubleDamage */) {
1727
+ } else if (powerupId === PowerupId.DoubleDamage) {
1712
1728
  client.double_time = newExpiresAt / 1e3;
1713
1729
  }
1714
1730
  setPickup(inventory, icon, time);
@@ -5583,7 +5599,7 @@ function chaingunThink(player, sys) {
5583
5599
  if (!player.client) {
5584
5600
  return;
5585
5601
  }
5586
- const weaponState = getWeaponState(player.client.weaponStates, "chaingun" /* Chaingun */);
5602
+ const weaponState = getWeaponState(player.client.weaponStates, WeaponId.Chaingun);
5587
5603
  if (!(player.client.buttons & BUTTON_ATTACK) && weaponState.spinupCount && weaponState.spinupCount > 0) {
5588
5604
  sys.sound(player, 0, "weapons/chngnd1a.wav", 1, 0, 0);
5589
5605
  weaponState.spinupCount = 0;
@@ -5596,7 +5612,7 @@ var WEAPON_ITEMS = {
5596
5612
  type: "weapon",
5597
5613
  id: "weapon_blaster",
5598
5614
  name: "Blaster",
5599
- weaponId: "blaster" /* Blaster */,
5615
+ weaponId: WeaponId.Blaster,
5600
5616
  ammoType: null,
5601
5617
  initialAmmo: 0,
5602
5618
  pickupAmmo: 0,
@@ -5606,7 +5622,7 @@ var WEAPON_ITEMS = {
5606
5622
  type: "weapon",
5607
5623
  id: "weapon_shotgun",
5608
5624
  name: "Shotgun",
5609
- weaponId: "shotgun" /* Shotgun */,
5625
+ weaponId: WeaponId.Shotgun,
5610
5626
  ammoType: AmmoType.Shells,
5611
5627
  initialAmmo: 10,
5612
5628
  pickupAmmo: 10,
@@ -5616,7 +5632,7 @@ var WEAPON_ITEMS = {
5616
5632
  type: "weapon",
5617
5633
  id: "weapon_supershotgun",
5618
5634
  name: "Super Shotgun",
5619
- weaponId: "supershotgun" /* SuperShotgun */,
5635
+ weaponId: WeaponId.SuperShotgun,
5620
5636
  ammoType: AmmoType.Shells,
5621
5637
  initialAmmo: 10,
5622
5638
  pickupAmmo: 10,
@@ -5626,7 +5642,7 @@ var WEAPON_ITEMS = {
5626
5642
  type: "weapon",
5627
5643
  id: "weapon_machinegun",
5628
5644
  name: "Machinegun",
5629
- weaponId: "machinegun" /* Machinegun */,
5645
+ weaponId: WeaponId.Machinegun,
5630
5646
  ammoType: AmmoType.Bullets,
5631
5647
  initialAmmo: 50,
5632
5648
  pickupAmmo: 50,
@@ -5637,7 +5653,7 @@ var WEAPON_ITEMS = {
5637
5653
  type: "weapon",
5638
5654
  id: "weapon_chaingun",
5639
5655
  name: "Chaingun",
5640
- weaponId: "chaingun" /* Chaingun */,
5656
+ weaponId: WeaponId.Chaingun,
5641
5657
  ammoType: AmmoType.Bullets,
5642
5658
  initialAmmo: 50,
5643
5659
  pickupAmmo: 50,
@@ -5647,7 +5663,7 @@ var WEAPON_ITEMS = {
5647
5663
  type: "weapon",
5648
5664
  id: "weapon_grenades",
5649
5665
  name: "Hand Grenade",
5650
- weaponId: "grenades" /* HandGrenade */,
5666
+ weaponId: WeaponId.HandGrenade,
5651
5667
  ammoType: AmmoType.Grenades,
5652
5668
  initialAmmo: 5,
5653
5669
  pickupAmmo: 5,
@@ -5657,7 +5673,7 @@ var WEAPON_ITEMS = {
5657
5673
  type: "weapon",
5658
5674
  id: "weapon_grenadelauncher",
5659
5675
  name: "Grenade Launcher",
5660
- weaponId: "grenadelauncher" /* GrenadeLauncher */,
5676
+ weaponId: WeaponId.GrenadeLauncher,
5661
5677
  ammoType: AmmoType.Grenades,
5662
5678
  initialAmmo: 10,
5663
5679
  pickupAmmo: 10,
@@ -5667,7 +5683,7 @@ var WEAPON_ITEMS = {
5667
5683
  type: "weapon",
5668
5684
  id: "weapon_rocketlauncher",
5669
5685
  name: "Rocket Launcher",
5670
- weaponId: "rocketlauncher" /* RocketLauncher */,
5686
+ weaponId: WeaponId.RocketLauncher,
5671
5687
  ammoType: AmmoType.Rockets,
5672
5688
  initialAmmo: 5,
5673
5689
  pickupAmmo: 5,
@@ -5677,7 +5693,7 @@ var WEAPON_ITEMS = {
5677
5693
  type: "weapon",
5678
5694
  id: "weapon_hyperblaster",
5679
5695
  name: "HyperBlaster",
5680
- weaponId: "hyperblaster" /* HyperBlaster */,
5696
+ weaponId: WeaponId.HyperBlaster,
5681
5697
  ammoType: AmmoType.Cells,
5682
5698
  initialAmmo: 50,
5683
5699
  pickupAmmo: 50,
@@ -5687,7 +5703,7 @@ var WEAPON_ITEMS = {
5687
5703
  type: "weapon",
5688
5704
  id: "weapon_railgun",
5689
5705
  name: "Railgun",
5690
- weaponId: "railgun" /* Railgun */,
5706
+ weaponId: WeaponId.Railgun,
5691
5707
  ammoType: AmmoType.Slugs,
5692
5708
  initialAmmo: 10,
5693
5709
  pickupAmmo: 10,
@@ -5697,7 +5713,7 @@ var WEAPON_ITEMS = {
5697
5713
  type: "weapon",
5698
5714
  id: "weapon_bfg",
5699
5715
  name: "BFG10K",
5700
- weaponId: "bfg10k" /* BFG10K */,
5716
+ weaponId: WeaponId.BFG10K,
5701
5717
  ammoType: AmmoType.Cells,
5702
5718
  initialAmmo: 50,
5703
5719
  pickupAmmo: 50,
@@ -5709,7 +5725,7 @@ var WEAPON_ITEMS = {
5709
5725
  id: "weapon_boomer",
5710
5726
  // Ion Ripper
5711
5727
  name: "Ion Ripper",
5712
- weaponId: "ionripper" /* IonRipper */,
5728
+ weaponId: WeaponId.IonRipper,
5713
5729
  ammoType: AmmoType.Cells,
5714
5730
  initialAmmo: 50,
5715
5731
  pickupAmmo: 50,
@@ -5719,7 +5735,7 @@ var WEAPON_ITEMS = {
5719
5735
  type: "weapon",
5720
5736
  id: "weapon_phalanx",
5721
5737
  name: "Phalanx",
5722
- weaponId: "phalanx" /* Phalanx */,
5738
+ weaponId: WeaponId.Phalanx,
5723
5739
  ammoType: AmmoType.MagSlugs,
5724
5740
  initialAmmo: 50,
5725
5741
  pickupAmmo: 50,
@@ -5729,7 +5745,7 @@ var WEAPON_ITEMS = {
5729
5745
  type: "weapon",
5730
5746
  id: "weapon_beam",
5731
5747
  name: "Plasma Beam",
5732
- weaponId: "plasmabeam" /* PlasmaBeam */,
5748
+ weaponId: WeaponId.PlasmaBeam,
5733
5749
  ammoType: AmmoType.Cells,
5734
5750
  initialAmmo: 50,
5735
5751
  pickupAmmo: 50,
@@ -5739,7 +5755,7 @@ var WEAPON_ITEMS = {
5739
5755
  type: "weapon",
5740
5756
  id: "weapon_etf_rifle",
5741
5757
  name: "ETF Rifle",
5742
- weaponId: "etfrifle" /* EtfRifle */,
5758
+ weaponId: WeaponId.EtfRifle,
5743
5759
  ammoType: AmmoType.Flechettes,
5744
5760
  initialAmmo: 50,
5745
5761
  pickupAmmo: 50,
@@ -5749,7 +5765,7 @@ var WEAPON_ITEMS = {
5749
5765
  type: "weapon",
5750
5766
  id: "weapon_proxlauncher",
5751
5767
  name: "Prox Launcher",
5752
- weaponId: "proxlauncher" /* ProxLauncher */,
5768
+ weaponId: WeaponId.ProxLauncher,
5753
5769
  ammoType: AmmoType.Prox,
5754
5770
  initialAmmo: 5,
5755
5771
  pickupAmmo: 5,
@@ -11658,8 +11674,8 @@ function actor_pain(self, other, kick, damage) {
11658
11674
  if (context.timeSeconds < self.pain_debounce_time)
11659
11675
  return;
11660
11676
  self.pain_debounce_time = context.timeSeconds + 3;
11661
- const random10 = Math.random();
11662
- if (other && other.client && random10 < 0.4) {
11677
+ const random12 = Math.random();
11678
+ if (other && other.client && random12 < 0.4) {
11663
11679
  const v = subtractVec3(other.origin, self.origin);
11664
11680
  self.ideal_yaw = vectorToYaw(v);
11665
11681
  if (Math.random() < 0.5)
@@ -14355,6 +14371,934 @@ function registerTurretSpawns(registry) {
14355
14371
  registry.register("monster_turret", SP_monster_turret);
14356
14372
  }
14357
14373
 
14374
+ // src/entities/monsters/gekk.ts
14375
+ var MONSTER_TICK24 = 0.1;
14376
+ var random8 = () => Math.random();
14377
+ var frandom2 = () => Math.random();
14378
+ var irandom2 = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
14379
+ function monster_ai_stand22(self, dist, context) {
14380
+ ai_stand(self, MONSTER_TICK24, context);
14381
+ }
14382
+ function monster_ai_walk20(self, dist, context) {
14383
+ ai_walk(self, dist, MONSTER_TICK24, context);
14384
+ }
14385
+ function monster_ai_run21(self, dist, context) {
14386
+ ai_run(self, dist, MONSTER_TICK24, context);
14387
+ }
14388
+ function monster_ai_charge22(self, dist, context) {
14389
+ ai_charge(self, dist, MONSTER_TICK24, context);
14390
+ }
14391
+ function monster_ai_move21(self, dist, context) {
14392
+ ai_move(self, dist);
14393
+ }
14394
+ var gekk_move_stand;
14395
+ var gekk_move_standunderwater;
14396
+ var gekk_move_swim_loop;
14397
+ var gekk_move_swim_start;
14398
+ var gekk_move_chant;
14399
+ var gekk_move_idle;
14400
+ var gekk_move_idle2;
14401
+ var gekk_move_walk;
14402
+ var gekk_move_run;
14403
+ var gekk_move_run_start;
14404
+ var gekk_move_attack1;
14405
+ var gekk_move_attack2;
14406
+ var gekk_move_spit;
14407
+ var gekk_move_leapatk;
14408
+ var gekk_move_leapatk2;
14409
+ var gekk_move_attack;
14410
+ var gekk_move_pain;
14411
+ var gekk_move_pain1;
14412
+ var gekk_move_pain2;
14413
+ var gekk_move_death1;
14414
+ var gekk_move_death3;
14415
+ var gekk_move_death4;
14416
+ var gekk_move_wdeath;
14417
+ var WATER_WAIST = 2;
14418
+ var RANGE_MELEE2 = 80;
14419
+ var RANGE_NEAR2 = 100;
14420
+ var RANGE_MID2 = 400;
14421
+ var SPAWNFLAG_GEKK_CHANT = 8;
14422
+ var SPAWNFLAG_GEKK_NOJUMPING = 16;
14423
+ var SPAWNFLAG_GEKK_NOSWIM = 32;
14424
+ var GIB_HEALTH = -30;
14425
+ function gekk_check_underwater(self, context) {
14426
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14427
+ land_to_water(self);
14428
+ }
14429
+ }
14430
+ function gekk_stand(self) {
14431
+ if (self.waterlevel >= WATER_WAIST) {
14432
+ self.flags |= 2 /* Swim */;
14433
+ self.monsterinfo.current_move = gekk_move_standunderwater;
14434
+ } else {
14435
+ if (self.monsterinfo.current_move !== gekk_move_chant) {
14436
+ self.monsterinfo.current_move = gekk_move_stand;
14437
+ }
14438
+ }
14439
+ }
14440
+ function gekk_swim_loop_func(self) {
14441
+ self.flags |= 2 /* Swim */;
14442
+ self.monsterinfo.current_move = gekk_move_swim_loop;
14443
+ }
14444
+ function gekk_hit_left(self, context) {
14445
+ if (!self.enemy) return;
14446
+ const damage = irandom2(5, 10);
14447
+ const range = 100;
14448
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14449
+ const dist = lengthVec3(dir);
14450
+ if (dist <= range) {
14451
+ context.engine.sound?.(self, 0, "gek/gk_atck2.wav", 1, 1, 0);
14452
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, damage, 0, 0 /* UNKNOWN */, context.timeSeconds);
14453
+ } else {
14454
+ context.engine.sound?.(self, 0, "gek/gk_atck1.wav", 1, 1, 0);
14455
+ }
14456
+ }
14457
+ function gekk_hit_right(self, context) {
14458
+ if (!self.enemy) return;
14459
+ const damage = irandom2(5, 10);
14460
+ const range = 100;
14461
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14462
+ const dist = lengthVec3(dir);
14463
+ if (dist <= range) {
14464
+ context.engine.sound?.(self, 0, "gek/gk_atck3.wav", 1, 1, 0);
14465
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, damage, 0, 0 /* UNKNOWN */, context.timeSeconds);
14466
+ } else {
14467
+ context.engine.sound?.(self, 0, "gek/gk_atck1.wav", 1, 1, 0);
14468
+ }
14469
+ }
14470
+ function gekk_bite(self, context) {
14471
+ if (!self.enemy) return;
14472
+ const damage = 5;
14473
+ const range = RANGE_MELEE2;
14474
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14475
+ const dist = lengthVec3(dir);
14476
+ if (dist <= range) {
14477
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, 0, 0, 0 /* UNKNOWN */, context.timeSeconds);
14478
+ }
14479
+ }
14480
+ function gekk_check_melee(self, context) {
14481
+ if (!self.enemy || self.enemy.health <= 0 || self.monsterinfo.melee_debounce_time && self.monsterinfo.melee_debounce_time > context.timeSeconds)
14482
+ return false;
14483
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14484
+ return dist <= RANGE_MELEE2;
14485
+ }
14486
+ function gekk_check_jump(self, context) {
14487
+ if (!self.enemy) return false;
14488
+ if (self.absmin.z + 125 < self.enemy.absmin.z)
14489
+ return false;
14490
+ const v = subtractVec3(self.origin, self.enemy.origin);
14491
+ v.z = 0;
14492
+ const distance2 = lengthVec3(v);
14493
+ if (distance2 < 100) return false;
14494
+ if (distance2 > 100) {
14495
+ if (frandom2() < (self.waterlevel >= WATER_WAIST ? 0.2 : 0.9))
14496
+ return false;
14497
+ }
14498
+ return true;
14499
+ }
14500
+ function gekk_check_jump_close(self, context) {
14501
+ if (!self.enemy) return false;
14502
+ const v = subtractVec3(self.origin, self.enemy.origin);
14503
+ v.z = 0;
14504
+ const distance2 = lengthVec3(v);
14505
+ if (distance2 < 100) {
14506
+ if (self.absmax.z <= self.enemy.absmin.z) return false;
14507
+ }
14508
+ return true;
14509
+ }
14510
+ function gekk_checkattack(self, context) {
14511
+ if (!self.enemy || self.enemy.health <= 0) return false;
14512
+ if (gekk_check_melee(self, context)) {
14513
+ return true;
14514
+ }
14515
+ if (gekk_check_jump(self, context)) {
14516
+ return true;
14517
+ }
14518
+ if (gekk_check_jump_close(self, context) && !(self.flags & 2 /* Swim */)) {
14519
+ return true;
14520
+ }
14521
+ return false;
14522
+ }
14523
+ function gekk_chant(self) {
14524
+ self.monsterinfo.current_move = gekk_move_chant;
14525
+ }
14526
+ function gekk_idle_loop(self) {
14527
+ if (frandom2() > 0.75 && self.health < self.max_health) {
14528
+ self.monsterinfo.nextframe = 0;
14529
+ }
14530
+ }
14531
+ function gekk_step(self, context) {
14532
+ const n = irandom2(0, 2);
14533
+ const sounds = ["gek/gk_step1.wav", "gek/gk_step2.wav", "gek/gk_step3.wav"];
14534
+ context.engine.sound?.(self, 0, sounds[n], 1, 1, 0);
14535
+ }
14536
+ function gekk_search(self, context) {
14537
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14538
+ const r = frandom2();
14539
+ if (r < 0.33) context.engine.sound?.(self, 0, "gek/gek_low.wav", 1, 1, 0);
14540
+ else if (r < 0.66) context.engine.sound?.(self, 0, "gek/gek_mid.wav", 1, 1, 0);
14541
+ else context.engine.sound?.(self, 0, "gek/gek_high.wav", 1, 1, 0);
14542
+ } else {
14543
+ context.engine.sound?.(self, 0, "gek/gk_idle1.wav", 1, 1, 0);
14544
+ }
14545
+ self.health += irandom2(10, 20);
14546
+ if (self.health > self.max_health) self.health = self.max_health;
14547
+ if (self.health < self.max_health / 4) self.skin = 2;
14548
+ else if (self.health < self.max_health / 2) self.skin = 1;
14549
+ else self.skin = 0;
14550
+ }
14551
+ function gekk_run_start(self) {
14552
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14553
+ self.monsterinfo.current_move = gekk_move_swim_start;
14554
+ } else {
14555
+ self.monsterinfo.current_move = gekk_move_run_start;
14556
+ }
14557
+ }
14558
+ function gekk_run(self) {
14559
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14560
+ self.monsterinfo.current_move = gekk_move_swim_start;
14561
+ } else {
14562
+ self.monsterinfo.current_move = gekk_move_run;
14563
+ }
14564
+ }
14565
+ function gekk_check_refire(self) {
14566
+ if (!self.enemy || self.enemy.health <= 0) return;
14567
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14568
+ if (dist <= RANGE_MELEE2) {
14569
+ if (self.frame === 114) {
14570
+ self.monsterinfo.current_move = gekk_move_attack2;
14571
+ } else if (self.frame === 123) {
14572
+ self.monsterinfo.current_move = gekk_move_attack1;
14573
+ }
14574
+ }
14575
+ }
14576
+ function fire_loogie(self, start, dir, damage, speed, context) {
14577
+ const bolt = createBlasterBolt(context, self, start, dir, damage, speed, 0 /* UNKNOWN */);
14578
+ bolt.model = "models/objects/loogy/tris.md2";
14579
+ }
14580
+ function loogie_fire(self, context) {
14581
+ if (!self.enemy || self.enemy.health <= 0) return;
14582
+ const vectors = angleVectors(self.angles);
14583
+ const forward = vectors.forward;
14584
+ const right = vectors.right;
14585
+ const up = vectors.up;
14586
+ const offset = { x: -18, y: -0.8, z: 24 };
14587
+ const start = addVec3(self.origin, addVec3(scaleVec3(forward, offset.x), addVec3(scaleVec3(right, offset.y), scaleVec3(up, offset.z))));
14588
+ start.z += 2;
14589
+ const end = copyVec3(self.enemy.origin);
14590
+ end.z += self.enemy.viewheight || 0;
14591
+ const dir = normalizeVec3(subtractVec3(end, start));
14592
+ fire_loogie(self, start, dir, 5, 550, context);
14593
+ context.engine.sound?.(self, 0, "gek/gk_atck4.wav", 1, 1, 0);
14594
+ }
14595
+ function reloogie(self) {
14596
+ if (frandom2() > 0.8 && self.health < self.max_health) {
14597
+ self.monsterinfo.current_move = gekk_move_idle2;
14598
+ return;
14599
+ }
14600
+ if (self.enemy && self.enemy.health > 0) {
14601
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14602
+ if (frandom2() > 0.7 && dist <= RANGE_NEAR2) {
14603
+ self.monsterinfo.current_move = gekk_move_spit;
14604
+ }
14605
+ }
14606
+ }
14607
+ function gekk_jump_touch(self, other, plane, surf) {
14608
+ if (self.health <= 0) {
14609
+ self.touch = void 0;
14610
+ return;
14611
+ }
14612
+ self.touch = void 0;
14613
+ }
14614
+ function gekk_jump_takeoff(self, context) {
14615
+ const vectors = angleVectors(self.angles);
14616
+ const forward = vectors.forward;
14617
+ context.engine.sound?.(self, 0, "gek/gk_sght1.wav", 1, 1, 0);
14618
+ self.origin.z += 1;
14619
+ self.velocity = addVec3(scaleVec3(forward, 700), { x: 0, y: 0, z: 250 });
14620
+ self.groundentity = null;
14621
+ self.touch = gekk_jump_touch;
14622
+ }
14623
+ function gekk_check_landing(self, context) {
14624
+ if (self.groundentity) {
14625
+ context.engine.sound?.(self, 0, "mutant/thud1.wav", 1, 1, 0);
14626
+ self.velocity = ZERO_VEC3;
14627
+ return;
14628
+ }
14629
+ }
14630
+ function gekk_stop_skid(self) {
14631
+ if (self.groundentity) self.velocity = ZERO_VEC3;
14632
+ }
14633
+ function gekk_preattack(self, context) {
14634
+ }
14635
+ function gekk_dead(self) {
14636
+ self.mins = { x: -16, y: -16, z: -24 };
14637
+ self.maxs = { x: 16, y: 16, z: -8 };
14638
+ self.nextthink = -1;
14639
+ }
14640
+ function gekk_gibfest(self, context) {
14641
+ throwGibs(context, self.origin, 20);
14642
+ self.deadflag = 2 /* Dead */;
14643
+ }
14644
+ function isgibfest(self, context) {
14645
+ if (frandom2() > 0.9) gekk_gibfest(self, context);
14646
+ }
14647
+ function gekk_shrink(self) {
14648
+ self.maxs.z = 0;
14649
+ }
14650
+ function land_to_water(self) {
14651
+ self.flags |= 2 /* Swim */;
14652
+ self.yaw_speed = 10;
14653
+ self.viewheight = 10;
14654
+ self.monsterinfo.current_move = gekk_move_swim_start;
14655
+ self.mins = { x: -18, y: -18, z: -24 };
14656
+ self.maxs = { x: 18, y: 18, z: 16 };
14657
+ }
14658
+ var frames_stand2 = Array(38).fill({ ai: monster_ai_stand22, dist: 0 });
14659
+ frames_stand2[38] = { ai: monster_ai_stand22, dist: 0, think: gekk_check_underwater };
14660
+ gekk_move_stand = {
14661
+ firstframe: 0,
14662
+ lastframe: 38,
14663
+ frames: frames_stand2,
14664
+ endfunc: null
14665
+ };
14666
+ var frames_standunderwater = Array(32).fill({ ai: monster_ai_stand22, dist: 14 });
14667
+ gekk_move_standunderwater = {
14668
+ firstframe: 39,
14669
+ lastframe: 70,
14670
+ frames: frames_standunderwater,
14671
+ endfunc: null
14672
+ };
14673
+ var frames_swim = Array(32).fill({ ai: monster_ai_run21, dist: 14 });
14674
+ gekk_move_swim_loop = {
14675
+ firstframe: 39,
14676
+ lastframe: 70,
14677
+ frames: frames_swim,
14678
+ endfunc: gekk_swim_loop_func
14679
+ };
14680
+ var frames_swim_start = Array(32).fill({ ai: monster_ai_run21, dist: 14 });
14681
+ frames_swim_start[8] = { ai: monster_ai_run21, dist: 18, think: gekk_hit_left };
14682
+ frames_swim_start[14] = { ai: monster_ai_run21, dist: 24, think: gekk_hit_right };
14683
+ frames_swim_start[20] = { ai: monster_ai_run21, dist: 22, think: gekk_bite };
14684
+ gekk_move_swim_start = {
14685
+ firstframe: 39,
14686
+ lastframe: 70,
14687
+ frames: frames_swim_start,
14688
+ endfunc: gekk_swim_loop_func
14689
+ };
14690
+ var frames_idle = Array(32).fill({ ai: monster_ai_stand22, dist: 0 });
14691
+ frames_idle[0] = { ai: monster_ai_stand22, dist: 0, think: gekk_search };
14692
+ frames_idle[31] = { ai: monster_ai_stand22, dist: 0, think: gekk_idle_loop };
14693
+ gekk_move_idle = {
14694
+ firstframe: 71,
14695
+ lastframe: 102,
14696
+ frames: frames_idle,
14697
+ endfunc: gekk_stand
14698
+ };
14699
+ var frames_idle2 = Array(32).fill({ ai: monster_ai_move21, dist: 0 });
14700
+ frames_idle2[0] = { ai: monster_ai_move21, dist: 0, think: gekk_search };
14701
+ frames_idle2[31] = { ai: monster_ai_move21, dist: 0, think: gekk_idle_loop };
14702
+ gekk_move_idle2 = {
14703
+ firstframe: 71,
14704
+ lastframe: 102,
14705
+ frames: frames_idle2,
14706
+ endfunc: (s) => M_SetAnimation2(s, gekk_move_stand)
14707
+ // or face
14708
+ };
14709
+ gekk_move_chant = {
14710
+ firstframe: 71,
14711
+ lastframe: 102,
14712
+ frames: frames_idle2,
14713
+ endfunc: gekk_chant
14714
+ };
14715
+ var frames_walk2 = [
14716
+ { ai: monster_ai_walk20, dist: 3.8, think: gekk_check_underwater },
14717
+ { ai: monster_ai_walk20, dist: 19.6 },
14718
+ { ai: monster_ai_walk20, dist: 25.5 },
14719
+ { ai: monster_ai_walk20, dist: 34.6, think: gekk_step },
14720
+ { ai: monster_ai_walk20, dist: 27.3 },
14721
+ { ai: monster_ai_walk20, dist: 28.4 }
14722
+ ];
14723
+ gekk_move_walk = {
14724
+ firstframe: 103,
14725
+ lastframe: 108,
14726
+ frames: frames_walk2,
14727
+ endfunc: null
14728
+ };
14729
+ var frames_run2 = [
14730
+ { ai: monster_ai_run21, dist: 3.8, think: gekk_check_underwater },
14731
+ { ai: monster_ai_run21, dist: 19.6 },
14732
+ { ai: monster_ai_run21, dist: 25.5 },
14733
+ { ai: monster_ai_run21, dist: 34.6, think: gekk_step },
14734
+ { ai: monster_ai_run21, dist: 27.3 },
14735
+ { ai: monster_ai_run21, dist: 28.4 }
14736
+ ];
14737
+ gekk_move_run = {
14738
+ firstframe: 103,
14739
+ lastframe: 108,
14740
+ frames: frames_run2,
14741
+ endfunc: null
14742
+ };
14743
+ var frames_run_st = [
14744
+ { ai: monster_ai_run21, dist: 0.2 },
14745
+ { ai: monster_ai_run21, dist: 19.7 }
14746
+ ];
14747
+ gekk_move_run_start = {
14748
+ firstframe: 0,
14749
+ lastframe: 1,
14750
+ // Frames 0 and 1 reuse stand start? C says FRAME_stand_01, FRAME_stand_02
14751
+ frames: frames_run_st,
14752
+ endfunc: gekk_run
14753
+ };
14754
+ var frames_spit = [
14755
+ { ai: monster_ai_charge22, dist: 0 },
14756
+ { ai: monster_ai_charge22, dist: 0 },
14757
+ { ai: monster_ai_charge22, dist: 0 },
14758
+ { ai: monster_ai_charge22, dist: 0 },
14759
+ { ai: monster_ai_charge22, dist: 0 },
14760
+ { ai: monster_ai_charge22, dist: 0, think: loogie_fire },
14761
+ { ai: monster_ai_charge22, dist: 0, think: reloogie }
14762
+ ];
14763
+ gekk_move_spit = {
14764
+ firstframe: 133,
14765
+ // FRAME_spit_01
14766
+ lastframe: 139,
14767
+ frames: frames_spit,
14768
+ endfunc: gekk_run_start
14769
+ };
14770
+ var frames_attack1 = [
14771
+ { ai: monster_ai_charge22, dist: 0 },
14772
+ { ai: monster_ai_charge22, dist: 0 },
14773
+ { ai: monster_ai_charge22, dist: 0 },
14774
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_left },
14775
+ { ai: monster_ai_charge22, dist: 0 },
14776
+ { ai: monster_ai_charge22, dist: 0 },
14777
+ { ai: monster_ai_charge22, dist: 0 },
14778
+ { ai: monster_ai_charge22, dist: 0 },
14779
+ { ai: monster_ai_charge22, dist: 0, think: gekk_check_refire }
14780
+ ];
14781
+ gekk_move_attack1 = {
14782
+ firstframe: 109,
14783
+ lastframe: 117,
14784
+ frames: frames_attack1,
14785
+ endfunc: gekk_run_start
14786
+ };
14787
+ var frames_attack2 = [
14788
+ { ai: monster_ai_charge22, dist: 0 },
14789
+ { ai: monster_ai_charge22, dist: 0 },
14790
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_left },
14791
+ { ai: monster_ai_charge22, dist: 0 },
14792
+ { ai: monster_ai_charge22, dist: 0 },
14793
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_right },
14794
+ { ai: monster_ai_charge22, dist: 0 },
14795
+ { ai: monster_ai_charge22, dist: 0 },
14796
+ { ai: monster_ai_charge22, dist: 0, think: gekk_check_refire }
14797
+ ];
14798
+ gekk_move_attack2 = {
14799
+ firstframe: 118,
14800
+ lastframe: 126,
14801
+ frames: frames_attack2,
14802
+ endfunc: gekk_run_start
14803
+ };
14804
+ var frames_leapatk = [
14805
+ { ai: monster_ai_charge22, dist: 0 },
14806
+ { ai: monster_ai_charge22, dist: -0.3 },
14807
+ { ai: monster_ai_charge22, dist: -1.1 },
14808
+ { ai: monster_ai_charge22, dist: -0.2 },
14809
+ { ai: monster_ai_charge22, dist: 6.7, think: gekk_jump_takeoff },
14810
+ { ai: monster_ai_charge22, dist: 6.4 },
14811
+ { ai: monster_ai_charge22, dist: 0.1 },
14812
+ { ai: monster_ai_charge22, dist: 28.3 },
14813
+ { ai: monster_ai_charge22, dist: 24.1 },
14814
+ { ai: monster_ai_charge22, dist: 31.7 },
14815
+ { ai: monster_ai_charge22, dist: 35.9, think: gekk_check_landing },
14816
+ { ai: monster_ai_charge22, dist: 12.3, think: gekk_stop_skid },
14817
+ { ai: monster_ai_charge22, dist: 20.1, think: gekk_stop_skid },
14818
+ { ai: monster_ai_charge22, dist: -1, think: gekk_stop_skid },
14819
+ { ai: monster_ai_charge22, dist: 2.5, think: gekk_stop_skid },
14820
+ { ai: monster_ai_charge22, dist: 0.5, think: gekk_stop_skid },
14821
+ { ai: monster_ai_charge22, dist: 1.8, think: gekk_stop_skid },
14822
+ { ai: monster_ai_charge22, dist: 1.2, think: gekk_stop_skid },
14823
+ { ai: monster_ai_charge22, dist: -0.4, think: gekk_check_underwater }
14824
+ ];
14825
+ gekk_move_leapatk = {
14826
+ firstframe: 140,
14827
+ lastframe: 158,
14828
+ frames: frames_leapatk,
14829
+ endfunc: gekk_run_start
14830
+ };
14831
+ gekk_move_leapatk2 = {
14832
+ firstframe: 140,
14833
+ lastframe: 158,
14834
+ frames: frames_leapatk,
14835
+ // reusing frames
14836
+ endfunc: gekk_run_start
14837
+ };
14838
+ var frames_attack3 = Array(21).fill({ ai: monster_ai_charge22, dist: 16 });
14839
+ frames_attack3[0] = { ai: monster_ai_charge22, dist: 16, think: gekk_preattack };
14840
+ frames_attack3[4] = { ai: monster_ai_charge22, dist: 16, think: gekk_bite };
14841
+ frames_attack3[9] = { ai: monster_ai_charge22, dist: 16, think: gekk_bite };
14842
+ frames_attack3[13] = { ai: monster_ai_charge22, dist: 16, think: gekk_hit_left };
14843
+ frames_attack3[18] = { ai: monster_ai_charge22, dist: 16, think: gekk_hit_right };
14844
+ gekk_move_attack = {
14845
+ firstframe: 159,
14846
+ lastframe: 179,
14847
+ frames: frames_attack3,
14848
+ endfunc: gekk_run_start
14849
+ };
14850
+ var frames_pain = Array(6).fill({ ai: monster_ai_move21, dist: 0 });
14851
+ gekk_move_pain = {
14852
+ firstframe: 180,
14853
+ lastframe: 185,
14854
+ frames: frames_pain,
14855
+ endfunc: gekk_run_start
14856
+ };
14857
+ var frames_pain12 = Array(11).fill({ ai: monster_ai_move21, dist: 0 });
14858
+ frames_pain12[10] = { ai: monster_ai_move21, dist: 0, think: gekk_check_underwater };
14859
+ gekk_move_pain1 = {
14860
+ firstframe: 186,
14861
+ lastframe: 196,
14862
+ frames: frames_pain12,
14863
+ endfunc: gekk_run_start
14864
+ };
14865
+ var frames_pain22 = Array(13).fill({ ai: monster_ai_move21, dist: 0 });
14866
+ frames_pain22[12] = { ai: monster_ai_move21, dist: 0, think: gekk_check_underwater };
14867
+ gekk_move_pain2 = {
14868
+ firstframe: 197,
14869
+ lastframe: 209,
14870
+ frames: frames_pain22,
14871
+ endfunc: gekk_run_start
14872
+ };
14873
+ function gekk_pain(self, other, kick, damage, context) {
14874
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14875
+ self.spawnflags &= ~SPAWNFLAG_GEKK_CHANT;
14876
+ return;
14877
+ }
14878
+ context.engine.sound?.(self, 0, "gek/gk_pain1.wav", 1, 1, 0);
14879
+ if (self.waterlevel >= WATER_WAIST) {
14880
+ if (!(self.flags & 2 /* Swim */)) {
14881
+ self.flags |= 2 /* Swim */;
14882
+ }
14883
+ self.monsterinfo.current_move = gekk_move_pain;
14884
+ } else {
14885
+ if (random8() > 0.5) self.monsterinfo.current_move = gekk_move_pain1;
14886
+ else self.monsterinfo.current_move = gekk_move_pain2;
14887
+ }
14888
+ }
14889
+ var frames_death12 = Array(10).fill({ ai: monster_ai_move21, dist: 0 });
14890
+ frames_death12[5] = { ai: monster_ai_move21, dist: -7, think: gekk_shrink };
14891
+ gekk_move_death1 = {
14892
+ firstframe: 210,
14893
+ lastframe: 219,
14894
+ frames: frames_death12,
14895
+ endfunc: gekk_dead
14896
+ };
14897
+ var frames_death3 = Array(7).fill({ ai: monster_ai_move21, dist: 0 });
14898
+ frames_death3[5] = { ai: monster_ai_move21, dist: -7, think: isgibfest };
14899
+ gekk_move_death3 = {
14900
+ firstframe: 220,
14901
+ lastframe: 226,
14902
+ frames: frames_death3,
14903
+ endfunc: gekk_dead
14904
+ };
14905
+ var frames_death4 = Array(35).fill({ ai: monster_ai_move21, dist: 0 });
14906
+ frames_death4[34] = { ai: monster_ai_move21, dist: 0, think: gekk_gibfest };
14907
+ gekk_move_death4 = {
14908
+ firstframe: 227,
14909
+ lastframe: 261,
14910
+ frames: frames_death4,
14911
+ endfunc: gekk_dead
14912
+ };
14913
+ var frames_wdeath = Array(45).fill({ ai: monster_ai_move21, dist: 0 });
14914
+ gekk_move_wdeath = {
14915
+ firstframe: 262,
14916
+ lastframe: 306,
14917
+ frames: frames_wdeath,
14918
+ endfunc: gekk_dead
14919
+ };
14920
+ function gekk_die(self, inflictor, attacker, damage, point, mod, context) {
14921
+ if (self.health <= GIB_HEALTH) {
14922
+ throwGibs(context, self.origin, damage);
14923
+ return;
14924
+ }
14925
+ if (self.deadflag === 2 /* Dead */) return;
14926
+ context.engine.sound?.(self, 0, "gek/gk_deth1.wav", 1, 1, 0);
14927
+ self.deadflag = 2 /* Dead */;
14928
+ self.takedamage = true;
14929
+ if (self.waterlevel >= WATER_WAIST) {
14930
+ gekk_shrink(self);
14931
+ self.monsterinfo.current_move = gekk_move_wdeath;
14932
+ } else {
14933
+ const r = frandom2();
14934
+ if (r > 0.66) self.monsterinfo.current_move = gekk_move_death1;
14935
+ else if (r > 0.33) self.monsterinfo.current_move = gekk_move_death3;
14936
+ else self.monsterinfo.current_move = gekk_move_death4;
14937
+ }
14938
+ }
14939
+ function SP_monster_gekk(self, context) {
14940
+ self.classname = "monster_gekk";
14941
+ self.model = "models/monsters/gekk/tris.md2";
14942
+ self.movetype = 5 /* Step */;
14943
+ self.solid = 2 /* BoundingBox */;
14944
+ self.mins = { x: -18, y: -18, z: -24 };
14945
+ self.maxs = { x: 18, y: 18, z: 24 };
14946
+ self.health = 125;
14947
+ self.max_health = 125;
14948
+ self.mass = 300;
14949
+ self.pain = (e, o, k, d) => gekk_pain(e, o, k, d, context.entities);
14950
+ self.die = (e, i, a, d, p, m3) => gekk_die(e, i, a, d, p, m3, context.entities);
14951
+ self.monsterinfo.stand = gekk_stand;
14952
+ self.monsterinfo.walk = (s) => M_SetAnimation2(s, gekk_move_walk);
14953
+ self.monsterinfo.run = gekk_run_start;
14954
+ self.monsterinfo.attack = (s) => gekk_attack(s, context.entities);
14955
+ self.monsterinfo.melee = gekk_melee;
14956
+ self.monsterinfo.sight = (s, o) => context.entities.sound?.(s, 0, "gek/gk_sght1.wav", 1, 1, 0);
14957
+ self.monsterinfo.search = (s) => gekk_search(s, context.entities);
14958
+ self.monsterinfo.idle = (s) => {
14959
+ if (s.spawnflags & SPAWNFLAG_GEKK_NOSWIM || s.waterlevel < WATER_WAIST) {
14960
+ M_SetAnimation2(s, gekk_move_idle);
14961
+ } else {
14962
+ M_SetAnimation2(s, gekk_move_swim_start);
14963
+ }
14964
+ };
14965
+ self.monsterinfo.checkattack = (s) => gekk_checkattack(s, context.entities);
14966
+ context.entities.linkentity(self);
14967
+ M_SetAnimation2(self, gekk_move_stand);
14968
+ self.think = monster_think;
14969
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK24;
14970
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14971
+ M_SetAnimation2(self, gekk_move_chant);
14972
+ }
14973
+ }
14974
+ function M_SetAnimation2(self, move) {
14975
+ self.monsterinfo.current_move = move;
14976
+ }
14977
+ function gekk_attack(self, context) {
14978
+ if (!self.enemy) return;
14979
+ const r = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14980
+ if (self.flags & 2 /* Swim */) {
14981
+ if (self.enemy && self.enemy.waterlevel >= WATER_WAIST && r <= RANGE_NEAR2)
14982
+ return;
14983
+ self.flags &= ~2 /* Swim */;
14984
+ M_SetAnimation2(self, gekk_move_leapatk);
14985
+ self.frame = 144;
14986
+ } else {
14987
+ if (r >= RANGE_MID2) {
14988
+ if (frandom2() > 0.5) {
14989
+ M_SetAnimation2(self, gekk_move_spit);
14990
+ } else {
14991
+ M_SetAnimation2(self, gekk_move_run_start);
14992
+ }
14993
+ } else if (frandom2() > 0.7) {
14994
+ M_SetAnimation2(self, gekk_move_spit);
14995
+ } else {
14996
+ if (self.spawnflags & SPAWNFLAG_GEKK_NOJUMPING || frandom2() > 0.7) {
14997
+ M_SetAnimation2(self, gekk_move_run_start);
14998
+ } else {
14999
+ M_SetAnimation2(self, gekk_move_leapatk);
15000
+ }
15001
+ }
15002
+ }
15003
+ }
15004
+ function gekk_melee(self) {
15005
+ if (self.waterlevel >= WATER_WAIST) {
15006
+ M_SetAnimation2(self, gekk_move_attack);
15007
+ } else {
15008
+ if (frandom2() > 0.66) M_SetAnimation2(self, gekk_move_attack1);
15009
+ else M_SetAnimation2(self, gekk_move_attack2);
15010
+ }
15011
+ }
15012
+ function registerGekkSpawns(registry) {
15013
+ registry.register("monster_gekk", SP_monster_gekk);
15014
+ }
15015
+
15016
+ // src/entities/monsters/fixbot.ts
15017
+ var MONSTER_TICK25 = 0.1;
15018
+ var random9 = () => Math.random();
15019
+ var frandom3 = () => Math.random();
15020
+ function monster_ai_walk21(self, dist, context) {
15021
+ ai_walk(self, dist, MONSTER_TICK25, context);
15022
+ }
15023
+ function monster_ai_run22(self, dist, context) {
15024
+ ai_run(self, dist, MONSTER_TICK25, context);
15025
+ }
15026
+ function monster_ai_charge23(self, dist, context) {
15027
+ ai_charge(self, dist, MONSTER_TICK25, context);
15028
+ }
15029
+ function monster_ai_move22(self, dist, context) {
15030
+ ai_move(self, dist);
15031
+ }
15032
+ var fixbot_move_stand;
15033
+ var fixbot_move_walk;
15034
+ var fixbot_move_run;
15035
+ var fixbot_move_attack2;
15036
+ var fixbot_move_laserattack;
15037
+ var fixbot_move_weld_start;
15038
+ var fixbot_move_weld;
15039
+ var fixbot_move_weld_end;
15040
+ var fixbot_move_start_attack;
15041
+ var fixbot_move_pain3;
15042
+ var fixbot_move_painb;
15043
+ var fixbot_move_paina;
15044
+ var MZ2_HOVER_BLASTER_1 = 1;
15045
+ function fixbot_set_fly_parameters(self, heal, weld) {
15046
+ if (heal) {
15047
+ } else if (weld) {
15048
+ } else {
15049
+ }
15050
+ }
15051
+ function fixbot_FindDeadMonster(self, context) {
15052
+ const radius = 1024;
15053
+ const candidates = context.findByRadius(self.origin, radius);
15054
+ let best = null;
15055
+ for (const ent of candidates) {
15056
+ if (ent === self) continue;
15057
+ if (!ent.monsterinfo) continue;
15058
+ if (ent.monsterinfo.aiflags & 256 /* GoodGuy */) continue;
15059
+ if (ent.health > 0) continue;
15060
+ if (ent.nextthink && ent.think === context.free) continue;
15061
+ if (ent.health <= -40) continue;
15062
+ if (!visible(self, ent, context.trace)) continue;
15063
+ if (!best) {
15064
+ best = ent;
15065
+ continue;
15066
+ }
15067
+ if (ent.max_health <= best.max_health) continue;
15068
+ best = ent;
15069
+ }
15070
+ return best;
15071
+ }
15072
+ function fixbot_search(self, context) {
15073
+ if (self.enemy) return;
15074
+ const ent = fixbot_FindDeadMonster(self, context);
15075
+ if (ent) {
15076
+ self.enemy = ent;
15077
+ self.monsterinfo.aiflags |= 8192 /* Medic */;
15078
+ fixbot_run(self);
15079
+ fixbot_set_fly_parameters(self, true, false);
15080
+ } else {
15081
+ if (random9() < 0.1) {
15082
+ context.engine.sound?.(self, 0, "flyer/flysght1.wav", 1, 1, 0);
15083
+ }
15084
+ }
15085
+ }
15086
+ function fixbot_die(self, inflictor, attacker, damage, point, mod, context) {
15087
+ context.engine.sound?.(self, 0, "flyer/flydeth1.wav", 1, 1, 0);
15088
+ throwGibs(context, self.origin, damage);
15089
+ self.deadflag = 2 /* Dead */;
15090
+ self.takedamage = false;
15091
+ context.free(self);
15092
+ }
15093
+ function fixbot_fire_blaster_func(self, context) {
15094
+ if (!self.enemy || !self.enemy.inUse) {
15095
+ self.monsterinfo.current_move = fixbot_move_run;
15096
+ return;
15097
+ }
15098
+ const vectors = angleVectors(self.angles);
15099
+ const start = addVec3(self.origin, addVec3(scaleVec3(vectors.forward, 0), addVec3(scaleVec3(vectors.right, 0), scaleVec3(vectors.up, 0))));
15100
+ const end = copyVec3(self.enemy.origin);
15101
+ end.z += self.enemy.viewheight || 0;
15102
+ const dir = normalizeVec3(subtractVec3(end, start));
15103
+ monster_fire_blaster(self, start, dir, 15, 1e3, MZ2_HOVER_BLASTER_1, 0, context);
15104
+ }
15105
+ function fixbot_fire_laser(self, context) {
15106
+ if (!self.enemy || !self.enemy.inUse || self.enemy.health <= -40) {
15107
+ self.monsterinfo.current_move = fixbot_move_stand;
15108
+ self.monsterinfo.aiflags &= ~8192 /* Medic */;
15109
+ return;
15110
+ }
15111
+ if (self.enemy.health < self.enemy.max_health) {
15112
+ self.enemy.health += 5;
15113
+ if (self.enemy.health > self.enemy.max_health) self.enemy.health = self.enemy.max_health;
15114
+ } else {
15115
+ if (self.enemy.deadflag === 2 /* Dead */) {
15116
+ self.enemy.deadflag = 0 /* Alive */;
15117
+ self.enemy.solid = 2 /* BoundingBox */;
15118
+ self.enemy.takedamage = true;
15119
+ self.enemy.health = self.enemy.max_health;
15120
+ self.enemy.monsterinfo.aiflags &= ~128 /* HoldFrame */;
15121
+ }
15122
+ self.monsterinfo.current_move = fixbot_move_stand;
15123
+ self.monsterinfo.aiflags &= ~8192 /* Medic */;
15124
+ self.enemy = null;
15125
+ }
15126
+ }
15127
+ function fixbot_fire_welder(self, context) {
15128
+ if (frandom3() > 0.8) {
15129
+ const r = frandom3();
15130
+ if (r < 0.33) context.engine.sound?.(self, 0, "misc/welder1.wav", 1, 1, 0);
15131
+ else if (r < 0.66) context.engine.sound?.(self, 0, "misc/welder2.wav", 1, 1, 0);
15132
+ else context.engine.sound?.(self, 0, "misc/welder3.wav", 1, 1, 0);
15133
+ }
15134
+ }
15135
+ function fixbot_pain(self, other, kick, damage, context) {
15136
+ if (self.timestamp < (self.pain_debounce_time || 0)) return;
15137
+ self.pain_debounce_time = self.timestamp + 3;
15138
+ context.engine.sound?.(self, 0, "flyer/flypain1.wav", 1, 1, 0);
15139
+ if (damage <= 10) self.monsterinfo.current_move = fixbot_move_pain3;
15140
+ else if (damage <= 25) self.monsterinfo.current_move = fixbot_move_painb;
15141
+ else self.monsterinfo.current_move = fixbot_move_paina;
15142
+ }
15143
+ function fixbot_stand(self) {
15144
+ self.monsterinfo.current_move = fixbot_move_stand;
15145
+ }
15146
+ function fixbot_walk(self) {
15147
+ self.monsterinfo.current_move = fixbot_move_walk;
15148
+ }
15149
+ function fixbot_run(self) {
15150
+ if (self.monsterinfo.aiflags & 1 /* StandGround */)
15151
+ self.monsterinfo.current_move = fixbot_move_stand;
15152
+ else
15153
+ self.monsterinfo.current_move = fixbot_move_run;
15154
+ }
15155
+ function fixbot_start_attack(self) {
15156
+ self.monsterinfo.current_move = fixbot_move_start_attack;
15157
+ }
15158
+ function fixbot_attack(self) {
15159
+ if (self.monsterinfo.aiflags & 8192 /* Medic */) {
15160
+ self.monsterinfo.current_move = fixbot_move_laserattack;
15161
+ } else {
15162
+ self.monsterinfo.current_move = fixbot_move_attack2;
15163
+ }
15164
+ }
15165
+ function weldstate(self) {
15166
+ if (self.goalentity && self.goalentity.health > 0) {
15167
+ } else {
15168
+ self.monsterinfo.current_move = fixbot_move_stand;
15169
+ }
15170
+ }
15171
+ var frames_stand3 = Array(19).fill({ ai: monster_ai_move22, dist: 0 });
15172
+ frames_stand3[18] = { ai: monster_ai_move22, dist: 0, think: fixbot_search };
15173
+ fixbot_move_stand = {
15174
+ firstframe: 58,
15175
+ // FRAME_ambient_01
15176
+ lastframe: 76,
15177
+ frames: frames_stand3,
15178
+ endfunc: null
15179
+ };
15180
+ var frames_walk3 = [
15181
+ { ai: monster_ai_walk21, dist: 5 }
15182
+ ];
15183
+ fixbot_move_walk = {
15184
+ firstframe: 0,
15185
+ lastframe: 0,
15186
+ frames: frames_walk3,
15187
+ endfunc: null
15188
+ };
15189
+ var frames_run3 = [
15190
+ { ai: monster_ai_run22, dist: 10 }
15191
+ ];
15192
+ fixbot_move_run = {
15193
+ firstframe: 0,
15194
+ lastframe: 0,
15195
+ frames: frames_run3,
15196
+ endfunc: null
15197
+ };
15198
+ var frames_attack22 = Array(31).fill({ ai: monster_ai_charge23, dist: 0 });
15199
+ frames_attack22[20] = { ai: monster_ai_charge23, dist: 0, think: fixbot_fire_blaster_func };
15200
+ fixbot_move_attack2 = {
15201
+ firstframe: 121,
15202
+ // FRAME_charging_01
15203
+ lastframe: 151,
15204
+ frames: frames_attack22,
15205
+ endfunc: fixbot_run
15206
+ };
15207
+ var frames_laserattack = Array(6).fill({ ai: monster_ai_charge23, dist: 0, think: fixbot_fire_laser });
15208
+ fixbot_move_laserattack = {
15209
+ firstframe: 115,
15210
+ // FRAME_shoot_01
15211
+ lastframe: 120,
15212
+ frames: frames_laserattack,
15213
+ endfunc: null
15214
+ // Loops or handled by AI?
15215
+ };
15216
+ var frames_weld_start = Array(10).fill({ ai: monster_ai_move22, dist: 0 });
15217
+ frames_weld_start[9] = { ai: monster_ai_move22, dist: 0, think: weldstate };
15218
+ fixbot_move_weld_start = {
15219
+ firstframe: 77,
15220
+ // FRAME_weldstart_01
15221
+ lastframe: 86,
15222
+ frames: frames_weld_start,
15223
+ endfunc: null
15224
+ };
15225
+ var frames_weld = Array(7).fill({ ai: monster_ai_move22, dist: 0, think: fixbot_fire_welder });
15226
+ frames_weld[6] = { ai: monster_ai_move22, dist: 0, think: weldstate };
15227
+ fixbot_move_weld = {
15228
+ firstframe: 87,
15229
+ // FRAME_weldmiddle_01
15230
+ lastframe: 93,
15231
+ frames: frames_weld,
15232
+ endfunc: null
15233
+ };
15234
+ var frames_weld_end = Array(7).fill({ ai: monster_ai_move22, dist: -2 });
15235
+ frames_weld_end[6] = { ai: monster_ai_move22, dist: -2, think: weldstate };
15236
+ fixbot_move_weld_end = {
15237
+ firstframe: 94,
15238
+ // FRAME_weldend_01
15239
+ lastframe: 100,
15240
+ frames: frames_weld_end,
15241
+ endfunc: null
15242
+ };
15243
+ var frames_start_attack = [
15244
+ { ai: monster_ai_charge23, dist: 0 }
15245
+ ];
15246
+ fixbot_move_start_attack = {
15247
+ firstframe: 0,
15248
+ lastframe: 0,
15249
+ frames: frames_start_attack,
15250
+ endfunc: fixbot_attack
15251
+ };
15252
+ var frames_pain32 = [
15253
+ { ai: monster_ai_move22, dist: -1 }
15254
+ ];
15255
+ fixbot_move_pain3 = {
15256
+ firstframe: 0,
15257
+ lastframe: 0,
15258
+ frames: frames_pain32,
15259
+ endfunc: fixbot_run
15260
+ };
15261
+ var frames_painb = Array(8).fill({ ai: monster_ai_move22, dist: 0 });
15262
+ fixbot_move_painb = {
15263
+ firstframe: 107,
15264
+ // FRAME_painb_01
15265
+ lastframe: 114,
15266
+ frames: frames_painb,
15267
+ endfunc: fixbot_run
15268
+ };
15269
+ var frames_paina = Array(6).fill({ ai: monster_ai_move22, dist: 0 });
15270
+ fixbot_move_paina = {
15271
+ firstframe: 101,
15272
+ // FRAME_paina_01
15273
+ lastframe: 106,
15274
+ frames: frames_paina,
15275
+ endfunc: fixbot_run
15276
+ };
15277
+ function SP_monster_fixbot(self, context) {
15278
+ self.classname = "monster_fixbot";
15279
+ self.model = "models/monsters/fixbot/tris.md2";
15280
+ self.mins = { x: -32, y: -32, z: -24 };
15281
+ self.maxs = { x: 32, y: 32, z: 24 };
15282
+ self.movetype = 5 /* Step */;
15283
+ self.solid = 2 /* BoundingBox */;
15284
+ self.health = 150;
15285
+ self.mass = 150;
15286
+ self.pain = (e, o, k, d) => fixbot_pain(e, o, k, d, context.entities);
15287
+ self.die = (e, i, a, d, p, m3) => fixbot_die(e, i, a, d, p, m3, context.entities);
15288
+ self.monsterinfo.stand = fixbot_stand;
15289
+ self.monsterinfo.walk = fixbot_walk;
15290
+ self.monsterinfo.run = fixbot_run;
15291
+ self.monsterinfo.attack = fixbot_start_attack;
15292
+ context.entities.linkentity(self);
15293
+ self.monsterinfo.current_move = fixbot_move_stand;
15294
+ self.think = monster_think;
15295
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK25;
15296
+ self.flags |= 1 /* Fly */;
15297
+ }
15298
+ function registerFixbotSpawns(registry) {
15299
+ registry.register("monster_fixbot", SP_monster_fixbot);
15300
+ }
15301
+
14358
15302
  // src/entities/monsters/index.ts
14359
15303
  function registerMonsterSpawns2(registry) {
14360
15304
  registerMonsterSpawns(registry);
@@ -14381,6 +15325,8 @@ function registerMonsterSpawns2(registry) {
14381
15325
  registerMakronSpawns(registry);
14382
15326
  registerInsaneSpawns(registry);
14383
15327
  registerActorSpawns(registry);
15328
+ registerGekkSpawns(registry);
15329
+ registerFixbotSpawns(registry);
14384
15330
  }
14385
15331
 
14386
15332
  // src/entities/worldspawn.ts
@@ -15691,7 +16637,7 @@ function PlayerNoise(who, where, type, context) {
15691
16637
  }
15692
16638
 
15693
16639
  // src/combat/obituary.ts
15694
- var random8 = createRandomGenerator();
16640
+ var random10 = createRandomGenerator();
15695
16641
  var PRINT_MEDIUM = 1;
15696
16642
  function getGender(ent) {
15697
16643
  return "male";
@@ -15854,7 +16800,7 @@ var ANIM_PAIN = 2;
15854
16800
  var ANIM_DEATH = 3;
15855
16801
 
15856
16802
  // src/combat/weapons/firing.ts
15857
- var random9 = createRandomGenerator();
16803
+ var random11 = createRandomGenerator();
15858
16804
 
15859
16805
  // src/entities/player.ts
15860
16806
  function P_PlayerThink(ent, sys) {
@@ -15911,7 +16857,7 @@ function player_pain(self, damage) {
15911
16857
  return;
15912
16858
  }
15913
16859
  self.client.anim_priority = ANIM_PAIN;
15914
- const r = random9.frandom();
16860
+ const r = random11.frandom();
15915
16861
  if (r < 0.33) {
15916
16862
  self.frame = FRAME_pain1012;
15917
16863
  self.client.anim_end = FRAME_pain104;
@@ -15934,7 +16880,7 @@ function player_die(self, inflictor, attacker, damage, point, mod, sys) {
15934
16880
  }
15935
16881
  if (self.client) {
15936
16882
  self.client.anim_priority = ANIM_DEATH;
15937
- const r = random9.frandom();
16883
+ const r = random11.frandom();
15938
16884
  if (r < 0.33) {
15939
16885
  self.frame = FRAME_death1012;
15940
16886
  self.client.anim_end = FRAME_death106;
@@ -15987,25 +16933,12 @@ function player_think(self, sys) {
15987
16933
  }
15988
16934
 
15989
16935
  // src/entities/playerStats.ts
15990
- var WEAPON_WHEEL_ORDER = [
15991
- "blaster" /* Blaster */,
15992
- "shotgun" /* Shotgun */,
15993
- "supershotgun" /* SuperShotgun */,
15994
- "machinegun" /* Machinegun */,
15995
- "chaingun" /* Chaingun */,
15996
- "grenadelauncher" /* GrenadeLauncher */,
15997
- "rocketlauncher" /* RocketLauncher */,
15998
- "grenades" /* HandGrenade */,
15999
- "hyperblaster" /* HyperBlaster */,
16000
- "railgun" /* Railgun */,
16001
- "bfg10k" /* BFG10K */
16002
- ];
16003
16936
  var POWERUP_TIMERS = [
16004
- { id: "quad" /* QuadDamage */, priority: 1 },
16005
- { id: "invulnerability" /* Invulnerability */, priority: 2 },
16006
- { id: "enviro" /* EnviroSuit */, priority: 3 },
16007
- { id: "rebreather" /* Rebreather */, priority: 4 },
16008
- { id: "silencer" /* Silencer */, priority: 5 }
16937
+ { id: PowerupId.QuadDamage, priority: 1 },
16938
+ { id: PowerupId.Invulnerability, priority: 2 },
16939
+ { id: PowerupId.EnviroSuit, priority: 3 },
16940
+ { id: PowerupId.Rebreather, priority: 4 },
16941
+ { id: PowerupId.Silencer, priority: 5 }
16009
16942
  ];
16010
16943
  function populatePlayerStats(player, timeSeconds) {
16011
16944
  if (!player.client) return [];
@@ -16024,6 +16957,12 @@ function populatePlayerStats(player, timeSeconds) {
16024
16957
  }
16025
16958
  statArray[PlayerStat.STAT_WEAPONS_OWNED_1] = weaponBits & 65535;
16026
16959
  statArray[PlayerStat.STAT_WEAPONS_OWNED_2] = weaponBits >> 16 & 65535;
16960
+ if (inventory.currentWeapon) {
16961
+ const index = WEAPON_WHEEL_ORDER.indexOf(inventory.currentWeapon);
16962
+ if (index !== -1) {
16963
+ statArray[PlayerStat.STAT_ACTIVE_WHEEL_WEAPON] = index;
16964
+ }
16965
+ }
16027
16966
  statArray[PlayerStat.STAT_AMMO] = 0;
16028
16967
  if (inventory.currentWeapon) {
16029
16968
  const weaponItem = Object.values(WEAPON_ITEMS).find((item) => item.weaponId === inventory.currentWeapon);
@@ -16328,7 +17267,7 @@ var WEAPONS = {
16328
17267
  };
16329
17268
 
16330
17269
  // src/index.ts
16331
- var ZERO_VEC36 = { x: 0, y: 0, z: 0 };
17270
+ var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
16332
17271
  function createGame(imports, engine, options) {
16333
17272
  const gravity = options.gravity;
16334
17273
  const deathmatch = options.deathmatch ?? false;
@@ -16397,26 +17336,26 @@ function createGame(imports, engine, options) {
16397
17336
  };
16398
17337
  entities.runFrame();
16399
17338
  });
16400
- let origin = { ...ZERO_VEC36 };
16401
- let velocity = { ...ZERO_VEC36 };
17339
+ let origin = { ...ZERO_VEC37 };
17340
+ let velocity = { ...ZERO_VEC37 };
16402
17341
  const calculateBlend = (player, time) => {
16403
17342
  const blend = [0, 0, 0, 0];
16404
17343
  if (!player || !player.client) return blend;
16405
17344
  const inventory = player.client.inventory;
16406
- if (inventory.powerups.has("quad" /* QuadDamage */)) {
17345
+ if (inventory.powerups.has(PowerupId.QuadDamage)) {
16407
17346
  blend[2] = 1;
16408
17347
  blend[3] = 0.08;
16409
17348
  }
16410
- if (inventory.powerups.has("invulnerability" /* Invulnerability */)) {
17349
+ if (inventory.powerups.has(PowerupId.Invulnerability)) {
16411
17350
  blend[0] = 1;
16412
17351
  blend[1] = 1;
16413
17352
  blend[3] = 0.08;
16414
17353
  }
16415
- if (inventory.powerups.has("enviro" /* EnviroSuit */)) {
17354
+ if (inventory.powerups.has(PowerupId.EnviroSuit)) {
16416
17355
  blend[1] = 1;
16417
17356
  blend[3] = 0.08;
16418
17357
  }
16419
- if (inventory.powerups.has("rebreather" /* Rebreather */)) {
17358
+ if (inventory.powerups.has(PowerupId.Rebreather)) {
16420
17359
  blend[0] = 0.4;
16421
17360
  blend[1] = 1;
16422
17361
  blend[2] = 0.4;
@@ -16480,10 +17419,10 @@ function createGame(imports, engine, options) {
16480
17419
  // TODO
16481
17420
  damageIndicators: [],
16482
17421
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
16483
- kick_angles: player?.client?.kick_angles ?? ZERO_VEC36,
16484
- kick_origin: player?.client?.kick_origin ?? ZERO_VEC36,
16485
- gunoffset: ZERO_VEC36,
16486
- gunangles: ZERO_VEC36,
17422
+ kick_angles: player?.client?.kick_angles ?? ZERO_VEC37,
17423
+ kick_origin: player?.client?.kick_origin ?? ZERO_VEC37,
17424
+ gunoffset: ZERO_VEC37,
17425
+ gunangles: ZERO_VEC37,
16487
17426
  gunindex: 0,
16488
17427
  gun_frame: player?.client?.gun_frame ?? 0,
16489
17428
  rdflags: player?.client?.rdflags ?? 0,
@@ -16497,8 +17436,8 @@ function createGame(imports, engine, options) {
16497
17436
  const resetState = (startTimeMs) => {
16498
17437
  frameLoop.reset(startTimeMs);
16499
17438
  levelClock.start(startTimeMs);
16500
- origin = { ...ZERO_VEC36 };
16501
- velocity = { ...ZERO_VEC36 };
17439
+ origin = { ...ZERO_VEC37 };
17440
+ velocity = { ...ZERO_VEC37 };
16502
17441
  entities.beginFrame(startTimeMs / 1e3);
16503
17442
  entities.runFrame();
16504
17443
  };
@@ -16526,10 +17465,10 @@ function createGame(imports, engine, options) {
16526
17465
  blend: [0, 0, 0, 0],
16527
17466
  // Stubs
16528
17467
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
16529
- kick_angles: ZERO_VEC36,
16530
- kick_origin: ZERO_VEC36,
16531
- gunoffset: ZERO_VEC36,
16532
- gunangles: ZERO_VEC36,
17468
+ kick_angles: ZERO_VEC37,
17469
+ kick_origin: ZERO_VEC37,
17470
+ gunoffset: ZERO_VEC37,
17471
+ gunangles: ZERO_VEC37,
16533
17472
  gunindex: 0,
16534
17473
  pm_type: 0,
16535
17474
  pm_time: 0,
@@ -16659,8 +17598,8 @@ function createGame(imports, engine, options) {
16659
17598
  rng,
16660
17599
  player: player?.client?.inventory
16661
17600
  });
16662
- origin = player ? { ...player.origin } : { ...ZERO_VEC36 };
16663
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC36 };
17601
+ origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
17602
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
16664
17603
  frameLoop.reset(save.level.timeSeconds * 1e3);
16665
17604
  }
16666
17605
  };