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

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

unix.superglobalmegacorp.com

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