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
@@ -2852,6 +2852,7 @@ var AttackState = /* @__PURE__ */ ((AttackState2) => {
2852
2852
  AttackState2[AttackState2["Blind"] = 4] = "Blind";
2853
2853
  return AttackState2;
2854
2854
  })(AttackState || {});
2855
+ var MonsterAttackState = AttackState;
2855
2856
  var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
2856
2857
  TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
2857
2858
  TraceMask2[TraceMask2["Window"] = 2] = "Window";
@@ -2861,12 +2862,12 @@ var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
2861
2862
  // src/ai/perception.ts
2862
2863
  init_esm();
2863
2864
  init_esm();
2864
- var RangeCategory = /* @__PURE__ */ ((RangeCategory4) => {
2865
- RangeCategory4["Melee"] = "melee";
2866
- RangeCategory4["Near"] = "near";
2867
- RangeCategory4["Mid"] = "mid";
2868
- RangeCategory4["Far"] = "far";
2869
- return RangeCategory4;
2865
+ var RangeCategory = /* @__PURE__ */ ((RangeCategory5) => {
2866
+ RangeCategory5["Melee"] = "melee";
2867
+ RangeCategory5["Near"] = "near";
2868
+ RangeCategory5["Mid"] = "mid";
2869
+ RangeCategory5["Far"] = "far";
2870
+ return RangeCategory5;
2870
2871
  })(RangeCategory || {});
2871
2872
  function absBounds(entity) {
2872
2873
  return {
@@ -5287,6 +5288,52 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5287
5288
  sys.scheduleThink(bfgBall, sys.timeSeconds + 0.016);
5288
5289
  sys.finalizeSpawn(bfgBall);
5289
5290
  }
5291
+ function createFlechette(sys, owner, start, dir, damage, speed) {
5292
+ const flechette = sys.spawn();
5293
+ flechette.classname = "flechette";
5294
+ flechette.owner = owner;
5295
+ flechette.origin = { ...start };
5296
+ flechette.velocity = { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed };
5297
+ flechette.movetype = 8 /* FlyMissile */;
5298
+ flechette.solid = 2 /* BoundingBox */;
5299
+ flechette.modelindex = sys.modelIndex("models/objects/projectile/tris.md2");
5300
+ flechette.mins = { x: -2, y: -2, z: -2 };
5301
+ flechette.maxs = { x: 2, y: 2, z: 2 };
5302
+ flechette.angles = vectorToAngles(dir);
5303
+ flechette.touch = (self, other, plane, surf) => {
5304
+ if (other === self.owner) {
5305
+ return;
5306
+ }
5307
+ if (other && other.takedamage) {
5308
+ T_Damage(
5309
+ other,
5310
+ self,
5311
+ self.owner,
5312
+ self.velocity,
5313
+ self.origin,
5314
+ plane ? plane.normal : ZERO_VEC3,
5315
+ damage,
5316
+ 1,
5317
+ 0 /* NONE */,
5318
+ 43 /* ETF_RIFLE */,
5319
+ // Assuming this exists or falls under UNKNOWN
5320
+ sys.timeSeconds,
5321
+ sys.multicast ? sys.multicast.bind(sys) : void 0
5322
+ );
5323
+ if (other.monsterinfo) {
5324
+ const time = sys.timeSeconds || 0;
5325
+ other.monsterinfo.freeze_time = time + 3;
5326
+ }
5327
+ sys.free(self);
5328
+ return;
5329
+ }
5330
+ if (plane) {
5331
+ sys.multicast(self.origin, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.SPARKS, self.origin, plane.normal);
5332
+ }
5333
+ sys.free(self);
5334
+ };
5335
+ sys.finalizeSpawn(flechette);
5336
+ }
5290
5337
 
5291
5338
  // src/entities/targets.ts
5292
5339
  var ATTN_NONE = 0;
@@ -9524,6 +9571,9 @@ function monster_fire_dabeam(self, damage, secondary, update_func, context) {
9524
9571
  update_func(beam, context);
9525
9572
  dabeam_update(beam, context);
9526
9573
  }
9574
+ function monster_fire_flechette(self, start, dir, damage, speed, flashtype, context) {
9575
+ createFlechette(context, self, start, dir, damage, speed);
9576
+ }
9527
9577
 
9528
9578
  // src/entities/monsters/boss2.ts
9529
9579
  init_esm();
@@ -17265,6 +17315,20 @@ function M_ProjectFlashSource(self, offset, forward, right) {
17265
17315
  const start3 = addVec3(start2, { x: 0, y: 0, z: offset.z });
17266
17316
  return start3;
17267
17317
  }
17318
+ function M_MonsterDodge(self, attacker, eta) {
17319
+ }
17320
+ function M_CheckClearShot(self, offset, context) {
17321
+ if (!self.enemy) return false;
17322
+ const start = { ...self.origin };
17323
+ start.z += self.viewheight;
17324
+ const end = { ...self.enemy.origin };
17325
+ end.z += self.enemy.viewheight;
17326
+ const tr = context.trace(start, end, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
17327
+ if (tr.fraction === 1 || tr.ent === self.enemy) {
17328
+ return true;
17329
+ }
17330
+ return false;
17331
+ }
17268
17332
 
17269
17333
  // src/entities/monsters/arachnid.ts
17270
17334
  var FRAME_rails1 = 0;
@@ -17644,6 +17708,1227 @@ function registerArachnidSpawns(registry) {
17644
17708
  registry.register("monster_arachnid", SP_monster_arachnid);
17645
17709
  }
17646
17710
 
17711
+ // src/entities/monsters/gunnerCommander.ts
17712
+ init_esm();
17713
+ var MONSTER_TICK28 = 0.1;
17714
+ var MORTAR_SPEED = 850;
17715
+ var GRENADE_SPEED = 600;
17716
+ var MZ2_GUNCMDR_CHAINGUN_1 = 1;
17717
+ var MZ2_GUNCMDR_CHAINGUN_2 = 2;
17718
+ var MZ2_GUNCMDR_GRENADE_MORTAR_1 = 3;
17719
+ var MZ2_GUNCMDR_GRENADE_MORTAR_2 = 4;
17720
+ var MZ2_GUNCMDR_GRENADE_MORTAR_3 = 5;
17721
+ var MZ2_GUNCMDR_GRENADE_FRONT_1 = 6;
17722
+ var MZ2_GUNCMDR_GRENADE_FRONT_2 = 7;
17723
+ var MZ2_GUNCMDR_GRENADE_FRONT_3 = 8;
17724
+ var MZ2_GUNCMDR_GRENADE_CROUCH_1 = 9;
17725
+ var MZ2_GUNCMDR_GRENADE_CROUCH_2 = 10;
17726
+ var MZ2_GUNCMDR_GRENADE_CROUCH_3 = 11;
17727
+ var monster_flash_offset = {
17728
+ [MZ2_GUNCMDR_CHAINGUN_1]: { x: 37, y: -4, z: 12.5 },
17729
+ [MZ2_GUNCMDR_CHAINGUN_2]: { x: 37, y: -4, z: 12.5 },
17730
+ [MZ2_GUNCMDR_GRENADE_MORTAR_1]: { x: 14, y: 7, z: 27.5 },
17731
+ [MZ2_GUNCMDR_GRENADE_MORTAR_2]: { x: 14, y: 7, z: 27.5 },
17732
+ [MZ2_GUNCMDR_GRENADE_MORTAR_3]: { x: 14, y: 7, z: 27.5 },
17733
+ [MZ2_GUNCMDR_GRENADE_FRONT_1]: { x: 19, y: 7, z: 13.5 },
17734
+ [MZ2_GUNCMDR_GRENADE_FRONT_2]: { x: 19, y: 7, z: 13.5 },
17735
+ [MZ2_GUNCMDR_GRENADE_FRONT_3]: { x: 19, y: 7, z: 13.5 },
17736
+ [MZ2_GUNCMDR_GRENADE_CROUCH_1]: { x: 19, y: 7, z: 13.5 },
17737
+ [MZ2_GUNCMDR_GRENADE_CROUCH_2]: { x: 19, y: 7, z: 13.5 },
17738
+ [MZ2_GUNCMDR_GRENADE_CROUCH_3]: { x: 19, y: 7, z: 13.5 }
17739
+ };
17740
+ function monster_ai_stand24(self, dist, context) {
17741
+ ai_stand(self, MONSTER_TICK28, context);
17742
+ }
17743
+ function monster_ai_walk23(self, dist, context) {
17744
+ ai_walk(self, dist, MONSTER_TICK28, context);
17745
+ }
17746
+ function monster_ai_run24(self, dist, context) {
17747
+ ai_run(self, dist, MONSTER_TICK28, context);
17748
+ }
17749
+ function monster_ai_charge25(self, dist, context) {
17750
+ ai_charge(self, dist, MONSTER_TICK28, context);
17751
+ }
17752
+ function monster_ai_move24(self, dist, context) {
17753
+ ai_move(self, dist);
17754
+ }
17755
+ var stand_move21;
17756
+ var fidget_move4;
17757
+ var walk_move18;
17758
+ var run_move20;
17759
+ var attack_chain_move3;
17760
+ var fire_chain_move2;
17761
+ var fire_chain_run_move;
17762
+ var fire_chain_dodge_right_move;
17763
+ var fire_chain_dodge_left_move;
17764
+ var endfire_chain_move2;
17765
+ var attack_mortar_move;
17766
+ var attack_mortar_dodge_move;
17767
+ var attack_grenade_back_move;
17768
+ var attack_grenade_back_dodge_right_move;
17769
+ var attack_grenade_back_dodge_left_move;
17770
+ var attack_kick_move;
17771
+ var duck_attack_move;
17772
+ var jump_move3;
17773
+ var jump2_move;
17774
+ var pain1_move8;
17775
+ var pain2_move8;
17776
+ var pain3_move7;
17777
+ var pain4_move2;
17778
+ var pain5_move2;
17779
+ var pain6_move2;
17780
+ var pain7_move;
17781
+ var death1_move3;
17782
+ var death2_move3;
17783
+ var death3_move;
17784
+ var death4_move;
17785
+ var death5_move;
17786
+ var death6_move;
17787
+ var death7_move;
17788
+ function guncmdr_idlesound(self, context) {
17789
+ context.engine.sound?.(self, 0, "guncmdr/gcdridle1.wav", 1, 1, 0);
17790
+ }
17791
+ function guncmdr_sight(self, other, context) {
17792
+ context.engine.sound?.(self, 0, "guncmdr/sight1.wav", 1, 1, 0);
17793
+ }
17794
+ function guncmdr_search(self, context) {
17795
+ context.engine.sound?.(self, 0, "guncmdr/gcdrsrch1.wav", 1, 1, 0);
17796
+ }
17797
+ function guncmdr_opengun(self, context) {
17798
+ context.engine.sound?.(self, 0, "guncmdr/gcdratck1.wav", 1, 1, 0);
17799
+ }
17800
+ function guncmdr_fidget(self, context) {
17801
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) return;
17802
+ if (self.enemy) return;
17803
+ if (Math.random() <= 0.05) {
17804
+ M_SetAnimation3(self, fidget_move4, context);
17805
+ }
17806
+ }
17807
+ function guncmdr_stand(self, context) {
17808
+ M_SetAnimation3(self, stand_move21, context);
17809
+ }
17810
+ function guncmdr_walk(self, context) {
17811
+ M_SetAnimation3(self, walk_move18, context);
17812
+ }
17813
+ function monster_done_dodge2(self) {
17814
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
17815
+ }
17816
+ function guncmdr_run(self, context) {
17817
+ monster_done_dodge2(self);
17818
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) {
17819
+ M_SetAnimation3(self, stand_move21, context);
17820
+ } else {
17821
+ M_SetAnimation3(self, run_move20, context);
17822
+ }
17823
+ }
17824
+ function guncmdr_fire_chain(self, context) {
17825
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
17826
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
17827
+ if (dist > 400 && ai_move(self, 8)) {
17828
+ M_SetAnimation3(self, fire_chain_run_move, context);
17829
+ return;
17830
+ }
17831
+ }
17832
+ M_SetAnimation3(self, fire_chain_move2, context);
17833
+ }
17834
+ function guncmdr_refire_chain(self, context) {
17835
+ monster_done_dodge2(self);
17836
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
17837
+ if (self.enemy && self.enemy.health > 0) {
17838
+ if (visible(self, self.enemy, context.trace)) {
17839
+ if (Math.random() <= 0.5) {
17840
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
17841
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
17842
+ if (dist > 400 && ai_move(self, 8)) {
17843
+ M_SetAnimation3(self, fire_chain_run_move, context);
17844
+ return;
17845
+ }
17846
+ }
17847
+ M_SetAnimation3(self, fire_chain_move2, context);
17848
+ return;
17849
+ }
17850
+ }
17851
+ }
17852
+ M_SetAnimation3(self, endfire_chain_move2, context);
17853
+ }
17854
+ function GunnerCmdrFire(self, context) {
17855
+ if (!self.enemy || !self.enemy.inUse) return;
17856
+ let flash_number;
17857
+ if (self.monsterinfo.current_move === fire_chain_dodge_right_move || self.monsterinfo.current_move === fire_chain_dodge_left_move) {
17858
+ flash_number = MZ2_GUNCMDR_CHAINGUN_2;
17859
+ } else {
17860
+ flash_number = MZ2_GUNCMDR_CHAINGUN_1;
17861
+ }
17862
+ const { forward, right } = angleVectors(self.angles);
17863
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
17864
+ let aim = normalizeVec3(subtractVec3(self.enemy.origin, start));
17865
+ const randomAim = { ...aim };
17866
+ for (let i = 0; i < 3; i++) {
17867
+ randomAim.x += (Math.random() - 0.5) * 0.05;
17868
+ randomAim.y += (Math.random() - 0.5) * 0.05;
17869
+ randomAim.z += (Math.random() - 0.5) * 0.05;
17870
+ }
17871
+ aim = normalizeVec3(randomAim);
17872
+ monster_fire_flechette(self, start, aim, 4, 800, flash_number, context);
17873
+ }
17874
+ function GunnerCmdrGrenade(self, context) {
17875
+ if (!self.enemy || !self.enemy.inUse) return;
17876
+ let spread = 0;
17877
+ let flash_number = 0;
17878
+ const frameIndex = self.frame;
17879
+ if (self.monsterinfo.current_move === attack_mortar_move) {
17880
+ const offset = frameIndex - attack_mortar_move.firstframe;
17881
+ if (offset === 4) {
17882
+ spread = -0.1;
17883
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_1;
17884
+ } else if (offset === 7) {
17885
+ spread = 0;
17886
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_2;
17887
+ } else if (offset === 10) {
17888
+ spread = 0.1;
17889
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_3;
17890
+ }
17891
+ } else if (self.monsterinfo.current_move === attack_grenade_back_move) {
17892
+ const offset = frameIndex - attack_grenade_back_move.firstframe;
17893
+ if (offset === 2) {
17894
+ spread = -0.1;
17895
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_1;
17896
+ } else if (offset === 5) {
17897
+ spread = 0;
17898
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_2;
17899
+ } else if (offset === 8) {
17900
+ spread = 0.1;
17901
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_3;
17902
+ }
17903
+ }
17904
+ if (flash_number === 0) return;
17905
+ const { forward, right, up } = angleVectors(self.angles);
17906
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
17907
+ let aim;
17908
+ let pitch = 0;
17909
+ const target = self.enemy.origin;
17910
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_FRONT_1 && flash_number <= MZ2_GUNCMDR_GRENADE_FRONT_3) {
17911
+ pitch -= 0.05;
17912
+ }
17913
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3) {
17914
+ let distVector = subtractVec3(target, self.origin);
17915
+ let dist = lengthVec3(distVector);
17916
+ if (dist > 512 && distVector.z < 64 && distVector.z > -64) {
17917
+ const newZ = distVector.z + (dist - 512);
17918
+ distVector = { ...distVector, z: newZ };
17919
+ }
17920
+ distVector = normalizeVec3(distVector);
17921
+ let p = distVector.z;
17922
+ if (p > 0.4) p = 0.4;
17923
+ else if (p < -0.5) p = -0.5;
17924
+ if (self.enemy.absmin.z - self.absmax.z > 16) {
17925
+ p += 0.5;
17926
+ }
17927
+ pitch += p;
17928
+ }
17929
+ aim = normalizeVec3(addVec3(addVec3(forward, scaleVec3(right, spread)), scaleVec3(up, pitch)));
17930
+ let speed = flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3 ? MORTAR_SPEED : GRENADE_SPEED;
17931
+ createGrenade(context, self, start, aim, 50, speed);
17932
+ }
17933
+ function guncmdr_grenade_mortar_resume(self, context) {
17934
+ M_SetAnimation3(self, attack_mortar_move, context);
17935
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
17936
+ self.frame = self.count;
17937
+ }
17938
+ function guncmdr_grenade_back_dodge_resume(self, context) {
17939
+ M_SetAnimation3(self, attack_grenade_back_move, context);
17940
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
17941
+ self.frame = self.count;
17942
+ }
17943
+ function guncmdr_kick_finished(self, context) {
17944
+ self.monsterinfo.melee_debounce_time = context.timeSeconds + 3;
17945
+ if (self.monsterinfo.attack) {
17946
+ self.monsterinfo.attack(self, context);
17947
+ }
17948
+ }
17949
+ function guncmdr_kick(self, context) {
17950
+ if (!self.enemy) return;
17951
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
17952
+ if (dist < 100) {
17953
+ if (self.enemy.client && self.enemy.velocity.z < 270) {
17954
+ self.enemy.velocity = { ...self.enemy.velocity, z: 270 };
17955
+ }
17956
+ }
17957
+ }
17958
+ function monster_duck_down(self, context) {
17959
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) return;
17960
+ self.monsterinfo.aiflags |= 2048 /* Ducked */;
17961
+ self.maxs = { ...self.maxs, z: self.maxs.z - 32 };
17962
+ self.takedamage = true;
17963
+ self.monsterinfo.pausetime = context.timeSeconds + 1;
17964
+ }
17965
+ function monster_duck_hold(self, context) {
17966
+ if (context.timeSeconds >= self.monsterinfo.pausetime) {
17967
+ self.monsterinfo.aiflags &= ~128 /* HoldFrame */;
17968
+ } else {
17969
+ self.monsterinfo.aiflags |= 128 /* HoldFrame */;
17970
+ }
17971
+ }
17972
+ function monster_duck_up(self, context) {
17973
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
17974
+ self.maxs = { ...self.maxs, z: self.maxs.z + 32 };
17975
+ self.takedamage = true;
17976
+ }
17977
+ function guncmdr_jump_now(self, context) {
17978
+ const { forward, up } = angleVectors(self.angles);
17979
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 100));
17980
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 300));
17981
+ }
17982
+ function guncmdr_jump2_now(self, context) {
17983
+ const { forward, up } = angleVectors(self.angles);
17984
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 150));
17985
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 400));
17986
+ }
17987
+ function guncmdr_jump_wait_land(self, context) {
17988
+ if (self.groundentity === null) {
17989
+ self.monsterinfo.nextframe = self.frame;
17990
+ } else {
17991
+ self.monsterinfo.nextframe = self.frame + 1;
17992
+ }
17993
+ }
17994
+ function GunnerCmdrCounter(self, context) {
17995
+ context.engine.sound?.(self, 0, "weapons/rocklx1a.wav", 1, 1, 0);
17996
+ }
17997
+ function guncmdr_attack(self, context) {
17998
+ monster_done_dodge2(self);
17999
+ const d = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18000
+ const { forward, right } = angleVectors(self.angles);
18001
+ const RANGE_GRENADE = 100;
18002
+ const RANGE_GRENADE_MORTAR = 525;
18003
+ const RANGE_MELEE3 = 64;
18004
+ if (d < RANGE_MELEE3 && (self.monsterinfo.melee_debounce_time === void 0 || self.monsterinfo.melee_debounce_time < context.timeSeconds)) {
18005
+ M_SetAnimation3(self, attack_kick_move, context);
18006
+ } else if (d <= RANGE_GRENADE && M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_CHAINGUN_1], context)) {
18007
+ M_SetAnimation3(self, attack_chain_move3, context);
18008
+ } 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)) {
18009
+ M_SetAnimation3(self, attack_mortar_move, context);
18010
+ monster_duck_down(self, context);
18011
+ } else if (M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_GRENADE_FRONT_1], context) && !(self.monsterinfo.aiflags & 1 /* StandGround */)) {
18012
+ M_SetAnimation3(self, attack_grenade_back_move, context);
18013
+ } else if (self.monsterinfo.aiflags & 1 /* StandGround */) {
18014
+ M_SetAnimation3(self, attack_chain_move3, context);
18015
+ } else {
18016
+ M_SetAnimation3(self, attack_chain_move3, context);
18017
+ }
18018
+ }
18019
+ function guncmdr_pain5_to_death1(self, context) {
18020
+ if (self.health < 0) M_SetAnimation3(self, death1_move3, context);
18021
+ }
18022
+ function guncmdr_pain5_to_death2(self, context) {
18023
+ if (self.health < 0 && Math.random() < 0.5) M_SetAnimation3(self, death2_move3, context);
18024
+ }
18025
+ function guncmdr_pain6_to_death6(self, context) {
18026
+ if (self.health < 0) M_SetAnimation3(self, death6_move, context);
18027
+ }
18028
+ function guncmdr_shrink(self, context) {
18029
+ self.maxs = { ...self.maxs, z: -4 * (self.monsterinfo.scale || 1) };
18030
+ }
18031
+ function guncmdr_dead(self, context) {
18032
+ const scale = self.monsterinfo.scale || 1;
18033
+ self.mins = scaleVec3({ x: -16, y: -16, z: -24 }, scale);
18034
+ self.maxs = scaleVec3({ x: 16, y: 16, z: -8 }, scale);
18035
+ self.nextthink = -1;
18036
+ self.solid = 0 /* Not */;
18037
+ }
18038
+ function guncmdr_pain(self, context) {
18039
+ monster_done_dodge2(self);
18040
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move || self.monsterinfo.current_move === duck_attack_move) {
18041
+ return;
18042
+ }
18043
+ if (context.timeSeconds < self.pain_debounce_time) {
18044
+ return;
18045
+ }
18046
+ self.pain_debounce_time = context.timeSeconds + 3;
18047
+ if (Math.random() < 0.5) {
18048
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain2.wav", 1, 1, 0);
18049
+ } else {
18050
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain1.wav", 1, 1, 0);
18051
+ }
18052
+ if (!M_ShouldReactToPain(self)) return;
18053
+ const r = Math.floor(Math.random() * 7);
18054
+ switch (r) {
18055
+ case 0:
18056
+ M_SetAnimation3(self, pain1_move8, context);
18057
+ break;
18058
+ case 1:
18059
+ M_SetAnimation3(self, pain2_move8, context);
18060
+ break;
18061
+ case 2:
18062
+ M_SetAnimation3(self, pain3_move7, context);
18063
+ break;
18064
+ case 3:
18065
+ M_SetAnimation3(self, pain4_move2, context);
18066
+ break;
18067
+ case 4:
18068
+ M_SetAnimation3(self, pain5_move2, context);
18069
+ break;
18070
+ case 5:
18071
+ M_SetAnimation3(self, pain6_move2, context);
18072
+ break;
18073
+ default:
18074
+ M_SetAnimation3(self, pain7_move, context);
18075
+ break;
18076
+ }
18077
+ self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
18078
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) monster_duck_up(self, context);
18079
+ }
18080
+ function guncmdr_die(self, inflictor, attacker, damage, point, context) {
18081
+ if (M_CheckGib(self, damage)) {
18082
+ context.engine.sound?.(self, 0, "misc/udeath.wav", 1, 1, 0);
18083
+ throwGibs(context, self.origin, [{
18084
+ count: 1,
18085
+ model: "models/monsters/gunner/gibs/chest.md2",
18086
+ flags: 1 /* Metallic */
18087
+ }]);
18088
+ self.deadflag = 2 /* Dead */;
18089
+ return;
18090
+ }
18091
+ if (self.deadflag) return;
18092
+ context.engine.sound?.(self, 0, "guncmdr/gcdrdeath1.wav", 1, 1, 0);
18093
+ self.deadflag = 2 /* Dead */;
18094
+ self.takedamage = true;
18095
+ const r = Math.floor(Math.random() * 7);
18096
+ switch (r) {
18097
+ case 0:
18098
+ M_SetAnimation3(self, death1_move3, context);
18099
+ break;
18100
+ case 1:
18101
+ M_SetAnimation3(self, death2_move3, context);
18102
+ break;
18103
+ case 2:
18104
+ M_SetAnimation3(self, death3_move, context);
18105
+ break;
18106
+ case 3:
18107
+ M_SetAnimation3(self, death4_move, context);
18108
+ break;
18109
+ case 4:
18110
+ M_SetAnimation3(self, death5_move, context);
18111
+ break;
18112
+ case 5:
18113
+ M_SetAnimation3(self, death6_move, context);
18114
+ break;
18115
+ default:
18116
+ M_SetAnimation3(self, death7_move, context);
18117
+ break;
18118
+ }
18119
+ }
18120
+ function guncmdr_setskin(self, context) {
18121
+ if (self.health < self.max_health / 2) {
18122
+ self.skin |= 1;
18123
+ } else {
18124
+ self.skin &= ~1;
18125
+ }
18126
+ }
18127
+ function guncmdr_duck(self, eta, context) {
18128
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move) return false;
18129
+ 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) {
18130
+ monster_duck_up(self, context);
18131
+ return false;
18132
+ }
18133
+ M_SetAnimation3(self, duck_attack_move, context);
18134
+ return true;
18135
+ }
18136
+ function guncmdr_sidestep(self, context) {
18137
+ if (self.monsterinfo.current_move === fire_chain_move2 || self.monsterinfo.current_move === fire_chain_run_move) {
18138
+ M_SetAnimation3(self, Math.random() < 0.5 ? fire_chain_dodge_right_move : fire_chain_dodge_left_move, context);
18139
+ return true;
18140
+ }
18141
+ if (self.monsterinfo.current_move === attack_grenade_back_move) {
18142
+ self.count = self.frame;
18143
+ M_SetAnimation3(self, Math.random() < 0.5 ? attack_grenade_back_dodge_right_move : attack_grenade_back_dodge_left_move, context);
18144
+ return true;
18145
+ }
18146
+ if (self.monsterinfo.current_move === attack_mortar_move) {
18147
+ self.count = self.frame;
18148
+ M_SetAnimation3(self, attack_mortar_dodge_move, context);
18149
+ return true;
18150
+ }
18151
+ if (self.monsterinfo.current_move === run_move20) {
18152
+ M_SetAnimation3(self, run_move20, context);
18153
+ return true;
18154
+ }
18155
+ return false;
18156
+ }
18157
+ fidget_move4 = {
18158
+ firstframe: 201,
18159
+ lastframe: 254,
18160
+ frames: Array(54).fill({ ai: monster_ai_stand24, dist: 0 }),
18161
+ endfunc: guncmdr_stand
18162
+ };
18163
+ fidget_move4.frames[6] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18164
+ fidget_move4.frames[10] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18165
+ stand_move21 = {
18166
+ firstframe: 101,
18167
+ lastframe: 140,
18168
+ frames: Array(40).fill({ ai: monster_ai_stand24, dist: 0 }),
18169
+ endfunc: null
18170
+ };
18171
+ var stand_fidget = (self, context) => guncmdr_fidget(self, context);
18172
+ [9, 19, 29, 39].forEach((i) => {
18173
+ stand_move21.frames[i] = { ai: monster_ai_stand24, dist: 0, think: stand_fidget };
18174
+ });
18175
+ walk_move18 = {
18176
+ firstframe: 101,
18177
+ lastframe: 124,
18178
+ frames: [
18179
+ { ai: monster_ai_walk23, dist: 1.5 },
18180
+ { ai: monster_ai_walk23, dist: 2.5 },
18181
+ { ai: monster_ai_walk23, dist: 3 },
18182
+ { ai: monster_ai_walk23, dist: 2.5 },
18183
+ { ai: monster_ai_walk23, dist: 2.3 },
18184
+ { ai: monster_ai_walk23, dist: 3 },
18185
+ { ai: monster_ai_walk23, dist: 2.8 },
18186
+ { ai: monster_ai_walk23, dist: 3.6 },
18187
+ { ai: monster_ai_walk23, dist: 2.8 },
18188
+ { ai: monster_ai_walk23, dist: 2.5 },
18189
+ { ai: monster_ai_walk23, dist: 2.3 },
18190
+ { ai: monster_ai_walk23, dist: 4.3 },
18191
+ { ai: monster_ai_walk23, dist: 3 },
18192
+ { ai: monster_ai_walk23, dist: 1.5 },
18193
+ { ai: monster_ai_walk23, dist: 2.5 },
18194
+ { ai: monster_ai_walk23, dist: 3.3 },
18195
+ { ai: monster_ai_walk23, dist: 2.8 },
18196
+ { ai: monster_ai_walk23, dist: 3 },
18197
+ { ai: monster_ai_walk23, dist: 2 },
18198
+ { ai: monster_ai_walk23, dist: 2 },
18199
+ { ai: monster_ai_walk23, dist: 3.3 },
18200
+ { ai: monster_ai_walk23, dist: 3.6 },
18201
+ { ai: monster_ai_walk23, dist: 3.4 },
18202
+ { ai: monster_ai_walk23, dist: 2.8 }
18203
+ ],
18204
+ endfunc: null
18205
+ };
18206
+ run_move20 = {
18207
+ firstframe: 101,
18208
+ lastframe: 106,
18209
+ frames: [
18210
+ { ai: monster_ai_run24, dist: 15, think: monster_done_dodge2 },
18211
+ { ai: monster_ai_run24, dist: 16 },
18212
+ { ai: monster_ai_run24, dist: 20 },
18213
+ { ai: monster_ai_run24, dist: 18 },
18214
+ { ai: monster_ai_run24, dist: 24 },
18215
+ { ai: monster_ai_run24, dist: 13.5 }
18216
+ ],
18217
+ endfunc: null
18218
+ };
18219
+ attack_chain_move3 = {
18220
+ firstframe: 101,
18221
+ lastframe: 106,
18222
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0 }),
18223
+ endfunc: guncmdr_fire_chain
18224
+ };
18225
+ attack_chain_move3.frames[4].think = guncmdr_opengun;
18226
+ fire_chain_move2 = {
18227
+ firstframe: 107,
18228
+ lastframe: 112,
18229
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0, think: GunnerCmdrFire }),
18230
+ endfunc: guncmdr_refire_chain
18231
+ };
18232
+ fire_chain_run_move = {
18233
+ firstframe: 201,
18234
+ lastframe: 206,
18235
+ frames: [
18236
+ { ai: monster_ai_charge25, dist: 15, think: GunnerCmdrFire },
18237
+ { ai: monster_ai_charge25, dist: 16, think: GunnerCmdrFire },
18238
+ { ai: monster_ai_charge25, dist: 20, think: GunnerCmdrFire },
18239
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18240
+ { ai: monster_ai_charge25, dist: 24, think: GunnerCmdrFire },
18241
+ { ai: monster_ai_charge25, dist: 13.5, think: GunnerCmdrFire }
18242
+ ],
18243
+ endfunc: guncmdr_refire_chain
18244
+ };
18245
+ fire_chain_dodge_right_move = {
18246
+ firstframe: 401,
18247
+ lastframe: 405,
18248
+ frames: [
18249
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18250
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18251
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18252
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18253
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18254
+ ],
18255
+ endfunc: guncmdr_refire_chain
18256
+ };
18257
+ fire_chain_dodge_left_move = {
18258
+ firstframe: 501,
18259
+ lastframe: 505,
18260
+ frames: [
18261
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18262
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18263
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18264
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18265
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18266
+ ],
18267
+ endfunc: guncmdr_refire_chain
18268
+ };
18269
+ endfire_chain_move2 = {
18270
+ firstframe: 118,
18271
+ lastframe: 124,
18272
+ frames: Array(7).fill({ ai: monster_ai_charge25, dist: 0 }),
18273
+ endfunc: guncmdr_run
18274
+ };
18275
+ endfire_chain_move2.frames[2].think = guncmdr_opengun;
18276
+ attack_mortar_move = {
18277
+ firstframe: 201,
18278
+ lastframe: 221,
18279
+ frames: Array(21).fill({ ai: monster_ai_charge25, dist: 0 }),
18280
+ endfunc: guncmdr_run
18281
+ };
18282
+ attack_mortar_move.frames[4].think = GunnerCmdrGrenade;
18283
+ attack_mortar_move.frames[7].think = GunnerCmdrGrenade;
18284
+ attack_mortar_move.frames[10].think = GunnerCmdrGrenade;
18285
+ attack_mortar_move.frames[13].think = monster_duck_up;
18286
+ attack_mortar_dodge_move = {
18287
+ firstframe: 0,
18288
+ lastframe: 5,
18289
+ frames: [
18290
+ { ai: monster_ai_charge25, dist: 11 },
18291
+ { ai: monster_ai_charge25, dist: 12 },
18292
+ { ai: monster_ai_charge25, dist: 16 },
18293
+ { ai: monster_ai_charge25, dist: 16 },
18294
+ { ai: monster_ai_charge25, dist: 12 },
18295
+ { ai: monster_ai_charge25, dist: 11 }
18296
+ ],
18297
+ endfunc: guncmdr_grenade_mortar_resume
18298
+ };
18299
+ attack_grenade_back_move = {
18300
+ firstframe: 302,
18301
+ lastframe: 321,
18302
+ frames: [
18303
+ { ai: monster_ai_charge25, dist: -2 },
18304
+ { ai: monster_ai_charge25, dist: -1.5 },
18305
+ { ai: monster_ai_charge25, dist: -0.5, think: GunnerCmdrGrenade },
18306
+ { ai: monster_ai_charge25, dist: -6 },
18307
+ { ai: monster_ai_charge25, dist: -4 },
18308
+ { ai: monster_ai_charge25, dist: -2.5, think: GunnerCmdrGrenade },
18309
+ { ai: monster_ai_charge25, dist: -7 },
18310
+ { ai: monster_ai_charge25, dist: -3.5 },
18311
+ { ai: monster_ai_charge25, dist: -1.1, think: GunnerCmdrGrenade },
18312
+ { ai: monster_ai_charge25, dist: -4.6 },
18313
+ { ai: monster_ai_charge25, dist: 1.9 },
18314
+ { ai: monster_ai_charge25, dist: 1 },
18315
+ { ai: monster_ai_charge25, dist: -4.5 },
18316
+ { ai: monster_ai_charge25, dist: 3.2 },
18317
+ { ai: monster_ai_charge25, dist: 4.4 },
18318
+ { ai: monster_ai_charge25, dist: -6.5 },
18319
+ { ai: monster_ai_charge25, dist: -6.1 },
18320
+ { ai: monster_ai_charge25, dist: 3 },
18321
+ { ai: monster_ai_charge25, dist: -0.7 },
18322
+ { ai: monster_ai_charge25, dist: -1 }
18323
+ ],
18324
+ endfunc: guncmdr_run
18325
+ };
18326
+ attack_grenade_back_dodge_right_move = {
18327
+ firstframe: 601,
18328
+ lastframe: 605,
18329
+ frames: [
18330
+ { ai: monster_ai_charge25, dist: 10.2 },
18331
+ { ai: monster_ai_charge25, dist: 18 },
18332
+ { ai: monster_ai_charge25, dist: 7 },
18333
+ { ai: monster_ai_charge25, dist: 7.2 },
18334
+ { ai: monster_ai_charge25, dist: -2 }
18335
+ ],
18336
+ endfunc: guncmdr_grenade_back_dodge_resume
18337
+ };
18338
+ attack_grenade_back_dodge_left_move = {
18339
+ firstframe: 701,
18340
+ lastframe: 705,
18341
+ frames: [
18342
+ { ai: monster_ai_charge25, dist: 10.2 },
18343
+ { ai: monster_ai_charge25, dist: 18 },
18344
+ { ai: monster_ai_charge25, dist: 7 },
18345
+ { ai: monster_ai_charge25, dist: 7.2 },
18346
+ { ai: monster_ai_charge25, dist: -2 }
18347
+ ],
18348
+ endfunc: guncmdr_grenade_back_dodge_resume
18349
+ };
18350
+ attack_kick_move = {
18351
+ firstframe: 801,
18352
+ lastframe: 808,
18353
+ frames: [
18354
+ { ai: monster_ai_charge25, dist: -7.7 },
18355
+ { ai: monster_ai_charge25, dist: -4.9 },
18356
+ { ai: monster_ai_charge25, dist: 12.6, think: guncmdr_kick },
18357
+ { ai: monster_ai_charge25, dist: 0 },
18358
+ { ai: monster_ai_charge25, dist: -3 },
18359
+ { ai: monster_ai_charge25, dist: 0 },
18360
+ { ai: monster_ai_charge25, dist: -4.1 },
18361
+ { ai: monster_ai_charge25, dist: 8.6 }
18362
+ ],
18363
+ endfunc: guncmdr_kick_finished
18364
+ };
18365
+ duck_attack_move = {
18366
+ firstframe: 901,
18367
+ lastframe: 919,
18368
+ frames: [
18369
+ { ai: monster_ai_move24, dist: 3.6 },
18370
+ { ai: monster_ai_move24, dist: 5.6, think: monster_duck_down },
18371
+ { ai: monster_ai_move24, dist: 8.4 },
18372
+ { ai: monster_ai_move24, dist: 2, think: monster_duck_hold },
18373
+ { ai: monster_ai_charge25, dist: 0 },
18374
+ { ai: monster_ai_charge25, dist: 0 },
18375
+ { ai: monster_ai_charge25, dist: 0 },
18376
+ { ai: monster_ai_charge25, dist: 0 },
18377
+ { ai: monster_ai_charge25, dist: 0 },
18378
+ { ai: monster_ai_charge25, dist: 0 },
18379
+ { ai: monster_ai_charge25, dist: 0 },
18380
+ { ai: monster_ai_charge25, dist: 9.5, think: GunnerCmdrCounter },
18381
+ { ai: monster_ai_charge25, dist: -1.5 },
18382
+ { ai: monster_ai_charge25, dist: 0 },
18383
+ { ai: monster_ai_charge25, dist: 0, think: monster_duck_up },
18384
+ { ai: monster_ai_charge25, dist: 0 },
18385
+ { ai: monster_ai_charge25, dist: 11 },
18386
+ { ai: monster_ai_charge25, dist: 2 },
18387
+ { ai: monster_ai_charge25, dist: 5.6 }
18388
+ ],
18389
+ endfunc: guncmdr_run
18390
+ };
18391
+ jump_move3 = {
18392
+ firstframe: 0,
18393
+ lastframe: 9,
18394
+ frames: [
18395
+ { ai: monster_ai_move24, dist: 0 },
18396
+ { ai: monster_ai_move24, dist: 0 },
18397
+ { ai: monster_ai_move24, dist: 0 },
18398
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_now },
18399
+ { ai: monster_ai_move24, dist: 0 },
18400
+ { ai: monster_ai_move24, dist: 0 },
18401
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18402
+ { ai: monster_ai_move24, dist: 0 },
18403
+ { ai: monster_ai_move24, dist: 0 },
18404
+ { ai: monster_ai_move24, dist: 0 }
18405
+ ],
18406
+ endfunc: guncmdr_run
18407
+ };
18408
+ jump2_move = {
18409
+ firstframe: 0,
18410
+ lastframe: 9,
18411
+ frames: [
18412
+ { ai: monster_ai_move24, dist: -8 },
18413
+ { ai: monster_ai_move24, dist: -4 },
18414
+ { ai: monster_ai_move24, dist: -4 },
18415
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump2_now },
18416
+ { ai: monster_ai_move24, dist: 0 },
18417
+ { ai: monster_ai_move24, dist: 0 },
18418
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18419
+ { ai: monster_ai_move24, dist: 0 },
18420
+ { ai: monster_ai_move24, dist: 0 },
18421
+ { ai: monster_ai_move24, dist: 0 }
18422
+ ],
18423
+ endfunc: guncmdr_run
18424
+ };
18425
+ pain1_move8 = { firstframe: 101, lastframe: 104, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18426
+ pain2_move8 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18427
+ pain3_move7 = { firstframe: 301, lastframe: 304, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18428
+ pain4_move2 = { firstframe: 401, lastframe: 415, frames: Array(15).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18429
+ pain5_move2 = { firstframe: 501, lastframe: 524, frames: Array(24).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18430
+ pain5_move2.frames[5].think = guncmdr_pain5_to_death2;
18431
+ pain5_move2.frames[8].think = guncmdr_pain5_to_death1;
18432
+ pain6_move2 = { firstframe: 601, lastframe: 632, frames: Array(32).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18433
+ pain6_move2.frames[6].think = guncmdr_pain6_to_death6;
18434
+ pain7_move = { firstframe: 701, lastframe: 714, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18435
+ death1_move3 = { firstframe: 101, lastframe: 118, frames: Array(18).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18436
+ death2_move3 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18437
+ death3_move = { firstframe: 301, lastframe: 321, frames: Array(21).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18438
+ death3_move.frames[2].think = guncmdr_shrink;
18439
+ death4_move = { firstframe: 401, lastframe: 436, frames: Array(36).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18440
+ death4_move.frames[2].think = guncmdr_shrink;
18441
+ death5_move = { firstframe: 501, lastframe: 528, frames: Array(28).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18442
+ death6_move = { firstframe: 601, lastframe: 614, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18443
+ death6_move.frames[0].think = guncmdr_shrink;
18444
+ death7_move = { firstframe: 701, lastframe: 730, frames: Array(30).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18445
+ death7_move.frames[2].think = guncmdr_shrink;
18446
+ function SP_monster_guncmdr(self, context) {
18447
+ if (!M_AllowSpawn(self, context.entities)) {
18448
+ context.entities.free(self);
18449
+ return;
18450
+ }
18451
+ self.movetype = 5 /* Step */;
18452
+ self.solid = 2 /* BoundingBox */;
18453
+ self.model = "models/monsters/gunner/tris.md2";
18454
+ self.modelindex = context.entities.modelIndex("models/monsters/gunner/tris.md2");
18455
+ self.monsterinfo.scale = 1.25;
18456
+ self.mins = { x: -16, y: -16, z: -24 };
18457
+ self.maxs = { x: 16, y: 16, z: 36 };
18458
+ self.skin = 2;
18459
+ const healthMultiplier = context.keyValues["health_multiplier"] ? parseFloat(context.keyValues["health_multiplier"]) : 1;
18460
+ self.health = 325 * healthMultiplier;
18461
+ self.max_health = self.health;
18462
+ self.mass = 255;
18463
+ self.pain = (s, o, k, d) => guncmdr_pain(s, context.entities);
18464
+ self.die = (s, i, a, d, p) => guncmdr_die(s, i, a, d, p, context.entities);
18465
+ self.monsterinfo.stand = (s) => guncmdr_stand(s, context.entities);
18466
+ self.monsterinfo.walk = (s) => guncmdr_walk(s, context.entities);
18467
+ self.monsterinfo.run = (s) => guncmdr_run(s, context.entities);
18468
+ self.monsterinfo.dodge = (s, a, e) => M_MonsterDodge(s, a, e);
18469
+ self.monsterinfo.duck = (s, e) => guncmdr_duck(s, e, context.entities);
18470
+ self.monsterinfo.unduck = (s) => monster_duck_up(s, context.entities);
18471
+ self.monsterinfo.sidestep = (s) => guncmdr_sidestep(s, context.entities);
18472
+ self.monsterinfo.attack = (s) => guncmdr_attack(s, context.entities);
18473
+ self.monsterinfo.sight = (s, o) => guncmdr_sight(s, o, context.entities);
18474
+ self.monsterinfo.search = (s) => guncmdr_search(s, context.entities);
18475
+ self.monsterinfo.setskin = (s) => guncmdr_setskin(s, context.entities);
18476
+ self.monsterinfo.power_armor_power = 200;
18477
+ self.monsterinfo.power_armor_type = 1;
18478
+ context.entities.linkentity(self);
18479
+ M_SetAnimation3(self, stand_move21, context.entities);
18480
+ self.think = monster_think;
18481
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK28;
18482
+ }
18483
+ function registerGunCommanderSpawns(registry) {
18484
+ registry.register("monster_guncmdr", SP_monster_guncmdr);
18485
+ }
18486
+
18487
+ // src/entities/monsters/guardian.ts
18488
+ init_esm();
18489
+ var MONSTER_TICK29 = 0.1;
18490
+ var MELEE_DISTANCE6 = 80;
18491
+ var FRAME_idle12 = 76;
18492
+ var FRAME_idle52 = 127;
18493
+ var FRAME_walk13 = 160;
18494
+ var FRAME_walk19 = 178;
18495
+ var FRAME_pain1_1 = 68;
18496
+ var FRAME_pain1_8 = 75;
18497
+ var FRAME_atk1_out1 = 40;
18498
+ var FRAME_atk1_out3 = 42;
18499
+ var FRAME_atk1_spin1 = 184;
18500
+ var FRAME_atk1_spin12 = 195;
18501
+ var FRAME_atk1_spin15 = 198;
18502
+ var FRAME_atk1_in1 = 128;
18503
+ var FRAME_atk1_in3 = 130;
18504
+ var FRAME_atk2_out1 = 43;
18505
+ var FRAME_atk2_out7 = 49;
18506
+ var FRAME_atk2_fire1 = 199;
18507
+ var FRAME_atk2_fire4 = 202;
18508
+ var FRAME_atk2_in1 = 214;
18509
+ var FRAME_atk2_in12 = 225;
18510
+ var FRAME_kick_in1 = 131;
18511
+ var FRAME_kick_in13 = 143;
18512
+ var FRAME_death12 = 14;
18513
+ var FRAME_death26 = 39;
18514
+ var sound_step2 = "zortemp/step.wav";
18515
+ var sound_charge2 = "weapons/hyprbu1a.wav";
18516
+ var sound_laser = "weapons/laser2.wav";
18517
+ var guardian_move_stand;
18518
+ var guardian_move_walk;
18519
+ var guardian_move_run;
18520
+ var guardian_move_pain1;
18521
+ var guardian_atk1_out;
18522
+ var guardian_move_atk1_spin;
18523
+ var guardian_move_atk1_in;
18524
+ var guardian_move_atk2_out;
18525
+ var guardian_move_atk2_fire;
18526
+ var guardian_move_atk2_in;
18527
+ var guardian_move_kick;
18528
+ var guardian_move_death;
18529
+ var guardian_move_atk1_spin_loop;
18530
+ function guardian_ai_stand(self, dist, context) {
18531
+ ai_stand(self, MONSTER_TICK29, context);
18532
+ }
18533
+ function guardian_ai_walk(self, dist, context) {
18534
+ ai_walk(self, dist, MONSTER_TICK29, context);
18535
+ }
18536
+ function guardian_ai_run(self, dist, context) {
18537
+ ai_run(self, dist, MONSTER_TICK29, context);
18538
+ }
18539
+ function guardian_ai_charge(self, dist, context) {
18540
+ ai_charge(self, dist, MONSTER_TICK29, context);
18541
+ }
18542
+ function guardian_ai_move(self, dist, context) {
18543
+ ai_move(self, dist);
18544
+ }
18545
+ function guardian_stand(self, context) {
18546
+ M_SetAnimation3(self, guardian_move_stand, context);
18547
+ }
18548
+ var guardian_frames_stand = Array(52).fill({ ai: guardian_ai_stand, dist: 0 });
18549
+ guardian_move_stand = {
18550
+ firstframe: FRAME_idle12,
18551
+ lastframe: FRAME_idle52,
18552
+ frames: guardian_frames_stand,
18553
+ endfunc: null
18554
+ };
18555
+ function guardian_footstep(self, context) {
18556
+ context.sound(self, 2, sound_step2, 1, 1, 0);
18557
+ }
18558
+ var guardian_frames_walk = [
18559
+ { ai: guardian_ai_walk, dist: 8 },
18560
+ { ai: guardian_ai_walk, dist: 8 },
18561
+ { ai: guardian_ai_walk, dist: 8 },
18562
+ { ai: guardian_ai_walk, dist: 8 },
18563
+ { ai: guardian_ai_walk, dist: 8 },
18564
+ { ai: guardian_ai_walk, dist: 8 },
18565
+ { ai: guardian_ai_walk, dist: 8 },
18566
+ { ai: guardian_ai_walk, dist: 8, think: guardian_footstep },
18567
+ { ai: guardian_ai_walk, dist: 8 },
18568
+ { ai: guardian_ai_walk, dist: 8 },
18569
+ { ai: guardian_ai_walk, dist: 8 },
18570
+ { ai: guardian_ai_walk, dist: 8 },
18571
+ { ai: guardian_ai_walk, dist: 8 },
18572
+ { ai: guardian_ai_walk, dist: 8 },
18573
+ { ai: guardian_ai_walk, dist: 8 },
18574
+ { ai: guardian_ai_walk, dist: 8 },
18575
+ { ai: guardian_ai_walk, dist: 8 },
18576
+ { ai: guardian_ai_walk, dist: 8, think: guardian_footstep },
18577
+ { ai: guardian_ai_walk, dist: 8 }
18578
+ ];
18579
+ guardian_move_walk = {
18580
+ firstframe: FRAME_walk13,
18581
+ lastframe: FRAME_walk19,
18582
+ frames: guardian_frames_walk,
18583
+ endfunc: null
18584
+ };
18585
+ function guardian_walk(self, context) {
18586
+ M_SetAnimation3(self, guardian_move_walk, context);
18587
+ }
18588
+ var guardian_frames_run = [
18589
+ { ai: guardian_ai_run, dist: 8 },
18590
+ { ai: guardian_ai_run, dist: 8 },
18591
+ { ai: guardian_ai_run, dist: 8 },
18592
+ { ai: guardian_ai_run, dist: 8 },
18593
+ { ai: guardian_ai_run, dist: 8 },
18594
+ { ai: guardian_ai_run, dist: 8 },
18595
+ { ai: guardian_ai_run, dist: 8 },
18596
+ { ai: guardian_ai_run, dist: 8, think: guardian_footstep },
18597
+ { ai: guardian_ai_run, dist: 8 },
18598
+ { ai: guardian_ai_run, dist: 8 },
18599
+ { ai: guardian_ai_run, dist: 8 },
18600
+ { ai: guardian_ai_run, dist: 8 },
18601
+ { ai: guardian_ai_run, dist: 8 },
18602
+ { ai: guardian_ai_run, dist: 8 },
18603
+ { ai: guardian_ai_run, dist: 8 },
18604
+ { ai: guardian_ai_run, dist: 8 },
18605
+ { ai: guardian_ai_run, dist: 8 },
18606
+ { ai: guardian_ai_run, dist: 8, think: guardian_footstep },
18607
+ { ai: guardian_ai_run, dist: 8 }
18608
+ ];
18609
+ guardian_move_run = {
18610
+ firstframe: FRAME_walk13,
18611
+ lastframe: FRAME_walk19,
18612
+ frames: guardian_frames_run,
18613
+ endfunc: null
18614
+ };
18615
+ function guardian_run(self, context) {
18616
+ M_SetAnimation3(self, guardian_move_run, context);
18617
+ }
18618
+ var guardian_frames_pain1 = Array(8).fill({ ai: guardian_ai_move, dist: 0 });
18619
+ guardian_move_pain1 = {
18620
+ firstframe: FRAME_pain1_1,
18621
+ lastframe: FRAME_pain1_8,
18622
+ frames: guardian_frames_pain1,
18623
+ endfunc: guardian_run
18624
+ };
18625
+ function guardian_pain(self, other, kick, damage) {
18626
+ if (damage <= 10) return;
18627
+ const frame = self.frame;
18628
+ if (frame >= FRAME_atk1_spin1 && frame <= FRAME_atk1_spin15) return;
18629
+ if (frame >= FRAME_atk2_fire1 && frame <= FRAME_atk2_fire4) return;
18630
+ if (frame >= FRAME_kick_in1 && frame <= FRAME_kick_in13) return;
18631
+ if (!M_ShouldReactToPain(self)) return;
18632
+ M_SetAnimation3(self, guardian_move_pain1, null);
18633
+ }
18634
+ var guardian_frames_atk1_out = [
18635
+ { ai: guardian_ai_charge, dist: 0 },
18636
+ { ai: guardian_ai_charge, dist: 0 },
18637
+ { ai: guardian_ai_charge, dist: 0 }
18638
+ ];
18639
+ guardian_atk1_out = {
18640
+ firstframe: FRAME_atk1_out1,
18641
+ lastframe: FRAME_atk1_out3,
18642
+ frames: guardian_frames_atk1_out,
18643
+ endfunc: guardian_run
18644
+ };
18645
+ function guardian_atk1_finish(self, context) {
18646
+ M_SetAnimation3(self, guardian_atk1_out, context);
18647
+ }
18648
+ function guardian_atk1_charge(self, context) {
18649
+ context.sound(self, 1, sound_charge2, 1, 1, 0);
18650
+ }
18651
+ function guardian_fire_blaster_func(self, context) {
18652
+ if (!self.enemy) return;
18653
+ const { forward, right } = angleVectors(self.angles);
18654
+ const start = addVec3(self.origin, scaleVec3(forward, 20));
18655
+ start.z += self.viewheight ? self.viewheight - 10 : 0;
18656
+ start.x += right.x * 20;
18657
+ start.y += right.y * 20;
18658
+ const target = { ...self.enemy.origin };
18659
+ target.z += self.enemy.viewheight || 0;
18660
+ target.x += (Math.random() * 2 - 1) * 5;
18661
+ target.y += (Math.random() * 2 - 1) * 5;
18662
+ target.z += (Math.random() * 2 - 1) * 5;
18663
+ const dir = normalizeVec3(subtractVec3(target, start));
18664
+ monster_fire_blaster(self, start, dir, 2, 1e3, 0, 0, context, 10 /* HYPERBLASTER */);
18665
+ }
18666
+ function guardian_fire_blaster_loop(self, context) {
18667
+ guardian_fire_blaster_func(self, context);
18668
+ if (self.enemy && self.enemy.health > 0 && self.frame === FRAME_atk1_spin12 && self.timestamp > context.timeSeconds && visible(self, self.enemy, context.trace)) {
18669
+ M_SetAnimation3(self, guardian_move_atk1_spin_loop, context);
18670
+ }
18671
+ }
18672
+ var guardian_frames_atk1_spin = [
18673
+ { ai: guardian_ai_charge, dist: 0, think: guardian_atk1_charge },
18674
+ { ai: guardian_ai_charge, dist: 0 },
18675
+ { ai: guardian_ai_charge, dist: 0 },
18676
+ { ai: guardian_ai_charge, dist: 0 },
18677
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18678
+ // 5
18679
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18680
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18681
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18682
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18683
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18684
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_func },
18685
+ { ai: guardian_ai_charge, dist: 0, think: guardian_fire_blaster_loop },
18686
+ // 12
18687
+ { ai: guardian_ai_charge, dist: 0 },
18688
+ { ai: guardian_ai_charge, dist: 0 },
18689
+ { ai: guardian_ai_charge, dist: 0 }
18690
+ ];
18691
+ guardian_move_atk1_spin = {
18692
+ firstframe: FRAME_atk1_spin1,
18693
+ lastframe: FRAME_atk1_spin15,
18694
+ frames: guardian_frames_atk1_spin,
18695
+ endfunc: guardian_atk1_finish
18696
+ };
18697
+ guardian_move_atk1_spin_loop = {
18698
+ firstframe: FRAME_atk1_spin1 + 4,
18699
+ lastframe: FRAME_atk1_spin15,
18700
+ frames: guardian_frames_atk1_spin.slice(4),
18701
+ endfunc: guardian_atk1_finish
18702
+ };
18703
+ function guardian_atk1(self, context) {
18704
+ M_SetAnimation3(self, guardian_move_atk1_spin, context);
18705
+ self.timestamp = context.timeSeconds + 0.65 + Math.random() * 1.5;
18706
+ }
18707
+ var guardian_frames_atk1_in = [
18708
+ { ai: guardian_ai_charge, dist: 0 },
18709
+ { ai: guardian_ai_charge, dist: 0 },
18710
+ { ai: guardian_ai_charge, dist: 0 }
18711
+ ];
18712
+ guardian_move_atk1_in = {
18713
+ firstframe: FRAME_atk1_in1,
18714
+ lastframe: FRAME_atk1_in3,
18715
+ frames: guardian_frames_atk1_in,
18716
+ endfunc: guardian_atk1
18717
+ };
18718
+ var guardian_frames_atk2_out = [
18719
+ { ai: guardian_ai_charge, dist: 0 },
18720
+ { ai: guardian_ai_charge, dist: 0 },
18721
+ { ai: guardian_ai_charge, dist: 0 },
18722
+ { ai: guardian_ai_charge, dist: 0 },
18723
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18724
+ { ai: guardian_ai_charge, dist: 0 },
18725
+ { ai: guardian_ai_charge, dist: 0 }
18726
+ ];
18727
+ guardian_move_atk2_out = {
18728
+ firstframe: FRAME_atk2_out1,
18729
+ lastframe: FRAME_atk2_out7,
18730
+ frames: guardian_frames_atk2_out,
18731
+ endfunc: guardian_run
18732
+ };
18733
+ function guardian_atk2_out(self, context) {
18734
+ M_SetAnimation3(self, guardian_move_atk2_out, context);
18735
+ }
18736
+ var laser_positions = [
18737
+ { x: 125, y: -70, z: 60 },
18738
+ { x: 112, y: -62, z: 60 }
18739
+ ];
18740
+ function guardian_fire_update(laser, context) {
18741
+ const self = laser.owner;
18742
+ if (!self || !self.inUse) {
18743
+ context.free(laser);
18744
+ return;
18745
+ }
18746
+ const { forward, right } = angleVectors(self.angles);
18747
+ const offset = laser_positions[1 - (self.frame & 1)];
18748
+ const start = addVec3(self.origin, scaleVec3(forward, offset.x));
18749
+ start.z += offset.z;
18750
+ start.x += right.x * offset.y;
18751
+ start.y += right.y * offset.y;
18752
+ start.z += right.z * offset.y;
18753
+ if (!self.enemy) return;
18754
+ const target = addVec3(self.enemy.origin, self.enemy.mins);
18755
+ target.x += Math.random() * self.enemy.size.x;
18756
+ target.y += Math.random() * self.enemy.size.y;
18757
+ target.z += Math.random() * self.enemy.size.z;
18758
+ const dir = normalizeVec3(subtractVec3(target, start));
18759
+ laser.origin = start;
18760
+ laser.movedir = dir;
18761
+ context.linkentity(laser);
18762
+ }
18763
+ function guardian_laser_fire(self, context) {
18764
+ context.sound(self, 1, sound_laser, 1, 1, 0);
18765
+ monster_fire_dabeam(self, 25, self.frame % 2 !== 0, guardian_fire_update, context);
18766
+ }
18767
+ var guardian_frames_atk2_fire = [
18768
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18769
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18770
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire },
18771
+ { ai: guardian_ai_charge, dist: 0, think: guardian_laser_fire }
18772
+ ];
18773
+ guardian_move_atk2_fire = {
18774
+ firstframe: FRAME_atk2_fire1,
18775
+ lastframe: FRAME_atk2_fire4,
18776
+ frames: guardian_frames_atk2_fire,
18777
+ endfunc: guardian_atk2_out
18778
+ };
18779
+ function guardian_atk2(self, context) {
18780
+ M_SetAnimation3(self, guardian_move_atk2_fire, context);
18781
+ }
18782
+ var guardian_frames_atk2_in = [
18783
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18784
+ { ai: guardian_ai_charge, dist: 0 },
18785
+ { ai: guardian_ai_charge, dist: 0 },
18786
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18787
+ { ai: guardian_ai_charge, dist: 0 },
18788
+ { ai: guardian_ai_charge, dist: 0 },
18789
+ { ai: guardian_ai_charge, dist: 0 },
18790
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18791
+ { ai: guardian_ai_charge, dist: 0 },
18792
+ { ai: guardian_ai_charge, dist: 0 },
18793
+ { ai: guardian_ai_charge, dist: 0 },
18794
+ { ai: guardian_ai_charge, dist: 0 }
18795
+ ];
18796
+ guardian_move_atk2_in = {
18797
+ firstframe: FRAME_atk2_in1,
18798
+ lastframe: FRAME_atk2_in12,
18799
+ frames: guardian_frames_atk2_in,
18800
+ endfunc: guardian_atk2
18801
+ };
18802
+ function guardian_kick(self, context) {
18803
+ const aim = { x: MELEE_DISTANCE6, y: 0, z: -80 };
18804
+ if (!monster_fire_hit(self, aim, 85, 700, context)) {
18805
+ self.monsterinfo.melee_debounce_time = context.timeSeconds + 1;
18806
+ }
18807
+ }
18808
+ var guardian_frames_kick = [
18809
+ { ai: guardian_ai_charge, dist: 0 },
18810
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18811
+ { ai: guardian_ai_charge, dist: 0 },
18812
+ { ai: guardian_ai_charge, dist: 0 },
18813
+ { ai: guardian_ai_charge, dist: 0 },
18814
+ { ai: guardian_ai_charge, dist: 0, think: guardian_kick },
18815
+ { ai: guardian_ai_charge, dist: 0 },
18816
+ { ai: guardian_ai_charge, dist: 0 },
18817
+ { ai: guardian_ai_charge, dist: 0 },
18818
+ { ai: guardian_ai_charge, dist: 0 },
18819
+ { ai: guardian_ai_charge, dist: 0, think: guardian_footstep },
18820
+ { ai: guardian_ai_charge, dist: 0 },
18821
+ { ai: guardian_ai_charge, dist: 0 }
18822
+ ];
18823
+ guardian_move_kick = {
18824
+ firstframe: FRAME_kick_in1,
18825
+ lastframe: FRAME_kick_in13,
18826
+ frames: guardian_frames_kick,
18827
+ endfunc: guardian_run
18828
+ };
18829
+ function guardian_attack(self, context) {
18830
+ if (!self.enemy || !self.enemy.inUse) return;
18831
+ const r = rangeTo(self, self.enemy);
18832
+ if (r > 500) {
18833
+ M_SetAnimation3(self, guardian_move_atk2_in, context);
18834
+ } else if (context.timeSeconds > (self.monsterinfo.melee_debounce_time ?? 0) && r < 120) {
18835
+ M_SetAnimation3(self, guardian_move_kick, context);
18836
+ } else {
18837
+ M_SetAnimation3(self, guardian_move_atk1_in, context);
18838
+ }
18839
+ }
18840
+ function guardian_explode(self, context) {
18841
+ const org = {
18842
+ x: self.origin.x + self.mins.x + Math.random() * self.size.x,
18843
+ y: self.origin.y + self.mins.y + Math.random() * self.size.y,
18844
+ z: self.origin.z + self.mins.z + Math.random() * self.size.z
18845
+ };
18846
+ context.multicast(self.origin, 0 /* All */, ServerCommand.temp_entity, TempEntity.EXPLOSION1_BIG, org);
18847
+ }
18848
+ function guardian_dead(self, context) {
18849
+ for (let i = 0; i < 3; i++) {
18850
+ guardian_explode(self, context);
18851
+ }
18852
+ throwGibs(context, self.origin, 250, GIB_METALLIC);
18853
+ self.nextthink = -1;
18854
+ }
18855
+ function BossExplode(self, context) {
18856
+ guardian_explode(self, context);
18857
+ }
18858
+ var guardian_frames_death1 = [
18859
+ { ai: guardian_ai_move, dist: 0, think: BossExplode },
18860
+ { ai: guardian_ai_move, dist: 0 },
18861
+ { ai: guardian_ai_move, dist: 0 },
18862
+ { ai: guardian_ai_move, dist: 0 },
18863
+ { ai: guardian_ai_move, dist: 0 },
18864
+ { ai: guardian_ai_move, dist: 0 },
18865
+ { ai: guardian_ai_move, dist: 0 },
18866
+ { ai: guardian_ai_move, dist: 0 },
18867
+ { ai: guardian_ai_move, dist: 0 },
18868
+ { ai: guardian_ai_move, dist: 0 },
18869
+ { ai: guardian_ai_move, dist: 0 },
18870
+ { ai: guardian_ai_move, dist: 0 },
18871
+ { ai: guardian_ai_move, dist: 0 },
18872
+ { ai: guardian_ai_move, dist: 0 },
18873
+ { ai: guardian_ai_move, dist: 0 },
18874
+ { ai: guardian_ai_move, dist: 0 },
18875
+ { ai: guardian_ai_move, dist: 0 },
18876
+ { ai: guardian_ai_move, dist: 0 },
18877
+ { ai: guardian_ai_move, dist: 0 },
18878
+ { ai: guardian_ai_move, dist: 0 },
18879
+ { ai: guardian_ai_move, dist: 0 },
18880
+ { ai: guardian_ai_move, dist: 0 },
18881
+ { ai: guardian_ai_move, dist: 0 },
18882
+ { ai: guardian_ai_move, dist: 0 },
18883
+ { ai: guardian_ai_move, dist: 0 },
18884
+ { ai: guardian_ai_move, dist: 0 }
18885
+ ];
18886
+ guardian_move_death = {
18887
+ firstframe: FRAME_death12,
18888
+ lastframe: FRAME_death26,
18889
+ frames: guardian_frames_death1,
18890
+ endfunc: guardian_dead
18891
+ };
18892
+ function SP_monster_guardian(self, context) {
18893
+ if (!M_AllowSpawn(self, context.entities)) {
18894
+ context.entities.free(self);
18895
+ return;
18896
+ }
18897
+ self.classname = "monster_guardian";
18898
+ self.model = "models/monsters/guardian/tris.md2";
18899
+ self.mins = { x: -96, y: -96, z: -66 };
18900
+ self.maxs = { x: 96, y: 96, z: 62 };
18901
+ self.movetype = 5 /* Step */;
18902
+ self.solid = 2 /* BoundingBox */;
18903
+ self.health = 2500;
18904
+ self.mass = 850;
18905
+ self.pain = (ent, other, kick, damage) => {
18906
+ guardian_pain(ent, other, kick, damage);
18907
+ };
18908
+ self.die = (ent, inflictor, attacker, damage, point, mod) => {
18909
+ ent.deadflag = 2 /* Dead */;
18910
+ ent.takedamage = true;
18911
+ if (ent.health < -200) {
18912
+ guardian_dead(ent, context.entities);
18913
+ context.entities.free(ent);
18914
+ return;
18915
+ }
18916
+ M_SetAnimation3(ent, guardian_move_death, context.entities);
18917
+ };
18918
+ self.monsterinfo.stand = guardian_stand;
18919
+ self.monsterinfo.walk = guardian_walk;
18920
+ self.monsterinfo.run = guardian_run;
18921
+ self.monsterinfo.attack = guardian_attack;
18922
+ self.monsterinfo.melee_debounce_time = 0;
18923
+ context.entities.linkentity(self);
18924
+ M_SetAnimation3(self, guardian_move_stand, context.entities);
18925
+ self.think = monster_think;
18926
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK29;
18927
+ }
18928
+ function registerGuardianSpawns(registry) {
18929
+ registry.register("monster_guardian", SP_monster_guardian);
18930
+ }
18931
+
17647
18932
  // src/entities/monsters/index.ts
17648
18933
  function registerMonsterSpawns2(registry) {
17649
18934
  registerMonsterSpawns(registry);
@@ -17673,6 +18958,8 @@ function registerMonsterSpawns2(registry) {
17673
18958
  registerGekkSpawns(registry);
17674
18959
  registerFixbotSpawns(registry);
17675
18960
  registerArachnidSpawns(registry);
18961
+ registerGunCommanderSpawns(registry);
18962
+ registerGuardianSpawns(registry);
17676
18963
  }
17677
18964
 
17678
18965
  // src/entities/worldspawn.ts
@@ -19615,7 +20902,7 @@ var WEAPONS = {
19615
20902
  };
19616
20903
 
19617
20904
  // src/index.ts
19618
- var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
20905
+ var ZERO_VEC39 = { x: 0, y: 0, z: 0 };
19619
20906
  function createGame(imports, engine, options) {
19620
20907
  const gravity = options.gravity;
19621
20908
  const deathmatch = options.deathmatch ?? false;
@@ -19694,8 +20981,8 @@ function createGame(imports, engine, options) {
19694
20981
  };
19695
20982
  entities.runFrame();
19696
20983
  });
19697
- let origin = { ...ZERO_VEC38 };
19698
- let velocity = { ...ZERO_VEC38 };
20984
+ let origin = { ...ZERO_VEC39 };
20985
+ let velocity = { ...ZERO_VEC39 };
19699
20986
  const calculateBlend = (player, time) => {
19700
20987
  const blend = [0, 0, 0, 0];
19701
20988
  if (!player || !player.client) return blend;
@@ -19777,10 +21064,10 @@ function createGame(imports, engine, options) {
19777
21064
  // TODO
19778
21065
  damageIndicators: [],
19779
21066
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
19780
- kick_angles: player?.client?.kick_angles ?? ZERO_VEC38,
19781
- kick_origin: player?.client?.kick_origin ?? ZERO_VEC38,
19782
- gunoffset: ZERO_VEC38,
19783
- gunangles: ZERO_VEC38,
21067
+ kick_angles: player?.client?.kick_angles ?? ZERO_VEC39,
21068
+ kick_origin: player?.client?.kick_origin ?? ZERO_VEC39,
21069
+ gunoffset: ZERO_VEC39,
21070
+ gunangles: ZERO_VEC39,
19784
21071
  gunindex: 0,
19785
21072
  gun_frame: player?.client?.gun_frame ?? 0,
19786
21073
  rdflags: player?.client?.rdflags ?? 0,
@@ -19794,8 +21081,8 @@ function createGame(imports, engine, options) {
19794
21081
  const resetState = (startTimeMs) => {
19795
21082
  frameLoop.reset(startTimeMs);
19796
21083
  levelClock.start(startTimeMs);
19797
- origin = { ...ZERO_VEC38 };
19798
- velocity = { ...ZERO_VEC38 };
21084
+ origin = { ...ZERO_VEC39 };
21085
+ velocity = { ...ZERO_VEC39 };
19799
21086
  entities.beginFrame(startTimeMs / 1e3);
19800
21087
  entities.runFrame();
19801
21088
  };
@@ -19823,10 +21110,10 @@ function createGame(imports, engine, options) {
19823
21110
  blend: [0, 0, 0, 0],
19824
21111
  // Stubs
19825
21112
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
19826
- kick_angles: ZERO_VEC38,
19827
- kick_origin: ZERO_VEC38,
19828
- gunoffset: ZERO_VEC38,
19829
- gunangles: ZERO_VEC38,
21113
+ kick_angles: ZERO_VEC39,
21114
+ kick_origin: ZERO_VEC39,
21115
+ gunoffset: ZERO_VEC39,
21116
+ gunangles: ZERO_VEC39,
19830
21117
  gunindex: 0,
19831
21118
  pm_type: 0,
19832
21119
  pm_time: 0,
@@ -19962,8 +21249,8 @@ function createGame(imports, engine, options) {
19962
21249
  rng,
19963
21250
  player: player?.client?.inventory
19964
21251
  });
19965
- origin = player ? { ...player.origin } : { ...ZERO_VEC38 };
19966
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC38 };
21252
+ origin = player ? { ...player.origin } : { ...ZERO_VEC39 };
21253
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC39 };
19967
21254
  frameLoop.reset(save.level.timeSeconds * 1e3);
19968
21255
  }
19969
21256
  };
@@ -19998,6 +21285,7 @@ export {
19998
21285
  M_CheckBottom,
19999
21286
  M_MoveFrame,
20000
21287
  M_walkmove,
21288
+ MonsterAttackState,
20001
21289
  MoveType,
20002
21290
  MulticastType,
20003
21291
  ORDERED_DAMAGE_MODS,