File: game\m_flyer.c

    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 }
  627