📄 p_enemy.c
字号:
void A_CentaurAttack2(mobj_t *actor){ if(!actor->target) { return; } P_SpawnMissile(actor, actor->target, MT_CENTAUR_FX); S_StartSound(actor, SFX_CENTAURLEADER_ATTACK);}//============================================================================//// A_CentaurDropStuff//// Spawn shield/sword sprites when the centaur pulps //============================================================================void A_CentaurDropStuff(mobj_t *actor){ mobj_t *mo; angle_t angle; mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, MT_CENTAUR_SHIELD); if(mo) { angle = actor->angle+ANG90; mo->momz = FRACUNIT*8+(P_Random()<<10); mo->momx = FixedMul(((P_Random()-128)<<11)+FRACUNIT, finecosine[angle>>ANGLETOFINESHIFT]); mo->momy = FixedMul(((P_Random()-128)<<11)+FRACUNIT, finesine[angle>>ANGLETOFINESHIFT]); mo->target = actor; } mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, MT_CENTAUR_SWORD); if(mo) { angle = actor->angle-ANG90; mo->momz = FRACUNIT*8+(P_Random()<<10); mo->momx = FixedMul(((P_Random()-128)<<11)+FRACUNIT, finecosine[angle>>ANGLETOFINESHIFT]); mo->momy = FixedMul(((P_Random()-128)<<11)+FRACUNIT, finesine[angle>>ANGLETOFINESHIFT]); mo->target = actor; }}//============================================================================//// A_CentaurDefend////============================================================================void A_CentaurDefend(mobj_t *actor){ A_FaceTarget(actor); if(P_CheckMeleeRange(actor) && P_Random() < 32) { A_UnSetInvulnerable(actor); P_SetMobjState(actor, actor->info->meleestate); }}//============================================================================//// A_BishopAttack////============================================================================void A_BishopAttack(mobj_t *actor){ if(!actor->target) { return; } S_StartSound(actor, actor->info->attacksound); if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(4)); return; } actor->special1 = (P_Random()&3)+5;}//============================================================================//// A_BishopAttack2//// Spawns one of a string of bishop missiles//============================================================================void A_BishopAttack2(mobj_t *actor){ mobj_t *mo; if(!actor->target || !actor->special1) { actor->special1 = 0; P_SetMobjState(actor, S_BISHOP_WALK1); return; } mo = P_SpawnMissile(actor, actor->target, MT_BISH_FX); if(mo) { mo->special1 = (int)actor->target; mo->special2 = 16; // High word == x/y, Low word == z } actor->special1--;}//============================================================================//// A_BishopMissileWeave////============================================================================void A_BishopMissileWeave(mobj_t *actor){ fixed_t newX, newY; int weaveXY, weaveZ; int angle; weaveXY = actor->special2>>16; weaveZ = actor->special2&0xFFFF; angle = (actor->angle+ANG90)>>ANGLETOFINESHIFT; newX = actor->x-FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]<<1); newY = actor->y-FixedMul(finesine[angle], FloatBobOffsets[weaveXY]<<1); weaveXY = (weaveXY+2)&63; newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]<<1); newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY]<<1); P_TryMove(actor, newX, newY); actor->z -= FloatBobOffsets[weaveZ]; weaveZ = (weaveZ+2)&63; actor->z += FloatBobOffsets[weaveZ]; actor->special2 = weaveZ+(weaveXY<<16);}//============================================================================//// A_BishopMissileSeek////============================================================================void A_BishopMissileSeek(mobj_t *actor){ P_SeekerMissile(actor, ANGLE_1*2, ANGLE_1*3);}//============================================================================//// A_BishopDecide////============================================================================void A_BishopDecide(mobj_t *actor){ if(P_Random() < 220) { return; } else { P_SetMobjState(actor, S_BISHOP_BLUR1); } }//============================================================================//// A_BishopDoBlur////============================================================================void A_BishopDoBlur(mobj_t *actor){ actor->special1 = (P_Random()&3)+3; // Random number of blurs if(P_Random() < 120) { P_ThrustMobj(actor, actor->angle+ANG90, 11*FRACUNIT); } else if(P_Random() > 125) { P_ThrustMobj(actor, actor->angle-ANG90, 11*FRACUNIT); } else { // Thrust forward P_ThrustMobj(actor, actor->angle, 11*FRACUNIT); } S_StartSound(actor, SFX_BISHOP_BLUR);}//============================================================================//// A_BishopSpawnBlur////============================================================================void A_BishopSpawnBlur(mobj_t *actor){ mobj_t *mo; if(!--actor->special1) { actor->momx = 0; actor->momy = 0; if(P_Random() > 96) { P_SetMobjState(actor, S_BISHOP_WALK1); } else { P_SetMobjState(actor, S_BISHOP_ATK1); } } mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BISHOPBLUR); if(mo) { mo->angle = actor->angle; }}//============================================================================//// A_BishopChase////============================================================================void A_BishopChase(mobj_t *actor){ actor->z -= FloatBobOffsets[actor->special2]>>1; actor->special2 = (actor->special2+4)&63; actor->z += FloatBobOffsets[actor->special2]>>1;}//============================================================================//// A_BishopPuff////============================================================================void A_BishopPuff(mobj_t *actor){ mobj_t *mo; mo = P_SpawnMobj(actor->x, actor->y, actor->z+40*FRACUNIT, MT_BISHOP_PUFF); if(mo) { mo->momz = FRACUNIT/2; }}//============================================================================//// A_BishopPainBlur////============================================================================void A_BishopPainBlur(mobj_t *actor){ mobj_t *mo; if(P_Random() < 64) { P_SetMobjState(actor, S_BISHOP_BLUR1); return; } mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<12), actor->y +((P_Random()-P_Random())<<12), actor->z+((P_Random()-P_Random())<<11), MT_BISHOPPAINBLUR); if(mo) { mo->angle = actor->angle; }}//============================================================================//// DragonSeek////============================================================================static void DragonSeek(mobj_t *actor, angle_t thresh, angle_t turnMax){ int dir; int dist; angle_t delta; angle_t angle; mobj_t *target; int search; int i; int bestArg; angle_t bestAngle; angle_t angleToSpot, angleToTarget; mobj_t *mo; target = (mobj_t *)actor->special1; if(target == NULL) { return; } dir = P_FaceMobj(actor, target, &delta); if(delta > thresh) { delta >>= 1; if(delta > turnMax) { delta = turnMax; } } if(dir) { // Turn clockwise actor->angle += delta; } else { // Turn counter clockwise actor->angle -= delta; } angle = actor->angle>>ANGLETOFINESHIFT; actor->momx = FixedMul(actor->info->speed, finecosine[angle]); actor->momy = FixedMul(actor->info->speed, finesine[angle]); if(actor->z+actor->height < target->z || target->z+target->height < actor->z) { dist = P_AproxDistance(target->x-actor->x, target->y-actor->y); dist = dist/actor->info->speed; if(dist < 1) { dist = 1; } actor->momz = (target->z-actor->z)/dist; } else { dist = P_AproxDistance(target->x-actor->x, target->y-actor->y); dist = dist/actor->info->speed; } if(target->flags&MF_SHOOTABLE && P_Random() < 64) { // attack the destination mobj if it's attackable mobj_t *oldTarget; if(abs(actor->angle-R_PointToAngle2(actor->x, actor->y, target->x, target->y)) < ANGLE_45/2) { oldTarget = actor->target; actor->target = target; if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(10)); S_StartSound(actor, SFX_DRAGON_ATTACK); } else if(P_Random() < 128 && P_CheckMissileRange(actor)) { P_SpawnMissile(actor, target, MT_DRAGON_FX); S_StartSound(actor, SFX_DRAGON_ATTACK); } actor->target = oldTarget; } } if(dist < 4) { // Hit the target thing if(actor->target && P_Random() < 200) { bestArg = -1; bestAngle = ANGLE_MAX; angleToTarget = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); for(i = 0; i < 5; i++) { if(!target->args[i]) { continue; } search = -1; mo = P_FindMobjFromTID(target->args[i], &search); angleToSpot = R_PointToAngle2(actor->x, actor->y, mo->x, mo->y); if(abs(angleToSpot-angleToTarget) < bestAngle) { bestAngle = abs(angleToSpot-angleToTarget); bestArg = i; } } if(bestArg != -1) { search = -1; actor->special1 = (int)P_FindMobjFromTID(target->args[bestArg], &search); } } else { do { i = (P_Random()>>2)%5; } while(!target->args[i]); search = -1; actor->special1 = (int)P_FindMobjFromTID(target->args[i], &search); } }}//============================================================================//// A_DragonInitFlight////============================================================================void A_DragonInitFlight(mobj_t *actor){ int search; search = -1; do { // find the first tid identical to the dragon's tid actor->special1 = (int)P_FindMobjFromTID(actor->tid, &search); if(search == -1) { P_SetMobjState(actor, actor->info->spawnstate); return; } } while(actor->special1 == (int)actor); P_RemoveMobjFromTIDList(actor);}//============================================================================//// A_DragonFlight////============================================================================void A_DragonFlight(mobj_t *actor){ angle_t angle; DragonSeek(actor, 4*ANGLE_1, 8*ANGLE_1); if(actor->target) { if(!(actor->target->flags&MF_SHOOTABLE)) { // target died actor->target = NULL; return; } angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); if(abs(actor->angle-angle) < ANGLE_45/2 && P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(8)); S_StartSound(actor, SFX_DRAGON_ATTACK); } else if(abs(actor->angle-angle) <= ANGLE_1*20) { P_SetMobjState(actor, actor->info->missilestate); S_StartSound(actor, SFX_DRAGON_ATTACK); } } else { P_LookForPlayers(actor, true); }}//============================================================================//// A_DragonFlap////============================================================================void A_DragonFlap(mobj_t *actor){ A_DragonFlight(actor); if(P_Random() < 240) { S_StartSound(actor, SFX_DRAGON_WINGFLAP); } else { S_StartSound(actor, actor->info->activesound); }}//============================================================================//// A_DragonAttack////============================================================================void A_DragonAttack(mobj_t *actor){ mobj_t *mo; mo = P_SpawnMissile(actor, actor->target, MT_DRAGON_FX); }//============================================================================//// A_DragonFX2////============================================================================void A_DragonFX2(mobj_t *actor){ mobj_t *mo; int i; int delay; delay = 16+(P_Random()>>3); for(i = 1+(P_Random()&3); i; i--) { mo = P_SpawnMobj(actor->x+((P_Random()-128)<<14), actor->y+((P_Random()-128)<<14), actor->z+((P_Random()-128)<<12), MT_DRAGON_FX2); if(mo) { mo->tics = delay+(P_Random()&3)*i*2; mo->target = actor->target; } } }//============================================================================//// A_DragonPain////============================================================================void A_DragonPain(mobj_t *actor){ A_Pain(actor); if(!actor->special1) { // no destination spot yet P_SetMobjState(actor, S_DRAGON_INIT); }}//============================================================================//// A_DragonCheckCrash////============================================================================void A_DragonCheckCrash(mobj_t *actor){ if(actor->z <= actor->floorz) { P_SetMobjState(actor, S_DRAGON_CRASH1); }}//============================================================================// Demon AI//============================================================================//// A_DemonAttack1 (melee)//void A_DemonAttack1(mobj_t *actor){ if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(2)); }}//// A_DemonAttack2 (missile)//void A_DemonAttack2(mobj_t *actor){ mobj_t *mo; int fireBall; if(actor->type == MT_DEMON) { fireBall = MT_DEMONFX1; } else { fireBall = MT_DEMON2FX1; } mo = P_SpawnMissile(actor, actor->target, fireBall); if (mo) { mo->z += 30*FRACUNIT; S_StartSound(actor, SFX_DEMON_MISSILE_FIRE); }}//// A_DemonDeath//void A_DemonDeath(mobj_t *actor){ mobj_t *mo; angle_t angle; mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, MT_DEMONCHUNK1); if(mo) { angle = actor->angle+ANG90; mo->momz = 8*FRACUNIT; mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, finecosine[angle>>ANGLETOFINESHIFT]); mo->momy = FixedMul((P_Random()<
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -