Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

m_mutant.c (14658B)


      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 
     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 
     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 
     67 void mutant_search (edict_t *self)
     68 {
     69 	gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
     70 }
     71 
     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 
    143 void mutant_stand (edict_t *self)
    144 {
    145 	self->monsterinfo.currentmove = &mutant_move_stand;
    146 }
    147 
    148 
    149 //
    150 // IDLE
    151 //
    152 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    298 void mutant_melee (edict_t *self)
    299 {
    300 	self->monsterinfo.currentmove = &mutant_move_attack;
    301 }
    302 
    303 
    304 //
    305 // ATTACK
    306 //
    307 
    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 
    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 
    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 
    389 void mutant_jump (edict_t *self)
    390 {
    391 	self->monsterinfo.currentmove = &mutant_move_jump;
    392 }
    393 
    394 
    395 //
    396 // CHECKATTACK
    397 //
    398 
    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 
    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 
    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 
    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 
    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 
    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 */
    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 }