Annotation of quake2/rogue/m_chick.c, revision 1.1

1.1     ! root        1: /*
        !             2: ==============================================================================
        !             3: 
        !             4: chick
        !             5: 
        !             6: ==============================================================================
        !             7: */
        !             8: 
        !             9: #include "g_local.h"
        !            10: #include "m_chick.h"
        !            11: 
        !            12: // ROGUE
        !            13: #define LEAD_TARGET            1
        !            14: // ROGUE
        !            15: 
        !            16: qboolean visible (edict_t *self, edict_t *other);
        !            17: 
        !            18: void chick_stand (edict_t *self);
        !            19: void chick_run (edict_t *self);
        !            20: void chick_reslash(edict_t *self);
        !            21: void chick_rerocket(edict_t *self);
        !            22: void chick_attack1(edict_t *self);
        !            23: 
        !            24: static int     sound_missile_prelaunch;
        !            25: static int     sound_missile_launch;
        !            26: static int     sound_melee_swing;
        !            27: static int     sound_melee_hit;
        !            28: static int     sound_missile_reload;
        !            29: static int     sound_death1;
        !            30: static int     sound_death2;
        !            31: static int     sound_fall_down;
        !            32: static int     sound_idle1;
        !            33: static int     sound_idle2;
        !            34: static int     sound_pain1;
        !            35: static int     sound_pain2;
        !            36: static int     sound_pain3;
        !            37: static int     sound_sight;
        !            38: static int     sound_search;
        !            39: 
        !            40: void ChickMoan (edict_t *self)
        !            41: {
        !            42:        if (random() < 0.5)
        !            43:                gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
        !            44:        else
        !            45:                gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0);
        !            46: }
        !            47: 
        !            48: mframe_t chick_frames_fidget [] =
        !            49: {
        !            50:        ai_stand, 0,  NULL,
        !            51:        ai_stand, 0,  NULL,
        !            52:        ai_stand, 0,  NULL,
        !            53:        ai_stand, 0,  NULL,
        !            54:        ai_stand, 0,  NULL,
        !            55:        ai_stand, 0,  NULL,
        !            56:        ai_stand, 0,  NULL,
        !            57:        ai_stand, 0,  NULL,
        !            58:        ai_stand, 0,  ChickMoan,
        !            59:        ai_stand, 0,  NULL,
        !            60:        ai_stand, 0,  NULL,
        !            61:        ai_stand, 0,  NULL,
        !            62:        ai_stand, 0,  NULL,
        !            63:        ai_stand, 0,  NULL,
        !            64:        ai_stand, 0,  NULL,
        !            65:        ai_stand, 0,  NULL,
        !            66:        ai_stand, 0,  NULL,
        !            67:        ai_stand, 0,  NULL,
        !            68:        ai_stand, 0,  NULL,
        !            69:        ai_stand, 0,  NULL,
        !            70:        ai_stand, 0,  NULL,
        !            71:        ai_stand, 0,  NULL,
        !            72:        ai_stand, 0,  NULL,
        !            73:        ai_stand, 0,  NULL,
        !            74:        ai_stand, 0,  NULL,
        !            75:        ai_stand, 0,  NULL,
        !            76:        ai_stand, 0,  NULL,
        !            77:        ai_stand, 0,  NULL,
        !            78:        ai_stand, 0,  NULL,
        !            79:        ai_stand, 0,  NULL
        !            80: };
        !            81: mmove_t chick_move_fidget = {FRAME_stand201, FRAME_stand230, chick_frames_fidget, chick_stand};
        !            82: 
        !            83: void chick_fidget (edict_t *self)
        !            84: {
        !            85:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
        !            86:                return;
        !            87:        if (random() <= 0.3)
        !            88:                self->monsterinfo.currentmove = &chick_move_fidget;
        !            89: }
        !            90: 
        !            91: mframe_t chick_frames_stand [] =
        !            92: {
        !            93:        ai_stand, 0, NULL,
        !            94:        ai_stand, 0, NULL,
        !            95:        ai_stand, 0, NULL,
        !            96:        ai_stand, 0, NULL,
        !            97:        ai_stand, 0, NULL,
        !            98:        ai_stand, 0, NULL,
        !            99:        ai_stand, 0, NULL,
        !           100:        ai_stand, 0, NULL,
        !           101:        ai_stand, 0, NULL,
        !           102:        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:        ai_stand, 0, NULL,
        !           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, chick_fidget,
        !           123: 
        !           124: };
        !           125: mmove_t chick_move_stand = {FRAME_stand101, FRAME_stand130, chick_frames_stand, NULL};
        !           126: 
        !           127: void chick_stand (edict_t *self)
        !           128: {
        !           129:        self->monsterinfo.currentmove = &chick_move_stand;
        !           130: }
        !           131: 
        !           132: mframe_t chick_frames_start_run [] =
        !           133: {
        !           134:        ai_run, 1,  NULL,
        !           135:        ai_run, 0,  NULL,
        !           136:        ai_run, 0,       NULL,
        !           137:        ai_run, -1, NULL, 
        !           138:        ai_run, -1, NULL, 
        !           139:        ai_run, 0,  NULL,
        !           140:        ai_run, 1,  NULL,
        !           141:        ai_run, 3,  NULL,
        !           142:        ai_run, 6,       NULL,
        !           143:        ai_run, 3,       NULL
        !           144: };
        !           145: mmove_t chick_move_start_run = {FRAME_walk01, FRAME_walk10, chick_frames_start_run, chick_run};
        !           146: 
        !           147: mframe_t chick_frames_run [] =
        !           148: {
        !           149:        ai_run, 6,      NULL,
        !           150:        ai_run, 8,  NULL,
        !           151:        ai_run, 13, NULL,
        !           152:        ai_run, 5,  monster_done_dodge,  // make sure to clear dodge bit
        !           153:        ai_run, 7,  NULL,
        !           154:        ai_run, 4,  NULL,
        !           155:        ai_run, 11, NULL,
        !           156:        ai_run, 5,  NULL,
        !           157:        ai_run, 9,  NULL,
        !           158:        ai_run, 7,  NULL
        !           159: };
        !           160: 
        !           161: mmove_t chick_move_run = {FRAME_walk11, FRAME_walk20, chick_frames_run, NULL};
        !           162: 
        !           163: mframe_t chick_frames_walk [] =
        !           164: {
        !           165:        ai_walk, 6,      NULL,
        !           166:        ai_walk, 8,  NULL,
        !           167:        ai_walk, 13, NULL,
        !           168:        ai_walk, 5,  NULL,
        !           169:        ai_walk, 7,  NULL,
        !           170:        ai_walk, 4,  NULL,
        !           171:        ai_walk, 11, NULL,
        !           172:        ai_walk, 5,  NULL,
        !           173:        ai_walk, 9,  NULL,
        !           174:        ai_walk, 7,  NULL
        !           175: };
        !           176: 
        !           177: mmove_t chick_move_walk = {FRAME_walk11, FRAME_walk20, chick_frames_walk, NULL};
        !           178: 
        !           179: void chick_walk (edict_t *self)
        !           180: {
        !           181:        self->monsterinfo.currentmove = &chick_move_walk;
        !           182: }
        !           183: 
        !           184: void chick_run (edict_t *self)
        !           185: {
        !           186:        monster_done_dodge (self);
        !           187: 
        !           188:        if (self->monsterinfo.aiflags & AI_STAND_GROUND)
        !           189:        {
        !           190:                self->monsterinfo.currentmove = &chick_move_stand;
        !           191:                return;
        !           192:        }
        !           193: 
        !           194:        if (self->monsterinfo.currentmove == &chick_move_walk ||
        !           195:                self->monsterinfo.currentmove == &chick_move_start_run)
        !           196:        {
        !           197:                self->monsterinfo.currentmove = &chick_move_run;
        !           198:        }
        !           199:        else
        !           200:        {
        !           201:                self->monsterinfo.currentmove = &chick_move_start_run;
        !           202:        }
        !           203: }
        !           204: 
        !           205: mframe_t chick_frames_pain1 [] =
        !           206: {
        !           207:        ai_move, 0, NULL,
        !           208:        ai_move, 0, NULL,
        !           209:        ai_move, 0, NULL,
        !           210:        ai_move, 0, NULL,
        !           211:        ai_move, 0, NULL
        !           212: };
        !           213: mmove_t chick_move_pain1 = {FRAME_pain101, FRAME_pain105, chick_frames_pain1, chick_run};
        !           214: 
        !           215: mframe_t chick_frames_pain2 [] =
        !           216: {
        !           217:        ai_move, 0, NULL,
        !           218:        ai_move, 0, NULL,
        !           219:        ai_move, 0, NULL,
        !           220:        ai_move, 0, NULL,
        !           221:        ai_move, 0, NULL
        !           222: };
        !           223: mmove_t chick_move_pain2 = {FRAME_pain201, FRAME_pain205, chick_frames_pain2, chick_run};
        !           224: 
        !           225: mframe_t chick_frames_pain3 [] =
        !           226: {
        !           227:        ai_move, 0,             NULL,
        !           228:        ai_move, 0,             NULL,
        !           229:        ai_move, -6,    NULL,
        !           230:        ai_move, 3,             NULL,
        !           231:        ai_move, 11,    NULL,
        !           232:        ai_move, 3,             NULL,
        !           233:        ai_move, 0,             NULL,
        !           234:        ai_move, 0,             NULL,
        !           235:        ai_move, 4,             NULL,
        !           236:        ai_move, 1,             NULL,
        !           237:        ai_move, 0,             NULL,
        !           238:        ai_move, -3,    NULL,
        !           239:        ai_move, -4,    NULL,
        !           240:        ai_move, 5,             NULL,
        !           241:        ai_move, 7,             NULL,
        !           242:        ai_move, -2,    NULL,
        !           243:        ai_move, 3,             NULL,
        !           244:        ai_move, -5,    NULL,
        !           245:        ai_move, -2,    NULL,
        !           246:        ai_move, -8,    NULL,
        !           247:        ai_move, 2,             NULL
        !           248: };
        !           249: mmove_t chick_move_pain3 = {FRAME_pain301, FRAME_pain321, chick_frames_pain3, chick_run};
        !           250: 
        !           251: void chick_pain (edict_t *self, edict_t *other, float kick, int damage)
        !           252: {
        !           253:        float   r;
        !           254: 
        !           255:        monster_done_dodge(self);
        !           256: 
        !           257:        if (self->health < (self->max_health / 2))
        !           258:                self->s.skinnum = 1;
        !           259: 
        !           260:        if (level.time < self->pain_debounce_time)
        !           261:                return;
        !           262: 
        !           263:        self->pain_debounce_time = level.time + 3;
        !           264: 
        !           265:        r = random();
        !           266:        if (r < 0.33)
        !           267:                gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
        !           268:        else if (r < 0.66)
        !           269:                gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
        !           270:        else
        !           271:                gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM, 0);
        !           272: 
        !           273:        if (skill->value == 3)
        !           274:                return;         // no pain anims in nightmare
        !           275: 
        !           276:        // PMM - clear this from blindfire
        !           277:        self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
        !           278: 
        !           279:        if (damage <= 10)
        !           280:                self->monsterinfo.currentmove = &chick_move_pain1;
        !           281:        else if (damage <= 25)
        !           282:                self->monsterinfo.currentmove = &chick_move_pain2;
        !           283:        else
        !           284:                self->monsterinfo.currentmove = &chick_move_pain3;
        !           285: 
        !           286:        // PMM - clear duck flag
        !           287:        if (self->monsterinfo.aiflags & AI_DUCKED)
        !           288:                monster_duck_up(self);
        !           289: }
        !           290: 
        !           291: void chick_dead (edict_t *self)
        !           292: {
        !           293:        VectorSet (self->mins, -16, -16, 0);
        !           294:        VectorSet (self->maxs, 16, 16, 16);
        !           295:        self->movetype = MOVETYPE_TOSS;
        !           296:        self->svflags |= SVF_DEADMONSTER;
        !           297:        self->nextthink = 0;
        !           298:        gi.linkentity (self);
        !           299: }
        !           300: 
        !           301: mframe_t chick_frames_death2 [] =
        !           302: {
        !           303:        ai_move, -6, NULL,
        !           304:        ai_move, 0,  NULL,
        !           305:        ai_move, -1,  NULL,
        !           306:        ai_move, -5, NULL,
        !           307:        ai_move, 0, NULL,
        !           308:        ai_move, -1,  NULL,
        !           309:        ai_move, -2,  NULL,
        !           310:        ai_move, 1,  NULL,
        !           311:        ai_move, 10, NULL,
        !           312:        ai_move, 2,  NULL,
        !           313:        ai_move, 3,  NULL,
        !           314:        ai_move, 1,  NULL,
        !           315:        ai_move, 2, NULL,
        !           316:        ai_move, 0,  NULL,
        !           317:        ai_move, 3,  NULL,
        !           318:        ai_move, 3,  NULL,
        !           319:        ai_move, 1,  NULL,
        !           320:        ai_move, -3,  NULL,
        !           321:        ai_move, -5, NULL,
        !           322:        ai_move, 4, NULL,
        !           323:        ai_move, 15, NULL,
        !           324:        ai_move, 14, NULL,
        !           325:        ai_move, 1, NULL
        !           326: };
        !           327: mmove_t chick_move_death2 = {FRAME_death201, FRAME_death223, chick_frames_death2, chick_dead};
        !           328: 
        !           329: mframe_t chick_frames_death1 [] =
        !           330: {
        !           331:        ai_move, 0,  NULL,
        !           332:        ai_move, 0,  NULL,
        !           333:        ai_move, -7, NULL,
        !           334:        ai_move, 4,  NULL,
        !           335:        ai_move, 11, NULL,
        !           336:        ai_move, 0,  NULL,
        !           337:        ai_move, 0,  NULL,
        !           338:        ai_move, 0,  NULL,
        !           339:        ai_move, 0,  NULL,
        !           340:        ai_move, 0,  NULL,
        !           341:        ai_move, 0,  NULL,
        !           342:        ai_move, 0,  NULL
        !           343:        
        !           344: };
        !           345: mmove_t chick_move_death1 = {FRAME_death101, FRAME_death112, chick_frames_death1, chick_dead};
        !           346: 
        !           347: void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
        !           348: {
        !           349:        int             n;
        !           350: 
        !           351: // check for gib
        !           352:        if (self->health <= self->gib_health)
        !           353:        {
        !           354:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
        !           355:                for (n= 0; n < 2; n++)
        !           356:                        ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
        !           357:                for (n= 0; n < 4; n++)
        !           358:                        ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
        !           359:                ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
        !           360:                self->deadflag = DEAD_DEAD;
        !           361:                return;
        !           362:        }
        !           363: 
        !           364:        if (self->deadflag == DEAD_DEAD)
        !           365:                return;
        !           366: 
        !           367: // regular death
        !           368:        self->deadflag = DEAD_DEAD;
        !           369:        self->takedamage = DAMAGE_YES;
        !           370: 
        !           371:        n = rand() % 2;
        !           372:        if (n == 0)
        !           373:        {
        !           374:                self->monsterinfo.currentmove = &chick_move_death1;
        !           375:                gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
        !           376:        }
        !           377:        else
        !           378:        {
        !           379:                self->monsterinfo.currentmove = &chick_move_death2;
        !           380:                gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
        !           381:        }
        !           382: }
        !           383: 
        !           384: // PMM - changes to duck code for new dodge
        !           385: 
        !           386: mframe_t chick_frames_duck [] =
        !           387: {
        !           388:        ai_move, 0, monster_duck_down,
        !           389:        ai_move, 1, NULL,
        !           390:        ai_move, 4, monster_duck_hold,
        !           391:        ai_move, -4,  NULL,
        !           392:        ai_move, -5,  monster_duck_up,
        !           393:        ai_move, 3, NULL,
        !           394:        ai_move, 1,  NULL
        !           395: };
        !           396: mmove_t chick_move_duck = {FRAME_duck01, FRAME_duck07, chick_frames_duck, chick_run};
        !           397: 
        !           398: /*
        !           399: void chick_dodge (edict_t *self, edict_t *attacker, float eta, trace_t *tr)
        !           400: {
        !           401: // begin orig code
        !           402:        if (random() > 0.25)
        !           403:                return;
        !           404: 
        !           405:        if (!self->enemy)
        !           406:                self->enemy = attacker;
        !           407: 
        !           408:        self->monsterinfo.currentmove = &chick_move_duck;
        !           409: // end
        !           410: 
        !           411:        float   r;
        !           412:        float   height;
        !           413:        int             shooting = 0;
        !           414: 
        !           415:        if (!self->enemy)
        !           416:        {
        !           417:                self->enemy = attacker;
        !           418:                FoundTarget (self);
        !           419:        }
        !           420: 
        !           421:        // PMM - don't bother if it's going to hit anyway; fix for weird in-your-face etas (I was
        !           422:        // seeing numbers like 13 and 14)
        !           423:        if ((eta < 0.1) || (eta > 5))
        !           424:                return;
        !           425: 
        !           426:        r = random();
        !           427:        if (r > (0.25*((skill->value)+1)))
        !           428:                return;
        !           429: 
        !           430:        if ((self->monsterinfo.currentmove == &chick_move_start_attack1) ||
        !           431:                (self->monsterinfo.currentmove == &chick_move_attack1))
        !           432:        {
        !           433:                shooting = 1;
        !           434:        }
        !           435:        if (self->monsterinfo.aiflags & AI_DODGING)
        !           436:        {
        !           437:                height = self->absmax[2];
        !           438:        }
        !           439:        else
        !           440:        {
        !           441:                height = self->absmax[2]-32-1;  // the -1 is because the absmax is s.origin + maxs + 1
        !           442:        }
        !           443: 
        !           444:        // check to see if it makes sense to duck
        !           445:        if (tr->endpos[2] <= height)
        !           446:        {
        !           447:                vec3_t right, diff;
        !           448:                if (shooting)
        !           449:                {
        !           450:                        self->monsterinfo.attack_state = AS_SLIDING;
        !           451:                        return;
        !           452:                }
        !           453:                AngleVectors (self->s.angles, NULL, right, NULL);
        !           454:                VectorSubtract (tr->endpos, self->s.origin, diff);
        !           455:                if (DotProduct (right, diff) < 0)
        !           456:                {
        !           457:                        self->monsterinfo.lefty = 1;
        !           458:                }
        !           459:                // if it doesn't sense to duck, try to strafe away
        !           460:                monster_done_dodge (self);
        !           461:                self->monsterinfo.currentmove = &chick_move_run;
        !           462:                self->monsterinfo.attack_state = AS_SLIDING;
        !           463:                return;
        !           464:        }
        !           465: 
        !           466:        if (skill->value == 0)
        !           467:        {
        !           468:                self->monsterinfo.currentmove = &chick_move_duck;
        !           469:                // PMM - stupid dodge
        !           470:                self->monsterinfo.duck_wait_time = level.time + eta + 1;
        !           471:                self->monsterinfo.aiflags |= AI_DODGING;
        !           472:                return;
        !           473:        }
        !           474: 
        !           475:        if (!shooting)
        !           476:        {
        !           477:                self->monsterinfo.currentmove = &chick_move_duck;
        !           478:                self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
        !           479:                self->monsterinfo.aiflags |= AI_DODGING;
        !           480:        }
        !           481:        return;
        !           482: 
        !           483: }
        !           484: */
        !           485: void ChickSlash (edict_t *self)
        !           486: {
        !           487:        vec3_t  aim;
        !           488: 
        !           489:        VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10);
        !           490:        gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0);
        !           491:        fire_hit (self, aim, (10 + (rand() %6)), 100);
        !           492: }
        !           493: 
        !           494: 
        !           495: void ChickRocket (edict_t *self)
        !           496: {
        !           497:        vec3_t  forward, right;
        !           498:        vec3_t  start;
        !           499:        vec3_t  dir;
        !           500:        vec3_t  vec;
        !           501:        trace_t trace;  // PMM - check target
        !           502:        int             rocketSpeed;
        !           503:        float   dist;
        !           504:        // pmm - blindfire
        !           505:        vec3_t  target;
        !           506:        qboolean blindfire = false;
        !           507: 
        !           508:        if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
        !           509:                blindfire = true;
        !           510:        else
        !           511:                blindfire = false;
        !           512: 
        !           513:        if(!self->enemy || !self->enemy->inuse)         //PGM
        !           514:                return;                                                                 //PGM
        !           515: 
        !           516:        AngleVectors (self->s.angles, forward, right, NULL);
        !           517:        G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start);
        !           518: 
        !           519:        rocketSpeed = 500 + (100 * skill->value);       // PGM rock & roll.... :)
        !           520: 
        !           521:        // put a debug trail from start to endpoint, confirm that the start point is
        !           522:        // correct for the trace
        !           523: 
        !           524:        // PMM
        !           525:        if (blindfire)
        !           526:                VectorCopy (self->monsterinfo.blind_fire_target, target);
        !           527:        else
        !           528:                VectorCopy (self->enemy->s.origin, target);
        !           529:        // pmm
        !           530: //PGM
        !           531:        // PMM - blindfire shooting
        !           532:        if (blindfire)
        !           533:        {
        !           534:                VectorCopy (target, vec);
        !           535:                VectorSubtract (vec, start, dir);
        !           536:        }
        !           537:        // pmm
        !           538:        // don't shoot at feet if they're above where i'm shooting from.
        !           539:        else if(random() < 0.33 || (start[2] < self->enemy->absmin[2]))
        !           540:        {
        !           541: //             gi.dprintf("normal shot\n");
        !           542:                VectorCopy (target, vec);
        !           543:                vec[2] += self->enemy->viewheight;
        !           544:                VectorSubtract (vec, start, dir);
        !           545:        }
        !           546:        else
        !           547:        {
        !           548: //             gi.dprintf("shooting at feet!\n");
        !           549:                VectorCopy (target, vec);
        !           550:                vec[2] = self->enemy->absmin[2];
        !           551:                VectorSubtract (vec, start, dir);
        !           552:        }
        !           553: //PGM
        !           554: 
        !           555: //======
        !           556: //PMM - lead target  (not when blindfiring)
        !           557:        // 20, 35, 50, 65 chance of leading
        !           558:        if((!blindfire) && ((random() < (0.2 + ((3 - skill->value) * 0.15)))))
        !           559:        {
        !           560:                float   time;
        !           561: 
        !           562: //             gi.dprintf ("leading target\n");
        !           563:                dist = VectorLength (dir);
        !           564:                time = dist/rocketSpeed;
        !           565:                VectorMA(vec, time, self->enemy->velocity, vec);
        !           566:                VectorSubtract(vec, start, dir);
        !           567:        }
        !           568: //PMM - lead target
        !           569: //======
        !           570: 
        !           571:        VectorNormalize (dir);
        !           572: 
        !           573:        // pmm blindfire doesn't check target (done in checkattack)
        !           574:        // paranoia, make sure we're not shooting a target right next to us
        !           575:        trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
        !           576:        if (blindfire)
        !           577:        {
        !           578:                // blindfire has different fail criteria for the trace
        !           579:                if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
        !           580:                        monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
        !           581:                else 
        !           582:                {
        !           583:                        // geez, this is bad.  she's avoiding about 80% of her blindfires due to hitting things.
        !           584:                        // hunt around for a good shot
        !           585:                        // try shifting the target to the left a little (to help counter her large offset)
        !           586:                        VectorCopy (target, vec);
        !           587:                        VectorMA (vec, -10, right, vec);
        !           588:                        VectorSubtract(vec, start, dir);
        !           589:                        VectorNormalize (dir);
        !           590:                        trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
        !           591:                        if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
        !           592:                                monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
        !           593:                        else 
        !           594:                        {
        !           595:                                // ok, that failed.  try to the right
        !           596:                                VectorCopy (target, vec);
        !           597:                                VectorMA (vec, 10, right, vec);
        !           598:                                VectorSubtract(vec, start, dir);
        !           599:                                VectorNormalize (dir);
        !           600:                                trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
        !           601:                                if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5)))
        !           602:                                        monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
        !           603:                                else if ((g_showlogic) && (g_showlogic->value))
        !           604:                                        // ok, I give up
        !           605:                                        gi.dprintf ("chick avoiding blindfire shot\n");
        !           606:                        }
        !           607:                }
        !           608:        }
        !           609:        else
        !           610:        {
        !           611:                trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
        !           612:                if(trace.ent == self->enemy || trace.ent == world)
        !           613:                {
        !           614:                        if(trace.fraction > 0.5 || (trace.ent && trace.ent->client))
        !           615:                                monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1);
        !           616:        //              else
        !           617:        //                      gi.dprintf("didn't make it halfway to target...aborting\n");
        !           618:                }
        !           619:        }
        !           620: }      
        !           621: 
        !           622: void Chick_PreAttack1 (edict_t *self)
        !           623: {
        !           624:        gi.sound (self, CHAN_VOICE, sound_missile_prelaunch, 1, ATTN_NORM, 0);
        !           625: }
        !           626: 
        !           627: void ChickReload (edict_t *self)
        !           628: {
        !           629:        gi.sound (self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0);
        !           630: }
        !           631: 
        !           632: 
        !           633: mframe_t chick_frames_start_attack1 [] =
        !           634: {
        !           635:        ai_charge, 0,   Chick_PreAttack1,
        !           636:        ai_charge, 0,   NULL,
        !           637:        ai_charge, 0,   NULL,
        !           638:        ai_charge, 4,   NULL,
        !           639:        ai_charge, 0,   NULL,
        !           640:        ai_charge, -3,  NULL,
        !           641:        ai_charge, 3,   NULL,
        !           642:        ai_charge, 5,   NULL,
        !           643:        ai_charge, 7,   NULL,
        !           644:        ai_charge, 0,   NULL,
        !           645:        ai_charge, 0,   NULL,
        !           646:        ai_charge, 0,   NULL,
        !           647:        ai_charge, 0,   chick_attack1
        !           648: };
        !           649: mmove_t chick_move_start_attack1 = {FRAME_attak101, FRAME_attak113, chick_frames_start_attack1, NULL};
        !           650: 
        !           651: 
        !           652: mframe_t chick_frames_attack1 [] =
        !           653: {
        !           654:        ai_charge, 19,  ChickRocket,
        !           655:        ai_charge, -6,  NULL,
        !           656:        ai_charge, -5,  NULL,
        !           657:        ai_charge, -2,  NULL,
        !           658:        ai_charge, -7,  NULL,
        !           659:        ai_charge, 0,   NULL,
        !           660:        ai_charge, 1,   NULL,
        !           661:        ai_charge, 10,  ChickReload,
        !           662:        ai_charge, 4,   NULL,
        !           663:        ai_charge, 5,   NULL,
        !           664:        ai_charge, 6,   NULL,
        !           665:        ai_charge, 6,   NULL,
        !           666:        ai_charge, 4,   NULL,
        !           667:        ai_charge, 3,   chick_rerocket
        !           668: 
        !           669: };
        !           670: mmove_t chick_move_attack1 = {FRAME_attak114, FRAME_attak127, chick_frames_attack1, NULL};
        !           671: 
        !           672: mframe_t chick_frames_end_attack1 [] =
        !           673: {
        !           674:        ai_charge, -3,  NULL,
        !           675:        ai_charge, 0,   NULL,
        !           676:        ai_charge, -6,  NULL,
        !           677:        ai_charge, -4,  NULL,
        !           678:        ai_charge, -2,  NULL
        !           679: };
        !           680: mmove_t chick_move_end_attack1 = {FRAME_attak128, FRAME_attak132, chick_frames_end_attack1, chick_run};
        !           681: 
        !           682: void chick_rerocket(edict_t *self)
        !           683: {
        !           684:        if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
        !           685:        {
        !           686:                self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
        !           687:                self->monsterinfo.currentmove = &chick_move_end_attack1;
        !           688:                return;
        !           689:        }
        !           690:        if (self->enemy->health > 0)
        !           691:        {
        !           692:                if (range (self, self->enemy) > RANGE_MELEE)
        !           693:                        if ( visible (self, self->enemy) )
        !           694:                                if (random() <= (0.6 + (0.05*((float)skill->value))))
        !           695:                                {
        !           696:                                        self->monsterinfo.currentmove = &chick_move_attack1;
        !           697:                                        return;
        !           698:                                }
        !           699:        }       
        !           700:        self->monsterinfo.currentmove = &chick_move_end_attack1;
        !           701: }
        !           702: 
        !           703: void chick_attack1(edict_t *self)
        !           704: {
        !           705:        self->monsterinfo.currentmove = &chick_move_attack1;
        !           706: }
        !           707: 
        !           708: mframe_t chick_frames_slash [] =
        !           709: {
        !           710:        ai_charge, 1,   NULL,
        !           711:        ai_charge, 7,   ChickSlash,
        !           712:        ai_charge, -7,  NULL,
        !           713:        ai_charge, 1,   NULL,
        !           714:        ai_charge, -1,  NULL,
        !           715:        ai_charge, 1,   NULL,
        !           716:        ai_charge, 0,   NULL,
        !           717:        ai_charge, 1,   NULL,
        !           718:        ai_charge, -2,  chick_reslash
        !           719: };
        !           720: mmove_t chick_move_slash = {FRAME_attak204, FRAME_attak212, chick_frames_slash, NULL};
        !           721: 
        !           722: mframe_t chick_frames_end_slash [] =
        !           723: {
        !           724:        ai_charge, -6,  NULL,
        !           725:        ai_charge, -1,  NULL,
        !           726:        ai_charge, -6,  NULL,
        !           727:        ai_charge, 0,   NULL
        !           728: };
        !           729: mmove_t chick_move_end_slash = {FRAME_attak213, FRAME_attak216, chick_frames_end_slash, chick_run};
        !           730: 
        !           731: 
        !           732: void chick_reslash(edict_t *self)
        !           733: {
        !           734:        if (self->enemy->health > 0)
        !           735:        {
        !           736:                if (range (self, self->enemy) == RANGE_MELEE)
        !           737:                        if (random() <= 0.9)
        !           738:                        {                               
        !           739:                                self->monsterinfo.currentmove = &chick_move_slash;
        !           740:                                return;
        !           741:                        }
        !           742:                        else
        !           743:                        {
        !           744:                                self->monsterinfo.currentmove = &chick_move_end_slash;
        !           745:                                return;
        !           746:                        }
        !           747:        }
        !           748:        self->monsterinfo.currentmove = &chick_move_end_slash;
        !           749: }
        !           750: 
        !           751: void chick_slash(edict_t *self)
        !           752: {
        !           753:        self->monsterinfo.currentmove = &chick_move_slash;
        !           754: }
        !           755: 
        !           756: 
        !           757: mframe_t chick_frames_start_slash [] =
        !           758: {      
        !           759:        ai_charge, 1,   NULL,
        !           760:        ai_charge, 8,   NULL,
        !           761:        ai_charge, 3,   NULL
        !           762: };
        !           763: mmove_t chick_move_start_slash = {FRAME_attak201, FRAME_attak203, chick_frames_start_slash, chick_slash};
        !           764: 
        !           765: 
        !           766: 
        !           767: void chick_melee(edict_t *self)
        !           768: {
        !           769:        self->monsterinfo.currentmove = &chick_move_start_slash;
        !           770: }
        !           771: 
        !           772: 
        !           773: void chick_attack(edict_t *self)
        !           774: {
        !           775:        float r, chance;
        !           776: 
        !           777:        monster_done_dodge (self);
        !           778: 
        !           779:        // PMM 
        !           780:        if (self->monsterinfo.attack_state == AS_BLIND)
        !           781:        {
        !           782:                // setup shot probabilities
        !           783:                if (self->monsterinfo.blind_fire_delay < 1.0)
        !           784:                        chance = 1.0;
        !           785:                else if (self->monsterinfo.blind_fire_delay < 7.5)
        !           786:                        chance = 0.4;
        !           787:                else
        !           788:                        chance = 0.1;
        !           789: 
        !           790:                r = random();
        !           791: 
        !           792:                gi.dprintf ("chance = %2.2f, roll = %2.2f\n", chance, r);
        !           793: 
        !           794:                // minimum of 2 seconds, plus 0-3, after the shots are done
        !           795:                self->monsterinfo.blind_fire_delay += 4.0 + 1.5 + random();
        !           796: 
        !           797:                // don't shoot at the origin
        !           798:                if (VectorCompare (self->monsterinfo.blind_fire_target, vec3_origin))
        !           799:                        return;
        !           800: 
        !           801:                // don't shoot if the dice say not to
        !           802:                if (r > chance)
        !           803:                {
        !           804:                        if ((g_showlogic) && (g_showlogic->value))
        !           805:                                gi.dprintf ("blindfire - NO SHOT\n");
        !           806:                        return;
        !           807:                }
        !           808: 
        !           809:                // turn on manual steering to signal both manual steering and blindfire
        !           810:                self->monsterinfo.aiflags |= AI_MANUAL_STEERING;
        !           811:                self->monsterinfo.currentmove = &chick_move_start_attack1;
        !           812:                self->monsterinfo.attack_finished = level.time + 2*random();
        !           813:                return;
        !           814:        }
        !           815:        // pmm
        !           816: 
        !           817:        self->monsterinfo.currentmove = &chick_move_start_attack1;
        !           818: }
        !           819: 
        !           820: void chick_sight(edict_t *self, edict_t *other)
        !           821: {
        !           822:        gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
        !           823: }
        !           824: 
        !           825: //===========
        !           826: //PGM
        !           827: qboolean chick_blocked (edict_t *self, float dist)
        !           828: {
        !           829:        if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
        !           830:                return true;
        !           831: 
        !           832:        if(blocked_checkplat (self, dist))
        !           833:                return true;
        !           834: 
        !           835:        return false;
        !           836: }
        !           837: //PGM
        !           838: //===========
        !           839: 
        !           840: void chick_duck (edict_t *self, float eta)
        !           841: {
        !           842:        if ((self->monsterinfo.currentmove == &chick_move_start_attack1) ||
        !           843:                (self->monsterinfo.currentmove == &chick_move_attack1))
        !           844:        {
        !           845:                // if we're shooting, and not on easy, don't dodge
        !           846:                if (skill->value)
        !           847:                {
        !           848:                        self->monsterinfo.aiflags &= ~AI_DUCKED;
        !           849:                        return;
        !           850:                }
        !           851:        }
        !           852: 
        !           853:        if (skill->value == 0)
        !           854:                // PMM - stupid dodge
        !           855:                self->monsterinfo.duck_wait_time = level.time + eta + 1;
        !           856:        else
        !           857:                self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
        !           858: 
        !           859:        // has to be done immediately otherwise she can get stuck
        !           860:        monster_duck_down(self);
        !           861: 
        !           862:        self->monsterinfo.nextframe = FRAME_duck01;
        !           863:        self->monsterinfo.currentmove = &chick_move_duck;
        !           864:        return;
        !           865: }
        !           866: 
        !           867: void chick_sidestep (edict_t *self)
        !           868: {
        !           869:        if ((self->monsterinfo.currentmove == &chick_move_start_attack1) ||
        !           870:                (self->monsterinfo.currentmove == &chick_move_attack1))
        !           871:        {
        !           872:                // if we're shooting, and not on easy, don't dodge
        !           873:                if (skill->value)
        !           874:                {
        !           875:                        self->monsterinfo.aiflags &= ~AI_DODGING;
        !           876:                        return;
        !           877:                }
        !           878:        }
        !           879: 
        !           880:        if (self->monsterinfo.currentmove != &chick_move_run)
        !           881:                self->monsterinfo.currentmove = &chick_move_run;
        !           882: }
        !           883: 
        !           884: /*QUAKED monster_chick (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
        !           885: */
        !           886: void SP_monster_chick (edict_t *self)
        !           887: {
        !           888:        if (deathmatch->value)
        !           889:        {
        !           890:                G_FreeEdict (self);
        !           891:                return;
        !           892:        }
        !           893: 
        !           894:        sound_missile_prelaunch = gi.soundindex ("chick/chkatck1.wav"); 
        !           895:        sound_missile_launch    = gi.soundindex ("chick/chkatck2.wav"); 
        !           896:        sound_melee_swing               = gi.soundindex ("chick/chkatck3.wav"); 
        !           897:        sound_melee_hit                 = gi.soundindex ("chick/chkatck4.wav"); 
        !           898:        sound_missile_reload    = gi.soundindex ("chick/chkatck5.wav"); 
        !           899:        sound_death1                    = gi.soundindex ("chick/chkdeth1.wav"); 
        !           900:        sound_death2                    = gi.soundindex ("chick/chkdeth2.wav"); 
        !           901:        sound_fall_down                 = gi.soundindex ("chick/chkfall1.wav"); 
        !           902:        sound_idle1                             = gi.soundindex ("chick/chkidle1.wav"); 
        !           903:        sound_idle2                             = gi.soundindex ("chick/chkidle2.wav"); 
        !           904:        sound_pain1                             = gi.soundindex ("chick/chkpain1.wav"); 
        !           905:        sound_pain2                             = gi.soundindex ("chick/chkpain2.wav"); 
        !           906:        sound_pain3                             = gi.soundindex ("chick/chkpain3.wav"); 
        !           907:        sound_sight                             = gi.soundindex ("chick/chksght1.wav"); 
        !           908:        sound_search                    = gi.soundindex ("chick/chksrch1.wav"); 
        !           909: 
        !           910:        self->movetype = MOVETYPE_STEP;
        !           911:        self->solid = SOLID_BBOX;
        !           912:        self->s.modelindex = gi.modelindex ("models/monsters/bitch2/tris.md2");
        !           913:        VectorSet (self->mins, -16, -16, 0);
        !           914:        VectorSet (self->maxs, 16, 16, 56);
        !           915: 
        !           916:        self->health = 175;
        !           917:        self->gib_health = -70;
        !           918:        self->mass = 200;
        !           919: 
        !           920:        self->pain = chick_pain;
        !           921:        self->die = chick_die;
        !           922: 
        !           923:        self->monsterinfo.stand = chick_stand;
        !           924:        self->monsterinfo.walk = chick_walk;
        !           925:        self->monsterinfo.run = chick_run;
        !           926:        // pmm
        !           927:        self->monsterinfo.dodge = M_MonsterDodge;
        !           928:        self->monsterinfo.duck = chick_duck;
        !           929:        self->monsterinfo.unduck = monster_duck_up;
        !           930:        self->monsterinfo.sidestep = chick_sidestep;
        !           931: //     self->monsterinfo.dodge = chick_dodge;
        !           932:        // pmm
        !           933:        self->monsterinfo.attack = chick_attack;
        !           934:        self->monsterinfo.melee = chick_melee;
        !           935:        self->monsterinfo.sight = chick_sight;
        !           936:        self->monsterinfo.blocked = chick_blocked;              // PGM
        !           937: 
        !           938:        gi.linkentity (self);
        !           939: 
        !           940:        self->monsterinfo.currentmove = &chick_move_stand;
        !           941:        self->monsterinfo.scale = MODEL_SCALE;
        !           942: 
        !           943:        // PMM
        !           944:        self->monsterinfo.blindfire = true;
        !           945:        // pmm
        !           946:        walkmonster_start (self);
        !           947: }
        !           948: 

unix.superglobalmegacorp.com

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