Annotation of quake2/xatrix/m_soldier.c, revision 1.1.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.