icculus quake2 doxygen  1.0 dev
m_medic.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 MEDIC
24 
25 ==============================================================================
26 */
27 
28 #include "g_local.h"
29 #include "m_medic.h"
30 
31 qboolean visible (edict_t *self, edict_t *other);
32 
33 
34 static int sound_idle1;
35 static int sound_pain1;
36 static int sound_pain2;
37 static int sound_die;
38 static int sound_sight;
39 static int sound_search;
40 static int sound_hook_launch;
41 static int sound_hook_hit;
42 static int sound_hook_heal;
43 static int sound_hook_retract;
44 
45 
47 {
48  edict_t *ent = NULL;
49  edict_t *best = NULL;
50 
51  while ((ent = findradius(ent, self->s.origin, 1024)) != NULL)
52  {
53  if (ent == self)
54  continue;
55  if (!(ent->svflags & SVF_MONSTER))
56  continue;
57  if (ent->monsterinfo.aiflags & AI_GOOD_GUY)
58  continue;
59  if (ent->owner)
60  continue;
61  if (ent->health > 0)
62  continue;
63  if (ent->nextthink)
64  continue;
65  if (!visible(self, ent))
66  continue;
67  if (!best)
68  {
69  best = ent;
70  continue;
71  }
72  if (ent->max_health <= best->max_health)
73  continue;
74  best = ent;
75  }
76 
77  return best;
78 }
79 
80 void medic_idle (edict_t *self)
81 {
82  edict_t *ent;
83 
84  gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
85 
86  ent = medic_FindDeadMonster(self);
87  if (ent)
88  {
89  self->enemy = ent;
90  self->enemy->owner = self;
91  self->monsterinfo.aiflags |= AI_MEDIC;
92  FoundTarget (self);
93  }
94 }
95 
96 void medic_search (edict_t *self)
97 {
98  edict_t *ent;
99 
100  gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_IDLE, 0);
101 
102  if (!self->oldenemy)
103  {
104  ent = medic_FindDeadMonster(self);
105  if (ent)
106  {
107  self->oldenemy = self->enemy;
108  self->enemy = ent;
109  self->enemy->owner = self;
110  self->monsterinfo.aiflags |= AI_MEDIC;
111  FoundTarget (self);
112  }
113  }
114 }
115 
116 void medic_sight (edict_t *self, edict_t *other)
117 {
118  gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
119 }
120 
121 
123 {
124  {ai_stand, 0, medic_idle},
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},
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  {ai_stand, 0, NULL},
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  {ai_stand, 0, NULL},
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  {ai_stand, 0, NULL},
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  {ai_stand, 0, NULL},
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, 0, NULL},
182  {ai_stand, 0, NULL},
183  {ai_stand, 0, NULL},
184  {ai_stand, 0, NULL},
185  {ai_stand, 0, NULL},
186  {ai_stand, 0, NULL},
187  {ai_stand, 0, NULL},
188  {ai_stand, 0, NULL},
189  {ai_stand, 0, NULL},
190  {ai_stand, 0, NULL},
191  {ai_stand, 0, NULL},
192  {ai_stand, 0, NULL},
193  {ai_stand, 0, NULL},
194  {ai_stand, 0, NULL},
195  {ai_stand, 0, NULL},
196  {ai_stand, 0, NULL},
197  {ai_stand, 0, NULL},
198  {ai_stand, 0, NULL},
199  {ai_stand, 0, NULL},
200  {ai_stand, 0, NULL},
201  {ai_stand, 0, NULL},
202  {ai_stand, 0, NULL},
203  {ai_stand, 0, NULL},
204  {ai_stand, 0, NULL},
205  {ai_stand, 0, NULL},
206  {ai_stand, 0, NULL},
207  {ai_stand, 0, NULL},
208  {ai_stand, 0, NULL},
209  {ai_stand, 0, NULL},
210  {ai_stand, 0, NULL},
211  {ai_stand, 0, NULL},
212  {ai_stand, 0, NULL},
213  {ai_stand, 0, NULL},
214 
215 };
217 
218 void medic_stand (edict_t *self)
219 {
220  self->monsterinfo.currentmove = &medic_move_stand;
221 }
222 
223 
225 {
226  {ai_walk, 6.2, NULL},
227  {ai_walk, 18.1, NULL},
228  {ai_walk, 1, NULL},
229  {ai_walk, 9, NULL},
230  {ai_walk, 10, NULL},
231  {ai_walk, 9, NULL},
232  {ai_walk, 11, NULL},
233  {ai_walk, 11.6, NULL},
234  {ai_walk, 2, NULL},
235  {ai_walk, 9.9, NULL},
236  {ai_walk, 14, NULL},
237  {ai_walk, 9.3, NULL}
238 };
240 
241 void medic_walk (edict_t *self)
242 {
243  self->monsterinfo.currentmove = &medic_move_walk;
244 }
245 
246 
248 {
249  {ai_run, 18, NULL},
250  {ai_run, 22.5, NULL},
251  {ai_run, 25.4, NULL},
252  {ai_run, 23.4, NULL},
253  {ai_run, 24, NULL},
254  {ai_run, 35.6, NULL}
255 
256 };
258 
259 void medic_run (edict_t *self)
260 {
261  if (!(self->monsterinfo.aiflags & AI_MEDIC))
262  {
263  edict_t *ent;
264 
265  ent = medic_FindDeadMonster(self);
266  if (ent)
267  {
268  self->oldenemy = self->enemy;
269  self->enemy = ent;
270  self->enemy->owner = self;
271  self->monsterinfo.aiflags |= AI_MEDIC;
272  FoundTarget (self);
273  return;
274  }
275  }
276 
277  if (self->monsterinfo.aiflags & AI_STAND_GROUND)
278  self->monsterinfo.currentmove = &medic_move_stand;
279  else
280  self->monsterinfo.currentmove = &medic_move_run;
281 }
282 
283 
285 {
286  {ai_move, 0, NULL},
287  {ai_move, 0, NULL},
288  {ai_move, 0, NULL},
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 };
296 
298 {
299  {ai_move, 0, NULL},
300  {ai_move, 0, NULL},
301  {ai_move, 0, NULL},
302  {ai_move, 0, NULL},
303  {ai_move, 0, NULL},
304  {ai_move, 0, NULL},
305  {ai_move, 0, NULL},
306  {ai_move, 0, NULL},
307  {ai_move, 0, NULL},
308  {ai_move, 0, NULL},
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 };
316 
317 void medic_pain (edict_t *self, edict_t *other, float kick, int damage)
318 {
319  if (self->health < (self->max_health / 2))
320  self->s.skinnum = 1;
321 
322  if (level.time < self->pain_debounce_time)
323  return;
324 
325  self->pain_debounce_time = level.time + 3;
326 
327  if (skill->value == 3)
328  return; // no pain anims in nightmare
329 
330  if (random() < 0.5)
331  {
332  self->monsterinfo.currentmove = &medic_move_pain1;
333  gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
334  }
335  else
336  {
337  self->monsterinfo.currentmove = &medic_move_pain2;
338  gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
339  }
340 }
341 
343 {
344  vec3_t start;
346  vec3_t end;
347  vec3_t dir;
348  int effect;
349 
350  if ((self->s.frame == FRAME_attack9) || (self->s.frame == FRAME_attack12))
351  effect = EF_BLASTER;
352  else if ((self->s.frame == FRAME_attack19) || (self->s.frame == FRAME_attack22) || (self->s.frame == FRAME_attack25) || (self->s.frame == FRAME_attack28))
353  effect = EF_HYPERBLASTER;
354  else
355  effect = 0;
356 
357  AngleVectors (self->s.angles, forward, right, NULL);
359 
360  VectorCopy (self->enemy->s.origin, end);
361  end[2] += self->enemy->viewheight;
362  VectorSubtract (end, start, dir);
363 
364  monster_fire_blaster (self, start, dir, 2, 1000, MZ2_MEDIC_BLASTER_1, effect);
365 }
366 
367 
368 void medic_dead (edict_t *self)
369 {
370  VectorSet (self->mins, -16, -16, -24);
371  VectorSet (self->maxs, 16, 16, -8);
372  self->movetype = MOVETYPE_TOSS;
373  self->svflags |= SVF_DEADMONSTER;
374  self->nextthink = 0;
375  gi.linkentity (self);
376 }
377 
379 {
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  {ai_move, 0, NULL},
390  {ai_move, 0, NULL},
391  {ai_move, 0, NULL},
392  {ai_move, 0, NULL},
393  {ai_move, 0, NULL},
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  {ai_move, 0, NULL},
408  {ai_move, 0, NULL},
409  {ai_move, 0, NULL}
410 };
412 
413 void medic_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
414 {
415  int n;
416 
417  // if we had a pending patient, free him up for another medic
418  if ((self->enemy) && (self->enemy->owner == self))
419  self->enemy->owner = NULL;
420 
421 // check for gib
422  if (self->health <= self->gib_health)
423  {
424  gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
425  for (n= 0; n < 2; n++)
426  ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
427  for (n= 0; n < 4; n++)
428  ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
429  ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
430  self->deadflag = DEAD_DEAD;
431  return;
432  }
433 
434  if (self->deadflag == DEAD_DEAD)
435  return;
436 
437 // regular death
438  gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
439  self->deadflag = DEAD_DEAD;
440  self->takedamage = DAMAGE_YES;
441 
442  self->monsterinfo.currentmove = &medic_move_death;
443 }
444 
445 
447 {
448  if (self->monsterinfo.aiflags & AI_DUCKED)
449  return;
450  self->monsterinfo.aiflags |= AI_DUCKED;
451  self->maxs[2] -= 32;
452  self->takedamage = DAMAGE_YES;
453  self->monsterinfo.pausetime = level.time + 1;
454  gi.linkentity (self);
455 }
456 
458 {
459  if (level.time >= self->monsterinfo.pausetime)
460  self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
461  else
462  self->monsterinfo.aiflags |= AI_HOLD_FRAME;
463 }
464 
465 void medic_duck_up (edict_t *self)
466 {
467  self->monsterinfo.aiflags &= ~AI_DUCKED;
468  self->maxs[2] += 32;
469  self->takedamage = DAMAGE_AIM;
470  gi.linkentity (self);
471 }
472 
474 {
475  {ai_move, -1, NULL},
476  {ai_move, -1, NULL},
477  {ai_move, -1, medic_duck_down},
478  {ai_move, -1, medic_duck_hold},
479  {ai_move, -1, NULL},
480  {ai_move, -1, NULL},
481  {ai_move, -1, medic_duck_up},
482  {ai_move, -1, NULL},
483  {ai_move, -1, NULL},
484  {ai_move, -1, NULL},
485  {ai_move, -1, NULL},
486  {ai_move, -1, NULL},
487  {ai_move, -1, NULL},
488  {ai_move, -1, NULL},
489  {ai_move, -1, NULL},
490  {ai_move, -1, NULL}
491 };
493 
494 void medic_dodge (edict_t *self, edict_t *attacker, float eta)
495 {
496  if (random() > 0.25)
497  return;
498 
499  if (!self->enemy)
500  self->enemy = attacker;
501 
503 }
504 
506 {
507  {ai_charge, 0, NULL},
508  {ai_charge, 0, NULL},
509  {ai_charge, 0, NULL},
510  {ai_charge, 0, NULL},
523 };
525 
526 
528 {
529  if (visible (self, self->enemy) )
530  if (random() <= 0.95)
531  self->monsterinfo.currentmove = &medic_move_attackHyperBlaster;
532 }
533 
534 
536 {
537  {ai_charge, 0, NULL},
538  {ai_charge, 5, NULL},
539  {ai_charge, 5, NULL},
540  {ai_charge, 3, NULL},
541  {ai_charge, 2, NULL},
542  {ai_charge, 0, NULL},
543  {ai_charge, 0, NULL},
544  {ai_charge, 0, NULL},
546  {ai_charge, 0, NULL},
547  {ai_charge, 0, NULL},
549  {ai_charge, 0, NULL},
550  {ai_charge, 0, medic_continue} // Change to medic_continue... Else, go to frame 32
551 };
553 
554 
556 {
558 }
559 
560 void ED_CallSpawn (edict_t *ent);
561 
563 {
564  {45.0, -9.2, 15.5},
565  {48.4, -9.7, 15.2},
566  {47.8, -9.8, 15.8},
567  {47.3, -9.3, 14.3},
568  {45.4, -10.1, 13.1},
569  {41.9, -12.7, 12.0},
570  {37.8, -15.8, 11.2},
571  {34.3, -18.4, 10.7},
572  {32.7, -19.7, 10.4},
573  {32.7, -19.7, 10.4}
574 };
575 
577 {
578  vec3_t offset, start, end, f, r;
579  trace_t tr;
580  vec3_t dir, angles;
581  float distance;
582 
583  if (!self->enemy->inuse)
584  return;
585 
586  AngleVectors (self->s.angles, f, r, NULL);
587  VectorCopy (medic_cable_offsets[self->s.frame - FRAME_attack42], offset);
588  G_ProjectSource (self->s.origin, offset, f, r, start);
589 
590  // check for max distance
591  VectorSubtract (start, self->enemy->s.origin, dir);
592  distance = VectorLength(dir);
593  if (distance > 256)
594  return;
595 
596  // check for min/max pitch
597  vectoangles (dir, angles);
598  if (angles[0] < -180)
599  angles[0] += 360;
600  if (fabs(angles[0]) > 45)
601  return;
602 
603  tr = gi.trace (start, NULL, NULL, self->enemy->s.origin, self, MASK_SHOT);
604  if (tr.fraction != 1.0 && tr.ent != self->enemy)
605  return;
606 
607  if (self->s.frame == FRAME_attack43)
608  {
609  gi.sound (self->enemy, CHAN_AUTO, sound_hook_hit, 1, ATTN_NORM, 0);
610  self->enemy->monsterinfo.aiflags |= AI_RESURRECTING;
611  }
612  else if (self->s.frame == FRAME_attack50)
613  {
614  self->enemy->spawnflags = 0;
615  self->enemy->monsterinfo.aiflags = 0;
616  self->enemy->target = NULL;
617  self->enemy->targetname = NULL;
618  self->enemy->combattarget = NULL;
619  self->enemy->deathtarget = NULL;
620  self->enemy->owner = self;
621  ED_CallSpawn (self->enemy);
622  self->enemy->owner = NULL;
623  if (self->enemy->think)
624  {
625  self->enemy->nextthink = level.time;
626  self->enemy->think (self->enemy);
627  }
628  self->enemy->monsterinfo.aiflags |= AI_RESURRECTING;
629  if (self->oldenemy && self->oldenemy->client)
630  {
631  self->enemy->enemy = self->oldenemy;
632  FoundTarget (self->enemy);
633  }
634  }
635  else
636  {
637  if (self->s.frame == FRAME_attack44)
638  gi.sound (self, CHAN_WEAPON, sound_hook_heal, 1, ATTN_NORM, 0);
639  }
640 
641  // adjust start for beam origin being in middle of a segment
642  VectorMA (start, 8, f, start);
643 
644  // adjust end z for end spot since the monster is currently dead
645  VectorCopy (self->enemy->s.origin, end);
646  end[2] = self->enemy->absmin[2] + self->enemy->size[2] / 2;
647 
650  gi.WriteShort (self - g_edicts);
651  gi.WritePosition (start);
652  gi.WritePosition (end);
653  gi.multicast (self->s.origin, MULTICAST_PVS);
654 }
655 
657 {
659  self->enemy->monsterinfo.aiflags &= ~AI_RESURRECTING;
660 }
661 
663 {
664  {ai_move, 2, NULL},
665  {ai_move, 3, NULL},
666  {ai_move, 5, NULL},
667  {ai_move, 4.4, NULL},
668  {ai_charge, 4.7, NULL},
669  {ai_charge, 5, NULL},
670  {ai_charge, 6, NULL},
671  {ai_charge, 4, NULL},
672  {ai_charge, 0, NULL},
683  {ai_move, -15, medic_hook_retract},
684  {ai_move, -1.5, NULL},
685  {ai_move, -1.2, NULL},
686  {ai_move, -3, NULL},
687  {ai_move, -2, NULL},
688  {ai_move, 0.3, NULL},
689  {ai_move, 0.7, NULL},
690  {ai_move, 1.2, NULL},
691  {ai_move, 1.3, NULL}
692 };
694 
695 
697 {
698  if (self->monsterinfo.aiflags & AI_MEDIC)
699  self->monsterinfo.currentmove = &medic_move_attackCable;
700  else
701  self->monsterinfo.currentmove = &medic_move_attackBlaster;
702 }
703 
705 {
706  if (self->monsterinfo.aiflags & AI_MEDIC)
707  {
708  medic_attack(self);
709  return true;
710  }
711 
712  return M_CheckAttack (self);
713 }
714 
715 
716 /*QUAKED monster_medic (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
717 */
719 {
720  if (deathmatch->value)
721  {
722  G_FreeEdict (self);
723  return;
724  }
725 
726  sound_idle1 = gi.soundindex ("medic/idle.wav");
727  sound_pain1 = gi.soundindex ("medic/medpain1.wav");
728  sound_pain2 = gi.soundindex ("medic/medpain2.wav");
729  sound_die = gi.soundindex ("medic/meddeth1.wav");
730  sound_sight = gi.soundindex ("medic/medsght1.wav");
731  sound_search = gi.soundindex ("medic/medsrch1.wav");
732  sound_hook_launch = gi.soundindex ("medic/medatck2.wav");
733  sound_hook_hit = gi.soundindex ("medic/medatck3.wav");
734  sound_hook_heal = gi.soundindex ("medic/medatck4.wav");
735  sound_hook_retract = gi.soundindex ("medic/medatck5.wav");
736 
737  gi.soundindex ("medic/medatck1.wav");
738 
739  self->movetype = MOVETYPE_STEP;
740  self->solid = SOLID_BBOX;
741  self->s.modelindex = gi.modelindex ("models/monsters/medic/tris.md2");
742  VectorSet (self->mins, -24, -24, -24);
743  VectorSet (self->maxs, 24, 24, 32);
744 
745  self->health = 300;
746  self->gib_health = -130;
747  self->mass = 400;
748 
749  self->pain = medic_pain;
750  self->die = medic_die;
751 
752  self->monsterinfo.stand = medic_stand;
753  self->monsterinfo.walk = medic_walk;
754  self->monsterinfo.run = medic_run;
755  self->monsterinfo.dodge = medic_dodge;
756  self->monsterinfo.attack = medic_attack;
757  self->monsterinfo.melee = NULL;
758  self->monsterinfo.sight = medic_sight;
759  self->monsterinfo.idle = medic_idle;
760  self->monsterinfo.search = medic_search;
761  self->monsterinfo.checkattack = medic_checkattack;
762 
763  gi.linkentity (self);
764 
765  self->monsterinfo.currentmove = &medic_move_stand;
766  self->monsterinfo.scale = MODEL_SCALE;
767 
768  walkmonster_start (self);
769 }
gi
game_import_t gi
Definition: g_main.c:25
AI_RESURRECTING
#define AI_RESURRECTING
Definition: g_local.h:141
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
deathmatch
cvar_t * deathmatch
Definition: g_main.c:35
medic_attack
void medic_attack(edict_t *self)
Definition: m_medic.c:696
AI_MEDIC
#define AI_MEDIC
Definition: g_local.h:140
DEAD_DEAD
#define DEAD_DEAD
Definition: g_local.h:113
sound_die
static int sound_die
Definition: m_medic.c:37
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
trace_t::fraction
float fraction
Definition: q_shared.h:453
ThrowGib
void ThrowGib(edict_t *self, char *gibname, int damage, int type)
Definition: g_misc.c:135
medic_checkattack
qboolean medic_checkattack(edict_t *self)
Definition: m_medic.c:704
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:156
FRAME_paina1
#define FRAME_paina1
Definition: m_medic.h:132
ED_CallSpawn
void ED_CallSpawn(edict_t *ent)
Definition: g_spawn.c:278
FRAME_attack1
#define FRAME_attack1
Definition: m_boss2.h:94
ai_charge
void ai_charge(edict_t *self, float dist)
Definition: g_ai.c:194
AI_GOOD_GUY
#define AI_GOOD_GUY
Definition: g_local.h:135
game_import_t::WritePosition
void(* WritePosition)(vec3_t pos)
Definition: game.h:152
game_import_t::multicast
void(* multicast)(vec3_t origin, multicast_t to)
Definition: game.h:144
SOLID_BBOX
@ SOLID_BBOX
Definition: game.h:37
FRAME_attack15
#define FRAME_attack15
Definition: m_boss2.h:108
sound_hook_heal
static int sound_hook_heal
Definition: m_medic.c:42
m_medic.h
FRAME_run6
#define FRAME_run6
Definition: m_berserk.h:65
sound_search
static int sound_search
Definition: m_medic.c:39
medic_sight
void medic_sight(edict_t *self, edict_t *other)
Definition: m_medic.c:116
FRAME_attack28
#define FRAME_attack28
Definition: m_boss2.h:121
entity_state_s::origin
vec3_t origin
Definition: q_shared.h:1173
medic_frames_duck
mframe_t medic_frames_duck[]
Definition: m_medic.c:473
FRAME_attack43
#define FRAME_attack43
Definition: m_medic.h:243
TE_MEDIC_CABLE_ATTACK
@ TE_MEDIC_CABLE_ATTACK
Definition: q_shared.h:954
sound_hook_hit
static int sound_hook_hit
Definition: m_medic.c:41
AI_STAND_GROUND
#define AI_STAND_GROUND
Definition: g_local.h:127
qboolean
qboolean
Definition: q_shared.h:56
trace_t
Definition: q_shared.h:449
MODEL_SCALE
#define MODEL_SCALE
Definition: m_actor.h:506
edict_s::max_health
int max_health
Definition: g_local.h:1052
medic_frames_attackBlaster
mframe_t medic_frames_attackBlaster[]
Definition: m_medic.c:535
medic_hook_retract
void medic_hook_retract(edict_t *self)
Definition: m_medic.c:656
medic_run
void medic_run(edict_t *self)
Definition: m_medic.c:259
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
FRAME_attack14
#define FRAME_attack14
Definition: m_boss2.h:107
ATTN_IDLE
#define ATTN_IDLE
Definition: q_shared.h:1020
MASK_SHOT
#define MASK_SHOT
Definition: q_shared.h:397
monsterinfo_t::currentmove
mmove_t * currentmove
Definition: g_local.h:418
medic_duck_hold
void medic_duck_hold(edict_t *self)
Definition: m_medic.c:457
M_CheckAttack
qboolean M_CheckAttack(edict_t *self)
Definition: g_ai.c:607
FRAME_attack30
#define FRAME_attack30
Definition: m_boss2.h:123
g_edicts
edict_t * g_edicts
Definition: g_main.c:33
ATTN_NORM
#define ATTN_NORM
Definition: q_shared.h:1019
medic_frames_attackCable
mframe_t medic_frames_attackCable[]
Definition: m_medic.c:662
walkmonster_start
void walkmonster_start(edict_t *self)
Definition: g_monster.c:692
MOVETYPE_STEP
@ MOVETYPE_STEP
Definition: g_local.h:194
FRAME_walk12
#define FRAME_walk12
Definition: m_boss2.h:85
medic_move_pain2
mmove_t medic_move_pain2
Definition: m_medic.c:315
visible
qboolean visible(edict_t *self, edict_t *other)
Definition: g_ai.c:287
MZ2_MEDIC_BLASTER_1
#define MZ2_MEDIC_BLASTER_1
Definition: q_shared.h:759
medic_cable_offsets
static vec3_t medic_cable_offsets[]
Definition: m_medic.c:562
sound_pain2
static int sound_pain2
Definition: m_medic.c:36
SVF_DEADMONSTER
#define SVF_DEADMONSTER
Definition: game.h:28
CHAN_AUTO
#define CHAN_AUTO
Definition: q_shared.h:1007
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: q_shared.c:93
edict_s::svflags
int svflags
Definition: g_local.h:983
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_duck16
#define FRAME_duck16
Definition: m_medic.h:170
edict_s
Definition: g_local.h:962
FRAME_death1
#define FRAME_death1
Definition: m_berserk.h:247
medic_walk
void medic_walk(edict_t *self)
Definition: m_medic.c:241
medic_frames_pain1
mframe_t medic_frames_pain1[]
Definition: m_medic.c:284
findradius
edict_t * findradius(edict_t *from, vec3_t org, float rad)
Definition: g_utils.c:78
G_FreeEdict
void G_FreeEdict(edict_t *e)
Definition: g_utils.c:452
medic_frames_walk
mframe_t medic_frames_walk[]
Definition: m_medic.c:224
r
GLdouble GLdouble r
Definition: qgl_win.c:336
medic_duck_up
void medic_duck_up(edict_t *self)
Definition: m_medic.c:465
medic_pain
void medic_pain(edict_t *self, edict_t *other, float kick, int damage)
Definition: m_medic.c:317
sound_idle1
static int sound_idle1
Definition: m_medic.c:34
game_import_t::soundindex
int(* soundindex)(char *name)
Definition: game.h:122
FRAME_attack12
#define FRAME_attack12
Definition: m_boss2.h:105
forward
static vec3_t forward
Definition: p_view.c:29
FRAME_painb15
#define FRAME_painb15
Definition: m_berserk.h:241
EF_BLASTER
#define EF_BLASTER
Definition: q_shared.h:560
VectorLength
vec_t VectorLength(vec3_t v)
Definition: q_shared.c:762
edict_s::owner
edict_t * owner
Definition: g_local.h:988
medic_move_stand
mmove_t medic_move_stand
Definition: m_medic.c:216
AI_HOLD_FRAME
#define AI_HOLD_FRAME
Definition: g_local.h:134
medic_move_attackHyperBlaster
mmove_t medic_move_attackHyperBlaster
Definition: m_medic.c:524
game_import_t::modelindex
int(* modelindex)(char *name)
Definition: game.h:121
mframe_t
Definition: g_local.h:401
FRAME_attack19
#define FRAME_attack19
Definition: m_boss2.h:112
mmove_t
Definition: g_local.h:408
medic_move_walk
mmove_t medic_move_walk
Definition: m_medic.c:239
edict_s::nextthink
float nextthink
Definition: g_local.h:1036
cvar_s::value
float value
Definition: q_shared.h:324
FRAME_wait90
#define FRAME_wait90
Definition: m_medic.h:125
ai_walk
void ai_walk(edict_t *self, float dist)
Definition: g_ai.c:163
FRAME_attack9
#define FRAME_attack9
Definition: m_boss2.h:102
random
#define random()
Definition: g_local.h:509
FRAME_attack25
#define FRAME_attack25
Definition: m_boss2.h:118
medic_move_duck
mmove_t medic_move_duck
Definition: m_medic.c:492
FRAME_attack22
#define FRAME_attack22
Definition: m_boss2.h:115
SP_monster_medic
void SP_monster_medic(edict_t *self)
Definition: m_medic.c:718
medic_dead
void medic_dead(edict_t *self)
Definition: m_medic.c:368
FRAME_wait1
#define FRAME_wait1
Definition: m_medic.h:36
NULL
#define NULL
Definition: q_shared.h:60
FoundTarget
void FoundTarget(edict_t *self)
Definition: g_ai.c:347
medic_idle
void medic_idle(edict_t *self)
Definition: m_medic.c:80
sound_hook_launch
static int sound_hook_launch
Definition: m_medic.c:40
FRAME_painb1
#define FRAME_painb1
Definition: m_berserk.h:227
monsterinfo_t::aiflags
int aiflags
Definition: g_local.h:419
sound_sight
static int sound_sight
Definition: m_medic.c:38
skill
cvar_t * skill
Definition: g_main.c:38
medic_frames_run
mframe_t medic_frames_run[]
Definition: m_medic.c:247
medic_move_pain1
mmove_t medic_move_pain1
Definition: m_medic.c:295
medic_move_run
mmove_t medic_move_run
Definition: m_medic.c:257
ai_move
void ai_move(edict_t *self, float dist)
Definition: g_ai.c:92
medic_fire_blaster
void medic_fire_blaster(edict_t *self)
Definition: m_medic.c:342
game_import_t::WriteShort
void(* WriteShort)(int c)
Definition: game.h:148
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
svc_temp_entity
@ svc_temp_entity
Definition: qcommon.h:210
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:158
FRAME_walk1
#define FRAME_walk1
Definition: m_boss2.h:74
medic_move_attackBlaster
mmove_t medic_move_attackBlaster
Definition: m_medic.c:552
edict_s::monsterinfo
monsterinfo_t monsterinfo
Definition: g_local.h:1108
medic_search
void medic_search(edict_t *self)
Definition: m_medic.c:96
DAMAGE_AIM
@ DAMAGE_AIM
Definition: g_local.h:88
CHAN_WEAPON
#define CHAN_WEAPON
Definition: q_shared.h:1008
medic_frames_attackHyperBlaster
mframe_t medic_frames_attackHyperBlaster[]
Definition: m_medic.c:505
game_import_t::WriteByte
void(* WriteByte)(int c)
Definition: game.h:147
medic_hook_launch
void medic_hook_launch(edict_t *self)
Definition: m_medic.c:555
medic_move_attackCable
mmove_t medic_move_attackCable
Definition: m_medic.c:693
level
GLint level
Definition: qgl_win.c:116
ai_run
void ai_run(edict_t *self, float dist)
Definition: g_ai.c:915
GIB_ORGANIC
#define GIB_ORGANIC
Definition: g_local.h:123
FRAME_run1
#define FRAME_run1
Definition: m_berserk.h:60
VectorMA
void VectorMA(vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
Definition: q_shared.c:719
medic_dodge
void medic_dodge(edict_t *self, edict_t *attacker, float eta)
Definition: m_medic.c:494
FRAME_attack42
#define FRAME_attack42
Definition: m_medic.h:242
medic_frames_death
mframe_t medic_frames_death[]
Definition: m_medic.c:378
medic_duck_down
void medic_duck_down(edict_t *self)
Definition: m_medic.c:446
trace_t::ent
struct edict_s * ent
Definition: q_shared.h:458
FRAME_paina8
#define FRAME_paina8
Definition: m_medic.h:139
sound_hook_retract
static int sound_hook_retract
Definition: m_medic.c:43
ThrowHead
void ThrowHead(edict_t *self, char *gibname, int damage, int type)
Definition: g_misc.c:183
SVF_MONSTER
#define SVF_MONSTER
Definition: game.h:29
medic_stand
void medic_stand(edict_t *self)
Definition: m_medic.c:218
sound_pain1
static int sound_pain1
Definition: m_medic.c:35
medic_move_death
mmove_t medic_move_death
Definition: m_medic.c:411
medic_continue
void medic_continue(edict_t *self)
Definition: m_medic.c:527
MOVETYPE_TOSS
@ MOVETYPE_TOSS
Definition: g_local.h:196
VectorSet
#define VectorSet(v, x, y, z)
Definition: q_shared.h:161
right
GLdouble right
Definition: qgl_win.c:159
medic_die
void medic_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: m_medic.c:413
FRAME_death30
#define FRAME_death30
Definition: m_boss2.h:184
edict_s::enemy
edict_t * enemy
Definition: g_local.h:1070
AI_DUCKED
#define AI_DUCKED
Definition: g_local.h:138
game_import_t::linkentity
void(* linkentity)(edict_t *ent)
Definition: game.h:138
medic_frames_pain2
mframe_t medic_frames_pain2[]
Definition: m_medic.c:297
EF_HYPERBLASTER
#define EF_HYPERBLASTER
Definition: q_shared.h:563
FRAME_attack33
#define FRAME_attack33
Definition: m_boss2.h:126
medic_cable_attack
void medic_cable_attack(edict_t *self)
Definition: m_medic.c:576
MULTICAST_PVS
@ MULTICAST_PVS
Definition: q_shared.h:111
FRAME_duck1
#define FRAME_duck1
Definition: m_berserk.h:193
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:127
medic_frames_stand
mframe_t medic_frames_stand[]
Definition: m_medic.c:122
FRAME_attack44
#define FRAME_attack44
Definition: m_medic.h:244
ai_stand
void ai_stand(edict_t *self, float dist)
Definition: g_ai.c:106
medic_FindDeadMonster
edict_t * medic_FindDeadMonster(edict_t *self)
Definition: m_medic.c:46
FRAME_attack50
#define FRAME_attack50
Definition: m_medic.h:250
g_local.h
FRAME_attack60
#define FRAME_attack60
Definition: m_medic.h:260
edict_s::health
int health
Definition: g_local.h:1051