Annotation of quake2/xatrix/m_boss2.c, revision 1.1.1.1

1.1       root        1: /*
                      2: ==============================================================================
                      3: 
                      4: boss2
                      5: 
                      6: ==============================================================================
                      7: */
                      8: 
                      9: #include "g_local.h"
                     10: #include "m_boss2.h"
                     11: 
                     12: void BossExplode (edict_t *self);
                     13: 
                     14: qboolean infront (edict_t *self, edict_t *other);
                     15: 
                     16: static int     sound_pain1;
                     17: static int     sound_pain2;
                     18: static int     sound_pain3;
                     19: static int     sound_death;
                     20: static int     sound_search1;
                     21: 
                     22: void boss2_search (edict_t *self)
                     23: {
                     24:        if (random() < 0.5)
                     25:                gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0);
                     26: }
                     27: 
                     28: void boss2_run (edict_t *self);
                     29: void boss2_stand (edict_t *self);
                     30: void boss2_dead (edict_t *self);
                     31: void boss2_attack (edict_t *self);
                     32: void boss2_attack_mg (edict_t *self);
                     33: void boss2_reattack_mg (edict_t *self);
                     34: void boss2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
                     35: 
                     36: void Boss2Rocket (edict_t *self)
                     37: {
                     38:        vec3_t  forward, right;
                     39:        vec3_t  start;
                     40:        vec3_t  dir;
                     41:        vec3_t  vec;
                     42: 
                     43:        AngleVectors (self->s.angles, forward, right, NULL);
                     44: 
                     45: //1
                     46:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start);
                     47:        VectorCopy (self->enemy->s.origin, vec);
                     48:        vec[2] += self->enemy->viewheight;
                     49:        VectorSubtract (vec, start, dir);
                     50:        VectorNormalize (dir);
                     51:        monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1);
                     52: 
                     53: //2
                     54:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start);
                     55:        VectorCopy (self->enemy->s.origin, vec);
                     56:        vec[2] += self->enemy->viewheight;
                     57:        VectorSubtract (vec, start, dir);
                     58:        VectorNormalize (dir);
                     59:        monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2);
                     60: 
                     61: //3
                     62:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start);
                     63:        VectorCopy (self->enemy->s.origin, vec);
                     64:        vec[2] += self->enemy->viewheight;
                     65:        VectorSubtract (vec, start, dir);
                     66:        VectorNormalize (dir);
                     67:        monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3);
                     68: 
                     69: //4
                     70:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start);
                     71:        VectorCopy (self->enemy->s.origin, vec);
                     72:        vec[2] += self->enemy->viewheight;
                     73:        VectorSubtract (vec, start, dir);
                     74:        VectorNormalize (dir);
                     75:        monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4);
                     76: }      
                     77: 
                     78: void boss2_firebullet_right (edict_t *self)
                     79: {
                     80:        vec3_t  forward, right, target;
                     81:        vec3_t  start;
                     82: 
                     83:        AngleVectors (self->s.angles, forward, right, NULL);
                     84:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_R1], forward, right, start);
                     85: 
                     86:        VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
                     87:        target[2] += self->enemy->viewheight;
                     88:        VectorSubtract (target, start, forward);
                     89:        VectorNormalize (forward);
                     90: 
                     91:        monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_R1);
                     92: }      
                     93: 
                     94: void boss2_firebullet_left (edict_t *self)
                     95: {
                     96:        vec3_t  forward, right, target;
                     97:        vec3_t  start;
                     98:        
                     99:        AngleVectors (self->s.angles, forward, right, NULL);
                    100:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_L1], forward, right, start);
                    101: 
                    102:        VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
                    103: 
                    104:        target[2] += self->enemy->viewheight;
                    105:        VectorSubtract (target, start, forward);
                    106:        VectorNormalize (forward);
                    107: 
                    108:        monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_L1);
                    109: }      
                    110: 
                    111: void Boss2MachineGun (edict_t *self)
                    112: {
                    113: /*     vec3_t  forward, right;
                    114:        vec3_t  start;
                    115:        vec3_t  dir;
                    116:        vec3_t  vec;
                    117:        int             flash_number;
                    118: 
                    119:        AngleVectors (self->s.angles, forward, right, NULL);
                    120: 
                    121:        flash_number = MZ2_BOSS2_MACHINEGUN_1 + (self->s.frame - FRAME_attack10);
                    122:        G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
                    123: 
                    124:        VectorCopy (self->enemy->s.origin, vec);
                    125:        vec[2] += self->enemy->viewheight;
                    126:        VectorSubtract (vec, start, dir);
                    127:        VectorNormalize (dir);
                    128:        monster_fire_bullet (self, start, dir, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
                    129: */
                    130:        boss2_firebullet_left(self);
                    131:        boss2_firebullet_right(self);
                    132: }      
                    133: 
                    134: 
                    135: mframe_t boss2_frames_stand [] =
                    136: {
                    137:        ai_stand, 0, NULL,
                    138:        ai_stand, 0, NULL,
                    139:        ai_stand, 0, NULL,
                    140:        ai_stand, 0, NULL,
                    141:        ai_stand, 0, NULL,
                    142:        ai_stand, 0, NULL,
                    143:        ai_stand, 0, NULL,
                    144:        ai_stand, 0, NULL,
                    145:        ai_stand, 0, NULL,
                    146:        ai_stand, 0, NULL,
                    147:        ai_stand, 0, NULL,
                    148:        ai_stand, 0, NULL,
                    149:        ai_stand, 0, NULL,
                    150:        ai_stand, 0, NULL,
                    151:        ai_stand, 0, NULL,
                    152:        ai_stand, 0, NULL,
                    153:        ai_stand, 0, NULL,
                    154:        ai_stand, 0, NULL,
                    155:        ai_stand, 0, NULL,
                    156:        ai_stand, 0, NULL,
                    157:        ai_stand, 0, NULL
                    158: };
                    159: mmove_t        boss2_move_stand = {FRAME_stand30, FRAME_stand50, boss2_frames_stand, NULL};
                    160: 
                    161: mframe_t boss2_frames_fidget [] =
                    162: {
                    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:        ai_stand, 0, NULL,
                    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:        ai_stand, 0, NULL,
                    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: mmove_t boss2_move_fidget = {FRAME_stand1, FRAME_stand30, boss2_frames_fidget, NULL};
                    195: 
                    196: mframe_t boss2_frames_walk [] =
                    197: {
                    198:        ai_walk,        8,      NULL,
                    199:        ai_walk,        8,      NULL,
                    200:        ai_walk,        8,      NULL,
                    201:        ai_walk,        8,      NULL,
                    202:        ai_walk,        8,      NULL,
                    203:        ai_walk,        8,      NULL,
                    204:        ai_walk,        8,      NULL,
                    205:        ai_walk,        8,      NULL,
                    206:        ai_walk,        8,      NULL,
                    207:        ai_walk,        8,      NULL,
                    208:        ai_walk,        8,      NULL,
                    209:        ai_walk,        8,      NULL,
                    210:        ai_walk,        8,      NULL,
                    211:        ai_walk,        8,      NULL,
                    212:        ai_walk,        8,      NULL,
                    213:        ai_walk,        8,      NULL,
                    214:        ai_walk,        8,      NULL,
                    215:        ai_walk,        8,      NULL,
                    216:        ai_walk,        8,      NULL,
                    217:        ai_walk,        8,      NULL
                    218: };
                    219: mmove_t boss2_move_walk = {FRAME_walk1, FRAME_walk20, boss2_frames_walk, NULL};
                    220: 
                    221: 
                    222: mframe_t boss2_frames_run [] =
                    223: {
                    224:        ai_run, 8,      NULL,
                    225:        ai_run, 8,      NULL,
                    226:        ai_run, 8,      NULL,
                    227:        ai_run, 8,      NULL,
                    228:        ai_run, 8,      NULL,
                    229:        ai_run, 8,      NULL,
                    230:        ai_run, 8,      NULL,
                    231:        ai_run, 8,      NULL,
                    232:        ai_run, 8,      NULL,
                    233:        ai_run, 8,      NULL,
                    234:        ai_run, 8,      NULL,
                    235:        ai_run, 8,      NULL,
                    236:        ai_run, 8,      NULL,
                    237:        ai_run, 8,      NULL,
                    238:        ai_run, 8,      NULL,
                    239:        ai_run, 8,      NULL,
                    240:        ai_run, 8,      NULL,
                    241:        ai_run, 8,      NULL,
                    242:        ai_run, 8,      NULL,
                    243:        ai_run, 8,      NULL
                    244: };
                    245: mmove_t boss2_move_run = {FRAME_walk1, FRAME_walk20, boss2_frames_run, NULL};
                    246: 
                    247: mframe_t boss2_frames_attack_pre_mg [] =
                    248: {
                    249:        ai_charge,      1,      NULL,
                    250:        ai_charge,      1,      NULL,
                    251:        ai_charge,      1,      NULL,
                    252:        ai_charge,      1,      NULL,
                    253:        ai_charge,      1,      NULL,
                    254:        ai_charge,      1,      NULL,
                    255:        ai_charge,      1,      NULL,
                    256:        ai_charge,      1,      NULL,
                    257:        ai_charge,      1,      boss2_attack_mg
                    258: };
                    259: mmove_t boss2_move_attack_pre_mg = {FRAME_attack1, FRAME_attack9, boss2_frames_attack_pre_mg, NULL};
                    260: 
                    261: 
                    262: // Loop this
                    263: mframe_t boss2_frames_attack_mg [] =
                    264: {
                    265:        ai_charge,      1,      Boss2MachineGun,
                    266:        ai_charge,      1,      Boss2MachineGun,
                    267:        ai_charge,      1,      Boss2MachineGun,
                    268:        ai_charge,      1,      Boss2MachineGun,
                    269:        ai_charge,      1,      Boss2MachineGun,
                    270:        ai_charge,      1,      boss2_reattack_mg
                    271: };
                    272: mmove_t boss2_move_attack_mg = {FRAME_attack10, FRAME_attack15, boss2_frames_attack_mg, NULL};
                    273: 
                    274: mframe_t boss2_frames_attack_post_mg [] =
                    275: {
                    276:        ai_charge,      1,      NULL,
                    277:        ai_charge,      1,      NULL,
                    278:        ai_charge,      1,      NULL,
                    279:        ai_charge,      1,      NULL
                    280: };
                    281: mmove_t boss2_move_attack_post_mg = {FRAME_attack16, FRAME_attack19, boss2_frames_attack_post_mg, boss2_run};
                    282: 
                    283: mframe_t boss2_frames_attack_rocket [] =
                    284: {
                    285:        ai_charge,      1,      NULL,
                    286:        ai_charge,      1,      NULL,
                    287:        ai_charge,      1,      NULL,
                    288:        ai_charge,      1,      NULL,
                    289:        ai_charge,      1,      NULL,
                    290:        ai_charge,      1,      NULL,
                    291:        ai_charge,      1,      NULL,
                    292:        ai_charge,      1,      NULL,
                    293:        ai_charge,      1,      NULL,
                    294:        ai_charge,      1,      NULL,
                    295:        ai_charge,      1,      NULL,
                    296:        ai_charge,      1,      NULL,
                    297:        ai_move,        -20,    Boss2Rocket,
                    298:        ai_charge,      1,      NULL,
                    299:        ai_charge,      1,      NULL,
                    300:        ai_charge,      1,      NULL,
                    301:        ai_charge,      1,      NULL,
                    302:        ai_charge,      1,      NULL,
                    303:        ai_charge,      1,      NULL,
                    304:        ai_charge,      1,      NULL,
                    305:        ai_charge,      1,      NULL
                    306: };
                    307: mmove_t boss2_move_attack_rocket = {FRAME_attack20, FRAME_attack40, boss2_frames_attack_rocket, boss2_run};
                    308: 
                    309: mframe_t boss2_frames_pain_heavy [] =
                    310: {
                    311:        ai_move,        0,      NULL,
                    312:        ai_move,        0,      NULL,
                    313:        ai_move,        0,      NULL,
                    314:        ai_move,        0,      NULL,
                    315:        ai_move,        0,      NULL,
                    316:        ai_move,        0,      NULL,
                    317:        ai_move,        0,      NULL,
                    318:        ai_move,        0,      NULL,
                    319:        ai_move,        0,      NULL,
                    320:        ai_move,        0,      NULL,
                    321:        ai_move,        0,      NULL,
                    322:        ai_move,        0,      NULL,
                    323:        ai_move,        0,      NULL,
                    324:        ai_move,        0,      NULL,
                    325:        ai_move,        0,      NULL,
                    326:        ai_move,        0,      NULL,
                    327:        ai_move,        0,      NULL,
                    328:        ai_move,        0,      NULL
                    329: };
                    330: mmove_t boss2_move_pain_heavy = {FRAME_pain2, FRAME_pain19, boss2_frames_pain_heavy, boss2_run};
                    331: 
                    332: mframe_t boss2_frames_pain_light [] =
                    333: {
                    334:        ai_move,        0,      NULL,
                    335:        ai_move,        0,      NULL,
                    336:        ai_move,        0,      NULL,
                    337:        ai_move,        0,      NULL
                    338: };
                    339: mmove_t boss2_move_pain_light = {FRAME_pain20, FRAME_pain23, boss2_frames_pain_light, boss2_run};
                    340: 
                    341: mframe_t boss2_frames_death [] =
                    342: {
                    343:        ai_move,        0,      NULL,
                    344:        ai_move,        0,      NULL,
                    345:        ai_move,        0,      NULL,
                    346:        ai_move,        0,      NULL,
                    347:        ai_move,        0,      NULL,
                    348:        ai_move,        0,      NULL,
                    349:        ai_move,        0,      NULL,
                    350:        ai_move,        0,      NULL,
                    351:        ai_move,        0,      NULL,
                    352:        ai_move,        0,      NULL,
                    353:        ai_move,        0,      NULL,
                    354:        ai_move,        0,      NULL,
                    355:        ai_move,        0,      NULL,
                    356:        ai_move,        0,      NULL,
                    357:        ai_move,        0,      NULL,
                    358:        ai_move,        0,      NULL,
                    359:        ai_move,        0,      NULL,
                    360:        ai_move,        0,      NULL,
                    361:        ai_move,        0,      NULL,
                    362:        ai_move,        0,      NULL,
                    363:        ai_move,        0,      NULL,
                    364:        ai_move,        0,      NULL,
                    365:        ai_move,        0,      NULL,
                    366:        ai_move,        0,      NULL,
                    367:        ai_move,        0,      NULL,
                    368:        ai_move,        0,      NULL,
                    369:        ai_move,        0,      NULL,
                    370:        ai_move,        0,      NULL,
                    371:        ai_move,        0,      NULL,
                    372:        ai_move,        0,      NULL,
                    373:        ai_move,        0,      NULL,
                    374:        ai_move,        0,      NULL,
                    375:        ai_move,        0,      NULL,
                    376:        ai_move,        0,      NULL,
                    377:        ai_move,        0,      NULL,
                    378:        ai_move,        0,      NULL,
                    379:        ai_move,        0,      NULL,
                    380:        ai_move,        0,      NULL,
                    381:        ai_move,        0,      NULL,
                    382:        ai_move,        0,      NULL,
                    383:        ai_move,        0,      NULL,
                    384:        ai_move,        0,      NULL,
                    385:        ai_move,        0,      NULL,
                    386:        ai_move,        0,      NULL,
                    387:        ai_move,        0,      NULL,
                    388:        ai_move,        0,      NULL,
                    389:        ai_move,        0,      NULL,
                    390:        ai_move,        0,      NULL,
                    391:        ai_move,        0,      BossExplode
                    392: };
                    393: mmove_t boss2_move_death = {FRAME_death2, FRAME_death50, boss2_frames_death, boss2_dead};
                    394: 
                    395: void boss2_stand (edict_t *self)
                    396: {
                    397:                self->monsterinfo.currentmove = &boss2_move_stand;
                    398: }
                    399: 
                    400: void boss2_run (edict_t *self)
                    401: {
                    402:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
                    403:                self->monsterinfo.currentmove = &boss2_move_stand;
                    404:        else
                    405:                self->monsterinfo.currentmove = &boss2_move_run;
                    406: }
                    407: 
                    408: void boss2_walk (edict_t *self)
                    409: {
                    410:        self->monsterinfo.currentmove = &boss2_move_walk;
                    411: }
                    412: 
                    413: void boss2_attack (edict_t *self)
                    414: {
                    415:        vec3_t  vec;
                    416:        float   range;
                    417: 
                    418:        VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
                    419:        range = VectorLength (vec);
                    420:        
                    421:        if (range <= 125)
                    422:        {
                    423:                self->monsterinfo.currentmove = &boss2_move_attack_pre_mg;
                    424:        }
                    425:        else 
                    426:        {
                    427:                if (random() <= 0.6)
                    428:                        self->monsterinfo.currentmove = &boss2_move_attack_pre_mg;
                    429:                else
                    430:                        self->monsterinfo.currentmove = &boss2_move_attack_rocket;
                    431:        }
                    432: }
                    433: 
                    434: void boss2_attack_mg (edict_t *self)
                    435: {
                    436:        self->monsterinfo.currentmove = &boss2_move_attack_mg;
                    437: }
                    438: 
                    439: void boss2_reattack_mg (edict_t *self)
                    440: {
                    441:        if ( infront(self, self->enemy) )
                    442:                if (random() <= 0.7)
                    443:                        self->monsterinfo.currentmove = &boss2_move_attack_mg;
                    444:                else
                    445:                        self->monsterinfo.currentmove = &boss2_move_attack_post_mg;
                    446:        else
                    447:                self->monsterinfo.currentmove = &boss2_move_attack_post_mg;
                    448: }
                    449: 
                    450: 
                    451: void boss2_pain (edict_t *self, edict_t *other, float kick, int damage)
                    452: {
                    453:        if (self->health < (self->max_health / 2))
                    454:                self->s.skinnum = 1;
                    455: 
                    456:        if (level.time < self->pain_debounce_time)
                    457:                return;
                    458: 
                    459:        self->pain_debounce_time = level.time + 3;
                    460: // American wanted these at no attenuation
                    461:        if (damage < 10)
                    462:        {
                    463:                gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0);
                    464:                self->monsterinfo.currentmove = &boss2_move_pain_light;
                    465:        }
                    466:        else if (damage < 30)
                    467:        {
                    468:                gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0);
                    469:                self->monsterinfo.currentmove = &boss2_move_pain_light;
                    470:        }
                    471:        else 
                    472:        {
                    473:                gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0);
                    474:                self->monsterinfo.currentmove = &boss2_move_pain_heavy;
                    475:        }
                    476: }
                    477: 
                    478: void boss2_dead (edict_t *self)
                    479: {
                    480:        VectorSet (self->mins, -56, -56, 0);
                    481:        VectorSet (self->maxs, 56, 56, 80);
                    482:        self->movetype = MOVETYPE_TOSS;
                    483:        self->svflags |= SVF_DEADMONSTER;
                    484:        self->nextthink = 0;
                    485:        gi.linkentity (self);
                    486: }
                    487: 
                    488: void boss2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
                    489: {
                    490:        gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
                    491:        self->deadflag = DEAD_DEAD;
                    492:        self->takedamage = DAMAGE_NO;
                    493:        self->count = 0;
                    494:        self->monsterinfo.currentmove = &boss2_move_death;
                    495: #if 0
                    496:        int             n;
                    497: 
                    498:        self->s.sound = 0;
                    499:        // check for gib
                    500:        if (self->health <= self->gib_health)
                    501:        {
                    502:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
                    503:                for (n= 0; n < 2; n++)
                    504:                        ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
                    505:                for (n= 0; n < 4; n++)
                    506:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
                    507:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
                    508:                self->deadflag = DEAD_DEAD;
                    509:                return;
                    510:        }
                    511: 
                    512:        if (self->deadflag == DEAD_DEAD)
                    513:                return;
                    514: 
                    515:        self->deadflag = DEAD_DEAD;
                    516:        self->takedamage = DAMAGE_YES;
                    517:        self->monsterinfo.currentmove = &boss2_move_death;
                    518: #endif
                    519: }
                    520: 
                    521: qboolean Boss2_CheckAttack (edict_t *self)
                    522: {
                    523:        vec3_t  spot1, spot2;
                    524:        vec3_t  temp;
                    525:        float   chance;
                    526:        trace_t tr;
                    527:        qboolean        enemy_infront;
                    528:        int                     enemy_range;
                    529:        float           enemy_yaw;
                    530: 
                    531:        if (self->enemy->health > 0)
                    532:        {
                    533:        // see if any entities are in the way of the shot
                    534:                VectorCopy (self->s.origin, spot1);
                    535:                spot1[2] += self->viewheight;
                    536:                VectorCopy (self->enemy->s.origin, spot2);
                    537:                spot2[2] += self->enemy->viewheight;
                    538: 
                    539:                tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA);
                    540: 
                    541:                // do we have a clear shot?
                    542:                if (tr.ent != self->enemy)
                    543:                        return false;
                    544:        }
                    545:        
                    546:        enemy_infront = infront(self, self->enemy);
                    547:        enemy_range = range(self, self->enemy);
                    548:        VectorSubtract (self->enemy->s.origin, self->s.origin, temp);
                    549:        enemy_yaw = vectoyaw(temp);
                    550: 
                    551:        self->ideal_yaw = enemy_yaw;
                    552: 
                    553: 
                    554:        // melee attack
                    555:        if (enemy_range == RANGE_MELEE)
                    556:        {
                    557:                if (self->monsterinfo.melee)
                    558:                        self->monsterinfo.attack_state = AS_MELEE;
                    559:                else
                    560:                        self->monsterinfo.attack_state = AS_MISSILE;
                    561:                return true;
                    562:        }
                    563:        
                    564: // missile attack
                    565:        if (!self->monsterinfo.attack)
                    566:                return false;
                    567:                
                    568:        if (level.time < self->monsterinfo.attack_finished)
                    569:                return false;
                    570:                
                    571:        if (enemy_range == RANGE_FAR)
                    572:                return false;
                    573: 
                    574:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
                    575:        {
                    576:                chance = 0.4;
                    577:        }
                    578:        else if (enemy_range == RANGE_MELEE)
                    579:        {
                    580:                chance = 0.8;
                    581:        }
                    582:        else if (enemy_range == RANGE_NEAR)
                    583:        {
                    584:                chance = 0.8;
                    585:        }
                    586:        else if (enemy_range == RANGE_MID)
                    587:        {
                    588:                chance = 0.8;
                    589:        }
                    590:        else
                    591:        {
                    592:                return false;
                    593:        }
                    594: 
                    595:        if (random () < chance)
                    596:        {
                    597:                self->monsterinfo.attack_state = AS_MISSILE;
                    598:                self->monsterinfo.attack_finished = level.time + 2*random();
                    599:                return true;
                    600:        }
                    601: 
                    602:        if (self->flags & FL_FLY)
                    603:        {
                    604:                if (random() < 0.3)
                    605:                        self->monsterinfo.attack_state = AS_SLIDING;
                    606:                else
                    607:                        self->monsterinfo.attack_state = AS_STRAIGHT;
                    608:        }
                    609: 
                    610:        return false;
                    611: }
                    612: 
                    613: 
                    614: 
                    615: /*QUAKED monster_boss2 (1 .5 0) (-56 -56 0) (56 56 80) Ambush Trigger_Spawn Sight
                    616: */
                    617: void SP_monster_boss2 (edict_t *self)
                    618: {
                    619:        if (deathmatch->value)
                    620:        {
                    621:                G_FreeEdict (self);
                    622:                return;
                    623:        }
                    624: 
                    625:        sound_pain1 = gi.soundindex ("bosshovr/bhvpain1.wav");
                    626:        sound_pain2 = gi.soundindex ("bosshovr/bhvpain2.wav");
                    627:        sound_pain3 = gi.soundindex ("bosshovr/bhvpain3.wav");
                    628:        sound_death = gi.soundindex ("bosshovr/bhvdeth1.wav");
                    629:        sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav");
                    630: 
                    631:        self->s.sound = gi.soundindex ("bosshovr/bhvengn1.wav");
                    632: 
                    633:        self->movetype = MOVETYPE_STEP;
                    634:        self->solid = SOLID_BBOX;
                    635:        self->s.modelindex = gi.modelindex ("models/monsters/boss2/tris.md2");
                    636:        VectorSet (self->mins, -56, -56, 0);
                    637:        VectorSet (self->maxs, 56, 56, 80);
                    638: 
                    639:        self->health = 2000;
                    640:        self->gib_health = -200;
                    641:        self->mass = 1000;
                    642: 
                    643:        self->flags |= FL_IMMUNE_LASER;
                    644: 
                    645:        self->pain = boss2_pain;
                    646:        self->die = boss2_die;
                    647: 
                    648:        self->monsterinfo.stand = boss2_stand;
                    649:        self->monsterinfo.walk = boss2_walk;
                    650:        self->monsterinfo.run = boss2_run;
                    651:        self->monsterinfo.attack = boss2_attack;
                    652:        self->monsterinfo.search = boss2_search;
                    653:        self->monsterinfo.checkattack = Boss2_CheckAttack;
                    654:        gi.linkentity (self);
                    655: 
                    656:        self->monsterinfo.currentmove = &boss2_move_stand;      
                    657:        self->monsterinfo.scale = MODEL_SCALE;
                    658: 
                    659:        flymonster_start (self);
                    660: }

unix.superglobalmegacorp.com

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