quake2ts 0.0.303 → 0.0.307

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 (31) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +13 -13
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +17 -1
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +17 -1
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/client/dist/types/index.d.ts.map +1 -1
  10. package/packages/game/dist/browser/index.global.js +4 -4
  11. package/packages/game/dist/browser/index.global.js.map +1 -1
  12. package/packages/game/dist/cjs/index.cjs +1310 -21
  13. package/packages/game/dist/cjs/index.cjs.map +1 -1
  14. package/packages/game/dist/esm/index.js +1309 -21
  15. package/packages/game/dist/esm/index.js.map +1 -1
  16. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  17. package/packages/game/dist/types/ai/constants.d.ts +1 -0
  18. package/packages/game/dist/types/ai/constants.d.ts.map +1 -1
  19. package/packages/game/dist/types/entities/gibs.d.ts +4 -0
  20. package/packages/game/dist/types/entities/gibs.d.ts.map +1 -1
  21. package/packages/game/dist/types/entities/monsters/attack.d.ts +1 -0
  22. package/packages/game/dist/types/entities/monsters/attack.d.ts.map +1 -1
  23. package/packages/game/dist/types/entities/monsters/common.d.ts +3 -0
  24. package/packages/game/dist/types/entities/monsters/common.d.ts.map +1 -1
  25. package/packages/game/dist/types/entities/monsters/guardian.d.ts +5 -0
  26. package/packages/game/dist/types/entities/monsters/guardian.d.ts.map +1 -0
  27. package/packages/game/dist/types/entities/monsters/gunnerCommander.d.ts +5 -0
  28. package/packages/game/dist/types/entities/monsters/gunnerCommander.d.ts.map +1 -0
  29. package/packages/game/dist/types/entities/monsters/index.d.ts.map +1 -1
  30. package/packages/game/dist/types/index.d.ts +5 -0
  31. package/packages/game/dist/types/index.d.ts.map +1 -1
@@ -2455,6 +2455,7 @@ __export(index_exports, {
2455
2455
  M_CheckBottom: () => M_CheckBottom,
2456
2456
  M_MoveFrame: () => M_MoveFrame,
2457
2457
  M_walkmove: () => M_walkmove,
2458
+ MonsterAttackState: () => MonsterAttackState,
2458
2459
  MoveType: () => MoveType,
2459
2460
  MulticastType: () => MulticastType,
2460
2461
  ORDERED_DAMAGE_MODS: () => ORDERED_DAMAGE_MODS,
@@ -3011,6 +3012,7 @@ var AttackState = /* @__PURE__ */ ((AttackState2) => {
3011
3012
  AttackState2[AttackState2["Blind"] = 4] = "Blind";
3012
3013
  return AttackState2;
3013
3014
  })(AttackState || {});
3015
+ var MonsterAttackState = AttackState;
3014
3016
  var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
3015
3017
  TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
3016
3018
  TraceMask2[TraceMask2["Window"] = 2] = "Window";
@@ -3020,12 +3022,12 @@ var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
3020
3022
  // src/ai/perception.ts
3021
3023
  init_esm();
3022
3024
  init_esm();
3023
- var RangeCategory = /* @__PURE__ */ ((RangeCategory4) => {
3024
- RangeCategory4["Melee"] = "melee";
3025
- RangeCategory4["Near"] = "near";
3026
- RangeCategory4["Mid"] = "mid";
3027
- RangeCategory4["Far"] = "far";
3028
- return RangeCategory4;
3025
+ var RangeCategory = /* @__PURE__ */ ((RangeCategory5) => {
3026
+ RangeCategory5["Melee"] = "melee";
3027
+ RangeCategory5["Near"] = "near";
3028
+ RangeCategory5["Mid"] = "mid";
3029
+ RangeCategory5["Far"] = "far";
3030
+ return RangeCategory5;
3029
3031
  })(RangeCategory || {});
3030
3032
  function absBounds(entity) {
3031
3033
  return {
@@ -5446,6 +5448,52 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5446
5448
  sys.scheduleThink(bfgBall, sys.timeSeconds + 0.016);
5447
5449
  sys.finalizeSpawn(bfgBall);
5448
5450
  }
5451
+ function createFlechette(sys, owner, start, dir, damage, speed) {
5452
+ const flechette = sys.spawn();
5453
+ flechette.classname = "flechette";
5454
+ flechette.owner = owner;
5455
+ flechette.origin = { ...start };
5456
+ flechette.velocity = { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed };
5457
+ flechette.movetype = 8 /* FlyMissile */;
5458
+ flechette.solid = 2 /* BoundingBox */;
5459
+ flechette.modelindex = sys.modelIndex("models/objects/projectile/tris.md2");
5460
+ flechette.mins = { x: -2, y: -2, z: -2 };
5461
+ flechette.maxs = { x: 2, y: 2, z: 2 };
5462
+ flechette.angles = vectorToAngles(dir);
5463
+ flechette.touch = (self, other, plane, surf) => {
5464
+ if (other === self.owner) {
5465
+ return;
5466
+ }
5467
+ if (other && other.takedamage) {
5468
+ T_Damage(
5469
+ other,
5470
+ self,
5471
+ self.owner,
5472
+ self.velocity,
5473
+ self.origin,
5474
+ plane ? plane.normal : ZERO_VEC3,
5475
+ damage,
5476
+ 1,
5477
+ 0 /* NONE */,
5478
+ 43 /* ETF_RIFLE */,
5479
+ // Assuming this exists or falls under UNKNOWN
5480
+ sys.timeSeconds,
5481
+ sys.multicast ? sys.multicast.bind(sys) : void 0
5482
+ );
5483
+ if (other.monsterinfo) {
5484
+ const time = sys.timeSeconds || 0;
5485
+ other.monsterinfo.freeze_time = time + 3;
5486
+ }
5487
+ sys.free(self);
5488
+ return;
5489
+ }
5490
+ if (plane) {
5491
+ sys.multicast(self.origin, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.SPARKS, self.origin, plane.normal);
5492
+ }
5493
+ sys.free(self);
5494
+ };
5495
+ sys.finalizeSpawn(flechette);
5496
+ }
5449
5497
 
5450
5498
  // src/entities/targets.ts
5451
5499
  var ATTN_NONE = 0;
@@ -9683,6 +9731,9 @@ function monster_fire_dabeam(self, damage, secondary, update_func, context) {
9683
9731
  update_func(beam, context);
9684
9732
  dabeam_update(beam, context);
9685
9733
  }
9734
+ function monster_fire_flechette(self, start, dir, damage, speed, flashtype, context) {
9735
+ createFlechette(context, self, start, dir, damage, speed);
9736
+ }
9686
9737
 
9687
9738
  // src/entities/monsters/boss2.ts
9688
9739
  init_esm();
@@ -17424,6 +17475,20 @@ function M_ProjectFlashSource(self, offset, forward, right) {
17424
17475
  const start3 = addVec3(start2, { x: 0, y: 0, z: offset.z });
17425
17476
  return start3;
17426
17477
  }
17478
+ function M_MonsterDodge(self, attacker, eta) {
17479
+ }
17480
+ function M_CheckClearShot(self, offset, context) {
17481
+ if (!self.enemy) return false;
17482
+ const start = { ...self.origin };
17483
+ start.z += self.viewheight;
17484
+ const end = { ...self.enemy.origin };
17485
+ end.z += self.enemy.viewheight;
17486
+ const tr = context.trace(start, end, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
17487
+ if (tr.fraction === 1 || tr.ent === self.enemy) {
17488
+ return true;
17489
+ }
17490
+ return false;
17491
+ }
17427
17492
 
17428
17493
  // src/entities/monsters/arachnid.ts
17429
17494
  var FRAME_rails1 = 0;
@@ -17803,6 +17868,1227 @@ function registerArachnidSpawns(registry) {
17803
17868
  registry.register("monster_arachnid", SP_monster_arachnid);
17804
17869
  }
17805
17870
 
17871
+ // src/entities/monsters/gunnerCommander.ts
17872
+ init_esm();
17873
+ var MONSTER_TICK28 = 0.1;
17874
+ var MORTAR_SPEED = 850;
17875
+ var GRENADE_SPEED = 600;
17876
+ var MZ2_GUNCMDR_CHAINGUN_1 = 1;
17877
+ var MZ2_GUNCMDR_CHAINGUN_2 = 2;
17878
+ var MZ2_GUNCMDR_GRENADE_MORTAR_1 = 3;
17879
+ var MZ2_GUNCMDR_GRENADE_MORTAR_2 = 4;
17880
+ var MZ2_GUNCMDR_GRENADE_MORTAR_3 = 5;
17881
+ var MZ2_GUNCMDR_GRENADE_FRONT_1 = 6;
17882
+ var MZ2_GUNCMDR_GRENADE_FRONT_2 = 7;
17883
+ var MZ2_GUNCMDR_GRENADE_FRONT_3 = 8;
17884
+ var MZ2_GUNCMDR_GRENADE_CROUCH_1 = 9;
17885
+ var MZ2_GUNCMDR_GRENADE_CROUCH_2 = 10;
17886
+ var MZ2_GUNCMDR_GRENADE_CROUCH_3 = 11;
17887
+ var monster_flash_offset = {
17888
+ [MZ2_GUNCMDR_CHAINGUN_1]: { x: 37, y: -4, z: 12.5 },
17889
+ [MZ2_GUNCMDR_CHAINGUN_2]: { x: 37, y: -4, z: 12.5 },
17890
+ [MZ2_GUNCMDR_GRENADE_MORTAR_1]: { x: 14, y: 7, z: 27.5 },
17891
+ [MZ2_GUNCMDR_GRENADE_MORTAR_2]: { x: 14, y: 7, z: 27.5 },
17892
+ [MZ2_GUNCMDR_GRENADE_MORTAR_3]: { x: 14, y: 7, z: 27.5 },
17893
+ [MZ2_GUNCMDR_GRENADE_FRONT_1]: { x: 19, y: 7, z: 13.5 },
17894
+ [MZ2_GUNCMDR_GRENADE_FRONT_2]: { x: 19, y: 7, z: 13.5 },
17895
+ [MZ2_GUNCMDR_GRENADE_FRONT_3]: { x: 19, y: 7, z: 13.5 },
17896
+ [MZ2_GUNCMDR_GRENADE_CROUCH_1]: { x: 19, y: 7, z: 13.5 },
17897
+ [MZ2_GUNCMDR_GRENADE_CROUCH_2]: { x: 19, y: 7, z: 13.5 },
17898
+ [MZ2_GUNCMDR_GRENADE_CROUCH_3]: { x: 19, y: 7, z: 13.5 }
17899
+ };
17900
+ function monster_ai_stand24(self, dist, context) {
17901
+ ai_stand(self, MONSTER_TICK28, context);
17902
+ }
17903
+ function monster_ai_walk23(self, dist, context) {
17904
+ ai_walk(self, dist, MONSTER_TICK28, context);
17905
+ }
17906
+ function monster_ai_run24(self, dist, context) {
17907
+ ai_run(self, dist, MONSTER_TICK28, context);
17908
+ }
17909
+ function monster_ai_charge25(self, dist, context) {
17910
+ ai_charge(self, dist, MONSTER_TICK28, context);
17911
+ }
17912
+ function monster_ai_move24(self, dist, context) {
17913
+ ai_move(self, dist);
17914
+ }
17915
+ var stand_move21;
17916
+ var fidget_move4;
17917
+ var walk_move18;
17918
+ var run_move20;
17919
+ var attack_chain_move3;
17920
+ var fire_chain_move2;
17921
+ var fire_chain_run_move;
17922
+ var fire_chain_dodge_right_move;
17923
+ var fire_chain_dodge_left_move;
17924
+ var endfire_chain_move2;
17925
+ var attack_mortar_move;
17926
+ var attack_mortar_dodge_move;
17927
+ var attack_grenade_back_move;
17928
+ var attack_grenade_back_dodge_right_move;
17929
+ var attack_grenade_back_dodge_left_move;
17930
+ var attack_kick_move;
17931
+ var duck_attack_move;
17932
+ var jump_move3;
17933
+ var jump2_move;
17934
+ var pain1_move8;
17935
+ var pain2_move8;
17936
+ var pain3_move7;
17937
+ var pain4_move2;
17938
+ var pain5_move2;
17939
+ var pain6_move2;
17940
+ var pain7_move;
17941
+ var death1_move3;
17942
+ var death2_move3;
17943
+ var death3_move;
17944
+ var death4_move;
17945
+ var death5_move;
17946
+ var death6_move;
17947
+ var death7_move;
17948
+ function guncmdr_idlesound(self, context) {
17949
+ context.engine.sound?.(self, 0, "guncmdr/gcdridle1.wav", 1, 1, 0);
17950
+ }
17951
+ function guncmdr_sight(self, other, context) {
17952
+ context.engine.sound?.(self, 0, "guncmdr/sight1.wav", 1, 1, 0);
17953
+ }
17954
+ function guncmdr_search(self, context) {
17955
+ context.engine.sound?.(self, 0, "guncmdr/gcdrsrch1.wav", 1, 1, 0);
17956
+ }
17957
+ function guncmdr_opengun(self, context) {
17958
+ context.engine.sound?.(self, 0, "guncmdr/gcdratck1.wav", 1, 1, 0);
17959
+ }
17960
+ function guncmdr_fidget(self, context) {
17961
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) return;
17962
+ if (self.enemy) return;
17963
+ if (Math.random() <= 0.05) {
17964
+ M_SetAnimation3(self, fidget_move4, context);
17965
+ }
17966
+ }
17967
+ function guncmdr_stand(self, context) {
17968
+ M_SetAnimation3(self, stand_move21, context);
17969
+ }
17970
+ function guncmdr_walk(self, context) {
17971
+ M_SetAnimation3(self, walk_move18, context);
17972
+ }
17973
+ function monster_done_dodge2(self) {
17974
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
17975
+ }
17976
+ function guncmdr_run(self, context) {
17977
+ monster_done_dodge2(self);
17978
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) {
17979
+ M_SetAnimation3(self, stand_move21, context);
17980
+ } else {
17981
+ M_SetAnimation3(self, run_move20, context);
17982
+ }
17983
+ }
17984
+ function guncmdr_fire_chain(self, context) {
17985
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
17986
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
17987
+ if (dist > 400 && ai_move(self, 8)) {
17988
+ M_SetAnimation3(self, fire_chain_run_move, context);
17989
+ return;
17990
+ }
17991
+ }
17992
+ M_SetAnimation3(self, fire_chain_move2, context);
17993
+ }
17994
+ function guncmdr_refire_chain(self, context) {
17995
+ monster_done_dodge2(self);
17996
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
17997
+ if (self.enemy && self.enemy.health > 0) {
17998
+ if (visible(self, self.enemy, context.trace)) {
17999
+ if (Math.random() <= 0.5) {
18000
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
18001
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18002
+ if (dist > 400 && ai_move(self, 8)) {
18003
+ M_SetAnimation3(self, fire_chain_run_move, context);
18004
+ return;
18005
+ }
18006
+ }
18007
+ M_SetAnimation3(self, fire_chain_move2, context);
18008
+ return;
18009
+ }
18010
+ }
18011
+ }
18012
+ M_SetAnimation3(self, endfire_chain_move2, context);
18013
+ }
18014
+ function GunnerCmdrFire(self, context) {
18015
+ if (!self.enemy || !self.enemy.inUse) return;
18016
+ let flash_number;
18017
+ if (self.monsterinfo.current_move === fire_chain_dodge_right_move || self.monsterinfo.current_move === fire_chain_dodge_left_move) {
18018
+ flash_number = MZ2_GUNCMDR_CHAINGUN_2;
18019
+ } else {
18020
+ flash_number = MZ2_GUNCMDR_CHAINGUN_1;
18021
+ }
18022
+ const { forward, right } = angleVectors(self.angles);
18023
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
18024
+ let aim = normalizeVec3(subtractVec3(self.enemy.origin, start));
18025
+ const randomAim = { ...aim };
18026
+ for (let i = 0; i < 3; i++) {
18027
+ randomAim.x += (Math.random() - 0.5) * 0.05;
18028
+ randomAim.y += (Math.random() - 0.5) * 0.05;
18029
+ randomAim.z += (Math.random() - 0.5) * 0.05;
18030
+ }
18031
+ aim = normalizeVec3(randomAim);
18032
+ monster_fire_flechette(self, start, aim, 4, 800, flash_number, context);
18033
+ }
18034
+ function GunnerCmdrGrenade(self, context) {
18035
+ if (!self.enemy || !self.enemy.inUse) return;
18036
+ let spread = 0;
18037
+ let flash_number = 0;
18038
+ const frameIndex = self.frame;
18039
+ if (self.monsterinfo.current_move === attack_mortar_move) {
18040
+ const offset = frameIndex - attack_mortar_move.firstframe;
18041
+ if (offset === 4) {
18042
+ spread = -0.1;
18043
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_1;
18044
+ } else if (offset === 7) {
18045
+ spread = 0;
18046
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_2;
18047
+ } else if (offset === 10) {
18048
+ spread = 0.1;
18049
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_3;
18050
+ }
18051
+ } else if (self.monsterinfo.current_move === attack_grenade_back_move) {
18052
+ const offset = frameIndex - attack_grenade_back_move.firstframe;
18053
+ if (offset === 2) {
18054
+ spread = -0.1;
18055
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_1;
18056
+ } else if (offset === 5) {
18057
+ spread = 0;
18058
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_2;
18059
+ } else if (offset === 8) {
18060
+ spread = 0.1;
18061
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_3;
18062
+ }
18063
+ }
18064
+ if (flash_number === 0) return;
18065
+ const { forward, right, up } = angleVectors(self.angles);
18066
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
18067
+ let aim;
18068
+ let pitch = 0;
18069
+ const target = self.enemy.origin;
18070
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_FRONT_1 && flash_number <= MZ2_GUNCMDR_GRENADE_FRONT_3) {
18071
+ pitch -= 0.05;
18072
+ }
18073
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3) {
18074
+ let distVector = subtractVec3(target, self.origin);
18075
+ let dist = lengthVec3(distVector);
18076
+ if (dist > 512 && distVector.z < 64 && distVector.z > -64) {
18077
+ const newZ = distVector.z + (dist - 512);
18078
+ distVector = { ...distVector, z: newZ };
18079
+ }
18080
+ distVector = normalizeVec3(distVector);
18081
+ let p = distVector.z;
18082
+ if (p > 0.4) p = 0.4;
18083
+ else if (p < -0.5) p = -0.5;
18084
+ if (self.enemy.absmin.z - self.absmax.z > 16) {
18085
+ p += 0.5;
18086
+ }
18087
+ pitch += p;
18088
+ }
18089
+ aim = normalizeVec3(addVec3(addVec3(forward, scaleVec3(right, spread)), scaleVec3(up, pitch)));
18090
+ let speed = flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3 ? MORTAR_SPEED : GRENADE_SPEED;
18091
+ createGrenade(context, self, start, aim, 50, speed);
18092
+ }
18093
+ function guncmdr_grenade_mortar_resume(self, context) {
18094
+ M_SetAnimation3(self, attack_mortar_move, context);
18095
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
18096
+ self.frame = self.count;
18097
+ }
18098
+ function guncmdr_grenade_back_dodge_resume(self, context) {
18099
+ M_SetAnimation3(self, attack_grenade_back_move, context);
18100
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
18101
+ self.frame = self.count;
18102
+ }
18103
+ function guncmdr_kick_finished(self, context) {
18104
+ self.monsterinfo.melee_debounce_time = context.timeSeconds + 3;
18105
+ if (self.monsterinfo.attack) {
18106
+ self.monsterinfo.attack(self, context);
18107
+ }
18108
+ }
18109
+ function guncmdr_kick(self, context) {
18110
+ if (!self.enemy) return;
18111
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18112
+ if (dist < 100) {
18113
+ if (self.enemy.client && self.enemy.velocity.z < 270) {
18114
+ self.enemy.velocity = { ...self.enemy.velocity, z: 270 };
18115
+ }
18116
+ }
18117
+ }
18118
+ function monster_duck_down(self, context) {
18119
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) return;
18120
+ self.monsterinfo.aiflags |= 2048 /* Ducked */;
18121
+ self.maxs = { ...self.maxs, z: self.maxs.z - 32 };
18122
+ self.takedamage = true;
18123
+ self.monsterinfo.pausetime = context.timeSeconds + 1;
18124
+ }
18125
+ function monster_duck_hold(self, context) {
18126
+ if (context.timeSeconds >= self.monsterinfo.pausetime) {
18127
+ self.monsterinfo.aiflags &= ~128 /* HoldFrame */;
18128
+ } else {
18129
+ self.monsterinfo.aiflags |= 128 /* HoldFrame */;
18130
+ }
18131
+ }
18132
+ function monster_duck_up(self, context) {
18133
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
18134
+ self.maxs = { ...self.maxs, z: self.maxs.z + 32 };
18135
+ self.takedamage = true;
18136
+ }
18137
+ function guncmdr_jump_now(self, context) {
18138
+ const { forward, up } = angleVectors(self.angles);
18139
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 100));
18140
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 300));
18141
+ }
18142
+ function guncmdr_jump2_now(self, context) {
18143
+ const { forward, up } = angleVectors(self.angles);
18144
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 150));
18145
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 400));
18146
+ }
18147
+ function guncmdr_jump_wait_land(self, context) {
18148
+ if (self.groundentity === null) {
18149
+ self.monsterinfo.nextframe = self.frame;
18150
+ } else {
18151
+ self.monsterinfo.nextframe = self.frame + 1;
18152
+ }
18153
+ }
18154
+ function GunnerCmdrCounter(self, context) {
18155
+ context.engine.sound?.(self, 0, "weapons/rocklx1a.wav", 1, 1, 0);
18156
+ }
18157
+ function guncmdr_attack(self, context) {
18158
+ monster_done_dodge2(self);
18159
+ const d = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18160
+ const { forward, right } = angleVectors(self.angles);
18161
+ const RANGE_GRENADE = 100;
18162
+ const RANGE_GRENADE_MORTAR = 525;
18163
+ const RANGE_MELEE3 = 64;
18164
+ if (d < RANGE_MELEE3 && (self.monsterinfo.melee_debounce_time === void 0 || self.monsterinfo.melee_debounce_time < context.timeSeconds)) {
18165
+ M_SetAnimation3(self, attack_kick_move, context);
18166
+ } else if (d <= RANGE_GRENADE && M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_CHAINGUN_1], context)) {
18167
+ M_SetAnimation3(self, attack_chain_move3, context);
18168
+ } else if ((d >= RANGE_GRENADE_MORTAR || Math.abs(self.absmin.z - self.enemy.absmax.z) > 64) && M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_GRENADE_MORTAR_1], context)) {
18169
+ M_SetAnimation3(self, attack_mortar_move, context);
18170
+ monster_duck_down(self, context);
18171
+ } else if (M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_GRENADE_FRONT_1], context) && !(self.monsterinfo.aiflags & 1 /* StandGround */)) {
18172
+ M_SetAnimation3(self, attack_grenade_back_move, context);
18173
+ } else if (self.monsterinfo.aiflags & 1 /* StandGround */) {
18174
+ M_SetAnimation3(self, attack_chain_move3, context);
18175
+ } else {
18176
+ M_SetAnimation3(self, attack_chain_move3, context);
18177
+ }
18178
+ }
18179
+ function guncmdr_pain5_to_death1(self, context) {
18180
+ if (self.health < 0) M_SetAnimation3(self, death1_move3, context);
18181
+ }
18182
+ function guncmdr_pain5_to_death2(self, context) {
18183
+ if (self.health < 0 && Math.random() < 0.5) M_SetAnimation3(self, death2_move3, context);
18184
+ }
18185
+ function guncmdr_pain6_to_death6(self, context) {
18186
+ if (self.health < 0) M_SetAnimation3(self, death6_move, context);
18187
+ }
18188
+ function guncmdr_shrink(self, context) {
18189
+ self.maxs = { ...self.maxs, z: -4 * (self.monsterinfo.scale || 1) };
18190
+ }
18191
+ function guncmdr_dead(self, context) {
18192
+ const scale = self.monsterinfo.scale || 1;
18193
+ self.mins = scaleVec3({ x: -16, y: -16, z: -24 }, scale);
18194
+ self.maxs = scaleVec3({ x: 16, y: 16, z: -8 }, scale);
18195
+ self.nextthink = -1;
18196
+ self.solid = 0 /* Not */;
18197
+ }
18198
+ function guncmdr_pain(self, context) {
18199
+ monster_done_dodge2(self);
18200
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move || self.monsterinfo.current_move === duck_attack_move) {
18201
+ return;
18202
+ }
18203
+ if (context.timeSeconds < self.pain_debounce_time) {
18204
+ return;
18205
+ }
18206
+ self.pain_debounce_time = context.timeSeconds + 3;
18207
+ if (Math.random() < 0.5) {
18208
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain2.wav", 1, 1, 0);
18209
+ } else {
18210
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain1.wav", 1, 1, 0);
18211
+ }
18212
+ if (!M_ShouldReactToPain(self)) return;
18213
+ const r = Math.floor(Math.random() * 7);
18214
+ switch (r) {
18215
+ case 0:
18216
+ M_SetAnimation3(self, pain1_move8, context);
18217
+ break;
18218
+ case 1:
18219
+ M_SetAnimation3(self, pain2_move8, context);
18220
+ break;
18221
+ case 2:
18222
+ M_SetAnimation3(self, pain3_move7, context);
18223
+ break;
18224
+ case 3:
18225
+ M_SetAnimation3(self, pain4_move2, context);
18226
+ break;
18227
+ case 4:
18228
+ M_SetAnimation3(self, pain5_move2, context);
18229
+ break;
18230
+ case 5:
18231
+ M_SetAnimation3(self, pain6_move2, context);
18232
+ break;
18233
+ default:
18234
+ M_SetAnimation3(self, pain7_move, context);
18235
+ break;
18236
+ }
18237
+ self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
18238
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) monster_duck_up(self, context);
18239
+ }
18240
+ function guncmdr_die(self, inflictor, attacker, damage, point, context) {
18241
+ if (M_CheckGib(self, damage)) {
18242
+ context.engine.sound?.(self, 0, "misc/udeath.wav", 1, 1, 0);
18243
+ throwGibs(context, self.origin, [{
18244
+ count: 1,
18245
+ model: "models/monsters/gunner/gibs/chest.md2",
18246
+ flags: 1 /* Metallic */
18247
+ }]);
18248
+ self.deadflag = 2 /* Dead */;
18249
+ return;
18250
+ }
18251
+ if (self.deadflag) return;
18252
+ context.engine.sound?.(self, 0, "guncmdr/gcdrdeath1.wav", 1, 1, 0);
18253
+ self.deadflag = 2 /* Dead */;
18254
+ self.takedamage = true;
18255
+ const r = Math.floor(Math.random() * 7);
18256
+ switch (r) {
18257
+ case 0:
18258
+ M_SetAnimation3(self, death1_move3, context);
18259
+ break;
18260
+ case 1:
18261
+ M_SetAnimation3(self, death2_move3, context);
18262
+ break;
18263
+ case 2:
18264
+ M_SetAnimation3(self, death3_move, context);
18265
+ break;
18266
+ case 3:
18267
+ M_SetAnimation3(self, death4_move, context);
18268
+ break;
18269
+ case 4:
18270
+ M_SetAnimation3(self, death5_move, context);
18271
+ break;
18272
+ case 5:
18273
+ M_SetAnimation3(self, death6_move, context);
18274
+ break;
18275
+ default:
18276
+ M_SetAnimation3(self, death7_move, context);
18277
+ break;
18278
+ }
18279
+ }
18280
+ function guncmdr_setskin(self, context) {
18281
+ if (self.health < self.max_health / 2) {
18282
+ self.skin |= 1;
18283
+ } else {
18284
+ self.skin &= ~1;
18285
+ }
18286
+ }
18287
+ function guncmdr_duck(self, eta, context) {
18288
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move) return false;
18289
+ if (self.monsterinfo.current_move === fire_chain_dodge_left_move || self.monsterinfo.current_move === fire_chain_dodge_right_move || self.monsterinfo.current_move === attack_grenade_back_dodge_left_move || self.monsterinfo.current_move === attack_grenade_back_dodge_right_move || self.monsterinfo.current_move === attack_mortar_dodge_move) {
18290
+ monster_duck_up(self, context);
18291
+ return false;
18292
+ }
18293
+ M_SetAnimation3(self, duck_attack_move, context);
18294
+ return true;
18295
+ }
18296
+ function guncmdr_sidestep(self, context) {
18297
+ if (self.monsterinfo.current_move === fire_chain_move2 || self.monsterinfo.current_move === fire_chain_run_move) {
18298
+ M_SetAnimation3(self, Math.random() < 0.5 ? fire_chain_dodge_right_move : fire_chain_dodge_left_move, context);
18299
+ return true;
18300
+ }
18301
+ if (self.monsterinfo.current_move === attack_grenade_back_move) {
18302
+ self.count = self.frame;
18303
+ M_SetAnimation3(self, Math.random() < 0.5 ? attack_grenade_back_dodge_right_move : attack_grenade_back_dodge_left_move, context);
18304
+ return true;
18305
+ }
18306
+ if (self.monsterinfo.current_move === attack_mortar_move) {
18307
+ self.count = self.frame;
18308
+ M_SetAnimation3(self, attack_mortar_dodge_move, context);
18309
+ return true;
18310
+ }
18311
+ if (self.monsterinfo.current_move === run_move20) {
18312
+ M_SetAnimation3(self, run_move20, context);
18313
+ return true;
18314
+ }
18315
+ return false;
18316
+ }
18317
+ fidget_move4 = {
18318
+ firstframe: 201,
18319
+ lastframe: 254,
18320
+ frames: Array(54).fill({ ai: monster_ai_stand24, dist: 0 }),
18321
+ endfunc: guncmdr_stand
18322
+ };
18323
+ fidget_move4.frames[6] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18324
+ fidget_move4.frames[10] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18325
+ stand_move21 = {
18326
+ firstframe: 101,
18327
+ lastframe: 140,
18328
+ frames: Array(40).fill({ ai: monster_ai_stand24, dist: 0 }),
18329
+ endfunc: null
18330
+ };
18331
+ var stand_fidget = (self, context) => guncmdr_fidget(self, context);
18332
+ [9, 19, 29, 39].forEach((i) => {
18333
+ stand_move21.frames[i] = { ai: monster_ai_stand24, dist: 0, think: stand_fidget };
18334
+ });
18335
+ walk_move18 = {
18336
+ firstframe: 101,
18337
+ lastframe: 124,
18338
+ frames: [
18339
+ { ai: monster_ai_walk23, dist: 1.5 },
18340
+ { ai: monster_ai_walk23, dist: 2.5 },
18341
+ { ai: monster_ai_walk23, dist: 3 },
18342
+ { ai: monster_ai_walk23, dist: 2.5 },
18343
+ { ai: monster_ai_walk23, dist: 2.3 },
18344
+ { ai: monster_ai_walk23, dist: 3 },
18345
+ { ai: monster_ai_walk23, dist: 2.8 },
18346
+ { ai: monster_ai_walk23, dist: 3.6 },
18347
+ { ai: monster_ai_walk23, dist: 2.8 },
18348
+ { ai: monster_ai_walk23, dist: 2.5 },
18349
+ { ai: monster_ai_walk23, dist: 2.3 },
18350
+ { ai: monster_ai_walk23, dist: 4.3 },
18351
+ { ai: monster_ai_walk23, dist: 3 },
18352
+ { ai: monster_ai_walk23, dist: 1.5 },
18353
+ { ai: monster_ai_walk23, dist: 2.5 },
18354
+ { ai: monster_ai_walk23, dist: 3.3 },
18355
+ { ai: monster_ai_walk23, dist: 2.8 },
18356
+ { ai: monster_ai_walk23, dist: 3 },
18357
+ { ai: monster_ai_walk23, dist: 2 },
18358
+ { ai: monster_ai_walk23, dist: 2 },
18359
+ { ai: monster_ai_walk23, dist: 3.3 },
18360
+ { ai: monster_ai_walk23, dist: 3.6 },
18361
+ { ai: monster_ai_walk23, dist: 3.4 },
18362
+ { ai: monster_ai_walk23, dist: 2.8 }
18363
+ ],
18364
+ endfunc: null
18365
+ };
18366
+ run_move20 = {
18367
+ firstframe: 101,
18368
+ lastframe: 106,
18369
+ frames: [
18370
+ { ai: monster_ai_run24, dist: 15, think: monster_done_dodge2 },
18371
+ { ai: monster_ai_run24, dist: 16 },
18372
+ { ai: monster_ai_run24, dist: 20 },
18373
+ { ai: monster_ai_run24, dist: 18 },
18374
+ { ai: monster_ai_run24, dist: 24 },
18375
+ { ai: monster_ai_run24, dist: 13.5 }
18376
+ ],
18377
+ endfunc: null
18378
+ };
18379
+ attack_chain_move3 = {
18380
+ firstframe: 101,
18381
+ lastframe: 106,
18382
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0 }),
18383
+ endfunc: guncmdr_fire_chain
18384
+ };
18385
+ attack_chain_move3.frames[4].think = guncmdr_opengun;
18386
+ fire_chain_move2 = {
18387
+ firstframe: 107,
18388
+ lastframe: 112,
18389
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0, think: GunnerCmdrFire }),
18390
+ endfunc: guncmdr_refire_chain
18391
+ };
18392
+ fire_chain_run_move = {
18393
+ firstframe: 201,
18394
+ lastframe: 206,
18395
+ frames: [
18396
+ { ai: monster_ai_charge25, dist: 15, think: GunnerCmdrFire },
18397
+ { ai: monster_ai_charge25, dist: 16, think: GunnerCmdrFire },
18398
+ { ai: monster_ai_charge25, dist: 20, think: GunnerCmdrFire },
18399
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18400
+ { ai: monster_ai_charge25, dist: 24, think: GunnerCmdrFire },
18401
+ { ai: monster_ai_charge25, dist: 13.5, think: GunnerCmdrFire }
18402
+ ],
18403
+ endfunc: guncmdr_refire_chain
18404
+ };
18405
+ fire_chain_dodge_right_move = {
18406
+ firstframe: 401,
18407
+ lastframe: 405,
18408
+ frames: [
18409
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18410
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18411
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18412
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18413
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18414
+ ],
18415
+ endfunc: guncmdr_refire_chain
18416
+ };
18417
+ fire_chain_dodge_left_move = {
18418
+ firstframe: 501,
18419
+ lastframe: 505,
18420
+ frames: [
18421
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18422
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18423
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18424
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18425
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18426
+ ],
18427
+ endfunc: guncmdr_refire_chain
18428
+ };
18429
+ endfire_chain_move2 = {
18430
+ firstframe: 118,
18431
+ lastframe: 124,
18432
+ frames: Array(7).fill({ ai: monster_ai_charge25, dist: 0 }),
18433
+ endfunc: guncmdr_run
18434
+ };
18435
+ endfire_chain_move2.frames[2].think = guncmdr_opengun;
18436
+ attack_mortar_move = {
18437
+ firstframe: 201,
18438
+ lastframe: 221,
18439
+ frames: Array(21).fill({ ai: monster_ai_charge25, dist: 0 }),
18440
+ endfunc: guncmdr_run
18441
+ };
18442
+ attack_mortar_move.frames[4].think = GunnerCmdrGrenade;
18443
+ attack_mortar_move.frames[7].think = GunnerCmdrGrenade;
18444
+ attack_mortar_move.frames[10].think = GunnerCmdrGrenade;
18445
+ attack_mortar_move.frames[13].think = monster_duck_up;
18446
+ attack_mortar_dodge_move = {
18447
+ firstframe: 0,
18448
+ lastframe: 5,
18449
+ frames: [
18450
+ { ai: monster_ai_charge25, dist: 11 },
18451
+ { ai: monster_ai_charge25, dist: 12 },
18452
+ { ai: monster_ai_charge25, dist: 16 },
18453
+ { ai: monster_ai_charge25, dist: 16 },
18454
+ { ai: monster_ai_charge25, dist: 12 },
18455
+ { ai: monster_ai_charge25, dist: 11 }
18456
+ ],
18457
+ endfunc: guncmdr_grenade_mortar_resume
18458
+ };
18459
+ attack_grenade_back_move = {
18460
+ firstframe: 302,
18461
+ lastframe: 321,
18462
+ frames: [
18463
+ { ai: monster_ai_charge25, dist: -2 },
18464
+ { ai: monster_ai_charge25, dist: -1.5 },
18465
+ { ai: monster_ai_charge25, dist: -0.5, think: GunnerCmdrGrenade },
18466
+ { ai: monster_ai_charge25, dist: -6 },
18467
+ { ai: monster_ai_charge25, dist: -4 },
18468
+ { ai: monster_ai_charge25, dist: -2.5, think: GunnerCmdrGrenade },
18469
+ { ai: monster_ai_charge25, dist: -7 },
18470
+ { ai: monster_ai_charge25, dist: -3.5 },
18471
+ { ai: monster_ai_charge25, dist: -1.1, think: GunnerCmdrGrenade },
18472
+ { ai: monster_ai_charge25, dist: -4.6 },
18473
+ { ai: monster_ai_charge25, dist: 1.9 },
18474
+ { ai: monster_ai_charge25, dist: 1 },
18475
+ { ai: monster_ai_charge25, dist: -4.5 },
18476
+ { ai: monster_ai_charge25, dist: 3.2 },
18477
+ { ai: monster_ai_charge25, dist: 4.4 },
18478
+ { ai: monster_ai_charge25, dist: -6.5 },
18479
+ { ai: monster_ai_charge25, dist: -6.1 },
18480
+ { ai: monster_ai_charge25, dist: 3 },
18481
+ { ai: monster_ai_charge25, dist: -0.7 },
18482
+ { ai: monster_ai_charge25, dist: -1 }
18483
+ ],
18484
+ endfunc: guncmdr_run
18485
+ };
18486
+ attack_grenade_back_dodge_right_move = {
18487
+ firstframe: 601,
18488
+ lastframe: 605,
18489
+ frames: [
18490
+ { ai: monster_ai_charge25, dist: 10.2 },
18491
+ { ai: monster_ai_charge25, dist: 18 },
18492
+ { ai: monster_ai_charge25, dist: 7 },
18493
+ { ai: monster_ai_charge25, dist: 7.2 },
18494
+ { ai: monster_ai_charge25, dist: -2 }
18495
+ ],
18496
+ endfunc: guncmdr_grenade_back_dodge_resume
18497
+ };
18498
+ attack_grenade_back_dodge_left_move = {
18499
+ firstframe: 701,
18500
+ lastframe: 705,
18501
+ frames: [
18502
+ { ai: monster_ai_charge25, dist: 10.2 },
18503
+ { ai: monster_ai_charge25, dist: 18 },
18504
+ { ai: monster_ai_charge25, dist: 7 },
18505
+ { ai: monster_ai_charge25, dist: 7.2 },
18506
+ { ai: monster_ai_charge25, dist: -2 }
18507
+ ],
18508
+ endfunc: guncmdr_grenade_back_dodge_resume
18509
+ };
18510
+ attack_kick_move = {
18511
+ firstframe: 801,
18512
+ lastframe: 808,
18513
+ frames: [
18514
+ { ai: monster_ai_charge25, dist: -7.7 },
18515
+ { ai: monster_ai_charge25, dist: -4.9 },
18516
+ { ai: monster_ai_charge25, dist: 12.6, think: guncmdr_kick },
18517
+ { ai: monster_ai_charge25, dist: 0 },
18518
+ { ai: monster_ai_charge25, dist: -3 },
18519
+ { ai: monster_ai_charge25, dist: 0 },
18520
+ { ai: monster_ai_charge25, dist: -4.1 },
18521
+ { ai: monster_ai_charge25, dist: 8.6 }
18522
+ ],
18523
+ endfunc: guncmdr_kick_finished
18524
+ };
18525
+ duck_attack_move = {
18526
+ firstframe: 901,
18527
+ lastframe: 919,
18528
+ frames: [
18529
+ { ai: monster_ai_move24, dist: 3.6 },
18530
+ { ai: monster_ai_move24, dist: 5.6, think: monster_duck_down },
18531
+ { ai: monster_ai_move24, dist: 8.4 },
18532
+ { ai: monster_ai_move24, dist: 2, think: monster_duck_hold },
18533
+ { ai: monster_ai_charge25, dist: 0 },
18534
+ { ai: monster_ai_charge25, dist: 0 },
18535
+ { ai: monster_ai_charge25, dist: 0 },
18536
+ { ai: monster_ai_charge25, dist: 0 },
18537
+ { ai: monster_ai_charge25, dist: 0 },
18538
+ { ai: monster_ai_charge25, dist: 0 },
18539
+ { ai: monster_ai_charge25, dist: 0 },
18540
+ { ai: monster_ai_charge25, dist: 9.5, think: GunnerCmdrCounter },
18541
+ { ai: monster_ai_charge25, dist: -1.5 },
18542
+ { ai: monster_ai_charge25, dist: 0 },
18543
+ { ai: monster_ai_charge25, dist: 0, think: monster_duck_up },
18544
+ { ai: monster_ai_charge25, dist: 0 },
18545
+ { ai: monster_ai_charge25, dist: 11 },
18546
+ { ai: monster_ai_charge25, dist: 2 },
18547
+ { ai: monster_ai_charge25, dist: 5.6 }
18548
+ ],
18549
+ endfunc: guncmdr_run
18550
+ };
18551
+ jump_move3 = {
18552
+ firstframe: 0,
18553
+ lastframe: 9,
18554
+ frames: [
18555
+ { ai: monster_ai_move24, dist: 0 },
18556
+ { ai: monster_ai_move24, dist: 0 },
18557
+ { ai: monster_ai_move24, dist: 0 },
18558
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_now },
18559
+ { ai: monster_ai_move24, dist: 0 },
18560
+ { ai: monster_ai_move24, dist: 0 },
18561
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18562
+ { ai: monster_ai_move24, dist: 0 },
18563
+ { ai: monster_ai_move24, dist: 0 },
18564
+ { ai: monster_ai_move24, dist: 0 }
18565
+ ],
18566
+ endfunc: guncmdr_run
18567
+ };
18568
+ jump2_move = {
18569
+ firstframe: 0,
18570
+ lastframe: 9,
18571
+ frames: [
18572
+ { ai: monster_ai_move24, dist: -8 },
18573
+ { ai: monster_ai_move24, dist: -4 },
18574
+ { ai: monster_ai_move24, dist: -4 },
18575
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump2_now },
18576
+ { ai: monster_ai_move24, dist: 0 },
18577
+ { ai: monster_ai_move24, dist: 0 },
18578
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18579
+ { ai: monster_ai_move24, dist: 0 },
18580
+ { ai: monster_ai_move24, dist: 0 },
18581
+ { ai: monster_ai_move24, dist: 0 }
18582
+ ],
18583
+ endfunc: guncmdr_run
18584
+ };
18585
+ pain1_move8 = { firstframe: 101, lastframe: 104, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18586
+ pain2_move8 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18587
+ pain3_move7 = { firstframe: 301, lastframe: 304, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18588
+ pain4_move2 = { firstframe: 401, lastframe: 415, frames: Array(15).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18589
+ pain5_move2 = { firstframe: 501, lastframe: 524, frames: Array(24).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18590
+ pain5_move2.frames[5].think = guncmdr_pain5_to_death2;
18591
+ pain5_move2.frames[8].think = guncmdr_pain5_to_death1;
18592
+ pain6_move2 = { firstframe: 601, lastframe: 632, frames: Array(32).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18593
+ pain6_move2.frames[6].think = guncmdr_pain6_to_death6;
18594
+ pain7_move = { firstframe: 701, lastframe: 714, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18595
+ death1_move3 = { firstframe: 101, lastframe: 118, frames: Array(18).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18596
+ death2_move3 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18597
+ death3_move = { firstframe: 301, lastframe: 321, frames: Array(21).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18598
+ death3_move.frames[2].think = guncmdr_shrink;
18599
+ death4_move = { firstframe: 401, lastframe: 436, frames: Array(36).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18600
+ death4_move.frames[2].think = guncmdr_shrink;
18601
+ death5_move = { firstframe: 501, lastframe: 528, frames: Array(28).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18602
+ death6_move = { firstframe: 601, lastframe: 614, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18603
+ death6_move.frames[0].think = guncmdr_shrink;
18604
+ death7_move = { firstframe: 701, lastframe: 730, frames: Array(30).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18605
+ death7_move.frames[2].think = guncmdr_shrink;
18606
+ function SP_monster_guncmdr(self, context) {
18607
+ if (!M_AllowSpawn(self, context.entities)) {
18608
+ context.entities.free(self);
18609
+ return;
18610
+ }
18611
+ self.movetype = 5 /* Step */;
18612
+ self.solid = 2 /* BoundingBox */;
18613
+ self.model = "models/monsters/gunner/tris.md2";
18614
+ self.modelindex = context.entities.modelIndex("models/monsters/gunner/tris.md2");
18615
+ self.monsterinfo.scale = 1.25;
18616
+ self.mins = { x: -16, y: -16, z: -24 };
18617
+ self.maxs = { x: 16, y: 16, z: 36 };
18618
+ self.skin = 2;
18619
+ const healthMultiplier = context.keyValues["health_multiplier"] ? parseFloat(context.keyValues["health_multiplier"]) : 1;
18620
+ self.health = 325 * healthMultiplier;
18621
+ self.max_health = self.health;
18622
+ self.mass = 255;
18623
+ self.pain = (s, o, k, d) => guncmdr_pain(s, context.entities);
18624
+ self.die = (s, i, a, d, p) => guncmdr_die(s, i, a, d, p, context.entities);
18625
+ self.monsterinfo.stand = (s) => guncmdr_stand(s, context.entities);
18626
+ self.monsterinfo.walk = (s) => guncmdr_walk(s, context.entities);
18627
+ self.monsterinfo.run = (s) => guncmdr_run(s, context.entities);
18628
+ self.monsterinfo.dodge = (s, a, e) => M_MonsterDodge(s, a, e);
18629
+ self.monsterinfo.duck = (s, e) => guncmdr_duck(s, e, context.entities);
18630
+ self.monsterinfo.unduck = (s) => monster_duck_up(s, context.entities);
18631
+ self.monsterinfo.sidestep = (s) => guncmdr_sidestep(s, context.entities);
18632
+ self.monsterinfo.attack = (s) => guncmdr_attack(s, context.entities);
18633
+ self.monsterinfo.sight = (s, o) => guncmdr_sight(s, o, context.entities);
18634
+ self.monsterinfo.search = (s) => guncmdr_search(s, context.entities);
18635
+ self.monsterinfo.setskin = (s) => guncmdr_setskin(s, context.entities);
18636
+ self.monsterinfo.power_armor_power = 200;
18637
+ self.monsterinfo.power_armor_type = 1;
18638
+ context.entities.linkentity(self);
18639
+ M_SetAnimation3(self, stand_move21, context.entities);
18640
+ self.think = monster_think;
18641
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK28;
18642
+ }
18643
+ function registerGunCommanderSpawns(registry) {
18644
+ registry.register("monster_guncmdr", SP_monster_guncmdr);
18645
+ }
18646
+
18647
+ // src/entities/monsters/guardian.ts
18648
+ init_esm();
18649
+ var MONSTER_TICK29 = 0.1;
18650
+ var MELEE_DISTANCE6 = 80;
18651
+ var FRAME_idle12 = 76;
18652
+ var FRAME_idle52 = 127;
18653
+ var FRAME_walk13 = 160;
18654
+ var FRAME_walk19 = 178;
18655
+ var FRAME_pain1_1 = 68;
18656
+ var FRAME_pain1_8 = 75;
18657
+ var FRAME_atk1_out1 = 40;
18658
+ var FRAME_atk1_out3 = 42;
18659
+ var FRAME_atk1_spin1 = 184;
18660
+ var FRAME_atk1_spin12 = 195;
18661
+ var FRAME_atk1_spin15 = 198;
18662
+ var FRAME_atk1_in1 = 128;
18663
+ var FRAME_atk1_in3 = 130;
18664
+ var FRAME_atk2_out1 = 43;
18665
+ var FRAME_atk2_out7 = 49;
18666
+ var FRAME_atk2_fire1 = 199;
18667
+ var FRAME_atk2_fire4 = 202;
18668
+ var FRAME_atk2_in1 = 214;
18669
+ var FRAME_atk2_in12 = 225;
18670
+ var FRAME_kick_in1 = 131;
18671
+ var FRAME_kick_in13 = 143;
18672
+ var FRAME_death12 = 14;
18673
+ var FRAME_death26 = 39;
18674
+ var sound_step2 = "zortemp/step.wav";
18675
+ var sound_charge2 = "weapons/hyprbu1a.wav";
18676
+ var sound_laser = "weapons/laser2.wav";
18677
+ var guardian_move_stand;
18678
+ var guardian_move_walk;
18679
+ var guardian_move_run;
18680
+ var guardian_move_pain1;
18681
+ var guardian_atk1_out;
18682
+ var guardian_move_atk1_spin;
18683
+ var guardian_move_atk1_in;
18684
+ var guardian_move_atk2_out;
18685
+ var guardian_move_atk2_fire;
18686
+ var guardian_move_atk2_in;
18687
+ var guardian_move_kick;
18688
+ var guardian_move_death;
18689
+ var guardian_move_atk1_spin_loop;
18690
+ function guardian_ai_stand(self, dist, context) {
18691
+ ai_stand(self, MONSTER_TICK29, context);
18692
+ }
18693
+ function guardian_ai_walk(self, dist, context) {
18694
+ ai_walk(self, dist, MONSTER_TICK29, context);
18695
+ }
18696
+ function guardian_ai_run(self, dist, context) {
18697
+ ai_run(self, dist, MONSTER_TICK29, context);
18698
+ }
18699
+ function guardian_ai_charge(self, dist, context) {
18700
+ ai_charge(self, dist, MONSTER_TICK29, context);
18701
+ }
18702
+ function guardian_ai_move(self, dist, context) {
18703
+ ai_move(self, dist);
18704
+ }
18705
+ function guardian_stand(self, context) {
18706
+ M_SetAnimation3(self, guardian_move_stand, context);
18707
+ }
18708
+ var guardian_frames_stand = Array(52).fill({ ai: guardian_ai_stand, dist: 0 });
18709
+ guardian_move_stand = {
18710
+ firstframe: FRAME_idle12,
18711
+ lastframe: FRAME_idle52,
18712
+ frames: guardian_frames_stand,
18713
+ endfunc: null
18714
+ };
18715
+ function guardian_footstep(self, context) {
18716
+ context.sound(self, 2, sound_step2, 1, 1, 0);
18717
+ }
18718
+ var guardian_frames_walk = [
18719
+ { ai: guardian_ai_walk, dist: 8 },
18720
+ { ai: guardian_ai_walk, dist: 8 },
18721
+ { ai: guardian_ai_walk, dist: 8 },
18722
+ { ai: guardian_ai_walk, dist: 8 },
18723
+ { ai: guardian_ai_walk, dist: 8 },
18724
+ { ai: guardian_ai_walk, dist: 8 },
18725
+ { ai: guardian_ai_walk, dist: 8 },
18726
+ { ai: guardian_ai_walk, dist: 8, think: guardian_footstep },
18727
+ { ai: guardian_ai_walk, dist: 8 },
18728
+ { ai: guardian_ai_walk, dist: 8 },
18729
+ { ai: guardian_ai_walk, dist: 8 },
18730
+ { ai: guardian_ai_walk, dist: 8 },
18731
+ { ai: guardian_ai_walk, dist: 8 },
18732
+ { ai: guardian_ai_walk, dist: 8 },
18733
+ { ai: guardian_ai_walk, dist: 8 },
18734
+ { ai: guardian_ai_walk, dist: 8 },
18735
+ { ai: guardian_ai_walk, dist: 8 },
18736
+ { ai: guardian_ai_walk, dist: 8, think: guardian_footstep },
18737
+ { ai: guardian_ai_walk, dist: 8 }
18738
+ ];
18739
+ guardian_move_walk = {
18740
+ firstframe: FRAME_walk13,
18741
+ lastframe: FRAME_walk19,
18742
+ frames: guardian_frames_walk,
18743
+ endfunc: null
18744
+ };
18745
+ function guardian_walk(self, context) {
18746
+ M_SetAnimation3(self, guardian_move_walk, context);
18747
+ }
18748
+ var guardian_frames_run = [
18749
+ { ai: guardian_ai_run, dist: 8 },
18750
+ { ai: guardian_ai_run, dist: 8 },
18751
+ { ai: guardian_ai_run, dist: 8 },
18752
+ { ai: guardian_ai_run, dist: 8 },
18753
+ { ai: guardian_ai_run, dist: 8 },
18754
+ { ai: guardian_ai_run, dist: 8 },
18755
+ { ai: guardian_ai_run, dist: 8 },
18756
+ { ai: guardian_ai_run, dist: 8, think: guardian_footstep },
18757
+ { ai: guardian_ai_run, dist: 8 },
18758
+ { ai: guardian_ai_run, dist: 8 },
18759
+ { ai: guardian_ai_run, dist: 8 },
18760
+ { ai: guardian_ai_run, dist: 8 },
18761
+ { ai: guardian_ai_run, dist: 8 },
18762
+ { ai: guardian_ai_run, dist: 8 },
18763
+ { ai: guardian_ai_run, dist: 8 },
18764
+ { ai: guardian_ai_run, dist: 8 },
18765
+ { ai: guardian_ai_run, dist: 8 },
18766
+ { ai: guardian_ai_run, dist: 8, think: guardian_footstep },
18767
+ { ai: guardian_ai_run, dist: 8 }
18768
+ ];
18769
+ guardian_move_run = {
18770
+ firstframe: FRAME_walk13,
18771
+ lastframe: FRAME_walk19,
18772
+ frames: guardian_frames_run,
18773
+ endfunc: null
18774
+ };
18775
+ function guardian_run(self, context) {
18776
+ M_SetAnimation3(self, guardian_move_run, context);
18777
+ }
18778
+ var guardian_frames_pain1 = Array(8).fill({ ai: guardian_ai_move, dist: 0 });
18779
+ guardian_move_pain1 = {
18780
+ firstframe: FRAME_pain1_1,
18781
+ lastframe: FRAME_pain1_8,
18782
+ frames: guardian_frames_pain1,
18783
+ endfunc: guardian_run
18784
+ };
18785
+ function guardian_pain(self, other, kick, damage) {
18786
+ if (damage <= 10) return;
18787
+ const frame = self.frame;
18788
+ if (frame >= FRAME_atk1_spin1 && frame <= FRAME_atk1_spin15) return;
18789
+ if (frame >= FRAME_atk2_fire1 && frame <= FRAME_atk2_fire4) return;
18790
+ if (frame >= FRAME_kick_in1 && frame <= FRAME_kick_in13) return;
18791
+ if (!M_ShouldReactToPain(self)) return;
18792
+ M_SetAnimation3(self, guardian_move_pain1, null);
18793
+ }
18794
+ var guardian_frames_atk1_out = [
18795
+ { ai: guardian_ai_charge, dist: 0 },
18796
+ { ai: guardian_ai_charge, dist: 0 },
18797
+ { ai: guardian_ai_charge, dist: 0 }
18798
+ ];
18799
+ guardian_atk1_out = {
18800
+ firstframe: FRAME_atk1_out1,
18801
+ lastframe: FRAME_atk1_out3,
18802
+ frames: guardian_frames_atk1_out,
18803
+ endfunc: guardian_run
18804
+ };
18805
+ function guardian_atk1_finish(self, context) {
18806
+ M_SetAnimation3(self, guardian_atk1_out, context);
18807
+ }
18808
+ function guardian_atk1_charge(self, context) {
18809
+ context.sound(self, 1, sound_charge2, 1, 1, 0);
18810
+ }
18811
+ function guardian_fire_blaster_func(self, context) {
18812
+ if (!self.enemy) return;
18813
+ const { forward, right } = angleVectors(self.angles);
18814
+ const start = addVec3(self.origin, scaleVec3(forward, 20));
18815
+ start.z += self.viewheight ? self.viewheight - 10 : 0;
18816
+ start.x += right.x * 20;
18817
+ start.y += right.y * 20;
18818
+ const target = { ...self.enemy.origin };
18819
+ target.z += self.enemy.viewheight || 0;
18820
+ target.x += (Math.random() * 2 - 1) * 5;
18821
+ target.y += (Math.random() * 2 - 1) * 5;
18822
+ target.z += (Math.random() * 2 - 1) * 5;
18823
+ const dir = normalizeVec3(subtractVec3(target, start));
18824
+ monster_fire_blaster(self, start, dir, 2, 1e3, 0, 0, context, 10 /* HYPERBLASTER */);
18825
+ }
18826
+ function guardian_fire_blaster_loop(self, context) {
18827
+ guardian_fire_blaster_func(self, context);
18828
+ if (self.enemy && self.enemy.health > 0 && self.frame === FRAME_atk1_spin12 && self.timestamp > context.timeSeconds && visible(self, self.enemy, context.trace)) {
18829
+ M_SetAnimation3(self, guardian_move_atk1_spin_loop, context);
18830
+ }
18831
+ }
18832
+ var guardian_frames_atk1_spin = [
18833
+ { ai: guardian_ai_charge, dist: 0, think: guardian_atk1_charge },
18834
+ { ai: guardian_ai_charge, dist: 0 },
18835
+ { ai: guardian_ai_charge, dist: 0 },
18836
+ { ai: guardian_ai_charge, dist: 0 },
18837
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18838
+ // 5
18839
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18840
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18841
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18842
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18843
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18844
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18845
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_loop },
18846
+ // 12
18847
+ { ai: guardian_ai_charge, dist: 0 },
18848
+ { ai: guardian_ai_charge, dist: 0 },
18849
+ { ai: guardian_ai_charge, dist: 0 }
18850
+ ];
18851
+ guardian_move_atk1_spin = {
18852
+ firstframe: FRAME_atk1_spin1,
18853
+ lastframe: FRAME_atk1_spin15,
18854
+ frames: guardian_frames_atk1_spin,
18855
+ endfunc: guardian_atk1_finish
18856
+ };
18857
+ guardian_move_atk1_spin_loop = {
18858
+ firstframe: FRAME_atk1_spin1 + 4,
18859
+ lastframe: FRAME_atk1_spin15,
18860
+ frames: guardian_frames_atk1_spin.slice(4),
18861
+ endfunc: guardian_atk1_finish
18862
+ };
18863
+ function guardian_atk1(self, context) {
18864
+ M_SetAnimation3(self, guardian_move_atk1_spin, context);
18865
+ self.timestamp = context.timeSeconds + 0.65 + Math.random() * 1.5;
18866
+ }
18867
+ var guardian_frames_atk1_in = [
18868
+ { ai: guardian_ai_charge, dist: 0 },
18869
+ { ai: guardian_ai_charge, dist: 0 },
18870
+ { ai: guardian_ai_charge, dist: 0 }
18871
+ ];
18872
+ guardian_move_atk1_in = {
18873
+ firstframe: FRAME_atk1_in1,
18874
+ lastframe: FRAME_atk1_in3,
18875
+ frames: guardian_frames_atk1_in,
18876
+ endfunc: guardian_atk1
18877
+ };
18878
+ var guardian_frames_atk2_out = [
18879
+ { ai: guardian_ai_charge, dist: 0 },
18880
+ { ai: guardian_ai_charge, dist: 0 },
18881
+ { ai: guardian_ai_charge, dist: 0 },
18882
+ { ai: guardian_ai_charge, dist: 0 },
18883
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18884
+ { ai: guardian_ai_charge, dist: 0 },
18885
+ { ai: guardian_ai_charge, dist: 0 }
18886
+ ];
18887
+ guardian_move_atk2_out = {
18888
+ firstframe: FRAME_atk2_out1,
18889
+ lastframe: FRAME_atk2_out7,
18890
+ frames: guardian_frames_atk2_out,
18891
+ endfunc: guardian_run
18892
+ };
18893
+ function guardian_atk2_out(self, context) {
18894
+ M_SetAnimation3(self, guardian_move_atk2_out, context);
18895
+ }
18896
+ var laser_positions = [
18897
+ { x: 125, y: -70, z: 60 },
18898
+ { x: 112, y: -62, z: 60 }
18899
+ ];
18900
+ function guardian_fire_update(laser, context) {
18901
+ const self = laser.owner;
18902
+ if (!self || !self.inUse) {
18903
+ context.free(laser);
18904
+ return;
18905
+ }
18906
+ const { forward, right } = angleVectors(self.angles);
18907
+ const offset = laser_positions[1 - (self.frame & 1)];
18908
+ const start = addVec3(self.origin, scaleVec3(forward, offset.x));
18909
+ start.z += offset.z;
18910
+ start.x += right.x * offset.y;
18911
+ start.y += right.y * offset.y;
18912
+ start.z += right.z * offset.y;
18913
+ if (!self.enemy) return;
18914
+ const target = addVec3(self.enemy.origin, self.enemy.mins);
18915
+ target.x += Math.random() * self.enemy.size.x;
18916
+ target.y += Math.random() * self.enemy.size.y;
18917
+ target.z += Math.random() * self.enemy.size.z;
18918
+ const dir = normalizeVec3(subtractVec3(target, start));
18919
+ laser.origin = start;
18920
+ laser.movedir = dir;
18921
+ context.linkentity(laser);
18922
+ }
18923
+ function guardian_laser_fire(self, context) {
18924
+ context.sound(self, 1, sound_laser, 1, 1, 0);
18925
+ monster_fire_dabeam(self, 25, self.frame % 2 !== 0, guardian_fire_update, context);
18926
+ }
18927
+ var guardian_frames_atk2_fire = [
18928
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18929
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18930
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18931
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire }
18932
+ ];
18933
+ guardian_move_atk2_fire = {
18934
+ firstframe: FRAME_atk2_fire1,
18935
+ lastframe: FRAME_atk2_fire4,
18936
+ frames: guardian_frames_atk2_fire,
18937
+ endfunc: guardian_atk2_out
18938
+ };
18939
+ function guardian_atk2(self, context) {
18940
+ M_SetAnimation3(self, guardian_move_atk2_fire, context);
18941
+ }
18942
+ var guardian_frames_atk2_in = [
18943
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18944
+ { ai: guardian_ai_charge, dist: 0 },
18945
+ { ai: guardian_ai_charge, dist: 0 },
18946
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18947
+ { ai: guardian_ai_charge, dist: 0 },
18948
+ { ai: guardian_ai_charge, dist: 0 },
18949
+ { ai: guardian_ai_charge, dist: 0 },
18950
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18951
+ { ai: guardian_ai_charge, dist: 0 },
18952
+ { ai: guardian_ai_charge, dist: 0 },
18953
+ { ai: guardian_ai_charge, dist: 0 },
18954
+ { ai: guardian_ai_charge, dist: 0 }
18955
+ ];
18956
+ guardian_move_atk2_in = {
18957
+ firstframe: FRAME_atk2_in1,
18958
+ lastframe: FRAME_atk2_in12,
18959
+ frames: guardian_frames_atk2_in,
18960
+ endfunc: guardian_atk2
18961
+ };
18962
+ function guardian_kick(self, context) {
18963
+ const aim = { x: MELEE_DISTANCE6, y: 0, z: -80 };
18964
+ if (!monster_fire_hit(self, aim, 85, 700, context)) {
18965
+ self.monsterinfo.melee_debounce_time = context.timeSeconds + 1;
18966
+ }
18967
+ }
18968
+ var guardian_frames_kick = [
18969
+ { ai: guardian_ai_charge, dist: 0 },
18970
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18971
+ { ai: guardian_ai_charge, dist: 0 },
18972
+ { ai: guardian_ai_charge, dist: 0 },
18973
+ { ai: guardian_ai_charge, dist: 0 },
18974
+ { ai: guardian_ai_charge, dist: 0, think: guardian_kick },
18975
+ { ai: guardian_ai_charge, dist: 0 },
18976
+ { ai: guardian_ai_charge, dist: 0 },
18977
+ { ai: guardian_ai_charge, dist: 0 },
18978
+ { ai: guardian_ai_charge, dist: 0 },
18979
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18980
+ { ai: guardian_ai_charge, dist: 0 },
18981
+ { ai: guardian_ai_charge, dist: 0 }
18982
+ ];
18983
+ guardian_move_kick = {
18984
+ firstframe: FRAME_kick_in1,
18985
+ lastframe: FRAME_kick_in13,
18986
+ frames: guardian_frames_kick,
18987
+ endfunc: guardian_run
18988
+ };
18989
+ function guardian_attack(self, context) {
18990
+ if (!self.enemy || !self.enemy.inUse) return;
18991
+ const r = rangeTo(self, self.enemy);
18992
+ if (r > 500) {
18993
+ M_SetAnimation3(self, guardian_move_atk2_in, context);
18994
+ } else if (context.timeSeconds > (self.monsterinfo.melee_debounce_time ?? 0) && r < 120) {
18995
+ M_SetAnimation3(self, guardian_move_kick, context);
18996
+ } else {
18997
+ M_SetAnimation3(self, guardian_move_atk1_in, context);
18998
+ }
18999
+ }
19000
+ function guardian_explode(self, context) {
19001
+ const org = {
19002
+ x: self.origin.x + self.mins.x + Math.random() * self.size.x,
19003
+ y: self.origin.y + self.mins.y + Math.random() * self.size.y,
19004
+ z: self.origin.z + self.mins.z + Math.random() * self.size.z
19005
+ };
19006
+ context.multicast(self.origin, 0 /* All */, ServerCommand.temp_entity, TempEntity.EXPLOSION1_BIG, org);
19007
+ }
19008
+ function guardian_dead(self, context) {
19009
+ for (let i = 0; i < 3; i++) {
19010
+ guardian_explode(self, context);
19011
+ }
19012
+ throwGibs(context, self.origin, 250, GIB_METALLIC);
19013
+ self.nextthink = -1;
19014
+ }
19015
+ function BossExplode(self, context) {
19016
+ guardian_explode(self, context);
19017
+ }
19018
+ var guardian_frames_death1 = [
19019
+ { ai: guardian_ai_move, dist: 0, think: BossExplode },
19020
+ { ai: guardian_ai_move, dist: 0 },
19021
+ { ai: guardian_ai_move, dist: 0 },
19022
+ { ai: guardian_ai_move, dist: 0 },
19023
+ { ai: guardian_ai_move, dist: 0 },
19024
+ { ai: guardian_ai_move, dist: 0 },
19025
+ { ai: guardian_ai_move, dist: 0 },
19026
+ { ai: guardian_ai_move, dist: 0 },
19027
+ { ai: guardian_ai_move, dist: 0 },
19028
+ { ai: guardian_ai_move, dist: 0 },
19029
+ { ai: guardian_ai_move, dist: 0 },
19030
+ { ai: guardian_ai_move, dist: 0 },
19031
+ { ai: guardian_ai_move, dist: 0 },
19032
+ { ai: guardian_ai_move, dist: 0 },
19033
+ { ai: guardian_ai_move, dist: 0 },
19034
+ { ai: guardian_ai_move, dist: 0 },
19035
+ { ai: guardian_ai_move, dist: 0 },
19036
+ { ai: guardian_ai_move, dist: 0 },
19037
+ { ai: guardian_ai_move, dist: 0 },
19038
+ { ai: guardian_ai_move, dist: 0 },
19039
+ { ai: guardian_ai_move, dist: 0 },
19040
+ { ai: guardian_ai_move, dist: 0 },
19041
+ { ai: guardian_ai_move, dist: 0 },
19042
+ { ai: guardian_ai_move, dist: 0 },
19043
+ { ai: guardian_ai_move, dist: 0 },
19044
+ { ai: guardian_ai_move, dist: 0 }
19045
+ ];
19046
+ guardian_move_death = {
19047
+ firstframe: FRAME_death12,
19048
+ lastframe: FRAME_death26,
19049
+ frames: guardian_frames_death1,
19050
+ endfunc: guardian_dead
19051
+ };
19052
+ function SP_monster_guardian(self, context) {
19053
+ if (!M_AllowSpawn(self, context.entities)) {
19054
+ context.entities.free(self);
19055
+ return;
19056
+ }
19057
+ self.classname = "monster_guardian";
19058
+ self.model = "models/monsters/guardian/tris.md2";
19059
+ self.mins = { x: -96, y: -96, z: -66 };
19060
+ self.maxs = { x: 96, y: 96, z: 62 };
19061
+ self.movetype = 5 /* Step */;
19062
+ self.solid = 2 /* BoundingBox */;
19063
+ self.health = 2500;
19064
+ self.mass = 850;
19065
+ self.pain = (ent, other, kick, damage) => {
19066
+ guardian_pain(ent, other, kick, damage);
19067
+ };
19068
+ self.die = (ent, inflictor, attacker, damage, point, mod) => {
19069
+ ent.deadflag = 2 /* Dead */;
19070
+ ent.takedamage = true;
19071
+ if (ent.health < -200) {
19072
+ guardian_dead(ent, context.entities);
19073
+ context.entities.free(ent);
19074
+ return;
19075
+ }
19076
+ M_SetAnimation3(ent, guardian_move_death, context.entities);
19077
+ };
19078
+ self.monsterinfo.stand = guardian_stand;
19079
+ self.monsterinfo.walk = guardian_walk;
19080
+ self.monsterinfo.run = guardian_run;
19081
+ self.monsterinfo.attack = guardian_attack;
19082
+ self.monsterinfo.melee_debounce_time = 0;
19083
+ context.entities.linkentity(self);
19084
+ M_SetAnimation3(self, guardian_move_stand, context.entities);
19085
+ self.think = monster_think;
19086
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK29;
19087
+ }
19088
+ function registerGuardianSpawns(registry) {
19089
+ registry.register("monster_guardian", SP_monster_guardian);
19090
+ }
19091
+
17806
19092
  // src/entities/monsters/index.ts
17807
19093
  function registerMonsterSpawns2(registry) {
17808
19094
  registerMonsterSpawns(registry);
@@ -17832,6 +19118,8 @@ function registerMonsterSpawns2(registry) {
17832
19118
  registerGekkSpawns(registry);
17833
19119
  registerFixbotSpawns(registry);
17834
19120
  registerArachnidSpawns(registry);
19121
+ registerGunCommanderSpawns(registry);
19122
+ registerGuardianSpawns(registry);
17835
19123
  }
17836
19124
 
17837
19125
  // src/entities/worldspawn.ts
@@ -19774,7 +21062,7 @@ var WEAPONS = {
19774
21062
  };
19775
21063
 
19776
21064
  // src/index.ts
19777
- var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
21065
+ var ZERO_VEC39 = { x: 0, y: 0, z: 0 };
19778
21066
  function createGame(imports, engine, options) {
19779
21067
  const gravity = options.gravity;
19780
21068
  const deathmatch = options.deathmatch ?? false;
@@ -19853,8 +21141,8 @@ function createGame(imports, engine, options) {
19853
21141
  };
19854
21142
  entities.runFrame();
19855
21143
  });
19856
- let origin = { ...ZERO_VEC38 };
19857
- let velocity = { ...ZERO_VEC38 };
21144
+ let origin = { ...ZERO_VEC39 };
21145
+ let velocity = { ...ZERO_VEC39 };
19858
21146
  const calculateBlend = (player, time) => {
19859
21147
  const blend = [0, 0, 0, 0];
19860
21148
  if (!player || !player.client) return blend;
@@ -19936,10 +21224,10 @@ function createGame(imports, engine, options) {
19936
21224
  // TODO
19937
21225
  damageIndicators: [],
19938
21226
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
19939
- kick_angles: player?.client?.kick_angles ?? ZERO_VEC38,
19940
- kick_origin: player?.client?.kick_origin ?? ZERO_VEC38,
19941
- gunoffset: ZERO_VEC38,
19942
- gunangles: ZERO_VEC38,
21227
+ kick_angles: player?.client?.kick_angles ?? ZERO_VEC39,
21228
+ kick_origin: player?.client?.kick_origin ?? ZERO_VEC39,
21229
+ gunoffset: ZERO_VEC39,
21230
+ gunangles: ZERO_VEC39,
19943
21231
  gunindex: 0,
19944
21232
  gun_frame: player?.client?.gun_frame ?? 0,
19945
21233
  rdflags: player?.client?.rdflags ?? 0,
@@ -19953,8 +21241,8 @@ function createGame(imports, engine, options) {
19953
21241
  const resetState = (startTimeMs) => {
19954
21242
  frameLoop.reset(startTimeMs);
19955
21243
  levelClock.start(startTimeMs);
19956
- origin = { ...ZERO_VEC38 };
19957
- velocity = { ...ZERO_VEC38 };
21244
+ origin = { ...ZERO_VEC39 };
21245
+ velocity = { ...ZERO_VEC39 };
19958
21246
  entities.beginFrame(startTimeMs / 1e3);
19959
21247
  entities.runFrame();
19960
21248
  };
@@ -19982,10 +21270,10 @@ function createGame(imports, engine, options) {
19982
21270
  blend: [0, 0, 0, 0],
19983
21271
  // Stubs
19984
21272
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
19985
- kick_angles: ZERO_VEC38,
19986
- kick_origin: ZERO_VEC38,
19987
- gunoffset: ZERO_VEC38,
19988
- gunangles: ZERO_VEC38,
21273
+ kick_angles: ZERO_VEC39,
21274
+ kick_origin: ZERO_VEC39,
21275
+ gunoffset: ZERO_VEC39,
21276
+ gunangles: ZERO_VEC39,
19989
21277
  gunindex: 0,
19990
21278
  pm_type: 0,
19991
21279
  pm_time: 0,
@@ -20121,8 +21409,8 @@ function createGame(imports, engine, options) {
20121
21409
  rng,
20122
21410
  player: player?.client?.inventory
20123
21411
  });
20124
- origin = player ? { ...player.origin } : { ...ZERO_VEC38 };
20125
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC38 };
21412
+ origin = player ? { ...player.origin } : { ...ZERO_VEC39 };
21413
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC39 };
20126
21414
  frameLoop.reset(save.level.timeSeconds * 1e3);
20127
21415
  }
20128
21416
  };
@@ -20158,6 +21446,7 @@ function createGame(imports, engine, options) {
20158
21446
  M_CheckBottom,
20159
21447
  M_MoveFrame,
20160
21448
  M_walkmove,
21449
+ MonsterAttackState,
20161
21450
  MoveType,
20162
21451
  MulticastType,
20163
21452
  ORDERED_DAMAGE_MODS,