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

📄 p_henemy.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -