Annotation of quake2/game/m_gunner.c, revision 1.1.1.2

1.1       root        1: /*
1.1.1.2 ! root        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: /*
1.1       root       21: ==============================================================================
                     22: 
                     23: GUNNER
                     24: 
                     25: ==============================================================================
                     26: */
                     27: 
                     28: #include "g_local.h"
                     29: #include "m_gunner.h"
                     30: 
                     31: 
                     32: static int     sound_pain;
                     33: static int     sound_pain2;
                     34: static int     sound_death;
                     35: static int     sound_idle;
                     36: static int     sound_open;
                     37: static int     sound_search;
                     38: static int     sound_sight;
                     39: 
                     40: 
                     41: void gunner_idlesound (edict_t *self)
                     42: {
                     43:        gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
                     44: }
                     45: 
                     46: void gunner_sight (edict_t *self, edict_t *other)
                     47: {
                     48:        gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
                     49: }
                     50: 
                     51: void gunner_search (edict_t *self)
                     52: {
                     53:        gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
                     54: }
                     55: 
                     56: 
                     57: qboolean visible (edict_t *self, edict_t *other);
                     58: void GunnerGrenade (edict_t *self);
                     59: void GunnerFire (edict_t *self);
                     60: void gunner_fire_chain(edict_t *self);
                     61: void gunner_refire_chain(edict_t *self);
                     62: 
                     63: 
                     64: void gunner_stand (edict_t *self);
                     65: 
                     66: mframe_t gunner_frames_fidget [] =
                     67: {
                     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,
                     75:        ai_stand, 0, gunner_idlesound,
                     76:        ai_stand, 0, NULL,
                     77: 
                     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: 
                     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: 
                    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: 
                    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,
                    119:        ai_stand, 0, NULL,
                    120:        ai_stand, 0, NULL
                    121: };
                    122: mmove_t        gunner_move_fidget = {FRAME_stand31, FRAME_stand70, gunner_frames_fidget, gunner_stand};
                    123: 
                    124: void gunner_fidget (edict_t *self)
                    125: {
                    126:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
                    127:                return;
                    128:        if (random() <= 0.05)
                    129:                self->monsterinfo.currentmove = &gunner_move_fidget;
                    130: }
                    131: 
                    132: mframe_t gunner_frames_stand [] =
                    133: {
                    134:        ai_stand, 0, NULL,
                    135:        ai_stand, 0, NULL,
                    136:        ai_stand, 0, NULL,
                    137:        ai_stand, 0, NULL,
                    138:        ai_stand, 0, NULL,
                    139:        ai_stand, 0, NULL,
                    140:        ai_stand, 0, NULL,
                    141:        ai_stand, 0, NULL,
                    142:        ai_stand, 0, NULL,
                    143:        ai_stand, 0, gunner_fidget,
                    144: 
                    145:        ai_stand, 0, NULL,
                    146:        ai_stand, 0, NULL,
                    147:        ai_stand, 0, NULL,
                    148:        ai_stand, 0, NULL,
                    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, gunner_fidget,
                    155: 
                    156:        ai_stand, 0, NULL,
                    157:        ai_stand, 0, NULL,
                    158:        ai_stand, 0, NULL,
                    159:        ai_stand, 0, NULL,
                    160:        ai_stand, 0, NULL,
                    161:        ai_stand, 0, NULL,
                    162:        ai_stand, 0, NULL,
                    163:        ai_stand, 0, NULL,
                    164:        ai_stand, 0, NULL,
                    165:        ai_stand, 0, gunner_fidget
                    166: };
                    167: mmove_t        gunner_move_stand = {FRAME_stand01, FRAME_stand30, gunner_frames_stand, NULL};
                    168: 
                    169: void gunner_stand (edict_t *self)
                    170: {
                    171:                self->monsterinfo.currentmove = &gunner_move_stand;
                    172: }
                    173: 
                    174: 
                    175: mframe_t gunner_frames_walk [] =
                    176: {
                    177:        ai_walk, 0, NULL,
                    178:        ai_walk, 3, NULL,
                    179:        ai_walk, 4, NULL,
                    180:        ai_walk, 5, NULL,
                    181:        ai_walk, 7, NULL,
                    182:        ai_walk, 2, NULL,
                    183:        ai_walk, 6, NULL,
                    184:        ai_walk, 4, NULL,
                    185:        ai_walk, 2, NULL,
                    186:        ai_walk, 7, NULL,
                    187:        ai_walk, 5, NULL,
                    188:        ai_walk, 7, NULL,
                    189:        ai_walk, 4, NULL
                    190: };
                    191: mmove_t gunner_move_walk = {FRAME_walk07, FRAME_walk19, gunner_frames_walk, NULL};
                    192: 
                    193: void gunner_walk (edict_t *self)
                    194: {
                    195:        self->monsterinfo.currentmove = &gunner_move_walk;
                    196: }
                    197: 
                    198: mframe_t gunner_frames_run [] =
                    199: {
                    200:        ai_run, 26, NULL,
                    201:        ai_run, 9,  NULL,
                    202:        ai_run, 9,  NULL,
                    203:        ai_run, 9,  NULL,
                    204:        ai_run, 15, NULL,
                    205:        ai_run, 10, NULL,
                    206:        ai_run, 13, NULL,
                    207:        ai_run, 6,  NULL
                    208: };
                    209: 
                    210: mmove_t gunner_move_run = {FRAME_run01, FRAME_run08, gunner_frames_run, NULL};
                    211: 
                    212: void gunner_run (edict_t *self)
                    213: {
                    214:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
                    215:                self->monsterinfo.currentmove = &gunner_move_stand;
                    216:        else
                    217:                self->monsterinfo.currentmove = &gunner_move_run;
                    218: }
                    219: 
                    220: mframe_t gunner_frames_runandshoot [] =
                    221: {
                    222:        ai_run, 32, NULL,
                    223:        ai_run, 15, NULL,
                    224:        ai_run, 10, NULL,
                    225:        ai_run, 18, NULL,
                    226:        ai_run, 8,  NULL,
                    227:        ai_run, 20, NULL
                    228: };
                    229: 
                    230: mmove_t gunner_move_runandshoot = {FRAME_runs01, FRAME_runs06, gunner_frames_runandshoot, NULL};
                    231: 
                    232: void gunner_runandshoot (edict_t *self)
                    233: {
                    234:        self->monsterinfo.currentmove = &gunner_move_runandshoot;
                    235: }
                    236: 
                    237: mframe_t gunner_frames_pain3 [] =
                    238: {
                    239:        ai_move, -3, NULL,
                    240:        ai_move, 1,      NULL,
                    241:        ai_move, 1,      NULL,
                    242:        ai_move, 0,      NULL,
                    243:        ai_move, 1,      NULL
                    244: };
                    245: mmove_t gunner_move_pain3 = {FRAME_pain301, FRAME_pain305, gunner_frames_pain3, gunner_run};
                    246: 
                    247: mframe_t gunner_frames_pain2 [] =
                    248: {
                    249:        ai_move, -2, NULL,
                    250:        ai_move, 11, NULL,
                    251:        ai_move, 6,      NULL,
                    252:        ai_move, 2,      NULL,
                    253:        ai_move, -1, NULL,
                    254:        ai_move, -7, NULL,
                    255:        ai_move, -2, NULL,
                    256:        ai_move, -7, NULL
                    257: };
                    258: mmove_t gunner_move_pain2 = {FRAME_pain201, FRAME_pain208, gunner_frames_pain2, gunner_run};
                    259: 
                    260: mframe_t gunner_frames_pain1 [] =
                    261: {
                    262:        ai_move, 2,      NULL,
                    263:        ai_move, 0,      NULL,
                    264:        ai_move, -5, NULL,
                    265:        ai_move, 3,      NULL,
                    266:        ai_move, -1, NULL,
                    267:        ai_move, 0,      NULL,
                    268:        ai_move, 0,      NULL,
                    269:        ai_move, 0,      NULL,
                    270:        ai_move, 0,      NULL,
                    271:        ai_move, 1,      NULL,
                    272:        ai_move, 1,      NULL,
                    273:        ai_move, 2,      NULL,
                    274:        ai_move, 1,      NULL,
                    275:        ai_move, 0,      NULL,
                    276:        ai_move, -2, NULL,
                    277:        ai_move, -2, NULL,
                    278:        ai_move, 0,      NULL,
                    279:        ai_move, 0,      NULL
                    280: };
                    281: mmove_t gunner_move_pain1 = {FRAME_pain101, FRAME_pain118, gunner_frames_pain1, gunner_run};
                    282: 
                    283: void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
                    284: {
                    285:        if (self->health < (self->max_health / 2))
                    286:                self->s.skinnum = 1;
                    287: 
                    288:        if (level.time < self->pain_debounce_time)
                    289:                return;
                    290: 
                    291:        self->pain_debounce_time = level.time + 3;
                    292: 
                    293:        if (rand()&1)
                    294:                gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
                    295:        else
                    296:                gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
                    297: 
                    298:        if (skill->value == 3)
                    299:                return;         // no pain anims in nightmare
                    300: 
                    301:        if (damage <= 10)
                    302:                self->monsterinfo.currentmove = &gunner_move_pain3;
                    303:        else if (damage <= 25)
                    304:                self->monsterinfo.currentmove = &gunner_move_pain2;
                    305:        else
                    306:                self->monsterinfo.currentmove = &gunner_move_pain1;
                    307: }
                    308: 
                    309: void gunner_dead (edict_t *self)
                    310: {
                    311:        VectorSet (self->mins, -16, -16, -24);
                    312:        VectorSet (self->maxs, 16, 16, -8);
                    313:        self->movetype = MOVETYPE_TOSS;
                    314:        self->svflags |= SVF_DEADMONSTER;
                    315:        self->nextthink = 0;
                    316:        gi.linkentity (self);
                    317: }
                    318: 
                    319: mframe_t gunner_frames_death [] =
                    320: {
                    321:        ai_move, 0,      NULL,
                    322:        ai_move, 0,      NULL,
                    323:        ai_move, 0,      NULL,
                    324:        ai_move, -7, NULL,
                    325:        ai_move, -3, NULL,
                    326:        ai_move, -5, NULL,
                    327:        ai_move, 8,      NULL,
                    328:        ai_move, 6,      NULL,
                    329:        ai_move, 0,      NULL,
                    330:        ai_move, 0,      NULL,
                    331:        ai_move, 0,      NULL
                    332: };
                    333: mmove_t gunner_move_death = {FRAME_death01, FRAME_death11, gunner_frames_death, gunner_dead};
                    334: 
                    335: void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
                    336: {
                    337:        int             n;
                    338: 
                    339: // check for gib
                    340:        if (self->health <= self->gib_health)
                    341:        {
                    342:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
                    343:                for (n= 0; n < 2; n++)
                    344:                        ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
                    345:                for (n= 0; n < 4; n++)
                    346:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
                    347:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
                    348:                self->deadflag = DEAD_DEAD;
                    349:                return;
                    350:        }
                    351: 
                    352:        if (self->deadflag == DEAD_DEAD)
                    353:                return;
                    354: 
                    355: // regular death
                    356:        gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
                    357:        self->deadflag = DEAD_DEAD;
                    358:        self->takedamage = DAMAGE_YES;
                    359:        self->monsterinfo.currentmove = &gunner_move_death;
                    360: }
                    361: 
                    362: 
                    363: void gunner_duck_down (edict_t *self)
                    364: {
                    365:        if (self->monsterinfo.aiflags & AI_DUCKED)
                    366:                return;
                    367:        self->monsterinfo.aiflags |= AI_DUCKED;
                    368:        if (skill->value >= 2)
                    369:        {
                    370:                if (random() > 0.5)
                    371:                        GunnerGrenade (self);
                    372:        }
                    373: 
                    374:        self->maxs[2] -= 32;
                    375:        self->takedamage = DAMAGE_YES;
                    376:        self->monsterinfo.pausetime = level.time + 1;
                    377:        gi.linkentity (self);
                    378: }
                    379: 
                    380: void gunner_duck_hold (edict_t *self)
                    381: {
                    382:        if (level.time >= self->monsterinfo.pausetime)
                    383:                self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
                    384:        else
                    385:                self->monsterinfo.aiflags |= AI_HOLD_FRAME;
                    386: }
                    387: 
                    388: void gunner_duck_up (edict_t *self)
                    389: {
                    390:        self->monsterinfo.aiflags &= ~AI_DUCKED;
                    391:        self->maxs[2] += 32;
                    392:        self->takedamage = DAMAGE_AIM;
                    393:        gi.linkentity (self);
                    394: }
                    395: 
                    396: mframe_t gunner_frames_duck [] =
                    397: {
                    398:        ai_move, 1,  gunner_duck_down,
                    399:        ai_move, 1,  NULL,
                    400:        ai_move, 1,  gunner_duck_hold,
                    401:        ai_move, 0,  NULL,
                    402:        ai_move, -1, NULL,
                    403:        ai_move, -1, NULL,
                    404:        ai_move, 0,  gunner_duck_up,
                    405:        ai_move, -1, NULL
                    406: };
                    407: mmove_t        gunner_move_duck = {FRAME_duck01, FRAME_duck08, gunner_frames_duck, gunner_run};
                    408: 
                    409: void gunner_dodge (edict_t *self, edict_t *attacker, float eta)
                    410: {
                    411:        if (random() > 0.25)
                    412:                return;
                    413: 
                    414:        if (!self->enemy)
                    415:                self->enemy = attacker;
                    416: 
                    417:        self->monsterinfo.currentmove = &gunner_move_duck;
                    418: }
                    419: 
                    420: 
                    421: void gunner_opengun (edict_t *self)
                    422: {
                    423:        gi.sound (self, CHAN_VOICE, sound_open, 1, ATTN_IDLE, 0);
                    424: }
                    425: 
                    426: void GunnerFire (edict_t *self)
                    427: {
                    428:        vec3_t  start;
                    429:        vec3_t  forward, right;
                    430:        vec3_t  target;
                    431:        vec3_t  aim;
                    432:        int             flash_number;
                    433: 
                    434:        flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216);
                    435: 
                    436:        AngleVectors (self->s.angles, forward, right, NULL);
                    437:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
                    438: 
                    439:        // project enemy back a bit and target there
                    440:        VectorCopy (self->enemy->s.origin, target);
                    441:        VectorMA (target, -0.2, self->enemy->velocity, target);
                    442:        target[2] += self->enemy->viewheight;
                    443: 
                    444:        VectorSubtract (target, start, aim);
                    445:        VectorNormalize (aim);
                    446:        monster_fire_bullet (self, start, aim, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
                    447: }
                    448: 
                    449: void GunnerGrenade (edict_t *self)
                    450: {
                    451:        vec3_t  start;
                    452:        vec3_t  forward, right;
                    453:        vec3_t  aim;
                    454:        int             flash_number;
                    455: 
                    456:        if (self->s.frame == FRAME_attak105)
                    457:                flash_number = MZ2_GUNNER_GRENADE_1;
                    458:        else if (self->s.frame == FRAME_attak108)
                    459:                flash_number = MZ2_GUNNER_GRENADE_2;
                    460:        else if (self->s.frame == FRAME_attak111)
                    461:                flash_number = MZ2_GUNNER_GRENADE_3;
                    462:        else // (self->s.frame == FRAME_attak114)
                    463:                flash_number = MZ2_GUNNER_GRENADE_4;
                    464: 
                    465:        AngleVectors (self->s.angles, forward, right, NULL);
                    466:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
                    467: 
                    468:        //FIXME : do a spread -225 -75 75 225 degrees around forward
                    469:        VectorCopy (forward, aim);
                    470: 
                    471:        monster_fire_grenade (self, start, aim, 50, 600, flash_number);
                    472: }
                    473: 
                    474: mframe_t gunner_frames_attack_chain [] =
                    475: {
                    476:        /*
                    477:        ai_charge, 0, NULL,
                    478:        ai_charge, 0, NULL,
                    479:        ai_charge, 0, NULL,
                    480:        ai_charge, 0, NULL,
                    481:        ai_charge, 0, NULL,
                    482:        ai_charge, 0, NULL,
                    483:        ai_charge, 0, NULL,
                    484:        ai_charge, 0, NULL,
                    485:        */
                    486:        ai_charge, 0, gunner_opengun,
                    487:        ai_charge, 0, NULL,
                    488:        ai_charge, 0, NULL,
                    489:        ai_charge, 0, NULL,
                    490:        ai_charge, 0, NULL,
                    491:        ai_charge, 0, NULL,
                    492:        ai_charge, 0, NULL
                    493: };
                    494: mmove_t gunner_move_attack_chain = {FRAME_attak209, FRAME_attak215, gunner_frames_attack_chain, gunner_fire_chain};
                    495: 
                    496: mframe_t gunner_frames_fire_chain [] =
                    497: {
                    498:        ai_charge,   0, GunnerFire,
                    499:        ai_charge,   0, GunnerFire,
                    500:        ai_charge,   0, GunnerFire,
                    501:        ai_charge,   0, GunnerFire,
                    502:        ai_charge,   0, GunnerFire,
                    503:        ai_charge,   0, GunnerFire,
                    504:        ai_charge,   0, GunnerFire,
                    505:        ai_charge,   0, GunnerFire
                    506: };
                    507: mmove_t gunner_move_fire_chain = {FRAME_attak216, FRAME_attak223, gunner_frames_fire_chain, gunner_refire_chain};
                    508: 
                    509: mframe_t gunner_frames_endfire_chain [] =
                    510: {
                    511:        ai_charge, 0, NULL,
                    512:        ai_charge, 0, NULL,
                    513:        ai_charge, 0, NULL,
                    514:        ai_charge, 0, NULL,
                    515:        ai_charge, 0, NULL,
                    516:        ai_charge, 0, NULL,
                    517:        ai_charge, 0, NULL
                    518: };
                    519: mmove_t gunner_move_endfire_chain = {FRAME_attak224, FRAME_attak230, gunner_frames_endfire_chain, gunner_run};
                    520: 
                    521: mframe_t gunner_frames_attack_grenade [] =
                    522: {
                    523:        ai_charge, 0, NULL,
                    524:        ai_charge, 0, NULL,
                    525:        ai_charge, 0, NULL,
                    526:        ai_charge, 0, NULL,
                    527:        ai_charge, 0, GunnerGrenade,
                    528:        ai_charge, 0, NULL,
                    529:        ai_charge, 0, NULL,
                    530:        ai_charge, 0, GunnerGrenade,
                    531:        ai_charge, 0, NULL,
                    532:        ai_charge, 0, NULL,
                    533:        ai_charge, 0, GunnerGrenade,
                    534:        ai_charge, 0, NULL,
                    535:        ai_charge, 0, NULL,
                    536:        ai_charge, 0, GunnerGrenade,
                    537:        ai_charge, 0, NULL,
                    538:        ai_charge, 0, NULL,
                    539:        ai_charge, 0, NULL,
                    540:        ai_charge, 0, NULL,
                    541:        ai_charge, 0, NULL,
                    542:        ai_charge, 0, NULL,
                    543:        ai_charge, 0, NULL
                    544: };
                    545: mmove_t gunner_move_attack_grenade = {FRAME_attak101, FRAME_attak121, gunner_frames_attack_grenade, gunner_run};
                    546: 
                    547: void gunner_attack(edict_t *self)
                    548: {
                    549:        if (range (self, self->enemy) == RANGE_MELEE)
                    550:        {
                    551:                self->monsterinfo.currentmove = &gunner_move_attack_chain;
                    552:        }
                    553:        else
                    554:        {
                    555:                if (random() <= 0.5)
                    556:                        self->monsterinfo.currentmove = &gunner_move_attack_grenade;
                    557:                else
                    558:                        self->monsterinfo.currentmove = &gunner_move_attack_chain;
                    559:        }
                    560: }
                    561: 
                    562: void gunner_fire_chain(edict_t *self)
                    563: {
                    564:        self->monsterinfo.currentmove = &gunner_move_fire_chain;
                    565: }
                    566: 
                    567: void gunner_refire_chain(edict_t *self)
                    568: {
                    569:        if (self->enemy->health > 0)
                    570:                if ( visible (self, self->enemy) )
                    571:                        if (random() <= 0.5)
                    572:                        {
                    573:                                self->monsterinfo.currentmove = &gunner_move_fire_chain;
                    574:                                return;
                    575:                        }
                    576:        self->monsterinfo.currentmove = &gunner_move_endfire_chain;
                    577: }
                    578: 
                    579: /*QUAKED monster_gunner (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
                    580: */
                    581: void SP_monster_gunner (edict_t *self)
                    582: {
                    583:        if (deathmatch->value)
                    584:        {
                    585:                G_FreeEdict (self);
                    586:                return;
                    587:        }
                    588: 
                    589:        sound_death = gi.soundindex ("gunner/death1.wav");      
                    590:        sound_pain = gi.soundindex ("gunner/gunpain2.wav");     
                    591:        sound_pain2 = gi.soundindex ("gunner/gunpain1.wav");    
                    592:        sound_idle = gi.soundindex ("gunner/gunidle1.wav");     
                    593:        sound_open = gi.soundindex ("gunner/gunatck1.wav");     
                    594:        sound_search = gi.soundindex ("gunner/gunsrch1.wav");   
                    595:        sound_sight = gi.soundindex ("gunner/sight1.wav");      
                    596: 
                    597:        gi.soundindex ("gunner/gunatck2.wav");
                    598:        gi.soundindex ("gunner/gunatck3.wav");
                    599: 
                    600:        self->movetype = MOVETYPE_STEP;
                    601:        self->solid = SOLID_BBOX;
                    602:        self->s.modelindex = gi.modelindex ("models/monsters/gunner/tris.md2");
                    603:        VectorSet (self->mins, -16, -16, -24);
                    604:        VectorSet (self->maxs, 16, 16, 32);
                    605: 
                    606:        self->health = 175;
                    607:        self->gib_health = -70;
                    608:        self->mass = 200;
                    609: 
                    610:        self->pain = gunner_pain;
                    611:        self->die = gunner_die;
                    612: 
                    613:        self->monsterinfo.stand = gunner_stand;
                    614:        self->monsterinfo.walk = gunner_walk;
                    615:        self->monsterinfo.run = gunner_run;
                    616:        self->monsterinfo.dodge = gunner_dodge;
                    617:        self->monsterinfo.attack = gunner_attack;
                    618:        self->monsterinfo.melee = NULL;
                    619:        self->monsterinfo.sight = gunner_sight;
                    620:        self->monsterinfo.search = gunner_search;
                    621: 
                    622:        gi.linkentity (self);
                    623: 
                    624:        self->monsterinfo.currentmove = &gunner_move_stand;     
                    625:        self->monsterinfo.scale = MODEL_SCALE;
                    626: 
                    627:        walkmonster_start (self);
                    628: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.