home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / m_soldier.c < prev    next >
C/C++ Source or Header  |  1997-11-24  |  29KB  |  1,275 lines

  1. /*
  2. ==============================================================================
  3.  
  4. SOLDIER
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_soldier.h"
  11.  
  12.  
  13. static int    sound_idle;
  14. static int    sound_sight1;
  15. static int    sound_sight2;
  16. static int    sound_pain_light;
  17. static int    sound_pain;
  18. static int    sound_pain_ss;
  19. static int    sound_death_light;
  20. static int    sound_death;
  21. static int    sound_death_ss;
  22. static int    sound_cock;
  23.  
  24.  
  25. void soldier_idle (edict_t *self)
  26. {
  27.     if (random() > 0.8)
  28.         gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
  29. }
  30.  
  31. void soldier_cock (edict_t *self)
  32. {
  33.     if (self->s.frame == FRAME_stand322)
  34.         gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
  35.     else
  36.         gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
  37. }
  38.  
  39.  
  40. // STAND
  41.  
  42. void soldier_stand (edict_t *self);
  43.  
  44. mframe_t soldier_frames_stand1 [] =
  45. {
  46.     ai_stand, 0, soldier_idle,
  47.     ai_stand, 0, NULL,
  48.     ai_stand, 0, NULL,
  49.     ai_stand, 0, NULL,
  50.     ai_stand, 0, NULL,
  51.     ai_stand, 0, NULL,
  52.     ai_stand, 0, NULL,
  53.     ai_stand, 0, NULL,
  54.     ai_stand, 0, NULL,
  55.     ai_stand, 0, NULL,
  56.  
  57.     ai_stand, 0, NULL,
  58.     ai_stand, 0, NULL,
  59.     ai_stand, 0, NULL,
  60.     ai_stand, 0, NULL,
  61.     ai_stand, 0, NULL,
  62.     ai_stand, 0, NULL,
  63.     ai_stand, 0, NULL,
  64.     ai_stand, 0, NULL,
  65.     ai_stand, 0, NULL,
  66.     ai_stand, 0, NULL,
  67.  
  68.     ai_stand, 0, NULL,
  69.     ai_stand, 0, NULL,
  70.     ai_stand, 0, NULL,
  71.     ai_stand, 0, NULL,
  72.     ai_stand, 0, NULL,
  73.     ai_stand, 0, NULL,
  74.     ai_stand, 0, NULL,
  75.     ai_stand, 0, NULL,
  76.     ai_stand, 0, NULL,
  77.     ai_stand, 0, NULL
  78. };
  79. mmove_t soldier_move_stand1 = {FRAME_stand101, FRAME_stand130, soldier_frames_stand1, soldier_stand};
  80.  
  81. mframe_t soldier_frames_stand3 [] =
  82. {
  83.     ai_stand, 0, NULL,
  84.     ai_stand, 0, NULL,
  85.     ai_stand, 0, NULL,
  86.     ai_stand, 0, NULL,
  87.     ai_stand, 0, NULL,
  88.     ai_stand, 0, NULL,
  89.     ai_stand, 0, NULL,
  90.     ai_stand, 0, NULL,
  91.     ai_stand, 0, NULL,
  92.     ai_stand, 0, NULL,
  93.  
  94.     ai_stand, 0, NULL,
  95.     ai_stand, 0, NULL,
  96.     ai_stand, 0, NULL,
  97.     ai_stand, 0, NULL,
  98.     ai_stand, 0, NULL,
  99.     ai_stand, 0, NULL,
  100.     ai_stand, 0, NULL,
  101.     ai_stand, 0, NULL,
  102.     ai_stand, 0, NULL,
  103.     ai_stand, 0, NULL,
  104.  
  105.     ai_stand, 0, NULL,
  106.     ai_stand, 0, soldier_cock,
  107.     ai_stand, 0, NULL,
  108.     ai_stand, 0, NULL,
  109.     ai_stand, 0, NULL,
  110.     ai_stand, 0, NULL,
  111.     ai_stand, 0, NULL,
  112.     ai_stand, 0, NULL,
  113.     ai_stand, 0, NULL,
  114.     ai_stand, 0, NULL,
  115.  
  116.     ai_stand, 0, NULL,
  117.     ai_stand, 0, NULL,
  118.     ai_stand, 0, NULL,
  119.     ai_stand, 0, NULL,
  120.     ai_stand, 0, NULL,
  121.     ai_stand, 0, NULL,
  122.     ai_stand, 0, NULL,
  123.     ai_stand, 0, NULL,
  124.     ai_stand, 0, NULL
  125. };
  126. mmove_t soldier_move_stand3 = {FRAME_stand301, FRAME_stand339, soldier_frames_stand3, soldier_stand};
  127.  
  128. #if 0
  129. mframe_t soldier_frames_stand4 [] =
  130. {
  131.     ai_stand, 0, NULL,
  132.     ai_stand, 0, NULL,
  133.     ai_stand, 0, NULL,
  134.     ai_stand, 0, NULL,
  135.     ai_stand, 0, NULL,
  136.     ai_stand, 0, NULL,
  137.     ai_stand, 0, NULL,
  138.     ai_stand, 0, NULL,
  139.     ai_stand, 0, NULL,
  140.     ai_stand, 0, NULL,
  141.  
  142.     ai_stand, 0, NULL,
  143.     ai_stand, 0, NULL,
  144.     ai_stand, 0, NULL,
  145.     ai_stand, 0, NULL,
  146.     ai_stand, 0, NULL,
  147.     ai_stand, 0, NULL,
  148.     ai_stand, 0, NULL,
  149.     ai_stand, 0, NULL,
  150.     ai_stand, 0, NULL,
  151.     ai_stand, 0, NULL,
  152.  
  153.     ai_stand, 0, NULL,
  154.     ai_stand, 0, NULL,
  155.     ai_stand, 0, NULL,
  156.     ai_stand, 0, NULL,
  157.     ai_stand, 0, NULL,
  158.     ai_stand, 0, NULL,
  159.     ai_stand, 0, NULL,
  160.     ai_stand, 0, NULL,
  161.     ai_stand, 0, NULL,
  162.     ai_stand, 0, NULL,
  163.  
  164.     ai_stand, 0, NULL,
  165.     ai_stand, 0, NULL,
  166.     ai_stand, 0, NULL,
  167.     ai_stand, 0, NULL,
  168.     ai_stand, 0, NULL,
  169.     ai_stand, 0, NULL,
  170.     ai_stand, 0, NULL,
  171.     ai_stand, 0, NULL,
  172.     ai_stand, 0, NULL,
  173.     ai_stand, 0, NULL,
  174.  
  175.     ai_stand, 0, NULL,
  176.     ai_stand, 0, NULL,
  177.     ai_stand, 0, NULL,
  178.     ai_stand, 0, NULL,
  179.     ai_stand, 0, NULL,
  180.     ai_stand, 0, NULL,
  181.     ai_stand, 4, NULL,
  182.     ai_stand, 1, NULL,
  183.     ai_stand, -1, NULL,
  184.     ai_stand, -2, NULL,
  185.  
  186.     ai_stand, 0, NULL,
  187.     ai_stand, 0, NULL
  188. };
  189. mmove_t soldier_move_stand4 = {FRAME_stand401, FRAME_stand452, soldier_frames_stand4, NULL};
  190. #endif
  191.  
  192. void soldier_stand (edict_t *self)
  193. {
  194.     if ((self->monsterinfo.currentmove == &soldier_move_stand3) || (random() < 0.8))
  195.         self->monsterinfo.currentmove = &soldier_move_stand1;
  196.     else
  197.         self->monsterinfo.currentmove = &soldier_move_stand3;
  198. }
  199.  
  200.  
  201. //
  202. // WALK
  203. //
  204.  
  205. void soldier_walk1_random (edict_t *self)
  206. {
  207.     if (random() > 0.1)
  208.         self->monsterinfo.nextframe = FRAME_walk101;
  209. }
  210.  
  211. mframe_t soldier_frames_walk1 [] =
  212. {
  213.     ai_walk, 3,  NULL,
  214.     ai_walk, 6,  NULL,
  215.     ai_walk, 2,  NULL,
  216.     ai_walk, 2,  NULL,
  217.     ai_walk, 2,  NULL,
  218.     ai_walk, 1,  NULL,
  219.     ai_walk, 6,  NULL,
  220.     ai_walk, 5,  NULL,
  221.     ai_walk, 3,  NULL,
  222.     ai_walk, -1, soldier_walk1_random,
  223.     ai_walk, 0,  NULL,
  224.     ai_walk, 0,  NULL,
  225.     ai_walk, 0,  NULL,
  226.     ai_walk, 0,  NULL,
  227.     ai_walk, 0,  NULL,
  228.     ai_walk, 0,  NULL,
  229.     ai_walk, 0,  NULL,
  230.     ai_walk, 0,  NULL,
  231.     ai_walk, 0,  NULL,
  232.     ai_walk, 0,  NULL,
  233.     ai_walk, 0,  NULL,
  234.     ai_walk, 0,  NULL,
  235.     ai_walk, 0,  NULL,
  236.     ai_walk, 0,  NULL,
  237.     ai_walk, 0,  NULL,
  238.     ai_walk, 0,  NULL,
  239.     ai_walk, 0,  NULL,
  240.     ai_walk, 0,  NULL,
  241.     ai_walk, 0,  NULL,
  242.     ai_walk, 0,  NULL,
  243.     ai_walk, 0,  NULL,
  244.     ai_walk, 0,  NULL,
  245.     ai_walk, 0,  NULL
  246. };
  247. mmove_t soldier_move_walk1 = {FRAME_walk101, FRAME_walk133, soldier_frames_walk1, NULL};
  248.  
  249. mframe_t soldier_frames_walk2 [] =
  250. {
  251.     ai_walk, 4,  NULL,
  252.     ai_walk, 4,  NULL,
  253.     ai_walk, 9,  NULL,
  254.     ai_walk, 8,  NULL,
  255.     ai_walk, 5,  NULL,
  256.     ai_walk, 1,  NULL,
  257.     ai_walk, 3,  NULL,
  258.     ai_walk, 7,  NULL,
  259.     ai_walk, 6,  NULL,
  260.     ai_walk, 7,  NULL
  261. };
  262. mmove_t soldier_move_walk2 = {FRAME_walk209, FRAME_walk218, soldier_frames_walk2, NULL};
  263.  
  264. void soldier_walk (edict_t *self)
  265. {
  266.     if (random() < 0.5)
  267.         self->monsterinfo.currentmove = &soldier_move_walk1;
  268.     else
  269.         self->monsterinfo.currentmove = &soldier_move_walk2;
  270. }
  271.  
  272.  
  273. //
  274. // RUN
  275. //
  276.  
  277. void soldier_run (edict_t *self);
  278.  
  279. mframe_t soldier_frames_start_run [] =
  280. {
  281.     ai_run, 7,  NULL,
  282.     ai_run, 5,  NULL
  283. };
  284. mmove_t soldier_move_start_run = {FRAME_run01, FRAME_run02, soldier_frames_start_run, soldier_run};
  285.  
  286. mframe_t soldier_frames_run [] =
  287. {
  288.     ai_run, 10, NULL,
  289.     ai_run, 11, NULL,
  290.     ai_run, 11, NULL,
  291.     ai_run, 16, NULL,
  292.     ai_run, 10, NULL,
  293.     ai_run, 15, NULL
  294. };
  295. mmove_t soldier_move_run = {FRAME_run03, FRAME_run08, soldier_frames_run, NULL};
  296.  
  297. void soldier_run (edict_t *self)
  298. {
  299.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  300.     {
  301.         self->monsterinfo.currentmove = &soldier_move_stand1;
  302.         return;
  303.     }
  304.  
  305.     if (self->monsterinfo.currentmove == &soldier_move_walk1 ||
  306.         self->monsterinfo.currentmove == &soldier_move_walk2 ||
  307.         self->monsterinfo.currentmove == &soldier_move_start_run)
  308.     {
  309.         self->monsterinfo.currentmove = &soldier_move_run;
  310.     }
  311.     else
  312.     {
  313.         self->monsterinfo.currentmove = &soldier_move_start_run;
  314.     }
  315. }
  316.  
  317.  
  318. //
  319. // PAIN
  320. //
  321.  
  322. mframe_t soldier_frames_pain1 [] =
  323. {
  324.     ai_move, -3, NULL,
  325.     ai_move, 4,  NULL,
  326.     ai_move, 1,  NULL,
  327.     ai_move, 1,  NULL,
  328.     ai_move, 0,  NULL
  329. };
  330. mmove_t soldier_move_pain1 = {FRAME_pain101, FRAME_pain105, soldier_frames_pain1, soldier_run};
  331.  
  332. mframe_t soldier_frames_pain2 [] =
  333. {
  334.     ai_move, -13, NULL,
  335.     ai_move, -1,  NULL,
  336.     ai_move, 2,   NULL,
  337.     ai_move, 4,   NULL,
  338.     ai_move, 2,   NULL,
  339.     ai_move, 3,   NULL,
  340.     ai_move, 2,   NULL
  341. };
  342. mmove_t soldier_move_pain2 = {FRAME_pain201, FRAME_pain207, soldier_frames_pain2, soldier_run};
  343.  
  344. mframe_t soldier_frames_pain3 [] =
  345. {
  346.     ai_move, -8, NULL,
  347.     ai_move, 10, NULL,
  348.     ai_move, -4, NULL,
  349.     ai_move, -1, NULL,
  350.     ai_move, -3, NULL,
  351.     ai_move, 0,  NULL,
  352.     ai_move, 3,  NULL,
  353.     ai_move, 0,  NULL,
  354.     ai_move, 0,  NULL,
  355.     ai_move, 0,  NULL,
  356.     ai_move, 0,  NULL,
  357.     ai_move, 1,  NULL,
  358.     ai_move, 0,  NULL,
  359.     ai_move, 1,  NULL,
  360.     ai_move, 2,  NULL,
  361.     ai_move, 4,  NULL,
  362.     ai_move, 3,  NULL,
  363.     ai_move, 2,  NULL
  364. };
  365. mmove_t soldier_move_pain3 = {FRAME_pain301, FRAME_pain318, soldier_frames_pain3, soldier_run};
  366.  
  367. mframe_t soldier_frames_pain4 [] =
  368. {
  369.     ai_move, 0,   NULL,
  370.     ai_move, 0,   NULL,
  371.     ai_move, 0,   NULL,
  372.     ai_move, -10, NULL,
  373.     ai_move, -6,  NULL,
  374.     ai_move, 8,   NULL,
  375.     ai_move, 4,   NULL,
  376.     ai_move, 1,   NULL,
  377.     ai_move, 0,   NULL,
  378.     ai_move, 2,   NULL,
  379.     ai_move, 5,   NULL,
  380.     ai_move, 2,   NULL,
  381.     ai_move, -1,  NULL,
  382.     ai_move, -1,  NULL,
  383.     ai_move, 3,   NULL,
  384.     ai_move, 2,   NULL,
  385.     ai_move, 0,   NULL
  386. };
  387. mmove_t soldier_move_pain4 = {FRAME_pain401, FRAME_pain417, soldier_frames_pain4, soldier_run};
  388.  
  389.  
  390. void soldier_pain (edict_t *self, edict_t *other, float kick, int damage)
  391. {
  392.     float    r;
  393.  
  394.     if (self->health < (self->max_health / 2))
  395.             self->s.skinnum |= 1;
  396.  
  397.     if (level.time < self->pain_debounce_time)
  398.     {
  399.         if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldier_move_pain1) || (self->monsterinfo.currentmove == &soldier_move_pain2) || (self->monsterinfo.currentmove == &soldier_move_pain3)))
  400.             self->monsterinfo.currentmove = &soldier_move_pain4;
  401.         return;
  402.     }
  403.  
  404.     self->pain_debounce_time = level.time + 3;
  405.     
  406.     if (self->s.skinnum == 0)
  407.         gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
  408.     else if (self->s.skinnum == 1)
  409.         gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
  410.     else
  411.         gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
  412.  
  413.     if (self->velocity[2] > 100)
  414.     {
  415.         self->monsterinfo.currentmove = &soldier_move_pain4;
  416.         return;
  417.     }
  418.  
  419.     r = random();
  420.  
  421.     if (r < 0.33)
  422.         self->monsterinfo.currentmove = &soldier_move_pain1;
  423.     else if (r < 0.66)
  424.         self->monsterinfo.currentmove = &soldier_move_pain2;
  425.     else
  426.         self->monsterinfo.currentmove = &soldier_move_pain3;
  427. }
  428.  
  429.  
  430. //
  431. // ATTACK
  432. //
  433.  
  434. static int blaster_flash [] = {MZ2_SOLDIER_BLASTER_1, MZ2_SOLDIER_BLASTER_2, MZ2_SOLDIER_BLASTER_3, MZ2_SOLDIER_BLASTER_4, MZ2_SOLDIER_BLASTER_5, MZ2_SOLDIER_BLASTER_6, MZ2_SOLDIER_BLASTER_7, MZ2_SOLDIER_BLASTER_8};
  435. static int shotgun_flash [] = {MZ2_SOLDIER_SHOTGUN_1, MZ2_SOLDIER_SHOTGUN_2, MZ2_SOLDIER_SHOTGUN_3, MZ2_SOLDIER_SHOTGUN_4, MZ2_SOLDIER_SHOTGUN_5, MZ2_SOLDIER_SHOTGUN_6, MZ2_SOLDIER_SHOTGUN_7, MZ2_SOLDIER_SHOTGUN_8};
  436. static int machinegun_flash [] = {MZ2_SOLDIER_MACHINEGUN_1, MZ2_SOLDIER_MACHINEGUN_2, MZ2_SOLDIER_MACHINEGUN_3, MZ2_SOLDIER_MACHINEGUN_4, MZ2_SOLDIER_MACHINEGUN_5, MZ2_SOLDIER_MACHINEGUN_6, MZ2_SOLDIER_MACHINEGUN_7, MZ2_SOLDIER_MACHINEGUN_8};
  437.  
  438. void soldier_fire (edict_t *self, int flash_number)
  439. {
  440.     vec3_t    start;
  441.     vec3_t    forward, right, up;
  442.     vec3_t    aim;
  443.     vec3_t    dir;
  444.     vec3_t    end;
  445.     float    r, u;
  446.     int        flash_index;
  447.  
  448.     if (self->s.skinnum < 2)
  449.         flash_index = blaster_flash[flash_number];
  450.     else if (self->s.skinnum < 4)
  451.         flash_index = shotgun_flash[flash_number];
  452.     else
  453.         flash_index = machinegun_flash[flash_number];
  454.  
  455.     AngleVectors (self->s.angles, forward, right, NULL);
  456.     G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
  457.  
  458.     if (flash_number == 5 || flash_number == 6)
  459.     {
  460.         VectorCopy (forward, aim);
  461.     }
  462.     else
  463.     {
  464.         VectorCopy (self->enemy->s.origin, end);
  465.         end[2] += self->enemy->viewheight;
  466.         VectorSubtract (end, start, aim);
  467.         vectoangles (aim, dir);
  468.         AngleVectors (dir, forward, right, up);
  469.  
  470.         r = crandom()*1000;
  471.         u = crandom()*500;
  472.         VectorMA (start, 8192, forward, end);
  473.         VectorMA (end, r, right, end);
  474.         VectorMA (end, u, up, end);
  475.  
  476.         VectorSubtract (end, start, aim);
  477.         VectorNormalize (aim);
  478.     }
  479.  
  480.     if (self->s.skinnum <= 1)
  481.     {
  482.         monster_fire_blaster (self, start, aim, 5, 600, flash_index, EF_BLASTER);
  483.     }
  484.     else if (self->s.skinnum <= 3)
  485.     {
  486.         monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index);
  487.     }
  488.     else
  489.     {
  490.         if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
  491.             self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
  492.  
  493.         monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);
  494.  
  495.         if (level.time >= self->monsterinfo.pausetime)
  496.             self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
  497.         else
  498.             self->monsterinfo.aiflags |= AI_HOLD_FRAME;
  499.     }
  500. }
  501.  
  502. // ATTACK1 (blaster/shotgun)
  503.  
  504. void soldier_fire1 (edict_t *self)
  505. {
  506.     soldier_fire (self, 0);
  507. }
  508.  
  509. void soldier_attack1_refire1 (edict_t *self)
  510. {
  511.     if (self->s.skinnum > 1)
  512.         return;
  513.  
  514.     if (self->enemy->health <= 0)
  515.         return;
  516.  
  517.     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  518.         self->monsterinfo.nextframe = FRAME_attak102;
  519.     else
  520.         self->monsterinfo.nextframe = FRAME_attak110;
  521. }
  522.  
  523. void soldier_attack1_refire2 (edict_t *self)
  524. {
  525.     if (self->s.skinnum < 2)
  526.         return;
  527.  
  528.     if (self->enemy->health <= 0)
  529.         return;
  530.  
  531.     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  532.         self->monsterinfo.nextframe = FRAME_attak102;
  533. }
  534.  
  535. mframe_t soldier_frames_attack1 [] =
  536. {
  537.     ai_charge, 0,  NULL,
  538.     ai_charge, 0,  NULL,
  539.     ai_charge, 0,  soldier_fire1,
  540.     ai_charge, 0,  NULL,
  541.     ai_charge, 0,  NULL,
  542.     ai_charge, 0,  soldier_attack1_refire1,
  543.     ai_charge, 0,  NULL,
  544.     ai_charge, 0,  soldier_cock,
  545.     ai_charge, 0,  soldier_attack1_refire2,
  546.     ai_charge, 0,  NULL,
  547.     ai_charge, 0,  NULL,
  548.     ai_charge, 0,  NULL
  549. };
  550. mmove_t soldier_move_attack1 = {FRAME_attak101, FRAME_attak112, soldier_frames_attack1, soldier_run};
  551.  
  552. // ATTACK2 (blaster/shotgun)
  553.  
  554. void soldier_fire2 (edict_t *self)
  555. {
  556.     soldier_fire (self, 1);
  557. }
  558.  
  559. void soldier_attack2_refire1 (edict_t *self)
  560. {
  561.     if (self->s.skinnum > 1)
  562.         return;
  563.  
  564.     if (self->enemy->health <= 0)
  565.         return;
  566.  
  567.     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  568.         self->monsterinfo.nextframe = FRAME_attak204;
  569.     else
  570.         self->monsterinfo.nextframe = FRAME_attak216;
  571. }
  572.  
  573. void soldier_attack2_refire2 (edict_t *self)
  574. {
  575.     if (self->s.skinnum < 2)
  576.         return;
  577.  
  578.     if (self->enemy->health <= 0)
  579.         return;
  580.  
  581.     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  582.         self->monsterinfo.nextframe = FRAME_attak204;
  583. }
  584.  
  585. mframe_t soldier_frames_attack2 [] =
  586. {
  587.     ai_charge, 0, NULL,
  588.     ai_charge, 0, NULL,
  589.     ai_charge, 0, NULL,
  590.     ai_charge, 0, NULL,
  591.     ai_charge, 0, soldier_fire2,
  592.     ai_charge, 0, NULL,
  593.     ai_charge, 0, NULL,
  594.     ai_charge, 0, soldier_attack2_refire1,
  595.     ai_charge, 0, NULL,
  596.     ai_charge, 0, NULL,
  597.     ai_charge, 0, NULL,
  598.     ai_charge, 0, NULL,
  599.     ai_charge, 0, soldier_cock,
  600.     ai_charge, 0, NULL,
  601.     ai_charge, 0, soldier_attack2_refire2,
  602.     ai_charge, 0, NULL,
  603.     ai_charge, 0, NULL,
  604.     ai_charge, 0, NULL
  605. };
  606. mmove_t soldier_move_attack2 = {FRAME_attak201, FRAME_attak218, soldier_frames_attack2, soldier_run};
  607.  
  608. // ATTACK3 (duck and shoot)
  609.  
  610. void soldier_duck_down (edict_t *self)
  611. {
  612.     if (self->monsterinfo.aiflags & AI_DUCKED)
  613.         return;
  614.     self->monsterinfo.aiflags |= AI_DUCKED;
  615.     self->maxs[2] -= 32;
  616.     self->takedamage = DAMAGE_YES;
  617.     self->monsterinfo.pausetime = level.time + 1;
  618.     gi.linkentity (self);
  619. }
  620.  
  621. void soldier_duck_up (edict_t *self)
  622. {
  623.     self->monsterinfo.aiflags &= ~AI_DUCKED;
  624.     self->maxs[2] += 32;
  625.     self->takedamage = DAMAGE_AIM;
  626.     gi.linkentity (self);
  627. }
  628.  
  629. void soldier_fire3 (edict_t *self)
  630. {
  631.     soldier_duck_down (self);
  632.     soldier_fire (self, 2);
  633. }
  634.  
  635. void soldier_attack3_refire (edict_t *self)
  636. {
  637.     if ((level.time + 0.4) < self->monsterinfo.pausetime)
  638.         self->monsterinfo.nextframe = FRAME_attak303;
  639. }
  640.  
  641. mframe_t soldier_frames_attack3 [] =
  642. {
  643.     ai_charge, 0, NULL,
  644.     ai_charge, 0, NULL,
  645.     ai_charge, 0, soldier_fire3,
  646.     ai_charge, 0, NULL,
  647.     ai_charge, 0, NULL,
  648.     ai_charge, 0, soldier_attack3_refire,
  649.     ai_charge, 0, soldier_duck_up,
  650.     ai_charge, 0, NULL,
  651.     ai_charge, 0, NULL
  652. };
  653. mmove_t soldier_move_attack3 = {FRAME_attak301, FRAME_attak309, soldier_frames_attack3, soldier_run};
  654.  
  655. // ATTACK4 (machinegun)
  656.  
  657. void soldier_fire4 (edict_t *self)
  658. {
  659.     soldier_fire (self, 3);
  660. //
  661. //    if (self->enemy->health <= 0)
  662. //        return;
  663. //
  664. //    if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  665. //        self->monsterinfo.nextframe = FRAME_attak402;
  666. }
  667.  
  668. mframe_t soldier_frames_attack4 [] =
  669. {
  670.     ai_charge, 0, NULL,
  671.     ai_charge, 0, NULL,
  672.     ai_charge, 0, soldier_fire4,
  673.     ai_charge, 0, NULL,
  674.     ai_charge, 0, NULL,
  675.     ai_charge, 0, NULL
  676. };
  677. mmove_t soldier_move_attack4 = {FRAME_attak401, FRAME_attak406, soldier_frames_attack4, soldier_run};
  678.  
  679. #if 0
  680. // ATTACK5 (prone)
  681.  
  682. void soldier_fire5 (edict_t *self)
  683. {
  684.     soldier_fire (self, 4);
  685. }
  686.  
  687. void soldier_attack5_refire (edict_t *self)
  688. {
  689.     if (self->enemy->health <= 0)
  690.         return;
  691.  
  692.     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
  693.         self->monsterinfo.nextframe = FRAME_attak505;
  694. }
  695.  
  696. mframe_t soldier_frames_attack5 [] =
  697. {
  698.     ai_charge, 8, NULL,
  699.     ai_charge, 8, NULL,
  700.     ai_charge, 0, NULL,
  701.     ai_charge, 0, NULL,
  702.     ai_charge, 0, soldier_fire5,
  703.     ai_charge, 0, NULL,
  704.     ai_charge, 0, NULL,
  705.     ai_charge, 0, soldier_attack5_refire
  706. };
  707. mmove_t soldier_move_attack5 = {FRAME_attak501, FRAME_attak508, soldier_frames_attack5, soldier_run};
  708. #endif
  709.  
  710. // ATTACK6 (run & shoot)
  711.  
  712. void soldier_fire8 (edict_t *self)
  713. {
  714.     soldier_fire (self, 7);
  715. }
  716.  
  717. void soldier_attack6_refire (edict_t *self)
  718. {
  719.     if (self->enemy->health <= 0)
  720.         return;
  721.  
  722.     if (range(self, self->enemy) < RANGE_MID)
  723.         return;
  724.  
  725.     if (skill->value == 3)
  726.         self->monsterinfo.nextframe = FRAME_runs03;
  727. }
  728.  
  729. mframe_t soldier_frames_attack6 [] =
  730. {
  731.     ai_charge, 10, NULL,
  732.     ai_charge,  4, NULL,
  733.     ai_charge, 12, NULL,
  734.     ai_charge, 11, soldier_fire8,
  735.     ai_charge, 13, NULL,
  736.     ai_charge, 18, NULL,
  737.     ai_charge, 15, NULL,
  738.     ai_charge, 14, NULL,
  739.     ai_charge, 11, NULL,
  740.     ai_charge,  8, NULL,
  741.     ai_charge, 11, NULL,
  742.     ai_charge, 12, NULL,
  743.     ai_charge, 12, NULL,
  744.     ai_charge, 17, soldier_attack6_refire
  745. };
  746. mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attack6, soldier_run};
  747.  
  748. void soldier_attack(edict_t *self)
  749. {
  750.     if (self->s.skinnum < 4)
  751.     {
  752.         if (random() < 0.5)
  753.             self->monsterinfo.currentmove = &soldier_move_attack1;
  754.         else
  755.             self->monsterinfo.currentmove = &soldier_move_attack2;
  756.     }
  757.     else
  758.     {
  759.         self->monsterinfo.currentmove = &soldier_move_attack4;
  760.     }
  761. }
  762.  
  763.  
  764. //
  765. // SIGHT
  766. //
  767.  
  768. void soldier_sight(edict_t *self, edict_t *other)
  769. {
  770.     if (random() < 0.5)
  771.         gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
  772.     else
  773.         gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
  774.  
  775.     if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
  776.     {
  777.         if (random() > 0.5)
  778.             self->monsterinfo.currentmove = &soldier_move_attack6;
  779.     }
  780. }
  781.  
  782. //
  783. // DUCK
  784. //
  785.  
  786. void soldier_duck_hold (edict_t *self)
  787. {
  788.     if (level.time >= self->monsterinfo.pausetime)
  789.         self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
  790.     else
  791.         self->monsterinfo.aiflags |= AI_HOLD_FRAME;
  792. }
  793.  
  794. mframe_t soldier_frames_duck [] =
  795. {
  796.     ai_move, 5, soldier_duck_down,
  797.     ai_move, -1, soldier_duck_hold,
  798.     ai_move, 1,  NULL,
  799.     ai_move, 0,  soldier_duck_up,
  800.     ai_move, 5,  NULL
  801. };
  802. mmove_t soldier_move_duck = {FRAME_duck01, FRAME_duck05, soldier_frames_duck, soldier_run};
  803.  
  804. void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
  805. {
  806.     float    r;
  807.  
  808.     r = random();
  809.     if (r > 0.25)
  810.         return;
  811.  
  812.     if (!self->enemy)
  813.         self->enemy = attacker;
  814.  
  815.     if (skill->value == 0)
  816.     {
  817.         self->monsterinfo.currentmove = &soldier_move_duck;
  818.         return;
  819.     }
  820.  
  821.     self->monsterinfo.pausetime = level.time + eta + 0.3;
  822.     r = random();
  823.  
  824.     if (skill->value == 1)
  825.     {
  826.         if (r > 0.33)
  827.             self->monsterinfo.currentmove = &soldier_move_duck;
  828.         else
  829.             self->monsterinfo.currentmove = &soldier_move_attack3;
  830.         return;
  831.     }
  832.  
  833.     if (skill->value == 2)
  834.     {
  835.         if (r > 0.66)
  836.             self->monsterinfo.currentmove = &soldier_move_duck;
  837.         else
  838.             self->monsterinfo.currentmove = &soldier_move_attack3;
  839.         return;
  840.     }
  841.  
  842.     self->monsterinfo.currentmove = &soldier_move_attack3;
  843. }
  844.  
  845.  
  846. //
  847. // DEATH
  848. //
  849.  
  850. void soldier_fire6 (edict_t *self)
  851. {
  852.     soldier_fire (self, 5);
  853. }
  854.  
  855. void soldier_fire7 (edict_t *self)
  856. {
  857.     soldier_fire (self, 6);
  858. }
  859.  
  860. void soldier_dead (edict_t *self)
  861. {
  862.     VectorSet (self->mins, -16, -16, -24);
  863.     VectorSet (self->maxs, 16, 16, -8);
  864.     self->movetype = MOVETYPE_TOSS;
  865.     self->nextthink = 0;
  866.     gi.linkentity (self);
  867. }
  868.  
  869. mframe_t soldier_frames_death1 [] =
  870. {
  871.     ai_move, 0,   NULL,
  872.     ai_move, -10, NULL,
  873.     ai_move, -10, NULL,
  874.     ai_move, -10, NULL,
  875.     ai_move, -5,  NULL,
  876.     ai_move, 0,   NULL,
  877.     ai_move, 0,   NULL,
  878.     ai_move, 0,   NULL,
  879.     ai_move, 0,   NULL,
  880.     ai_move, 0,   NULL,
  881.  
  882.     ai_move, 0,   NULL,
  883.     ai_move, 0,   NULL,
  884.     ai_move, 0,   NULL,
  885.     ai_move, 0,   NULL,
  886.     ai_move, 0,   NULL,
  887.     ai_move, 0,   NULL,
  888.     ai_move, 0,   NULL,
  889.     ai_move, 0,   NULL,
  890.     ai_move, 0,   NULL,
  891.     ai_move, 0,   NULL,
  892.  
  893.     ai_move, 0,   NULL,
  894.     ai_move, 0,   soldier_fire6,
  895.     ai_move, 0,   NULL,
  896.     ai_move, 0,   NULL,
  897.     ai_move, 0,   soldier_fire7,
  898.     ai_move, 0,   NULL,
  899.     ai_move, 0,   NULL,
  900.     ai_move, 0,   NULL,
  901.     ai_move, 0,   NULL,
  902.     ai_move, 0,   NULL,
  903.  
  904.     ai_move, 0,   NULL,
  905.     ai_move, 0,   NULL,
  906.     ai_move, 0,   NULL,
  907.     ai_move, 0,   NULL,
  908.     ai_move, 0,   NULL,
  909.     ai_move, 0,   NULL
  910. };
  911. mmove_t soldier_move_death1 = {FRAME_death101, FRAME_death136, soldier_frames_death1, soldier_dead};
  912.  
  913. mframe_t soldier_frames_death2 [] =
  914. {
  915.     ai_move, -5,  NULL,
  916.     ai_move, -5,  NULL,
  917.     ai_move, -5,  NULL,
  918.     ai_move, 0,   NULL,
  919.     ai_move, 0,   NULL,
  920.     ai_move, 0,   NULL,
  921.     ai_move, 0,   NULL,
  922.     ai_move, 0,   NULL,
  923.     ai_move, 0,   NULL,
  924.     ai_move, 0,   NULL,
  925.  
  926.     ai_move, 0,   NULL,
  927.     ai_move, 0,   NULL,
  928.     ai_move, 0,   NULL,
  929.     ai_move, 0,   NULL,
  930.     ai_move, 0,   NULL,
  931.     ai_move, 0,   NULL,
  932.     ai_move, 0,   NULL,
  933.     ai_move, 0,   NULL,
  934.     ai_move, 0,   NULL,
  935.     ai_move, 0,   NULL,
  936.  
  937.     ai_move, 0,   NULL,
  938.     ai_move, 0,   NULL,
  939.     ai_move, 0,   NULL,
  940.     ai_move, 0,   NULL,
  941.     ai_move, 0,   NULL,
  942.     ai_move, 0,   NULL,
  943.     ai_move, 0,   NULL,
  944.     ai_move, 0,   NULL,
  945.     ai_move, 0,   NULL,
  946.     ai_move, 0,   NULL,
  947.  
  948.     ai_move, 0,   NULL,
  949.     ai_move, 0,   NULL,
  950.     ai_move, 0,   NULL,
  951.     ai_move, 0,   NULL,
  952.     ai_move, 0,   NULL
  953. };
  954. mmove_t soldier_move_death2 = {FRAME_death201, FRAME_death235, soldier_frames_death2, soldier_dead};
  955.  
  956. mframe_t soldier_frames_death3 [] =
  957. {
  958.     ai_move, -5,  NULL,
  959.     ai_move, -5,  NULL,
  960.     ai_move, -5,  NULL,
  961.     ai_move, 0,   NULL,
  962.     ai_move, 0,   NULL,
  963.     ai_move, 0,   NULL,
  964.     ai_move, 0,   NULL,
  965.     ai_move, 0,   NULL,
  966.     ai_move, 0,   NULL,
  967.     ai_move, 0,   NULL,
  968.  
  969.     ai_move, 0,   NULL,
  970.     ai_move, 0,   NULL,
  971.     ai_move, 0,   NULL,
  972.     ai_move, 0,   NULL,
  973.     ai_move, 0,   NULL,
  974.     ai_move, 0,   NULL,
  975.     ai_move, 0,   NULL,
  976.     ai_move, 0,   NULL,
  977.     ai_move, 0,   NULL,
  978.     ai_move, 0,   NULL,
  979.  
  980.     ai_move, 0,   NULL,
  981.     ai_move, 0,   NULL,
  982.     ai_move, 0,   NULL,
  983.     ai_move, 0,   NULL,
  984.     ai_move, 0,   NULL,
  985.     ai_move, 0,   NULL,
  986.     ai_move, 0,   NULL,
  987.     ai_move, 0,   NULL,
  988.     ai_move, 0,   NULL,
  989.     ai_move, 0,   NULL,
  990.  
  991.     ai_move, 0,   NULL,
  992.     ai_move, 0,   NULL,
  993.     ai_move, 0,   NULL,
  994.     ai_move, 0,   NULL,
  995.     ai_move, 0,   NULL,
  996.     ai_move, 0,   NULL,
  997.     ai_move, 0,   NULL,
  998.     ai_move, 0,   NULL,
  999.     ai_move, 0,   NULL,
  1000.     ai_move, 0,   NULL,
  1001.  
  1002.     ai_move, 0,   NULL,
  1003.     ai_move, 0,   NULL,
  1004.     ai_move, 0,   NULL,
  1005.     ai_move, 0,   NULL,
  1006.     ai_move, 0,   NULL,
  1007. };
  1008. mmove_t soldier_move_death3 = {FRAME_death301, FRAME_death345, soldier_frames_death3, soldier_dead};
  1009.  
  1010. mframe_t soldier_frames_death4 [] =
  1011. {
  1012.     ai_move, 0,   NULL,
  1013.     ai_move, 0,   NULL,
  1014.     ai_move, 0,   NULL,
  1015.     ai_move, 0,   NULL,
  1016.     ai_move, 0,   NULL,
  1017.     ai_move, 0,   NULL,
  1018.     ai_move, 0,   NULL,
  1019.     ai_move, 0,   NULL,
  1020.     ai_move, 0,   NULL,
  1021.     ai_move, 0,   NULL,
  1022.  
  1023.     ai_move, 0,   NULL,
  1024.     ai_move, 0,   NULL,
  1025.     ai_move, 0,   NULL,
  1026.     ai_move, 0,   NULL,
  1027.     ai_move, 0,   NULL,
  1028.     ai_move, 0,   NULL,
  1029.     ai_move, 0,   NULL,
  1030.     ai_move, 0,   NULL,
  1031.     ai_move, 0,   NULL,
  1032.     ai_move, 0,   NULL,
  1033.  
  1034.     ai_move, 0,   NULL,
  1035.     ai_move, 0,   NULL,
  1036.     ai_move, 0,   NULL,
  1037.     ai_move, 0,   NULL,
  1038.     ai_move, 0,   NULL,
  1039.     ai_move, 0,   NULL,
  1040.     ai_move, 0,   NULL,
  1041.     ai_move, 0,   NULL,
  1042.     ai_move, 0,   NULL,
  1043.     ai_move, 0,   NULL,
  1044.  
  1045.     ai_move, 0,   NULL,
  1046.     ai_move, 0,   NULL,
  1047.     ai_move, 0,   NULL,
  1048.     ai_move, 0,   NULL,
  1049.     ai_move, 0,   NULL,
  1050.     ai_move, 0,   NULL,
  1051.     ai_move, 0,   NULL,
  1052.     ai_move, 0,   NULL,
  1053.     ai_move, 0,   NULL,
  1054.     ai_move, 0,   NULL,
  1055.  
  1056.     ai_move, 0,   NULL,
  1057.     ai_move, 0,   NULL,
  1058.     ai_move, 0,   NULL,
  1059.     ai_move, 0,   NULL,
  1060.     ai_move, 0,   NULL,
  1061.     ai_move, 0,   NULL,
  1062.     ai_move, 0,   NULL,
  1063.     ai_move, 0,   NULL,
  1064.     ai_move, 0,   NULL,
  1065.     ai_move, 0,   NULL,
  1066.  
  1067.     ai_move, 0,   NULL,
  1068.     ai_move, 0,   NULL,
  1069.     ai_move, 0,   NULL
  1070. };
  1071. mmove_t soldier_move_death4 = {FRAME_death401, FRAME_death453, soldier_frames_death4, soldier_dead};
  1072.  
  1073. mframe_t soldier_frames_death5 [] =
  1074. {
  1075.     ai_move, -5,  NULL,
  1076.     ai_move, -5,  NULL,
  1077.     ai_move, -5,  NULL,
  1078.     ai_move, 0,   NULL,
  1079.     ai_move, 0,   NULL,
  1080.     ai_move, 0,   NULL,
  1081.     ai_move, 0,   NULL,
  1082.     ai_move, 0,   NULL,
  1083.     ai_move, 0,   NULL,
  1084.     ai_move, 0,   NULL,
  1085.  
  1086.     ai_move, 0,   NULL,
  1087.     ai_move, 0,   NULL,
  1088.     ai_move, 0,   NULL,
  1089.     ai_move, 0,   NULL,
  1090.     ai_move, 0,   NULL,
  1091.     ai_move, 0,   NULL,
  1092.     ai_move, 0,   NULL,
  1093.     ai_move, 0,   NULL,
  1094.     ai_move, 0,   NULL,
  1095.     ai_move, 0,   NULL,
  1096.  
  1097.     ai_move, 0,   NULL,
  1098.     ai_move, 0,   NULL,
  1099.     ai_move, 0,   NULL,
  1100.     ai_move, 0,   NULL
  1101. };
  1102. mmove_t soldier_move_death5 = {FRAME_death501, FRAME_death524, soldier_frames_death5, soldier_dead};
  1103.  
  1104. mframe_t soldier_frames_death6 [] =
  1105. {
  1106.     ai_move, 0,   NULL,
  1107.     ai_move, 0,   NULL,
  1108.     ai_move, 0,   NULL,
  1109.     ai_move, 0,   NULL,
  1110.     ai_move, 0,   NULL,
  1111.     ai_move, 0,   NULL,
  1112.     ai_move, 0,   NULL,
  1113.     ai_move, 0,   NULL,
  1114.     ai_move, 0,   NULL,
  1115.     ai_move, 0,   NULL
  1116. };
  1117. mmove_t soldier_move_death6 = {FRAME_death601, FRAME_death610, soldier_frames_death6, soldier_dead};
  1118.  
  1119. void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  1120. {
  1121.     int        n;
  1122.  
  1123. // check for gib
  1124.     if (self->health <= self->gib_health)
  1125.     {
  1126.         gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  1127.         for (n= 0; n < 3; n++)
  1128.             ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  1129.         ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
  1130.         ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
  1131.         self->deadflag = DEAD_DEAD;
  1132.         return;
  1133.     }
  1134.  
  1135.     if (self->deadflag == DEAD_DEAD)
  1136.         return;
  1137.  
  1138. // regular death
  1139.     self->deadflag = DEAD_DEAD;
  1140.     self->takedamage = DAMAGE_YES;
  1141.     self->s.skinnum |= 1;
  1142.  
  1143.     if (self->s.skinnum == 1)
  1144.         gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
  1145.     else if (self->s.skinnum == 3)
  1146.         gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
  1147.     else // (self->s.skinnum == 5)
  1148.         gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
  1149.  
  1150.     if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
  1151.     {
  1152.         // head shot
  1153.         self->monsterinfo.currentmove = &soldier_move_death3;
  1154.         return;
  1155.     }
  1156.  
  1157.     n = rand() % 5;
  1158.     if (n == 0)
  1159.         self->monsterinfo.currentmove = &soldier_move_death1;
  1160.     else if (n == 1)
  1161.         self->monsterinfo.currentmove = &soldier_move_death2;
  1162.     else if (n == 2)
  1163.         self->monsterinfo.currentmove = &soldier_move_death4;
  1164.     else if (n == 3)
  1165.         self->monsterinfo.currentmove = &soldier_move_death5;
  1166.     else
  1167.         self->monsterinfo.currentmove = &soldier_move_death6;
  1168. }
  1169.  
  1170.  
  1171. //
  1172. // SPAWN
  1173. //
  1174.  
  1175. void SP_monster_soldier_x (edict_t *self)
  1176. {
  1177.  
  1178.     self->s.modelindex = gi.modelindex ("models/monsters/soldier/tris.md2");
  1179.     self->monsterinfo.scale = MODEL_SCALE;
  1180.     VectorSet (self->mins, -16, -16, -24);
  1181.     VectorSet (self->maxs, 16, 16, 32);
  1182.     self->movetype = MOVETYPE_STEP;
  1183.     self->solid = SOLID_BBOX;
  1184.  
  1185.     sound_idle =    gi.soundindex ("soldier/solidle1.wav");
  1186.     sound_sight1 =    gi.soundindex ("soldier/solsght1.wav");
  1187.     sound_sight2 =    gi.soundindex ("soldier/solsrch1.wav");
  1188.     sound_cock =    gi.soundindex ("infantry/infatck3.wav");
  1189.  
  1190.     self->mass = 100;
  1191.  
  1192.     self->pain = soldier_pain;
  1193.     self->die = soldier_die;
  1194.  
  1195.     self->monsterinfo.stand = soldier_stand;
  1196.     self->monsterinfo.walk = soldier_walk;
  1197.     self->monsterinfo.run = soldier_run;
  1198.     self->monsterinfo.dodge = soldier_dodge;
  1199.     self->monsterinfo.attack = soldier_attack;
  1200.     self->monsterinfo.melee = NULL;
  1201.     self->monsterinfo.sight = soldier_sight;
  1202.  
  1203.     gi.linkentity (self);
  1204.  
  1205.     self->monsterinfo.stand (self);
  1206.  
  1207.     walkmonster_start (self);
  1208. }
  1209.  
  1210.  
  1211. /*QUAKED monster_soldier_light (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  1212. */
  1213. void SP_monster_soldier_light (edict_t *self)
  1214. {
  1215.     if (deathmatch->value)
  1216.     {
  1217.         G_FreeEdict (self);
  1218.         return;
  1219.     }
  1220.  
  1221.     SP_monster_soldier_x (self);
  1222.  
  1223.     sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
  1224.     sound_death_light =    gi.soundindex ("soldier/soldeth2.wav");
  1225.     gi.modelindex ("models/objects/laser/tris.md2");
  1226.     gi.soundindex ("misc/lasfly.wav");
  1227.     gi.soundindex ("soldier/solatck2.wav");
  1228.  
  1229.     self->s.skinnum = 0;
  1230.     self->health = 20;
  1231.     self->gib_health = -30;
  1232. }
  1233.  
  1234. /*QUAKED monster_soldier (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  1235. */
  1236. void SP_monster_soldier (edict_t *self)
  1237. {
  1238.     if (deathmatch->value)
  1239.     {
  1240.         G_FreeEdict (self);
  1241.         return;
  1242.     }
  1243.  
  1244.     SP_monster_soldier_x (self);
  1245.  
  1246.     sound_pain = gi.soundindex ("soldier/solpain1.wav");
  1247.     sound_death = gi.soundindex ("soldier/soldeth1.wav");
  1248.     gi.soundindex ("soldier/solatck1.wav");
  1249.  
  1250.     self->s.skinnum = 2;
  1251.     self->health = 30;
  1252.     self->gib_health = -30;
  1253. }
  1254.  
  1255. /*QUAKED monster_soldier_ss (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  1256. */
  1257. void SP_monster_soldier_ss (edict_t *self)
  1258. {
  1259.     if (deathmatch->value)
  1260.     {
  1261.         G_FreeEdict (self);
  1262.         return;
  1263.     }
  1264.  
  1265.     SP_monster_soldier_x (self);
  1266.  
  1267.     sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
  1268.     sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
  1269.     gi.soundindex ("soldier/solatck3.wav");
  1270.  
  1271.     self->s.skinnum = 4;
  1272.     self->health = 40;
  1273.     self->gib_health = -30;
  1274. }
  1275.