Annotation of quake2/xatrix/m_soldier.c, revision 1.1

1.1     ! root        1: /*
        !             2: ==============================================================================
        !             3: 
        !             4: SOLDIER
        !             5: 
        !             6: ==============================================================================
        !             7: */
        !             8: 
        !             9: #include "g_local.h"
        !            10: #include "m_soldier.h"
        !            11: 
        !            12: 
        !            13: static int     sound_idle;
        !            14: static int     sound_sight1;
        !            15: static int     sound_sight2;
        !            16: static int     sound_pain_light;
        !            17: static int     sound_pain;
        !            18: static int     sound_pain_ss;
        !            19: static int     sound_death_light;
        !            20: static int     sound_death;
        !            21: static int     sound_death_ss;
        !            22: static int     sound_cock;
        !            23: 
        !            24: 
        !            25: void soldier_idle (edict_t *self)
        !            26: {
        !            27:        if (random() > 0.8)
        !            28:                gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
        !            29: }
        !            30: 
        !            31: void soldier_cock (edict_t *self)
        !            32: {
        !            33:        if (self->s.frame == FRAME_stand322)
        !            34:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
        !            35:        else
        !            36:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
        !            37: }
        !            38: 
        !            39: 
        !            40: // STAND
        !            41: 
        !            42: void soldier_stand (edict_t *self);
        !            43: 
        !            44: mframe_t soldier_frames_stand1 [] =
        !            45: {
        !            46:        ai_stand, 0, soldier_idle,
        !            47:        ai_stand, 0, NULL,
        !            48:        ai_stand, 0, NULL,
        !            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: 
        !            57:        ai_stand, 0, NULL,
        !            58:        ai_stand, 0, NULL,
        !            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: 
        !            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, NULL,
        !            76:        ai_stand, 0, NULL,
        !            77:        ai_stand, 0, NULL
        !            78: };
        !            79: mmove_t soldier_move_stand1 = {FRAME_stand101, FRAME_stand130, soldier_frames_stand1, soldier_stand};
        !            80: 
        !            81: mframe_t soldier_frames_stand3 [] =
        !            82: {
        !            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: 
        !            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: 
        !           105:        ai_stand, 0, NULL,
        !           106:        ai_stand, 0, soldier_cock,
        !           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:        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, NULL
        !           125: };
        !           126: mmove_t soldier_move_stand3 = {FRAME_stand301, FRAME_stand339, soldier_frames_stand3, soldier_stand};
        !           127: 
        !           128: #if 0
        !           129: mframe_t soldier_frames_stand4 [] =
        !           130: {
        !           131:        ai_stand, 0, NULL,
        !           132:        ai_stand, 0, NULL,
        !           133:        ai_stand, 0, NULL,
        !           134:        ai_stand, 0, NULL,
        !           135:        ai_stand, 0, NULL,
        !           136:        ai_stand, 0, NULL,
        !           137:        ai_stand, 0, NULL,
        !           138:        ai_stand, 0, NULL,
        !           139:        ai_stand, 0, NULL,
        !           140:        ai_stand, 0, NULL,
        !           141: 
        !           142:        ai_stand, 0, NULL,
        !           143:        ai_stand, 0, NULL,
        !           144:        ai_stand, 0, NULL,
        !           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: 
        !           153:        ai_stand, 0, NULL,
        !           154:        ai_stand, 0, NULL,
        !           155:        ai_stand, 0, NULL,
        !           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: 
        !           164:        ai_stand, 0, NULL,
        !           165:        ai_stand, 0, NULL,
        !           166:        ai_stand, 0, NULL,
        !           167:        ai_stand, 0, NULL,
        !           168:        ai_stand, 0, NULL,
        !           169:        ai_stand, 0, NULL,
        !           170:        ai_stand, 0, NULL,
        !           171:        ai_stand, 0, NULL,
        !           172:        ai_stand, 0, NULL,
        !           173:        ai_stand, 0, NULL,
        !           174: 
        !           175:        ai_stand, 0, NULL,
        !           176:        ai_stand, 0, NULL,
        !           177:        ai_stand, 0, NULL,
        !           178:        ai_stand, 0, NULL,
        !           179:        ai_stand, 0, NULL,
        !           180:        ai_stand, 0, NULL,
        !           181:        ai_stand, 4, NULL,
        !           182:        ai_stand, 1, NULL,
        !           183:        ai_stand, -1, NULL,
        !           184:        ai_stand, -2, NULL,
        !           185: 
        !           186:        ai_stand, 0, NULL,
        !           187:        ai_stand, 0, NULL
        !           188: };
        !           189: mmove_t soldier_move_stand4 = {FRAME_stand401, FRAME_stand452, soldier_frames_stand4, NULL};
        !           190: #endif
        !           191: 
        !           192: void soldier_stand (edict_t *self)
        !           193: {
        !           194:        if ((self->monsterinfo.currentmove == &soldier_move_stand3) || (random() < 0.8))
        !           195:                self->monsterinfo.currentmove = &soldier_move_stand1;
        !           196:        else
        !           197:                self->monsterinfo.currentmove = &soldier_move_stand3;
        !           198: }
        !           199: 
        !           200: 
        !           201: //
        !           202: // WALK
        !           203: //
        !           204: 
        !           205: void soldier_walk1_random (edict_t *self)
        !           206: {
        !           207:        if (random() > 0.1)
        !           208:                self->monsterinfo.nextframe = FRAME_walk101;
        !           209: }
        !           210: 
        !           211: mframe_t soldier_frames_walk1 [] =
        !           212: {
        !           213:        ai_walk, 3,  NULL,
        !           214:        ai_walk, 6,  NULL,
        !           215:        ai_walk, 2,  NULL,
        !           216:        ai_walk, 2,  NULL,
        !           217:        ai_walk, 2,  NULL,
        !           218:        ai_walk, 1,  NULL,
        !           219:        ai_walk, 6,  NULL,
        !           220:        ai_walk, 5,  NULL,
        !           221:        ai_walk, 3,  NULL,
        !           222:        ai_walk, -1, soldier_walk1_random,
        !           223:        ai_walk, 0,  NULL,
        !           224:        ai_walk, 0,  NULL,
        !           225:        ai_walk, 0,  NULL,
        !           226:        ai_walk, 0,  NULL,
        !           227:        ai_walk, 0,  NULL,
        !           228:        ai_walk, 0,  NULL,
        !           229:        ai_walk, 0,  NULL,
        !           230:        ai_walk, 0,  NULL,
        !           231:        ai_walk, 0,  NULL,
        !           232:        ai_walk, 0,  NULL,
        !           233:        ai_walk, 0,  NULL,
        !           234:        ai_walk, 0,  NULL,
        !           235:        ai_walk, 0,  NULL,
        !           236:        ai_walk, 0,  NULL,
        !           237:        ai_walk, 0,  NULL,
        !           238:        ai_walk, 0,  NULL,
        !           239:        ai_walk, 0,  NULL,
        !           240:        ai_walk, 0,  NULL,
        !           241:        ai_walk, 0,  NULL,
        !           242:        ai_walk, 0,  NULL,
        !           243:        ai_walk, 0,  NULL,
        !           244:        ai_walk, 0,  NULL,
        !           245:        ai_walk, 0,  NULL
        !           246: };
        !           247: mmove_t soldier_move_walk1 = {FRAME_walk101, FRAME_walk133, soldier_frames_walk1, NULL};
        !           248: 
        !           249: mframe_t soldier_frames_walk2 [] =
        !           250: {
        !           251:        ai_walk, 4,  NULL,
        !           252:        ai_walk, 4,  NULL,
        !           253:        ai_walk, 9,  NULL,
        !           254:        ai_walk, 8,  NULL,
        !           255:        ai_walk, 5,  NULL,
        !           256:        ai_walk, 1,  NULL,
        !           257:        ai_walk, 3,  NULL,
        !           258:        ai_walk, 7,  NULL,
        !           259:        ai_walk, 6,  NULL,
        !           260:        ai_walk, 7,  NULL
        !           261: };
        !           262: mmove_t soldier_move_walk2 = {FRAME_walk209, FRAME_walk218, soldier_frames_walk2, NULL};
        !           263: 
        !           264: void soldier_walk (edict_t *self)
        !           265: {
        !           266:        if (random() < 0.5)
        !           267:                self->monsterinfo.currentmove = &soldier_move_walk1;
        !           268:        else
        !           269:                self->monsterinfo.currentmove = &soldier_move_walk2;
        !           270: }
        !           271: 
        !           272: 
        !           273: //
        !           274: // RUN
        !           275: //
        !           276: 
        !           277: void soldier_run (edict_t *self);
        !           278: 
        !           279: mframe_t soldier_frames_start_run [] =
        !           280: {
        !           281:        ai_run, 7,  NULL,
        !           282:        ai_run, 5,  NULL
        !           283: };
        !           284: mmove_t soldier_move_start_run = {FRAME_run01, FRAME_run02, soldier_frames_start_run, soldier_run};
        !           285: 
        !           286: mframe_t soldier_frames_run [] =
        !           287: {
        !           288:        ai_run, 10, NULL,
        !           289:        ai_run, 11, NULL,
        !           290:        ai_run, 11, NULL,
        !           291:        ai_run, 16, NULL,
        !           292:        ai_run, 10, NULL,
        !           293:        ai_run, 15, NULL
        !           294: };
        !           295: mmove_t soldier_move_run = {FRAME_run03, FRAME_run08, soldier_frames_run, NULL};
        !           296: 
        !           297: void soldier_run (edict_t *self)
        !           298: {
        !           299:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
        !           300:        {
        !           301:                self->monsterinfo.currentmove = &soldier_move_stand1;
        !           302:                return;
        !           303:        }
        !           304: 
        !           305:        if (self->monsterinfo.currentmove == &soldier_move_walk1 ||
        !           306:                self->monsterinfo.currentmove == &soldier_move_walk2 ||
        !           307:                self->monsterinfo.currentmove == &soldier_move_start_run)
        !           308:        {
        !           309:                self->monsterinfo.currentmove = &soldier_move_run;
        !           310:        }
        !           311:        else
        !           312:        {
        !           313:                self->monsterinfo.currentmove = &soldier_move_start_run;
        !           314:        }
        !           315: }
        !           316: 
        !           317: 
        !           318: //
        !           319: // PAIN
        !           320: //
        !           321: 
        !           322: mframe_t soldier_frames_pain1 [] =
        !           323: {
        !           324:        ai_move, -3, NULL,
        !           325:        ai_move, 4,  NULL,
        !           326:        ai_move, 1,  NULL,
        !           327:        ai_move, 1,  NULL,
        !           328:        ai_move, 0,  NULL
        !           329: };
        !           330: mmove_t soldier_move_pain1 = {FRAME_pain101, FRAME_pain105, soldier_frames_pain1, soldier_run};
        !           331: 
        !           332: mframe_t soldier_frames_pain2 [] =
        !           333: {
        !           334:        ai_move, -13, NULL,
        !           335:        ai_move, -1,  NULL,
        !           336:        ai_move, 2,   NULL,
        !           337:        ai_move, 4,   NULL,
        !           338:        ai_move, 2,   NULL,
        !           339:        ai_move, 3,   NULL,
        !           340:        ai_move, 2,   NULL
        !           341: };
        !           342: mmove_t soldier_move_pain2 = {FRAME_pain201, FRAME_pain207, soldier_frames_pain2, soldier_run};
        !           343: 
        !           344: mframe_t soldier_frames_pain3 [] =
        !           345: {
        !           346:        ai_move, -8, NULL,
        !           347:        ai_move, 10, NULL,
        !           348:        ai_move, -4, NULL,
        !           349:        ai_move, -1, NULL,
        !           350:        ai_move, -3, NULL,
        !           351:        ai_move, 0,  NULL,
        !           352:        ai_move, 3,  NULL,
        !           353:        ai_move, 0,  NULL,
        !           354:        ai_move, 0,  NULL,
        !           355:        ai_move, 0,  NULL,
        !           356:        ai_move, 0,  NULL,
        !           357:        ai_move, 1,  NULL,
        !           358:        ai_move, 0,  NULL,
        !           359:        ai_move, 1,  NULL,
        !           360:        ai_move, 2,  NULL,
        !           361:        ai_move, 4,  NULL,
        !           362:        ai_move, 3,  NULL,
        !           363:        ai_move, 2,  NULL
        !           364: };
        !           365: mmove_t soldier_move_pain3 = {FRAME_pain301, FRAME_pain318, soldier_frames_pain3, soldier_run};
        !           366: 
        !           367: mframe_t soldier_frames_pain4 [] =
        !           368: {
        !           369:        ai_move, 0,   NULL,
        !           370:        ai_move, 0,   NULL,
        !           371:        ai_move, 0,   NULL,
        !           372:        ai_move, -10, NULL,
        !           373:        ai_move, -6,  NULL,
        !           374:        ai_move, 8,   NULL,
        !           375:        ai_move, 4,   NULL,
        !           376:        ai_move, 1,   NULL,
        !           377:        ai_move, 0,   NULL,
        !           378:        ai_move, 2,   NULL,
        !           379:        ai_move, 5,   NULL,
        !           380:        ai_move, 2,   NULL,
        !           381:        ai_move, -1,  NULL,
        !           382:        ai_move, -1,  NULL,
        !           383:        ai_move, 3,   NULL,
        !           384:        ai_move, 2,   NULL,
        !           385:        ai_move, 0,   NULL
        !           386: };
        !           387: mmove_t soldier_move_pain4 = {FRAME_pain401, FRAME_pain417, soldier_frames_pain4, soldier_run};
        !           388: 
        !           389: 
        !           390: void soldier_pain (edict_t *self, edict_t *other, float kick, int damage)
        !           391: {
        !           392:        float   r;
        !           393:        int             n;
        !           394: 
        !           395:        if (self->health < (self->max_health / 2))
        !           396:                        self->s.skinnum |= 1;
        !           397: 
        !           398:        if (level.time < self->pain_debounce_time)
        !           399:        {
        !           400:                if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldier_move_pain1) || (self->monsterinfo.currentmove == &soldier_move_pain2) || (self->monsterinfo.currentmove == &soldier_move_pain3)))
        !           401:                        self->monsterinfo.currentmove = &soldier_move_pain4;
        !           402:                return;
        !           403:        }
        !           404: 
        !           405:        self->pain_debounce_time = level.time + 3;
        !           406: 
        !           407:        n = self->s.skinnum | 1;
        !           408:        if (n == 1)
        !           409:                gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
        !           410:        else if (n == 3)
        !           411:                gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
        !           412:        else
        !           413:                gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
        !           414: 
        !           415:        if (self->velocity[2] > 100)
        !           416:        {
        !           417:                self->monsterinfo.currentmove = &soldier_move_pain4;
        !           418:                return;
        !           419:        }
        !           420: 
        !           421:        if (skill->value == 3)
        !           422:                return;         // no pain anims in nightmare
        !           423: 
        !           424:        r = random();
        !           425: 
        !           426:        if (r < 0.33)
        !           427:                self->monsterinfo.currentmove = &soldier_move_pain1;
        !           428:        else if (r < 0.66)
        !           429:                self->monsterinfo.currentmove = &soldier_move_pain2;
        !           430:        else
        !           431:                self->monsterinfo.currentmove = &soldier_move_pain3;
        !           432: }
        !           433: 
        !           434: 
        !           435: //
        !           436: // ATTACK
        !           437: //
        !           438: 
        !           439: static int blaster_flash [] = {MZ2_SOLDIER_BLASTER_1, MZ2_SOLDIER_BLASTER_2, MZ2_SOLDIER_BLASTER_3, MZ2_SOLDIER_BLASTER_4, MZ2_SOLDIER_BLASTER_5, MZ2_SOLDIER_BLASTER_6, MZ2_SOLDIER_BLASTER_7, MZ2_SOLDIER_BLASTER_8};
        !           440: static int shotgun_flash [] = {MZ2_SOLDIER_SHOTGUN_1, MZ2_SOLDIER_SHOTGUN_2, MZ2_SOLDIER_SHOTGUN_3, MZ2_SOLDIER_SHOTGUN_4, MZ2_SOLDIER_SHOTGUN_5, MZ2_SOLDIER_SHOTGUN_6, MZ2_SOLDIER_SHOTGUN_7, MZ2_SOLDIER_SHOTGUN_8};
        !           441: static int machinegun_flash [] = {MZ2_SOLDIER_MACHINEGUN_1, MZ2_SOLDIER_MACHINEGUN_2, MZ2_SOLDIER_MACHINEGUN_3, MZ2_SOLDIER_MACHINEGUN_4, MZ2_SOLDIER_MACHINEGUN_5, MZ2_SOLDIER_MACHINEGUN_6, MZ2_SOLDIER_MACHINEGUN_7, MZ2_SOLDIER_MACHINEGUN_8};
        !           442: 
        !           443: void soldier_fire (edict_t *self, int flash_number)
        !           444: {
        !           445:        vec3_t  start;
        !           446:        vec3_t  forward, right, up;
        !           447:        vec3_t  aim;
        !           448:        vec3_t  dir;
        !           449:        vec3_t  end;
        !           450:        float   r, u;
        !           451:        int             flash_index;
        !           452: 
        !           453:        if (self->s.skinnum < 2)
        !           454:                flash_index = blaster_flash[flash_number];
        !           455:        else if (self->s.skinnum < 4)
        !           456:                flash_index = shotgun_flash[flash_number];
        !           457:        else
        !           458:                flash_index = machinegun_flash[flash_number];
        !           459: 
        !           460:        AngleVectors (self->s.angles, forward, right, NULL);
        !           461:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
        !           462: 
        !           463:        if (flash_number == 5 || flash_number == 6)
        !           464:        {
        !           465:                VectorCopy (forward, aim);
        !           466:        }
        !           467:        else
        !           468:        {
        !           469:                VectorCopy (self->enemy->s.origin, end);
        !           470:                end[2] += self->enemy->viewheight;
        !           471:                VectorSubtract (end, start, aim);
        !           472:                vectoangles (aim, dir);
        !           473:                AngleVectors (dir, forward, right, up);
        !           474: 
        !           475:                r = crandom()*1000;
        !           476:                u = crandom()*500;
        !           477:                VectorMA (start, 8192, forward, end);
        !           478:                VectorMA (end, r, right, end);
        !           479:                VectorMA (end, u, up, end);
        !           480: 
        !           481:                VectorSubtract (end, start, aim);
        !           482:                VectorNormalize (aim);
        !           483:        }
        !           484: 
        !           485:        if (self->s.skinnum <= 1)
        !           486:        {
        !           487:                monster_fire_blaster (self, start, aim, 5, 600, flash_index, EF_BLASTER);
        !           488:        }
        !           489:        else if (self->s.skinnum <= 3)
        !           490:        {
        !           491:                monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index);
        !           492:        }
        !           493:        else
        !           494:        {
        !           495:                if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
        !           496:                        self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
        !           497: 
        !           498:                monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);
        !           499: 
        !           500:                if (level.time >= self->monsterinfo.pausetime)
        !           501:                        self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
        !           502:                else
        !           503:                        self->monsterinfo.aiflags |= AI_HOLD_FRAME;
        !           504:        }
        !           505: }
        !           506: 
        !           507: // ATTACK1 (blaster/shotgun)
        !           508: 
        !           509: void soldier_fire1 (edict_t *self)
        !           510: {
        !           511:        soldier_fire (self, 0);
        !           512: }
        !           513: 
        !           514: void soldier_attack1_refire1 (edict_t *self)
        !           515: {
        !           516:        if (self->s.skinnum > 1)
        !           517:                return;
        !           518: 
        !           519:        if (self->enemy->health <= 0)
        !           520:                return;
        !           521: 
        !           522:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           523:                self->monsterinfo.nextframe = FRAME_attak102;
        !           524:        else
        !           525:                self->monsterinfo.nextframe = FRAME_attak110;
        !           526: }
        !           527: 
        !           528: void soldier_attack1_refire2 (edict_t *self)
        !           529: {
        !           530:        if (self->s.skinnum < 2)
        !           531:                return;
        !           532: 
        !           533:        if (self->enemy->health <= 0)
        !           534:                return;
        !           535: 
        !           536:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           537:                self->monsterinfo.nextframe = FRAME_attak102;
        !           538: }
        !           539: 
        !           540: mframe_t soldier_frames_attack1 [] =
        !           541: {
        !           542:        ai_charge, 0,  NULL,
        !           543:        ai_charge, 0,  NULL,
        !           544:        ai_charge, 0,  soldier_fire1,
        !           545:        ai_charge, 0,  NULL,
        !           546:        ai_charge, 0,  NULL,
        !           547:        ai_charge, 0,  soldier_attack1_refire1,
        !           548:        ai_charge, 0,  NULL,
        !           549:        ai_charge, 0,  soldier_cock,
        !           550:        ai_charge, 0,  soldier_attack1_refire2,
        !           551:        ai_charge, 0,  NULL,
        !           552:        ai_charge, 0,  NULL,
        !           553:        ai_charge, 0,  NULL
        !           554: };
        !           555: mmove_t soldier_move_attack1 = {FRAME_attak101, FRAME_attak112, soldier_frames_attack1, soldier_run};
        !           556: 
        !           557: // ATTACK2 (blaster/shotgun)
        !           558: 
        !           559: void soldier_fire2 (edict_t *self)
        !           560: {
        !           561:        soldier_fire (self, 1);
        !           562: }
        !           563: 
        !           564: void soldier_attack2_refire1 (edict_t *self)
        !           565: {
        !           566:        if (self->s.skinnum > 1)
        !           567:                return;
        !           568: 
        !           569:        if (self->enemy->health <= 0)
        !           570:                return;
        !           571: 
        !           572:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           573:                self->monsterinfo.nextframe = FRAME_attak204;
        !           574:        else
        !           575:                self->monsterinfo.nextframe = FRAME_attak216;
        !           576: }
        !           577: 
        !           578: void soldier_attack2_refire2 (edict_t *self)
        !           579: {
        !           580:        if (self->s.skinnum < 2)
        !           581:                return;
        !           582: 
        !           583:        if (self->enemy->health <= 0)
        !           584:                return;
        !           585: 
        !           586:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           587:                self->monsterinfo.nextframe = FRAME_attak204;
        !           588: }
        !           589: 
        !           590: mframe_t soldier_frames_attack2 [] =
        !           591: {
        !           592:        ai_charge, 0, NULL,
        !           593:        ai_charge, 0, NULL,
        !           594:        ai_charge, 0, NULL,
        !           595:        ai_charge, 0, NULL,
        !           596:        ai_charge, 0, soldier_fire2,
        !           597:        ai_charge, 0, NULL,
        !           598:        ai_charge, 0, NULL,
        !           599:        ai_charge, 0, soldier_attack2_refire1,
        !           600:        ai_charge, 0, NULL,
        !           601:        ai_charge, 0, NULL,
        !           602:        ai_charge, 0, NULL,
        !           603:        ai_charge, 0, NULL,
        !           604:        ai_charge, 0, soldier_cock,
        !           605:        ai_charge, 0, NULL,
        !           606:        ai_charge, 0, soldier_attack2_refire2,
        !           607:        ai_charge, 0, NULL,
        !           608:        ai_charge, 0, NULL,
        !           609:        ai_charge, 0, NULL
        !           610: };
        !           611: mmove_t soldier_move_attack2 = {FRAME_attak201, FRAME_attak218, soldier_frames_attack2, soldier_run};
        !           612: 
        !           613: // ATTACK3 (duck and shoot)
        !           614: 
        !           615: void soldier_duck_down (edict_t *self)
        !           616: {
        !           617:        if (self->monsterinfo.aiflags & AI_DUCKED)
        !           618:                return;
        !           619:        self->monsterinfo.aiflags |= AI_DUCKED;
        !           620:        self->maxs[2] -= 32;
        !           621:        self->takedamage = DAMAGE_YES;
        !           622:        self->monsterinfo.pausetime = level.time + 1;
        !           623:        gi.linkentity (self);
        !           624: }
        !           625: 
        !           626: void soldier_duck_up (edict_t *self)
        !           627: {
        !           628:        self->monsterinfo.aiflags &= ~AI_DUCKED;
        !           629:        self->maxs[2] += 32;
        !           630:        self->takedamage = DAMAGE_AIM;
        !           631:        gi.linkentity (self);
        !           632: }
        !           633: 
        !           634: void soldier_fire3 (edict_t *self)
        !           635: {
        !           636:        soldier_duck_down (self);
        !           637:        soldier_fire (self, 2);
        !           638: }
        !           639: 
        !           640: void soldier_attack3_refire (edict_t *self)
        !           641: {
        !           642:        if ((level.time + 0.4) < self->monsterinfo.pausetime)
        !           643:                self->monsterinfo.nextframe = FRAME_attak303;
        !           644: }
        !           645: 
        !           646: mframe_t soldier_frames_attack3 [] =
        !           647: {
        !           648:        ai_charge, 0, NULL,
        !           649:        ai_charge, 0, NULL,
        !           650:        ai_charge, 0, soldier_fire3,
        !           651:        ai_charge, 0, NULL,
        !           652:        ai_charge, 0, NULL,
        !           653:        ai_charge, 0, soldier_attack3_refire,
        !           654:        ai_charge, 0, soldier_duck_up,
        !           655:        ai_charge, 0, NULL,
        !           656:        ai_charge, 0, NULL
        !           657: };
        !           658: mmove_t soldier_move_attack3 = {FRAME_attak301, FRAME_attak309, soldier_frames_attack3, soldier_run};
        !           659: 
        !           660: // ATTACK4 (machinegun)
        !           661: 
        !           662: void soldier_fire4 (edict_t *self)
        !           663: {
        !           664:        soldier_fire (self, 3);
        !           665: //
        !           666: //     if (self->enemy->health <= 0)
        !           667: //             return;
        !           668: //
        !           669: //     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           670: //             self->monsterinfo.nextframe = FRAME_attak402;
        !           671: }
        !           672: 
        !           673: mframe_t soldier_frames_attack4 [] =
        !           674: {
        !           675:        ai_charge, 0, NULL,
        !           676:        ai_charge, 0, NULL,
        !           677:        ai_charge, 0, soldier_fire4,
        !           678:        ai_charge, 0, NULL,
        !           679:        ai_charge, 0, NULL,
        !           680:        ai_charge, 0, NULL
        !           681: };
        !           682: mmove_t soldier_move_attack4 = {FRAME_attak401, FRAME_attak406, soldier_frames_attack4, soldier_run};
        !           683: 
        !           684: #if 0
        !           685: // ATTACK5 (prone)
        !           686: 
        !           687: void soldier_fire5 (edict_t *self)
        !           688: {
        !           689:        soldier_fire (self, 4);
        !           690: }
        !           691: 
        !           692: void soldier_attack5_refire (edict_t *self)
        !           693: {
        !           694:        if (self->enemy->health <= 0)
        !           695:                return;
        !           696: 
        !           697:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !           698:                self->monsterinfo.nextframe = FRAME_attak505;
        !           699: }
        !           700: 
        !           701: mframe_t soldier_frames_attack5 [] =
        !           702: {
        !           703:        ai_charge, 8, NULL,
        !           704:        ai_charge, 8, NULL,
        !           705:        ai_charge, 0, NULL,
        !           706:        ai_charge, 0, NULL,
        !           707:        ai_charge, 0, soldier_fire5,
        !           708:        ai_charge, 0, NULL,
        !           709:        ai_charge, 0, NULL,
        !           710:        ai_charge, 0, soldier_attack5_refire
        !           711: };
        !           712: mmove_t soldier_move_attack5 = {FRAME_attak501, FRAME_attak508, soldier_frames_attack5, soldier_run};
        !           713: #endif
        !           714: 
        !           715: // ATTACK6 (run & shoot)
        !           716: 
        !           717: void soldier_fire8 (edict_t *self)
        !           718: {
        !           719:        soldier_fire (self, 7);
        !           720: }
        !           721: 
        !           722: void soldier_attack6_refire (edict_t *self)
        !           723: {
        !           724:        if (self->enemy->health <= 0)
        !           725:                return;
        !           726: 
        !           727:        if (range(self, self->enemy) < RANGE_MID)
        !           728:                return;
        !           729: 
        !           730:        if (skill->value == 3)
        !           731:                self->monsterinfo.nextframe = FRAME_runs03;
        !           732: }
        !           733: 
        !           734: mframe_t soldier_frames_attack6 [] =
        !           735: {
        !           736:        ai_charge, 10, NULL,
        !           737:        ai_charge,  4, NULL,
        !           738:        ai_charge, 12, NULL,
        !           739:        ai_charge, 11, soldier_fire8,
        !           740:        ai_charge, 13, NULL,
        !           741:        ai_charge, 18, NULL,
        !           742:        ai_charge, 15, NULL,
        !           743:        ai_charge, 14, NULL,
        !           744:        ai_charge, 11, NULL,
        !           745:        ai_charge,  8, NULL,
        !           746:        ai_charge, 11, NULL,
        !           747:        ai_charge, 12, NULL,
        !           748:        ai_charge, 12, NULL,
        !           749:        ai_charge, 17, soldier_attack6_refire
        !           750: };
        !           751: mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attack6, soldier_run};
        !           752: 
        !           753: void soldier_attack(edict_t *self)
        !           754: {
        !           755:        if (self->s.skinnum < 4)
        !           756:        {
        !           757:                if (random() < 0.5)
        !           758:                        self->monsterinfo.currentmove = &soldier_move_attack1;
        !           759:                else
        !           760:                        self->monsterinfo.currentmove = &soldier_move_attack2;
        !           761:        }
        !           762:        else
        !           763:        {
        !           764:                self->monsterinfo.currentmove = &soldier_move_attack4;
        !           765:        }
        !           766: }
        !           767: 
        !           768: 
        !           769: //
        !           770: // SIGHT
        !           771: //
        !           772: 
        !           773: void soldier_sight(edict_t *self, edict_t *other)
        !           774: {
        !           775:        if (random() < 0.5)
        !           776:                gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
        !           777:        else
        !           778:                gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
        !           779: 
        !           780:        if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
        !           781:        {
        !           782:                if (random() > 0.5)
        !           783:                        self->monsterinfo.currentmove = &soldier_move_attack6;
        !           784:        }
        !           785: }
        !           786: 
        !           787: //
        !           788: // DUCK
        !           789: //
        !           790: 
        !           791: void soldier_duck_hold (edict_t *self)
        !           792: {
        !           793:        if (level.time >= self->monsterinfo.pausetime)
        !           794:                self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
        !           795:        else
        !           796:                self->monsterinfo.aiflags |= AI_HOLD_FRAME;
        !           797: }
        !           798: 
        !           799: mframe_t soldier_frames_duck [] =
        !           800: {
        !           801:        ai_move, 5, soldier_duck_down,
        !           802:        ai_move, -1, soldier_duck_hold,
        !           803:        ai_move, 1,  NULL,
        !           804:        ai_move, 0,  soldier_duck_up,
        !           805:        ai_move, 5,  NULL
        !           806: };
        !           807: mmove_t soldier_move_duck = {FRAME_duck01, FRAME_duck05, soldier_frames_duck, soldier_run};
        !           808: 
        !           809: void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
        !           810: {
        !           811:        float   r;
        !           812: 
        !           813:        r = random();
        !           814:        if (r > 0.25)
        !           815:                return;
        !           816: 
        !           817:        if (!self->enemy)
        !           818:                self->enemy = attacker;
        !           819: 
        !           820:        if (skill->value == 0)
        !           821:        {
        !           822:                self->monsterinfo.currentmove = &soldier_move_duck;
        !           823:                return;
        !           824:        }
        !           825: 
        !           826:        self->monsterinfo.pausetime = level.time + eta + 0.3;
        !           827:        r = random();
        !           828: 
        !           829:        if (skill->value == 1)
        !           830:        {
        !           831:                if (r > 0.33)
        !           832:                        self->monsterinfo.currentmove = &soldier_move_duck;
        !           833:                else
        !           834:                        self->monsterinfo.currentmove = &soldier_move_attack3;
        !           835:                return;
        !           836:        }
        !           837: 
        !           838:        if (skill->value >= 2)
        !           839:        {
        !           840:                if (r > 0.66)
        !           841:                        self->monsterinfo.currentmove = &soldier_move_duck;
        !           842:                else
        !           843:                        self->monsterinfo.currentmove = &soldier_move_attack3;
        !           844:                return;
        !           845:        }
        !           846: 
        !           847:        self->monsterinfo.currentmove = &soldier_move_attack3;
        !           848: }
        !           849: 
        !           850: 
        !           851: //
        !           852: // DEATH
        !           853: //
        !           854: 
        !           855: void soldier_fire6 (edict_t *self)
        !           856: {
        !           857:        soldier_fire (self, 5);
        !           858: }
        !           859: 
        !           860: void soldier_fire7 (edict_t *self)
        !           861: {
        !           862:        soldier_fire (self, 6);
        !           863: }
        !           864: 
        !           865: void soldier_dead (edict_t *self)
        !           866: {
        !           867:        VectorSet (self->mins, -16, -16, -24);
        !           868:        VectorSet (self->maxs, 16, 16, -8);
        !           869:        self->movetype = MOVETYPE_TOSS;
        !           870:        self->svflags |= SVF_DEADMONSTER;
        !           871:        self->nextthink = 0;
        !           872:        gi.linkentity (self);
        !           873: }
        !           874: 
        !           875: mframe_t soldier_frames_death1 [] =
        !           876: {
        !           877:        ai_move, 0,   NULL,
        !           878:        ai_move, -10, NULL,
        !           879:        ai_move, -10, NULL,
        !           880:        ai_move, -10, NULL,
        !           881:        ai_move, -5,  NULL,
        !           882:        ai_move, 0,   NULL,
        !           883:        ai_move, 0,   NULL,
        !           884:        ai_move, 0,   NULL,
        !           885:        ai_move, 0,   NULL,
        !           886:        ai_move, 0,   NULL,
        !           887: 
        !           888:        ai_move, 0,   NULL,
        !           889:        ai_move, 0,   NULL,
        !           890:        ai_move, 0,   NULL,
        !           891:        ai_move, 0,   NULL,
        !           892:        ai_move, 0,   NULL,
        !           893:        ai_move, 0,   NULL,
        !           894:        ai_move, 0,   NULL,
        !           895:        ai_move, 0,   NULL,
        !           896:        ai_move, 0,   NULL,
        !           897:        ai_move, 0,   NULL,
        !           898: 
        !           899:        ai_move, 0,   NULL,
        !           900:        ai_move, 0,   soldier_fire6,
        !           901:        ai_move, 0,   NULL,
        !           902:        ai_move, 0,   NULL,
        !           903:        ai_move, 0,   soldier_fire7,
        !           904:        ai_move, 0,   NULL,
        !           905:        ai_move, 0,   NULL,
        !           906:        ai_move, 0,   NULL,
        !           907:        ai_move, 0,   NULL,
        !           908:        ai_move, 0,   NULL,
        !           909: 
        !           910:        ai_move, 0,   NULL,
        !           911:        ai_move, 0,   NULL,
        !           912:        ai_move, 0,   NULL,
        !           913:        ai_move, 0,   NULL,
        !           914:        ai_move, 0,   NULL,
        !           915:        ai_move, 0,   NULL
        !           916: };
        !           917: mmove_t soldier_move_death1 = {FRAME_death101, FRAME_death136, soldier_frames_death1, soldier_dead};
        !           918: 
        !           919: mframe_t soldier_frames_death2 [] =
        !           920: {
        !           921:        ai_move, -5,  NULL,
        !           922:        ai_move, -5,  NULL,
        !           923:        ai_move, -5,  NULL,
        !           924:        ai_move, 0,   NULL,
        !           925:        ai_move, 0,   NULL,
        !           926:        ai_move, 0,   NULL,
        !           927:        ai_move, 0,   NULL,
        !           928:        ai_move, 0,   NULL,
        !           929:        ai_move, 0,   NULL,
        !           930:        ai_move, 0,   NULL,
        !           931: 
        !           932:        ai_move, 0,   NULL,
        !           933:        ai_move, 0,   NULL,
        !           934:        ai_move, 0,   NULL,
        !           935:        ai_move, 0,   NULL,
        !           936:        ai_move, 0,   NULL,
        !           937:        ai_move, 0,   NULL,
        !           938:        ai_move, 0,   NULL,
        !           939:        ai_move, 0,   NULL,
        !           940:        ai_move, 0,   NULL,
        !           941:        ai_move, 0,   NULL,
        !           942: 
        !           943:        ai_move, 0,   NULL,
        !           944:        ai_move, 0,   NULL,
        !           945:        ai_move, 0,   NULL,
        !           946:        ai_move, 0,   NULL,
        !           947:        ai_move, 0,   NULL,
        !           948:        ai_move, 0,   NULL,
        !           949:        ai_move, 0,   NULL,
        !           950:        ai_move, 0,   NULL,
        !           951:        ai_move, 0,   NULL,
        !           952:        ai_move, 0,   NULL,
        !           953: 
        !           954:        ai_move, 0,   NULL,
        !           955:        ai_move, 0,   NULL,
        !           956:        ai_move, 0,   NULL,
        !           957:        ai_move, 0,   NULL,
        !           958:        ai_move, 0,   NULL
        !           959: };
        !           960: mmove_t soldier_move_death2 = {FRAME_death201, FRAME_death235, soldier_frames_death2, soldier_dead};
        !           961: 
        !           962: mframe_t soldier_frames_death3 [] =
        !           963: {
        !           964:        ai_move, -5,  NULL,
        !           965:        ai_move, -5,  NULL,
        !           966:        ai_move, -5,  NULL,
        !           967:        ai_move, 0,   NULL,
        !           968:        ai_move, 0,   NULL,
        !           969:        ai_move, 0,   NULL,
        !           970:        ai_move, 0,   NULL,
        !           971:        ai_move, 0,   NULL,
        !           972:        ai_move, 0,   NULL,
        !           973:        ai_move, 0,   NULL,
        !           974: 
        !           975:        ai_move, 0,   NULL,
        !           976:        ai_move, 0,   NULL,
        !           977:        ai_move, 0,   NULL,
        !           978:        ai_move, 0,   NULL,
        !           979:        ai_move, 0,   NULL,
        !           980:        ai_move, 0,   NULL,
        !           981:        ai_move, 0,   NULL,
        !           982:        ai_move, 0,   NULL,
        !           983:        ai_move, 0,   NULL,
        !           984:        ai_move, 0,   NULL,
        !           985: 
        !           986:        ai_move, 0,   NULL,
        !           987:        ai_move, 0,   NULL,
        !           988:        ai_move, 0,   NULL,
        !           989:        ai_move, 0,   NULL,
        !           990:        ai_move, 0,   NULL,
        !           991:        ai_move, 0,   NULL,
        !           992:        ai_move, 0,   NULL,
        !           993:        ai_move, 0,   NULL,
        !           994:        ai_move, 0,   NULL,
        !           995:        ai_move, 0,   NULL,
        !           996: 
        !           997:        ai_move, 0,   NULL,
        !           998:        ai_move, 0,   NULL,
        !           999:        ai_move, 0,   NULL,
        !          1000:        ai_move, 0,   NULL,
        !          1001:        ai_move, 0,   NULL,
        !          1002:        ai_move, 0,   NULL,
        !          1003:        ai_move, 0,   NULL,
        !          1004:        ai_move, 0,   NULL,
        !          1005:        ai_move, 0,   NULL,
        !          1006:        ai_move, 0,   NULL,
        !          1007: 
        !          1008:        ai_move, 0,   NULL,
        !          1009:        ai_move, 0,   NULL,
        !          1010:        ai_move, 0,   NULL,
        !          1011:        ai_move, 0,   NULL,
        !          1012:        ai_move, 0,   NULL,
        !          1013: };
        !          1014: mmove_t soldier_move_death3 = {FRAME_death301, FRAME_death345, soldier_frames_death3, soldier_dead};
        !          1015: 
        !          1016: mframe_t soldier_frames_death4 [] =
        !          1017: {
        !          1018:        ai_move, 0,   NULL,
        !          1019:        ai_move, 0,   NULL,
        !          1020:        ai_move, 0,   NULL,
        !          1021:        ai_move, 0,   NULL,
        !          1022:        ai_move, 0,   NULL,
        !          1023:        ai_move, 0,   NULL,
        !          1024:        ai_move, 0,   NULL,
        !          1025:        ai_move, 0,   NULL,
        !          1026:        ai_move, 0,   NULL,
        !          1027:        ai_move, 0,   NULL,
        !          1028: 
        !          1029:        ai_move, 0,   NULL,
        !          1030:        ai_move, 0,   NULL,
        !          1031:        ai_move, 0,   NULL,
        !          1032:        ai_move, 0,   NULL,
        !          1033:        ai_move, 0,   NULL,
        !          1034:        ai_move, 0,   NULL,
        !          1035:        ai_move, 0,   NULL,
        !          1036:        ai_move, 0,   NULL,
        !          1037:        ai_move, 0,   NULL,
        !          1038:        ai_move, 0,   NULL,
        !          1039: 
        !          1040:        ai_move, 0,   NULL,
        !          1041:        ai_move, 0,   NULL,
        !          1042:        ai_move, 0,   NULL,
        !          1043:        ai_move, 0,   NULL,
        !          1044:        ai_move, 0,   NULL,
        !          1045:        ai_move, 0,   NULL,
        !          1046:        ai_move, 0,   NULL,
        !          1047:        ai_move, 0,   NULL,
        !          1048:        ai_move, 0,   NULL,
        !          1049:        ai_move, 0,   NULL,
        !          1050: 
        !          1051:        ai_move, 0,   NULL,
        !          1052:        ai_move, 0,   NULL,
        !          1053:        ai_move, 0,   NULL,
        !          1054:        ai_move, 0,   NULL,
        !          1055:        ai_move, 0,   NULL,
        !          1056:        ai_move, 0,   NULL,
        !          1057:        ai_move, 0,   NULL,
        !          1058:        ai_move, 0,   NULL,
        !          1059:        ai_move, 0,   NULL,
        !          1060:        ai_move, 0,   NULL,
        !          1061: 
        !          1062:        ai_move, 0,   NULL,
        !          1063:        ai_move, 0,   NULL,
        !          1064:        ai_move, 0,   NULL,
        !          1065:        ai_move, 0,   NULL,
        !          1066:        ai_move, 0,   NULL,
        !          1067:        ai_move, 0,   NULL,
        !          1068:        ai_move, 0,   NULL,
        !          1069:        ai_move, 0,   NULL,
        !          1070:        ai_move, 0,   NULL,
        !          1071:        ai_move, 0,   NULL,
        !          1072: 
        !          1073:        ai_move, 0,   NULL,
        !          1074:        ai_move, 0,   NULL,
        !          1075:        ai_move, 0,   NULL
        !          1076: };
        !          1077: mmove_t soldier_move_death4 = {FRAME_death401, FRAME_death453, soldier_frames_death4, soldier_dead};
        !          1078: 
        !          1079: mframe_t soldier_frames_death5 [] =
        !          1080: {
        !          1081:        ai_move, -5,  NULL,
        !          1082:        ai_move, -5,  NULL,
        !          1083:        ai_move, -5,  NULL,
        !          1084:        ai_move, 0,   NULL,
        !          1085:        ai_move, 0,   NULL,
        !          1086:        ai_move, 0,   NULL,
        !          1087:        ai_move, 0,   NULL,
        !          1088:        ai_move, 0,   NULL,
        !          1089:        ai_move, 0,   NULL,
        !          1090:        ai_move, 0,   NULL,
        !          1091: 
        !          1092:        ai_move, 0,   NULL,
        !          1093:        ai_move, 0,   NULL,
        !          1094:        ai_move, 0,   NULL,
        !          1095:        ai_move, 0,   NULL,
        !          1096:        ai_move, 0,   NULL,
        !          1097:        ai_move, 0,   NULL,
        !          1098:        ai_move, 0,   NULL,
        !          1099:        ai_move, 0,   NULL,
        !          1100:        ai_move, 0,   NULL,
        !          1101:        ai_move, 0,   NULL,
        !          1102: 
        !          1103:        ai_move, 0,   NULL,
        !          1104:        ai_move, 0,   NULL,
        !          1105:        ai_move, 0,   NULL,
        !          1106:        ai_move, 0,   NULL
        !          1107: };
        !          1108: mmove_t soldier_move_death5 = {FRAME_death501, FRAME_death524, soldier_frames_death5, soldier_dead};
        !          1109: 
        !          1110: mframe_t soldier_frames_death6 [] =
        !          1111: {
        !          1112:        ai_move, 0,   NULL,
        !          1113:        ai_move, 0,   NULL,
        !          1114:        ai_move, 0,   NULL,
        !          1115:        ai_move, 0,   NULL,
        !          1116:        ai_move, 0,   NULL,
        !          1117:        ai_move, 0,   NULL,
        !          1118:        ai_move, 0,   NULL,
        !          1119:        ai_move, 0,   NULL,
        !          1120:        ai_move, 0,   NULL,
        !          1121:        ai_move, 0,   NULL
        !          1122: };
        !          1123: mmove_t soldier_move_death6 = {FRAME_death601, FRAME_death610, soldier_frames_death6, soldier_dead};
        !          1124: 
        !          1125: void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
        !          1126: {
        !          1127:        int             n;
        !          1128: 
        !          1129: // check for gib
        !          1130:        if (self->health <= self->gib_health)
        !          1131:        {
        !          1132:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
        !          1133:                for (n= 0; n < 3; n++)
        !          1134:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
        !          1135:                ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
        !          1136:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
        !          1137:                self->deadflag = DEAD_DEAD;
        !          1138:                return;
        !          1139:        }
        !          1140: 
        !          1141:        if (self->deadflag == DEAD_DEAD)
        !          1142:                return;
        !          1143: 
        !          1144: // regular death
        !          1145:        self->deadflag = DEAD_DEAD;
        !          1146:        self->takedamage = DAMAGE_YES;
        !          1147:        self->s.skinnum |= 1;
        !          1148: 
        !          1149:        if (self->s.skinnum == 1)
        !          1150:                gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
        !          1151:        else if (self->s.skinnum == 3)
        !          1152:                gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
        !          1153:        else // (self->s.skinnum == 5)
        !          1154:                gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
        !          1155: 
        !          1156:        if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
        !          1157:        {
        !          1158:                // head shot
        !          1159:                self->monsterinfo.currentmove = &soldier_move_death3;
        !          1160:                return;
        !          1161:        }
        !          1162: 
        !          1163:        n = rand() % 5;
        !          1164:        if (n == 0)
        !          1165:                self->monsterinfo.currentmove = &soldier_move_death1;
        !          1166:        else if (n == 1)
        !          1167:                self->monsterinfo.currentmove = &soldier_move_death2;
        !          1168:        else if (n == 2)
        !          1169:                self->monsterinfo.currentmove = &soldier_move_death4;
        !          1170:        else if (n == 3)
        !          1171:                self->monsterinfo.currentmove = &soldier_move_death5;
        !          1172:        else
        !          1173:                self->monsterinfo.currentmove = &soldier_move_death6;
        !          1174: }
        !          1175: 
        !          1176: 
        !          1177: //
        !          1178: // SPAWN
        !          1179: //
        !          1180: 
        !          1181: void SP_monster_soldier_x (edict_t *self)
        !          1182: {
        !          1183: 
        !          1184:        self->s.modelindex = gi.modelindex ("models/monsters/soldier/tris.md2");
        !          1185:        self->monsterinfo.scale = MODEL_SCALE;
        !          1186:        VectorSet (self->mins, -16, -16, -24);
        !          1187:        VectorSet (self->maxs, 16, 16, 32);
        !          1188:        self->movetype = MOVETYPE_STEP;
        !          1189:        self->solid = SOLID_BBOX;
        !          1190: 
        !          1191:        sound_idle =    gi.soundindex ("soldier/solidle1.wav");
        !          1192:        sound_sight1 =  gi.soundindex ("soldier/solsght1.wav");
        !          1193:        sound_sight2 =  gi.soundindex ("soldier/solsrch1.wav");
        !          1194:        sound_cock =    gi.soundindex ("infantry/infatck3.wav");
        !          1195: 
        !          1196:        self->mass = 100;
        !          1197: 
        !          1198:        self->pain = soldier_pain;
        !          1199:        self->die = soldier_die;
        !          1200: 
        !          1201:        self->monsterinfo.stand = soldier_stand;
        !          1202:        self->monsterinfo.walk = soldier_walk;
        !          1203:        self->monsterinfo.run = soldier_run;
        !          1204:        self->monsterinfo.dodge = soldier_dodge;
        !          1205:        self->monsterinfo.attack = soldier_attack;
        !          1206:        self->monsterinfo.melee = NULL;
        !          1207:        self->monsterinfo.sight = soldier_sight;
        !          1208: 
        !          1209:        gi.linkentity (self);
        !          1210: 
        !          1211:        self->monsterinfo.stand (self);
        !          1212: 
        !          1213:        walkmonster_start (self);
        !          1214: }
        !          1215: 
        !          1216: 
        !          1217: /*QUAKED monster_soldier_light (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          1218: */
        !          1219: void SP_monster_soldier_light (edict_t *self)
        !          1220: {
        !          1221:        if (deathmatch->value)
        !          1222:        {
        !          1223:                G_FreeEdict (self);
        !          1224:                return;
        !          1225:        }
        !          1226: 
        !          1227:        SP_monster_soldier_x (self);
        !          1228: 
        !          1229:        sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
        !          1230:        sound_death_light =     gi.soundindex ("soldier/soldeth2.wav");
        !          1231:        gi.modelindex ("models/objects/laser/tris.md2");
        !          1232:        gi.soundindex ("misc/lasfly.wav");
        !          1233:        gi.soundindex ("soldier/solatck2.wav");
        !          1234: 
        !          1235:        self->s.skinnum = 0;
        !          1236:        self->health = 20;
        !          1237:        self->gib_health = -30;
        !          1238: }
        !          1239: 
        !          1240: /*QUAKED monster_soldier (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          1241: */
        !          1242: void SP_monster_soldier (edict_t *self)
        !          1243: {
        !          1244:        if (deathmatch->value)
        !          1245:        {
        !          1246:                G_FreeEdict (self);
        !          1247:                return;
        !          1248:        }
        !          1249: 
        !          1250:        SP_monster_soldier_x (self);
        !          1251: 
        !          1252:        sound_pain = gi.soundindex ("soldier/solpain1.wav");
        !          1253:        sound_death = gi.soundindex ("soldier/soldeth1.wav");
        !          1254:        gi.soundindex ("soldier/solatck1.wav");
        !          1255: 
        !          1256:        self->s.skinnum = 2;
        !          1257:        self->health = 30;
        !          1258:        self->gib_health = -30;
        !          1259: }
        !          1260: 
        !          1261: /*QUAKED monster_soldier_ss (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          1262: */
        !          1263: void SP_monster_soldier_ss (edict_t *self)
        !          1264: {
        !          1265:        if (deathmatch->value)
        !          1266:        {
        !          1267:                G_FreeEdict (self);
        !          1268:                return;
        !          1269:        }
        !          1270: 
        !          1271:        SP_monster_soldier_x (self);
        !          1272: 
        !          1273:        sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
        !          1274:        sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
        !          1275:        gi.soundindex ("soldier/solatck3.wav");
        !          1276: 
        !          1277:        self->s.skinnum = 4;
        !          1278:        self->health = 40;
        !          1279:        self->gib_health = -30;
        !          1280: }
        !          1281: 
        !          1282: 
        !          1283: // RAFAEL 13-APR-98
        !          1284: 
        !          1285: 
        !          1286: #include "m_soldierh.h"
        !          1287: 
        !          1288: void soldierh_idle (edict_t *self)
        !          1289: {
        !          1290:        if (random() > 0.8)
        !          1291:                gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
        !          1292: }
        !          1293: 
        !          1294: void soldierh_cock (edict_t *self)
        !          1295: {
        !          1296:        if (self->s.frame == FRAME_stand322)
        !          1297:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
        !          1298:        else
        !          1299:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
        !          1300: }
        !          1301: 
        !          1302: 
        !          1303: // STAND
        !          1304: 
        !          1305: void soldierh_stand (edict_t *self);
        !          1306: 
        !          1307: mframe_t soldierh_frames_stand1 [] =
        !          1308: {
        !          1309:        ai_stand, 0, soldierh_idle,
        !          1310:        ai_stand, 0, NULL,
        !          1311:        ai_stand, 0, NULL,
        !          1312:        ai_stand, 0, NULL,
        !          1313:        ai_stand, 0, NULL,
        !          1314:        ai_stand, 0, NULL,
        !          1315:        ai_stand, 0, NULL,
        !          1316:        ai_stand, 0, NULL,
        !          1317:        ai_stand, 0, NULL,
        !          1318:        ai_stand, 0, NULL,
        !          1319: 
        !          1320:        ai_stand, 0, NULL,
        !          1321:        ai_stand, 0, NULL,
        !          1322:        ai_stand, 0, NULL,
        !          1323:        ai_stand, 0, NULL,
        !          1324:        ai_stand, 0, NULL,
        !          1325:        ai_stand, 0, NULL,
        !          1326:        ai_stand, 0, NULL,
        !          1327:        ai_stand, 0, NULL,
        !          1328:        ai_stand, 0, NULL,
        !          1329:        ai_stand, 0, NULL,
        !          1330: 
        !          1331:        ai_stand, 0, NULL,
        !          1332:        ai_stand, 0, NULL,
        !          1333:        ai_stand, 0, NULL,
        !          1334:        ai_stand, 0, NULL,
        !          1335:        ai_stand, 0, NULL,
        !          1336:        ai_stand, 0, NULL,
        !          1337:        ai_stand, 0, NULL,
        !          1338:        ai_stand, 0, NULL,
        !          1339:        ai_stand, 0, NULL,
        !          1340:        ai_stand, 0, NULL
        !          1341: };
        !          1342: mmove_t soldierh_move_stand1 = {FRAME_stand101, FRAME_stand130, soldierh_frames_stand1, soldierh_stand};
        !          1343: 
        !          1344: mframe_t soldierh_frames_stand3 [] =
        !          1345: {
        !          1346:        ai_stand, 0, NULL,
        !          1347:        ai_stand, 0, NULL,
        !          1348:        ai_stand, 0, NULL,
        !          1349:        ai_stand, 0, NULL,
        !          1350:        ai_stand, 0, NULL,
        !          1351:        ai_stand, 0, NULL,
        !          1352:        ai_stand, 0, NULL,
        !          1353:        ai_stand, 0, NULL,
        !          1354:        ai_stand, 0, NULL,
        !          1355:        ai_stand, 0, NULL,
        !          1356: 
        !          1357:        ai_stand, 0, NULL,
        !          1358:        ai_stand, 0, NULL,
        !          1359:        ai_stand, 0, NULL,
        !          1360:        ai_stand, 0, NULL,
        !          1361:        ai_stand, 0, NULL,
        !          1362:        ai_stand, 0, NULL,
        !          1363:        ai_stand, 0, NULL,
        !          1364:        ai_stand, 0, NULL,
        !          1365:        ai_stand, 0, NULL,
        !          1366:        ai_stand, 0, NULL,
        !          1367: 
        !          1368:        ai_stand, 0, NULL,
        !          1369:        ai_stand, 0, soldierh_cock,
        !          1370:        ai_stand, 0, NULL,
        !          1371:        ai_stand, 0, NULL,
        !          1372:        ai_stand, 0, NULL,
        !          1373:        ai_stand, 0, NULL,
        !          1374:        ai_stand, 0, NULL,
        !          1375:        ai_stand, 0, NULL,
        !          1376:        ai_stand, 0, NULL,
        !          1377:        ai_stand, 0, NULL,
        !          1378: 
        !          1379:        ai_stand, 0, NULL,
        !          1380:        ai_stand, 0, NULL,
        !          1381:        ai_stand, 0, NULL,
        !          1382:        ai_stand, 0, NULL,
        !          1383:        ai_stand, 0, NULL,
        !          1384:        ai_stand, 0, NULL,
        !          1385:        ai_stand, 0, NULL,
        !          1386:        ai_stand, 0, NULL,
        !          1387:        ai_stand, 0, NULL
        !          1388: };
        !          1389: mmove_t soldierh_move_stand3 = {FRAME_stand301, FRAME_stand339, soldierh_frames_stand3, soldierh_stand};
        !          1390: 
        !          1391: 
        !          1392: void soldierh_stand (edict_t *self)
        !          1393: {
        !          1394:        if ((self->monsterinfo.currentmove == &soldierh_move_stand3) || (random() < 0.8))
        !          1395:                self->monsterinfo.currentmove = &soldierh_move_stand1;
        !          1396:        else
        !          1397:                self->monsterinfo.currentmove = &soldierh_move_stand3;
        !          1398: }
        !          1399: 
        !          1400: 
        !          1401: //
        !          1402: // WALK
        !          1403: //
        !          1404: 
        !          1405: void soldierh_walk1_random (edict_t *self)
        !          1406: {
        !          1407:        if (random() > 0.1)
        !          1408:                self->monsterinfo.nextframe = FRAME_walk101;
        !          1409: }
        !          1410: 
        !          1411: mframe_t soldierh_frames_walk1 [] =
        !          1412: {
        !          1413:        ai_walk, 3,  NULL,
        !          1414:        ai_walk, 6,  NULL,
        !          1415:        ai_walk, 2,  NULL,
        !          1416:        ai_walk, 2,  NULL,
        !          1417:        ai_walk, 2,  NULL,
        !          1418:        ai_walk, 1,  NULL,
        !          1419:        ai_walk, 6,  NULL,
        !          1420:        ai_walk, 5,  NULL,
        !          1421:        ai_walk, 3,  NULL,
        !          1422:        ai_walk, -1, soldierh_walk1_random,
        !          1423:        ai_walk, 0,  NULL,
        !          1424:        ai_walk, 0,  NULL,
        !          1425:        ai_walk, 0,  NULL,
        !          1426:        ai_walk, 0,  NULL,
        !          1427:        ai_walk, 0,  NULL,
        !          1428:        ai_walk, 0,  NULL,
        !          1429:        ai_walk, 0,  NULL,
        !          1430:        ai_walk, 0,  NULL,
        !          1431:        ai_walk, 0,  NULL,
        !          1432:        ai_walk, 0,  NULL,
        !          1433:        ai_walk, 0,  NULL,
        !          1434:        ai_walk, 0,  NULL,
        !          1435:        ai_walk, 0,  NULL,
        !          1436:        ai_walk, 0,  NULL,
        !          1437:        ai_walk, 0,  NULL,
        !          1438:        ai_walk, 0,  NULL,
        !          1439:        ai_walk, 0,  NULL,
        !          1440:        ai_walk, 0,  NULL,
        !          1441:        ai_walk, 0,  NULL,
        !          1442:        ai_walk, 0,  NULL,
        !          1443:        ai_walk, 0,  NULL,
        !          1444:        ai_walk, 0,  NULL,
        !          1445:        ai_walk, 0,  NULL
        !          1446: };
        !          1447: mmove_t soldierh_move_walk1 = {FRAME_walk101, FRAME_walk133, soldierh_frames_walk1, NULL};
        !          1448: 
        !          1449: mframe_t soldierh_frames_walk2 [] =
        !          1450: {
        !          1451:        ai_walk, 4,  NULL,
        !          1452:        ai_walk, 4,  NULL,
        !          1453:        ai_walk, 9,  NULL,
        !          1454:        ai_walk, 8,  NULL,
        !          1455:        ai_walk, 5,  NULL,
        !          1456:        ai_walk, 1,  NULL,
        !          1457:        ai_walk, 3,  NULL,
        !          1458:        ai_walk, 7,  NULL,
        !          1459:        ai_walk, 6,  NULL,
        !          1460:        ai_walk, 7,  NULL
        !          1461: };
        !          1462: mmove_t soldierh_move_walk2 = {FRAME_walk209, FRAME_walk218, soldierh_frames_walk2, NULL};
        !          1463: 
        !          1464: void soldierh_walk (edict_t *self)
        !          1465: {
        !          1466:        if (random() < 0.5)
        !          1467:                self->monsterinfo.currentmove = &soldierh_move_walk1;
        !          1468:        else
        !          1469:                self->monsterinfo.currentmove = &soldierh_move_walk2;
        !          1470: }
        !          1471: 
        !          1472: 
        !          1473: //
        !          1474: // RUN
        !          1475: //
        !          1476: 
        !          1477: void soldierh_run (edict_t *self);
        !          1478: 
        !          1479: mframe_t soldierh_frames_start_run [] =
        !          1480: {
        !          1481:        ai_run, 7,  NULL,
        !          1482:        ai_run, 5,  NULL
        !          1483: };
        !          1484: mmove_t soldierh_move_start_run = {FRAME_run01, FRAME_run02, soldierh_frames_start_run, soldierh_run};
        !          1485: 
        !          1486: mframe_t soldierh_frames_run [] =
        !          1487: {
        !          1488:        ai_run, 10, NULL,
        !          1489:        ai_run, 11, NULL,
        !          1490:        ai_run, 11, NULL,
        !          1491:        ai_run, 16, NULL,
        !          1492:        ai_run, 10, NULL,
        !          1493:        ai_run, 15, NULL
        !          1494: };
        !          1495: mmove_t soldierh_move_run = {FRAME_run03, FRAME_run08, soldierh_frames_run, NULL};
        !          1496: 
        !          1497: void soldierh_run (edict_t *self)
        !          1498: {
        !          1499:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
        !          1500:        {
        !          1501:                self->monsterinfo.currentmove = &soldierh_move_stand1;
        !          1502:                return;
        !          1503:        }
        !          1504: 
        !          1505:        if (self->monsterinfo.currentmove == &soldierh_move_walk1 ||
        !          1506:                self->monsterinfo.currentmove == &soldierh_move_walk2 ||
        !          1507:                self->monsterinfo.currentmove == &soldierh_move_start_run)
        !          1508:        {
        !          1509:                self->monsterinfo.currentmove = &soldierh_move_run;
        !          1510:        }
        !          1511:        else
        !          1512:        {
        !          1513:                self->monsterinfo.currentmove = &soldierh_move_start_run;
        !          1514:        }
        !          1515: }
        !          1516: 
        !          1517: 
        !          1518: //
        !          1519: // PAIN
        !          1520: //
        !          1521: 
        !          1522: mframe_t soldierh_frames_pain1 [] =
        !          1523: {
        !          1524:        ai_move, -3, NULL,
        !          1525:        ai_move, 4,  NULL,
        !          1526:        ai_move, 1,  NULL,
        !          1527:        ai_move, 1,  NULL,
        !          1528:        ai_move, 0,  NULL
        !          1529: };
        !          1530: mmove_t soldierh_move_pain1 = {FRAME_pain101, FRAME_pain105, soldierh_frames_pain1, soldierh_run};
        !          1531: 
        !          1532: mframe_t soldierh_frames_pain2 [] =
        !          1533: {
        !          1534:        ai_move, -13, NULL,
        !          1535:        ai_move, -1,  NULL,
        !          1536:        ai_move, 2,   NULL,
        !          1537:        ai_move, 4,   NULL,
        !          1538:        ai_move, 2,   NULL,
        !          1539:        ai_move, 3,   NULL,
        !          1540:        ai_move, 2,   NULL
        !          1541: };
        !          1542: mmove_t soldierh_move_pain2 = {FRAME_pain201, FRAME_pain207, soldierh_frames_pain2, soldierh_run};
        !          1543: 
        !          1544: mframe_t soldierh_frames_pain3 [] =
        !          1545: {
        !          1546:        ai_move, -8, NULL,
        !          1547:        ai_move, 10, NULL,
        !          1548:        ai_move, -4, NULL,
        !          1549:        ai_move, -1, NULL,
        !          1550:        ai_move, -3, NULL,
        !          1551:        ai_move, 0,  NULL,
        !          1552:        ai_move, 3,  NULL,
        !          1553:        ai_move, 0,  NULL,
        !          1554:        ai_move, 0,  NULL,
        !          1555:        ai_move, 0,  NULL,
        !          1556:        ai_move, 0,  NULL,
        !          1557:        ai_move, 1,  NULL,
        !          1558:        ai_move, 0,  NULL,
        !          1559:        ai_move, 1,  NULL,
        !          1560:        ai_move, 2,  NULL,
        !          1561:        ai_move, 4,  NULL,
        !          1562:        ai_move, 3,  NULL,
        !          1563:        ai_move, 2,  NULL
        !          1564: };
        !          1565: mmove_t soldierh_move_pain3 = {FRAME_pain301, FRAME_pain318, soldierh_frames_pain3, soldierh_run};
        !          1566: 
        !          1567: mframe_t soldierh_frames_pain4 [] =
        !          1568: {
        !          1569:        ai_move, 0,   NULL,
        !          1570:        ai_move, 0,   NULL,
        !          1571:        ai_move, 0,   NULL,
        !          1572:        ai_move, -10, NULL,
        !          1573:        ai_move, -6,  NULL,
        !          1574:        ai_move, 8,   NULL,
        !          1575:        ai_move, 4,   NULL,
        !          1576:        ai_move, 1,   NULL,
        !          1577:        ai_move, 0,   NULL,
        !          1578:        ai_move, 2,   NULL,
        !          1579:        ai_move, 5,   NULL,
        !          1580:        ai_move, 2,   NULL,
        !          1581:        ai_move, -1,  NULL,
        !          1582:        ai_move, -1,  NULL,
        !          1583:        ai_move, 3,   NULL,
        !          1584:        ai_move, 2,   NULL,
        !          1585:        ai_move, 0,   NULL
        !          1586: };
        !          1587: mmove_t soldierh_move_pain4 = {FRAME_pain401, FRAME_pain417, soldierh_frames_pain4, soldierh_run};
        !          1588: 
        !          1589: void soldierh_pain (edict_t *self, edict_t *other, float kick, int damage)
        !          1590: {
        !          1591:        float   r;
        !          1592:        int             n;
        !          1593: 
        !          1594:        if (self->health < (self->max_health / 2))
        !          1595:                        self->s.skinnum |= 1;
        !          1596: 
        !          1597:        if (level.time < self->pain_debounce_time)
        !          1598:        {
        !          1599:                if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldierh_move_pain1) || (self->monsterinfo.currentmove == &soldierh_move_pain2) || (self->monsterinfo.currentmove == &soldierh_move_pain3)))
        !          1600:                        self->monsterinfo.currentmove = &soldierh_move_pain4;
        !          1601:                return;
        !          1602:        }
        !          1603: 
        !          1604:        self->pain_debounce_time = level.time + 3;
        !          1605: 
        !          1606:        n = self->s.skinnum | 1;
        !          1607:        if (n == 1)
        !          1608:                gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
        !          1609:        else if (n == 3)
        !          1610:                gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
        !          1611:        else
        !          1612:                gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
        !          1613: 
        !          1614:        if (self->velocity[2] > 100)
        !          1615:        {
        !          1616:                self->monsterinfo.currentmove = &soldierh_move_pain4;
        !          1617:                return;
        !          1618:        }
        !          1619: 
        !          1620:        if (skill->value == 3)
        !          1621:                return;         // no pain anims in nightmare
        !          1622: 
        !          1623:        r = random();
        !          1624: 
        !          1625:        if (r < 0.33)
        !          1626:                self->monsterinfo.currentmove = &soldierh_move_pain1;
        !          1627:        else if (r < 0.66)
        !          1628:                self->monsterinfo.currentmove = &soldierh_move_pain2;
        !          1629:        else
        !          1630:                self->monsterinfo.currentmove = &soldierh_move_pain3;
        !          1631: }
        !          1632: 
        !          1633: 
        !          1634: //
        !          1635: // ATTACK
        !          1636: //
        !          1637: 
        !          1638: extern void brain_dabeam (edict_t *self);
        !          1639: 
        !          1640: void soldierh_laserbeam (edict_t *self, int flash_index)
        !          1641: {
        !          1642:  
        !          1643:        vec3_t forward, right, up;
        !          1644:        vec3_t tempang, start;
        !          1645:        vec3_t  dir, angles, end;
        !          1646:        vec3_t  tempvec;
        !          1647:        edict_t *ent;
        !          1648: 
        !          1649:        // RAFAEL
        !          1650:        // this sound can't be called this frequent
        !          1651:        if (random() > 0.8)
        !          1652:                gi.sound(self, CHAN_AUTO, gi.soundindex("misc/lasfly.wav"), 1, ATTN_STATIC, 0);
        !          1653: 
        !          1654:        VectorCopy (self->s.origin, start);
        !          1655:        VectorCopy (self->enemy->s.origin, end);
        !          1656:        VectorSubtract (end, start, dir);
        !          1657:        vectoangles (dir, angles);
        !          1658:        VectorCopy (monster_flash_offset[flash_index], tempvec);
        !          1659:        
        !          1660:        ent = G_Spawn ();
        !          1661:        VectorCopy (self->s.origin, ent->s.origin);
        !          1662:        VectorCopy (angles, tempang);
        !          1663:        AngleVectors (tempang, forward, right, up);
        !          1664:        VectorCopy (tempang, ent->s.angles);
        !          1665:        VectorCopy (ent->s.origin, start);
        !          1666: 
        !          1667:        if (flash_index == 85)
        !          1668:        {
        !          1669:                VectorMA (start, tempvec[0]-14, right, start);
        !          1670:                VectorMA (start, tempvec[2]+8, up, start);
        !          1671:                VectorMA (start, tempvec[1], forward, start);
        !          1672:        }
        !          1673:        else 
        !          1674:        {
        !          1675:                VectorMA (start, tempvec[0]+2, right, start);
        !          1676:                VectorMA (start, tempvec[2]+8, up, start);
        !          1677:                VectorMA (start, tempvec[1], forward, start);
        !          1678:        }
        !          1679:                        
        !          1680:        VectorCopy (start, ent->s.origin);
        !          1681:        ent->enemy = self->enemy;
        !          1682:        ent->owner = self;
        !          1683:        
        !          1684:        ent->dmg = 1;
        !          1685: 
        !          1686:        monster_dabeam (ent);
        !          1687:        
        !          1688: }
        !          1689: 
        !          1690: 
        !          1691: void soldierh_fire (edict_t *self, int flash_number)
        !          1692: {
        !          1693:        vec3_t  start;
        !          1694:        vec3_t  forward, right, up;
        !          1695:        vec3_t  aim;
        !          1696:        vec3_t  dir;
        !          1697:        vec3_t  end;
        !          1698:        float   r, u;
        !          1699:        int             flash_index;
        !          1700:        qboolean tone = true;
        !          1701: 
        !          1702:        if (self->s.skinnum < 2)
        !          1703:                flash_index = blaster_flash[flash_number]; // ripper
        !          1704:        else if (self->s.skinnum < 4)
        !          1705:                flash_index = blaster_flash[flash_number]; // hyperblaster
        !          1706:        else
        !          1707:                flash_index = machinegun_flash[flash_number]; // laserbeam
        !          1708: 
        !          1709:        AngleVectors (self->s.angles, forward, right, NULL);
        !          1710:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
        !          1711: 
        !          1712:        if (flash_number == 5 || flash_number == 6)
        !          1713:        {
        !          1714:                VectorCopy (forward, aim);
        !          1715:        }
        !          1716:        else
        !          1717:        {
        !          1718:                VectorCopy (self->enemy->s.origin, end);
        !          1719:                end[2] += self->enemy->viewheight;
        !          1720:                VectorSubtract (end, start, aim);
        !          1721:                vectoangles (aim, dir);
        !          1722:                AngleVectors (dir, forward, right, up);
        !          1723: 
        !          1724:                r = crandom()*100;
        !          1725:                u = crandom()*50;
        !          1726:                VectorMA (start, 8192, forward, end);
        !          1727:                VectorMA (end, r, right, end);
        !          1728:                VectorMA (end, u, up, end);
        !          1729: 
        !          1730:                VectorSubtract (end, start, aim);
        !          1731:                VectorNormalize (aim);
        !          1732:        }
        !          1733: 
        !          1734:        if (self->s.skinnum <= 1)
        !          1735:        {
        !          1736:                // RAFAEL 24-APR-98
        !          1737:                // droped the damage from 15 to 5 
        !          1738:                monster_fire_ionripper (self, start, aim, 5, 600, flash_index, EF_IONRIPPER);
        !          1739: 
        !          1740:        }
        !          1741:        else if (self->s.skinnum <= 3)
        !          1742:        {
        !          1743:                
        !          1744:                monster_fire_blueblaster (self, start, aim, 1, 600, MZ_BLUEHYPERBLASTER, EF_BLUEHYPERBLASTER);
        !          1745:                
        !          1746:        }
        !          1747:        else
        !          1748:        {
        !          1749:                if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
        !          1750:                        self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
        !          1751: 
        !          1752:                soldierh_laserbeam (self, flash_index);
        !          1753: 
        !          1754:                if (level.time >= self->monsterinfo.pausetime)
        !          1755:                        self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
        !          1756:                else
        !          1757:                        self->monsterinfo.aiflags |= AI_HOLD_FRAME;
        !          1758:        }
        !          1759: }
        !          1760: 
        !          1761: // ATTACK1 (blaster/shotgun)
        !          1762: 
        !          1763: void soldierh_hyper_refire1 (edict_t *self)
        !          1764: {
        !          1765:        if (self->s.skinnum < 2)
        !          1766:                return;
        !          1767:        else if (self->s.skinnum < 4)
        !          1768:        {
        !          1769:                if (random() < 0.7)
        !          1770:                        self->s.frame = FRAME_attak103;
        !          1771:                else
        !          1772:                        gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
        !          1773:        }
        !          1774: }
        !          1775: 
        !          1776: void soldierh_ripper1 (edict_t *self)
        !          1777: {
        !          1778:        if (self->s.skinnum < 2)
        !          1779:                soldierh_fire (self, 0);
        !          1780:        else if (self->s.skinnum < 4)
        !          1781:                soldierh_fire (self, 0);
        !          1782: }
        !          1783: 
        !          1784: 
        !          1785: void soldierh_fire1 (edict_t *self)
        !          1786: {
        !          1787:        soldierh_fire (self, 0);
        !          1788: }
        !          1789: 
        !          1790: void soldierh_attack1_refire1 (edict_t *self)
        !          1791: {
        !          1792:        if (self->s.skinnum > 1)
        !          1793:                return;
        !          1794: 
        !          1795:        if (self->enemy->health <= 0)
        !          1796:                return;
        !          1797: 
        !          1798:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !          1799:                self->monsterinfo.nextframe = FRAME_attak102;
        !          1800:        else
        !          1801:                self->monsterinfo.nextframe = FRAME_attak110;
        !          1802: }
        !          1803: 
        !          1804: void soldierh_attack1_refire2 (edict_t *self)
        !          1805: {
        !          1806:        if (self->s.skinnum < 2)
        !          1807:                return;
        !          1808: 
        !          1809:        if (self->enemy->health <= 0)
        !          1810:                return;
        !          1811: 
        !          1812:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !          1813:                self->monsterinfo.nextframe = FRAME_attak102;
        !          1814: }
        !          1815: 
        !          1816: void soldierh_hyper_sound (edict_t *self)
        !          1817: {
        !          1818:        if (self->s.skinnum < 2)
        !          1819:                return;
        !          1820:        else if (self->s.skinnum < 4)
        !          1821:                gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbl1a.wav"), 1, ATTN_NORM, 0);
        !          1822:        else
        !          1823:                return;
        !          1824: }
        !          1825: 
        !          1826: mframe_t soldierh_frames_attack1 [] =
        !          1827: {
        !          1828:        ai_charge, 0,  NULL,
        !          1829:        ai_charge, 0,  soldierh_hyper_sound,
        !          1830:        ai_charge, 0,  soldierh_fire1,
        !          1831:        ai_charge, 0,  soldierh_ripper1,
        !          1832:        ai_charge, 0,  soldierh_ripper1,
        !          1833:        ai_charge, 0,  soldierh_attack1_refire1,
        !          1834:        ai_charge, 0,  soldierh_hyper_refire1,
        !          1835:        ai_charge, 0,  soldierh_cock,
        !          1836:        ai_charge, 0,  soldierh_attack1_refire2,
        !          1837:        ai_charge, 0,  NULL,
        !          1838:        ai_charge, 0,  NULL,
        !          1839:        ai_charge, 0,  NULL
        !          1840: };
        !          1841: mmove_t soldierh_move_attack1 = {FRAME_attak101, FRAME_attak112, soldierh_frames_attack1, soldierh_run};
        !          1842: 
        !          1843: // ATTACK2 (blaster/shotgun)
        !          1844: 
        !          1845: void soldierh_hyper_refire2 (edict_t *self)
        !          1846: {
        !          1847:        if (self->s.skinnum < 2)
        !          1848:                return;
        !          1849:        else if (self->s.skinnum < 4)
        !          1850:        {
        !          1851:                if (random() < 0.7)
        !          1852:                        self->s.frame = FRAME_attak205;
        !          1853:                else
        !          1854:                        gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
        !          1855:        }
        !          1856: }
        !          1857: 
        !          1858: void soldierh_ripper2 (edict_t *self)
        !          1859: {
        !          1860:        if (self->s.skinnum < 2)
        !          1861:                soldierh_fire (self, 1);
        !          1862:        else if (self->s.skinnum < 4)
        !          1863:                soldierh_fire (self, 1);
        !          1864: }
        !          1865: 
        !          1866: void soldierh_fire2 (edict_t *self)
        !          1867: {
        !          1868:        soldierh_fire (self, 1);
        !          1869: }
        !          1870: 
        !          1871: 
        !          1872: void soldierh_attack2_refire1 (edict_t *self)
        !          1873: {
        !          1874:        if (self->s.skinnum > 1)
        !          1875:                return;
        !          1876: 
        !          1877:        if (self->enemy->health <= 0)
        !          1878:                return;
        !          1879: 
        !          1880:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
        !          1881:                self->monsterinfo.nextframe = FRAME_attak204;
        !          1882:        else
        !          1883:                self->monsterinfo.nextframe = FRAME_attak216;
        !          1884: }
        !          1885: 
        !          1886: void soldierh_attack2_refire2 (edict_t *self)
        !          1887: {
        !          1888:        if (self->s.skinnum < 2)
        !          1889:                return;
        !          1890: 
        !          1891:        if (self->enemy->health <= 0)
        !          1892:                return;
        !          1893: 
        !          1894:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) && self->s.skinnum < 4)
        !          1895:                self->monsterinfo.nextframe = FRAME_attak204;
        !          1896: }
        !          1897: 
        !          1898: mframe_t soldierh_frames_attack2 [] =
        !          1899: {
        !          1900:        ai_charge, 0, NULL,
        !          1901:        ai_charge, 0, NULL,
        !          1902:        ai_charge, 0, NULL,
        !          1903:        ai_charge, 0, soldierh_hyper_sound,
        !          1904:        ai_charge, 0, soldierh_fire2,
        !          1905:        ai_charge, 0, soldierh_ripper2,
        !          1906:        ai_charge, 0, soldierh_ripper2,
        !          1907:        ai_charge, 0, soldierh_attack2_refire1,
        !          1908:        ai_charge, 0, soldierh_hyper_refire2,
        !          1909:        ai_charge, 0, NULL,
        !          1910:        ai_charge, 0, NULL,
        !          1911:        ai_charge, 0, NULL,
        !          1912:        ai_charge, 0, soldierh_cock,
        !          1913:        ai_charge, 0, NULL,
        !          1914:        ai_charge, 0, soldierh_attack2_refire2,
        !          1915:        ai_charge, 0, NULL,
        !          1916:        ai_charge, 0, NULL,
        !          1917:        ai_charge, 0, NULL
        !          1918: };
        !          1919: mmove_t soldierh_move_attack2 = {FRAME_attak201, FRAME_attak218, soldierh_frames_attack2, soldierh_run};
        !          1920: 
        !          1921: // ATTACK3 (duck and shoot)
        !          1922: 
        !          1923: void soldierh_duck_down (edict_t *self)
        !          1924: {
        !          1925:        if (self->monsterinfo.aiflags & AI_DUCKED)
        !          1926:                return;
        !          1927:        self->monsterinfo.aiflags |= AI_DUCKED;
        !          1928:        self->maxs[2] -= 32;
        !          1929:        self->takedamage = DAMAGE_YES;
        !          1930:        self->monsterinfo.pausetime = level.time + 1;
        !          1931:        gi.linkentity (self);
        !          1932: }
        !          1933: 
        !          1934: void soldierh_duck_up (edict_t *self)
        !          1935: {
        !          1936:        self->monsterinfo.aiflags &= ~AI_DUCKED;
        !          1937:        self->maxs[2] += 32;
        !          1938:        self->takedamage = DAMAGE_AIM;
        !          1939:        gi.linkentity (self);
        !          1940: }
        !          1941: 
        !          1942: void soldierh_fire3 (edict_t *self)
        !          1943: {
        !          1944:        soldierh_duck_down (self);
        !          1945:        soldierh_fire (self, 2);
        !          1946: }
        !          1947: 
        !          1948: void soldierh_attack3_refire (edict_t *self)
        !          1949: {
        !          1950:        if ((level.time + 0.4) < self->monsterinfo.pausetime)
        !          1951:                self->monsterinfo.nextframe = FRAME_attak303;
        !          1952: }
        !          1953: 
        !          1954: mframe_t soldierh_frames_attack3 [] =
        !          1955: {
        !          1956:        ai_charge, 0, NULL,
        !          1957:        ai_charge, 0, NULL,
        !          1958:        ai_charge, 0, soldierh_fire3,
        !          1959:        ai_charge, 0, NULL,
        !          1960:        ai_charge, 0, NULL,
        !          1961:        ai_charge, 0, soldierh_attack3_refire,
        !          1962:        ai_charge, 0, soldierh_duck_up,
        !          1963:        ai_charge, 0, NULL,
        !          1964:        ai_charge, 0, NULL
        !          1965: };
        !          1966: mmove_t soldierh_move_attack3 = {FRAME_attak301, FRAME_attak309, soldierh_frames_attack3, soldierh_run};
        !          1967: 
        !          1968: // ATTACK4 (machinegun)
        !          1969: 
        !          1970: void soldierh_fire4 (edict_t *self)
        !          1971: {
        !          1972:        soldierh_fire (self, 3);
        !          1973: //
        !          1974: //     if (self->enemy->health <= 0)
        !          1975: //             return;
        !          1976: //
        !          1977: //     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !          1978: //             self->monsterinfo.nextframe = FRAME_attak402;
        !          1979: }
        !          1980: 
        !          1981: mframe_t soldierh_frames_attack4 [] =
        !          1982: {
        !          1983:        ai_charge, 0, NULL,
        !          1984:        ai_charge, 0, NULL,
        !          1985:        ai_charge, 0, soldierh_fire4,
        !          1986:        ai_charge, 0, NULL,
        !          1987:        ai_charge, 0, NULL,
        !          1988:        ai_charge, 0, NULL
        !          1989: };
        !          1990: mmove_t soldierh_move_attack4 = {FRAME_attak401, FRAME_attak406, soldierh_frames_attack4, soldierh_run};
        !          1991: 
        !          1992: #if 0
        !          1993: // ATTACK5 (prone)
        !          1994: 
        !          1995: void soldierh_fire5 (edict_t *self)
        !          1996: {
        !          1997:        soldierh_fire (self, 4);
        !          1998: }
        !          1999: 
        !          2000: void soldierh_attack5_refire (edict_t *self)
        !          2001: {
        !          2002:        if (self->enemy->health <= 0)
        !          2003:                return;
        !          2004: 
        !          2005:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
        !          2006:                self->monsterinfo.nextframe = FRAME_attak505;
        !          2007: }
        !          2008: 
        !          2009: mframe_t soldierh_frames_attack5 [] =
        !          2010: {
        !          2011:        ai_charge, 8, NULL,
        !          2012:        ai_charge, 8, NULL,
        !          2013:        ai_charge, 0, NULL,
        !          2014:        ai_charge, 0, NULL,
        !          2015:        ai_charge, 0, soldierh_fire5,
        !          2016:        ai_charge, 0, NULL,
        !          2017:        ai_charge, 0, NULL,
        !          2018:        ai_charge, 0, soldierh_attack5_refire
        !          2019: };
        !          2020: mmove_t soldierh_move_attack5 = {FRAME_attak501, FRAME_attak508, soldierh_frames_attack5, soldierh_run};
        !          2021: #endif
        !          2022: 
        !          2023: // ATTACK6 (run & shoot)
        !          2024: 
        !          2025: void soldierh_fire8 (edict_t *self)
        !          2026: {
        !          2027:        soldierh_fire (self, 7);
        !          2028: }
        !          2029: 
        !          2030: void soldierh_attack6_refire (edict_t *self)
        !          2031: {
        !          2032:        if (self->enemy->health <= 0)
        !          2033:                return;
        !          2034: 
        !          2035:        if (range(self, self->enemy) < RANGE_MID)
        !          2036:                return;
        !          2037: 
        !          2038:        if (skill->value == 3)
        !          2039:                self->monsterinfo.nextframe = FRAME_runs03;
        !          2040: }
        !          2041: 
        !          2042: mframe_t soldierh_frames_attack6 [] =
        !          2043: {
        !          2044:        ai_charge, 10, NULL,
        !          2045:        ai_charge,  4, NULL,
        !          2046:        ai_charge, 12, NULL,
        !          2047:        ai_charge, 11, soldierh_fire8,
        !          2048:        ai_charge, 13, NULL,
        !          2049:        ai_charge, 18, NULL,
        !          2050:        ai_charge, 15, NULL,
        !          2051:        ai_charge, 14, NULL,
        !          2052:        ai_charge, 11, NULL,
        !          2053:        ai_charge,  8, NULL,
        !          2054:        ai_charge, 11, NULL,
        !          2055:        ai_charge, 12, NULL,
        !          2056:        ai_charge, 12, NULL,
        !          2057:        ai_charge, 17, soldierh_attack6_refire
        !          2058: };
        !          2059: mmove_t soldierh_move_attack6 = {FRAME_runs01, FRAME_runs14, soldierh_frames_attack6, soldierh_run};
        !          2060: 
        !          2061: void soldierh_attack(edict_t *self)
        !          2062: {
        !          2063:        if (self->s.skinnum < 4)
        !          2064:        {
        !          2065:                if (random() < 0.5)
        !          2066:                        self->monsterinfo.currentmove = &soldierh_move_attack1;
        !          2067:                else
        !          2068:                        self->monsterinfo.currentmove = &soldierh_move_attack2;
        !          2069:        }
        !          2070:        else
        !          2071:        {
        !          2072:                self->monsterinfo.currentmove = &soldierh_move_attack4;
        !          2073:        }
        !          2074: }
        !          2075: 
        !          2076: 
        !          2077: //
        !          2078: // SIGHT
        !          2079: //
        !          2080: 
        !          2081: void soldierh_sight(edict_t *self, edict_t *other)
        !          2082: {
        !          2083:        if (random() < 0.5)
        !          2084:                gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
        !          2085:        else
        !          2086:                gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
        !          2087: 
        !          2088:        if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
        !          2089:        {
        !          2090:                if (random() > 0.5)
        !          2091:                {
        !          2092:                        if (self->s.skinnum < 4)        
        !          2093:                                self->monsterinfo.currentmove = &soldierh_move_attack6;
        !          2094:                        else
        !          2095:                                self->monsterinfo.currentmove = &soldierh_move_attack4;
        !          2096:                }
        !          2097:        }
        !          2098: }
        !          2099: 
        !          2100: //
        !          2101: // DUCK
        !          2102: //
        !          2103: 
        !          2104: void soldierh_duck_hold (edict_t *self)
        !          2105: {
        !          2106:        if (level.time >= self->monsterinfo.pausetime)
        !          2107:                self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
        !          2108:        else
        !          2109:                self->monsterinfo.aiflags |= AI_HOLD_FRAME;
        !          2110: }
        !          2111: 
        !          2112: mframe_t soldierh_frames_duck [] =
        !          2113: {
        !          2114:        ai_move, 5, soldierh_duck_down,
        !          2115:        ai_move, -1, soldierh_duck_hold,
        !          2116:        ai_move, 1,  NULL,
        !          2117:        ai_move, 0,  soldierh_duck_up,
        !          2118:        ai_move, 5,  NULL
        !          2119: };
        !          2120: mmove_t soldierh_move_duck = {FRAME_duck01, FRAME_duck05, soldierh_frames_duck, soldierh_run};
        !          2121: 
        !          2122: void soldierh_dodge (edict_t *self, edict_t *attacker, float eta)
        !          2123: {
        !          2124:        float   r;
        !          2125: 
        !          2126:        r = random();
        !          2127:        if (r > 0.25)
        !          2128:                return;
        !          2129: 
        !          2130:        if (!self->enemy)
        !          2131:                self->enemy = attacker;
        !          2132: 
        !          2133:        if (skill->value == 0)
        !          2134:        {
        !          2135:                self->monsterinfo.currentmove = &soldierh_move_duck;
        !          2136:                return;
        !          2137:        }
        !          2138: 
        !          2139:        self->monsterinfo.pausetime = level.time + eta + 0.3;
        !          2140:        r = random();
        !          2141: 
        !          2142:        if (skill->value == 1)
        !          2143:        {
        !          2144:                if (r > 0.33)
        !          2145:                        self->monsterinfo.currentmove = &soldierh_move_duck;
        !          2146:                else
        !          2147:                        self->monsterinfo.currentmove = &soldierh_move_attack3;
        !          2148:                return;
        !          2149:        }
        !          2150: 
        !          2151:        if (skill->value >= 2)
        !          2152:        {
        !          2153:                if (r > 0.66)
        !          2154:                        self->monsterinfo.currentmove = &soldierh_move_duck;
        !          2155:                else
        !          2156:                        self->monsterinfo.currentmove = &soldierh_move_attack3;
        !          2157:                return;
        !          2158:        }
        !          2159: 
        !          2160:        self->monsterinfo.currentmove = &soldierh_move_attack3;
        !          2161: }
        !          2162: 
        !          2163: 
        !          2164: //
        !          2165: // DEATH
        !          2166: //
        !          2167: 
        !          2168: void soldierh_fire6 (edict_t *self)
        !          2169: {
        !          2170:        
        !          2171:        // no fire laser
        !          2172:        if (self->s.skinnum < 4)
        !          2173:                soldierh_fire (self, 5);
        !          2174: 
        !          2175: }
        !          2176: 
        !          2177: void soldierh_fire7 (edict_t *self)
        !          2178: {
        !          2179:        
        !          2180:        // no fire laser
        !          2181:        if (self->s.skinnum < 4)
        !          2182:                soldierh_fire (self, 6);
        !          2183: 
        !          2184: }
        !          2185: 
        !          2186: void soldierh_dead (edict_t *self)
        !          2187: {
        !          2188:        VectorSet (self->mins, -16, -16, -24);
        !          2189:        VectorSet (self->maxs, 16, 16, -8);
        !          2190:        self->movetype = MOVETYPE_TOSS;
        !          2191:        self->svflags |= SVF_DEADMONSTER;
        !          2192:        self->nextthink = 0;
        !          2193:        gi.linkentity (self);
        !          2194: }
        !          2195: 
        !          2196: mframe_t soldierh_frames_death1 [] =
        !          2197: {
        !          2198:        ai_move, 0,   NULL,
        !          2199:        ai_move, -10, NULL,
        !          2200:        ai_move, -10, NULL,
        !          2201:        ai_move, -10, NULL,
        !          2202:        ai_move, -5,  NULL,
        !          2203:        ai_move, 0,   NULL,
        !          2204:        ai_move, 0,   NULL,
        !          2205:        ai_move, 0,   NULL,
        !          2206:        ai_move, 0,   NULL,
        !          2207:        ai_move, 0,   NULL,
        !          2208: 
        !          2209:        ai_move, 0,   NULL,
        !          2210:        ai_move, 0,   NULL,
        !          2211:        ai_move, 0,   NULL,
        !          2212:        ai_move, 0,   NULL,
        !          2213:        ai_move, 0,   NULL,
        !          2214:        ai_move, 0,   NULL,
        !          2215:        ai_move, 0,   NULL,
        !          2216:        ai_move, 0,   NULL,
        !          2217:        ai_move, 0,   NULL,
        !          2218:        ai_move, 0,   NULL,
        !          2219: 
        !          2220:        ai_move, 0,   NULL,
        !          2221:        ai_move, 0,   soldierh_fire6,
        !          2222:        ai_move, 0,   NULL,
        !          2223:        ai_move, 0,   NULL,
        !          2224:        ai_move, 0,   soldierh_fire7,
        !          2225:        ai_move, 0,   NULL,
        !          2226:        ai_move, 0,   NULL,
        !          2227:        ai_move, 0,   NULL,
        !          2228:        ai_move, 0,   NULL,
        !          2229:        ai_move, 0,   NULL,
        !          2230: 
        !          2231:        ai_move, 0,   NULL,
        !          2232:        ai_move, 0,   NULL,
        !          2233:        ai_move, 0,   NULL,
        !          2234:        ai_move, 0,   NULL,
        !          2235:        ai_move, 0,   NULL,
        !          2236:        ai_move, 0,   NULL
        !          2237: };
        !          2238: mmove_t soldierh_move_death1 = {FRAME_death101, FRAME_death136, soldierh_frames_death1, soldierh_dead};
        !          2239: 
        !          2240: mframe_t soldierh_frames_death2 [] =
        !          2241: {
        !          2242:        ai_move, -5,  NULL,
        !          2243:        ai_move, -5,  NULL,
        !          2244:        ai_move, -5,  NULL,
        !          2245:        ai_move, 0,   NULL,
        !          2246:        ai_move, 0,   NULL,
        !          2247:        ai_move, 0,   NULL,
        !          2248:        ai_move, 0,   NULL,
        !          2249:        ai_move, 0,   NULL,
        !          2250:        ai_move, 0,   NULL,
        !          2251:        ai_move, 0,   NULL,
        !          2252: 
        !          2253:        ai_move, 0,   NULL,
        !          2254:        ai_move, 0,   NULL,
        !          2255:        ai_move, 0,   NULL,
        !          2256:        ai_move, 0,   NULL,
        !          2257:        ai_move, 0,   NULL,
        !          2258:        ai_move, 0,   NULL,
        !          2259:        ai_move, 0,   NULL,
        !          2260:        ai_move, 0,   NULL,
        !          2261:        ai_move, 0,   NULL,
        !          2262:        ai_move, 0,   NULL,
        !          2263: 
        !          2264:        ai_move, 0,   NULL,
        !          2265:        ai_move, 0,   NULL,
        !          2266:        ai_move, 0,   NULL,
        !          2267:        ai_move, 0,   NULL,
        !          2268:        ai_move, 0,   NULL,
        !          2269:        ai_move, 0,   NULL,
        !          2270:        ai_move, 0,   NULL,
        !          2271:        ai_move, 0,   NULL,
        !          2272:        ai_move, 0,   NULL,
        !          2273:        ai_move, 0,   NULL,
        !          2274: 
        !          2275:        ai_move, 0,   NULL,
        !          2276:        ai_move, 0,   NULL,
        !          2277:        ai_move, 0,   NULL,
        !          2278:        ai_move, 0,   NULL,
        !          2279:        ai_move, 0,   NULL
        !          2280: };
        !          2281: mmove_t soldierh_move_death2 = {FRAME_death201, FRAME_death235, soldierh_frames_death2, soldierh_dead};
        !          2282: 
        !          2283: mframe_t soldierh_frames_death3 [] =
        !          2284: {
        !          2285:        ai_move, -5,  NULL,
        !          2286:        ai_move, -5,  NULL,
        !          2287:        ai_move, -5,  NULL,
        !          2288:        ai_move, 0,   NULL,
        !          2289:        ai_move, 0,   NULL,
        !          2290:        ai_move, 0,   NULL,
        !          2291:        ai_move, 0,   NULL,
        !          2292:        ai_move, 0,   NULL,
        !          2293:        ai_move, 0,   NULL,
        !          2294:        ai_move, 0,   NULL,
        !          2295: 
        !          2296:        ai_move, 0,   NULL,
        !          2297:        ai_move, 0,   NULL,
        !          2298:        ai_move, 0,   NULL,
        !          2299:        ai_move, 0,   NULL,
        !          2300:        ai_move, 0,   NULL,
        !          2301:        ai_move, 0,   NULL,
        !          2302:        ai_move, 0,   NULL,
        !          2303:        ai_move, 0,   NULL,
        !          2304:        ai_move, 0,   NULL,
        !          2305:        ai_move, 0,   NULL,
        !          2306: 
        !          2307:        ai_move, 0,   NULL,
        !          2308:        ai_move, 0,   NULL,
        !          2309:        ai_move, 0,   NULL,
        !          2310:        ai_move, 0,   NULL,
        !          2311:        ai_move, 0,   NULL,
        !          2312:        ai_move, 0,   NULL,
        !          2313:        ai_move, 0,   NULL,
        !          2314:        ai_move, 0,   NULL,
        !          2315:        ai_move, 0,   NULL,
        !          2316:        ai_move, 0,   NULL,
        !          2317: 
        !          2318:        ai_move, 0,   NULL,
        !          2319:        ai_move, 0,   NULL,
        !          2320:        ai_move, 0,   NULL,
        !          2321:        ai_move, 0,   NULL,
        !          2322:        ai_move, 0,   NULL,
        !          2323:        ai_move, 0,   NULL,
        !          2324:        ai_move, 0,   NULL,
        !          2325:        ai_move, 0,   NULL,
        !          2326:        ai_move, 0,   NULL,
        !          2327:        ai_move, 0,   NULL,
        !          2328: 
        !          2329:        ai_move, 0,   NULL,
        !          2330:        ai_move, 0,   NULL,
        !          2331:        ai_move, 0,   NULL,
        !          2332:        ai_move, 0,   NULL,
        !          2333:        ai_move, 0,   NULL,
        !          2334: };
        !          2335: mmove_t soldierh_move_death3 = {FRAME_death301, FRAME_death345, soldierh_frames_death3, soldierh_dead};
        !          2336: 
        !          2337: mframe_t soldierh_frames_death4 [] =
        !          2338: {
        !          2339:        ai_move, 0,   NULL,
        !          2340:        ai_move, 0,   NULL,
        !          2341:        ai_move, 0,   NULL,
        !          2342:        ai_move, 0,   NULL,
        !          2343:        ai_move, 0,   NULL,
        !          2344:        ai_move, 0,   NULL,
        !          2345:        ai_move, 0,   NULL,
        !          2346:        ai_move, 0,   NULL,
        !          2347:        ai_move, 0,   NULL,
        !          2348:        ai_move, 0,   NULL,
        !          2349: 
        !          2350:        ai_move, 0,   NULL,
        !          2351:        ai_move, 0,   NULL,
        !          2352:        ai_move, 0,   NULL,
        !          2353:        ai_move, 0,   NULL,
        !          2354:        ai_move, 0,   NULL,
        !          2355:        ai_move, 0,   NULL,
        !          2356:        ai_move, 0,   NULL,
        !          2357:        ai_move, 0,   NULL,
        !          2358:        ai_move, 0,   NULL,
        !          2359:        ai_move, 0,   NULL,
        !          2360: 
        !          2361:        ai_move, 0,   NULL,
        !          2362:        ai_move, 0,   NULL,
        !          2363:        ai_move, 0,   NULL,
        !          2364:        ai_move, 0,   NULL,
        !          2365:        ai_move, 0,   NULL,
        !          2366:        ai_move, 0,   NULL,
        !          2367:        ai_move, 0,   NULL,
        !          2368:        ai_move, 0,   NULL,
        !          2369:        ai_move, 0,   NULL,
        !          2370:        ai_move, 0,   NULL,
        !          2371: 
        !          2372:        ai_move, 0,   NULL,
        !          2373:        ai_move, 0,   NULL,
        !          2374:        ai_move, 0,   NULL,
        !          2375:        ai_move, 0,   NULL,
        !          2376:        ai_move, 0,   NULL,
        !          2377:        ai_move, 0,   NULL,
        !          2378:        ai_move, 0,   NULL,
        !          2379:        ai_move, 0,   NULL,
        !          2380:        ai_move, 0,   NULL,
        !          2381:        ai_move, 0,   NULL,
        !          2382: 
        !          2383:        ai_move, 0,   NULL,
        !          2384:        ai_move, 0,   NULL,
        !          2385:        ai_move, 0,   NULL,
        !          2386:        ai_move, 0,   NULL,
        !          2387:        ai_move, 0,   NULL,
        !          2388:        ai_move, 0,   NULL,
        !          2389:        ai_move, 0,   NULL,
        !          2390:        ai_move, 0,   NULL,
        !          2391:        ai_move, 0,   NULL,
        !          2392:        ai_move, 0,   NULL,
        !          2393: 
        !          2394:        ai_move, 0,   NULL,
        !          2395:        ai_move, 0,   NULL,
        !          2396:        ai_move, 0,   NULL
        !          2397: };
        !          2398: mmove_t soldierh_move_death4 = {FRAME_death401, FRAME_death453, soldierh_frames_death4, soldierh_dead};
        !          2399: 
        !          2400: mframe_t soldierh_frames_death5 [] =
        !          2401: {
        !          2402:        ai_move, -5,  NULL,
        !          2403:        ai_move, -5,  NULL,
        !          2404:        ai_move, -5,  NULL,
        !          2405:        ai_move, 0,   NULL,
        !          2406:        ai_move, 0,   NULL,
        !          2407:        ai_move, 0,   NULL,
        !          2408:        ai_move, 0,   NULL,
        !          2409:        ai_move, 0,   NULL,
        !          2410:        ai_move, 0,   NULL,
        !          2411:        ai_move, 0,   NULL,
        !          2412: 
        !          2413:        ai_move, 0,   NULL,
        !          2414:        ai_move, 0,   NULL,
        !          2415:        ai_move, 0,   NULL,
        !          2416:        ai_move, 0,   NULL,
        !          2417:        ai_move, 0,   NULL,
        !          2418:        ai_move, 0,   NULL,
        !          2419:        ai_move, 0,   NULL,
        !          2420:        ai_move, 0,   NULL,
        !          2421:        ai_move, 0,   NULL,
        !          2422:        ai_move, 0,   NULL,
        !          2423: 
        !          2424:        ai_move, 0,   NULL,
        !          2425:        ai_move, 0,   NULL,
        !          2426:        ai_move, 0,   NULL,
        !          2427:        ai_move, 0,   NULL
        !          2428: };
        !          2429: mmove_t soldierh_move_death5 = {FRAME_death501, FRAME_death524, soldierh_frames_death5, soldierh_dead};
        !          2430: 
        !          2431: mframe_t soldierh_frames_death6 [] =
        !          2432: {
        !          2433:        ai_move, 0,   NULL,
        !          2434:        ai_move, 0,   NULL,
        !          2435:        ai_move, 0,   NULL,
        !          2436:        ai_move, 0,   NULL,
        !          2437:        ai_move, 0,   NULL,
        !          2438:        ai_move, 0,   NULL,
        !          2439:        ai_move, 0,   NULL,
        !          2440:        ai_move, 0,   NULL,
        !          2441:        ai_move, 0,   NULL,
        !          2442:        ai_move, 0,   NULL
        !          2443: };
        !          2444: mmove_t soldierh_move_death6 = {FRAME_death601, FRAME_death610, soldierh_frames_death6, soldierh_dead};
        !          2445: 
        !          2446: void soldierh_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
        !          2447: {
        !          2448:        int             n;
        !          2449: 
        !          2450: // check for gib
        !          2451:        if (self->health <= self->gib_health)
        !          2452:        {
        !          2453:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
        !          2454:                for (n= 0; n < 3; n++)
        !          2455:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
        !          2456:                ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
        !          2457:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
        !          2458:                
        !          2459:                self->deadflag = DEAD_DEAD;
        !          2460:                return;
        !          2461:        }
        !          2462: 
        !          2463:        if (self->deadflag == DEAD_DEAD)
        !          2464:                return;
        !          2465: 
        !          2466: // regular death
        !          2467:        self->deadflag = DEAD_DEAD;
        !          2468:        self->takedamage = DAMAGE_YES;
        !          2469:        self->s.skinnum |= 1;
        !          2470: 
        !          2471:        if (self->s.skinnum == 1)
        !          2472:                gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
        !          2473:        else if (self->s.skinnum == 3)
        !          2474:                gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
        !          2475:        else // (self->s.skinnum == 5)
        !          2476:                gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
        !          2477: 
        !          2478:        if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
        !          2479:        {
        !          2480:                // head shot
        !          2481:                self->monsterinfo.currentmove = &soldierh_move_death3;
        !          2482:                return;
        !          2483:        }
        !          2484: 
        !          2485:        n = rand() % 5;
        !          2486:        if (n == 0)
        !          2487:                self->monsterinfo.currentmove = &soldierh_move_death1;
        !          2488:        else if (n == 1)
        !          2489:                self->monsterinfo.currentmove = &soldierh_move_death2;
        !          2490:        else if (n == 2)
        !          2491:                self->monsterinfo.currentmove = &soldierh_move_death4;
        !          2492:        else if (n == 3)
        !          2493:                self->monsterinfo.currentmove = &soldierh_move_death5;
        !          2494:        else
        !          2495:                self->monsterinfo.currentmove = &soldierh_move_death6;
        !          2496: }
        !          2497: 
        !          2498: 
        !          2499: //
        !          2500: // SPAWN
        !          2501: //
        !          2502: 
        !          2503: void SP_monster_soldier_h (edict_t *self)
        !          2504: {
        !          2505: 
        !          2506:        self->s.modelindex = gi.modelindex ("models/monsters/soldierh/tris.md2");
        !          2507:        self->monsterinfo.scale = MODEL_SCALE;
        !          2508:        VectorSet (self->mins, -16, -16, -24);
        !          2509:        VectorSet (self->maxs, 16, 16, 32);
        !          2510:        self->movetype = MOVETYPE_STEP;
        !          2511:        self->solid = SOLID_BBOX;
        !          2512: 
        !          2513:        sound_idle =    gi.soundindex ("soldier/solidle1.wav");
        !          2514:        sound_sight1 =  gi.soundindex ("soldier/solsght1.wav");
        !          2515:        sound_sight2 =  gi.soundindex ("soldier/solsrch1.wav");
        !          2516:        sound_cock =    gi.soundindex ("infantry/infatck3.wav");
        !          2517: 
        !          2518:        self->mass = 100;
        !          2519: 
        !          2520:        self->pain = soldierh_pain;
        !          2521:        self->die = soldierh_die;
        !          2522: 
        !          2523:        self->monsterinfo.stand = soldierh_stand;
        !          2524:        self->monsterinfo.walk = soldierh_walk;
        !          2525:        self->monsterinfo.run = soldierh_run;
        !          2526:        self->monsterinfo.dodge = soldierh_dodge;
        !          2527:        self->monsterinfo.attack = soldierh_attack;
        !          2528:        self->monsterinfo.melee = NULL;
        !          2529:        self->monsterinfo.sight = soldierh_sight;
        !          2530: 
        !          2531:        gi.linkentity (self);
        !          2532: 
        !          2533:        // self->monsterinfo.stand (self);
        !          2534:        self->monsterinfo.currentmove = &soldierh_move_stand3;  
        !          2535: 
        !          2536:        walkmonster_start (self);
        !          2537: }
        !          2538: 
        !          2539: 
        !          2540: /*QUAKED monster_soldier_ripper (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          2541: */
        !          2542: void SP_monster_soldier_ripper (edict_t *self)
        !          2543: {
        !          2544:        if (deathmatch->value)
        !          2545:        {
        !          2546:                G_FreeEdict (self);
        !          2547:                return;
        !          2548:        }
        !          2549: 
        !          2550:        SP_monster_soldier_h (self);
        !          2551: 
        !          2552:        sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
        !          2553:        sound_death_light =     gi.soundindex ("soldier/soldeth2.wav");
        !          2554:        
        !          2555:        gi.modelindex ("models/objects/boomrang/tris.md2");
        !          2556:        gi.soundindex ("misc/lasfly.wav");
        !          2557:        gi.soundindex ("soldier/solatck2.wav");
        !          2558: 
        !          2559:        self->s.skinnum = 0;
        !          2560:        self->health = 50;
        !          2561:        self->gib_health = -30;
        !          2562: }
        !          2563: 
        !          2564: /*QUAKED monster_soldier_hypergun (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          2565: */
        !          2566: void SP_monster_soldier_hypergun (edict_t *self)
        !          2567: {
        !          2568:        if (deathmatch->value)
        !          2569:        {
        !          2570:                G_FreeEdict (self);
        !          2571:                return;
        !          2572:        }
        !          2573: 
        !          2574:        SP_monster_soldier_h (self);
        !          2575: 
        !          2576:        gi.modelindex ("models/objects/blaser/tris.md2");
        !          2577:        sound_pain = gi.soundindex ("soldier/solpain1.wav");
        !          2578:        sound_death = gi.soundindex ("soldier/soldeth1.wav");
        !          2579:        gi.soundindex ("soldier/solatck1.wav");
        !          2580: 
        !          2581:        self->s.skinnum = 2;
        !          2582:        self->health = 60;
        !          2583:        self->gib_health = -30;
        !          2584: }
        !          2585: 
        !          2586: /*QUAKED monster_soldier_lasergun (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !          2587: */
        !          2588: void SP_monster_soldier_lasergun (edict_t *self)
        !          2589: {
        !          2590:        if (deathmatch->value)
        !          2591:        {
        !          2592:                G_FreeEdict (self);
        !          2593:                return;
        !          2594:        }
        !          2595: 
        !          2596:        SP_monster_soldier_h (self);
        !          2597: 
        !          2598:        sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
        !          2599:        sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
        !          2600:        gi.soundindex ("soldier/solatck3.wav");
        !          2601: 
        !          2602:        self->s.skinnum = 4;
        !          2603:        self->health = 70;
        !          2604:        self->gib_health = -30;
        !          2605:                
        !          2606: }
        !          2607: 
        !          2608: // END 13-APR-98

unix.superglobalmegacorp.com

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