1 /*
2 ==============================================================================
3 
4 mutant
5 
6 ==============================================================================
7 */
8 
9 #include "g_local.h"
10 #include "m_mutant.h"
11 
12 
13 static int	sound_swing;
14 static int	sound_hit;
15 static int	sound_hit2;
16 static int	sound_death;
17 static int	sound_idle;
18 static int	sound_pain1;
19 static int	sound_pain2;
20 static int	sound_sight;
21 static int	sound_search;
22 static int	sound_step1;
23 static int	sound_step2;
24 static int	sound_step3;
25 static int	sound_thud;
26 
27 //
28 // SOUNDS
29 //
30 
mutant_step(edict_t * self)31 void mutant_step (edict_t *self)
32 {
33 	int		n;
34 	n = (rand() + 1) % 3;
35 	if (n == 0)
36 		gi.sound (self, CHAN_VOICE, sound_step1, 1, ATTN_NORM, 0);
37 	else if (n == 1)
38 		gi.sound (self, CHAN_VOICE, sound_step2, 1, ATTN_NORM, 0);
39 	else
40 		gi.sound (self, CHAN_VOICE, sound_step3, 1, ATTN_NORM, 0);
41 }
42 
mutant_sight(edict_t * self,edict_t * other)43 void mutant_sight (edict_t *self, edict_t *other)
44 {
45 	gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
46 }
47 
mutant_search(edict_t * self)48 void mutant_search (edict_t *self)
49 {
50 	gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
51 }
52 
mutant_swing(edict_t * self)53 void mutant_swing (edict_t *self)
54 {
55 	gi.sound (self, CHAN_VOICE, sound_swing, 1, ATTN_NORM, 0);
56 }
57 
58 
59 //
60 // STAND
61 //
62 
63 mframe_t mutant_frames_stand [] =
64 {
65 	ai_stand, 0, NULL,
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,		// 10
75 
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,		// 20
86 
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,
96 	ai_stand, 0, NULL,		// 30
97 
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,
106 	ai_stand, 0, NULL,
107 	ai_stand, 0, NULL,		// 40
108 
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,
116 	ai_stand, 0, NULL,
117 	ai_stand, 0, NULL,
118 	ai_stand, 0, NULL,		// 50
119 
120 	ai_stand, 0, NULL
121 };
122 mmove_t mutant_move_stand = {FRAME_stand101, FRAME_stand151, mutant_frames_stand, NULL};
123 
mutant_stand(edict_t * self)124 void mutant_stand (edict_t *self)
125 {
126 	self->monsterinfo.currentmove = &mutant_move_stand;
127 }
128 
129 
130 //
131 // IDLE
132 //
133 
mutant_idle_loop(edict_t * self)134 void mutant_idle_loop (edict_t *self)
135 {
136 	if (random() < 0.75)
137 		self->monsterinfo.nextframe = FRAME_stand155;
138 }
139 
140 mframe_t mutant_frames_idle [] =
141 {
142 	ai_stand, 0, NULL,
143 	ai_stand, 0, NULL,
144 	ai_stand, 0, NULL,
145 	ai_stand, 0, NULL,					// scratch loop start
146 	ai_stand, 0, NULL,
147 	ai_stand, 0, NULL,
148 	ai_stand, 0, mutant_idle_loop,		// scratch loop end
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 };
156 mmove_t mutant_move_idle = {FRAME_stand152, FRAME_stand164, mutant_frames_idle, mutant_stand};
157 
mutant_idle(edict_t * self)158 void mutant_idle (edict_t *self)
159 {
160 	self->monsterinfo.currentmove = &mutant_move_idle;
161 	gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
162 }
163 
164 
165 //
166 // WALK
167 //
168 
169 void mutant_walk (edict_t *self);
170 
171 mframe_t mutant_frames_walk [] =
172 {
173 	ai_walk,	3,		NULL,
174 	ai_walk,	1,		NULL,
175 	ai_walk,	5,		NULL,
176 	ai_walk,	10,		NULL,
177 	ai_walk,	13,		NULL,
178 	ai_walk,	10,		NULL,
179 	ai_walk,	0,		NULL,
180 	ai_walk,	5,		NULL,
181 	ai_walk,	6,		NULL,
182 	ai_walk,	16,		NULL,
183 	ai_walk,	15,		NULL,
184 	ai_walk,	6,		NULL
185 };
186 mmove_t mutant_move_walk = {FRAME_walk05, FRAME_walk16, mutant_frames_walk, NULL};
187 
mutant_walk_loop(edict_t * self)188 void mutant_walk_loop (edict_t *self)
189 {
190 	self->monsterinfo.currentmove = &mutant_move_walk;
191 }
192 
193 mframe_t mutant_frames_start_walk [] =
194 {
195 	ai_walk,	5,		NULL,
196 	ai_walk,	5,		NULL,
197 	ai_walk,	-2,		NULL,
198 	ai_walk,	1,		NULL
199 };
200 mmove_t mutant_move_start_walk = {FRAME_walk01, FRAME_walk04, mutant_frames_start_walk, mutant_walk_loop};
201 
mutant_walk(edict_t * self)202 void mutant_walk (edict_t *self)
203 {
204 	self->monsterinfo.currentmove = &mutant_move_start_walk;
205 }
206 
207 
208 //
209 // RUN
210 //
211 
212 mframe_t mutant_frames_run [] =
213 {
214 	ai_run,	40,		NULL,
215 	ai_run,	40,		mutant_step,
216 	ai_run,	24,		NULL,
217 	ai_run,	5,		mutant_step,
218 	ai_run,	17,		NULL,
219 	ai_run,	10,		NULL
220 };
221 mmove_t mutant_move_run = {FRAME_run03, FRAME_run08, mutant_frames_run, NULL};
222 
mutant_run(edict_t * self)223 void mutant_run (edict_t *self)
224 {
225 	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
226 		self->monsterinfo.currentmove = &mutant_move_stand;
227 	else
228 		self->monsterinfo.currentmove = &mutant_move_run;
229 }
230 
231 
232 //
233 // MELEE
234 //
235 
mutant_hit_left(edict_t * self)236 void mutant_hit_left (edict_t *self)
237 {
238 	vec3_t	aim;
239 
240 	VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
241 	if (fire_hit (self, aim, (10 + (rand() %5)), 100))
242 		gi.sound (self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0);
243 	else
244 		gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
245 }
246 
mutant_hit_right(edict_t * self)247 void mutant_hit_right (edict_t *self)
248 {
249 	vec3_t	aim;
250 
251 	VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8);
252 	if (fire_hit (self, aim, (10 + (rand() %5)), 100))
253 		gi.sound (self, CHAN_WEAPON, sound_hit2, 1, ATTN_NORM, 0);
254 	else
255 		gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
256 }
257 
mutant_check_refire(edict_t * self)258 void mutant_check_refire (edict_t *self)
259 {
260 	if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0)
261 		return;
262 
263 	if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
264 		self->monsterinfo.nextframe = FRAME_attack09;
265 }
266 
267 mframe_t mutant_frames_attack [] =
268 {
269 	ai_charge,	0,	NULL,
270 	ai_charge,	0,	NULL,
271 	ai_charge,	0,	mutant_hit_left,
272 	ai_charge,	0,	NULL,
273 	ai_charge,	0,	NULL,
274 	ai_charge,	0,	mutant_hit_right,
275 	ai_charge,	0,	mutant_check_refire
276 };
277 mmove_t mutant_move_attack = {FRAME_attack09, FRAME_attack15, mutant_frames_attack, mutant_run};
278 
mutant_melee(edict_t * self)279 void mutant_melee (edict_t *self)
280 {
281 	self->monsterinfo.currentmove = &mutant_move_attack;
282 }
283 
284 
285 //
286 // ATTACK
287 //
288 
mutant_jump_touch(edict_t * self,edict_t * other,cplane_t * plane,csurface_t * surf)289 void mutant_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
290 {
291 	if (self->health <= 0)
292 	{
293 		self->touch = NULL;
294 		return;
295 	}
296 
297 	if (other->takedamage)
298 	{
299 		if (VectorLength(self->velocity) > 400)
300 		{
301 			vec3_t	point;
302 			vec3_t	normal;
303 			int		damage;
304 
305 			VectorCopy (self->velocity, normal);
306 			VectorNormalize(normal);
307 			VectorMA (self->s.origin, self->maxs[0], normal, point);
308 			damage = 40 + 10 * random();
309 			T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_UNKNOWN);
310 		}
311 	}
312 
313 	if (!M_CheckBottom (self))
314 	{
315 		if (self->groundentity)
316 		{
317 			self->monsterinfo.nextframe = FRAME_attack02;
318 			self->touch = NULL;
319 		}
320 		return;
321 	}
322 
323 	self->touch = NULL;
324 }
325 
mutant_jump_takeoff(edict_t * self)326 void mutant_jump_takeoff (edict_t *self)
327 {
328 	vec3_t	forward;
329 
330 	gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
331 	AngleVectors (self->s.angles, forward, NULL, NULL);
332 	self->s.origin[2] += 1;
333 	VectorScale (forward, 600, self->velocity);
334 	self->velocity[2] = 250;
335 	self->groundentity = NULL;
336 	self->monsterinfo.aiflags |= AI_DUCKED;
337 	self->monsterinfo.attack_finished = level.time + 3;
338 	self->touch = mutant_jump_touch;
339 }
340 
mutant_check_landing(edict_t * self)341 void mutant_check_landing (edict_t *self)
342 {
343 	if (self->groundentity)
344 	{
345 		gi.sound (self, CHAN_WEAPON, sound_thud, 1, ATTN_NORM, 0);
346 		self->monsterinfo.attack_finished = 0;
347 		self->monsterinfo.aiflags &= ~AI_DUCKED;
348 		return;
349 	}
350 
351 	if (level.time > self->monsterinfo.attack_finished)
352 		self->monsterinfo.nextframe = FRAME_attack02;
353 	else
354 		self->monsterinfo.nextframe = FRAME_attack05;
355 }
356 
357 mframe_t mutant_frames_jump [] =
358 {
359 	ai_charge,	 0,	NULL,
360 	ai_charge,	17,	NULL,
361 	ai_charge,	15,	mutant_jump_takeoff,
362 	ai_charge,	15,	NULL,
363 	ai_charge,	15,	mutant_check_landing,
364 	ai_charge,	 0,	NULL,
365 	ai_charge,	 3,	NULL,
366 	ai_charge,	 0,	NULL
367 };
368 mmove_t mutant_move_jump = {FRAME_attack01, FRAME_attack08, mutant_frames_jump, mutant_run};
369 
mutant_jump(edict_t * self)370 void mutant_jump (edict_t *self)
371 {
372 	self->monsterinfo.currentmove = &mutant_move_jump;
373 }
374 
375 
376 //
377 // CHECKATTACK
378 //
379 
mutant_check_melee(edict_t * self)380 qboolean mutant_check_melee (edict_t *self)
381 {
382 	if (range (self, self->enemy) == RANGE_MELEE)
383 		return true;
384 	return false;
385 }
386 
mutant_check_jump(edict_t * self)387 qboolean mutant_check_jump (edict_t *self)
388 {
389 	vec3_t	v;
390 	float	distance;
391 
392 	if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2]))
393 		return false;
394 
395 	if (self->absmax[2] < (self->enemy->absmin[2] + 0.25 * self->enemy->size[2]))
396 		return false;
397 
398 	v[0] = self->s.origin[0] - self->enemy->s.origin[0];
399 	v[1] = self->s.origin[1] - self->enemy->s.origin[1];
400 	v[2] = 0;
401 	distance = VectorLength(v);
402 
403 	if (distance < 100)
404 		return false;
405 	if (distance > 100)
406 	{
407 		if (random() < 0.9)
408 			return false;
409 	}
410 
411 	return true;
412 }
413 
mutant_checkattack(edict_t * self)414 qboolean mutant_checkattack (edict_t *self)
415 {
416 	if (!self->enemy || self->enemy->health <= 0)
417 		return false;
418 
419 	if (mutant_check_melee(self))
420 	{
421 		self->monsterinfo.attack_state = AS_MELEE;
422 		return true;
423 	}
424 
425 	if (mutant_check_jump(self))
426 	{
427 		self->monsterinfo.attack_state = AS_MISSILE;
428 		// FIXME play a jump sound here
429 		return true;
430 	}
431 
432 	return false;
433 }
434 
435 
436 //
437 // PAIN
438 //
439 
440 mframe_t mutant_frames_pain1 [] =
441 {
442 	ai_move,	4,	NULL,
443 	ai_move,	-3,	NULL,
444 	ai_move,	-8,	NULL,
445 	ai_move,	2,	NULL,
446 	ai_move,	5,	NULL
447 };
448 mmove_t mutant_move_pain1 = {FRAME_pain101, FRAME_pain105, mutant_frames_pain1, mutant_run};
449 
450 mframe_t mutant_frames_pain2 [] =
451 {
452 	ai_move,	-24,NULL,
453 	ai_move,	11,	NULL,
454 	ai_move,	5,	NULL,
455 	ai_move,	-2,	NULL,
456 	ai_move,	6,	NULL,
457 	ai_move,	4,	NULL
458 };
459 mmove_t mutant_move_pain2 = {FRAME_pain201, FRAME_pain206, mutant_frames_pain2, mutant_run};
460 
461 mframe_t mutant_frames_pain3 [] =
462 {
463 	ai_move,	-22,NULL,
464 	ai_move,	3,	NULL,
465 	ai_move,	3,	NULL,
466 	ai_move,	2,	NULL,
467 	ai_move,	1,	NULL,
468 	ai_move,	1,	NULL,
469 	ai_move,	6,	NULL,
470 	ai_move,	3,	NULL,
471 	ai_move,	2,	NULL,
472 	ai_move,	0,	NULL,
473 	ai_move,	1,	NULL
474 };
475 mmove_t mutant_move_pain3 = {FRAME_pain301, FRAME_pain311, mutant_frames_pain3, mutant_run};
476 
mutant_pain(edict_t * self,edict_t * other,float kick,int damage)477 void mutant_pain (edict_t *self, edict_t *other, float kick, int damage)
478 {
479 	float	r;
480 
481 	if (self->health < (self->max_health / 2))
482 		self->s.skinnum = 1;
483 
484 	if (level.time < self->pain_debounce_time)
485 		return;
486 
487 	self->pain_debounce_time = level.time + 3;
488 
489 	if (skill->value == 3)
490 		return;		// no pain anims in nightmare
491 
492 	r = random();
493 	if (r < 0.33)
494 	{
495 		gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
496 		self->monsterinfo.currentmove = &mutant_move_pain1;
497 	}
498 	else if (r < 0.66)
499 	{
500 		gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
501 		self->monsterinfo.currentmove = &mutant_move_pain2;
502 	}
503 	else
504 	{
505 		gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
506 		self->monsterinfo.currentmove = &mutant_move_pain3;
507 	}
508 }
509 
510 
511 //
512 // DEATH
513 //
514 
mutant_dead(edict_t * self)515 void mutant_dead (edict_t *self)
516 {
517 	VectorSet (self->mins, -16, -16, -24);
518 	VectorSet (self->maxs, 16, 16, -8);
519 	self->movetype = MOVETYPE_TOSS;
520 	self->svflags |= SVF_DEADMONSTER;
521 	gi.linkentity (self);
522 
523 	M_FlyCheck (self);
524 }
525 
526 mframe_t mutant_frames_death1 [] =
527 {
528 	ai_move,	0,	NULL,
529 	ai_move,	0,	NULL,
530 	ai_move,	0,	NULL,
531 	ai_move,	0,	NULL,
532 	ai_move,	0,	NULL,
533 	ai_move,	0,	NULL,
534 	ai_move,	0,	NULL,
535 	ai_move,	0,	NULL,
536 	ai_move,	0,	NULL
537 };
538 mmove_t mutant_move_death1 = {FRAME_death101, FRAME_death109, mutant_frames_death1, mutant_dead};
539 
540 mframe_t mutant_frames_death2 [] =
541 {
542 	ai_move,	0,	NULL,
543 	ai_move,	0,	NULL,
544 	ai_move,	0,	NULL,
545 	ai_move,	0,	NULL,
546 	ai_move,	0,	NULL,
547 	ai_move,	0,	NULL,
548 	ai_move,	0,	NULL,
549 	ai_move,	0,	NULL,
550 	ai_move,	0,	NULL,
551 	ai_move,	0,	NULL
552 };
553 mmove_t mutant_move_death2 = {FRAME_death201, FRAME_death210, mutant_frames_death2, mutant_dead};
554 
mutant_die(edict_t * self,edict_t * inflictor,edict_t * attacker,int damage,vec3_t point)555 void mutant_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
556 {
557 	int		n;
558 
559 	if (self->health <= self->gib_health)
560 	{
561 		gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
562 		for (n= 0; n < 2; n++)
563 			ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
564 		for (n= 0; n < 4; n++)
565 			ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
566 		ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
567 		self->deadflag = DEAD_DEAD;
568 		return;
569 	}
570 
571 	if (self->deadflag == DEAD_DEAD)
572 		return;
573 
574 	gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
575 	self->deadflag = DEAD_DEAD;
576 	self->takedamage = DAMAGE_YES;
577 	self->s.skinnum = 1;
578 
579 	if (random() < 0.5)
580 		self->monsterinfo.currentmove = &mutant_move_death1;
581 	else
582 		self->monsterinfo.currentmove = &mutant_move_death2;
583 }
584 
585 
586 
587 //================
588 //ROGUE
mutant_jump_down(edict_t * self)589 void mutant_jump_down (edict_t *self)
590 {
591 	vec3_t	forward,up;
592 
593 	AngleVectors (self->s.angles, forward, NULL, up);
594 	VectorMA(self->velocity, 100, forward, self->velocity);
595 	VectorMA(self->velocity, 300, up, self->velocity);
596 }
597 
mutant_jump_up(edict_t * self)598 void mutant_jump_up (edict_t *self)
599 {
600 	vec3_t	forward,up;
601 
602 	AngleVectors (self->s.angles, forward, NULL, up);
603 	VectorMA(self->velocity, 200, forward, self->velocity);
604 	VectorMA(self->velocity, 450, up, self->velocity);
605 }
606 
mutant_jump_wait_land(edict_t * self)607 void mutant_jump_wait_land (edict_t *self)
608 {
609 	if(self->groundentity == NULL)
610 		self->monsterinfo.nextframe = self->s.frame;
611 	else
612 		self->monsterinfo.nextframe = self->s.frame + 1;
613 }
614 
615 mframe_t mutant_frames_jump_up [] =
616 {
617 	ai_move, -8, NULL,
618 	ai_move, -8, mutant_jump_up,
619 	ai_move, 0, mutant_jump_wait_land,
620 	ai_move, 0, NULL,
621 	ai_move, 0, NULL
622 };
623 mmove_t mutant_move_jump_up = { FRAME_jump01, FRAME_jump05, mutant_frames_jump_up, mutant_run };
624 
625 mframe_t mutant_frames_jump_down [] =
626 {
627 	ai_move, 0, NULL,
628 	ai_move, 0, mutant_jump_down,
629 	ai_move, 0, mutant_jump_wait_land,
630 	ai_move, 0, NULL,
631 	ai_move, 0, NULL
632 };
633 mmove_t mutant_move_jump_down = { FRAME_jump01, FRAME_jump05, mutant_frames_jump_down, mutant_run };
634 
mutant_jump_updown(edict_t * self)635 void mutant_jump_updown (edict_t *self)
636 {
637 	if(!self->enemy)
638 		return;
639 
640 	if(self->enemy->s.origin[2] > self->s.origin[2])
641 		self->monsterinfo.currentmove = &mutant_move_jump_up;
642 	else
643 		self->monsterinfo.currentmove = &mutant_move_jump_down;
644 }
645 
646 /*
647 ===
648 Blocked
649 ===
650 */
mutant_blocked(edict_t * self,float dist)651 qboolean mutant_blocked (edict_t *self, float dist)
652 {
653 	if(blocked_checkjump (self, dist, 256, 68))
654 	{
655 		mutant_jump_updown (self);
656 		return true;
657 	}
658 
659 	if(blocked_checkplat (self, dist))
660 		return true;
661 }
662 //ROGUE
663 //================
664 
665 //
666 // SPAWN
667 //
668 
669 /*QUAKED monster_mutant (1 .5 0) (-32 -32 -24) (32 32 32) Ambush Trigger_Spawn Sight
670 */
SP_monster_mutant(edict_t * self)671 void SP_monster_mutant (edict_t *self)
672 {
673 	if (deathmatch->value)
674 	{
675 		G_FreeEdict (self);
676 		return;
677 	}
678 
679 	sound_swing = gi.soundindex ("mutant/mutatck1.wav");
680 	sound_hit = gi.soundindex ("mutant/mutatck2.wav");
681 	sound_hit2 = gi.soundindex ("mutant/mutatck3.wav");
682 	sound_death = gi.soundindex ("mutant/mutdeth1.wav");
683 	sound_idle = gi.soundindex ("mutant/mutidle1.wav");
684 	sound_pain1 = gi.soundindex ("mutant/mutpain1.wav");
685 	sound_pain2 = gi.soundindex ("mutant/mutpain2.wav");
686 	sound_sight = gi.soundindex ("mutant/mutsght1.wav");
687 	sound_search = gi.soundindex ("mutant/mutsrch1.wav");
688 	sound_step1 = gi.soundindex ("mutant/step1.wav");
689 	sound_step2 = gi.soundindex ("mutant/step2.wav");
690 	sound_step3 = gi.soundindex ("mutant/step3.wav");
691 	sound_thud = gi.soundindex ("mutant/thud1.wav");
692 
693 	self->movetype = MOVETYPE_STEP;
694 	self->solid = SOLID_BBOX;
695 	self->s.modelindex = gi.modelindex ("models/monsters/mutant/tris.md2");
696 	VectorSet (self->mins, -32, -32, -24);
697 	VectorSet (self->maxs, 32, 32, 48);
698 
699 	self->health = 300;
700 	self->gib_health = -120;
701 	self->mass = 300;
702 
703 	self->pain = mutant_pain;
704 	self->die = mutant_die;
705 
706 	self->monsterinfo.stand = mutant_stand;
707 	self->monsterinfo.walk = mutant_walk;
708 	self->monsterinfo.run = mutant_run;
709 	self->monsterinfo.dodge = NULL;
710 	self->monsterinfo.attack = mutant_jump;
711 	self->monsterinfo.melee = mutant_melee;
712 	self->monsterinfo.sight = mutant_sight;
713 	self->monsterinfo.search = mutant_search;
714 	self->monsterinfo.idle = mutant_idle;
715 	self->monsterinfo.checkattack = mutant_checkattack;
716 	self->monsterinfo.blocked = mutant_blocked;			// PGM
717 
718 	gi.linkentity (self);
719 
720 	self->monsterinfo.currentmove = &mutant_move_stand;
721 
722 	self->monsterinfo.scale = MODEL_SCALE;
723 	walkmonster_start (self);
724 }
725