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

1.1       root        1: /*
1.1.1.2 ! root        2: Copyright (C) 1997-2001 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
        !            20: /*
1.1       root       21: ==============================================================================
                     22: 
                     23: SOLDIER
                     24: 
                     25: ==============================================================================
                     26: */
                     27: 
                     28: #include "g_local.h"
                     29: #include "m_soldier.h"
                     30: 
                     31: 
                     32: static int     sound_idle;
                     33: static int     sound_sight1;
                     34: static int     sound_sight2;
                     35: static int     sound_pain_light;
                     36: static int     sound_pain;
                     37: static int     sound_pain_ss;
                     38: static int     sound_death_light;
                     39: static int     sound_death;
                     40: static int     sound_death_ss;
                     41: static int     sound_cock;
                     42: 
                     43: 
                     44: void soldier_idle (edict_t *self)
                     45: {
                     46:        if (random() > 0.8)
                     47:                gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
                     48: }
                     49: 
                     50: void soldier_cock (edict_t *self)
                     51: {
                     52:        if (self->s.frame == FRAME_stand322)
                     53:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
                     54:        else
                     55:                gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
                     56: }
                     57: 
                     58: 
                     59: // STAND
                     60: 
                     61: void soldier_stand (edict_t *self);
                     62: 
                     63: mframe_t soldier_frames_stand1 [] =
                     64: {
                     65:        ai_stand, 0, soldier_idle,
                     66:        ai_stand, 0, NULL,
                     67:        ai_stand, 0, NULL,
                     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: 
                     76:        ai_stand, 0, NULL,
                     77:        ai_stand, 0, NULL,
                     78:        ai_stand, 0, NULL,
                     79:        ai_stand, 0, NULL,
                     80:        ai_stand, 0, NULL,
                     81:        ai_stand, 0, NULL,
                     82:        ai_stand, 0, NULL,
                     83:        ai_stand, 0, NULL,
                     84:        ai_stand, 0, NULL,
                     85:        ai_stand, 0, NULL,
                     86: 
                     87:        ai_stand, 0, NULL,
                     88:        ai_stand, 0, NULL,
                     89:        ai_stand, 0, NULL,
                     90:        ai_stand, 0, NULL,
                     91:        ai_stand, 0, NULL,
                     92:        ai_stand, 0, NULL,
                     93:        ai_stand, 0, NULL,
                     94:        ai_stand, 0, NULL,
                     95:        ai_stand, 0, NULL,
                     96:        ai_stand, 0, NULL
                     97: };
                     98: mmove_t soldier_move_stand1 = {FRAME_stand101, FRAME_stand130, soldier_frames_stand1, soldier_stand};
                     99: 
                    100: mframe_t soldier_frames_stand3 [] =
                    101: {
                    102:        ai_stand, 0, NULL,
                    103:        ai_stand, 0, NULL,
                    104:        ai_stand, 0, NULL,
                    105:        ai_stand, 0, NULL,
                    106:        ai_stand, 0, NULL,
                    107:        ai_stand, 0, NULL,
                    108:        ai_stand, 0, NULL,
                    109:        ai_stand, 0, NULL,
                    110:        ai_stand, 0, NULL,
                    111:        ai_stand, 0, NULL,
                    112: 
                    113:        ai_stand, 0, NULL,
                    114:        ai_stand, 0, NULL,
                    115:        ai_stand, 0, NULL,
                    116:        ai_stand, 0, NULL,
                    117:        ai_stand, 0, NULL,
                    118:        ai_stand, 0, NULL,
                    119:        ai_stand, 0, NULL,
                    120:        ai_stand, 0, NULL,
                    121:        ai_stand, 0, NULL,
                    122:        ai_stand, 0, NULL,
                    123: 
                    124:        ai_stand, 0, NULL,
                    125:        ai_stand, 0, soldier_cock,
                    126:        ai_stand, 0, NULL,
                    127:        ai_stand, 0, NULL,
                    128:        ai_stand, 0, NULL,
                    129:        ai_stand, 0, NULL,
                    130:        ai_stand, 0, NULL,
                    131:        ai_stand, 0, NULL,
                    132:        ai_stand, 0, NULL,
                    133:        ai_stand, 0, NULL,
                    134: 
                    135:        ai_stand, 0, NULL,
                    136:        ai_stand, 0, NULL,
                    137:        ai_stand, 0, NULL,
                    138:        ai_stand, 0, NULL,
                    139:        ai_stand, 0, NULL,
                    140:        ai_stand, 0, NULL,
                    141:        ai_stand, 0, NULL,
                    142:        ai_stand, 0, NULL,
                    143:        ai_stand, 0, NULL
                    144: };
                    145: mmove_t soldier_move_stand3 = {FRAME_stand301, FRAME_stand339, soldier_frames_stand3, soldier_stand};
                    146: 
                    147: #if 0
                    148: mframe_t soldier_frames_stand4 [] =
                    149: {
                    150:        ai_stand, 0, NULL,
                    151:        ai_stand, 0, NULL,
                    152:        ai_stand, 0, NULL,
                    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: 
                    161:        ai_stand, 0, NULL,
                    162:        ai_stand, 0, NULL,
                    163:        ai_stand, 0, NULL,
                    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: 
                    172:        ai_stand, 0, NULL,
                    173:        ai_stand, 0, NULL,
                    174:        ai_stand, 0, NULL,
                    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, 0, NULL,
                    182: 
                    183:        ai_stand, 0, NULL,
                    184:        ai_stand, 0, NULL,
                    185:        ai_stand, 0, NULL,
                    186:        ai_stand, 0, NULL,
                    187:        ai_stand, 0, NULL,
                    188:        ai_stand, 0, NULL,
                    189:        ai_stand, 0, NULL,
                    190:        ai_stand, 0, NULL,
                    191:        ai_stand, 0, NULL,
                    192:        ai_stand, 0, NULL,
                    193: 
                    194:        ai_stand, 0, NULL,
                    195:        ai_stand, 0, NULL,
                    196:        ai_stand, 0, NULL,
                    197:        ai_stand, 0, NULL,
                    198:        ai_stand, 0, NULL,
                    199:        ai_stand, 0, NULL,
                    200:        ai_stand, 4, NULL,
                    201:        ai_stand, 1, NULL,
                    202:        ai_stand, -1, NULL,
                    203:        ai_stand, -2, NULL,
                    204: 
                    205:        ai_stand, 0, NULL,
                    206:        ai_stand, 0, NULL
                    207: };
                    208: mmove_t soldier_move_stand4 = {FRAME_stand401, FRAME_stand452, soldier_frames_stand4, NULL};
                    209: #endif
                    210: 
                    211: void soldier_stand (edict_t *self)
                    212: {
                    213:        if ((self->monsterinfo.currentmove == &soldier_move_stand3) || (random() < 0.8))
                    214:                self->monsterinfo.currentmove = &soldier_move_stand1;
                    215:        else
                    216:                self->monsterinfo.currentmove = &soldier_move_stand3;
                    217: }
                    218: 
                    219: 
                    220: //
                    221: // WALK
                    222: //
                    223: 
                    224: void soldier_walk1_random (edict_t *self)
                    225: {
                    226:        if (random() > 0.1)
                    227:                self->monsterinfo.nextframe = FRAME_walk101;
                    228: }
                    229: 
                    230: mframe_t soldier_frames_walk1 [] =
                    231: {
                    232:        ai_walk, 3,  NULL,
                    233:        ai_walk, 6,  NULL,
                    234:        ai_walk, 2,  NULL,
                    235:        ai_walk, 2,  NULL,
                    236:        ai_walk, 2,  NULL,
                    237:        ai_walk, 1,  NULL,
                    238:        ai_walk, 6,  NULL,
                    239:        ai_walk, 5,  NULL,
                    240:        ai_walk, 3,  NULL,
                    241:        ai_walk, -1, soldier_walk1_random,
                    242:        ai_walk, 0,  NULL,
                    243:        ai_walk, 0,  NULL,
                    244:        ai_walk, 0,  NULL,
                    245:        ai_walk, 0,  NULL,
                    246:        ai_walk, 0,  NULL,
                    247:        ai_walk, 0,  NULL,
                    248:        ai_walk, 0,  NULL,
                    249:        ai_walk, 0,  NULL,
                    250:        ai_walk, 0,  NULL,
                    251:        ai_walk, 0,  NULL,
                    252:        ai_walk, 0,  NULL,
                    253:        ai_walk, 0,  NULL,
                    254:        ai_walk, 0,  NULL,
                    255:        ai_walk, 0,  NULL,
                    256:        ai_walk, 0,  NULL,
                    257:        ai_walk, 0,  NULL,
                    258:        ai_walk, 0,  NULL,
                    259:        ai_walk, 0,  NULL,
                    260:        ai_walk, 0,  NULL,
                    261:        ai_walk, 0,  NULL,
                    262:        ai_walk, 0,  NULL,
                    263:        ai_walk, 0,  NULL,
                    264:        ai_walk, 0,  NULL
                    265: };
                    266: mmove_t soldier_move_walk1 = {FRAME_walk101, FRAME_walk133, soldier_frames_walk1, NULL};
                    267: 
                    268: mframe_t soldier_frames_walk2 [] =
                    269: {
                    270:        ai_walk, 4,  NULL,
                    271:        ai_walk, 4,  NULL,
                    272:        ai_walk, 9,  NULL,
                    273:        ai_walk, 8,  NULL,
                    274:        ai_walk, 5,  NULL,
                    275:        ai_walk, 1,  NULL,
                    276:        ai_walk, 3,  NULL,
                    277:        ai_walk, 7,  NULL,
                    278:        ai_walk, 6,  NULL,
                    279:        ai_walk, 7,  NULL
                    280: };
                    281: mmove_t soldier_move_walk2 = {FRAME_walk209, FRAME_walk218, soldier_frames_walk2, NULL};
                    282: 
                    283: void soldier_walk (edict_t *self)
                    284: {
                    285:        if (random() < 0.5)
                    286:                self->monsterinfo.currentmove = &soldier_move_walk1;
                    287:        else
                    288:                self->monsterinfo.currentmove = &soldier_move_walk2;
                    289: }
                    290: 
                    291: 
                    292: //
                    293: // RUN
                    294: //
                    295: 
                    296: void soldier_run (edict_t *self);
                    297: 
                    298: mframe_t soldier_frames_start_run [] =
                    299: {
                    300:        ai_run, 7,  NULL,
                    301:        ai_run, 5,  NULL
                    302: };
                    303: mmove_t soldier_move_start_run = {FRAME_run01, FRAME_run02, soldier_frames_start_run, soldier_run};
                    304: 
                    305: mframe_t soldier_frames_run [] =
                    306: {
                    307:        ai_run, 10, NULL,
                    308:        ai_run, 11, NULL,
                    309:        ai_run, 11, NULL,
                    310:        ai_run, 16, NULL,
                    311:        ai_run, 10, NULL,
                    312:        ai_run, 15, NULL
                    313: };
                    314: mmove_t soldier_move_run = {FRAME_run03, FRAME_run08, soldier_frames_run, NULL};
                    315: 
                    316: void soldier_run (edict_t *self)
                    317: {
                    318:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
                    319:        {
                    320:                self->monsterinfo.currentmove = &soldier_move_stand1;
                    321:                return;
                    322:        }
                    323: 
                    324:        if (self->monsterinfo.currentmove == &soldier_move_walk1 ||
                    325:                self->monsterinfo.currentmove == &soldier_move_walk2 ||
                    326:                self->monsterinfo.currentmove == &soldier_move_start_run)
                    327:        {
                    328:                self->monsterinfo.currentmove = &soldier_move_run;
                    329:        }
                    330:        else
                    331:        {
                    332:                self->monsterinfo.currentmove = &soldier_move_start_run;
                    333:        }
                    334: }
                    335: 
                    336: 
                    337: //
                    338: // PAIN
                    339: //
                    340: 
                    341: mframe_t soldier_frames_pain1 [] =
                    342: {
                    343:        ai_move, -3, NULL,
                    344:        ai_move, 4,  NULL,
                    345:        ai_move, 1,  NULL,
                    346:        ai_move, 1,  NULL,
                    347:        ai_move, 0,  NULL
                    348: };
                    349: mmove_t soldier_move_pain1 = {FRAME_pain101, FRAME_pain105, soldier_frames_pain1, soldier_run};
                    350: 
                    351: mframe_t soldier_frames_pain2 [] =
                    352: {
                    353:        ai_move, -13, NULL,
                    354:        ai_move, -1,  NULL,
                    355:        ai_move, 2,   NULL,
                    356:        ai_move, 4,   NULL,
                    357:        ai_move, 2,   NULL,
                    358:        ai_move, 3,   NULL,
                    359:        ai_move, 2,   NULL
                    360: };
                    361: mmove_t soldier_move_pain2 = {FRAME_pain201, FRAME_pain207, soldier_frames_pain2, soldier_run};
                    362: 
                    363: mframe_t soldier_frames_pain3 [] =
                    364: {
                    365:        ai_move, -8, NULL,
                    366:        ai_move, 10, NULL,
                    367:        ai_move, -4, NULL,
                    368:        ai_move, -1, NULL,
                    369:        ai_move, -3, NULL,
                    370:        ai_move, 0,  NULL,
                    371:        ai_move, 3,  NULL,
                    372:        ai_move, 0,  NULL,
                    373:        ai_move, 0,  NULL,
                    374:        ai_move, 0,  NULL,
                    375:        ai_move, 0,  NULL,
                    376:        ai_move, 1,  NULL,
                    377:        ai_move, 0,  NULL,
                    378:        ai_move, 1,  NULL,
                    379:        ai_move, 2,  NULL,
                    380:        ai_move, 4,  NULL,
                    381:        ai_move, 3,  NULL,
                    382:        ai_move, 2,  NULL
                    383: };
                    384: mmove_t soldier_move_pain3 = {FRAME_pain301, FRAME_pain318, soldier_frames_pain3, soldier_run};
                    385: 
                    386: mframe_t soldier_frames_pain4 [] =
                    387: {
                    388:        ai_move, 0,   NULL,
                    389:        ai_move, 0,   NULL,
                    390:        ai_move, 0,   NULL,
                    391:        ai_move, -10, NULL,
                    392:        ai_move, -6,  NULL,
                    393:        ai_move, 8,   NULL,
                    394:        ai_move, 4,   NULL,
                    395:        ai_move, 1,   NULL,
                    396:        ai_move, 0,   NULL,
                    397:        ai_move, 2,   NULL,
                    398:        ai_move, 5,   NULL,
                    399:        ai_move, 2,   NULL,
                    400:        ai_move, -1,  NULL,
                    401:        ai_move, -1,  NULL,
                    402:        ai_move, 3,   NULL,
                    403:        ai_move, 2,   NULL,
                    404:        ai_move, 0,   NULL
                    405: };
                    406: mmove_t soldier_move_pain4 = {FRAME_pain401, FRAME_pain417, soldier_frames_pain4, soldier_run};
                    407: 
                    408: 
                    409: void soldier_pain (edict_t *self, edict_t *other, float kick, int damage)
                    410: {
                    411:        float   r;
                    412:        int             n;
                    413: 
                    414:        if (self->health < (self->max_health / 2))
                    415:                        self->s.skinnum |= 1;
                    416: 
                    417:        if (level.time < self->pain_debounce_time)
                    418:        {
                    419:                if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldier_move_pain1) || (self->monsterinfo.currentmove == &soldier_move_pain2) || (self->monsterinfo.currentmove == &soldier_move_pain3)))
                    420:                        self->monsterinfo.currentmove = &soldier_move_pain4;
                    421:                return;
                    422:        }
                    423: 
                    424:        self->pain_debounce_time = level.time + 3;
                    425: 
                    426:        n = self->s.skinnum | 1;
                    427:        if (n == 1)
                    428:                gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
                    429:        else if (n == 3)
                    430:                gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
                    431:        else
                    432:                gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
                    433: 
                    434:        if (self->velocity[2] > 100)
                    435:        {
                    436:                self->monsterinfo.currentmove = &soldier_move_pain4;
                    437:                return;
                    438:        }
                    439: 
                    440:        if (skill->value == 3)
                    441:                return;         // no pain anims in nightmare
                    442: 
                    443:        r = random();
                    444: 
                    445:        if (r < 0.33)
                    446:                self->monsterinfo.currentmove = &soldier_move_pain1;
                    447:        else if (r < 0.66)
                    448:                self->monsterinfo.currentmove = &soldier_move_pain2;
                    449:        else
                    450:                self->monsterinfo.currentmove = &soldier_move_pain3;
                    451: }
                    452: 
                    453: 
                    454: //
                    455: // ATTACK
                    456: //
                    457: 
                    458: 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};
                    459: 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};
                    460: 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};
                    461: 
                    462: void soldier_fire (edict_t *self, int flash_number)
                    463: {
                    464:        vec3_t  start;
                    465:        vec3_t  forward, right, up;
                    466:        vec3_t  aim;
                    467:        vec3_t  dir;
                    468:        vec3_t  end;
                    469:        float   r, u;
                    470:        int             flash_index;
                    471: 
                    472:        if (self->s.skinnum < 2)
                    473:                flash_index = blaster_flash[flash_number];
                    474:        else if (self->s.skinnum < 4)
                    475:                flash_index = shotgun_flash[flash_number];
                    476:        else
                    477:                flash_index = machinegun_flash[flash_number];
                    478: 
                    479:        AngleVectors (self->s.angles, forward, right, NULL);
                    480:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
                    481: 
                    482:        if (flash_number == 5 || flash_number == 6)
                    483:        {
                    484:                VectorCopy (forward, aim);
                    485:        }
                    486:        else
                    487:        {
                    488:                VectorCopy (self->enemy->s.origin, end);
                    489:                end[2] += self->enemy->viewheight;
                    490:                VectorSubtract (end, start, aim);
                    491:                vectoangles (aim, dir);
                    492:                AngleVectors (dir, forward, right, up);
                    493: 
                    494:                r = crandom()*1000;
                    495:                u = crandom()*500;
                    496:                VectorMA (start, 8192, forward, end);
                    497:                VectorMA (end, r, right, end);
                    498:                VectorMA (end, u, up, end);
                    499: 
                    500:                VectorSubtract (end, start, aim);
                    501:                VectorNormalize (aim);
                    502:        }
                    503: 
                    504:        if (self->s.skinnum <= 1)
                    505:        {
                    506:                monster_fire_blaster (self, start, aim, 5, 600, flash_index, EF_BLASTER);
                    507:        }
                    508:        else if (self->s.skinnum <= 3)
                    509:        {
                    510:                monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index);
                    511:        }
                    512:        else
                    513:        {
                    514:                if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
                    515:                        self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
                    516: 
                    517:                monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);
                    518: 
                    519:                if (level.time >= self->monsterinfo.pausetime)
                    520:                        self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
                    521:                else
                    522:                        self->monsterinfo.aiflags |= AI_HOLD_FRAME;
                    523:        }
                    524: }
                    525: 
                    526: // ATTACK1 (blaster/shotgun)
                    527: 
                    528: void soldier_fire1 (edict_t *self)
                    529: {
                    530:        soldier_fire (self, 0);
                    531: }
                    532: 
                    533: void soldier_attack1_refire1 (edict_t *self)
                    534: {
                    535:        if (self->s.skinnum > 1)
                    536:                return;
                    537: 
                    538:        if (self->enemy->health <= 0)
                    539:                return;
                    540: 
                    541:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    542:                self->monsterinfo.nextframe = FRAME_attak102;
                    543:        else
                    544:                self->monsterinfo.nextframe = FRAME_attak110;
                    545: }
                    546: 
                    547: void soldier_attack1_refire2 (edict_t *self)
                    548: {
                    549:        if (self->s.skinnum < 2)
                    550:                return;
                    551: 
                    552:        if (self->enemy->health <= 0)
                    553:                return;
                    554: 
                    555:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    556:                self->monsterinfo.nextframe = FRAME_attak102;
                    557: }
                    558: 
                    559: mframe_t soldier_frames_attack1 [] =
                    560: {
                    561:        ai_charge, 0,  NULL,
                    562:        ai_charge, 0,  NULL,
                    563:        ai_charge, 0,  soldier_fire1,
                    564:        ai_charge, 0,  NULL,
                    565:        ai_charge, 0,  NULL,
                    566:        ai_charge, 0,  soldier_attack1_refire1,
                    567:        ai_charge, 0,  NULL,
                    568:        ai_charge, 0,  soldier_cock,
                    569:        ai_charge, 0,  soldier_attack1_refire2,
                    570:        ai_charge, 0,  NULL,
                    571:        ai_charge, 0,  NULL,
                    572:        ai_charge, 0,  NULL
                    573: };
                    574: mmove_t soldier_move_attack1 = {FRAME_attak101, FRAME_attak112, soldier_frames_attack1, soldier_run};
                    575: 
                    576: // ATTACK2 (blaster/shotgun)
                    577: 
                    578: void soldier_fire2 (edict_t *self)
                    579: {
                    580:        soldier_fire (self, 1);
                    581: }
                    582: 
                    583: void soldier_attack2_refire1 (edict_t *self)
                    584: {
                    585:        if (self->s.skinnum > 1)
                    586:                return;
                    587: 
                    588:        if (self->enemy->health <= 0)
                    589:                return;
                    590: 
                    591:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    592:                self->monsterinfo.nextframe = FRAME_attak204;
                    593:        else
                    594:                self->monsterinfo.nextframe = FRAME_attak216;
                    595: }
                    596: 
                    597: void soldier_attack2_refire2 (edict_t *self)
                    598: {
                    599:        if (self->s.skinnum < 2)
                    600:                return;
                    601: 
                    602:        if (self->enemy->health <= 0)
                    603:                return;
                    604: 
                    605:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    606:                self->monsterinfo.nextframe = FRAME_attak204;
                    607: }
                    608: 
                    609: mframe_t soldier_frames_attack2 [] =
                    610: {
                    611:        ai_charge, 0, NULL,
                    612:        ai_charge, 0, NULL,
                    613:        ai_charge, 0, NULL,
                    614:        ai_charge, 0, NULL,
                    615:        ai_charge, 0, soldier_fire2,
                    616:        ai_charge, 0, NULL,
                    617:        ai_charge, 0, NULL,
                    618:        ai_charge, 0, soldier_attack2_refire1,
                    619:        ai_charge, 0, NULL,
                    620:        ai_charge, 0, NULL,
                    621:        ai_charge, 0, NULL,
                    622:        ai_charge, 0, NULL,
                    623:        ai_charge, 0, soldier_cock,
                    624:        ai_charge, 0, NULL,
                    625:        ai_charge, 0, soldier_attack2_refire2,
                    626:        ai_charge, 0, NULL,
                    627:        ai_charge, 0, NULL,
                    628:        ai_charge, 0, NULL
                    629: };
                    630: mmove_t soldier_move_attack2 = {FRAME_attak201, FRAME_attak218, soldier_frames_attack2, soldier_run};
                    631: 
                    632: // ATTACK3 (duck and shoot)
                    633: 
                    634: void soldier_duck_down (edict_t *self)
                    635: {
                    636:        if (self->monsterinfo.aiflags & AI_DUCKED)
                    637:                return;
                    638:        self->monsterinfo.aiflags |= AI_DUCKED;
                    639:        self->maxs[2] -= 32;
                    640:        self->takedamage = DAMAGE_YES;
                    641:        self->monsterinfo.pausetime = level.time + 1;
                    642:        gi.linkentity (self);
                    643: }
                    644: 
                    645: void soldier_duck_up (edict_t *self)
                    646: {
                    647:        self->monsterinfo.aiflags &= ~AI_DUCKED;
                    648:        self->maxs[2] += 32;
                    649:        self->takedamage = DAMAGE_AIM;
                    650:        gi.linkentity (self);
                    651: }
                    652: 
                    653: void soldier_fire3 (edict_t *self)
                    654: {
                    655:        soldier_duck_down (self);
                    656:        soldier_fire (self, 2);
                    657: }
                    658: 
                    659: void soldier_attack3_refire (edict_t *self)
                    660: {
                    661:        if ((level.time + 0.4) < self->monsterinfo.pausetime)
                    662:                self->monsterinfo.nextframe = FRAME_attak303;
                    663: }
                    664: 
                    665: mframe_t soldier_frames_attack3 [] =
                    666: {
                    667:        ai_charge, 0, NULL,
                    668:        ai_charge, 0, NULL,
                    669:        ai_charge, 0, soldier_fire3,
                    670:        ai_charge, 0, NULL,
                    671:        ai_charge, 0, NULL,
                    672:        ai_charge, 0, soldier_attack3_refire,
                    673:        ai_charge, 0, soldier_duck_up,
                    674:        ai_charge, 0, NULL,
                    675:        ai_charge, 0, NULL
                    676: };
                    677: mmove_t soldier_move_attack3 = {FRAME_attak301, FRAME_attak309, soldier_frames_attack3, soldier_run};
                    678: 
                    679: // ATTACK4 (machinegun)
                    680: 
                    681: void soldier_fire4 (edict_t *self)
                    682: {
                    683:        soldier_fire (self, 3);
                    684: //
                    685: //     if (self->enemy->health <= 0)
                    686: //             return;
                    687: //
                    688: //     if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    689: //             self->monsterinfo.nextframe = FRAME_attak402;
                    690: }
                    691: 
                    692: mframe_t soldier_frames_attack4 [] =
                    693: {
                    694:        ai_charge, 0, NULL,
                    695:        ai_charge, 0, NULL,
                    696:        ai_charge, 0, soldier_fire4,
                    697:        ai_charge, 0, NULL,
                    698:        ai_charge, 0, NULL,
                    699:        ai_charge, 0, NULL
                    700: };
                    701: mmove_t soldier_move_attack4 = {FRAME_attak401, FRAME_attak406, soldier_frames_attack4, soldier_run};
                    702: 
                    703: #if 0
                    704: // ATTACK5 (prone)
                    705: 
                    706: void soldier_fire5 (edict_t *self)
                    707: {
                    708:        soldier_fire (self, 4);
                    709: }
                    710: 
                    711: void soldier_attack5_refire (edict_t *self)
                    712: {
                    713:        if (self->enemy->health <= 0)
                    714:                return;
                    715: 
                    716:        if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
                    717:                self->monsterinfo.nextframe = FRAME_attak505;
                    718: }
                    719: 
                    720: mframe_t soldier_frames_attack5 [] =
                    721: {
                    722:        ai_charge, 8, NULL,
                    723:        ai_charge, 8, NULL,
                    724:        ai_charge, 0, NULL,
                    725:        ai_charge, 0, NULL,
                    726:        ai_charge, 0, soldier_fire5,
                    727:        ai_charge, 0, NULL,
                    728:        ai_charge, 0, NULL,
                    729:        ai_charge, 0, soldier_attack5_refire
                    730: };
                    731: mmove_t soldier_move_attack5 = {FRAME_attak501, FRAME_attak508, soldier_frames_attack5, soldier_run};
                    732: #endif
                    733: 
                    734: // ATTACK6 (run & shoot)
                    735: 
                    736: void soldier_fire8 (edict_t *self)
                    737: {
                    738:        soldier_fire (self, 7);
                    739: }
                    740: 
                    741: void soldier_attack6_refire (edict_t *self)
                    742: {
                    743:        if (self->enemy->health <= 0)
                    744:                return;
                    745: 
                    746:        if (range(self, self->enemy) < RANGE_MID)
                    747:                return;
                    748: 
                    749:        if (skill->value == 3)
                    750:                self->monsterinfo.nextframe = FRAME_runs03;
                    751: }
                    752: 
                    753: mframe_t soldier_frames_attack6 [] =
                    754: {
                    755:        ai_charge, 10, NULL,
                    756:        ai_charge,  4, NULL,
                    757:        ai_charge, 12, NULL,
                    758:        ai_charge, 11, soldier_fire8,
                    759:        ai_charge, 13, NULL,
                    760:        ai_charge, 18, NULL,
                    761:        ai_charge, 15, NULL,
                    762:        ai_charge, 14, NULL,
                    763:        ai_charge, 11, NULL,
                    764:        ai_charge,  8, NULL,
                    765:        ai_charge, 11, NULL,
                    766:        ai_charge, 12, NULL,
                    767:        ai_charge, 12, NULL,
                    768:        ai_charge, 17, soldier_attack6_refire
                    769: };
                    770: mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attack6, soldier_run};
                    771: 
                    772: void soldier_attack(edict_t *self)
                    773: {
                    774:        if (self->s.skinnum < 4)
                    775:        {
                    776:                if (random() < 0.5)
                    777:                        self->monsterinfo.currentmove = &soldier_move_attack1;
                    778:                else
                    779:                        self->monsterinfo.currentmove = &soldier_move_attack2;
                    780:        }
                    781:        else
                    782:        {
                    783:                self->monsterinfo.currentmove = &soldier_move_attack4;
                    784:        }
                    785: }
                    786: 
                    787: 
                    788: //
                    789: // SIGHT
                    790: //
                    791: 
                    792: void soldier_sight(edict_t *self, edict_t *other)
                    793: {
                    794:        if (random() < 0.5)
                    795:                gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
                    796:        else
                    797:                gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
                    798: 
                    799:        if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
                    800:        {
                    801:                if (random() > 0.5)
                    802:                        self->monsterinfo.currentmove = &soldier_move_attack6;
                    803:        }
                    804: }
                    805: 
                    806: //
                    807: // DUCK
                    808: //
                    809: 
                    810: void soldier_duck_hold (edict_t *self)
                    811: {
                    812:        if (level.time >= self->monsterinfo.pausetime)
                    813:                self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
                    814:        else
                    815:                self->monsterinfo.aiflags |= AI_HOLD_FRAME;
                    816: }
                    817: 
                    818: mframe_t soldier_frames_duck [] =
                    819: {
                    820:        ai_move, 5, soldier_duck_down,
                    821:        ai_move, -1, soldier_duck_hold,
                    822:        ai_move, 1,  NULL,
                    823:        ai_move, 0,  soldier_duck_up,
                    824:        ai_move, 5,  NULL
                    825: };
                    826: mmove_t soldier_move_duck = {FRAME_duck01, FRAME_duck05, soldier_frames_duck, soldier_run};
                    827: 
                    828: void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
                    829: {
                    830:        float   r;
                    831: 
                    832:        r = random();
                    833:        if (r > 0.25)
                    834:                return;
                    835: 
                    836:        if (!self->enemy)
                    837:                self->enemy = attacker;
                    838: 
                    839:        if (skill->value == 0)
                    840:        {
                    841:                self->monsterinfo.currentmove = &soldier_move_duck;
                    842:                return;
                    843:        }
                    844: 
                    845:        self->monsterinfo.pausetime = level.time + eta + 0.3;
                    846:        r = random();
                    847: 
                    848:        if (skill->value == 1)
                    849:        {
                    850:                if (r > 0.33)
                    851:                        self->monsterinfo.currentmove = &soldier_move_duck;
                    852:                else
                    853:                        self->monsterinfo.currentmove = &soldier_move_attack3;
                    854:                return;
                    855:        }
                    856: 
                    857:        if (skill->value >= 2)
                    858:        {
                    859:                if (r > 0.66)
                    860:                        self->monsterinfo.currentmove = &soldier_move_duck;
                    861:                else
                    862:                        self->monsterinfo.currentmove = &soldier_move_attack3;
                    863:                return;
                    864:        }
                    865: 
                    866:        self->monsterinfo.currentmove = &soldier_move_attack3;
                    867: }
                    868: 
                    869: 
                    870: //
                    871: // DEATH
                    872: //
                    873: 
                    874: void soldier_fire6 (edict_t *self)
                    875: {
                    876:        soldier_fire (self, 5);
                    877: }
                    878: 
                    879: void soldier_fire7 (edict_t *self)
                    880: {
                    881:        soldier_fire (self, 6);
                    882: }
                    883: 
                    884: void soldier_dead (edict_t *self)
                    885: {
                    886:        VectorSet (self->mins, -16, -16, -24);
                    887:        VectorSet (self->maxs, 16, 16, -8);
                    888:        self->movetype = MOVETYPE_TOSS;
                    889:        self->svflags |= SVF_DEADMONSTER;
                    890:        self->nextthink = 0;
                    891:        gi.linkentity (self);
                    892: }
                    893: 
                    894: mframe_t soldier_frames_death1 [] =
                    895: {
                    896:        ai_move, 0,   NULL,
                    897:        ai_move, -10, NULL,
                    898:        ai_move, -10, NULL,
                    899:        ai_move, -10, NULL,
                    900:        ai_move, -5,  NULL,
                    901:        ai_move, 0,   NULL,
                    902:        ai_move, 0,   NULL,
                    903:        ai_move, 0,   NULL,
                    904:        ai_move, 0,   NULL,
                    905:        ai_move, 0,   NULL,
                    906: 
                    907:        ai_move, 0,   NULL,
                    908:        ai_move, 0,   NULL,
                    909:        ai_move, 0,   NULL,
                    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:        ai_move, 0,   NULL,
                    917: 
                    918:        ai_move, 0,   NULL,
                    919:        ai_move, 0,   soldier_fire6,
                    920:        ai_move, 0,   NULL,
                    921:        ai_move, 0,   NULL,
                    922:        ai_move, 0,   soldier_fire7,
                    923:        ai_move, 0,   NULL,
                    924:        ai_move, 0,   NULL,
                    925:        ai_move, 0,   NULL,
                    926:        ai_move, 0,   NULL,
                    927:        ai_move, 0,   NULL,
                    928: 
                    929:        ai_move, 0,   NULL,
                    930:        ai_move, 0,   NULL,
                    931:        ai_move, 0,   NULL,
                    932:        ai_move, 0,   NULL,
                    933:        ai_move, 0,   NULL,
                    934:        ai_move, 0,   NULL
                    935: };
                    936: mmove_t soldier_move_death1 = {FRAME_death101, FRAME_death136, soldier_frames_death1, soldier_dead};
                    937: 
                    938: mframe_t soldier_frames_death2 [] =
                    939: {
                    940:        ai_move, -5,  NULL,
                    941:        ai_move, -5,  NULL,
                    942:        ai_move, -5,  NULL,
                    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: 
                    951:        ai_move, 0,   NULL,
                    952:        ai_move, 0,   NULL,
                    953:        ai_move, 0,   NULL,
                    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:        ai_move, 0,   NULL,
                    960:        ai_move, 0,   NULL,
                    961: 
                    962:        ai_move, 0,   NULL,
                    963:        ai_move, 0,   NULL,
                    964:        ai_move, 0,   NULL,
                    965:        ai_move, 0,   NULL,
                    966:        ai_move, 0,   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: 
                    973:        ai_move, 0,   NULL,
                    974:        ai_move, 0,   NULL,
                    975:        ai_move, 0,   NULL,
                    976:        ai_move, 0,   NULL,
                    977:        ai_move, 0,   NULL
                    978: };
                    979: mmove_t soldier_move_death2 = {FRAME_death201, FRAME_death235, soldier_frames_death2, soldier_dead};
                    980: 
                    981: mframe_t soldier_frames_death3 [] =
                    982: {
                    983:        ai_move, -5,  NULL,
                    984:        ai_move, -5,  NULL,
                    985:        ai_move, -5,  NULL,
                    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: 
                    994:        ai_move, 0,   NULL,
                    995:        ai_move, 0,   NULL,
                    996:        ai_move, 0,   NULL,
                    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: 
                   1005:        ai_move, 0,   NULL,
                   1006:        ai_move, 0,   NULL,
                   1007:        ai_move, 0,   NULL,
                   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:        ai_move, 0,   NULL,
                   1014:        ai_move, 0,   NULL,
                   1015: 
                   1016:        ai_move, 0,   NULL,
                   1017:        ai_move, 0,   NULL,
                   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: 
                   1027:        ai_move, 0,   NULL,
                   1028:        ai_move, 0,   NULL,
                   1029:        ai_move, 0,   NULL,
                   1030:        ai_move, 0,   NULL,
                   1031:        ai_move, 0,   NULL,
                   1032: };
                   1033: mmove_t soldier_move_death3 = {FRAME_death301, FRAME_death345, soldier_frames_death3, soldier_dead};
                   1034: 
                   1035: mframe_t soldier_frames_death4 [] =
                   1036: {
                   1037:        ai_move, 0,   NULL,
                   1038:        ai_move, 0,   NULL,
                   1039:        ai_move, 0,   NULL,
                   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: 
                   1048:        ai_move, 0,   NULL,
                   1049:        ai_move, 0,   NULL,
                   1050:        ai_move, 0,   NULL,
                   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: 
                   1059:        ai_move, 0,   NULL,
                   1060:        ai_move, 0,   NULL,
                   1061:        ai_move, 0,   NULL,
                   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: 
                   1070:        ai_move, 0,   NULL,
                   1071:        ai_move, 0,   NULL,
                   1072:        ai_move, 0,   NULL,
                   1073:        ai_move, 0,   NULL,
                   1074:        ai_move, 0,   NULL,
                   1075:        ai_move, 0,   NULL,
                   1076:        ai_move, 0,   NULL,
                   1077:        ai_move, 0,   NULL,
                   1078:        ai_move, 0,   NULL,
                   1079:        ai_move, 0,   NULL,
                   1080: 
                   1081:        ai_move, 0,   NULL,
                   1082:        ai_move, 0,   NULL,
                   1083:        ai_move, 0,   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: };
                   1096: mmove_t soldier_move_death4 = {FRAME_death401, FRAME_death453, soldier_frames_death4, soldier_dead};
                   1097: 
                   1098: mframe_t soldier_frames_death5 [] =
                   1099: {
                   1100:        ai_move, -5,  NULL,
                   1101:        ai_move, -5,  NULL,
                   1102:        ai_move, -5,  NULL,
                   1103:        ai_move, 0,   NULL,
                   1104:        ai_move, 0,   NULL,
                   1105:        ai_move, 0,   NULL,
                   1106:        ai_move, 0,   NULL,
                   1107:        ai_move, 0,   NULL,
                   1108:        ai_move, 0,   NULL,
                   1109:        ai_move, 0,   NULL,
                   1110: 
                   1111:        ai_move, 0,   NULL,
                   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: 
                   1122:        ai_move, 0,   NULL,
                   1123:        ai_move, 0,   NULL,
                   1124:        ai_move, 0,   NULL,
                   1125:        ai_move, 0,   NULL
                   1126: };
                   1127: mmove_t soldier_move_death5 = {FRAME_death501, FRAME_death524, soldier_frames_death5, soldier_dead};
                   1128: 
                   1129: mframe_t soldier_frames_death6 [] =
                   1130: {
                   1131:        ai_move, 0,   NULL,
                   1132:        ai_move, 0,   NULL,
                   1133:        ai_move, 0,   NULL,
                   1134:        ai_move, 0,   NULL,
                   1135:        ai_move, 0,   NULL,
                   1136:        ai_move, 0,   NULL,
                   1137:        ai_move, 0,   NULL,
                   1138:        ai_move, 0,   NULL,
                   1139:        ai_move, 0,   NULL,
                   1140:        ai_move, 0,   NULL
                   1141: };
                   1142: mmove_t soldier_move_death6 = {FRAME_death601, FRAME_death610, soldier_frames_death6, soldier_dead};
                   1143: 
                   1144: void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
                   1145: {
                   1146:        int             n;
                   1147: 
                   1148: // check for gib
                   1149:        if (self->health <= self->gib_health)
                   1150:        {
                   1151:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
                   1152:                for (n= 0; n < 3; n++)
                   1153:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
                   1154:                ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
                   1155:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
                   1156:                self->deadflag = DEAD_DEAD;
                   1157:                return;
                   1158:        }
                   1159: 
                   1160:        if (self->deadflag == DEAD_DEAD)
                   1161:                return;
                   1162: 
                   1163: // regular death
                   1164:        self->deadflag = DEAD_DEAD;
                   1165:        self->takedamage = DAMAGE_YES;
                   1166:        self->s.skinnum |= 1;
                   1167: 
                   1168:        if (self->s.skinnum == 1)
                   1169:                gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
                   1170:        else if (self->s.skinnum == 3)
                   1171:                gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
                   1172:        else // (self->s.skinnum == 5)
                   1173:                gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
                   1174: 
                   1175:        if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
                   1176:        {
                   1177:                // head shot
                   1178:                self->monsterinfo.currentmove = &soldier_move_death3;
                   1179:                return;
                   1180:        }
                   1181: 
                   1182:        n = rand() % 5;
                   1183:        if (n == 0)
                   1184:                self->monsterinfo.currentmove = &soldier_move_death1;
                   1185:        else if (n == 1)
                   1186:                self->monsterinfo.currentmove = &soldier_move_death2;
                   1187:        else if (n == 2)
                   1188:                self->monsterinfo.currentmove = &soldier_move_death4;
                   1189:        else if (n == 3)
                   1190:                self->monsterinfo.currentmove = &soldier_move_death5;
                   1191:        else
                   1192:                self->monsterinfo.currentmove = &soldier_move_death6;
                   1193: }
                   1194: 
                   1195: 
                   1196: //
                   1197: // SPAWN
                   1198: //
                   1199: 
                   1200: void SP_monster_soldier_x (edict_t *self)
                   1201: {
                   1202: 
                   1203:        self->s.modelindex = gi.modelindex ("models/monsters/soldier/tris.md2");
                   1204:        self->monsterinfo.scale = MODEL_SCALE;
                   1205:        VectorSet (self->mins, -16, -16, -24);
                   1206:        VectorSet (self->maxs, 16, 16, 32);
                   1207:        self->movetype = MOVETYPE_STEP;
                   1208:        self->solid = SOLID_BBOX;
                   1209: 
                   1210:        sound_idle =    gi.soundindex ("soldier/solidle1.wav");
                   1211:        sound_sight1 =  gi.soundindex ("soldier/solsght1.wav");
                   1212:        sound_sight2 =  gi.soundindex ("soldier/solsrch1.wav");
                   1213:        sound_cock =    gi.soundindex ("infantry/infatck3.wav");
                   1214: 
                   1215:        self->mass = 100;
                   1216: 
                   1217:        self->pain = soldier_pain;
                   1218:        self->die = soldier_die;
                   1219: 
                   1220:        self->monsterinfo.stand = soldier_stand;
                   1221:        self->monsterinfo.walk = soldier_walk;
                   1222:        self->monsterinfo.run = soldier_run;
                   1223:        self->monsterinfo.dodge = soldier_dodge;
                   1224:        self->monsterinfo.attack = soldier_attack;
                   1225:        self->monsterinfo.melee = NULL;
                   1226:        self->monsterinfo.sight = soldier_sight;
                   1227: 
                   1228:        gi.linkentity (self);
                   1229: 
                   1230:        self->monsterinfo.stand (self);
                   1231: 
                   1232:        walkmonster_start (self);
                   1233: }
                   1234: 
                   1235: 
                   1236: /*QUAKED monster_soldier_light (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
                   1237: */
                   1238: void SP_monster_soldier_light (edict_t *self)
                   1239: {
                   1240:        if (deathmatch->value)
                   1241:        {
                   1242:                G_FreeEdict (self);
                   1243:                return;
                   1244:        }
                   1245: 
                   1246:        SP_monster_soldier_x (self);
                   1247: 
                   1248:        sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
                   1249:        sound_death_light =     gi.soundindex ("soldier/soldeth2.wav");
                   1250:        gi.modelindex ("models/objects/laser/tris.md2");
                   1251:        gi.soundindex ("misc/lasfly.wav");
                   1252:        gi.soundindex ("soldier/solatck2.wav");
                   1253: 
                   1254:        self->s.skinnum = 0;
                   1255:        self->health = 20;
                   1256:        self->gib_health = -30;
                   1257: }
                   1258: 
                   1259: /*QUAKED monster_soldier (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
                   1260: */
                   1261: void SP_monster_soldier (edict_t *self)
                   1262: {
                   1263:        if (deathmatch->value)
                   1264:        {
                   1265:                G_FreeEdict (self);
                   1266:                return;
                   1267:        }
                   1268: 
                   1269:        SP_monster_soldier_x (self);
                   1270: 
                   1271:        sound_pain = gi.soundindex ("soldier/solpain1.wav");
                   1272:        sound_death = gi.soundindex ("soldier/soldeth1.wav");
                   1273:        gi.soundindex ("soldier/solatck1.wav");
                   1274: 
                   1275:        self->s.skinnum = 2;
                   1276:        self->health = 30;
                   1277:        self->gib_health = -30;
                   1278: }
                   1279: 
                   1280: /*QUAKED monster_soldier_ss (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
                   1281: */
                   1282: void SP_monster_soldier_ss (edict_t *self)
                   1283: {
                   1284:        if (deathmatch->value)
                   1285:        {
                   1286:                G_FreeEdict (self);
                   1287:                return;
                   1288:        }
                   1289: 
                   1290:        SP_monster_soldier_x (self);
                   1291: 
                   1292:        sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
                   1293:        sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
                   1294:        gi.soundindex ("soldier/solatck3.wav");
                   1295: 
                   1296:        self->s.skinnum = 4;
                   1297:        self->health = 40;
                   1298:        self->gib_health = -30;
                   1299: }

unix.superglobalmegacorp.com

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