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
@@ -2455,6 +2455,7 @@ __export(index_exports, {
2455
2455
  M_CheckBottom: () => M_CheckBottom,
2456
2456
  M_MoveFrame: () => M_MoveFrame,
2457
2457
  M_walkmove: () => M_walkmove,
2458
+ MonsterAttackState: () => MonsterAttackState,
2458
2459
  MoveType: () => MoveType,
2459
2460
  MulticastType: () => MulticastType,
2460
2461
  ORDERED_DAMAGE_MODS: () => ORDERED_DAMAGE_MODS,
@@ -3011,6 +3012,7 @@ var AttackState = /* @__PURE__ */ ((AttackState2) => {
3011
3012
  AttackState2[AttackState2["Blind"] = 4] = "Blind";
3012
3013
  return AttackState2;
3013
3014
  })(AttackState || {});
3015
+ var MonsterAttackState = AttackState;
3014
3016
  var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
3015
3017
  TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
3016
3018
  TraceMask2[TraceMask2["Window"] = 2] = "Window";
@@ -5446,6 +5448,52 @@ function createBfgBall(sys, owner, start, dir, damage, speed, damageRadius) {
5446
5448
  sys.scheduleThink(bfgBall, sys.timeSeconds + 0.016);
5447
5449
  sys.finalizeSpawn(bfgBall);
5448
5450
  }
5451
+ function createFlechette(sys, owner, start, dir, damage, speed) {
5452
+ const flechette = sys.spawn();
5453
+ flechette.classname = "flechette";
5454
+ flechette.owner = owner;
5455
+ flechette.origin = { ...start };
5456
+ flechette.velocity = { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed };
5457
+ flechette.movetype = 8 /* FlyMissile */;
5458
+ flechette.solid = 2 /* BoundingBox */;
5459
+ flechette.modelindex = sys.modelIndex("models/objects/projectile/tris.md2");
5460
+ flechette.mins = { x: -2, y: -2, z: -2 };
5461
+ flechette.maxs = { x: 2, y: 2, z: 2 };
5462
+ flechette.angles = vectorToAngles(dir);
5463
+ flechette.touch = (self, other, plane, surf) => {
5464
+ if (other === self.owner) {
5465
+ return;
5466
+ }
5467
+ if (other && other.takedamage) {
5468
+ T_Damage(
5469
+ other,
5470
+ self,
5471
+ self.owner,
5472
+ self.velocity,
5473
+ self.origin,
5474
+ plane ? plane.normal : ZERO_VEC3,
5475
+ damage,
5476
+ 1,
5477
+ 0 /* NONE */,
5478
+ 43 /* ETF_RIFLE */,
5479
+ // Assuming this exists or falls under UNKNOWN
5480
+ sys.timeSeconds,
5481
+ sys.multicast ? sys.multicast.bind(sys) : void 0
5482
+ );
5483
+ if (other.monsterinfo) {
5484
+ const time = sys.timeSeconds || 0;
5485
+ other.monsterinfo.freeze_time = time + 3;
5486
+ }
5487
+ sys.free(self);
5488
+ return;
5489
+ }
5490
+ if (plane) {
5491
+ sys.multicast(self.origin, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.SPARKS, self.origin, plane.normal);
5492
+ }
5493
+ sys.free(self);
5494
+ };
5495
+ sys.finalizeSpawn(flechette);
5496
+ }
5449
5497
 
5450
5498
  // src/entities/targets.ts
5451
5499
  var ATTN_NONE = 0;
@@ -9683,6 +9731,9 @@ function monster_fire_dabeam(self, damage, secondary, update_func, context) {
9683
9731
  update_func(beam, context);
9684
9732
  dabeam_update(beam, context);
9685
9733
  }
9734
+ function monster_fire_flechette(self, start, dir, damage, speed, flashtype, context) {
9735
+ createFlechette(context, self, start, dir, damage, speed);
9736
+ }
9686
9737
 
9687
9738
  // src/entities/monsters/boss2.ts
9688
9739
  init_esm();
@@ -17424,6 +17475,20 @@ function M_ProjectFlashSource(self, offset, forward, right) {
17424
17475
  const start3 = addVec3(start2, { x: 0, y: 0, z: offset.z });
17425
17476
  return start3;
17426
17477
  }
17478
+ function M_MonsterDodge(self, attacker, eta) {
17479
+ }
17480
+ function M_CheckClearShot(self, offset, context) {
17481
+ if (!self.enemy) return false;
17482
+ const start = { ...self.origin };
17483
+ start.z += self.viewheight;
17484
+ const end = { ...self.enemy.origin };
17485
+ end.z += self.enemy.viewheight;
17486
+ const tr = context.trace(start, end, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
17487
+ if (tr.fraction === 1 || tr.ent === self.enemy) {
17488
+ return true;
17489
+ }
17490
+ return false;
17491
+ }
17427
17492
 
17428
17493
  // src/entities/monsters/arachnid.ts
17429
17494
  var FRAME_rails1 = 0;
@@ -17803,6 +17868,782 @@ function registerArachnidSpawns(registry) {
17803
17868
  registry.register("monster_arachnid", SP_monster_arachnid);
17804
17869
  }
17805
17870
 
17871
+ // src/entities/monsters/gunnerCommander.ts
17872
+ init_esm();
17873
+ var MONSTER_TICK28 = 0.1;
17874
+ var MORTAR_SPEED = 850;
17875
+ var GRENADE_SPEED = 600;
17876
+ var MZ2_GUNCMDR_CHAINGUN_1 = 1;
17877
+ var MZ2_GUNCMDR_CHAINGUN_2 = 2;
17878
+ var MZ2_GUNCMDR_GRENADE_MORTAR_1 = 3;
17879
+ var MZ2_GUNCMDR_GRENADE_MORTAR_2 = 4;
17880
+ var MZ2_GUNCMDR_GRENADE_MORTAR_3 = 5;
17881
+ var MZ2_GUNCMDR_GRENADE_FRONT_1 = 6;
17882
+ var MZ2_GUNCMDR_GRENADE_FRONT_2 = 7;
17883
+ var MZ2_GUNCMDR_GRENADE_FRONT_3 = 8;
17884
+ var MZ2_GUNCMDR_GRENADE_CROUCH_1 = 9;
17885
+ var MZ2_GUNCMDR_GRENADE_CROUCH_2 = 10;
17886
+ var MZ2_GUNCMDR_GRENADE_CROUCH_3 = 11;
17887
+ var monster_flash_offset = {
17888
+ [MZ2_GUNCMDR_CHAINGUN_1]: { x: 37, y: -4, z: 12.5 },
17889
+ [MZ2_GUNCMDR_CHAINGUN_2]: { x: 37, y: -4, z: 12.5 },
17890
+ [MZ2_GUNCMDR_GRENADE_MORTAR_1]: { x: 14, y: 7, z: 27.5 },
17891
+ [MZ2_GUNCMDR_GRENADE_MORTAR_2]: { x: 14, y: 7, z: 27.5 },
17892
+ [MZ2_GUNCMDR_GRENADE_MORTAR_3]: { x: 14, y: 7, z: 27.5 },
17893
+ [MZ2_GUNCMDR_GRENADE_FRONT_1]: { x: 19, y: 7, z: 13.5 },
17894
+ [MZ2_GUNCMDR_GRENADE_FRONT_2]: { x: 19, y: 7, z: 13.5 },
17895
+ [MZ2_GUNCMDR_GRENADE_FRONT_3]: { x: 19, y: 7, z: 13.5 },
17896
+ [MZ2_GUNCMDR_GRENADE_CROUCH_1]: { x: 19, y: 7, z: 13.5 },
17897
+ [MZ2_GUNCMDR_GRENADE_CROUCH_2]: { x: 19, y: 7, z: 13.5 },
17898
+ [MZ2_GUNCMDR_GRENADE_CROUCH_3]: { x: 19, y: 7, z: 13.5 }
17899
+ };
17900
+ function monster_ai_stand24(self, dist, context) {
17901
+ ai_stand(self, MONSTER_TICK28, context);
17902
+ }
17903
+ function monster_ai_walk23(self, dist, context) {
17904
+ ai_walk(self, dist, MONSTER_TICK28, context);
17905
+ }
17906
+ function monster_ai_run24(self, dist, context) {
17907
+ ai_run(self, dist, MONSTER_TICK28, context);
17908
+ }
17909
+ function monster_ai_charge25(self, dist, context) {
17910
+ ai_charge(self, dist, MONSTER_TICK28, context);
17911
+ }
17912
+ function monster_ai_move24(self, dist, context) {
17913
+ ai_move(self, dist);
17914
+ }
17915
+ var stand_move21;
17916
+ var fidget_move4;
17917
+ var walk_move18;
17918
+ var run_move20;
17919
+ var attack_chain_move3;
17920
+ var fire_chain_move2;
17921
+ var fire_chain_run_move;
17922
+ var fire_chain_dodge_right_move;
17923
+ var fire_chain_dodge_left_move;
17924
+ var endfire_chain_move2;
17925
+ var attack_mortar_move;
17926
+ var attack_mortar_dodge_move;
17927
+ var attack_grenade_back_move;
17928
+ var attack_grenade_back_dodge_right_move;
17929
+ var attack_grenade_back_dodge_left_move;
17930
+ var attack_kick_move;
17931
+ var duck_attack_move;
17932
+ var jump_move3;
17933
+ var jump2_move;
17934
+ var pain1_move8;
17935
+ var pain2_move8;
17936
+ var pain3_move7;
17937
+ var pain4_move2;
17938
+ var pain5_move2;
17939
+ var pain6_move2;
17940
+ var pain7_move;
17941
+ var death1_move3;
17942
+ var death2_move3;
17943
+ var death3_move;
17944
+ var death4_move;
17945
+ var death5_move;
17946
+ var death6_move;
17947
+ var death7_move;
17948
+ function guncmdr_idlesound(self, context) {
17949
+ context.engine.sound?.(self, 0, "guncmdr/gcdridle1.wav", 1, 1, 0);
17950
+ }
17951
+ function guncmdr_sight(self, other, context) {
17952
+ context.engine.sound?.(self, 0, "guncmdr/sight1.wav", 1, 1, 0);
17953
+ }
17954
+ function guncmdr_search(self, context) {
17955
+ context.engine.sound?.(self, 0, "guncmdr/gcdrsrch1.wav", 1, 1, 0);
17956
+ }
17957
+ function guncmdr_opengun(self, context) {
17958
+ context.engine.sound?.(self, 0, "guncmdr/gcdratck1.wav", 1, 1, 0);
17959
+ }
17960
+ function guncmdr_fidget(self, context) {
17961
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) return;
17962
+ if (self.enemy) return;
17963
+ if (Math.random() <= 0.05) {
17964
+ M_SetAnimation3(self, fidget_move4, context);
17965
+ }
17966
+ }
17967
+ function guncmdr_stand(self, context) {
17968
+ M_SetAnimation3(self, stand_move21, context);
17969
+ }
17970
+ function guncmdr_walk(self, context) {
17971
+ M_SetAnimation3(self, walk_move18, context);
17972
+ }
17973
+ function monster_done_dodge2(self) {
17974
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
17975
+ }
17976
+ function guncmdr_run(self, context) {
17977
+ monster_done_dodge2(self);
17978
+ if (self.monsterinfo.aiflags & 1 /* StandGround */) {
17979
+ M_SetAnimation3(self, stand_move21, context);
17980
+ } else {
17981
+ M_SetAnimation3(self, run_move20, context);
17982
+ }
17983
+ }
17984
+ function guncmdr_fire_chain(self, context) {
17985
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
17986
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
17987
+ if (dist > 400 && ai_move(self, 8)) {
17988
+ M_SetAnimation3(self, fire_chain_run_move, context);
17989
+ return;
17990
+ }
17991
+ }
17992
+ M_SetAnimation3(self, fire_chain_move2, context);
17993
+ }
17994
+ function guncmdr_refire_chain(self, context) {
17995
+ monster_done_dodge2(self);
17996
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
17997
+ if (self.enemy && self.enemy.health > 0) {
17998
+ if (visible(self, self.enemy, context.trace)) {
17999
+ if (Math.random() <= 0.5) {
18000
+ if (!(self.monsterinfo.aiflags & 1 /* StandGround */) && self.enemy) {
18001
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18002
+ if (dist > 400 && ai_move(self, 8)) {
18003
+ M_SetAnimation3(self, fire_chain_run_move, context);
18004
+ return;
18005
+ }
18006
+ }
18007
+ M_SetAnimation3(self, fire_chain_move2, context);
18008
+ return;
18009
+ }
18010
+ }
18011
+ }
18012
+ M_SetAnimation3(self, endfire_chain_move2, context);
18013
+ }
18014
+ function GunnerCmdrFire(self, context) {
18015
+ if (!self.enemy || !self.enemy.inUse) return;
18016
+ let flash_number;
18017
+ if (self.monsterinfo.current_move === fire_chain_dodge_right_move || self.monsterinfo.current_move === fire_chain_dodge_left_move) {
18018
+ flash_number = MZ2_GUNCMDR_CHAINGUN_2;
18019
+ } else {
18020
+ flash_number = MZ2_GUNCMDR_CHAINGUN_1;
18021
+ }
18022
+ const { forward, right } = angleVectors(self.angles);
18023
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
18024
+ let aim = normalizeVec3(subtractVec3(self.enemy.origin, start));
18025
+ const randomAim = { ...aim };
18026
+ for (let i = 0; i < 3; i++) {
18027
+ randomAim.x += (Math.random() - 0.5) * 0.05;
18028
+ randomAim.y += (Math.random() - 0.5) * 0.05;
18029
+ randomAim.z += (Math.random() - 0.5) * 0.05;
18030
+ }
18031
+ aim = normalizeVec3(randomAim);
18032
+ monster_fire_flechette(self, start, aim, 4, 800, flash_number, context);
18033
+ }
18034
+ function GunnerCmdrGrenade(self, context) {
18035
+ if (!self.enemy || !self.enemy.inUse) return;
18036
+ let spread = 0;
18037
+ let flash_number = 0;
18038
+ const frameIndex = self.frame;
18039
+ if (self.monsterinfo.current_move === attack_mortar_move) {
18040
+ const offset = frameIndex - attack_mortar_move.firstframe;
18041
+ if (offset === 4) {
18042
+ spread = -0.1;
18043
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_1;
18044
+ } else if (offset === 7) {
18045
+ spread = 0;
18046
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_2;
18047
+ } else if (offset === 10) {
18048
+ spread = 0.1;
18049
+ flash_number = MZ2_GUNCMDR_GRENADE_MORTAR_3;
18050
+ }
18051
+ } else if (self.monsterinfo.current_move === attack_grenade_back_move) {
18052
+ const offset = frameIndex - attack_grenade_back_move.firstframe;
18053
+ if (offset === 2) {
18054
+ spread = -0.1;
18055
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_1;
18056
+ } else if (offset === 5) {
18057
+ spread = 0;
18058
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_2;
18059
+ } else if (offset === 8) {
18060
+ spread = 0.1;
18061
+ flash_number = MZ2_GUNCMDR_GRENADE_FRONT_3;
18062
+ }
18063
+ }
18064
+ if (flash_number === 0) return;
18065
+ const { forward, right, up } = angleVectors(self.angles);
18066
+ const start = M_ProjectFlashSource(self, monster_flash_offset[flash_number], forward, right);
18067
+ let aim;
18068
+ let pitch = 0;
18069
+ const target = self.enemy.origin;
18070
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_FRONT_1 && flash_number <= MZ2_GUNCMDR_GRENADE_FRONT_3) {
18071
+ pitch -= 0.05;
18072
+ }
18073
+ if (flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3) {
18074
+ let distVector = subtractVec3(target, self.origin);
18075
+ let dist = lengthVec3(distVector);
18076
+ if (dist > 512 && distVector.z < 64 && distVector.z > -64) {
18077
+ const newZ = distVector.z + (dist - 512);
18078
+ distVector = { ...distVector, z: newZ };
18079
+ }
18080
+ distVector = normalizeVec3(distVector);
18081
+ let p = distVector.z;
18082
+ if (p > 0.4) p = 0.4;
18083
+ else if (p < -0.5) p = -0.5;
18084
+ if (self.enemy.absmin.z - self.absmax.z > 16) {
18085
+ p += 0.5;
18086
+ }
18087
+ pitch += p;
18088
+ }
18089
+ aim = normalizeVec3(addVec3(addVec3(forward, scaleVec3(right, spread)), scaleVec3(up, pitch)));
18090
+ let speed = flash_number >= MZ2_GUNCMDR_GRENADE_MORTAR_1 && flash_number <= MZ2_GUNCMDR_GRENADE_MORTAR_3 ? MORTAR_SPEED : GRENADE_SPEED;
18091
+ createGrenade(context, self, start, aim, 50, speed);
18092
+ }
18093
+ function guncmdr_grenade_mortar_resume(self, context) {
18094
+ M_SetAnimation3(self, attack_mortar_move, context);
18095
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
18096
+ self.frame = self.count;
18097
+ }
18098
+ function guncmdr_grenade_back_dodge_resume(self, context) {
18099
+ M_SetAnimation3(self, attack_grenade_back_move, context);
18100
+ self.monsterinfo.attack_state = MonsterAttackState.Straight;
18101
+ self.frame = self.count;
18102
+ }
18103
+ function guncmdr_kick_finished(self, context) {
18104
+ self.monsterinfo.melee_debounce_time = context.timeSeconds + 3;
18105
+ if (self.monsterinfo.attack) {
18106
+ self.monsterinfo.attack(self, context);
18107
+ }
18108
+ }
18109
+ function guncmdr_kick(self, context) {
18110
+ if (!self.enemy) return;
18111
+ const dist = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18112
+ if (dist < 100) {
18113
+ if (self.enemy.client && self.enemy.velocity.z < 270) {
18114
+ self.enemy.velocity = { ...self.enemy.velocity, z: 270 };
18115
+ }
18116
+ }
18117
+ }
18118
+ function monster_duck_down(self, context) {
18119
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) return;
18120
+ self.monsterinfo.aiflags |= 2048 /* Ducked */;
18121
+ self.maxs = { ...self.maxs, z: self.maxs.z - 32 };
18122
+ self.takedamage = true;
18123
+ self.monsterinfo.pausetime = context.timeSeconds + 1;
18124
+ }
18125
+ function monster_duck_hold(self, context) {
18126
+ if (context.timeSeconds >= self.monsterinfo.pausetime) {
18127
+ self.monsterinfo.aiflags &= ~128 /* HoldFrame */;
18128
+ } else {
18129
+ self.monsterinfo.aiflags |= 128 /* HoldFrame */;
18130
+ }
18131
+ }
18132
+ function monster_duck_up(self, context) {
18133
+ self.monsterinfo.aiflags &= ~2048 /* Ducked */;
18134
+ self.maxs = { ...self.maxs, z: self.maxs.z + 32 };
18135
+ self.takedamage = true;
18136
+ }
18137
+ function guncmdr_jump_now(self, context) {
18138
+ const { forward, up } = angleVectors(self.angles);
18139
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 100));
18140
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 300));
18141
+ }
18142
+ function guncmdr_jump2_now(self, context) {
18143
+ const { forward, up } = angleVectors(self.angles);
18144
+ self.velocity = addVec3(self.velocity, scaleVec3(forward, 150));
18145
+ self.velocity = addVec3(self.velocity, scaleVec3(up, 400));
18146
+ }
18147
+ function guncmdr_jump_wait_land(self, context) {
18148
+ if (self.groundentity === null) {
18149
+ self.monsterinfo.nextframe = self.frame;
18150
+ } else {
18151
+ self.monsterinfo.nextframe = self.frame + 1;
18152
+ }
18153
+ }
18154
+ function GunnerCmdrCounter(self, context) {
18155
+ context.engine.sound?.(self, 0, "weapons/rocklx1a.wav", 1, 1, 0);
18156
+ }
18157
+ function guncmdr_attack(self, context) {
18158
+ monster_done_dodge2(self);
18159
+ const d = lengthVec3(subtractVec3(self.enemy.origin, self.origin));
18160
+ const { forward, right } = angleVectors(self.angles);
18161
+ const RANGE_GRENADE = 100;
18162
+ const RANGE_GRENADE_MORTAR = 525;
18163
+ const RANGE_MELEE3 = 64;
18164
+ if (d < RANGE_MELEE3 && (self.monsterinfo.melee_debounce_time === void 0 || self.monsterinfo.melee_debounce_time < context.timeSeconds)) {
18165
+ M_SetAnimation3(self, attack_kick_move, context);
18166
+ } else if (d <= RANGE_GRENADE && M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_CHAINGUN_1], context)) {
18167
+ M_SetAnimation3(self, attack_chain_move3, context);
18168
+ } else if ((d >= RANGE_GRENADE_MORTAR || Math.abs(self.absmin.z - self.enemy.absmax.z) > 64) && M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_GRENADE_MORTAR_1], context)) {
18169
+ M_SetAnimation3(self, attack_mortar_move, context);
18170
+ monster_duck_down(self, context);
18171
+ } else if (M_CheckClearShot(self, monster_flash_offset[MZ2_GUNCMDR_GRENADE_FRONT_1], context) && !(self.monsterinfo.aiflags & 1 /* StandGround */)) {
18172
+ M_SetAnimation3(self, attack_grenade_back_move, context);
18173
+ } else if (self.monsterinfo.aiflags & 1 /* StandGround */) {
18174
+ M_SetAnimation3(self, attack_chain_move3, context);
18175
+ } else {
18176
+ M_SetAnimation3(self, attack_chain_move3, context);
18177
+ }
18178
+ }
18179
+ function guncmdr_pain5_to_death1(self, context) {
18180
+ if (self.health < 0) M_SetAnimation3(self, death1_move3, context);
18181
+ }
18182
+ function guncmdr_pain5_to_death2(self, context) {
18183
+ if (self.health < 0 && Math.random() < 0.5) M_SetAnimation3(self, death2_move3, context);
18184
+ }
18185
+ function guncmdr_pain6_to_death6(self, context) {
18186
+ if (self.health < 0) M_SetAnimation3(self, death6_move, context);
18187
+ }
18188
+ function guncmdr_shrink(self, context) {
18189
+ self.maxs = { ...self.maxs, z: -4 * (self.monsterinfo.scale || 1) };
18190
+ }
18191
+ function guncmdr_dead(self, context) {
18192
+ const scale = self.monsterinfo.scale || 1;
18193
+ self.mins = scaleVec3({ x: -16, y: -16, z: -24 }, scale);
18194
+ self.maxs = scaleVec3({ x: 16, y: 16, z: -8 }, scale);
18195
+ self.nextthink = -1;
18196
+ self.solid = 0 /* Not */;
18197
+ }
18198
+ function guncmdr_pain(self, context) {
18199
+ monster_done_dodge2(self);
18200
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move || self.monsterinfo.current_move === duck_attack_move) {
18201
+ return;
18202
+ }
18203
+ if (context.timeSeconds < self.pain_debounce_time) {
18204
+ return;
18205
+ }
18206
+ self.pain_debounce_time = context.timeSeconds + 3;
18207
+ if (Math.random() < 0.5) {
18208
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain2.wav", 1, 1, 0);
18209
+ } else {
18210
+ context.engine.sound?.(self, 0, "guncmdr/gcdrpain1.wav", 1, 1, 0);
18211
+ }
18212
+ if (!M_ShouldReactToPain(self)) return;
18213
+ const r = Math.floor(Math.random() * 7);
18214
+ switch (r) {
18215
+ case 0:
18216
+ M_SetAnimation3(self, pain1_move8, context);
18217
+ break;
18218
+ case 1:
18219
+ M_SetAnimation3(self, pain2_move8, context);
18220
+ break;
18221
+ case 2:
18222
+ M_SetAnimation3(self, pain3_move7, context);
18223
+ break;
18224
+ case 3:
18225
+ M_SetAnimation3(self, pain4_move2, context);
18226
+ break;
18227
+ case 4:
18228
+ M_SetAnimation3(self, pain5_move2, context);
18229
+ break;
18230
+ case 5:
18231
+ M_SetAnimation3(self, pain6_move2, context);
18232
+ break;
18233
+ default:
18234
+ M_SetAnimation3(self, pain7_move, context);
18235
+ break;
18236
+ }
18237
+ self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
18238
+ if (self.monsterinfo.aiflags & 2048 /* Ducked */) monster_duck_up(self, context);
18239
+ }
18240
+ function guncmdr_die(self, inflictor, attacker, damage, point, context) {
18241
+ if (M_CheckGib(self, damage)) {
18242
+ context.engine.sound?.(self, 0, "misc/udeath.wav", 1, 1, 0);
18243
+ throwGibs(context, self.origin, [{
18244
+ count: 1,
18245
+ model: "models/monsters/gunner/gibs/chest.md2",
18246
+ flags: 1 /* Metallic */
18247
+ }]);
18248
+ self.deadflag = 2 /* Dead */;
18249
+ return;
18250
+ }
18251
+ if (self.deadflag) return;
18252
+ context.engine.sound?.(self, 0, "guncmdr/gcdrdeath1.wav", 1, 1, 0);
18253
+ self.deadflag = 2 /* Dead */;
18254
+ self.takedamage = true;
18255
+ const r = Math.floor(Math.random() * 7);
18256
+ switch (r) {
18257
+ case 0:
18258
+ M_SetAnimation3(self, death1_move3, context);
18259
+ break;
18260
+ case 1:
18261
+ M_SetAnimation3(self, death2_move3, context);
18262
+ break;
18263
+ case 2:
18264
+ M_SetAnimation3(self, death3_move, context);
18265
+ break;
18266
+ case 3:
18267
+ M_SetAnimation3(self, death4_move, context);
18268
+ break;
18269
+ case 4:
18270
+ M_SetAnimation3(self, death5_move, context);
18271
+ break;
18272
+ case 5:
18273
+ M_SetAnimation3(self, death6_move, context);
18274
+ break;
18275
+ default:
18276
+ M_SetAnimation3(self, death7_move, context);
18277
+ break;
18278
+ }
18279
+ }
18280
+ function guncmdr_setskin(self, context) {
18281
+ if (self.health < self.max_health / 2) {
18282
+ self.skin |= 1;
18283
+ } else {
18284
+ self.skin &= ~1;
18285
+ }
18286
+ }
18287
+ function guncmdr_duck(self, eta, context) {
18288
+ if (self.monsterinfo.current_move === jump_move3 || self.monsterinfo.current_move === jump2_move) return false;
18289
+ if (self.monsterinfo.current_move === fire_chain_dodge_left_move || self.monsterinfo.current_move === fire_chain_dodge_right_move || self.monsterinfo.current_move === attack_grenade_back_dodge_left_move || self.monsterinfo.current_move === attack_grenade_back_dodge_right_move || self.monsterinfo.current_move === attack_mortar_dodge_move) {
18290
+ monster_duck_up(self, context);
18291
+ return false;
18292
+ }
18293
+ M_SetAnimation3(self, duck_attack_move, context);
18294
+ return true;
18295
+ }
18296
+ function guncmdr_sidestep(self, context) {
18297
+ if (self.monsterinfo.current_move === fire_chain_move2 || self.monsterinfo.current_move === fire_chain_run_move) {
18298
+ M_SetAnimation3(self, Math.random() < 0.5 ? fire_chain_dodge_right_move : fire_chain_dodge_left_move, context);
18299
+ return true;
18300
+ }
18301
+ if (self.monsterinfo.current_move === attack_grenade_back_move) {
18302
+ self.count = self.frame;
18303
+ M_SetAnimation3(self, Math.random() < 0.5 ? attack_grenade_back_dodge_right_move : attack_grenade_back_dodge_left_move, context);
18304
+ return true;
18305
+ }
18306
+ if (self.monsterinfo.current_move === attack_mortar_move) {
18307
+ self.count = self.frame;
18308
+ M_SetAnimation3(self, attack_mortar_dodge_move, context);
18309
+ return true;
18310
+ }
18311
+ if (self.monsterinfo.current_move === run_move20) {
18312
+ M_SetAnimation3(self, run_move20, context);
18313
+ return true;
18314
+ }
18315
+ return false;
18316
+ }
18317
+ fidget_move4 = {
18318
+ firstframe: 201,
18319
+ lastframe: 254,
18320
+ frames: Array(54).fill({ ai: monster_ai_stand24, dist: 0 }),
18321
+ endfunc: guncmdr_stand
18322
+ };
18323
+ fidget_move4.frames[6] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18324
+ fidget_move4.frames[10] = { ai: monster_ai_stand24, dist: 0, think: guncmdr_idlesound };
18325
+ stand_move21 = {
18326
+ firstframe: 101,
18327
+ lastframe: 140,
18328
+ frames: Array(40).fill({ ai: monster_ai_stand24, dist: 0 }),
18329
+ endfunc: null
18330
+ };
18331
+ var stand_fidget = (self, context) => guncmdr_fidget(self, context);
18332
+ [9, 19, 29, 39].forEach((i) => {
18333
+ stand_move21.frames[i] = { ai: monster_ai_stand24, dist: 0, think: stand_fidget };
18334
+ });
18335
+ walk_move18 = {
18336
+ firstframe: 101,
18337
+ lastframe: 124,
18338
+ frames: [
18339
+ { ai: monster_ai_walk23, dist: 1.5 },
18340
+ { ai: monster_ai_walk23, dist: 2.5 },
18341
+ { ai: monster_ai_walk23, dist: 3 },
18342
+ { ai: monster_ai_walk23, dist: 2.5 },
18343
+ { ai: monster_ai_walk23, dist: 2.3 },
18344
+ { ai: monster_ai_walk23, dist: 3 },
18345
+ { ai: monster_ai_walk23, dist: 2.8 },
18346
+ { ai: monster_ai_walk23, dist: 3.6 },
18347
+ { ai: monster_ai_walk23, dist: 2.8 },
18348
+ { ai: monster_ai_walk23, dist: 2.5 },
18349
+ { ai: monster_ai_walk23, dist: 2.3 },
18350
+ { ai: monster_ai_walk23, dist: 4.3 },
18351
+ { ai: monster_ai_walk23, dist: 3 },
18352
+ { ai: monster_ai_walk23, dist: 1.5 },
18353
+ { ai: monster_ai_walk23, dist: 2.5 },
18354
+ { ai: monster_ai_walk23, dist: 3.3 },
18355
+ { ai: monster_ai_walk23, dist: 2.8 },
18356
+ { ai: monster_ai_walk23, dist: 3 },
18357
+ { ai: monster_ai_walk23, dist: 2 },
18358
+ { ai: monster_ai_walk23, dist: 2 },
18359
+ { ai: monster_ai_walk23, dist: 3.3 },
18360
+ { ai: monster_ai_walk23, dist: 3.6 },
18361
+ { ai: monster_ai_walk23, dist: 3.4 },
18362
+ { ai: monster_ai_walk23, dist: 2.8 }
18363
+ ],
18364
+ endfunc: null
18365
+ };
18366
+ run_move20 = {
18367
+ firstframe: 101,
18368
+ lastframe: 106,
18369
+ frames: [
18370
+ { ai: monster_ai_run24, dist: 15, think: monster_done_dodge2 },
18371
+ { ai: monster_ai_run24, dist: 16 },
18372
+ { ai: monster_ai_run24, dist: 20 },
18373
+ { ai: monster_ai_run24, dist: 18 },
18374
+ { ai: monster_ai_run24, dist: 24 },
18375
+ { ai: monster_ai_run24, dist: 13.5 }
18376
+ ],
18377
+ endfunc: null
18378
+ };
18379
+ attack_chain_move3 = {
18380
+ firstframe: 101,
18381
+ lastframe: 106,
18382
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0 }),
18383
+ endfunc: guncmdr_fire_chain
18384
+ };
18385
+ attack_chain_move3.frames[4].think = guncmdr_opengun;
18386
+ fire_chain_move2 = {
18387
+ firstframe: 107,
18388
+ lastframe: 112,
18389
+ frames: Array(6).fill({ ai: monster_ai_charge25, dist: 0, think: GunnerCmdrFire }),
18390
+ endfunc: guncmdr_refire_chain
18391
+ };
18392
+ fire_chain_run_move = {
18393
+ firstframe: 201,
18394
+ lastframe: 206,
18395
+ frames: [
18396
+ { ai: monster_ai_charge25, dist: 15, think: GunnerCmdrFire },
18397
+ { ai: monster_ai_charge25, dist: 16, think: GunnerCmdrFire },
18398
+ { ai: monster_ai_charge25, dist: 20, think: GunnerCmdrFire },
18399
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18400
+ { ai: monster_ai_charge25, dist: 24, think: GunnerCmdrFire },
18401
+ { ai: monster_ai_charge25, dist: 13.5, think: GunnerCmdrFire }
18402
+ ],
18403
+ endfunc: guncmdr_refire_chain
18404
+ };
18405
+ fire_chain_dodge_right_move = {
18406
+ firstframe: 401,
18407
+ lastframe: 405,
18408
+ frames: [
18409
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18410
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18411
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18412
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18413
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18414
+ ],
18415
+ endfunc: guncmdr_refire_chain
18416
+ };
18417
+ fire_chain_dodge_left_move = {
18418
+ firstframe: 501,
18419
+ lastframe: 505,
18420
+ frames: [
18421
+ { ai: monster_ai_charge25, dist: 10.2, think: GunnerCmdrFire },
18422
+ { ai: monster_ai_charge25, dist: 18, think: GunnerCmdrFire },
18423
+ { ai: monster_ai_charge25, dist: 7, think: GunnerCmdrFire },
18424
+ { ai: monster_ai_charge25, dist: 7.2, think: GunnerCmdrFire },
18425
+ { ai: monster_ai_charge25, dist: -2, think: GunnerCmdrFire }
18426
+ ],
18427
+ endfunc: guncmdr_refire_chain
18428
+ };
18429
+ endfire_chain_move2 = {
18430
+ firstframe: 118,
18431
+ lastframe: 124,
18432
+ frames: Array(7).fill({ ai: monster_ai_charge25, dist: 0 }),
18433
+ endfunc: guncmdr_run
18434
+ };
18435
+ endfire_chain_move2.frames[2].think = guncmdr_opengun;
18436
+ attack_mortar_move = {
18437
+ firstframe: 201,
18438
+ lastframe: 221,
18439
+ frames: Array(21).fill({ ai: monster_ai_charge25, dist: 0 }),
18440
+ endfunc: guncmdr_run
18441
+ };
18442
+ attack_mortar_move.frames[4].think = GunnerCmdrGrenade;
18443
+ attack_mortar_move.frames[7].think = GunnerCmdrGrenade;
18444
+ attack_mortar_move.frames[10].think = GunnerCmdrGrenade;
18445
+ attack_mortar_move.frames[13].think = monster_duck_up;
18446
+ attack_mortar_dodge_move = {
18447
+ firstframe: 0,
18448
+ lastframe: 5,
18449
+ frames: [
18450
+ { ai: monster_ai_charge25, dist: 11 },
18451
+ { ai: monster_ai_charge25, dist: 12 },
18452
+ { ai: monster_ai_charge25, dist: 16 },
18453
+ { ai: monster_ai_charge25, dist: 16 },
18454
+ { ai: monster_ai_charge25, dist: 12 },
18455
+ { ai: monster_ai_charge25, dist: 11 }
18456
+ ],
18457
+ endfunc: guncmdr_grenade_mortar_resume
18458
+ };
18459
+ attack_grenade_back_move = {
18460
+ firstframe: 302,
18461
+ lastframe: 321,
18462
+ frames: [
18463
+ { ai: monster_ai_charge25, dist: -2 },
18464
+ { ai: monster_ai_charge25, dist: -1.5 },
18465
+ { ai: monster_ai_charge25, dist: -0.5, think: GunnerCmdrGrenade },
18466
+ { ai: monster_ai_charge25, dist: -6 },
18467
+ { ai: monster_ai_charge25, dist: -4 },
18468
+ { ai: monster_ai_charge25, dist: -2.5, think: GunnerCmdrGrenade },
18469
+ { ai: monster_ai_charge25, dist: -7 },
18470
+ { ai: monster_ai_charge25, dist: -3.5 },
18471
+ { ai: monster_ai_charge25, dist: -1.1, think: GunnerCmdrGrenade },
18472
+ { ai: monster_ai_charge25, dist: -4.6 },
18473
+ { ai: monster_ai_charge25, dist: 1.9 },
18474
+ { ai: monster_ai_charge25, dist: 1 },
18475
+ { ai: monster_ai_charge25, dist: -4.5 },
18476
+ { ai: monster_ai_charge25, dist: 3.2 },
18477
+ { ai: monster_ai_charge25, dist: 4.4 },
18478
+ { ai: monster_ai_charge25, dist: -6.5 },
18479
+ { ai: monster_ai_charge25, dist: -6.1 },
18480
+ { ai: monster_ai_charge25, dist: 3 },
18481
+ { ai: monster_ai_charge25, dist: -0.7 },
18482
+ { ai: monster_ai_charge25, dist: -1 }
18483
+ ],
18484
+ endfunc: guncmdr_run
18485
+ };
18486
+ attack_grenade_back_dodge_right_move = {
18487
+ firstframe: 601,
18488
+ lastframe: 605,
18489
+ frames: [
18490
+ { ai: monster_ai_charge25, dist: 10.2 },
18491
+ { ai: monster_ai_charge25, dist: 18 },
18492
+ { ai: monster_ai_charge25, dist: 7 },
18493
+ { ai: monster_ai_charge25, dist: 7.2 },
18494
+ { ai: monster_ai_charge25, dist: -2 }
18495
+ ],
18496
+ endfunc: guncmdr_grenade_back_dodge_resume
18497
+ };
18498
+ attack_grenade_back_dodge_left_move = {
18499
+ firstframe: 701,
18500
+ lastframe: 705,
18501
+ frames: [
18502
+ { ai: monster_ai_charge25, dist: 10.2 },
18503
+ { ai: monster_ai_charge25, dist: 18 },
18504
+ { ai: monster_ai_charge25, dist: 7 },
18505
+ { ai: monster_ai_charge25, dist: 7.2 },
18506
+ { ai: monster_ai_charge25, dist: -2 }
18507
+ ],
18508
+ endfunc: guncmdr_grenade_back_dodge_resume
18509
+ };
18510
+ attack_kick_move = {
18511
+ firstframe: 801,
18512
+ lastframe: 808,
18513
+ frames: [
18514
+ { ai: monster_ai_charge25, dist: -7.7 },
18515
+ { ai: monster_ai_charge25, dist: -4.9 },
18516
+ { ai: monster_ai_charge25, dist: 12.6, think: guncmdr_kick },
18517
+ { ai: monster_ai_charge25, dist: 0 },
18518
+ { ai: monster_ai_charge25, dist: -3 },
18519
+ { ai: monster_ai_charge25, dist: 0 },
18520
+ { ai: monster_ai_charge25, dist: -4.1 },
18521
+ { ai: monster_ai_charge25, dist: 8.6 }
18522
+ ],
18523
+ endfunc: guncmdr_kick_finished
18524
+ };
18525
+ duck_attack_move = {
18526
+ firstframe: 901,
18527
+ lastframe: 919,
18528
+ frames: [
18529
+ { ai: monster_ai_move24, dist: 3.6 },
18530
+ { ai: monster_ai_move24, dist: 5.6, think: monster_duck_down },
18531
+ { ai: monster_ai_move24, dist: 8.4 },
18532
+ { ai: monster_ai_move24, dist: 2, think: monster_duck_hold },
18533
+ { ai: monster_ai_charge25, dist: 0 },
18534
+ { ai: monster_ai_charge25, dist: 0 },
18535
+ { ai: monster_ai_charge25, dist: 0 },
18536
+ { ai: monster_ai_charge25, dist: 0 },
18537
+ { ai: monster_ai_charge25, dist: 0 },
18538
+ { ai: monster_ai_charge25, dist: 0 },
18539
+ { ai: monster_ai_charge25, dist: 0 },
18540
+ { ai: monster_ai_charge25, dist: 9.5, think: GunnerCmdrCounter },
18541
+ { ai: monster_ai_charge25, dist: -1.5 },
18542
+ { ai: monster_ai_charge25, dist: 0 },
18543
+ { ai: monster_ai_charge25, dist: 0, think: monster_duck_up },
18544
+ { ai: monster_ai_charge25, dist: 0 },
18545
+ { ai: monster_ai_charge25, dist: 11 },
18546
+ { ai: monster_ai_charge25, dist: 2 },
18547
+ { ai: monster_ai_charge25, dist: 5.6 }
18548
+ ],
18549
+ endfunc: guncmdr_run
18550
+ };
18551
+ jump_move3 = {
18552
+ firstframe: 0,
18553
+ lastframe: 9,
18554
+ frames: [
18555
+ { ai: monster_ai_move24, dist: 0 },
18556
+ { ai: monster_ai_move24, dist: 0 },
18557
+ { ai: monster_ai_move24, dist: 0 },
18558
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_now },
18559
+ { ai: monster_ai_move24, dist: 0 },
18560
+ { ai: monster_ai_move24, dist: 0 },
18561
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18562
+ { ai: monster_ai_move24, dist: 0 },
18563
+ { ai: monster_ai_move24, dist: 0 },
18564
+ { ai: monster_ai_move24, dist: 0 }
18565
+ ],
18566
+ endfunc: guncmdr_run
18567
+ };
18568
+ jump2_move = {
18569
+ firstframe: 0,
18570
+ lastframe: 9,
18571
+ frames: [
18572
+ { ai: monster_ai_move24, dist: -8 },
18573
+ { ai: monster_ai_move24, dist: -4 },
18574
+ { ai: monster_ai_move24, dist: -4 },
18575
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump2_now },
18576
+ { ai: monster_ai_move24, dist: 0 },
18577
+ { ai: monster_ai_move24, dist: 0 },
18578
+ { ai: monster_ai_move24, dist: 0, think: guncmdr_jump_wait_land },
18579
+ { ai: monster_ai_move24, dist: 0 },
18580
+ { ai: monster_ai_move24, dist: 0 },
18581
+ { ai: monster_ai_move24, dist: 0 }
18582
+ ],
18583
+ endfunc: guncmdr_run
18584
+ };
18585
+ pain1_move8 = { firstframe: 101, lastframe: 104, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18586
+ pain2_move8 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18587
+ pain3_move7 = { firstframe: 301, lastframe: 304, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18588
+ pain4_move2 = { firstframe: 401, lastframe: 415, frames: Array(15).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18589
+ pain5_move2 = { firstframe: 501, lastframe: 524, frames: Array(24).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18590
+ pain5_move2.frames[5].think = guncmdr_pain5_to_death2;
18591
+ pain5_move2.frames[8].think = guncmdr_pain5_to_death1;
18592
+ pain6_move2 = { firstframe: 601, lastframe: 632, frames: Array(32).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18593
+ pain6_move2.frames[6].think = guncmdr_pain6_to_death6;
18594
+ pain7_move = { firstframe: 701, lastframe: 714, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_run };
18595
+ death1_move3 = { firstframe: 101, lastframe: 118, frames: Array(18).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18596
+ death2_move3 = { firstframe: 201, lastframe: 204, frames: Array(4).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18597
+ death3_move = { firstframe: 301, lastframe: 321, frames: Array(21).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18598
+ death3_move.frames[2].think = guncmdr_shrink;
18599
+ death4_move = { firstframe: 401, lastframe: 436, frames: Array(36).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18600
+ death4_move.frames[2].think = guncmdr_shrink;
18601
+ death5_move = { firstframe: 501, lastframe: 528, frames: Array(28).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18602
+ death6_move = { firstframe: 601, lastframe: 614, frames: Array(14).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18603
+ death6_move.frames[0].think = guncmdr_shrink;
18604
+ death7_move = { firstframe: 701, lastframe: 730, frames: Array(30).fill({ ai: monster_ai_move24, dist: 0 }), endfunc: guncmdr_dead };
18605
+ death7_move.frames[2].think = guncmdr_shrink;
18606
+ function SP_monster_guncmdr(self, context) {
18607
+ if (!M_AllowSpawn(self, context.entities)) {
18608
+ context.entities.free(self);
18609
+ return;
18610
+ }
18611
+ self.movetype = 5 /* Step */;
18612
+ self.solid = 2 /* BoundingBox */;
18613
+ self.model = "models/monsters/gunner/tris.md2";
18614
+ self.modelindex = context.entities.modelIndex("models/monsters/gunner/tris.md2");
18615
+ self.monsterinfo.scale = 1.25;
18616
+ self.mins = { x: -16, y: -16, z: -24 };
18617
+ self.maxs = { x: 16, y: 16, z: 36 };
18618
+ self.skin = 2;
18619
+ const healthMultiplier = context.keyValues["health_multiplier"] ? parseFloat(context.keyValues["health_multiplier"]) : 1;
18620
+ self.health = 325 * healthMultiplier;
18621
+ self.max_health = self.health;
18622
+ self.mass = 255;
18623
+ self.pain = (s, o, k, d) => guncmdr_pain(s, context.entities);
18624
+ self.die = (s, i, a, d, p) => guncmdr_die(s, i, a, d, p, context.entities);
18625
+ self.monsterinfo.stand = (s) => guncmdr_stand(s, context.entities);
18626
+ self.monsterinfo.walk = (s) => guncmdr_walk(s, context.entities);
18627
+ self.monsterinfo.run = (s) => guncmdr_run(s, context.entities);
18628
+ self.monsterinfo.dodge = (s, a, e) => M_MonsterDodge(s, a, e);
18629
+ self.monsterinfo.duck = (s, e) => guncmdr_duck(s, e, context.entities);
18630
+ self.monsterinfo.unduck = (s) => monster_duck_up(s, context.entities);
18631
+ self.monsterinfo.sidestep = (s) => guncmdr_sidestep(s, context.entities);
18632
+ self.monsterinfo.attack = (s) => guncmdr_attack(s, context.entities);
18633
+ self.monsterinfo.sight = (s, o) => guncmdr_sight(s, o, context.entities);
18634
+ self.monsterinfo.search = (s) => guncmdr_search(s, context.entities);
18635
+ self.monsterinfo.setskin = (s) => guncmdr_setskin(s, context.entities);
18636
+ self.monsterinfo.power_armor_power = 200;
18637
+ self.monsterinfo.power_armor_type = 1;
18638
+ context.entities.linkentity(self);
18639
+ M_SetAnimation3(self, stand_move21, context.entities);
18640
+ self.think = monster_think;
18641
+ self.nextthink = context.entities.timeSeconds + MONSTER_TICK28;
18642
+ }
18643
+ function registerGunCommanderSpawns(registry) {
18644
+ registry.register("monster_guncmdr", SP_monster_guncmdr);
18645
+ }
18646
+
17806
18647
  // src/entities/monsters/index.ts
17807
18648
  function registerMonsterSpawns2(registry) {
17808
18649
  registerMonsterSpawns(registry);
@@ -17832,6 +18673,7 @@ function registerMonsterSpawns2(registry) {
17832
18673
  registerGekkSpawns(registry);
17833
18674
  registerFixbotSpawns(registry);
17834
18675
  registerArachnidSpawns(registry);
18676
+ registerGunCommanderSpawns(registry);
17835
18677
  }
17836
18678
 
17837
18679
  // src/entities/worldspawn.ts
@@ -20158,6 +21000,7 @@ function createGame(imports, engine, options) {
20158
21000
  M_CheckBottom,
20159
21001
  M_MoveFrame,
20160
21002
  M_walkmove,
21003
+ MonsterAttackState,
20161
21004
  MoveType,
20162
21005
  MulticastType,
20163
21006
  ORDERED_DAMAGE_MODS,