📄 p_enemy.c
字号:
// Initialize queue corpseQueueSlot=0; memset(corpseQueue, 0, sizeof(mobj_t *)*CORPSEQUEUESIZE); if (!corpseScan) return; // Search mobj list for corpses and place them in this queue for(think = thinkercap.next; think != &thinkercap; think = think->next) { if(think->function != P_MobjThinker) continue; mo = (mobj_t *)think; if (!(mo->flags&MF_CORPSE)) continue; // Must be a corpse if (mo->flags&MF_ICECORPSE) continue; // Not ice corpses // Only corpses that call A_QueueCorpse from death routine switch(mo->type) { case MT_CENTAUR: case MT_CENTAURLEADER: case MT_DEMON: case MT_DEMON2: case MT_WRAITH: case MT_WRAITHB: case MT_BISHOP: case MT_ETTIN: case MT_PIG: case MT_CENTAUR_SHIELD: case MT_CENTAUR_SWORD: case MT_DEMONCHUNK1: case MT_DEMONCHUNK2: case MT_DEMONCHUNK3: case MT_DEMONCHUNK4: case MT_DEMONCHUNK5: case MT_DEMON2CHUNK1: case MT_DEMON2CHUNK2: case MT_DEMON2CHUNK3: case MT_DEMON2CHUNK4: case MT_DEMON2CHUNK5: case MT_FIREDEMON_SPLOTCH1: case MT_FIREDEMON_SPLOTCH2: A_QueueCorpse(mo); // Add corpse to queue break; default: break; } }}//----------------------------------------------------------------------------//// PROC A_AddPlayerCorpse////----------------------------------------------------------------------------#define BODYQUESIZE 32mobj_t *bodyque[BODYQUESIZE];int bodyqueslot;void A_AddPlayerCorpse(mobj_t *actor){ if(bodyqueslot >= BODYQUESIZE) { // Too many player corpses - remove an old one P_RemoveMobj(bodyque[bodyqueslot%BODYQUESIZE]); } bodyque[bodyqueslot%BODYQUESIZE] = actor; bodyqueslot++;}//============================================================================//// A_SerpentUnHide////============================================================================void A_SerpentUnHide(mobj_t *actor){ actor->flags2 &= ~MF2_DONTDRAW; actor->floorclip = 24*FRACUNIT;}//============================================================================//// A_SerpentHide////============================================================================void A_SerpentHide(mobj_t *actor){ actor->flags2 |= MF2_DONTDRAW; actor->floorclip = 0;}//============================================================================//// A_SerpentChase////============================================================================void A_SerpentChase(mobj_t *actor){ int delta; int oldX, oldY, oldFloor; if(actor->reactiontime) { actor->reactiontime--; } // Modify target threshold if(actor->threshold) { actor->threshold--; } if(gameskill == sk_nightmare) { // 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)) { // got a new target return; } P_SetMobjState(actor, actor->info->spawnstate); return; }//// don't attack twice in a row// if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; if (gameskill != sk_nightmare) P_NewChaseDir (actor); return; }//// check for melee attack// if (actor->info->meleestate && P_CheckMeleeRange (actor)) { if(actor->info->attacksound) { S_StartSound (actor, actor->info->attacksound); } P_SetMobjState (actor, actor->info->meleestate); return; }//// possibly choose another target// if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) { if (P_LookForPlayers(actor,true)) return; // got a new target }//// chase towards player// oldX = actor->x; oldY = actor->y; oldFloor = actor->subsector->sector->floorpic; if (--actor->movecount<0 || !P_Move (actor)) { P_NewChaseDir (actor); } if(actor->subsector->sector->floorpic != oldFloor) { P_TryMove(actor, oldX, oldY); P_NewChaseDir (actor); }//// make active sound// if(actor->info->activesound && P_Random() < 3) { S_StartSound(actor, actor->info->activesound); }}//============================================================================//// A_SerpentRaiseHump// // Raises the hump above the surface by raising the floorclip level//============================================================================void A_SerpentRaiseHump(mobj_t *actor){ actor->floorclip -= 4*FRACUNIT;}//============================================================================//// A_SerpentLowerHump// //============================================================================void A_SerpentLowerHump(mobj_t *actor){ actor->floorclip += 4*FRACUNIT;}//============================================================================//// A_SerpentHumpDecide//// Decided whether to hump up, or if the mobj is a serpent leader, // to missile attack//============================================================================void A_SerpentHumpDecide(mobj_t *actor){ if(actor->type == MT_SERPENTLEADER) { if(P_Random() > 30) { return; } else if(P_Random() < 40) { // Missile attack P_SetMobjState(actor, S_SERPENT_SURFACE1); return; } } else if(P_Random() > 3) { return; } if(!P_CheckMeleeRange(actor)) { // The hump shouldn't occur when within melee range if(actor->type == MT_SERPENTLEADER && P_Random() < 128) { P_SetMobjState(actor, S_SERPENT_SURFACE1); } else { P_SetMobjState(actor, S_SERPENT_HUMP1); S_StartSound(actor, SFX_SERPENT_ACTIVE); } }}//============================================================================//// A_SerpentBirthScream////============================================================================void A_SerpentBirthScream(mobj_t *actor){ S_StartSound(actor, SFX_SERPENT_BIRTH);}//============================================================================//// A_SerpentDiveSound////============================================================================void A_SerpentDiveSound(mobj_t *actor){ S_StartSound(actor, SFX_SERPENT_ACTIVE);}//============================================================================//// A_SerpentWalk//// Similar to A_Chase, only has a hardcoded entering of meleestate//============================================================================void A_SerpentWalk(mobj_t *actor){ int delta; if(actor->reactiontime) { actor->reactiontime--; } // Modify target threshold if(actor->threshold) { actor->threshold--; } if(gameskill == sk_nightmare) { // 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)) { // got a new target return; } P_SetMobjState(actor, actor->info->spawnstate); return; }//// don't attack twice in a row// if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; if (gameskill != sk_nightmare) P_NewChaseDir (actor); return; }//// check for melee attack// if (actor->info->meleestate && P_CheckMeleeRange (actor)) { if (actor->info->attacksound) { S_StartSound (actor, actor->info->attacksound); } P_SetMobjState(actor, S_SERPENT_ATK1); return; }//// possibly choose another target// if (netgame && !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); }}//============================================================================//// A_SerpentCheckForAttack////============================================================================void A_SerpentCheckForAttack(mobj_t *actor){ if(!actor->target) { return; } if(actor->type == MT_SERPENTLEADER) { if(!P_CheckMeleeRange(actor)) { P_SetMobjState(actor, S_SERPENT_ATK1); return; } } if(P_CheckMeleeRange2(actor)) { P_SetMobjState(actor, S_SERPENT_WALK1); } else if(P_CheckMeleeRange(actor)) { if(P_Random() < 32) { P_SetMobjState(actor, S_SERPENT_WALK1); } else { P_SetMobjState(actor, S_SERPENT_ATK1); } }}//============================================================================//// A_SerpentChooseAttack////============================================================================void A_SerpentChooseAttack(mobj_t *actor){ if(!actor->target || P_CheckMeleeRange(actor)) { return; } if(actor->type == MT_SERPENTLEADER) { P_SetMobjState(actor, S_SERPENT_MISSILE1); }} //============================================================================//// A_SerpentMeleeAttack////============================================================================void A_SerpentMeleeAttack(mobj_t *actor){ if(!actor->target) { return; } if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(5)); S_StartSound(actor, SFX_SERPENT_MELEEHIT); } if(P_Random() < 96) { A_SerpentCheckForAttack(actor); }}//============================================================================//// A_SerpentMissileAttack////============================================================================ void A_SerpentMissileAttack(mobj_t *actor){ mobj_t *mo; if(!actor->target) { return; } mo = P_SpawnMissile(actor, actor->target, MT_SERPENTFX);}//============================================================================//// A_SerpentHeadPop////============================================================================void A_SerpentHeadPop(mobj_t *actor){ P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, MT_SERPENT_HEAD);}//============================================================================//// A_SerpentSpawnGibs////============================================================================void A_SerpentSpawnGibs(mobj_t *actor){ mobj_t *mo; mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, MT_SERPENT_GIB1); if(mo) { mo->momx = (P_Random()-128)<<6; mo->momy = (P_Random()-128)<<6; mo->floorclip = 6*FRACUNIT; } mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, MT_SERPENT_GIB2); if(mo) { mo->momx = (P_Random()-128)<<6; mo->momy = (P_Random()-128)<<6; mo->floorclip = 6*FRACUNIT; } mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, MT_SERPENT_GIB3); if(mo) { mo->momx = (P_Random()-128)<<6; mo->momy = (P_Random()-128)<<6; mo->floorclip = 6*FRACUNIT; }}//============================================================================//// A_FloatGib////============================================================================void A_FloatGib(mobj_t *actor){ actor->floorclip -= FRACUNIT;}//============================================================================//// A_SinkGib////============================================================================void A_SinkGib(mobj_t *actor){ actor->floorclip += FRACUNIT;}//============================================================================//// A_DelayGib////============================================================================void A_DelayGib(mobj_t *actor){ actor->tics -= P_Random()>>2;}//============================================================================//// A_SerpentHeadCheck////============================================================================void A_SerpentHeadCheck(mobj_t *actor){ if(actor->z <= actor->floorz) { if(P_GetThingFloorType(actor) >= FLOOR_LIQUID) { P_HitFloor(actor); P_SetMobjState(actor, S_NULL); } else { P_SetMobjState(actor, S_SERPENT_HEAD_X1); } }}//============================================================================//// A_CentaurAttack////============================================================================void A_CentaurAttack(mobj_t *actor){ if(!actor->target) { return; } if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, P_Random()%7+3); }}//============================================================================//// A_CentaurAttack2////============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -