📄 p_enemy.c
字号:
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 + -