quake2ts 0.0.303 → 0.0.305

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 (27) 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 +843 -0
  13. package/packages/game/dist/cjs/index.cjs.map +1 -1
  14. package/packages/game/dist/esm/index.js +842 -0
  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/gunnerCommander.d.ts +5 -0
  26. package/packages/game/dist/types/entities/monsters/gunnerCommander.d.ts.map +1 -0
  27. package/packages/game/dist/types/entities/monsters/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";
@@ -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,782 @@ 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
+
17647
18487
  // src/entities/monsters/index.ts
17648
18488
  function registerMonsterSpawns2(registry) {
17649
18489
  registerMonsterSpawns(registry);
@@ -17673,6 +18513,7 @@ function registerMonsterSpawns2(registry) {
17673
18513
  registerGekkSpawns(registry);
17674
18514
  registerFixbotSpawns(registry);
17675
18515
  registerArachnidSpawns(registry);
18516
+ registerGunCommanderSpawns(registry);
17676
18517
  }
17677
18518
 
17678
18519
  // src/entities/worldspawn.ts
@@ -19998,6 +20839,7 @@ export {
19998
20839
  M_CheckBottom,
19999
20840
  M_MoveFrame,
20000
20841
  M_walkmove,
20842
+ MonsterAttackState,
20001
20843
  MoveType,
20002
20844
  MulticastType,
20003
20845
  ORDERED_DAMAGE_MODS,