home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / m_boss32.c < prev    next >
C/C++ Source or Header  |  1998-01-13  |  21KB  |  895 lines

  1. /*
  2. ==============================================================================
  3.  
  4. Makron -- Final Boss
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_boss32.h"
  11.  
  12. qboolean visible (edict_t *self, edict_t *other);
  13.  
  14. void MakronRailgun (edict_t *self);
  15. void MakronSaveloc (edict_t *self);
  16. void MakronHyperblaster (edict_t *self);
  17. void makron_step_left (edict_t *self);
  18. void makron_step_right (edict_t *self);
  19. void makronBFG (edict_t *self);
  20. void makron_dead (edict_t *self);
  21.  
  22. static int    sound_pain4;
  23. static int    sound_pain5;
  24. static int    sound_pain6;
  25. static int    sound_death;
  26. static int    sound_step_left;
  27. static int    sound_step_right;
  28. static int    sound_attack_bfg;
  29. static int    sound_brainsplorch;
  30. static int    sound_prerailgun;
  31. static int    sound_popup;
  32. static int    sound_taunt1;
  33. static int    sound_taunt2;
  34. static int    sound_taunt3;
  35. static int    sound_hit;
  36.  
  37. void makron_taunt (edict_t *self)
  38. {
  39.     float r;
  40.  
  41.     r=random();
  42.     if (r <= 0.3)
  43.         gi.sound (self, CHAN_AUTO, sound_taunt1, 1, ATTN_NONE, 0);
  44.     else if (r <= 0.6)
  45.         gi.sound (self, CHAN_AUTO, sound_taunt2, 1, ATTN_NONE, 0);
  46.     else
  47.         gi.sound (self, CHAN_AUTO, sound_taunt3, 1, ATTN_NONE, 0);
  48. }
  49.  
  50. //
  51. // stand
  52. //
  53.  
  54. mframe_t makron_frames_stand []=
  55. {
  56.     ai_stand, 0, NULL,
  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,        // 10
  66.     ai_stand, 0, NULL,
  67.     ai_stand, 0, NULL,
  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,        // 20
  76.     ai_stand, 0, NULL,
  77.     ai_stand, 0, NULL,
  78.     ai_stand, 0, NULL,
  79.     ai_stand, 0, NULL,
  80.     ai_stand, 0, NULL,
  81.     ai_stand, 0, NULL,
  82.     ai_stand, 0, NULL,
  83.     ai_stand, 0, NULL,
  84.     ai_stand, 0, NULL,
  85.     ai_stand, 0, NULL,        // 30
  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.     ai_stand, 0, NULL,
  94.     ai_stand, 0, NULL,
  95.     ai_stand, 0, NULL,        // 40
  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.     ai_stand, 0, NULL,
  105.     ai_stand, 0, NULL,        // 50
  106.     ai_stand, 0, NULL,
  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.     ai_stand, 0, NULL        // 60
  116. };
  117. mmove_t    makron_move_stand = {FRAME_stand201, FRAME_stand260, makron_frames_stand, NULL};
  118.     
  119. void makron_stand (edict_t *self)
  120. {
  121.     self->monsterinfo.currentmove = &makron_move_stand;
  122. }
  123.  
  124. mframe_t makron_frames_run [] =
  125. {
  126.     ai_run, 3,    makron_step_left,
  127.     ai_run, 12,    NULL,
  128.     ai_run, 8,    NULL,
  129.     ai_run, 8,    NULL,
  130.     ai_run, 8,    makron_step_right,
  131.     ai_run, 6,    NULL,
  132.     ai_run, 12,    NULL,
  133.     ai_run, 9,    NULL,
  134.     ai_run, 6,    NULL,
  135.     ai_run, 12,    NULL
  136. };
  137. mmove_t    makron_move_run = {FRAME_walk204, FRAME_walk213, makron_frames_run, NULL};
  138.  
  139. void makron_hit (edict_t *self)
  140. {
  141.     gi.sound (self, CHAN_AUTO, sound_hit, 1, ATTN_NONE,0);
  142. }
  143.  
  144. void makron_popup (edict_t *self)
  145. {
  146.     gi.sound (self, CHAN_BODY, sound_popup, 1, ATTN_NONE,0);
  147. }
  148.  
  149. void makron_step_left (edict_t *self)
  150. {
  151.     gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0);
  152. }
  153.  
  154. void makron_step_right (edict_t *self)
  155. {
  156.     gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0);
  157. }
  158.  
  159. void makron_brainsplorch (edict_t *self)
  160. {
  161.     gi.sound (self, CHAN_VOICE, sound_brainsplorch, 1, ATTN_NORM,0);
  162. }
  163.  
  164. void makron_prerailgun (edict_t *self)
  165. {
  166.     gi.sound (self, CHAN_WEAPON, sound_prerailgun, 1, ATTN_NORM,0);
  167. }
  168.  
  169.  
  170. mframe_t makron_frames_walk [] =
  171. {
  172.     ai_walk, 3,    makron_step_left,
  173.     ai_walk, 12,    NULL,
  174.     ai_walk, 8,    NULL,
  175.     ai_walk, 8,    NULL,
  176.     ai_walk, 8,    makron_step_right,
  177.     ai_walk, 6,    NULL,
  178.     ai_walk, 12,    NULL,
  179.     ai_walk, 9,    NULL,
  180.     ai_walk, 6,    NULL,
  181.     ai_walk, 12,    NULL
  182. };
  183. mmove_t    makron_move_walk = {FRAME_walk204, FRAME_walk213, makron_frames_run, NULL};
  184.  
  185. void makron_walk (edict_t *self)
  186. {
  187.         self->monsterinfo.currentmove = &makron_move_walk;
  188. }
  189.  
  190. void makron_run (edict_t *self)
  191. {
  192.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  193.         self->monsterinfo.currentmove = &makron_move_stand;
  194.     else
  195.         self->monsterinfo.currentmove = &makron_move_run;
  196. }
  197.  
  198. mframe_t makron_frames_pain6 [] =
  199. {
  200.     ai_move,    0,    NULL,
  201.     ai_move,    0,    NULL,
  202.     ai_move,    0,    NULL,
  203.     ai_move,    0,    NULL,
  204.     ai_move,    0,    NULL,
  205.     ai_move,    0,    NULL,
  206.     ai_move,    0,    NULL,
  207.     ai_move,    0,    NULL,
  208.     ai_move,    0,    NULL,
  209.     ai_move,    0,    NULL,        // 10
  210.     ai_move,    0,    NULL,
  211.     ai_move,    0,    NULL,
  212.     ai_move,    0,    NULL,
  213.     ai_move,    0,    NULL,
  214.     ai_move,    0,    NULL,
  215.     ai_move,    0,    makron_popup,
  216.     ai_move,    0,    NULL,
  217.     ai_move,    0,    NULL,
  218.     ai_move,    0,    NULL,
  219.     ai_move,    0,    NULL,        // 20
  220.     ai_move,    0,    NULL,
  221.     ai_move,    0,    NULL,
  222.     ai_move,    0,    NULL,
  223.     ai_move,    0,    makron_taunt,
  224.     ai_move,    0,    NULL,
  225.     ai_move,    0,    NULL,
  226.     ai_move,    0,    NULL
  227. };
  228. mmove_t makron_move_pain6 = {FRAME_pain601, FRAME_pain627, makron_frames_pain6, makron_run};
  229.  
  230. mframe_t makron_frames_pain5 [] =
  231. {
  232.     ai_move,    0,    NULL,
  233.     ai_move,    0,    NULL,
  234.     ai_move,    0,    NULL,
  235.     ai_move,    0,    NULL
  236. };
  237. mmove_t makron_move_pain5 = {FRAME_pain501, FRAME_pain504, makron_frames_pain5, makron_run};
  238.  
  239. mframe_t makron_frames_pain4 [] =
  240. {
  241.     ai_move,    0,    NULL,
  242.     ai_move,    0,    NULL,
  243.     ai_move,    0,    NULL,
  244.     ai_move,    0,    NULL
  245. };
  246. mmove_t makron_move_pain4 = {FRAME_pain401, FRAME_pain404, makron_frames_pain4, makron_run};
  247.  
  248. mframe_t makron_frames_death2 [] =
  249. {
  250.     ai_move,    -15,    NULL,
  251.     ai_move,    3,    NULL,
  252.     ai_move,    -12,    NULL,
  253.     ai_move,    0,    makron_step_left,
  254.     ai_move,    0,    NULL,
  255.     ai_move,    0,    NULL,
  256.     ai_move,    0,    NULL,
  257.     ai_move,    0,    NULL,
  258.     ai_move,    0,    NULL,
  259.     ai_move,    0,    NULL,            // 10
  260.     ai_move,    0,    NULL,
  261.     ai_move,    0,    NULL,
  262.     ai_move,    0,    NULL,
  263.     ai_move,    0,    NULL,
  264.     ai_move,    0,    NULL,
  265.     ai_move,    11,    NULL,
  266.     ai_move,    12,    NULL,
  267.     ai_move,    11,    makron_step_right,
  268.     ai_move,    0,    NULL,
  269.     ai_move,    0,    NULL,            // 20
  270.     ai_move,    0,    NULL,
  271.     ai_move,    0,    NULL,
  272.     ai_move,    0,    NULL,
  273.     ai_move,    0,    NULL,
  274.     ai_move,    0,    NULL,
  275.     ai_move,    0,    NULL,
  276.     ai_move,    0,    NULL,            
  277.     ai_move,    0,    NULL,
  278.     ai_move,    0,    NULL,
  279.     ai_move,    0,    NULL,            // 30
  280.     ai_move,    0,    NULL,
  281.     ai_move,    0,    NULL,
  282.     ai_move,    0,    NULL,
  283.     ai_move,    5,    NULL,
  284.     ai_move,    7,    NULL,
  285.     ai_move,    6,    makron_step_left,
  286.     ai_move,    0,    NULL,
  287.     ai_move,    0,    NULL,
  288.     ai_move,    -1,    NULL,
  289.     ai_move,    2,    NULL,            // 40
  290.     ai_move,    0,    NULL,            
  291.     ai_move,    0,    NULL,
  292.     ai_move,    0,    NULL,
  293.     ai_move,    0,    NULL,
  294.     ai_move,    0,    NULL,
  295.     ai_move,    0,    NULL,
  296.     ai_move,    0,    NULL,
  297.     ai_move,    0,    NULL,
  298.     ai_move,    0,    NULL,            
  299.     ai_move,    0,    NULL,            // 50
  300.     ai_move,    0,    NULL,            
  301.     ai_move,    0,    NULL,
  302.     ai_move,    0,    NULL,
  303.     ai_move,    -6,    NULL,
  304.     ai_move,    -4,    NULL,
  305.     ai_move,    -6,    makron_step_right,
  306.     ai_move,    -4,    NULL,
  307.     ai_move,    -4,    makron_step_left,
  308.     ai_move,    0,    NULL,
  309.     ai_move,    0,    NULL,            // 60
  310.     ai_move,    0,    NULL,            
  311.     ai_move,    0,    NULL,
  312.     ai_move,    -2,    NULL,
  313.     ai_move,    -5,    NULL,
  314.     ai_move,    -3,    makron_step_right,
  315.     ai_move,    -8,    NULL,
  316.     ai_move,    -3,    makron_step_left,
  317.     ai_move,    -7,    NULL,
  318.     ai_move,    -4,    NULL,
  319.     ai_move,    -4,    makron_step_right,            // 70
  320.     ai_move,    -6,    NULL,            
  321.     ai_move,    -7,    NULL,
  322.     ai_move,    0,    makron_step_left,
  323.     ai_move,    0,    NULL,
  324.     ai_move,    0,    NULL,
  325.     ai_move,    0,    NULL,
  326.     ai_move,    0,    NULL,
  327.     ai_move,    0,    NULL,
  328.     ai_move,    0,    NULL,
  329.     ai_move,    0,    NULL,            // 80
  330.     ai_move,    0,    NULL,            
  331.     ai_move,    0,    NULL,
  332.     ai_move,    0,    NULL,
  333.     ai_move,    0,    NULL,
  334.     ai_move,    0,    NULL,
  335.     ai_move,    -2,    NULL,
  336.     ai_move,    0,    NULL,
  337.     ai_move,    0,    NULL,
  338.     ai_move,    2,    NULL,
  339.     ai_move,    0,    NULL,            // 90
  340.     ai_move,    27,    makron_hit,            
  341.     ai_move,    26,    NULL,
  342.     ai_move,    0,    makron_brainsplorch,
  343.     ai_move,    0,    NULL,
  344.     ai_move,    0,    NULL            // 95
  345. };
  346. mmove_t makron_move_death2 = {FRAME_death201, FRAME_death295, makron_frames_death2, makron_dead};
  347.  
  348. mframe_t makron_frames_death3 [] =
  349. {
  350.     ai_move,    0,    NULL,
  351.     ai_move,    0,    NULL,
  352.     ai_move,    0,    NULL,
  353.     ai_move,    0,    NULL,
  354.     ai_move,    0,    NULL,
  355.     ai_move,    0,    NULL,
  356.     ai_move,    0,    NULL,
  357.     ai_move,    0,    NULL,
  358.     ai_move,    0,    NULL,
  359.     ai_move,    0,    NULL,
  360.     ai_move,    0,    NULL,
  361.     ai_move,    0,    NULL,
  362.     ai_move,    0,    NULL,
  363.     ai_move,    0,    NULL,
  364.     ai_move,    0,    NULL,
  365.     ai_move,    0,    NULL,
  366.     ai_move,    0,    NULL,
  367.     ai_move,    0,    NULL,
  368.     ai_move,    0,    NULL,
  369.     ai_move,    0,    NULL
  370. };
  371. mmove_t makron_move_death3 = {FRAME_death301, FRAME_death320, makron_frames_death3, NULL};
  372.  
  373. mframe_t makron_frames_sight [] =
  374. {
  375.     ai_move,    0,    NULL,
  376.     ai_move,    0,    NULL,
  377.     ai_move,    0,    NULL,
  378.     ai_move,    0,    NULL,
  379.     ai_move,    0,    NULL,
  380.     ai_move,    0,    NULL,
  381.     ai_move,    0,    NULL,
  382.     ai_move,    0,    NULL,
  383.     ai_move,    0,    NULL,
  384.     ai_move,    0,    NULL,
  385.     ai_move,    0,    NULL,
  386.     ai_move,    0,    NULL,
  387.     ai_move,    0,    NULL
  388. };
  389. mmove_t makron_move_sight= {FRAME_active01, FRAME_active13, makron_frames_sight, makron_run};
  390.  
  391. void makronBFG (edict_t *self)
  392. {
  393.     vec3_t    forward, right;
  394.     vec3_t    start;
  395.     vec3_t    dir;
  396.     vec3_t    vec;
  397.  
  398.     AngleVectors (self->s.angles, forward, right, NULL);
  399.     G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_BFG], forward, right, start);
  400.  
  401.     VectorCopy (self->enemy->s.origin, vec);
  402.     vec[2] += self->enemy->viewheight;
  403.     VectorSubtract (vec, start, dir);
  404.     VectorNormalize (dir);
  405.     gi.sound (self, CHAN_VOICE, sound_attack_bfg, 1, ATTN_NORM, 0);
  406.     monster_fire_bfg (self, start, dir, 50, 300, 100, 300, MZ2_MAKRON_BFG);
  407. }    
  408.  
  409.  
  410. mframe_t makron_frames_attack3 []=
  411. {
  412.     ai_charge,    0,    NULL,
  413.     ai_charge,    0,    NULL,
  414.     ai_charge,    0,    NULL,
  415.     ai_charge,    0,    makronBFG,        // FIXME: BFG Attack here
  416.     ai_move,    0,    NULL,
  417.     ai_move,    0,    NULL,
  418.     ai_move,    0,    NULL,
  419.     ai_move,    0,    NULL
  420. };
  421. mmove_t makron_move_attack3 = {FRAME_attak301, FRAME_attak308, makron_frames_attack3, makron_run};
  422.  
  423. mframe_t makron_frames_attack4[]=
  424. {
  425.     ai_charge,    0,    NULL,
  426.     ai_charge,    0,    NULL,
  427.     ai_charge,    0,    NULL,
  428.     ai_charge,    0,    NULL,
  429.     ai_move,    0,    MakronHyperblaster,        // fire
  430.     ai_move,    0,    MakronHyperblaster,        // fire
  431.     ai_move,    0,    MakronHyperblaster,        // fire
  432.     ai_move,    0,    MakronHyperblaster,        // fire
  433.     ai_move,    0,    MakronHyperblaster,        // fire
  434.     ai_move,    0,    MakronHyperblaster,        // fire
  435.     ai_move,    0,    MakronHyperblaster,        // fire
  436.     ai_move,    0,    MakronHyperblaster,        // fire
  437.     ai_move,    0,    MakronHyperblaster,        // fire
  438.     ai_move,    0,    MakronHyperblaster,        // fire
  439.     ai_move,    0,    MakronHyperblaster,        // fire
  440.     ai_move,    0,    MakronHyperblaster,        // fire
  441.     ai_move,    0,    MakronHyperblaster,        // fire
  442.     ai_move,    0,    MakronHyperblaster,        // fire
  443.     ai_move,    0,    MakronHyperblaster,        // fire
  444.     ai_move,    0,    MakronHyperblaster,        // fire
  445.     ai_move,    0,    MakronHyperblaster,        // fire
  446.     ai_move,    0,    NULL,
  447.     ai_move,    0,    NULL,
  448.     ai_move,    0,    NULL,
  449.     ai_move,    0,    NULL,
  450.     ai_move,    0,    NULL
  451. };
  452. mmove_t makron_move_attack4 = {FRAME_attak401, FRAME_attak426, makron_frames_attack4, makron_run};
  453.  
  454. mframe_t makron_frames_attack5[]=
  455. {
  456.     ai_charge,    0,    makron_prerailgun,
  457.     ai_charge,    0,    NULL,
  458.     ai_charge,    0,    NULL,
  459.     ai_charge,    0,    NULL,
  460.     ai_charge,    0,    NULL,
  461.     ai_charge,    0,    NULL,
  462.     ai_charge,    0,    NULL,
  463.     ai_charge,    0,    MakronSaveloc,
  464.     ai_move,    0,    MakronRailgun,        // Fire railgun
  465.     ai_move,    0,    NULL,
  466.     ai_move,    0,    NULL,
  467.     ai_move,    0,    NULL,
  468.     ai_move,    0,    NULL,
  469.     ai_move,    0,    NULL,
  470.     ai_move,    0,    NULL,
  471.     ai_move,    0,    NULL
  472. };
  473. mmove_t makron_move_attack5 = {FRAME_attak501, FRAME_attak516, makron_frames_attack5, makron_run};
  474.  
  475. void MakronSaveloc (edict_t *self)
  476. {
  477.     VectorCopy (self->enemy->s.origin, self->pos1);    //save for aiming the shot
  478.     self->pos1[2] += self->enemy->viewheight;
  479. }
  480.  
  481. // FIXME: He's not firing from the proper Z
  482. void MakronRailgun (edict_t *self)
  483. {
  484.     vec3_t    start;
  485.     vec3_t    dir;
  486.     vec3_t    forward, right;
  487.  
  488.     AngleVectors (self->s.angles, forward, right, NULL);
  489.     G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_RAILGUN_1], forward, right, start);
  490.     
  491.     // calc direction to where we targted
  492.     VectorSubtract (self->pos1, start, dir);
  493.     VectorNormalize (dir);
  494.  
  495.     monster_fire_railgun (self, start, dir, 50, 100, MZ2_MAKRON_RAILGUN_1);
  496. }
  497.  
  498. // FIXME: This is all wrong. He's not firing at the proper angles.
  499. void MakronHyperblaster (edict_t *self)
  500. {
  501.     vec3_t    dir;
  502.     vec3_t    vec;
  503.     vec3_t    start;
  504.     vec3_t    forward, right;
  505.     int        flash_number;
  506.  
  507.     flash_number = MZ2_MAKRON_BLASTER_1 + (self->s.frame - FRAME_attak405);
  508.  
  509.     AngleVectors (self->s.angles, forward, right, NULL);
  510.     G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  511.  
  512.     if (self->enemy)
  513.     {
  514.         VectorCopy (self->enemy->s.origin, vec);
  515.         vec[2] += self->enemy->viewheight;
  516.         VectorSubtract (vec, start, vec);
  517.         vectoangles (vec, vec);
  518.         dir[0] = vec[0];
  519.     }
  520.     else
  521.     {
  522.         dir[0] = 0;
  523.     }
  524.     if (self->s.frame <= FRAME_attak413)
  525.         dir[1] = self->s.angles[1] - 10 * (self->s.frame - FRAME_attak413);
  526.     else
  527.         dir[1] = self->s.angles[1] + 10 * (self->s.frame - FRAME_attak421);
  528.     dir[2] = 0;
  529.  
  530.     AngleVectors (dir, forward, NULL, NULL);
  531.  
  532.     monster_fire_blaster (self, start, forward, 15, 1000, MZ2_MAKRON_BLASTER_1, EF_BLASTER);
  533. }    
  534.  
  535.  
  536. void makron_pain (edict_t *self, edict_t *other, float kick, int damage)
  537. {
  538.  
  539.     if (self->health < (self->max_health / 2))
  540.             self->s.skinnum = 1;
  541.  
  542.     if (level.time < self->pain_debounce_time)
  543.             return;
  544.  
  545.     // Lessen the chance of him going into his pain frames
  546.     if (damage <=25)
  547.         if (random()<0.2)
  548.             return;
  549.  
  550.     self->pain_debounce_time = level.time + 3;
  551.  
  552.     if (damage <= 40)
  553.     {
  554.         gi.sound (self, CHAN_VOICE, sound_pain4, 1, ATTN_NONE,0);
  555.         self->monsterinfo.currentmove = &makron_move_pain4;
  556.     }
  557.     else if (damage <= 110)
  558.     {
  559.         gi.sound (self, CHAN_VOICE, sound_pain5, 1, ATTN_NONE,0);
  560.         self->monsterinfo.currentmove = &makron_move_pain5;
  561.     }
  562.     else
  563.     {
  564.         if (damage <= 150)
  565.             if (random() <= 0.45)
  566.             {
  567.                 gi.sound (self, CHAN_VOICE, sound_pain6, 1, ATTN_NONE,0);
  568.                 self->monsterinfo.currentmove = &makron_move_pain6;
  569.             }
  570.         else
  571.             if (random() <= 0.35)
  572.             {
  573.                 gi.sound (self, CHAN_VOICE, sound_pain6, 1, ATTN_NONE,0);
  574.                 self->monsterinfo.currentmove = &makron_move_pain6;
  575.             }
  576.     }
  577. }
  578.  
  579. void makron_sight(edict_t *self, edict_t *other)
  580. {
  581.     self->monsterinfo.currentmove = &makron_move_sight;
  582. }
  583.  
  584. void makron_attack(edict_t *self)
  585. {
  586.     vec3_t    vec;
  587.     float    range;
  588.     float    r;
  589.  
  590.     r = random();
  591.  
  592.     VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
  593.     range = VectorLength (vec);
  594.  
  595.  
  596.     if (r <= 0.3)
  597.         self->monsterinfo.currentmove = &makron_move_attack3;
  598.     else if (r <= 0.6)
  599.         self->monsterinfo.currentmove = &makron_move_attack4;
  600.     else
  601.         self->monsterinfo.currentmove = &makron_move_attack5;
  602. }
  603.  
  604. /*
  605. ---
  606. Makron Torso. This needs to be spawned in
  607. ---
  608. */
  609.  
  610. void makron_torso_think (edict_t *self)
  611. {
  612.     if (++self->s.frame < 365)
  613.         self->nextthink = level.time + FRAMETIME;
  614.     else
  615.     {        
  616.         self->s.frame = 346;
  617.         self->nextthink = level.time + FRAMETIME;
  618.     }
  619. }
  620.  
  621. void makron_torso (edict_t *ent)
  622. {
  623.     ent->movetype = MOVETYPE_NONE;
  624.     ent->solid = SOLID_NOT;
  625.     VectorSet (ent->mins, -8, -8, 0);
  626.     VectorSet (ent->maxs, 8, 8, 8);
  627.     ent->s.frame = 346;
  628.     ent->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  629.     ent->think = makron_torso_think;
  630.     ent->nextthink = level.time + 2 * FRAMETIME;
  631.     ent->s.sound = gi.soundindex ("makron/spine.wav");
  632.     gi.linkentity (ent);
  633. }
  634.  
  635.  
  636. //
  637. // death
  638. //
  639.  
  640. void makron_dead (edict_t *self)
  641. {
  642.     /*
  643.     VectorSet (self->mins, -16, -16, -24);
  644.     VectorSet (self->maxs, 16, 16, -8);
  645.     */
  646.     VectorSet (self->mins, -60, -60, 0);
  647.     VectorSet (self->maxs, 60, 60, 72);
  648.     self->movetype = MOVETYPE_TOSS;
  649.     self->nextthink = 0;
  650.     gi.linkentity (self);
  651. }
  652.  
  653.  
  654. void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  655. {
  656.     edict_t *tempent;
  657.  
  658.     int        n;
  659.  
  660.     self->s.sound = 0;
  661.     // check for gib
  662.     if (self->health <= self->gib_health)
  663.     {
  664.         gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  665.         for (n= 0; n < 1 /*4*/; n++)
  666.             ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  667.         for (n= 0; n < 4; n++)
  668.             ThrowGib (self, "models/objects/gibs/sm_metal/tris.md2", damage, GIB_METALLIC);
  669.         ThrowHead (self, "models/objects/gibs/gear/tris.md2", damage, GIB_METALLIC);
  670.         self->deadflag = DEAD_DEAD;
  671.         return;
  672.     }
  673.  
  674.     if (self->deadflag == DEAD_DEAD)
  675.         return;
  676.  
  677. // regular death
  678.     gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
  679.     self->deadflag = DEAD_DEAD;
  680.     self->takedamage = DAMAGE_YES;
  681.  
  682.     tempent = G_Spawn();
  683.     VectorCopy (self->s.origin, tempent->s.origin);
  684.     VectorCopy (self->s.angles, tempent->s.angles);
  685.     tempent->s.origin[1] -= 84;
  686.     makron_torso (tempent);
  687.  
  688.     self->monsterinfo.currentmove = &makron_move_death2;
  689.     
  690. }
  691.  
  692. qboolean Makron_CheckAttack (edict_t *self)
  693. {
  694.     vec3_t    spot1, spot2;
  695.     vec3_t    temp;
  696.     float    chance;
  697.     trace_t    tr;
  698.     qboolean    enemy_infront;
  699.     int            enemy_range;
  700.     float        enemy_yaw;
  701.  
  702.     if (self->enemy->health > 0)
  703.     {
  704.     // see if any entities are in the way of the shot
  705.         VectorCopy (self->s.origin, spot1);
  706.         spot1[2] += self->viewheight;
  707.         VectorCopy (self->enemy->s.origin, spot2);
  708.         spot2[2] += self->enemy->viewheight;
  709.  
  710.         tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA);
  711.  
  712.         // do we have a clear shot?
  713.         if (tr.ent != self->enemy)
  714.             return false;
  715.     }
  716.     
  717.     enemy_infront = infront(self, self->enemy);
  718.     enemy_range = range(self, self->enemy);
  719.     VectorSubtract (self->enemy->s.origin, self->s.origin, temp);
  720.     enemy_yaw = vectoyaw(temp);
  721.  
  722.     self->ideal_yaw = enemy_yaw;
  723.  
  724.  
  725.     // melee attack
  726.     if (enemy_range == RANGE_MELEE)
  727.     {
  728.         if (self->monsterinfo.melee)
  729.             self->monsterinfo.attack_state = AS_MELEE;
  730.         else
  731.             self->monsterinfo.attack_state = AS_MISSILE;
  732.         return true;
  733.     }
  734.     
  735. // missile attack
  736.     if (!self->monsterinfo.attack)
  737.         return false;
  738.         
  739.     if (level.time < self->monsterinfo.attack_finished)
  740.         return false;
  741.         
  742.     if (enemy_range == RANGE_FAR)
  743.         return false;
  744.  
  745.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  746.     {
  747.         chance = 0.4;
  748.     }
  749.     else if (enemy_range == RANGE_MELEE)
  750.     {
  751.         chance = 0.8;
  752.     }
  753.     else if (enemy_range == RANGE_NEAR)
  754.     {
  755.         chance = 0.4;
  756.     }
  757.     else if (enemy_range == RANGE_MID)
  758.     {
  759.         chance = 0.2;
  760.     }
  761.     else
  762.     {
  763.         return false;
  764.     }
  765.  
  766.     if (random () < chance)
  767.     {
  768.         self->monsterinfo.attack_state = AS_MISSILE;
  769.         self->monsterinfo.attack_finished = level.time + 2*random();
  770.         return true;
  771.     }
  772.  
  773.     if (self->flags & FL_FLY)
  774.     {
  775.         if (random() < 0.3)
  776.             self->monsterinfo.attack_state = AS_SLIDING;
  777.         else
  778.             self->monsterinfo.attack_state = AS_STRAIGHT;
  779.     }
  780.  
  781.     return false;
  782. }
  783.  
  784.  
  785. //
  786. // monster_makron
  787. //
  788.  
  789. void MakronPrecache (void)
  790. {
  791.     sound_pain4 = gi.soundindex ("makron/pain3.wav");
  792.     sound_pain5 = gi.soundindex ("makron/pain2.wav");
  793.     sound_pain6 = gi.soundindex ("makron/pain1.wav");
  794.     sound_death = gi.soundindex ("makron/death.wav");
  795.     sound_step_left = gi.soundindex ("makron/step1.wav");
  796.     sound_step_right = gi.soundindex ("makron/step2.wav");
  797.     sound_attack_bfg = gi.soundindex ("makron/bfg_fire.wav");
  798.     sound_brainsplorch = gi.soundindex ("makron/brain1.wav");
  799.     sound_prerailgun = gi.soundindex ("makron/rail_up.wav");
  800.     sound_popup = gi.soundindex ("makron/popup.wav");
  801.     sound_taunt1 = gi.soundindex ("makron/voice4.wav");
  802.     sound_taunt2 = gi.soundindex ("makron/voice3.wav");
  803.     sound_taunt3 = gi.soundindex ("makron/voice.wav");
  804.     sound_hit = gi.soundindex ("makron/bhit.wav");
  805.  
  806.     gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  807. }
  808.  
  809. /*QUAKED monster_makron (1 .5 0) (-30 -30 0) (30 30 90) Ambush Trigger_Spawn Sight
  810. */
  811. void SP_monster_makron (edict_t *self)
  812. {
  813.     if (deathmatch->value)
  814.     {
  815.         G_FreeEdict (self);
  816.         return;
  817.     }
  818.  
  819.     MakronPrecache ();
  820.  
  821.     self->movetype = MOVETYPE_STEP;
  822.     self->solid = SOLID_BBOX;
  823.     self->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  824.     VectorSet (self->mins, -30, -30, 0);
  825.     VectorSet (self->maxs, 30, 30, 90);
  826.  
  827.     self->health = 3000;
  828.     self->gib_health = -2000;
  829.     self->mass = 500;
  830.  
  831.     self->pain = makron_pain;
  832.     self->die = makron_die;
  833.     self->monsterinfo.stand = makron_stand;
  834.     self->monsterinfo.walk = makron_walk;
  835.     self->monsterinfo.run = makron_run;
  836.     self->monsterinfo.dodge = NULL;
  837.     self->monsterinfo.attack = makron_attack;
  838.     self->monsterinfo.melee = NULL;
  839.     self->monsterinfo.sight = makron_sight;
  840.     self->monsterinfo.checkattack = Makron_CheckAttack;
  841.  
  842.     gi.linkentity (self);
  843.     
  844. //    self->monsterinfo.currentmove = &makron_move_stand;
  845.     self->monsterinfo.currentmove = &makron_move_sight;
  846.     self->monsterinfo.scale = MODEL_SCALE;
  847.  
  848.     walkmonster_start(self);
  849. }
  850.  
  851.  
  852. /*
  853. =================
  854. MakronSpawn
  855.  
  856. =================
  857. */
  858. void MakronSpawn (edict_t *self)
  859. {
  860.     vec3_t        vec;
  861.     edict_t        *player;
  862.  
  863.     SP_monster_makron (self);
  864.  
  865.     // jump at player
  866.     player = level.sight_client;
  867.     if (!player)
  868.         return;
  869.  
  870.     VectorSubtract (player->s.origin, self->s.origin, vec);
  871.     self->s.angles[YAW] = vectoyaw(vec);
  872.     VectorNormalize (vec);
  873.     VectorMA (vec3_origin, 400, vec, self->velocity);
  874.     self->velocity[2] = 200;
  875.     self->groundentity = NULL;
  876. }
  877.  
  878. /*
  879. =================
  880. MakronToss
  881.  
  882. Jorg is just about dead, so set up to launch Makron out
  883. =================
  884. */
  885. void MakronToss (edict_t *self)
  886. {
  887.     edict_t    *ent;
  888.  
  889.     ent = G_Spawn ();
  890.     ent->nextthink = level.time + 0.8;
  891.     ent->think = MakronSpawn;
  892.     ent->target = self->target;
  893.     VectorCopy (self->s.origin, ent->s.origin);
  894. }
  895.