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