📄 p_henemy.c
字号:
if(actor->health > (actor->info->spawnhealth/3)*2) { // Spit one fireball P_SpawnMissile(actor, actor->target, MT_SRCRFX1); } else { // Spit three fireballs mo = P_SpawnMissile(actor, actor->target, MT_SRCRFX1); if(mo) { momz = mo->momz; angle = mo->angle; P_SpawnMissileAngle(actor, MT_SRCRFX1, angle-ANGLE_1*3, momz); P_SpawnMissileAngle(actor, MT_SRCRFX1, angle+ANGLE_1*3, momz); } if(actor->health < actor->info->spawnhealth/3) { // Maybe attack again if(actor->special1) { // Just attacked, so don't attack again actor->special1 = 0; } else { // Set state to attack again actor->special1 = 1; P_SetMobjState(actor, S_SRCR1_ATK4); } } }}//----------------------------------------------------------------------------//// PROC A_SorcererRise////----------------------------------------------------------------------------void A_SorcererRise(mobj_t *actor){ mobj_t *mo; actor->flags &= ~MF_SOLID; mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCERER2); P_SetMobjState(mo, S_SOR2_RISE1); mo->angle = actor->angle; mo->target = actor->target;}//----------------------------------------------------------------------------//// PROC P_DSparilTeleport////----------------------------------------------------------------------------void P_DSparilTeleport(mobj_t *actor){ int i; fixed_t x; fixed_t y; fixed_t prevX; fixed_t prevY; fixed_t prevZ; mobj_t *mo; if(!BossSpotCount) { // No spots return; } i = P_Random(); do { i++; x = BossSpots[i%BossSpotCount].x; y = BossSpots[i%BossSpotCount].y; } while(P_AproxDistance(actor->x-x, actor->y-y) < 128*FRACUNIT); prevX = actor->x; prevY = actor->y; prevZ = actor->z; if(P_TeleportMove(actor, x, y)) { mo = P_SpawnMobj(prevX, prevY, prevZ, MT_SOR2TELEFADE); S_StartSound(mo, sfx_telept); P_SetMobjState(actor, S_SOR2_TELE1); S_StartSound(actor, sfx_telept); actor->z = actor->floorz; actor->angle = BossSpots[i%BossSpotCount].angle; actor->momx = actor->momy = actor->momz = 0; }}//----------------------------------------------------------------------------//// PROC A_Srcr2Decide////----------------------------------------------------------------------------void A_Srcr2Decide(mobj_t *actor){ static int chance[] = { 192, 120, 120, 120, 64, 64, 32, 16, 0 }; if(!BossSpotCount) { // No spots return; } if(P_Random() < chance[actor->health/(actor->info->spawnhealth/8)]) { P_DSparilTeleport(actor); }}//----------------------------------------------------------------------------//// PROC A_Srcr2Attack////----------------------------------------------------------------------------void A_Srcr2Attack(mobj_t *actor){ int chance; if(!actor->target) { return; } S_StartSound(NULL, actor->info->attacksound); if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(20)); return; } chance = actor->health < actor->info->spawnhealth/2 ? 96 : 48; if(P_Random() < chance) { // Wizard spawners P_SpawnMissileAngle(actor, MT_SOR2FX2, actor->angle-ANG45, FRACUNIT/2); P_SpawnMissileAngle(actor, MT_SOR2FX2, actor->angle+ANG45, FRACUNIT/2); } else { // Blue bolt P_SpawnMissile(actor, actor->target, MT_SOR2FX1); }}//----------------------------------------------------------------------------//// PROC A_BlueSpark////----------------------------------------------------------------------------void A_BlueSpark(mobj_t *actor){ int i; mobj_t *mo; for(i = 0; i < 2; i++) { mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SOR2FXSPARK); mo->momx = P_SignedRandom()<<9; mo->momy = P_SignedRandom()<<9; mo->momz = FRACUNIT+(P_Random()<<8); }}//----------------------------------------------------------------------------//// PROC A_GenWizard////----------------------------------------------------------------------------void A_GenWizard(mobj_t *actor){ mobj_t *mo; mobj_t *fog; mo = P_SpawnMobj(actor->x, actor->y, actor->z-mobjinfo[MT_WIZARD].height/2, MT_WIZARD); if(P_TestMobjLocation(mo) == false) { // Didn't fit P_RemoveMobj(mo); return; } actor->momx = actor->momy = actor->momz = 0; P_SetMobjState(actor, mobjinfo[actor->type].deathstate); actor->flags &= ~MF_MISSILE; fog = P_SpawnMobj(actor->x, actor->y, actor->z, MT_TFOG); S_StartSound(fog, sfx_telept);}//----------------------------------------------------------------------------//// PROC A_Sor2DthInit////----------------------------------------------------------------------------void A_Sor2DthInit(mobj_t *actor){ actor->special1 = 7; // Animation loop counter P_Massacre(); // Kill monsters early}//----------------------------------------------------------------------------//// PROC A_Sor2DthLoop////----------------------------------------------------------------------------void A_Sor2DthLoop(mobj_t *actor){ if(--actor->special1) { // Need to loop P_SetMobjState(actor, S_SOR2_DIE4); }}//----------------------------------------------------------------------------//// D'Sparil Sound Routines////----------------------------------------------------------------------------void A_SorZap(mobj_t *actor) {S_StartSound(NULL, sfx_sorzap);}void A_SorRise(mobj_t *actor) {S_StartSound(NULL, sfx_sorrise);}void A_SorDSph(mobj_t *actor) {S_StartSound(NULL, sfx_sordsph);}void A_SorDExp(mobj_t *actor) {S_StartSound(NULL, sfx_sordexp);}void A_SorDBon(mobj_t *actor) {S_StartSound(NULL, sfx_sordbon);}void A_SorSightSnd(mobj_t *actor) {S_StartSound(NULL, sfx_sorsit);}//----------------------------------------------------------------------------//// PROC A_MinotaurAtk1//// Melee attack.////----------------------------------------------------------------------------void A_MinotaurAtk1(mobj_t *actor){ player_t *player; if(!actor->target) { return; } S_StartSound(actor, sfx_stfpow); if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(4)); if((player = actor->target->player) != NULL) { // Squish the player player->deltaviewheight = -16*FRACUNIT; } }}//----------------------------------------------------------------------------//// PROC A_MinotaurDecide//// Choose a missile attack.////----------------------------------------------------------------------------#define MNTR_CHARGE_SPEED (13*FRACUNIT)void A_MinotaurDecide(mobj_t *actor){ angle_t angle; mobj_t *target; int dist; target = actor->target; if(!target) { return; } S_StartSound(actor, sfx_minsit); dist = P_AproxDistance(actor->x-target->x, actor->y-target->y); if(target->z+target->height > actor->z && target->z+target->height < actor->z+actor->height && dist < 8*64*FRACUNIT && dist > 1*64*FRACUNIT && P_Random() < 150) { // Charge attack // Don't call the state function right away P_SetMobjStateNF(actor, S_MNTR_ATK4_1); actor->flags |= MF_SKULLFLY; A_FaceTarget(actor); angle = actor->angle>>ANGLETOFINESHIFT; actor->momx = FixedMul(MNTR_CHARGE_SPEED, finecosine[angle]); actor->momy = FixedMul(MNTR_CHARGE_SPEED, finesine[angle]); actor->special1 = 35/2; // Charge duration } else if(target->z == target->floorz && dist < 9*64*FRACUNIT && P_Random() < 220) { // Floor fire attack P_SetMobjState(actor, S_MNTR_ATK3_1); actor->special2 = 0; } else { // Swing attack A_FaceTarget(actor); // Don't need to call P_SetMobjState because the current state // falls through to the swing attack }}//----------------------------------------------------------------------------//// PROC A_MinotaurCharge////----------------------------------------------------------------------------void A_MinotaurCharge(mobj_t *actor){ mobj_t *puff; if(actor->special1) { puff = P_SpawnMobj(actor->x, actor->y, actor->z, MT_PHOENIXPUFF); puff->momz = 2*FRACUNIT; actor->special1--; } else { actor->flags &= ~MF_SKULLFLY; P_SetMobjState(actor, actor->info->seestate); }}//----------------------------------------------------------------------------//// PROC A_MinotaurAtk2//// Swing attack.////----------------------------------------------------------------------------void A_MinotaurAtk2(mobj_t *actor){ mobj_t *mo; angle_t angle; fixed_t momz; if(!actor->target) { return; } S_StartSound(actor, sfx_minat2); if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(5)); return; } mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX1); if(mo) { S_StartSound(mo, sfx_minat2); momz = mo->momz; angle = mo->angle; P_SpawnMissileAngle(actor, MT_MNTRFX1, angle-(ANG45/8), momz); P_SpawnMissileAngle(actor, MT_MNTRFX1, angle+(ANG45/8), momz); P_SpawnMissileAngle(actor, MT_MNTRFX1, angle-(ANG45/16), momz); P_SpawnMissileAngle(actor, MT_MNTRFX1, angle+(ANG45/16), momz); }}//----------------------------------------------------------------------------//// PROC A_MinotaurAtk3//// Floor fire attack.////----------------------------------------------------------------------------void A_MinotaurAtk3(mobj_t *actor){ mobj_t *mo; player_t *player; if(!actor->target) { return; } if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(5)); if((player = actor->target->player) != NULL) { // Squish the player player->deltaviewheight = -16*FRACUNIT; } } else { mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX2); if(mo != NULL) { S_StartSound(mo, sfx_minat1); } } if(P_Random() < 192 && actor->special2 == 0) { P_SetMobjState(actor, S_MNTR_ATK3_4); actor->special2 = 1; }}//----------------------------------------------------------------------------//// PROC A_MntrFloorFire////----------------------------------------------------------------------------void A_MntrFloorFire(mobj_t *actor){ mobj_t *mo; int r,s; actor->z = actor->floorz; r = P_SignedRandom(); s = P_SignedRandom(); mo = P_SpawnMobj(actor->x+(r<<10), actor->y+(s<<10), ONFLOORZ, MT_MNTRFX3); mo->target = actor->target; mo->momx = 1; // Force block checking P_CheckMissileSpawn(mo);}//----------------------------------------------------------------------------//// PROC A_BeastAttack////----------------------------------------------------------------------------void A_BeastAttack(mobj_t *actor){ if(!actor->target) { return; } S_StartSound(actor, actor->info->attacksound); if(P_CheckMeleeRange(actor)) { P_DamageMobj(actor->target, actor, actor, HITDICE(3)); return; } P_SpawnMissile(actor, actor->target, MT_BEASTBALL);}//----------------------------------------------------------------------------//// PROC A_HeadAttack////----------------------------------------------------------------------------void A_HHeadAttack(mobj_t *actor){ int i; mobj_t *fire; mobj_t *baseFire; mobj_t *mo; mobj_t *target; int randAttack; static int atkResolve1[] = { 50, 150 }; static int atkResolve2[] = { 150, 200 }; int dist; // Ice ball (close 20% : far 60%) // Fire column (close 40% : far 20%) // Whirlwind (close 40% : far 20%) // Distance threshold = 8 cells target = actor->target; if(target == NULL) { return; } A_FaceTarget(actor); if(P_CheckMeleeRange(actor)) { P_DamageMobj(target, actor, actor, HITDICE(6)); return; } dist = P_AproxDistance(actor->x-target->x, actor->y-target->y) > 8*64*FRACUNIT; randAttack = P_Random(); if(randAttack < atkResolve1[dist]) { // Ice ball P_SpawnMissile(actor, target, MT_HEADFX1); S_StartSound(actor, sfx_hedat2); } else if(randAttack < atkResolve2[dist]) { // Fire column baseFire = P_SpawnMissile(actor, target, MT_HEADFX3); if(baseFire != NULL) { P_SetMobjState(baseFire, S_HHEADFX3_4); // Don't grow for(i = 0; i < 5; i++) { fire = P_SpawnMobj(baseFire->x, baseFire->y, baseFire->z, MT_HEADFX3); if(i == 0) { S_StartSound(actor, sfx_hedat1); } fire->target = baseFire->target; fire->angle = baseFire->angle; fire->momx = baseFire->momx; fire->momy = baseFire->momy; fire->momz = baseFire->momz; //fire->damage = 0; fire->health = (i+1)*2; P_CheckMissileSpawn(fire); } } } else { // Whirlwind mo = P_SpawnMissile(actor, target, MT_WHIRLWIND); if(mo != NULL) { mo->z -= 32*FRACUNIT; mo->special1 = (int)target; mo->special2 = 50; // Timer for active sound mo->health = 20*TICRATE; // Duration S_StartSound(actor, sfx_hedat3); } }}//----------------------------------------------------------------------------//// PROC A_WhirlwindSeek////----------------------------------------------------------------------------void A_WhirlwindSeek(mobj_t *actor){ actor->health -= 3; if(actor->health < 0) { actor->momx = actor->momy = actor->momz = 0; P_SetMobjState(actor, mobjinfo[actor->type].deathstate); actor->flags &= ~MF_MISSILE; return; } if((actor->special2 -= 3) < 0) { actor->special2 = 58+(P_Random()&31); S_StartSound(actor, sfx_hedat3); } if(actor->special1 && (((mobj_t *)(actor->special1))->flags&MF_SHADOW)) { return; } P_SeekerMissile(actor, ANGLE_1*10, ANGLE_1*30);}//----------------------------------------------------------------------------//// PROC A_HeadIceImpact////----------------------------------------------------------------------------void A_HeadIceImpact(mobj_t *ice){ int i; angle_t angle; mobj_t *shard; for(i = 0; i < 8; i++) { shard = P_SpawnMobj(ice->x, ice->y, ice->z, MT_HEADFX2); angle = i*ANG45; shard->target = ice->target; shard->angle = angle; angle >>= ANGLETOFINESHIFT; shard->momx = FixedMul(shard->info->speed, finecosine[angle]); shard->momy = FixedMul(shard->info->speed, finesine[angle]); shard->momz = -.6*FRACUNIT; P_CheckMissileSpawn(shard); }}//----------------------------------------------------------------------------//// PROC A_HeadFireGrow////----------------------------------------------------------------------------void A_HeadFireGrow(mobj_t *fire){ fire->health--; fire->z += 9*FRACUNIT; if(fire->health == 0) { //fire->damage = fire->info->damage; P_SetMobjState(fire, S_HHEADFX3_4); }}//----------------------------------------------------------------------------//// PROC A_SnakeAttack////----------------------------------------------------------------------------void A_SnakeAttack(mobj_t *actor){ if(!actor->target) { P_SetMobjState(actor, S_SNAKE_WALK1); return; } S_StartSound(actor, actor->info->attacksound); A_FaceTarget(actor); P_SpawnMissile(actor, actor->target, MT_SNAKEPRO_A);}//----------------------------------------------------------------------------//// PROC A_SnakeAttack2////----------------------------------------------------------------------------void A_SnakeAttack2(mobj_t *actor){ if(!actor->target) { P_SetMobjState(actor, S_SNAKE_WALK1); return; } S_StartSound(actor, actor->info->attacksound); A_FaceTarget(actor); P_SpawnMissile(actor, actor->target, MT_SNAKEPRO_B);}//----------------------------------------------------------------------------//// PROC A_ClinkAttack////----------------------------------------------------------------------------void A_ClinkAttack(mobj_t *actor){ int damage; if(!actor->target) { return; } S_StartSound(actor, actor->info->attacksound);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -