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