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
@@ -767,6 +767,33 @@ function setCompressedInteger(stats, startIndex, id, count, bitsPerValue) {
767
767
  const valueToWrite = base & ~mask | count << bitShift & mask;
768
768
  writeUint16LE(stats, startIndex, byteOffset, valueToWrite & 65535);
769
769
  }
770
+ var PowerupId = /* @__PURE__ */ ((PowerupId22) => {
771
+ PowerupId22["QuadDamage"] = "quad";
772
+ PowerupId22["Invulnerability"] = "invulnerability";
773
+ PowerupId22["EnviroSuit"] = "enviro_suit";
774
+ PowerupId22["Rebreather"] = "rebreather";
775
+ PowerupId22["Silencer"] = "silencer";
776
+ PowerupId22["PowerScreen"] = "power_screen";
777
+ PowerupId22["PowerShield"] = "power_shield";
778
+ PowerupId22["QuadFire"] = "quad_fire";
779
+ PowerupId22["Invisibility"] = "invisibility";
780
+ PowerupId22["Bandolier"] = "bandolier";
781
+ PowerupId22["AmmoPack"] = "ammo_pack";
782
+ PowerupId22["IRGoggles"] = "ir_goggles";
783
+ PowerupId22["DoubleDamage"] = "double_damage";
784
+ PowerupId22["SphereVengeance"] = "sphere_vengeance";
785
+ PowerupId22["SphereHunter"] = "sphere_hunter";
786
+ PowerupId22["SphereDefender"] = "sphere_defender";
787
+ PowerupId22["Doppelganger"] = "doppelganger";
788
+ PowerupId22["TagToken"] = "tag_token";
789
+ PowerupId22["TechResistance"] = "tech_resistance";
790
+ PowerupId22["TechStrength"] = "tech_strength";
791
+ PowerupId22["TechHaste"] = "tech_haste";
792
+ PowerupId22["TechRegeneration"] = "tech_regeneration";
793
+ PowerupId22["Flashlight"] = "flashlight";
794
+ PowerupId22["Compass"] = "compass";
795
+ return PowerupId22;
796
+ })(PowerupId || {});
770
797
  var PlayerStat = /* @__PURE__ */ ((PlayerStat2) => {
771
798
  PlayerStat2[PlayerStat2["STAT_HEALTH_ICON"] = 0] = "STAT_HEALTH_ICON";
772
799
  PlayerStat2[PlayerStat2["STAT_HEALTH"] = 1] = "STAT_HEALTH";
@@ -1081,6 +1108,29 @@ var applyPmove = (state, cmd, trace, pointContents2) => {
1081
1108
  velocity: finalVelocity
1082
1109
  };
1083
1110
  };
1111
+ var WeaponId = /* @__PURE__ */ ((WeaponId22) => {
1112
+ WeaponId22["Blaster"] = "blaster";
1113
+ WeaponId22["Shotgun"] = "shotgun";
1114
+ WeaponId22["SuperShotgun"] = "supershotgun";
1115
+ WeaponId22["Machinegun"] = "machinegun";
1116
+ WeaponId22["Chaingun"] = "chaingun";
1117
+ WeaponId22["HandGrenade"] = "grenades";
1118
+ WeaponId22["GrenadeLauncher"] = "grenadelauncher";
1119
+ WeaponId22["RocketLauncher"] = "rocketlauncher";
1120
+ WeaponId22["HyperBlaster"] = "hyperblaster";
1121
+ WeaponId22["Railgun"] = "railgun";
1122
+ WeaponId22["BFG10K"] = "bfg10k";
1123
+ WeaponId22["Grapple"] = "grapple";
1124
+ WeaponId22["ChainFist"] = "chainfist";
1125
+ WeaponId22["EtfRifle"] = "etf_rifle";
1126
+ WeaponId22["ProxLauncher"] = "prox_launcher";
1127
+ WeaponId22["IonRipper"] = "ionripper";
1128
+ WeaponId22["PlasmaBeam"] = "plasmabeam";
1129
+ WeaponId22["Phalanx"] = "phalanx";
1130
+ WeaponId22["Disruptor"] = "disruptor";
1131
+ WeaponId22["Trap"] = "trap";
1132
+ return WeaponId22;
1133
+ })(WeaponId || {});
1084
1134
  var AmmoType = /* @__PURE__ */ ((AmmoType22) => {
1085
1135
  AmmoType22[AmmoType22["Bullets"] = 0] = "Bullets";
1086
1136
  AmmoType22[AmmoType22["Shells"] = 1] = "Shells";
@@ -1114,6 +1164,20 @@ var AmmoItemId = /* @__PURE__ */ ((AmmoItemId22) => {
1114
1164
  AmmoItemId22["Prox"] = "ammo_prox";
1115
1165
  return AmmoItemId22;
1116
1166
  })(AmmoItemId || {});
1167
+ var WEAPON_WHEEL_ORDER = [
1168
+ "blaster",
1169
+ "shotgun",
1170
+ "supershotgun",
1171
+ "machinegun",
1172
+ "chaingun",
1173
+ "grenadelauncher",
1174
+ "rocketlauncher",
1175
+ "grenades",
1176
+ "hyperblaster",
1177
+ "railgun",
1178
+ "bfg10k"
1179
+ /* BFG10K */
1180
+ ];
1117
1181
 
1118
1182
  // src/inventory/ammo.ts
1119
1183
  var AMMO_ITEM_DEFINITIONS = {
@@ -1296,54 +1360,6 @@ function applyPowerArmor(damage, flags, hitPoint, _hitNormal, state, options = {
1296
1360
  }
1297
1361
 
1298
1362
  // src/inventory/playerInventory.ts
1299
- var WeaponId = /* @__PURE__ */ ((WeaponId3) => {
1300
- WeaponId3["Blaster"] = "blaster";
1301
- WeaponId3["Shotgun"] = "shotgun";
1302
- WeaponId3["SuperShotgun"] = "supershotgun";
1303
- WeaponId3["Machinegun"] = "machinegun";
1304
- WeaponId3["Chaingun"] = "chaingun";
1305
- WeaponId3["GrenadeLauncher"] = "grenadelauncher";
1306
- WeaponId3["RocketLauncher"] = "rocketlauncher";
1307
- WeaponId3["HyperBlaster"] = "hyperblaster";
1308
- WeaponId3["Railgun"] = "railgun";
1309
- WeaponId3["BFG10K"] = "bfg10k";
1310
- WeaponId3["HandGrenade"] = "grenades";
1311
- WeaponId3["Grapple"] = "grapple";
1312
- WeaponId3["IonRipper"] = "ionripper";
1313
- WeaponId3["Phalanx"] = "phalanx";
1314
- WeaponId3["Trap"] = "trap";
1315
- WeaponId3["PlasmaBeam"] = "plasmabeam";
1316
- WeaponId3["EtfRifle"] = "etfrifle";
1317
- WeaponId3["ProxLauncher"] = "proxlauncher";
1318
- WeaponId3["ChainFist"] = "chainfist";
1319
- WeaponId3["Disruptor"] = "disruptor";
1320
- return WeaponId3;
1321
- })(WeaponId || {});
1322
- var PowerupId = /* @__PURE__ */ ((PowerupId3) => {
1323
- PowerupId3["QuadDamage"] = "quad";
1324
- PowerupId3["Invulnerability"] = "invulnerability";
1325
- PowerupId3["Silencer"] = "silencer";
1326
- PowerupId3["Rebreather"] = "rebreather";
1327
- PowerupId3["EnviroSuit"] = "enviro";
1328
- PowerupId3["DoubleDamage"] = "double";
1329
- PowerupId3["QuadFire"] = "quadfire";
1330
- PowerupId3["Invisibility"] = "invisibility";
1331
- PowerupId3["Bandolier"] = "bandolier";
1332
- PowerupId3["AmmoPack"] = "pack";
1333
- PowerupId3["IRGoggles"] = "goggles";
1334
- PowerupId3["SphereVengeance"] = "vengeance";
1335
- PowerupId3["SphereHunter"] = "hunter";
1336
- PowerupId3["SphereDefender"] = "defender";
1337
- PowerupId3["Doppelganger"] = "doppelganger";
1338
- PowerupId3["TagToken"] = "tagtoken";
1339
- PowerupId3["TechResistance"] = "tech_resistance";
1340
- PowerupId3["TechStrength"] = "tech_strength";
1341
- PowerupId3["TechHaste"] = "tech_haste";
1342
- PowerupId3["TechRegeneration"] = "tech_regeneration";
1343
- PowerupId3["Flashlight"] = "flashlight";
1344
- PowerupId3["Compass"] = "compass";
1345
- return PowerupId3;
1346
- })(PowerupId || {});
1347
1363
  var KeyId = /* @__PURE__ */ ((KeyId2) => {
1348
1364
  KeyId2["Blue"] = "key_blue";
1349
1365
  KeyId2["Red"] = "key_red";
@@ -1368,7 +1384,7 @@ function createPlayerInventory(init = {}) {
1368
1384
  const ammoCaps = init.ammoCaps;
1369
1385
  const inv = {
1370
1386
  ammo: createAmmoInventory(ammoCaps),
1371
- ownedWeapons: new Set(init.weapons ?? ["blaster" /* Blaster */]),
1387
+ ownedWeapons: new Set(init.weapons ?? [WeaponId.Blaster]),
1372
1388
  armor: null,
1373
1389
  powerups: /* @__PURE__ */ new Map(),
1374
1390
  keys: /* @__PURE__ */ new Set(),
@@ -1382,8 +1398,8 @@ function createPlayerInventory(init = {}) {
1382
1398
  if (init.currentWeapon) {
1383
1399
  inv.currentWeapon = init.currentWeapon;
1384
1400
  } else if (inv.ownedWeapons.size > 0) {
1385
- if (inv.ownedWeapons.has("blaster" /* Blaster */)) inv.currentWeapon = "blaster" /* Blaster */;
1386
- else if (inv.ownedWeapons.has("shotgun" /* Shotgun */)) inv.currentWeapon = "shotgun" /* Shotgun */;
1401
+ if (inv.ownedWeapons.has(WeaponId.Blaster)) inv.currentWeapon = WeaponId.Blaster;
1402
+ else if (inv.ownedWeapons.has(WeaponId.Shotgun)) inv.currentWeapon = WeaponId.Shotgun;
1387
1403
  else inv.currentWeapon = [...inv.ownedWeapons][0];
1388
1404
  }
1389
1405
  return inv;
@@ -1512,27 +1528,27 @@ function pickupPowerup(client, item, time) {
1512
1528
  let icon = "";
1513
1529
  switch (item.id) {
1514
1530
  case "item_quad":
1515
- powerupId = "quad" /* QuadDamage */;
1531
+ powerupId = PowerupId.QuadDamage;
1516
1532
  icon = "p_quad";
1517
1533
  break;
1518
1534
  case "item_invulnerability":
1519
- powerupId = "invulnerability" /* Invulnerability */;
1535
+ powerupId = PowerupId.Invulnerability;
1520
1536
  icon = "p_invulnerability";
1521
1537
  break;
1522
1538
  case "item_silencer":
1523
- powerupId = "silencer" /* Silencer */;
1539
+ powerupId = PowerupId.Silencer;
1524
1540
  icon = "p_silencer";
1525
1541
  break;
1526
1542
  case "item_rebreather":
1527
- powerupId = "rebreather" /* Rebreather */;
1543
+ powerupId = PowerupId.Rebreather;
1528
1544
  icon = "p_rebreather";
1529
1545
  break;
1530
1546
  case "item_enviro":
1531
- powerupId = "enviro" /* EnviroSuit */;
1547
+ powerupId = PowerupId.EnviroSuit;
1532
1548
  icon = "p_envirosuit";
1533
1549
  break;
1534
1550
  case "item_double":
1535
- powerupId = "double" /* DoubleDamage */;
1551
+ powerupId = PowerupId.DoubleDamage;
1536
1552
  icon = "p_double";
1537
1553
  break;
1538
1554
  }
@@ -1540,9 +1556,9 @@ function pickupPowerup(client, item, time) {
1540
1556
  const expiresAt = inventory.powerups.get(powerupId);
1541
1557
  const newExpiresAt = expiresAt && expiresAt > time ? expiresAt + item.timer * 1e3 : time + item.timer * 1e3;
1542
1558
  inventory.powerups.set(powerupId, newExpiresAt);
1543
- if (powerupId === "quad" /* QuadDamage */) {
1559
+ if (powerupId === PowerupId.QuadDamage) {
1544
1560
  client.quad_time = newExpiresAt / 1e3;
1545
- } else if (powerupId === "double" /* DoubleDamage */) {
1561
+ } else if (powerupId === PowerupId.DoubleDamage) {
1546
1562
  client.double_time = newExpiresAt / 1e3;
1547
1563
  }
1548
1564
  setPickup(inventory, icon, time);
@@ -5417,7 +5433,7 @@ function chaingunThink(player, sys) {
5417
5433
  if (!player.client) {
5418
5434
  return;
5419
5435
  }
5420
- const weaponState = getWeaponState(player.client.weaponStates, "chaingun" /* Chaingun */);
5436
+ const weaponState = getWeaponState(player.client.weaponStates, WeaponId.Chaingun);
5421
5437
  if (!(player.client.buttons & BUTTON_ATTACK) && weaponState.spinupCount && weaponState.spinupCount > 0) {
5422
5438
  sys.sound(player, 0, "weapons/chngnd1a.wav", 1, 0, 0);
5423
5439
  weaponState.spinupCount = 0;
@@ -5430,7 +5446,7 @@ var WEAPON_ITEMS = {
5430
5446
  type: "weapon",
5431
5447
  id: "weapon_blaster",
5432
5448
  name: "Blaster",
5433
- weaponId: "blaster" /* Blaster */,
5449
+ weaponId: WeaponId.Blaster,
5434
5450
  ammoType: null,
5435
5451
  initialAmmo: 0,
5436
5452
  pickupAmmo: 0,
@@ -5440,7 +5456,7 @@ var WEAPON_ITEMS = {
5440
5456
  type: "weapon",
5441
5457
  id: "weapon_shotgun",
5442
5458
  name: "Shotgun",
5443
- weaponId: "shotgun" /* Shotgun */,
5459
+ weaponId: WeaponId.Shotgun,
5444
5460
  ammoType: AmmoType.Shells,
5445
5461
  initialAmmo: 10,
5446
5462
  pickupAmmo: 10,
@@ -5450,7 +5466,7 @@ var WEAPON_ITEMS = {
5450
5466
  type: "weapon",
5451
5467
  id: "weapon_supershotgun",
5452
5468
  name: "Super Shotgun",
5453
- weaponId: "supershotgun" /* SuperShotgun */,
5469
+ weaponId: WeaponId.SuperShotgun,
5454
5470
  ammoType: AmmoType.Shells,
5455
5471
  initialAmmo: 10,
5456
5472
  pickupAmmo: 10,
@@ -5460,7 +5476,7 @@ var WEAPON_ITEMS = {
5460
5476
  type: "weapon",
5461
5477
  id: "weapon_machinegun",
5462
5478
  name: "Machinegun",
5463
- weaponId: "machinegun" /* Machinegun */,
5479
+ weaponId: WeaponId.Machinegun,
5464
5480
  ammoType: AmmoType.Bullets,
5465
5481
  initialAmmo: 50,
5466
5482
  pickupAmmo: 50,
@@ -5471,7 +5487,7 @@ var WEAPON_ITEMS = {
5471
5487
  type: "weapon",
5472
5488
  id: "weapon_chaingun",
5473
5489
  name: "Chaingun",
5474
- weaponId: "chaingun" /* Chaingun */,
5490
+ weaponId: WeaponId.Chaingun,
5475
5491
  ammoType: AmmoType.Bullets,
5476
5492
  initialAmmo: 50,
5477
5493
  pickupAmmo: 50,
@@ -5481,7 +5497,7 @@ var WEAPON_ITEMS = {
5481
5497
  type: "weapon",
5482
5498
  id: "weapon_grenades",
5483
5499
  name: "Hand Grenade",
5484
- weaponId: "grenades" /* HandGrenade */,
5500
+ weaponId: WeaponId.HandGrenade,
5485
5501
  ammoType: AmmoType.Grenades,
5486
5502
  initialAmmo: 5,
5487
5503
  pickupAmmo: 5,
@@ -5491,7 +5507,7 @@ var WEAPON_ITEMS = {
5491
5507
  type: "weapon",
5492
5508
  id: "weapon_grenadelauncher",
5493
5509
  name: "Grenade Launcher",
5494
- weaponId: "grenadelauncher" /* GrenadeLauncher */,
5510
+ weaponId: WeaponId.GrenadeLauncher,
5495
5511
  ammoType: AmmoType.Grenades,
5496
5512
  initialAmmo: 10,
5497
5513
  pickupAmmo: 10,
@@ -5501,7 +5517,7 @@ var WEAPON_ITEMS = {
5501
5517
  type: "weapon",
5502
5518
  id: "weapon_rocketlauncher",
5503
5519
  name: "Rocket Launcher",
5504
- weaponId: "rocketlauncher" /* RocketLauncher */,
5520
+ weaponId: WeaponId.RocketLauncher,
5505
5521
  ammoType: AmmoType.Rockets,
5506
5522
  initialAmmo: 5,
5507
5523
  pickupAmmo: 5,
@@ -5511,7 +5527,7 @@ var WEAPON_ITEMS = {
5511
5527
  type: "weapon",
5512
5528
  id: "weapon_hyperblaster",
5513
5529
  name: "HyperBlaster",
5514
- weaponId: "hyperblaster" /* HyperBlaster */,
5530
+ weaponId: WeaponId.HyperBlaster,
5515
5531
  ammoType: AmmoType.Cells,
5516
5532
  initialAmmo: 50,
5517
5533
  pickupAmmo: 50,
@@ -5521,7 +5537,7 @@ var WEAPON_ITEMS = {
5521
5537
  type: "weapon",
5522
5538
  id: "weapon_railgun",
5523
5539
  name: "Railgun",
5524
- weaponId: "railgun" /* Railgun */,
5540
+ weaponId: WeaponId.Railgun,
5525
5541
  ammoType: AmmoType.Slugs,
5526
5542
  initialAmmo: 10,
5527
5543
  pickupAmmo: 10,
@@ -5531,7 +5547,7 @@ var WEAPON_ITEMS = {
5531
5547
  type: "weapon",
5532
5548
  id: "weapon_bfg",
5533
5549
  name: "BFG10K",
5534
- weaponId: "bfg10k" /* BFG10K */,
5550
+ weaponId: WeaponId.BFG10K,
5535
5551
  ammoType: AmmoType.Cells,
5536
5552
  initialAmmo: 50,
5537
5553
  pickupAmmo: 50,
@@ -5543,7 +5559,7 @@ var WEAPON_ITEMS = {
5543
5559
  id: "weapon_boomer",
5544
5560
  // Ion Ripper
5545
5561
  name: "Ion Ripper",
5546
- weaponId: "ionripper" /* IonRipper */,
5562
+ weaponId: WeaponId.IonRipper,
5547
5563
  ammoType: AmmoType.Cells,
5548
5564
  initialAmmo: 50,
5549
5565
  pickupAmmo: 50,
@@ -5553,7 +5569,7 @@ var WEAPON_ITEMS = {
5553
5569
  type: "weapon",
5554
5570
  id: "weapon_phalanx",
5555
5571
  name: "Phalanx",
5556
- weaponId: "phalanx" /* Phalanx */,
5572
+ weaponId: WeaponId.Phalanx,
5557
5573
  ammoType: AmmoType.MagSlugs,
5558
5574
  initialAmmo: 50,
5559
5575
  pickupAmmo: 50,
@@ -5563,7 +5579,7 @@ var WEAPON_ITEMS = {
5563
5579
  type: "weapon",
5564
5580
  id: "weapon_beam",
5565
5581
  name: "Plasma Beam",
5566
- weaponId: "plasmabeam" /* PlasmaBeam */,
5582
+ weaponId: WeaponId.PlasmaBeam,
5567
5583
  ammoType: AmmoType.Cells,
5568
5584
  initialAmmo: 50,
5569
5585
  pickupAmmo: 50,
@@ -5573,7 +5589,7 @@ var WEAPON_ITEMS = {
5573
5589
  type: "weapon",
5574
5590
  id: "weapon_etf_rifle",
5575
5591
  name: "ETF Rifle",
5576
- weaponId: "etfrifle" /* EtfRifle */,
5592
+ weaponId: WeaponId.EtfRifle,
5577
5593
  ammoType: AmmoType.Flechettes,
5578
5594
  initialAmmo: 50,
5579
5595
  pickupAmmo: 50,
@@ -5583,7 +5599,7 @@ var WEAPON_ITEMS = {
5583
5599
  type: "weapon",
5584
5600
  id: "weapon_proxlauncher",
5585
5601
  name: "Prox Launcher",
5586
- weaponId: "proxlauncher" /* ProxLauncher */,
5602
+ weaponId: WeaponId.ProxLauncher,
5587
5603
  ammoType: AmmoType.Prox,
5588
5604
  initialAmmo: 5,
5589
5605
  pickupAmmo: 5,
@@ -11492,8 +11508,8 @@ function actor_pain(self, other, kick, damage) {
11492
11508
  if (context.timeSeconds < self.pain_debounce_time)
11493
11509
  return;
11494
11510
  self.pain_debounce_time = context.timeSeconds + 3;
11495
- const random10 = Math.random();
11496
- if (other && other.client && random10 < 0.4) {
11511
+ const random12 = Math.random();
11512
+ if (other && other.client && random12 < 0.4) {
11497
11513
  const v = subtractVec3(other.origin, self.origin);
11498
11514
  self.ideal_yaw = vectorToYaw(v);
11499
11515
  if (Math.random() < 0.5)
@@ -14189,6 +14205,934 @@ function registerTurretSpawns(registry) {
14189
14205
  registry.register("monster_turret", SP_monster_turret);
14190
14206
  }
14191
14207
 
14208
+ // src/entities/monsters/gekk.ts
14209
+ var MONSTER_TICK24 = 0.1;
14210
+ var random8 = () => Math.random();
14211
+ var frandom2 = () => Math.random();
14212
+ var irandom2 = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
14213
+ function monster_ai_stand22(self, dist, context) {
14214
+ ai_stand(self, MONSTER_TICK24, context);
14215
+ }
14216
+ function monster_ai_walk20(self, dist, context) {
14217
+ ai_walk(self, dist, MONSTER_TICK24, context);
14218
+ }
14219
+ function monster_ai_run21(self, dist, context) {
14220
+ ai_run(self, dist, MONSTER_TICK24, context);
14221
+ }
14222
+ function monster_ai_charge22(self, dist, context) {
14223
+ ai_charge(self, dist, MONSTER_TICK24, context);
14224
+ }
14225
+ function monster_ai_move21(self, dist, context) {
14226
+ ai_move(self, dist);
14227
+ }
14228
+ var gekk_move_stand;
14229
+ var gekk_move_standunderwater;
14230
+ var gekk_move_swim_loop;
14231
+ var gekk_move_swim_start;
14232
+ var gekk_move_chant;
14233
+ var gekk_move_idle;
14234
+ var gekk_move_idle2;
14235
+ var gekk_move_walk;
14236
+ var gekk_move_run;
14237
+ var gekk_move_run_start;
14238
+ var gekk_move_attack1;
14239
+ var gekk_move_attack2;
14240
+ var gekk_move_spit;
14241
+ var gekk_move_leapatk;
14242
+ var gekk_move_leapatk2;
14243
+ var gekk_move_attack;
14244
+ var gekk_move_pain;
14245
+ var gekk_move_pain1;
14246
+ var gekk_move_pain2;
14247
+ var gekk_move_death1;
14248
+ var gekk_move_death3;
14249
+ var gekk_move_death4;
14250
+ var gekk_move_wdeath;
14251
+ var WATER_WAIST = 2;
14252
+ var RANGE_MELEE2 = 80;
14253
+ var RANGE_NEAR2 = 100;
14254
+ var RANGE_MID2 = 400;
14255
+ var SPAWNFLAG_GEKK_CHANT = 8;
14256
+ var SPAWNFLAG_GEKK_NOJUMPING = 16;
14257
+ var SPAWNFLAG_GEKK_NOSWIM = 32;
14258
+ var GIB_HEALTH = -30;
14259
+ function gekk_check_underwater(self, context) {
14260
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14261
+ land_to_water(self);
14262
+ }
14263
+ }
14264
+ function gekk_stand(self) {
14265
+ if (self.waterlevel >= WATER_WAIST) {
14266
+ self.flags |= 2 /* Swim */;
14267
+ self.monsterinfo.current_move = gekk_move_standunderwater;
14268
+ } else {
14269
+ if (self.monsterinfo.current_move !== gekk_move_chant) {
14270
+ self.monsterinfo.current_move = gekk_move_stand;
14271
+ }
14272
+ }
14273
+ }
14274
+ function gekk_swim_loop_func(self) {
14275
+ self.flags |= 2 /* Swim */;
14276
+ self.monsterinfo.current_move = gekk_move_swim_loop;
14277
+ }
14278
+ function gekk_hit_left(self, context) {
14279
+ if (!self.enemy) return;
14280
+ const damage = irandom2(5, 10);
14281
+ const range = 100;
14282
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14283
+ const dist = lengthVec3(dir);
14284
+ if (dist <= range) {
14285
+ context.engine.sound?.(self, 0, "gek/gk_atck2.wav", 1, 1, 0);
14286
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, damage, 0, 0 /* UNKNOWN */, context.timeSeconds);
14287
+ } else {
14288
+ context.engine.sound?.(self, 0, "gek/gk_atck1.wav", 1, 1, 0);
14289
+ }
14290
+ }
14291
+ function gekk_hit_right(self, context) {
14292
+ if (!self.enemy) return;
14293
+ const damage = irandom2(5, 10);
14294
+ const range = 100;
14295
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14296
+ const dist = lengthVec3(dir);
14297
+ if (dist <= range) {
14298
+ context.engine.sound?.(self, 0, "gek/gk_atck3.wav", 1, 1, 0);
14299
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, damage, 0, 0 /* UNKNOWN */, context.timeSeconds);
14300
+ } else {
14301
+ context.engine.sound?.(self, 0, "gek/gk_atck1.wav", 1, 1, 0);
14302
+ }
14303
+ }
14304
+ function gekk_bite(self, context) {
14305
+ if (!self.enemy) return;
14306
+ const damage = 5;
14307
+ const range = RANGE_MELEE2;
14308
+ const dir = subtractVec3(self.enemy.origin, self.origin);
14309
+ const dist = lengthVec3(dir);
14310
+ if (dist <= range) {
14311
+ T_Damage(self.enemy, self, self, normalizeVec3(dir), self.enemy.origin, ZERO_VEC3, damage, 0, 0, 0 /* UNKNOWN */, context.timeSeconds);
14312
+ }
14313
+ }
14314
+ function gekk_check_melee(self, context) {
14315
+ if (!self.enemy || self.enemy.health <= 0 || self.monsterinfo.melee_debounce_time && self.monsterinfo.melee_debounce_time > context.timeSeconds)
14316
+ return false;
14317
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14318
+ return dist <= RANGE_MELEE2;
14319
+ }
14320
+ function gekk_check_jump(self, context) {
14321
+ if (!self.enemy) return false;
14322
+ if (self.absmin.z + 125 < self.enemy.absmin.z)
14323
+ return false;
14324
+ const v = subtractVec3(self.origin, self.enemy.origin);
14325
+ v.z = 0;
14326
+ const distance2 = lengthVec3(v);
14327
+ if (distance2 < 100) return false;
14328
+ if (distance2 > 100) {
14329
+ if (frandom2() < (self.waterlevel >= WATER_WAIST ? 0.2 : 0.9))
14330
+ return false;
14331
+ }
14332
+ return true;
14333
+ }
14334
+ function gekk_check_jump_close(self, context) {
14335
+ if (!self.enemy) return false;
14336
+ const v = subtractVec3(self.origin, self.enemy.origin);
14337
+ v.z = 0;
14338
+ const distance2 = lengthVec3(v);
14339
+ if (distance2 < 100) {
14340
+ if (self.absmax.z <= self.enemy.absmin.z) return false;
14341
+ }
14342
+ return true;
14343
+ }
14344
+ function gekk_checkattack(self, context) {
14345
+ if (!self.enemy || self.enemy.health <= 0) return false;
14346
+ if (gekk_check_melee(self, context)) {
14347
+ return true;
14348
+ }
14349
+ if (gekk_check_jump(self, context)) {
14350
+ return true;
14351
+ }
14352
+ if (gekk_check_jump_close(self, context) && !(self.flags & 2 /* Swim */)) {
14353
+ return true;
14354
+ }
14355
+ return false;
14356
+ }
14357
+ function gekk_chant(self) {
14358
+ self.monsterinfo.current_move = gekk_move_chant;
14359
+ }
14360
+ function gekk_idle_loop(self) {
14361
+ if (frandom2() > 0.75 && self.health < self.max_health) {
14362
+ self.monsterinfo.nextframe = 0;
14363
+ }
14364
+ }
14365
+ function gekk_step(self, context) {
14366
+ const n = irandom2(0, 2);
14367
+ const sounds = ["gek/gk_step1.wav", "gek/gk_step2.wav", "gek/gk_step3.wav"];
14368
+ context.engine.sound?.(self, 0, sounds[n], 1, 1, 0);
14369
+ }
14370
+ function gekk_search(self, context) {
14371
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14372
+ const r = frandom2();
14373
+ if (r < 0.33) context.engine.sound?.(self, 0, "gek/gek_low.wav", 1, 1, 0);
14374
+ else if (r < 0.66) context.engine.sound?.(self, 0, "gek/gek_mid.wav", 1, 1, 0);
14375
+ else context.engine.sound?.(self, 0, "gek/gek_high.wav", 1, 1, 0);
14376
+ } else {
14377
+ context.engine.sound?.(self, 0, "gek/gk_idle1.wav", 1, 1, 0);
14378
+ }
14379
+ self.health += irandom2(10, 20);
14380
+ if (self.health > self.max_health) self.health = self.max_health;
14381
+ if (self.health < self.max_health / 4) self.skin = 2;
14382
+ else if (self.health < self.max_health / 2) self.skin = 1;
14383
+ else self.skin = 0;
14384
+ }
14385
+ function gekk_run_start(self) {
14386
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14387
+ self.monsterinfo.current_move = gekk_move_swim_start;
14388
+ } else {
14389
+ self.monsterinfo.current_move = gekk_move_run_start;
14390
+ }
14391
+ }
14392
+ function gekk_run(self) {
14393
+ if (!(self.spawnflags & SPAWNFLAG_GEKK_NOSWIM) && self.waterlevel >= WATER_WAIST) {
14394
+ self.monsterinfo.current_move = gekk_move_swim_start;
14395
+ } else {
14396
+ self.monsterinfo.current_move = gekk_move_run;
14397
+ }
14398
+ }
14399
+ function gekk_check_refire(self) {
14400
+ if (!self.enemy || self.enemy.health <= 0) return;
14401
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14402
+ if (dist <= RANGE_MELEE2) {
14403
+ if (self.frame === 114) {
14404
+ self.monsterinfo.current_move = gekk_move_attack2;
14405
+ } else if (self.frame === 123) {
14406
+ self.monsterinfo.current_move = gekk_move_attack1;
14407
+ }
14408
+ }
14409
+ }
14410
+ function fire_loogie(self, start, dir, damage, speed, context) {
14411
+ const bolt = createBlasterBolt(context, self, start, dir, damage, speed, 0 /* UNKNOWN */);
14412
+ bolt.model = "models/objects/loogy/tris.md2";
14413
+ }
14414
+ function loogie_fire(self, context) {
14415
+ if (!self.enemy || self.enemy.health <= 0) return;
14416
+ const vectors = angleVectors(self.angles);
14417
+ const forward = vectors.forward;
14418
+ const right = vectors.right;
14419
+ const up = vectors.up;
14420
+ const offset = { x: -18, y: -0.8, z: 24 };
14421
+ const start = addVec3(self.origin, addVec3(scaleVec3(forward, offset.x), addVec3(scaleVec3(right, offset.y), scaleVec3(up, offset.z))));
14422
+ start.z += 2;
14423
+ const end = copyVec3(self.enemy.origin);
14424
+ end.z += self.enemy.viewheight || 0;
14425
+ const dir = normalizeVec3(subtractVec3(end, start));
14426
+ fire_loogie(self, start, dir, 5, 550, context);
14427
+ context.engine.sound?.(self, 0, "gek/gk_atck4.wav", 1, 1, 0);
14428
+ }
14429
+ function reloogie(self) {
14430
+ if (frandom2() > 0.8 && self.health < self.max_health) {
14431
+ self.monsterinfo.current_move = gekk_move_idle2;
14432
+ return;
14433
+ }
14434
+ if (self.enemy && self.enemy.health > 0) {
14435
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14436
+ if (frandom2() > 0.7 && dist <= RANGE_NEAR2) {
14437
+ self.monsterinfo.current_move = gekk_move_spit;
14438
+ }
14439
+ }
14440
+ }
14441
+ function gekk_jump_touch(self, other, plane, surf) {
14442
+ if (self.health <= 0) {
14443
+ self.touch = void 0;
14444
+ return;
14445
+ }
14446
+ self.touch = void 0;
14447
+ }
14448
+ function gekk_jump_takeoff(self, context) {
14449
+ const vectors = angleVectors(self.angles);
14450
+ const forward = vectors.forward;
14451
+ context.engine.sound?.(self, 0, "gek/gk_sght1.wav", 1, 1, 0);
14452
+ self.origin.z += 1;
14453
+ self.velocity = addVec3(scaleVec3(forward, 700), { x: 0, y: 0, z: 250 });
14454
+ self.groundentity = null;
14455
+ self.touch = gekk_jump_touch;
14456
+ }
14457
+ function gekk_check_landing(self, context) {
14458
+ if (self.groundentity) {
14459
+ context.engine.sound?.(self, 0, "mutant/thud1.wav", 1, 1, 0);
14460
+ self.velocity = ZERO_VEC3;
14461
+ return;
14462
+ }
14463
+ }
14464
+ function gekk_stop_skid(self) {
14465
+ if (self.groundentity) self.velocity = ZERO_VEC3;
14466
+ }
14467
+ function gekk_preattack(self, context) {
14468
+ }
14469
+ function gekk_dead(self) {
14470
+ self.mins = { x: -16, y: -16, z: -24 };
14471
+ self.maxs = { x: 16, y: 16, z: -8 };
14472
+ self.nextthink = -1;
14473
+ }
14474
+ function gekk_gibfest(self, context) {
14475
+ throwGibs(context, self.origin, 20);
14476
+ self.deadflag = 2 /* Dead */;
14477
+ }
14478
+ function isgibfest(self, context) {
14479
+ if (frandom2() > 0.9) gekk_gibfest(self, context);
14480
+ }
14481
+ function gekk_shrink(self) {
14482
+ self.maxs.z = 0;
14483
+ }
14484
+ function land_to_water(self) {
14485
+ self.flags |= 2 /* Swim */;
14486
+ self.yaw_speed = 10;
14487
+ self.viewheight = 10;
14488
+ self.monsterinfo.current_move = gekk_move_swim_start;
14489
+ self.mins = { x: -18, y: -18, z: -24 };
14490
+ self.maxs = { x: 18, y: 18, z: 16 };
14491
+ }
14492
+ var frames_stand2 = Array(38).fill({ ai: monster_ai_stand22, dist: 0 });
14493
+ frames_stand2[38] = { ai: monster_ai_stand22, dist: 0, think: gekk_check_underwater };
14494
+ gekk_move_stand = {
14495
+ firstframe: 0,
14496
+ lastframe: 38,
14497
+ frames: frames_stand2,
14498
+ endfunc: null
14499
+ };
14500
+ var frames_standunderwater = Array(32).fill({ ai: monster_ai_stand22, dist: 14 });
14501
+ gekk_move_standunderwater = {
14502
+ firstframe: 39,
14503
+ lastframe: 70,
14504
+ frames: frames_standunderwater,
14505
+ endfunc: null
14506
+ };
14507
+ var frames_swim = Array(32).fill({ ai: monster_ai_run21, dist: 14 });
14508
+ gekk_move_swim_loop = {
14509
+ firstframe: 39,
14510
+ lastframe: 70,
14511
+ frames: frames_swim,
14512
+ endfunc: gekk_swim_loop_func
14513
+ };
14514
+ var frames_swim_start = Array(32).fill({ ai: monster_ai_run21, dist: 14 });
14515
+ frames_swim_start[8] = { ai: monster_ai_run21, dist: 18, think: gekk_hit_left };
14516
+ frames_swim_start[14] = { ai: monster_ai_run21, dist: 24, think: gekk_hit_right };
14517
+ frames_swim_start[20] = { ai: monster_ai_run21, dist: 22, think: gekk_bite };
14518
+ gekk_move_swim_start = {
14519
+ firstframe: 39,
14520
+ lastframe: 70,
14521
+ frames: frames_swim_start,
14522
+ endfunc: gekk_swim_loop_func
14523
+ };
14524
+ var frames_idle = Array(32).fill({ ai: monster_ai_stand22, dist: 0 });
14525
+ frames_idle[0] = { ai: monster_ai_stand22, dist: 0, think: gekk_search };
14526
+ frames_idle[31] = { ai: monster_ai_stand22, dist: 0, think: gekk_idle_loop };
14527
+ gekk_move_idle = {
14528
+ firstframe: 71,
14529
+ lastframe: 102,
14530
+ frames: frames_idle,
14531
+ endfunc: gekk_stand
14532
+ };
14533
+ var frames_idle2 = Array(32).fill({ ai: monster_ai_move21, dist: 0 });
14534
+ frames_idle2[0] = { ai: monster_ai_move21, dist: 0, think: gekk_search };
14535
+ frames_idle2[31] = { ai: monster_ai_move21, dist: 0, think: gekk_idle_loop };
14536
+ gekk_move_idle2 = {
14537
+ firstframe: 71,
14538
+ lastframe: 102,
14539
+ frames: frames_idle2,
14540
+ endfunc: (s) => M_SetAnimation2(s, gekk_move_stand)
14541
+ // or face
14542
+ };
14543
+ gekk_move_chant = {
14544
+ firstframe: 71,
14545
+ lastframe: 102,
14546
+ frames: frames_idle2,
14547
+ endfunc: gekk_chant
14548
+ };
14549
+ var frames_walk2 = [
14550
+ { ai: monster_ai_walk20, dist: 3.8, think: gekk_check_underwater },
14551
+ { ai: monster_ai_walk20, dist: 19.6 },
14552
+ { ai: monster_ai_walk20, dist: 25.5 },
14553
+ { ai: monster_ai_walk20, dist: 34.6, think: gekk_step },
14554
+ { ai: monster_ai_walk20, dist: 27.3 },
14555
+ { ai: monster_ai_walk20, dist: 28.4 }
14556
+ ];
14557
+ gekk_move_walk = {
14558
+ firstframe: 103,
14559
+ lastframe: 108,
14560
+ frames: frames_walk2,
14561
+ endfunc: null
14562
+ };
14563
+ var frames_run2 = [
14564
+ { ai: monster_ai_run21, dist: 3.8, think: gekk_check_underwater },
14565
+ { ai: monster_ai_run21, dist: 19.6 },
14566
+ { ai: monster_ai_run21, dist: 25.5 },
14567
+ { ai: monster_ai_run21, dist: 34.6, think: gekk_step },
14568
+ { ai: monster_ai_run21, dist: 27.3 },
14569
+ { ai: monster_ai_run21, dist: 28.4 }
14570
+ ];
14571
+ gekk_move_run = {
14572
+ firstframe: 103,
14573
+ lastframe: 108,
14574
+ frames: frames_run2,
14575
+ endfunc: null
14576
+ };
14577
+ var frames_run_st = [
14578
+ { ai: monster_ai_run21, dist: 0.2 },
14579
+ { ai: monster_ai_run21, dist: 19.7 }
14580
+ ];
14581
+ gekk_move_run_start = {
14582
+ firstframe: 0,
14583
+ lastframe: 1,
14584
+ // Frames 0 and 1 reuse stand start? C says FRAME_stand_01, FRAME_stand_02
14585
+ frames: frames_run_st,
14586
+ endfunc: gekk_run
14587
+ };
14588
+ var frames_spit = [
14589
+ { ai: monster_ai_charge22, dist: 0 },
14590
+ { ai: monster_ai_charge22, dist: 0 },
14591
+ { ai: monster_ai_charge22, dist: 0 },
14592
+ { ai: monster_ai_charge22, dist: 0 },
14593
+ { ai: monster_ai_charge22, dist: 0 },
14594
+ { ai: monster_ai_charge22, dist: 0, think: loogie_fire },
14595
+ { ai: monster_ai_charge22, dist: 0, think: reloogie }
14596
+ ];
14597
+ gekk_move_spit = {
14598
+ firstframe: 133,
14599
+ // FRAME_spit_01
14600
+ lastframe: 139,
14601
+ frames: frames_spit,
14602
+ endfunc: gekk_run_start
14603
+ };
14604
+ var frames_attack1 = [
14605
+ { ai: monster_ai_charge22, dist: 0 },
14606
+ { ai: monster_ai_charge22, dist: 0 },
14607
+ { ai: monster_ai_charge22, dist: 0 },
14608
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_left },
14609
+ { ai: monster_ai_charge22, dist: 0 },
14610
+ { ai: monster_ai_charge22, dist: 0 },
14611
+ { ai: monster_ai_charge22, dist: 0 },
14612
+ { ai: monster_ai_charge22, dist: 0 },
14613
+ { ai: monster_ai_charge22, dist: 0, think: gekk_check_refire }
14614
+ ];
14615
+ gekk_move_attack1 = {
14616
+ firstframe: 109,
14617
+ lastframe: 117,
14618
+ frames: frames_attack1,
14619
+ endfunc: gekk_run_start
14620
+ };
14621
+ var frames_attack2 = [
14622
+ { ai: monster_ai_charge22, dist: 0 },
14623
+ { ai: monster_ai_charge22, dist: 0 },
14624
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_left },
14625
+ { ai: monster_ai_charge22, dist: 0 },
14626
+ { ai: monster_ai_charge22, dist: 0 },
14627
+ { ai: monster_ai_charge22, dist: 0, think: gekk_hit_right },
14628
+ { ai: monster_ai_charge22, dist: 0 },
14629
+ { ai: monster_ai_charge22, dist: 0 },
14630
+ { ai: monster_ai_charge22, dist: 0, think: gekk_check_refire }
14631
+ ];
14632
+ gekk_move_attack2 = {
14633
+ firstframe: 118,
14634
+ lastframe: 126,
14635
+ frames: frames_attack2,
14636
+ endfunc: gekk_run_start
14637
+ };
14638
+ var frames_leapatk = [
14639
+ { ai: monster_ai_charge22, dist: 0 },
14640
+ { ai: monster_ai_charge22, dist: -0.3 },
14641
+ { ai: monster_ai_charge22, dist: -1.1 },
14642
+ { ai: monster_ai_charge22, dist: -0.2 },
14643
+ { ai: monster_ai_charge22, dist: 6.7, think: gekk_jump_takeoff },
14644
+ { ai: monster_ai_charge22, dist: 6.4 },
14645
+ { ai: monster_ai_charge22, dist: 0.1 },
14646
+ { ai: monster_ai_charge22, dist: 28.3 },
14647
+ { ai: monster_ai_charge22, dist: 24.1 },
14648
+ { ai: monster_ai_charge22, dist: 31.7 },
14649
+ { ai: monster_ai_charge22, dist: 35.9, think: gekk_check_landing },
14650
+ { ai: monster_ai_charge22, dist: 12.3, think: gekk_stop_skid },
14651
+ { ai: monster_ai_charge22, dist: 20.1, think: gekk_stop_skid },
14652
+ { ai: monster_ai_charge22, dist: -1, think: gekk_stop_skid },
14653
+ { ai: monster_ai_charge22, dist: 2.5, think: gekk_stop_skid },
14654
+ { ai: monster_ai_charge22, dist: 0.5, think: gekk_stop_skid },
14655
+ { ai: monster_ai_charge22, dist: 1.8, think: gekk_stop_skid },
14656
+ { ai: monster_ai_charge22, dist: 1.2, think: gekk_stop_skid },
14657
+ { ai: monster_ai_charge22, dist: -0.4, think: gekk_check_underwater }
14658
+ ];
14659
+ gekk_move_leapatk = {
14660
+ firstframe: 140,
14661
+ lastframe: 158,
14662
+ frames: frames_leapatk,
14663
+ endfunc: gekk_run_start
14664
+ };
14665
+ gekk_move_leapatk2 = {
14666
+ firstframe: 140,
14667
+ lastframe: 158,
14668
+ frames: frames_leapatk,
14669
+ // reusing frames
14670
+ endfunc: gekk_run_start
14671
+ };
14672
+ var frames_attack3 = Array(21).fill({ ai: monster_ai_charge22, dist: 16 });
14673
+ frames_attack3[0] = { ai: monster_ai_charge22, dist: 16, think: gekk_preattack };
14674
+ frames_attack3[4] = { ai: monster_ai_charge22, dist: 16, think: gekk_bite };
14675
+ frames_attack3[9] = { ai: monster_ai_charge22, dist: 16, think: gekk_bite };
14676
+ frames_attack3[13] = { ai: monster_ai_charge22, dist: 16, think: gekk_hit_left };
14677
+ frames_attack3[18] = { ai: monster_ai_charge22, dist: 16, think: gekk_hit_right };
14678
+ gekk_move_attack = {
14679
+ firstframe: 159,
14680
+ lastframe: 179,
14681
+ frames: frames_attack3,
14682
+ endfunc: gekk_run_start
14683
+ };
14684
+ var frames_pain = Array(6).fill({ ai: monster_ai_move21, dist: 0 });
14685
+ gekk_move_pain = {
14686
+ firstframe: 180,
14687
+ lastframe: 185,
14688
+ frames: frames_pain,
14689
+ endfunc: gekk_run_start
14690
+ };
14691
+ var frames_pain12 = Array(11).fill({ ai: monster_ai_move21, dist: 0 });
14692
+ frames_pain12[10] = { ai: monster_ai_move21, dist: 0, think: gekk_check_underwater };
14693
+ gekk_move_pain1 = {
14694
+ firstframe: 186,
14695
+ lastframe: 196,
14696
+ frames: frames_pain12,
14697
+ endfunc: gekk_run_start
14698
+ };
14699
+ var frames_pain22 = Array(13).fill({ ai: monster_ai_move21, dist: 0 });
14700
+ frames_pain22[12] = { ai: monster_ai_move21, dist: 0, think: gekk_check_underwater };
14701
+ gekk_move_pain2 = {
14702
+ firstframe: 197,
14703
+ lastframe: 209,
14704
+ frames: frames_pain22,
14705
+ endfunc: gekk_run_start
14706
+ };
14707
+ function gekk_pain(self, other, kick, damage, context) {
14708
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14709
+ self.spawnflags &= ~SPAWNFLAG_GEKK_CHANT;
14710
+ return;
14711
+ }
14712
+ context.engine.sound?.(self, 0, "gek/gk_pain1.wav", 1, 1, 0);
14713
+ if (self.waterlevel >= WATER_WAIST) {
14714
+ if (!(self.flags & 2 /* Swim */)) {
14715
+ self.flags |= 2 /* Swim */;
14716
+ }
14717
+ self.monsterinfo.current_move = gekk_move_pain;
14718
+ } else {
14719
+ if (random8() > 0.5) self.monsterinfo.current_move = gekk_move_pain1;
14720
+ else self.monsterinfo.current_move = gekk_move_pain2;
14721
+ }
14722
+ }
14723
+ var frames_death12 = Array(10).fill({ ai: monster_ai_move21, dist: 0 });
14724
+ frames_death12[5] = { ai: monster_ai_move21, dist: -7, think: gekk_shrink };
14725
+ gekk_move_death1 = {
14726
+ firstframe: 210,
14727
+ lastframe: 219,
14728
+ frames: frames_death12,
14729
+ endfunc: gekk_dead
14730
+ };
14731
+ var frames_death3 = Array(7).fill({ ai: monster_ai_move21, dist: 0 });
14732
+ frames_death3[5] = { ai: monster_ai_move21, dist: -7, think: isgibfest };
14733
+ gekk_move_death3 = {
14734
+ firstframe: 220,
14735
+ lastframe: 226,
14736
+ frames: frames_death3,
14737
+ endfunc: gekk_dead
14738
+ };
14739
+ var frames_death4 = Array(35).fill({ ai: monster_ai_move21, dist: 0 });
14740
+ frames_death4[34] = { ai: monster_ai_move21, dist: 0, think: gekk_gibfest };
14741
+ gekk_move_death4 = {
14742
+ firstframe: 227,
14743
+ lastframe: 261,
14744
+ frames: frames_death4,
14745
+ endfunc: gekk_dead
14746
+ };
14747
+ var frames_wdeath = Array(45).fill({ ai: monster_ai_move21, dist: 0 });
14748
+ gekk_move_wdeath = {
14749
+ firstframe: 262,
14750
+ lastframe: 306,
14751
+ frames: frames_wdeath,
14752
+ endfunc: gekk_dead
14753
+ };
14754
+ function gekk_die(self, inflictor, attacker, damage, point, mod, context) {
14755
+ if (self.health <= GIB_HEALTH) {
14756
+ throwGibs(context, self.origin, damage);
14757
+ return;
14758
+ }
14759
+ if (self.deadflag === 2 /* Dead */) return;
14760
+ context.engine.sound?.(self, 0, "gek/gk_deth1.wav", 1, 1, 0);
14761
+ self.deadflag = 2 /* Dead */;
14762
+ self.takedamage = true;
14763
+ if (self.waterlevel >= WATER_WAIST) {
14764
+ gekk_shrink(self);
14765
+ self.monsterinfo.current_move = gekk_move_wdeath;
14766
+ } else {
14767
+ const r = frandom2();
14768
+ if (r > 0.66) self.monsterinfo.current_move = gekk_move_death1;
14769
+ else if (r > 0.33) self.monsterinfo.current_move = gekk_move_death3;
14770
+ else self.monsterinfo.current_move = gekk_move_death4;
14771
+ }
14772
+ }
14773
+ function SP_monster_gekk(self, context) {
14774
+ self.classname = "monster_gekk";
14775
+ self.model = "models/monsters/gekk/tris.md2";
14776
+ self.movetype = 5 /* Step */;
14777
+ self.solid = 2 /* BoundingBox */;
14778
+ self.mins = { x: -18, y: -18, z: -24 };
14779
+ self.maxs = { x: 18, y: 18, z: 24 };
14780
+ self.health = 125;
14781
+ self.max_health = 125;
14782
+ self.mass = 300;
14783
+ self.pain = (e, o, k, d) => gekk_pain(e, o, k, d, context.entities);
14784
+ self.die = (e, i, a, d, p, m3) => gekk_die(e, i, a, d, p, m3, context.entities);
14785
+ self.monsterinfo.stand = gekk_stand;
14786
+ self.monsterinfo.walk = (s) => M_SetAnimation2(s, gekk_move_walk);
14787
+ self.monsterinfo.run = gekk_run_start;
14788
+ self.monsterinfo.attack = (s) => gekk_attack(s, context.entities);
14789
+ self.monsterinfo.melee = gekk_melee;
14790
+ self.monsterinfo.sight = (s, o) => context.entities.sound?.(s, 0, "gek/gk_sght1.wav", 1, 1, 0);
14791
+ self.monsterinfo.search = (s) => gekk_search(s, context.entities);
14792
+ self.monsterinfo.idle = (s) => {
14793
+ if (s.spawnflags & SPAWNFLAG_GEKK_NOSWIM || s.waterlevel < WATER_WAIST) {
14794
+ M_SetAnimation2(s, gekk_move_idle);
14795
+ } else {
14796
+ M_SetAnimation2(s, gekk_move_swim_start);
14797
+ }
14798
+ };
14799
+ self.monsterinfo.checkattack = (s) => gekk_checkattack(s, context.entities);
14800
+ context.entities.linkentity(self);
14801
+ M_SetAnimation2(self, gekk_move_stand);
14802
+ self.think = monster_think;
14803
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK24;
14804
+ if (self.spawnflags & SPAWNFLAG_GEKK_CHANT) {
14805
+ M_SetAnimation2(self, gekk_move_chant);
14806
+ }
14807
+ }
14808
+ function M_SetAnimation2(self, move) {
14809
+ self.monsterinfo.current_move = move;
14810
+ }
14811
+ function gekk_attack(self, context) {
14812
+ if (!self.enemy) return;
14813
+ const r = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
14814
+ if (self.flags & 2 /* Swim */) {
14815
+ if (self.enemy && self.enemy.waterlevel >= WATER_WAIST && r <= RANGE_NEAR2)
14816
+ return;
14817
+ self.flags &= ~2 /* Swim */;
14818
+ M_SetAnimation2(self, gekk_move_leapatk);
14819
+ self.frame = 144;
14820
+ } else {
14821
+ if (r >= RANGE_MID2) {
14822
+ if (frandom2() > 0.5) {
14823
+ M_SetAnimation2(self, gekk_move_spit);
14824
+ } else {
14825
+ M_SetAnimation2(self, gekk_move_run_start);
14826
+ }
14827
+ } else if (frandom2() > 0.7) {
14828
+ M_SetAnimation2(self, gekk_move_spit);
14829
+ } else {
14830
+ if (self.spawnflags & SPAWNFLAG_GEKK_NOJUMPING || frandom2() > 0.7) {
14831
+ M_SetAnimation2(self, gekk_move_run_start);
14832
+ } else {
14833
+ M_SetAnimation2(self, gekk_move_leapatk);
14834
+ }
14835
+ }
14836
+ }
14837
+ }
14838
+ function gekk_melee(self) {
14839
+ if (self.waterlevel >= WATER_WAIST) {
14840
+ M_SetAnimation2(self, gekk_move_attack);
14841
+ } else {
14842
+ if (frandom2() > 0.66) M_SetAnimation2(self, gekk_move_attack1);
14843
+ else M_SetAnimation2(self, gekk_move_attack2);
14844
+ }
14845
+ }
14846
+ function registerGekkSpawns(registry) {
14847
+ registry.register("monster_gekk", SP_monster_gekk);
14848
+ }
14849
+
14850
+ // src/entities/monsters/fixbot.ts
14851
+ var MONSTER_TICK25 = 0.1;
14852
+ var random9 = () => Math.random();
14853
+ var frandom3 = () => Math.random();
14854
+ function monster_ai_walk21(self, dist, context) {
14855
+ ai_walk(self, dist, MONSTER_TICK25, context);
14856
+ }
14857
+ function monster_ai_run22(self, dist, context) {
14858
+ ai_run(self, dist, MONSTER_TICK25, context);
14859
+ }
14860
+ function monster_ai_charge23(self, dist, context) {
14861
+ ai_charge(self, dist, MONSTER_TICK25, context);
14862
+ }
14863
+ function monster_ai_move22(self, dist, context) {
14864
+ ai_move(self, dist);
14865
+ }
14866
+ var fixbot_move_stand;
14867
+ var fixbot_move_walk;
14868
+ var fixbot_move_run;
14869
+ var fixbot_move_attack2;
14870
+ var fixbot_move_laserattack;
14871
+ var fixbot_move_weld_start;
14872
+ var fixbot_move_weld;
14873
+ var fixbot_move_weld_end;
14874
+ var fixbot_move_start_attack;
14875
+ var fixbot_move_pain3;
14876
+ var fixbot_move_painb;
14877
+ var fixbot_move_paina;
14878
+ var MZ2_HOVER_BLASTER_1 = 1;
14879
+ function fixbot_set_fly_parameters(self, heal, weld) {
14880
+ if (heal) {
14881
+ } else if (weld) {
14882
+ } else {
14883
+ }
14884
+ }
14885
+ function fixbot_FindDeadMonster(self, context) {
14886
+ const radius = 1024;
14887
+ const candidates = context.findByRadius(self.origin, radius);
14888
+ let best = null;
14889
+ for (const ent of candidates) {
14890
+ if (ent === self) continue;
14891
+ if (!ent.monsterinfo) continue;
14892
+ if (ent.monsterinfo.aiflags & 256 /* GoodGuy */) continue;
14893
+ if (ent.health > 0) continue;
14894
+ if (ent.nextthink && ent.think === context.free) continue;
14895
+ if (ent.health <= -40) continue;
14896
+ if (!visible(self, ent, context.trace)) continue;
14897
+ if (!best) {
14898
+ best = ent;
14899
+ continue;
14900
+ }
14901
+ if (ent.max_health <= best.max_health) continue;
14902
+ best = ent;
14903
+ }
14904
+ return best;
14905
+ }
14906
+ function fixbot_search(self, context) {
14907
+ if (self.enemy) return;
14908
+ const ent = fixbot_FindDeadMonster(self, context);
14909
+ if (ent) {
14910
+ self.enemy = ent;
14911
+ self.monsterinfo.aiflags |= 8192 /* Medic */;
14912
+ fixbot_run(self);
14913
+ fixbot_set_fly_parameters(self, true, false);
14914
+ } else {
14915
+ if (random9() < 0.1) {
14916
+ context.engine.sound?.(self, 0, "flyer/flysght1.wav", 1, 1, 0);
14917
+ }
14918
+ }
14919
+ }
14920
+ function fixbot_die(self, inflictor, attacker, damage, point, mod, context) {
14921
+ context.engine.sound?.(self, 0, "flyer/flydeth1.wav", 1, 1, 0);
14922
+ throwGibs(context, self.origin, damage);
14923
+ self.deadflag = 2 /* Dead */;
14924
+ self.takedamage = false;
14925
+ context.free(self);
14926
+ }
14927
+ function fixbot_fire_blaster_func(self, context) {
14928
+ if (!self.enemy || !self.enemy.inUse) {
14929
+ self.monsterinfo.current_move = fixbot_move_run;
14930
+ return;
14931
+ }
14932
+ const vectors = angleVectors(self.angles);
14933
+ const start = addVec3(self.origin, addVec3(scaleVec3(vectors.forward, 0), addVec3(scaleVec3(vectors.right, 0), scaleVec3(vectors.up, 0))));
14934
+ const end = copyVec3(self.enemy.origin);
14935
+ end.z += self.enemy.viewheight || 0;
14936
+ const dir = normalizeVec3(subtractVec3(end, start));
14937
+ monster_fire_blaster(self, start, dir, 15, 1e3, MZ2_HOVER_BLASTER_1, 0, context);
14938
+ }
14939
+ function fixbot_fire_laser(self, context) {
14940
+ if (!self.enemy || !self.enemy.inUse || self.enemy.health <= -40) {
14941
+ self.monsterinfo.current_move = fixbot_move_stand;
14942
+ self.monsterinfo.aiflags &= ~8192 /* Medic */;
14943
+ return;
14944
+ }
14945
+ if (self.enemy.health < self.enemy.max_health) {
14946
+ self.enemy.health += 5;
14947
+ if (self.enemy.health > self.enemy.max_health) self.enemy.health = self.enemy.max_health;
14948
+ } else {
14949
+ if (self.enemy.deadflag === 2 /* Dead */) {
14950
+ self.enemy.deadflag = 0 /* Alive */;
14951
+ self.enemy.solid = 2 /* BoundingBox */;
14952
+ self.enemy.takedamage = true;
14953
+ self.enemy.health = self.enemy.max_health;
14954
+ self.enemy.monsterinfo.aiflags &= ~128 /* HoldFrame */;
14955
+ }
14956
+ self.monsterinfo.current_move = fixbot_move_stand;
14957
+ self.monsterinfo.aiflags &= ~8192 /* Medic */;
14958
+ self.enemy = null;
14959
+ }
14960
+ }
14961
+ function fixbot_fire_welder(self, context) {
14962
+ if (frandom3() > 0.8) {
14963
+ const r = frandom3();
14964
+ if (r < 0.33) context.engine.sound?.(self, 0, "misc/welder1.wav", 1, 1, 0);
14965
+ else if (r < 0.66) context.engine.sound?.(self, 0, "misc/welder2.wav", 1, 1, 0);
14966
+ else context.engine.sound?.(self, 0, "misc/welder3.wav", 1, 1, 0);
14967
+ }
14968
+ }
14969
+ function fixbot_pain(self, other, kick, damage, context) {
14970
+ if (self.timestamp < (self.pain_debounce_time || 0)) return;
14971
+ self.pain_debounce_time = self.timestamp + 3;
14972
+ context.engine.sound?.(self, 0, "flyer/flypain1.wav", 1, 1, 0);
14973
+ if (damage <= 10) self.monsterinfo.current_move = fixbot_move_pain3;
14974
+ else if (damage <= 25) self.monsterinfo.current_move = fixbot_move_painb;
14975
+ else self.monsterinfo.current_move = fixbot_move_paina;
14976
+ }
14977
+ function fixbot_stand(self) {
14978
+ self.monsterinfo.current_move = fixbot_move_stand;
14979
+ }
14980
+ function fixbot_walk(self) {
14981
+ self.monsterinfo.current_move = fixbot_move_walk;
14982
+ }
14983
+ function fixbot_run(self) {
14984
+ if (self.monsterinfo.aiflags & 1 /* StandGround */)
14985
+ self.monsterinfo.current_move = fixbot_move_stand;
14986
+ else
14987
+ self.monsterinfo.current_move = fixbot_move_run;
14988
+ }
14989
+ function fixbot_start_attack(self) {
14990
+ self.monsterinfo.current_move = fixbot_move_start_attack;
14991
+ }
14992
+ function fixbot_attack(self) {
14993
+ if (self.monsterinfo.aiflags & 8192 /* Medic */) {
14994
+ self.monsterinfo.current_move = fixbot_move_laserattack;
14995
+ } else {
14996
+ self.monsterinfo.current_move = fixbot_move_attack2;
14997
+ }
14998
+ }
14999
+ function weldstate(self) {
15000
+ if (self.goalentity && self.goalentity.health > 0) {
15001
+ } else {
15002
+ self.monsterinfo.current_move = fixbot_move_stand;
15003
+ }
15004
+ }
15005
+ var frames_stand3 = Array(19).fill({ ai: monster_ai_move22, dist: 0 });
15006
+ frames_stand3[18] = { ai: monster_ai_move22, dist: 0, think: fixbot_search };
15007
+ fixbot_move_stand = {
15008
+ firstframe: 58,
15009
+ // FRAME_ambient_01
15010
+ lastframe: 76,
15011
+ frames: frames_stand3,
15012
+ endfunc: null
15013
+ };
15014
+ var frames_walk3 = [
15015
+ { ai: monster_ai_walk21, dist: 5 }
15016
+ ];
15017
+ fixbot_move_walk = {
15018
+ firstframe: 0,
15019
+ lastframe: 0,
15020
+ frames: frames_walk3,
15021
+ endfunc: null
15022
+ };
15023
+ var frames_run3 = [
15024
+ { ai: monster_ai_run22, dist: 10 }
15025
+ ];
15026
+ fixbot_move_run = {
15027
+ firstframe: 0,
15028
+ lastframe: 0,
15029
+ frames: frames_run3,
15030
+ endfunc: null
15031
+ };
15032
+ var frames_attack22 = Array(31).fill({ ai: monster_ai_charge23, dist: 0 });
15033
+ frames_attack22[20] = { ai: monster_ai_charge23, dist: 0, think: fixbot_fire_blaster_func };
15034
+ fixbot_move_attack2 = {
15035
+ firstframe: 121,
15036
+ // FRAME_charging_01
15037
+ lastframe: 151,
15038
+ frames: frames_attack22,
15039
+ endfunc: fixbot_run
15040
+ };
15041
+ var frames_laserattack = Array(6).fill({ ai: monster_ai_charge23, dist: 0, think: fixbot_fire_laser });
15042
+ fixbot_move_laserattack = {
15043
+ firstframe: 115,
15044
+ // FRAME_shoot_01
15045
+ lastframe: 120,
15046
+ frames: frames_laserattack,
15047
+ endfunc: null
15048
+ // Loops or handled by AI?
15049
+ };
15050
+ var frames_weld_start = Array(10).fill({ ai: monster_ai_move22, dist: 0 });
15051
+ frames_weld_start[9] = { ai: monster_ai_move22, dist: 0, think: weldstate };
15052
+ fixbot_move_weld_start = {
15053
+ firstframe: 77,
15054
+ // FRAME_weldstart_01
15055
+ lastframe: 86,
15056
+ frames: frames_weld_start,
15057
+ endfunc: null
15058
+ };
15059
+ var frames_weld = Array(7).fill({ ai: monster_ai_move22, dist: 0, think: fixbot_fire_welder });
15060
+ frames_weld[6] = { ai: monster_ai_move22, dist: 0, think: weldstate };
15061
+ fixbot_move_weld = {
15062
+ firstframe: 87,
15063
+ // FRAME_weldmiddle_01
15064
+ lastframe: 93,
15065
+ frames: frames_weld,
15066
+ endfunc: null
15067
+ };
15068
+ var frames_weld_end = Array(7).fill({ ai: monster_ai_move22, dist: -2 });
15069
+ frames_weld_end[6] = { ai: monster_ai_move22, dist: -2, think: weldstate };
15070
+ fixbot_move_weld_end = {
15071
+ firstframe: 94,
15072
+ // FRAME_weldend_01
15073
+ lastframe: 100,
15074
+ frames: frames_weld_end,
15075
+ endfunc: null
15076
+ };
15077
+ var frames_start_attack = [
15078
+ { ai: monster_ai_charge23, dist: 0 }
15079
+ ];
15080
+ fixbot_move_start_attack = {
15081
+ firstframe: 0,
15082
+ lastframe: 0,
15083
+ frames: frames_start_attack,
15084
+ endfunc: fixbot_attack
15085
+ };
15086
+ var frames_pain32 = [
15087
+ { ai: monster_ai_move22, dist: -1 }
15088
+ ];
15089
+ fixbot_move_pain3 = {
15090
+ firstframe: 0,
15091
+ lastframe: 0,
15092
+ frames: frames_pain32,
15093
+ endfunc: fixbot_run
15094
+ };
15095
+ var frames_painb = Array(8).fill({ ai: monster_ai_move22, dist: 0 });
15096
+ fixbot_move_painb = {
15097
+ firstframe: 107,
15098
+ // FRAME_painb_01
15099
+ lastframe: 114,
15100
+ frames: frames_painb,
15101
+ endfunc: fixbot_run
15102
+ };
15103
+ var frames_paina = Array(6).fill({ ai: monster_ai_move22, dist: 0 });
15104
+ fixbot_move_paina = {
15105
+ firstframe: 101,
15106
+ // FRAME_paina_01
15107
+ lastframe: 106,
15108
+ frames: frames_paina,
15109
+ endfunc: fixbot_run
15110
+ };
15111
+ function SP_monster_fixbot(self, context) {
15112
+ self.classname = "monster_fixbot";
15113
+ self.model = "models/monsters/fixbot/tris.md2";
15114
+ self.mins = { x: -32, y: -32, z: -24 };
15115
+ self.maxs = { x: 32, y: 32, z: 24 };
15116
+ self.movetype = 5 /* Step */;
15117
+ self.solid = 2 /* BoundingBox */;
15118
+ self.health = 150;
15119
+ self.mass = 150;
15120
+ self.pain = (e, o, k, d) => fixbot_pain(e, o, k, d, context.entities);
15121
+ self.die = (e, i, a, d, p, m3) => fixbot_die(e, i, a, d, p, m3, context.entities);
15122
+ self.monsterinfo.stand = fixbot_stand;
15123
+ self.monsterinfo.walk = fixbot_walk;
15124
+ self.monsterinfo.run = fixbot_run;
15125
+ self.monsterinfo.attack = fixbot_start_attack;
15126
+ context.entities.linkentity(self);
15127
+ self.monsterinfo.current_move = fixbot_move_stand;
15128
+ self.think = monster_think;
15129
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK25;
15130
+ self.flags |= 1 /* Fly */;
15131
+ }
15132
+ function registerFixbotSpawns(registry) {
15133
+ registry.register("monster_fixbot", SP_monster_fixbot);
15134
+ }
15135
+
14192
15136
  // src/entities/monsters/index.ts
14193
15137
  function registerMonsterSpawns2(registry) {
14194
15138
  registerMonsterSpawns(registry);
@@ -14215,6 +15159,8 @@ function registerMonsterSpawns2(registry) {
14215
15159
  registerMakronSpawns(registry);
14216
15160
  registerInsaneSpawns(registry);
14217
15161
  registerActorSpawns(registry);
15162
+ registerGekkSpawns(registry);
15163
+ registerFixbotSpawns(registry);
14218
15164
  }
14219
15165
 
14220
15166
  // src/entities/worldspawn.ts
@@ -15525,7 +16471,7 @@ function PlayerNoise(who, where, type, context) {
15525
16471
  }
15526
16472
 
15527
16473
  // src/combat/obituary.ts
15528
- var random8 = createRandomGenerator();
16474
+ var random10 = createRandomGenerator();
15529
16475
  var PRINT_MEDIUM = 1;
15530
16476
  function getGender(ent) {
15531
16477
  return "male";
@@ -15688,7 +16634,7 @@ var ANIM_PAIN = 2;
15688
16634
  var ANIM_DEATH = 3;
15689
16635
 
15690
16636
  // src/combat/weapons/firing.ts
15691
- var random9 = createRandomGenerator();
16637
+ var random11 = createRandomGenerator();
15692
16638
 
15693
16639
  // src/entities/player.ts
15694
16640
  function P_PlayerThink(ent, sys) {
@@ -15745,7 +16691,7 @@ function player_pain(self, damage) {
15745
16691
  return;
15746
16692
  }
15747
16693
  self.client.anim_priority = ANIM_PAIN;
15748
- const r = random9.frandom();
16694
+ const r = random11.frandom();
15749
16695
  if (r < 0.33) {
15750
16696
  self.frame = FRAME_pain1012;
15751
16697
  self.client.anim_end = FRAME_pain104;
@@ -15768,7 +16714,7 @@ function player_die(self, inflictor, attacker, damage, point, mod, sys) {
15768
16714
  }
15769
16715
  if (self.client) {
15770
16716
  self.client.anim_priority = ANIM_DEATH;
15771
- const r = random9.frandom();
16717
+ const r = random11.frandom();
15772
16718
  if (r < 0.33) {
15773
16719
  self.frame = FRAME_death1012;
15774
16720
  self.client.anim_end = FRAME_death106;
@@ -15821,25 +16767,12 @@ function player_think(self, sys) {
15821
16767
  }
15822
16768
 
15823
16769
  // src/entities/playerStats.ts
15824
- var WEAPON_WHEEL_ORDER = [
15825
- "blaster" /* Blaster */,
15826
- "shotgun" /* Shotgun */,
15827
- "supershotgun" /* SuperShotgun */,
15828
- "machinegun" /* Machinegun */,
15829
- "chaingun" /* Chaingun */,
15830
- "grenadelauncher" /* GrenadeLauncher */,
15831
- "rocketlauncher" /* RocketLauncher */,
15832
- "grenades" /* HandGrenade */,
15833
- "hyperblaster" /* HyperBlaster */,
15834
- "railgun" /* Railgun */,
15835
- "bfg10k" /* BFG10K */
15836
- ];
15837
16770
  var POWERUP_TIMERS = [
15838
- { id: "quad" /* QuadDamage */, priority: 1 },
15839
- { id: "invulnerability" /* Invulnerability */, priority: 2 },
15840
- { id: "enviro" /* EnviroSuit */, priority: 3 },
15841
- { id: "rebreather" /* Rebreather */, priority: 4 },
15842
- { id: "silencer" /* Silencer */, priority: 5 }
16771
+ { id: PowerupId.QuadDamage, priority: 1 },
16772
+ { id: PowerupId.Invulnerability, priority: 2 },
16773
+ { id: PowerupId.EnviroSuit, priority: 3 },
16774
+ { id: PowerupId.Rebreather, priority: 4 },
16775
+ { id: PowerupId.Silencer, priority: 5 }
15843
16776
  ];
15844
16777
  function populatePlayerStats(player, timeSeconds) {
15845
16778
  if (!player.client) return [];
@@ -15858,6 +16791,12 @@ function populatePlayerStats(player, timeSeconds) {
15858
16791
  }
15859
16792
  statArray[PlayerStat.STAT_WEAPONS_OWNED_1] = weaponBits & 65535;
15860
16793
  statArray[PlayerStat.STAT_WEAPONS_OWNED_2] = weaponBits >> 16 & 65535;
16794
+ if (inventory.currentWeapon) {
16795
+ const index = WEAPON_WHEEL_ORDER.indexOf(inventory.currentWeapon);
16796
+ if (index !== -1) {
16797
+ statArray[PlayerStat.STAT_ACTIVE_WHEEL_WEAPON] = index;
16798
+ }
16799
+ }
15861
16800
  statArray[PlayerStat.STAT_AMMO] = 0;
15862
16801
  if (inventory.currentWeapon) {
15863
16802
  const weaponItem = Object.values(WEAPON_ITEMS).find((item) => item.weaponId === inventory.currentWeapon);
@@ -16162,7 +17101,7 @@ var WEAPONS = {
16162
17101
  };
16163
17102
 
16164
17103
  // src/index.ts
16165
- var ZERO_VEC36 = { x: 0, y: 0, z: 0 };
17104
+ var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
16166
17105
  function createGame(imports, engine, options) {
16167
17106
  const gravity = options.gravity;
16168
17107
  const deathmatch = options.deathmatch ?? false;
@@ -16231,26 +17170,26 @@ function createGame(imports, engine, options) {
16231
17170
  };
16232
17171
  entities.runFrame();
16233
17172
  });
16234
- let origin = { ...ZERO_VEC36 };
16235
- let velocity = { ...ZERO_VEC36 };
17173
+ let origin = { ...ZERO_VEC37 };
17174
+ let velocity = { ...ZERO_VEC37 };
16236
17175
  const calculateBlend = (player, time) => {
16237
17176
  const blend = [0, 0, 0, 0];
16238
17177
  if (!player || !player.client) return blend;
16239
17178
  const inventory = player.client.inventory;
16240
- if (inventory.powerups.has("quad" /* QuadDamage */)) {
17179
+ if (inventory.powerups.has(PowerupId.QuadDamage)) {
16241
17180
  blend[2] = 1;
16242
17181
  blend[3] = 0.08;
16243
17182
  }
16244
- if (inventory.powerups.has("invulnerability" /* Invulnerability */)) {
17183
+ if (inventory.powerups.has(PowerupId.Invulnerability)) {
16245
17184
  blend[0] = 1;
16246
17185
  blend[1] = 1;
16247
17186
  blend[3] = 0.08;
16248
17187
  }
16249
- if (inventory.powerups.has("enviro" /* EnviroSuit */)) {
17188
+ if (inventory.powerups.has(PowerupId.EnviroSuit)) {
16250
17189
  blend[1] = 1;
16251
17190
  blend[3] = 0.08;
16252
17191
  }
16253
- if (inventory.powerups.has("rebreather" /* Rebreather */)) {
17192
+ if (inventory.powerups.has(PowerupId.Rebreather)) {
16254
17193
  blend[0] = 0.4;
16255
17194
  blend[1] = 1;
16256
17195
  blend[2] = 0.4;
@@ -16314,10 +17253,10 @@ function createGame(imports, engine, options) {
16314
17253
  // TODO
16315
17254
  damageIndicators: [],
16316
17255
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
16317
- kick_angles: player?.client?.kick_angles ?? ZERO_VEC36,
16318
- kick_origin: player?.client?.kick_origin ?? ZERO_VEC36,
16319
- gunoffset: ZERO_VEC36,
16320
- gunangles: ZERO_VEC36,
17256
+ kick_angles: player?.client?.kick_angles ?? ZERO_VEC37,
17257
+ kick_origin: player?.client?.kick_origin ?? ZERO_VEC37,
17258
+ gunoffset: ZERO_VEC37,
17259
+ gunangles: ZERO_VEC37,
16321
17260
  gunindex: 0,
16322
17261
  gun_frame: player?.client?.gun_frame ?? 0,
16323
17262
  rdflags: player?.client?.rdflags ?? 0,
@@ -16331,8 +17270,8 @@ function createGame(imports, engine, options) {
16331
17270
  const resetState = (startTimeMs) => {
16332
17271
  frameLoop.reset(startTimeMs);
16333
17272
  levelClock.start(startTimeMs);
16334
- origin = { ...ZERO_VEC36 };
16335
- velocity = { ...ZERO_VEC36 };
17273
+ origin = { ...ZERO_VEC37 };
17274
+ velocity = { ...ZERO_VEC37 };
16336
17275
  entities.beginFrame(startTimeMs / 1e3);
16337
17276
  entities.runFrame();
16338
17277
  };
@@ -16360,10 +17299,10 @@ function createGame(imports, engine, options) {
16360
17299
  blend: [0, 0, 0, 0],
16361
17300
  // Stubs
16362
17301
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
16363
- kick_angles: ZERO_VEC36,
16364
- kick_origin: ZERO_VEC36,
16365
- gunoffset: ZERO_VEC36,
16366
- gunangles: ZERO_VEC36,
17302
+ kick_angles: ZERO_VEC37,
17303
+ kick_origin: ZERO_VEC37,
17304
+ gunoffset: ZERO_VEC37,
17305
+ gunangles: ZERO_VEC37,
16367
17306
  gunindex: 0,
16368
17307
  pm_type: 0,
16369
17308
  pm_time: 0,
@@ -16493,8 +17432,8 @@ function createGame(imports, engine, options) {
16493
17432
  rng,
16494
17433
  player: player?.client?.inventory
16495
17434
  });
16496
- origin = player ? { ...player.origin } : { ...ZERO_VEC36 };
16497
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC36 };
17435
+ origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
17436
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
16498
17437
  frameLoop.reset(save.level.timeSeconds * 1e3);
16499
17438
  }
16500
17439
  };