Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

m_flyer.c (14678B)


      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 flyer
     24 
     25 ==============================================================================
     26 */
     27 
     28 #include "g_local.h"
     29 #include "m_flyer.h"
     30 
     31 qboolean visible (edict_t *self, edict_t *other);
     32 
     33 static int	nextmove;			// Used for start/stop frames
     34 
     35 static int	sound_sight;
     36 static int	sound_idle;
     37 static int	sound_pain1;
     38 static int	sound_pain2;
     39 static int	sound_slash;
     40 static int	sound_sproing;
     41 static int	sound_die;
     42 
     43 
     44 void flyer_check_melee(edict_t *self);
     45 void flyer_loop_melee (edict_t *self);
     46 void flyer_melee (edict_t *self);
     47 void flyer_setstart (edict_t *self);
     48 void flyer_stand (edict_t *self);
     49 void flyer_nextmove (edict_t *self);
     50 
     51 
     52 void flyer_sight (edict_t *self, edict_t *other)
     53 {
     54 	gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
     55 }
     56 
     57 void flyer_idle (edict_t *self)
     58 {
     59 	gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
     60 }
     61 
     62 void flyer_pop_blades (edict_t *self)
     63 {
     64 	gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
     65 }
     66 
     67 
     68 mframe_t flyer_frames_stand [] =
     69 {
     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,
     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,
     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,
     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,
    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
    115 };
    116 mmove_t	flyer_move_stand = {FRAME_stand01, FRAME_stand45, flyer_frames_stand, NULL};
    117 
    118 
    119 mframe_t flyer_frames_walk [] =
    120 {
    121 	ai_walk, 5, NULL,
    122 	ai_walk, 5, NULL,
    123 	ai_walk, 5, NULL,
    124 	ai_walk, 5, NULL,
    125 	ai_walk, 5, NULL,
    126 	ai_walk, 5, NULL,
    127 	ai_walk, 5, NULL,
    128 	ai_walk, 5, NULL,
    129 	ai_walk, 5, NULL,
    130 	ai_walk, 5, NULL,
    131 	ai_walk, 5, NULL,
    132 	ai_walk, 5, NULL,
    133 	ai_walk, 5, NULL,
    134 	ai_walk, 5, NULL,
    135 	ai_walk, 5, NULL,
    136 	ai_walk, 5, NULL,
    137 	ai_walk, 5, NULL,
    138 	ai_walk, 5, NULL,
    139 	ai_walk, 5, NULL,
    140 	ai_walk, 5, NULL,
    141 	ai_walk, 5, NULL,
    142 	ai_walk, 5, NULL,
    143 	ai_walk, 5, NULL,
    144 	ai_walk, 5, NULL,
    145 	ai_walk, 5, NULL,
    146 	ai_walk, 5, NULL,
    147 	ai_walk, 5, NULL,
    148 	ai_walk, 5, NULL,
    149 	ai_walk, 5, NULL,
    150 	ai_walk, 5, NULL,
    151 	ai_walk, 5, NULL,
    152 	ai_walk, 5, NULL,
    153 	ai_walk, 5, NULL,
    154 	ai_walk, 5, NULL,
    155 	ai_walk, 5, NULL,
    156 	ai_walk, 5, NULL,
    157 	ai_walk, 5, NULL,
    158 	ai_walk, 5, NULL,
    159 	ai_walk, 5, NULL,
    160 	ai_walk, 5, NULL,
    161 	ai_walk, 5, NULL,
    162 	ai_walk, 5, NULL,
    163 	ai_walk, 5, NULL,
    164 	ai_walk, 5, NULL,
    165 	ai_walk, 5, NULL
    166 };
    167 mmove_t	flyer_move_walk = {FRAME_stand01, FRAME_stand45, flyer_frames_walk, NULL};
    168 
    169 mframe_t flyer_frames_run [] =
    170 {
    171 	ai_run, 10, NULL,
    172 	ai_run, 10, NULL,
    173 	ai_run, 10, NULL,
    174 	ai_run, 10, NULL,
    175 	ai_run, 10, NULL,
    176 	ai_run, 10, NULL,
    177 	ai_run, 10, NULL,
    178 	ai_run, 10, NULL,
    179 	ai_run, 10, NULL,
    180 	ai_run, 10, NULL,
    181 	ai_run, 10, NULL,
    182 	ai_run, 10, NULL,
    183 	ai_run, 10, NULL,
    184 	ai_run, 10, NULL,
    185 	ai_run, 10, NULL,
    186 	ai_run, 10, NULL,
    187 	ai_run, 10, NULL,
    188 	ai_run, 10, NULL,
    189 	ai_run, 10, NULL,
    190 	ai_run, 10, NULL,
    191 	ai_run, 10, NULL,
    192 	ai_run, 10, NULL,
    193 	ai_run, 10, NULL,
    194 	ai_run, 10, NULL,
    195 	ai_run, 10, NULL,
    196 	ai_run, 10, NULL,
    197 	ai_run, 10, NULL,
    198 	ai_run, 10, NULL,
    199 	ai_run, 10, NULL,
    200 	ai_run, 10, NULL,
    201 	ai_run, 10, NULL,
    202 	ai_run, 10, NULL,
    203 	ai_run, 10, NULL,
    204 	ai_run, 10, NULL,
    205 	ai_run, 10, NULL,
    206 	ai_run, 10, NULL,
    207 	ai_run, 10, NULL,
    208 	ai_run, 10, NULL,
    209 	ai_run, 10, NULL,
    210 	ai_run, 10, NULL,
    211 	ai_run, 10, NULL,
    212 	ai_run, 10, NULL,
    213 	ai_run, 10, NULL,
    214 	ai_run, 10, NULL,
    215 	ai_run, 10, NULL
    216 };
    217 mmove_t	flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL};
    218 
    219 void flyer_run (edict_t *self)
    220 {
    221 	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
    222 		self->monsterinfo.currentmove = &flyer_move_stand;
    223 	else
    224 		self->monsterinfo.currentmove = &flyer_move_run;
    225 }
    226 
    227 void flyer_walk (edict_t *self)
    228 {
    229 	self->monsterinfo.currentmove = &flyer_move_walk;
    230 }
    231 
    232 void flyer_stand (edict_t *self)
    233 {
    234 		self->monsterinfo.currentmove = &flyer_move_stand;
    235 }
    236 
    237 mframe_t flyer_frames_start [] =
    238 {
    239 		ai_move, 0,	NULL,
    240 		ai_move, 0,	NULL,
    241 		ai_move, 0,	NULL,
    242 		ai_move, 0,	NULL,
    243 		ai_move, 0,	NULL,
    244 		ai_move, 0,	flyer_nextmove
    245 };
    246 mmove_t flyer_move_start = {FRAME_start01, FRAME_start06, flyer_frames_start, NULL};
    247 
    248 mframe_t flyer_frames_stop [] =
    249 {
    250 		ai_move, 0,	NULL,
    251 		ai_move, 0,	NULL,
    252 		ai_move, 0,	NULL,
    253 		ai_move, 0,	NULL,
    254 		ai_move, 0,	NULL,
    255 		ai_move, 0,	NULL,
    256 		ai_move, 0,	flyer_nextmove
    257 };
    258 mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL};
    259 
    260 void flyer_stop (edict_t *self)
    261 {
    262 		self->monsterinfo.currentmove = &flyer_move_stop;
    263 }
    264 
    265 void flyer_start (edict_t *self)
    266 {
    267 		self->monsterinfo.currentmove = &flyer_move_start;
    268 }
    269 
    270 
    271 mframe_t flyer_frames_rollright [] =
    272 {
    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,
    279 		ai_move, 0, NULL,
    280 		ai_move, 0, NULL,
    281 		ai_move, 0, NULL
    282 };
    283 mmove_t flyer_move_rollright = {FRAME_rollr01, FRAME_rollr09, flyer_frames_rollright, NULL};
    284 
    285 mframe_t flyer_frames_rollleft [] =
    286 {
    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 		ai_move, 0, NULL,
    295 		ai_move, 0, NULL
    296 };
    297 mmove_t flyer_move_rollleft = {FRAME_rollf01, FRAME_rollf09, flyer_frames_rollleft, NULL};
    298 
    299 mframe_t flyer_frames_pain3 [] =
    300 {	
    301 		ai_move, 0, NULL,
    302 		ai_move, 0, NULL,
    303 		ai_move, 0, NULL,
    304 		ai_move, 0, NULL
    305 };
    306 mmove_t flyer_move_pain3 = {FRAME_pain301, FRAME_pain304, flyer_frames_pain3, flyer_run};
    307 
    308 mframe_t flyer_frames_pain2 [] =
    309 {
    310 		ai_move, 0, NULL,
    311 		ai_move, 0, NULL,
    312 		ai_move, 0, NULL,
    313 		ai_move, 0, NULL
    314 };
    315 mmove_t flyer_move_pain2 = {FRAME_pain201, FRAME_pain204, flyer_frames_pain2, flyer_run};
    316 
    317 mframe_t flyer_frames_pain1 [] =
    318 {
    319 		ai_move, 0, NULL,
    320 		ai_move, 0, NULL,
    321 		ai_move, 0, NULL,
    322 		ai_move, 0, NULL,
    323 		ai_move, 0, NULL,
    324 		ai_move, 0, NULL,
    325 		ai_move, 0, NULL,
    326 		ai_move, 0, NULL,
    327 		ai_move, 0, NULL
    328 };
    329 mmove_t flyer_move_pain1 = {FRAME_pain101, FRAME_pain109, flyer_frames_pain1, flyer_run};
    330 
    331 mframe_t flyer_frames_defense [] = 
    332 {
    333 		ai_move, 0, NULL,
    334 		ai_move, 0, NULL,
    335 		ai_move, 0, NULL,		// Hold this frame
    336 		ai_move, 0, NULL,
    337 		ai_move, 0, NULL,
    338 		ai_move, 0, NULL
    339 };
    340 mmove_t flyer_move_defense = {FRAME_defens01, FRAME_defens06, flyer_frames_defense, NULL};
    341 
    342 mframe_t flyer_frames_bankright [] =
    343 {
    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,
    349 		ai_move, 0, NULL,
    350 		ai_move, 0, NULL
    351 };
    352 mmove_t flyer_move_bankright = {FRAME_bankr01, FRAME_bankr07, flyer_frames_bankright, NULL};
    353 
    354 mframe_t flyer_frames_bankleft [] =
    355 {
    356 		ai_move, 0, NULL,
    357 		ai_move, 0, NULL,
    358 		ai_move, 0, NULL,
    359 		ai_move, 0, NULL,
    360 		ai_move, 0, NULL,
    361 		ai_move, 0, NULL,
    362 		ai_move, 0, NULL
    363 };
    364 mmove_t flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl07, flyer_frames_bankleft, NULL};		
    365 
    366 
    367 void flyer_fire (edict_t *self, int flash_number)
    368 {
    369 	vec3_t	start;
    370 	vec3_t	forward, right;
    371 	vec3_t	end;
    372 	vec3_t	dir;
    373 	int		effect;
    374 
    375 	if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210))
    376 		effect = EF_HYPERBLASTER;
    377 	else
    378 		effect = 0;
    379 	AngleVectors (self->s.angles, forward, right, NULL);
    380 	G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
    381 	
    382 	VectorCopy (self->enemy->s.origin, end);
    383 	end[2] += self->enemy->viewheight;
    384 	VectorSubtract (end, start, dir);
    385 
    386 	monster_fire_blaster (self, start, dir, 1, 1000, flash_number, effect);
    387 }
    388 
    389 void flyer_fireleft (edict_t *self)
    390 {
    391 	flyer_fire (self, MZ2_FLYER_BLASTER_1);
    392 }
    393 
    394 void flyer_fireright (edict_t *self)
    395 {
    396 	flyer_fire (self, MZ2_FLYER_BLASTER_2);
    397 }
    398 
    399 
    400 mframe_t flyer_frames_attack2 [] =
    401 {
    402 		ai_charge, 0, NULL,
    403 		ai_charge, 0, NULL,
    404 		ai_charge, 0, NULL,
    405 		ai_charge, -10, flyer_fireleft,			// left gun
    406 		ai_charge, -10, flyer_fireright,		// right gun
    407 		ai_charge, -10, flyer_fireleft,			// left gun
    408 		ai_charge, -10, flyer_fireright,		// right gun
    409 		ai_charge, -10, flyer_fireleft,			// left gun
    410 		ai_charge, -10, flyer_fireright,		// right gun
    411 		ai_charge, -10, flyer_fireleft,			// left gun
    412 		ai_charge, -10, flyer_fireright,		// right gun
    413 		ai_charge, 0, NULL,
    414 		ai_charge, 0, NULL,
    415 		ai_charge, 0, NULL,
    416 		ai_charge, 0, NULL,
    417 		ai_charge, 0, NULL,
    418 		ai_charge, 0, NULL
    419 };
    420 mmove_t flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run};
    421 
    422 
    423 void flyer_slash_left (edict_t *self)
    424 {
    425 	vec3_t	aim;
    426 
    427 	VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0);
    428 	fire_hit (self, aim, 5, 0);
    429 	gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
    430 }
    431 
    432 void flyer_slash_right (edict_t *self)
    433 {
    434 	vec3_t	aim;
    435 
    436 	VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0);
    437 	fire_hit (self, aim, 5, 0);
    438 	gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
    439 }
    440 
    441 mframe_t flyer_frames_start_melee [] =
    442 {
    443 		ai_charge, 0, flyer_pop_blades,
    444 		ai_charge, 0, NULL,
    445 		ai_charge, 0, NULL,
    446 		ai_charge, 0, NULL,
    447 		ai_charge, 0, NULL,
    448 		ai_charge, 0, NULL
    449 };
    450 mmove_t flyer_move_start_melee = {FRAME_attak101, FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee};
    451 
    452 mframe_t flyer_frames_end_melee [] =
    453 {
    454 		ai_charge, 0, NULL,
    455 		ai_charge, 0, NULL,
    456 		ai_charge, 0, NULL
    457 };
    458 mmove_t flyer_move_end_melee = {FRAME_attak119, FRAME_attak121, flyer_frames_end_melee, flyer_run};
    459 
    460 
    461 mframe_t flyer_frames_loop_melee [] =
    462 {
    463 		ai_charge, 0, NULL,		// Loop Start
    464 		ai_charge, 0, NULL,
    465 		ai_charge, 0, flyer_slash_left,		// Left Wing Strike
    466 		ai_charge, 0, NULL,
    467 		ai_charge, 0, NULL,
    468 		ai_charge, 0, NULL,
    469 		ai_charge, 0, NULL,
    470 		ai_charge, 0, flyer_slash_right,	// Right Wing Strike
    471 		ai_charge, 0, NULL,
    472 		ai_charge, 0, NULL,
    473 		ai_charge, 0, NULL,
    474 		ai_charge, 0, NULL		// Loop Ends
    475 		
    476 };
    477 mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee};
    478 
    479 void flyer_loop_melee (edict_t *self)
    480 {
    481 /*	if (random() <= 0.5)	
    482 		self->monsterinfo.currentmove = &flyer_move_attack1;
    483 	else */
    484 	self->monsterinfo.currentmove = &flyer_move_loop_melee;
    485 }
    486 
    487 
    488 
    489 void flyer_attack (edict_t *self)
    490 {
    491 /*	if (random() <= 0.5)	
    492 		self->monsterinfo.currentmove = &flyer_move_attack1;
    493 	else */
    494 	self->monsterinfo.currentmove = &flyer_move_attack2;
    495 }
    496 
    497 void flyer_setstart (edict_t *self)
    498 {
    499 	nextmove = ACTION_run;
    500 	self->monsterinfo.currentmove = &flyer_move_start;
    501 }
    502 
    503 void flyer_nextmove (edict_t *self)
    504 {
    505 	if (nextmove == ACTION_attack1)
    506 		self->monsterinfo.currentmove = &flyer_move_start_melee;
    507 	else if (nextmove == ACTION_attack2)
    508 		self->monsterinfo.currentmove = &flyer_move_attack2;
    509 	else if (nextmove == ACTION_run)
    510 		self->monsterinfo.currentmove = &flyer_move_run;
    511 }
    512 
    513 void flyer_melee (edict_t *self)
    514 {
    515 //	flyer.nextmove = ACTION_attack1;
    516 //	self->monsterinfo.currentmove = &flyer_move_stop;
    517 	self->monsterinfo.currentmove = &flyer_move_start_melee;
    518 }
    519 
    520 void flyer_check_melee(edict_t *self)
    521 {
    522 	if (range (self, self->enemy) == RANGE_MELEE)
    523 		if (random() <= 0.8)
    524 			self->monsterinfo.currentmove = &flyer_move_loop_melee;
    525 		else
    526 			self->monsterinfo.currentmove = &flyer_move_end_melee;
    527 	else
    528 		self->monsterinfo.currentmove = &flyer_move_end_melee;
    529 }
    530 
    531 void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
    532 {
    533 	int		n;
    534 
    535 	if (self->health < (self->max_health / 2))
    536 		self->s.skinnum = 1;
    537 
    538 	if (level.time < self->pain_debounce_time)
    539 		return;
    540 
    541 	self->pain_debounce_time = level.time + 3;
    542 	if (skill->value == 3)
    543 		return;		// no pain anims in nightmare
    544 
    545 	n = rand() % 3;
    546 	if (n == 0)
    547 	{
    548 		gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
    549 		self->monsterinfo.currentmove = &flyer_move_pain1;
    550 	}
    551 	else if (n == 1)
    552 	{
    553 		gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
    554 		self->monsterinfo.currentmove = &flyer_move_pain2;
    555 	}
    556 	else
    557 	{
    558 		gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
    559 		self->monsterinfo.currentmove = &flyer_move_pain3;
    560 	}
    561 }
    562 
    563 
    564 void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
    565 {
    566 	gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
    567 	BecomeExplosion1(self);
    568 }
    569 	
    570 
    571 /*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
    572 */
    573 void SP_monster_flyer (edict_t *self)
    574 {
    575 	if (deathmatch->value)
    576 	{
    577 		G_FreeEdict (self);
    578 		return;
    579 	}
    580 
    581 	// fix a map bug in jail5.bsp
    582 	if (!Q_stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104))
    583 	{
    584 		self->targetname = self->target;
    585 		self->target = NULL;
    586 	}
    587 
    588 	sound_sight = gi.soundindex ("flyer/flysght1.wav");
    589 	sound_idle = gi.soundindex ("flyer/flysrch1.wav");
    590 	sound_pain1 = gi.soundindex ("flyer/flypain1.wav");
    591 	sound_pain2 = gi.soundindex ("flyer/flypain2.wav");
    592 	sound_slash = gi.soundindex ("flyer/flyatck2.wav");
    593 	sound_sproing = gi.soundindex ("flyer/flyatck1.wav");
    594 	sound_die = gi.soundindex ("flyer/flydeth1.wav");
    595 
    596 	gi.soundindex ("flyer/flyatck3.wav");
    597 
    598 	self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2");
    599 	VectorSet (self->mins, -16, -16, -24);
    600 	VectorSet (self->maxs, 16, 16, 32);
    601 	self->movetype = MOVETYPE_STEP;
    602 	self->solid = SOLID_BBOX;
    603 
    604 	self->s.sound = gi.soundindex ("flyer/flyidle1.wav");
    605 
    606 	self->health = 50;
    607 	self->mass = 50;
    608 
    609 	self->pain = flyer_pain;
    610 	self->die = flyer_die;
    611 
    612 	self->monsterinfo.stand = flyer_stand;
    613 	self->monsterinfo.walk = flyer_walk;
    614 	self->monsterinfo.run = flyer_run;
    615 	self->monsterinfo.attack = flyer_attack;
    616 	self->monsterinfo.melee = flyer_melee;
    617 	self->monsterinfo.sight = flyer_sight;
    618 	self->monsterinfo.idle = flyer_idle;
    619 
    620 	gi.linkentity (self);
    621 
    622 	self->monsterinfo.currentmove = &flyer_move_stand;	
    623 	self->monsterinfo.scale = MODEL_SCALE;
    624 
    625 	flymonster_start (self);
    626 }