⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_enemy.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 4 页
字号:
            return;    }    actor->movedir = DI_NODIR;  // can not move}//// P_LookForPlayers// If allaround is false, only look 180 degrees in front.// Returns true if a player is targeted.//static boolean P_LookForPlayers ( mobj_t*       actor,  boolean       allaround ){    int         c;    int         stop;    player_t*   player;    sector_t*   sector;    angle_t     an;    fixed_t     dist;    if(!multiplayer && players[0].health <= 0 && gamemode == heretic)    { // Single player game and player is dead, look for monsters        return(P_LookForMonsters(actor));    }    sector = actor->subsector->sector;    // BP: first time init, this allow minimum lastlook changes    if( actor->lastlook<0 && demoversion>=129 )        actor->lastlook = P_Random () % MAXPLAYERS;    c = 0;    stop = (actor->lastlook-1)&PLAYERSMASK;    for ( ; ; actor->lastlook = (actor->lastlook+1)&PLAYERSMASK )    {        // done looking        if (actor->lastlook == stop)            return false;        if (!playeringame[actor->lastlook])            continue;        if (c++ == 2)            return false;        player = &players[actor->lastlook];        if (player->health <= 0)            continue;           // dead        if (!P_CheckSight (actor, player->mo))            continue;           // out of sight        if (!allaround)        {            an = R_PointToAngle2 (actor->x,                                  actor->y,                                  player->mo->x,                                  player->mo->y)                - actor->angle;            if (an > ANG90 && an < ANG270)            {                dist = P_AproxDistance (player->mo->x - actor->x,                                        player->mo->y - actor->y);                // if real close, react anyway                if (dist > MELEERANGE)                    continue;   // behind back            }        }        if( gamemode == heretic && player->mo->flags&MF_SHADOW)        { // Player is invisible            if((P_AproxDistance(player->mo->x-actor->x,                player->mo->y-actor->y) > 2*MELEERANGE)                && P_AproxDistance(player->mo->momx, player->mo->momy)                < 5*FRACUNIT)            { // Player is sneaking - can't detect                return(false);            }            if(P_Random() < 225)            { // Player isn't sneaking, but still didn't detect                return(false);            }        }        actor->target = player->mo;        return true;    }    return false;}//// A_KeenDie// DOOM II special, map 32.// Uses special tag 666.//void A_KeenDie (mobj_t* mo){    thinker_t*  th;    mobj_t*     mo2;    line_t      junk;    A_Fall (mo);    // scan the remaining thinkers    // to see if all Keens are dead    for (th = thinkercap.next ; th != &thinkercap ; th=th->next)    {        if (th->function.acp1 != (actionf_p1)P_MobjThinker)            continue;        mo2 = (mobj_t *)th;        if (mo2 != mo            && mo2->type == mo->type            && mo2->health > 0)        {            // other Keen not dead            return;        }    }    junk.tag = 666;    EV_DoDoor(&junk,dooropen,VDOORSPEED);}//// ACTION ROUTINES////// A_Look// Stay in state until a player is sighted.//void A_Look (mobj_t* actor){    mobj_t*     targ;    actor->threshold = 0;       // any shot will wake up    targ = actor->subsector->sector->soundtarget;    if (targ && (targ->flags & MF_SHOOTABLE) )    {        actor->target = targ;        if ( actor->flags & MF_AMBUSH )        {            if (P_CheckSight (actor, actor->target))                goto seeyou;        }        else            goto seeyou;    }    if (!P_LookForPlayers (actor, false) )        return;    // go into chase state  seeyou:    if (actor->info->seesound)    {        int             sound;        switch (actor->info->seesound)        {          case sfx_posit1:          case sfx_posit2:          case sfx_posit3:            sound = sfx_posit1+P_Random()%3;            break;          case sfx_bgsit1:          case sfx_bgsit2:            sound = sfx_bgsit1+P_Random()%2;            break;          default:            sound = actor->info->seesound;            break;        }        if (actor->type==MT_SPIDER         || actor->type == MT_CYBORG         || (actor->flags2&MF2_BOSS))        {            // full volume            S_StartSound (NULL, sound);        }        else#ifdef HW3SOUND            S_StartScreamSound(actor, sound);#else            S_StartSound (actor, sound);#endif    }    P_SetMobjState (actor, actor->info->seestate);}//// A_Chase// Actor has a melee attack,// so it tries to close as fast as possible//void A_Chase (mobj_t*   actor){    int         delta;    if (actor->reactiontime)        actor->reactiontime--;    // modify target threshold    if  (actor->threshold)    {        if (gamemode != heretic             && (!actor->target              || actor->target->health <= 0              || (actor->target->flags & MF_CORPSE)))        {            actor->threshold = 0;        }        else            actor->threshold--;    }    if(gamemode == heretic  && cv_fastmonsters.value)    { // Monsters move faster in nightmare mode        actor->tics -= actor->tics/2;        if(actor->tics < 3)            actor->tics = 3;    }    // turn towards movement direction if not there yet    if (actor->movedir < 8)    {        actor->angle &= (7<<29);        delta = actor->angle - (actor->movedir << 29);        if (delta > 0)            actor->angle -= ANG90/2;        else if (delta < 0)            actor->angle += ANG90/2;    }    if (!actor->target        || !(actor->target->flags&MF_SHOOTABLE))    {        // look for a new target        if (P_LookForPlayers(actor,true))            return;     // got a new target        P_SetMobjState (actor, actor->info->spawnstate);        return;    }    // do not attack twice in a row    if (actor->flags & MF_JUSTATTACKED)    {        actor->flags &= ~MF_JUSTATTACKED;        if (!cv_fastmonsters.value)            P_NewChaseDir (actor);        return;    }    // check for melee attack    if (actor->info->meleestate        && P_CheckMeleeRange (actor))    {        if (actor->info->attacksound)#ifdef HW3SOUND            S_StartAttackSound(actor, actor->info->attacksound);#else            S_StartSound (actor, actor->info->attacksound);#endif        P_SetMobjState (actor, actor->info->meleestate);        return;    }    // check for missile attack    if (actor->info->missilestate)    {        if (!cv_fastmonsters.value && actor->movecount)        {            goto nomissile;        }        if (!P_CheckMissileRange (actor))            goto nomissile;        P_SetMobjState (actor, actor->info->missilestate);        actor->flags |= MF_JUSTATTACKED;        return;    }    // ?  nomissile:    // possibly choose another target    if (multiplayer        && !actor->threshold        && !P_CheckSight (actor, actor->target) )    {        if (P_LookForPlayers(actor,true))            return;     // got a new target    }    // chase towards player    if (--actor->movecount<0        || !P_Move (actor))    {        P_NewChaseDir (actor);    }    // make active sound    if (actor->info->activesound        && P_Random () < 3)    {        if(actor->type == MT_WIZARD && P_Random() < 128)#ifdef HW3SOUND            S_StartScreamSound(actor, actor->info->seesound);#else            S_StartSound(actor, actor->info->seesound);#endif        else if(actor->type == MT_SORCERER2)            S_StartSound(NULL, actor->info->activesound);        else#ifdef HW3SOUND            S_StartScreamSound(actor, actor->info->activesound);#else            S_StartSound(actor, actor->info->activesound);#endif    }}//// A_FaceTarget//void A_FaceTarget (mobj_t* actor){    if (!actor->target)        return;    actor->flags &= ~MF_AMBUSH;    actor->angle = R_PointToAngle2 (actor->x,                                    actor->y,                                    actor->target->x,                                    actor->target->y);    if (actor->target->flags & MF_SHADOW)        actor->angle += P_SignedRandom()<<21;}//// A_PosAttack//void A_PosAttack (mobj_t* actor){    int         angle;    int         damage;    int         slope;    if (!actor->target)        return;    A_FaceTarget (actor);    angle = actor->angle;    slope = P_AimLineAttack (actor, angle, MISSILERANGE);#ifdef HW3SOUND    S_StartAttackSound(actor, sfx_pistol);#else    S_StartSound (actor, sfx_pistol);#endif    angle += P_SignedRandom()<<20;    damage = ((P_Random()%5)+1)*3;    P_LineAttack (actor, angle, MISSILERANGE, slope, damage);}void A_SPosAttack (mobj_t* actor){    int         i;    int         angle;    int         bangle;    int         damage;    int         slope;    if (!actor->target)        return;#ifdef HW3SOUND    S_StartAttackSound(actor, sfx_shotgn);#else    S_StartSound (actor, sfx_shotgn);#endif    A_FaceTarget (actor);    bangle = actor->angle;    slope = P_AimLineAttack (actor, bangle, MISSILERANGE);    for (i=0 ; i<3 ; i++)    {        angle  = (P_SignedRandom()<<20)+bangle;        damage = ((P_Random()%5)+1)*3;        P_LineAttack (actor, angle, MISSILERANGE, slope, damage);    }}void A_CPosAttack (mobj_t* actor){    int         angle;    int         bangle;    int         damage;    int         slope;    if (!actor->target)        return;#ifdef HW3SOUND    S_StartAttackSound(actor, sfx_shotgn);#else    S_StartSound (actor, sfx_shotgn);#endif    A_FaceTarget (actor);    bangle = actor->angle;    slope = P_AimLineAttack (actor, bangle, MISSILERANGE);    angle  = (P_SignedRandom()<<20)+bangle;    damage = ((P_Random()%5)+1)*3;    P_LineAttack (actor, angle, MISSILERANGE, slope, damage);}void A_CPosRefire (mobj_t* actor){    // keep firing unless target got out of sight    A_FaceTarget (actor);    if (P_Random () < 40)        return;    if (!actor->target        || actor->target->health <= 0        || actor->target->flags & MF_CORPSE        || !P_CheckSight (actor, actor->target) )    {        P_SetMobjState (actor, actor->info->seestate);    }}void A_SpidRefire (mobj_t* actor){    // keep firing unless target got out of sight    A_FaceTarget (actor);    if (P_Random () < 10)        return;    if (!actor->target        || actor->target->health <= 0        || actor->target->flags & MF_CORPSE        || !P_CheckSight (actor, actor->target) )    {        P_SetMobjState (actor, actor->info->seestate);    }}void A_BspiAttack (mobj_t *actor){    if (!actor->target)        return;    A_FaceTarget (actor);    // launch a missile    P_SpawnMissile (actor, actor->target, MT_ARACHPLAZ);}//// A_TroopAttack//void A_TroopAttack (mobj_t* actor){    int         damage;    if (!actor->target)        return;    A_FaceTarget (actor);    if (P_CheckMeleeRange (actor))    {#ifdef HW3SOUND        S_StartAttackSound(actor, sfx_claw);#else        S_StartSound (actor, sfx_claw);#endif        damage = (P_Random()%8+1)*3;        P_DamageMobj (actor->target, actor, actor, damage);        return;    }    // launch a missile    P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);}void A_SargAttack (mobj_t* actor){    int         damage;    if (!actor->target)        return;    A_FaceTarget (actor);    if (P_CheckMeleeRange (actor))    {        damage = ((P_Random()%10)+1)*4;        P_DamageMobj (actor->target, actor, actor, damage);    }}void A_HeadAttack (mobj_t* actor){    int         damage;    if (!actor->target)        return;    A_FaceTarget (actor);    if (P_CheckMeleeRange (actor))    {        damage = (P_Random()%6+1)*10;        P_DamageMobj (actor->target, actor, actor, damage);        return;    }    // launch a missile    P_SpawnMissile (actor, actor->target, MT_HEADSHOT);}void A_CyberAttack (mobj_t* actor){    if (!actor->target)        return;    A_FaceTarget (actor);    P_SpawnMissile (actor, actor->target, MT_ROCKET);}void A_BruisAttack (mobj_t* actor){    int         damage;    if (!actor->target)        return;    if (P_CheckMeleeRange (actor))    {#ifdef HW3SOUND        S_StartAttackSound(actor, sfx_claw);#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -