quake2ts 0.0.270 → 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.
- package/package.json +1 -1
- package/packages/cgame/dist/index.cjs +29 -5
- package/packages/cgame/dist/index.cjs.map +1 -1
- package/packages/cgame/dist/index.js +30 -6
- package/packages/cgame/dist/index.js.map +1 -1
- package/packages/client/dist/browser/index.global.js +13 -13
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/cjs/index.cjs.map +1 -1
- package/packages/client/dist/esm/index.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/browser/index.global.js +6 -6
- package/packages/engine/dist/browser/index.global.js.map +1 -1
- package/packages/engine/dist/cjs/index.cjs.map +1 -1
- package/packages/engine/dist/esm/index.js.map +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/browser/index.global.js +3 -3
- package/packages/game/dist/browser/index.global.js.map +1 -1
- package/packages/game/dist/cjs/index.cjs +1170 -120
- package/packages/game/dist/cjs/index.cjs.map +1 -1
- package/packages/game/dist/esm/index.js +1170 -120
- package/packages/game/dist/esm/index.js.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/entities/entity.d.ts +2 -0
- package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
- package/packages/game/dist/types/entities/monsters/fixbot.d.ts +5 -0
- package/packages/game/dist/types/entities/monsters/fixbot.d.ts.map +1 -0
- package/packages/game/dist/types/entities/monsters/gekk.d.ts +5 -0
- package/packages/game/dist/types/entities/monsters/gekk.d.ts.map +1 -0
- package/packages/game/dist/types/entities/monsters/index.d.ts.map +1 -1
- package/packages/game/dist/types/entities/playerStats.d.ts.map +1 -1
- package/packages/game/dist/types/entities/system.d.ts.map +1 -1
- package/packages/game/dist/types/entities/targets.d.ts.map +1 -1
- package/packages/game/dist/types/inventory/playerInventory.d.ts +5 -48
- package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
- package/packages/server/dist/index.cjs +73 -5
- package/packages/server/dist/index.js +73 -5
- package/packages/shared/dist/browser/index.global.js +1 -1
- package/packages/shared/dist/browser/index.global.js.map +1 -1
- package/packages/shared/dist/cjs/index.cjs +47 -4
- package/packages/shared/dist/cjs/index.cjs.map +1 -1
- package/packages/shared/dist/esm/index.js +45 -4
- package/packages/shared/dist/esm/index.js.map +1 -1
- package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/shared/dist/types/items/index.d.ts +1 -0
- package/packages/shared/dist/types/items/index.d.ts.map +1 -1
- package/packages/shared/dist/types/items/weaponInfo.d.ts +5 -0
- package/packages/shared/dist/types/items/weaponInfo.d.ts.map +1 -0
- package/packages/shared/dist/types/items/weapons.d.ts +8 -7
- package/packages/shared/dist/types/items/weapons.d.ts.map +1 -1
- 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 ?? [
|
|
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(
|
|
1552
|
-
else if (inv.ownedWeapons.has(
|
|
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 =
|
|
1697
|
+
powerupId = PowerupId.QuadDamage;
|
|
1682
1698
|
icon = "p_quad";
|
|
1683
1699
|
break;
|
|
1684
1700
|
case "item_invulnerability":
|
|
1685
|
-
powerupId =
|
|
1701
|
+
powerupId = PowerupId.Invulnerability;
|
|
1686
1702
|
icon = "p_invulnerability";
|
|
1687
1703
|
break;
|
|
1688
1704
|
case "item_silencer":
|
|
1689
|
-
powerupId =
|
|
1705
|
+
powerupId = PowerupId.Silencer;
|
|
1690
1706
|
icon = "p_silencer";
|
|
1691
1707
|
break;
|
|
1692
1708
|
case "item_rebreather":
|
|
1693
|
-
powerupId =
|
|
1709
|
+
powerupId = PowerupId.Rebreather;
|
|
1694
1710
|
icon = "p_rebreather";
|
|
1695
1711
|
break;
|
|
1696
1712
|
case "item_enviro":
|
|
1697
|
-
powerupId =
|
|
1713
|
+
powerupId = PowerupId.EnviroSuit;
|
|
1698
1714
|
icon = "p_envirosuit";
|
|
1699
1715
|
break;
|
|
1700
1716
|
case "item_double":
|
|
1701
|
-
powerupId =
|
|
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 ===
|
|
1725
|
+
if (powerupId === PowerupId.QuadDamage) {
|
|
1710
1726
|
client.quad_time = newExpiresAt / 1e3;
|
|
1711
|
-
} else if (powerupId ===
|
|
1727
|
+
} else if (powerupId === PowerupId.DoubleDamage) {
|
|
1712
1728
|
client.double_time = newExpiresAt / 1e3;
|
|
1713
1729
|
}
|
|
1714
1730
|
setPickup(inventory, icon, time);
|
|
@@ -1916,6 +1932,8 @@ var Entity = class {
|
|
|
1916
1932
|
this.attenuation = 0;
|
|
1917
1933
|
this.volume = 0;
|
|
1918
1934
|
this.fly_sound_debounce_time = 0;
|
|
1935
|
+
this.last_move_time = 0;
|
|
1936
|
+
this.damage_debounce_time = 0;
|
|
1919
1937
|
this.enemy = null;
|
|
1920
1938
|
this.movetarget = null;
|
|
1921
1939
|
this.target_ent = null;
|
|
@@ -2055,6 +2073,8 @@ var Entity = class {
|
|
|
2055
2073
|
this.sounds = 0;
|
|
2056
2074
|
this.noise_index = 0;
|
|
2057
2075
|
this.fly_sound_debounce_time = 0;
|
|
2076
|
+
this.last_move_time = 0;
|
|
2077
|
+
this.damage_debounce_time = 0;
|
|
2058
2078
|
this.enemy = null;
|
|
2059
2079
|
this.movetarget = null;
|
|
2060
2080
|
this.target_ent = null;
|
|
@@ -2150,6 +2170,8 @@ var ENTITY_FIELD_METADATA = [
|
|
|
2150
2170
|
{ name: "attenuation", type: "float", save: true },
|
|
2151
2171
|
{ name: "volume", type: "float", save: true },
|
|
2152
2172
|
{ name: "fly_sound_debounce_time", type: "float", save: true },
|
|
2173
|
+
{ name: "last_move_time", type: "float", save: true },
|
|
2174
|
+
{ name: "damage_debounce_time", type: "float", save: true },
|
|
2153
2175
|
{ name: "enemy", type: "entity", save: true },
|
|
2154
2176
|
{ name: "movetarget", type: "entity", save: true },
|
|
2155
2177
|
{ name: "target_ent", type: "entity", save: true },
|
|
@@ -3388,7 +3410,9 @@ var EntitySystem = class {
|
|
|
3388
3410
|
}
|
|
3389
3411
|
forEachEntity(callback) {
|
|
3390
3412
|
for (const entity of this.pool) {
|
|
3391
|
-
|
|
3413
|
+
if (entity.inUse && !entity.freePending) {
|
|
3414
|
+
callback(entity);
|
|
3415
|
+
}
|
|
3392
3416
|
}
|
|
3393
3417
|
}
|
|
3394
3418
|
find(predicate) {
|
|
@@ -4539,6 +4563,7 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
|
|
|
4539
4563
|
}
|
|
4540
4564
|
|
|
4541
4565
|
// src/entities/targets.ts
|
|
4566
|
+
var ATTN_NONE = 0;
|
|
4542
4567
|
var ATTN_NORM = 1;
|
|
4543
4568
|
var SPEAKER_SPAWNFLAGS = {
|
|
4544
4569
|
LoopedOn: 1 << 0,
|
|
@@ -4631,6 +4656,88 @@ function useTargetBlaster(self, other, activator, context) {
|
|
|
4631
4656
|
}
|
|
4632
4657
|
context.entities.sound(self, 2, "weapons/laser2.wav", 1, ATTN_NORM, 0);
|
|
4633
4658
|
}
|
|
4659
|
+
var SPAWNFLAG_EARTHQUAKE_SILENT = 1;
|
|
4660
|
+
var SPAWNFLAG_EARTHQUAKE_TOGGLE = 2;
|
|
4661
|
+
var SPAWNFLAG_EARTHQUAKE_ONE_SHOT = 8;
|
|
4662
|
+
function target_earthquake_think(self, context) {
|
|
4663
|
+
if (!(self.spawnflags & SPAWNFLAG_EARTHQUAKE_SILENT)) {
|
|
4664
|
+
if (self.last_move_time < context.entities.timeSeconds) {
|
|
4665
|
+
context.entities.sound(self, 2, "world/quake.wav", 1, ATTN_NONE, 0);
|
|
4666
|
+
self.last_move_time = context.entities.timeSeconds + 0.5;
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
context.entities.forEachEntity((ent) => {
|
|
4670
|
+
if (!ent.client) return;
|
|
4671
|
+
ent.client.quake_time = context.entities.timeSeconds + 0.2;
|
|
4672
|
+
});
|
|
4673
|
+
if (context.entities.timeSeconds < self.timestamp) {
|
|
4674
|
+
self.nextthink = context.entities.timeSeconds + 0.1;
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
function useTargetEarthquake(self, other, activator, context) {
|
|
4678
|
+
if (self.spawnflags & SPAWNFLAG_EARTHQUAKE_ONE_SHOT) {
|
|
4679
|
+
context.entities.forEachEntity((ent) => {
|
|
4680
|
+
if (!ent.client) return;
|
|
4681
|
+
if (ent.client) {
|
|
4682
|
+
if (!ent.client.kick_angles) ent.client.kick_angles = { x: 0, y: 0, z: 0 };
|
|
4683
|
+
ent.client.kick_angles = { ...ent.client.kick_angles, x: -self.speed * 0.1 };
|
|
4684
|
+
}
|
|
4685
|
+
});
|
|
4686
|
+
return;
|
|
4687
|
+
}
|
|
4688
|
+
self.timestamp = context.entities.timeSeconds + self.count;
|
|
4689
|
+
if (self.spawnflags & SPAWNFLAG_EARTHQUAKE_TOGGLE) {
|
|
4690
|
+
if (self.style) {
|
|
4691
|
+
self.nextthink = 0;
|
|
4692
|
+
} else {
|
|
4693
|
+
self.nextthink = context.entities.timeSeconds + 0.1;
|
|
4694
|
+
}
|
|
4695
|
+
self.style = !self.style ? 1 : 0;
|
|
4696
|
+
} else {
|
|
4697
|
+
self.nextthink = context.entities.timeSeconds + 0.1;
|
|
4698
|
+
self.last_move_time = 0;
|
|
4699
|
+
}
|
|
4700
|
+
self.activator = activator;
|
|
4701
|
+
}
|
|
4702
|
+
var SPAWNFLAG_LIGHTRAMP_TOGGLE = 1;
|
|
4703
|
+
function target_lightramp_think(self, context) {
|
|
4704
|
+
const timeDelta = context.entities.timeSeconds - self.timestamp;
|
|
4705
|
+
const val = self.movedir.x + timeDelta / 0.1 * self.movedir.z;
|
|
4706
|
+
let charCode = Math.floor("a".charCodeAt(0) + val);
|
|
4707
|
+
const styleStr = String.fromCharCode(charCode);
|
|
4708
|
+
const CS_LIGHTS = 32;
|
|
4709
|
+
if (self.enemy && self.enemy.style !== void 0) {
|
|
4710
|
+
context.entities.configstring(CS_LIGHTS + self.enemy.style, styleStr);
|
|
4711
|
+
}
|
|
4712
|
+
if (timeDelta < self.speed) {
|
|
4713
|
+
self.nextthink = context.entities.timeSeconds + 0.1;
|
|
4714
|
+
} else if (self.spawnflags & SPAWNFLAG_LIGHTRAMP_TOGGLE) {
|
|
4715
|
+
const temp = self.movedir.x;
|
|
4716
|
+
self.movedir = { ...self.movedir, x: self.movedir.y, y: temp, z: self.movedir.z * -1 };
|
|
4717
|
+
}
|
|
4718
|
+
}
|
|
4719
|
+
function useTargetLightramp(self, other, activator, context) {
|
|
4720
|
+
if (!self.enemy) {
|
|
4721
|
+
let e = null;
|
|
4722
|
+
let found = false;
|
|
4723
|
+
context.entities.forEachEntity((ent) => {
|
|
4724
|
+
if (ent.targetname === self.target) {
|
|
4725
|
+
if (ent.classname === "light") {
|
|
4726
|
+
self.enemy = ent;
|
|
4727
|
+
found = true;
|
|
4728
|
+
} else {
|
|
4729
|
+
context.warn(`${self.classname} target ${self.target} is not a light`);
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
});
|
|
4733
|
+
if (!found) {
|
|
4734
|
+
context.warn(`${self.classname} target ${self.target} not found`);
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
self.timestamp = context.entities.timeSeconds;
|
|
4739
|
+
target_lightramp_think(self, context);
|
|
4740
|
+
}
|
|
4634
4741
|
var TARGET_LASER_START_ON = 1;
|
|
4635
4742
|
var TARGET_LASER_RED = 2;
|
|
4636
4743
|
var TARGET_LASER_GREEN = 4;
|
|
@@ -4887,6 +4994,26 @@ function registerTargetSpawns(registry) {
|
|
|
4887
4994
|
};
|
|
4888
4995
|
context.entities.scheduleThink(entity, context.entities.timeSeconds + entity.delay);
|
|
4889
4996
|
});
|
|
4997
|
+
registry.register("target_earthquake", (entity, context) => {
|
|
4998
|
+
if (!entity.count) entity.count = 5;
|
|
4999
|
+
if (!entity.speed) entity.speed = 200;
|
|
5000
|
+
entity.svflags |= 1 /* NoClient */;
|
|
5001
|
+
entity.think = (self) => target_earthquake_think(self, context);
|
|
5002
|
+
entity.use = (self, other, activator) => useTargetEarthquake(self, other, activator ?? null, context);
|
|
5003
|
+
if (!(entity.spawnflags & SPAWNFLAG_EARTHQUAKE_SILENT)) {
|
|
5004
|
+
}
|
|
5005
|
+
});
|
|
5006
|
+
registry.register("target_lightramp", (entity, context) => {
|
|
5007
|
+
entity.svflags |= 1 /* NoClient */;
|
|
5008
|
+
entity.use = (self, other, activator) => useTargetLightramp(self, other, activator ?? null, context);
|
|
5009
|
+
entity.think = (self) => target_lightramp_think(self, context);
|
|
5010
|
+
if (entity.message && entity.message.length === 2 && entity.speed) {
|
|
5011
|
+
const start = entity.message.charCodeAt(0) - "a".charCodeAt(0);
|
|
5012
|
+
const end = entity.message.charCodeAt(1) - "a".charCodeAt(0);
|
|
5013
|
+
const slope = (end - start) / (entity.speed / 0.1);
|
|
5014
|
+
entity.movedir = { x: start, y: end, z: slope };
|
|
5015
|
+
}
|
|
5016
|
+
});
|
|
4890
5017
|
}
|
|
4891
5018
|
|
|
4892
5019
|
// src/entities/triggers.ts
|
|
@@ -5472,7 +5599,7 @@ function chaingunThink(player, sys) {
|
|
|
5472
5599
|
if (!player.client) {
|
|
5473
5600
|
return;
|
|
5474
5601
|
}
|
|
5475
|
-
const weaponState = getWeaponState(player.client.weaponStates,
|
|
5602
|
+
const weaponState = getWeaponState(player.client.weaponStates, WeaponId.Chaingun);
|
|
5476
5603
|
if (!(player.client.buttons & BUTTON_ATTACK) && weaponState.spinupCount && weaponState.spinupCount > 0) {
|
|
5477
5604
|
sys.sound(player, 0, "weapons/chngnd1a.wav", 1, 0, 0);
|
|
5478
5605
|
weaponState.spinupCount = 0;
|
|
@@ -5485,7 +5612,7 @@ var WEAPON_ITEMS = {
|
|
|
5485
5612
|
type: "weapon",
|
|
5486
5613
|
id: "weapon_blaster",
|
|
5487
5614
|
name: "Blaster",
|
|
5488
|
-
weaponId:
|
|
5615
|
+
weaponId: WeaponId.Blaster,
|
|
5489
5616
|
ammoType: null,
|
|
5490
5617
|
initialAmmo: 0,
|
|
5491
5618
|
pickupAmmo: 0,
|
|
@@ -5495,7 +5622,7 @@ var WEAPON_ITEMS = {
|
|
|
5495
5622
|
type: "weapon",
|
|
5496
5623
|
id: "weapon_shotgun",
|
|
5497
5624
|
name: "Shotgun",
|
|
5498
|
-
weaponId:
|
|
5625
|
+
weaponId: WeaponId.Shotgun,
|
|
5499
5626
|
ammoType: AmmoType.Shells,
|
|
5500
5627
|
initialAmmo: 10,
|
|
5501
5628
|
pickupAmmo: 10,
|
|
@@ -5505,7 +5632,7 @@ var WEAPON_ITEMS = {
|
|
|
5505
5632
|
type: "weapon",
|
|
5506
5633
|
id: "weapon_supershotgun",
|
|
5507
5634
|
name: "Super Shotgun",
|
|
5508
|
-
weaponId:
|
|
5635
|
+
weaponId: WeaponId.SuperShotgun,
|
|
5509
5636
|
ammoType: AmmoType.Shells,
|
|
5510
5637
|
initialAmmo: 10,
|
|
5511
5638
|
pickupAmmo: 10,
|
|
@@ -5515,7 +5642,7 @@ var WEAPON_ITEMS = {
|
|
|
5515
5642
|
type: "weapon",
|
|
5516
5643
|
id: "weapon_machinegun",
|
|
5517
5644
|
name: "Machinegun",
|
|
5518
|
-
weaponId:
|
|
5645
|
+
weaponId: WeaponId.Machinegun,
|
|
5519
5646
|
ammoType: AmmoType.Bullets,
|
|
5520
5647
|
initialAmmo: 50,
|
|
5521
5648
|
pickupAmmo: 50,
|
|
@@ -5526,7 +5653,7 @@ var WEAPON_ITEMS = {
|
|
|
5526
5653
|
type: "weapon",
|
|
5527
5654
|
id: "weapon_chaingun",
|
|
5528
5655
|
name: "Chaingun",
|
|
5529
|
-
weaponId:
|
|
5656
|
+
weaponId: WeaponId.Chaingun,
|
|
5530
5657
|
ammoType: AmmoType.Bullets,
|
|
5531
5658
|
initialAmmo: 50,
|
|
5532
5659
|
pickupAmmo: 50,
|
|
@@ -5536,7 +5663,7 @@ var WEAPON_ITEMS = {
|
|
|
5536
5663
|
type: "weapon",
|
|
5537
5664
|
id: "weapon_grenades",
|
|
5538
5665
|
name: "Hand Grenade",
|
|
5539
|
-
weaponId:
|
|
5666
|
+
weaponId: WeaponId.HandGrenade,
|
|
5540
5667
|
ammoType: AmmoType.Grenades,
|
|
5541
5668
|
initialAmmo: 5,
|
|
5542
5669
|
pickupAmmo: 5,
|
|
@@ -5546,7 +5673,7 @@ var WEAPON_ITEMS = {
|
|
|
5546
5673
|
type: "weapon",
|
|
5547
5674
|
id: "weapon_grenadelauncher",
|
|
5548
5675
|
name: "Grenade Launcher",
|
|
5549
|
-
weaponId:
|
|
5676
|
+
weaponId: WeaponId.GrenadeLauncher,
|
|
5550
5677
|
ammoType: AmmoType.Grenades,
|
|
5551
5678
|
initialAmmo: 10,
|
|
5552
5679
|
pickupAmmo: 10,
|
|
@@ -5556,7 +5683,7 @@ var WEAPON_ITEMS = {
|
|
|
5556
5683
|
type: "weapon",
|
|
5557
5684
|
id: "weapon_rocketlauncher",
|
|
5558
5685
|
name: "Rocket Launcher",
|
|
5559
|
-
weaponId:
|
|
5686
|
+
weaponId: WeaponId.RocketLauncher,
|
|
5560
5687
|
ammoType: AmmoType.Rockets,
|
|
5561
5688
|
initialAmmo: 5,
|
|
5562
5689
|
pickupAmmo: 5,
|
|
@@ -5566,7 +5693,7 @@ var WEAPON_ITEMS = {
|
|
|
5566
5693
|
type: "weapon",
|
|
5567
5694
|
id: "weapon_hyperblaster",
|
|
5568
5695
|
name: "HyperBlaster",
|
|
5569
|
-
weaponId:
|
|
5696
|
+
weaponId: WeaponId.HyperBlaster,
|
|
5570
5697
|
ammoType: AmmoType.Cells,
|
|
5571
5698
|
initialAmmo: 50,
|
|
5572
5699
|
pickupAmmo: 50,
|
|
@@ -5576,7 +5703,7 @@ var WEAPON_ITEMS = {
|
|
|
5576
5703
|
type: "weapon",
|
|
5577
5704
|
id: "weapon_railgun",
|
|
5578
5705
|
name: "Railgun",
|
|
5579
|
-
weaponId:
|
|
5706
|
+
weaponId: WeaponId.Railgun,
|
|
5580
5707
|
ammoType: AmmoType.Slugs,
|
|
5581
5708
|
initialAmmo: 10,
|
|
5582
5709
|
pickupAmmo: 10,
|
|
@@ -5586,7 +5713,7 @@ var WEAPON_ITEMS = {
|
|
|
5586
5713
|
type: "weapon",
|
|
5587
5714
|
id: "weapon_bfg",
|
|
5588
5715
|
name: "BFG10K",
|
|
5589
|
-
weaponId:
|
|
5716
|
+
weaponId: WeaponId.BFG10K,
|
|
5590
5717
|
ammoType: AmmoType.Cells,
|
|
5591
5718
|
initialAmmo: 50,
|
|
5592
5719
|
pickupAmmo: 50,
|
|
@@ -5598,7 +5725,7 @@ var WEAPON_ITEMS = {
|
|
|
5598
5725
|
id: "weapon_boomer",
|
|
5599
5726
|
// Ion Ripper
|
|
5600
5727
|
name: "Ion Ripper",
|
|
5601
|
-
weaponId:
|
|
5728
|
+
weaponId: WeaponId.IonRipper,
|
|
5602
5729
|
ammoType: AmmoType.Cells,
|
|
5603
5730
|
initialAmmo: 50,
|
|
5604
5731
|
pickupAmmo: 50,
|
|
@@ -5608,7 +5735,7 @@ var WEAPON_ITEMS = {
|
|
|
5608
5735
|
type: "weapon",
|
|
5609
5736
|
id: "weapon_phalanx",
|
|
5610
5737
|
name: "Phalanx",
|
|
5611
|
-
weaponId:
|
|
5738
|
+
weaponId: WeaponId.Phalanx,
|
|
5612
5739
|
ammoType: AmmoType.MagSlugs,
|
|
5613
5740
|
initialAmmo: 50,
|
|
5614
5741
|
pickupAmmo: 50,
|
|
@@ -5618,7 +5745,7 @@ var WEAPON_ITEMS = {
|
|
|
5618
5745
|
type: "weapon",
|
|
5619
5746
|
id: "weapon_beam",
|
|
5620
5747
|
name: "Plasma Beam",
|
|
5621
|
-
weaponId:
|
|
5748
|
+
weaponId: WeaponId.PlasmaBeam,
|
|
5622
5749
|
ammoType: AmmoType.Cells,
|
|
5623
5750
|
initialAmmo: 50,
|
|
5624
5751
|
pickupAmmo: 50,
|
|
@@ -5628,7 +5755,7 @@ var WEAPON_ITEMS = {
|
|
|
5628
5755
|
type: "weapon",
|
|
5629
5756
|
id: "weapon_etf_rifle",
|
|
5630
5757
|
name: "ETF Rifle",
|
|
5631
|
-
weaponId:
|
|
5758
|
+
weaponId: WeaponId.EtfRifle,
|
|
5632
5759
|
ammoType: AmmoType.Flechettes,
|
|
5633
5760
|
initialAmmo: 50,
|
|
5634
5761
|
pickupAmmo: 50,
|
|
@@ -5638,7 +5765,7 @@ var WEAPON_ITEMS = {
|
|
|
5638
5765
|
type: "weapon",
|
|
5639
5766
|
id: "weapon_proxlauncher",
|
|
5640
5767
|
name: "Prox Launcher",
|
|
5641
|
-
weaponId:
|
|
5768
|
+
weaponId: WeaponId.ProxLauncher,
|
|
5642
5769
|
ammoType: AmmoType.Prox,
|
|
5643
5770
|
initialAmmo: 5,
|
|
5644
5771
|
pickupAmmo: 5,
|
|
@@ -11547,8 +11674,8 @@ function actor_pain(self, other, kick, damage) {
|
|
|
11547
11674
|
if (context.timeSeconds < self.pain_debounce_time)
|
|
11548
11675
|
return;
|
|
11549
11676
|
self.pain_debounce_time = context.timeSeconds + 3;
|
|
11550
|
-
const
|
|
11551
|
-
if (other && other.client &&
|
|
11677
|
+
const random12 = Math.random();
|
|
11678
|
+
if (other && other.client && random12 < 0.4) {
|
|
11552
11679
|
const v = subtractVec3(other.origin, self.origin);
|
|
11553
11680
|
self.ideal_yaw = vectorToYaw(v);
|
|
11554
11681
|
if (Math.random() < 0.5)
|
|
@@ -14244,6 +14371,934 @@ function registerTurretSpawns(registry) {
|
|
|
14244
14371
|
registry.register("monster_turret", SP_monster_turret);
|
|
14245
14372
|
}
|
|
14246
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
|
+
|
|
14247
15302
|
// src/entities/monsters/index.ts
|
|
14248
15303
|
function registerMonsterSpawns2(registry) {
|
|
14249
15304
|
registerMonsterSpawns(registry);
|
|
@@ -14270,6 +15325,8 @@ function registerMonsterSpawns2(registry) {
|
|
|
14270
15325
|
registerMakronSpawns(registry);
|
|
14271
15326
|
registerInsaneSpawns(registry);
|
|
14272
15327
|
registerActorSpawns(registry);
|
|
15328
|
+
registerGekkSpawns(registry);
|
|
15329
|
+
registerFixbotSpawns(registry);
|
|
14273
15330
|
}
|
|
14274
15331
|
|
|
14275
15332
|
// src/entities/worldspawn.ts
|
|
@@ -15580,7 +16637,7 @@ function PlayerNoise(who, where, type, context) {
|
|
|
15580
16637
|
}
|
|
15581
16638
|
|
|
15582
16639
|
// src/combat/obituary.ts
|
|
15583
|
-
var
|
|
16640
|
+
var random10 = createRandomGenerator();
|
|
15584
16641
|
var PRINT_MEDIUM = 1;
|
|
15585
16642
|
function getGender(ent) {
|
|
15586
16643
|
return "male";
|
|
@@ -15743,7 +16800,7 @@ var ANIM_PAIN = 2;
|
|
|
15743
16800
|
var ANIM_DEATH = 3;
|
|
15744
16801
|
|
|
15745
16802
|
// src/combat/weapons/firing.ts
|
|
15746
|
-
var
|
|
16803
|
+
var random11 = createRandomGenerator();
|
|
15747
16804
|
|
|
15748
16805
|
// src/entities/player.ts
|
|
15749
16806
|
function P_PlayerThink(ent, sys) {
|
|
@@ -15800,7 +16857,7 @@ function player_pain(self, damage) {
|
|
|
15800
16857
|
return;
|
|
15801
16858
|
}
|
|
15802
16859
|
self.client.anim_priority = ANIM_PAIN;
|
|
15803
|
-
const r =
|
|
16860
|
+
const r = random11.frandom();
|
|
15804
16861
|
if (r < 0.33) {
|
|
15805
16862
|
self.frame = FRAME_pain1012;
|
|
15806
16863
|
self.client.anim_end = FRAME_pain104;
|
|
@@ -15823,7 +16880,7 @@ function player_die(self, inflictor, attacker, damage, point, mod, sys) {
|
|
|
15823
16880
|
}
|
|
15824
16881
|
if (self.client) {
|
|
15825
16882
|
self.client.anim_priority = ANIM_DEATH;
|
|
15826
|
-
const r =
|
|
16883
|
+
const r = random11.frandom();
|
|
15827
16884
|
if (r < 0.33) {
|
|
15828
16885
|
self.frame = FRAME_death1012;
|
|
15829
16886
|
self.client.anim_end = FRAME_death106;
|
|
@@ -15876,25 +16933,12 @@ function player_think(self, sys) {
|
|
|
15876
16933
|
}
|
|
15877
16934
|
|
|
15878
16935
|
// src/entities/playerStats.ts
|
|
15879
|
-
var WEAPON_WHEEL_ORDER = [
|
|
15880
|
-
"blaster" /* Blaster */,
|
|
15881
|
-
"shotgun" /* Shotgun */,
|
|
15882
|
-
"supershotgun" /* SuperShotgun */,
|
|
15883
|
-
"machinegun" /* Machinegun */,
|
|
15884
|
-
"chaingun" /* Chaingun */,
|
|
15885
|
-
"grenadelauncher" /* GrenadeLauncher */,
|
|
15886
|
-
"rocketlauncher" /* RocketLauncher */,
|
|
15887
|
-
"grenades" /* HandGrenade */,
|
|
15888
|
-
"hyperblaster" /* HyperBlaster */,
|
|
15889
|
-
"railgun" /* Railgun */,
|
|
15890
|
-
"bfg10k" /* BFG10K */
|
|
15891
|
-
];
|
|
15892
16936
|
var POWERUP_TIMERS = [
|
|
15893
|
-
{ id:
|
|
15894
|
-
{ id:
|
|
15895
|
-
{ id:
|
|
15896
|
-
{ id:
|
|
15897
|
-
{ id:
|
|
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 }
|
|
15898
16942
|
];
|
|
15899
16943
|
function populatePlayerStats(player, timeSeconds) {
|
|
15900
16944
|
if (!player.client) return [];
|
|
@@ -15913,6 +16957,12 @@ function populatePlayerStats(player, timeSeconds) {
|
|
|
15913
16957
|
}
|
|
15914
16958
|
statArray[PlayerStat.STAT_WEAPONS_OWNED_1] = weaponBits & 65535;
|
|
15915
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
|
+
}
|
|
15916
16966
|
statArray[PlayerStat.STAT_AMMO] = 0;
|
|
15917
16967
|
if (inventory.currentWeapon) {
|
|
15918
16968
|
const weaponItem = Object.values(WEAPON_ITEMS).find((item) => item.weaponId === inventory.currentWeapon);
|
|
@@ -16217,7 +17267,7 @@ var WEAPONS = {
|
|
|
16217
17267
|
};
|
|
16218
17268
|
|
|
16219
17269
|
// src/index.ts
|
|
16220
|
-
var
|
|
17270
|
+
var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
|
|
16221
17271
|
function createGame(imports, engine, options) {
|
|
16222
17272
|
const gravity = options.gravity;
|
|
16223
17273
|
const deathmatch = options.deathmatch ?? false;
|
|
@@ -16286,26 +17336,26 @@ function createGame(imports, engine, options) {
|
|
|
16286
17336
|
};
|
|
16287
17337
|
entities.runFrame();
|
|
16288
17338
|
});
|
|
16289
|
-
let origin = { ...
|
|
16290
|
-
let velocity = { ...
|
|
17339
|
+
let origin = { ...ZERO_VEC37 };
|
|
17340
|
+
let velocity = { ...ZERO_VEC37 };
|
|
16291
17341
|
const calculateBlend = (player, time) => {
|
|
16292
17342
|
const blend = [0, 0, 0, 0];
|
|
16293
17343
|
if (!player || !player.client) return blend;
|
|
16294
17344
|
const inventory = player.client.inventory;
|
|
16295
|
-
if (inventory.powerups.has(
|
|
17345
|
+
if (inventory.powerups.has(PowerupId.QuadDamage)) {
|
|
16296
17346
|
blend[2] = 1;
|
|
16297
17347
|
blend[3] = 0.08;
|
|
16298
17348
|
}
|
|
16299
|
-
if (inventory.powerups.has(
|
|
17349
|
+
if (inventory.powerups.has(PowerupId.Invulnerability)) {
|
|
16300
17350
|
blend[0] = 1;
|
|
16301
17351
|
blend[1] = 1;
|
|
16302
17352
|
blend[3] = 0.08;
|
|
16303
17353
|
}
|
|
16304
|
-
if (inventory.powerups.has(
|
|
17354
|
+
if (inventory.powerups.has(PowerupId.EnviroSuit)) {
|
|
16305
17355
|
blend[1] = 1;
|
|
16306
17356
|
blend[3] = 0.08;
|
|
16307
17357
|
}
|
|
16308
|
-
if (inventory.powerups.has(
|
|
17358
|
+
if (inventory.powerups.has(PowerupId.Rebreather)) {
|
|
16309
17359
|
blend[0] = 0.4;
|
|
16310
17360
|
blend[1] = 1;
|
|
16311
17361
|
blend[2] = 0.4;
|
|
@@ -16369,10 +17419,10 @@ function createGame(imports, engine, options) {
|
|
|
16369
17419
|
// TODO
|
|
16370
17420
|
damageIndicators: [],
|
|
16371
17421
|
stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
|
|
16372
|
-
kick_angles: player?.client?.kick_angles ??
|
|
16373
|
-
kick_origin: player?.client?.kick_origin ??
|
|
16374
|
-
gunoffset:
|
|
16375
|
-
gunangles:
|
|
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,
|
|
16376
17426
|
gunindex: 0,
|
|
16377
17427
|
gun_frame: player?.client?.gun_frame ?? 0,
|
|
16378
17428
|
rdflags: player?.client?.rdflags ?? 0,
|
|
@@ -16386,8 +17436,8 @@ function createGame(imports, engine, options) {
|
|
|
16386
17436
|
const resetState = (startTimeMs) => {
|
|
16387
17437
|
frameLoop.reset(startTimeMs);
|
|
16388
17438
|
levelClock.start(startTimeMs);
|
|
16389
|
-
origin = { ...
|
|
16390
|
-
velocity = { ...
|
|
17439
|
+
origin = { ...ZERO_VEC37 };
|
|
17440
|
+
velocity = { ...ZERO_VEC37 };
|
|
16391
17441
|
entities.beginFrame(startTimeMs / 1e3);
|
|
16392
17442
|
entities.runFrame();
|
|
16393
17443
|
};
|
|
@@ -16415,10 +17465,10 @@ function createGame(imports, engine, options) {
|
|
|
16415
17465
|
blend: [0, 0, 0, 0],
|
|
16416
17466
|
// Stubs
|
|
16417
17467
|
stats: populatePlayerStats(player, levelClock.current.timeSeconds),
|
|
16418
|
-
kick_angles:
|
|
16419
|
-
kick_origin:
|
|
16420
|
-
gunoffset:
|
|
16421
|
-
gunangles:
|
|
17468
|
+
kick_angles: ZERO_VEC37,
|
|
17469
|
+
kick_origin: ZERO_VEC37,
|
|
17470
|
+
gunoffset: ZERO_VEC37,
|
|
17471
|
+
gunangles: ZERO_VEC37,
|
|
16422
17472
|
gunindex: 0,
|
|
16423
17473
|
pm_type: 0,
|
|
16424
17474
|
pm_time: 0,
|
|
@@ -16548,8 +17598,8 @@ function createGame(imports, engine, options) {
|
|
|
16548
17598
|
rng,
|
|
16549
17599
|
player: player?.client?.inventory
|
|
16550
17600
|
});
|
|
16551
|
-
origin = player ? { ...player.origin } : { ...
|
|
16552
|
-
velocity = player ? { ...player.velocity } : { ...
|
|
17601
|
+
origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
|
|
17602
|
+
velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
|
|
16553
17603
|
frameLoop.reset(save.level.timeSeconds * 1e3);
|
|
16554
17604
|
}
|
|
16555
17605
|
};
|