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

📄 p_enemy.c

📁 制作游戏 魔法师传奇 源代码设计 MOFASHICHUANQI 经典老游戏
💻 C
📖 第 1 页 / 共 5 页
字号:
	// Missile attack	if (actor->info->missilestate && P_CheckMissileRange(actor))	{		P_SetMobjState (actor, actor->info->missilestate);		return;	}	// chase towards target	if (!P_Move(actor))	{		P_NewChaseDir(actor);	}	// Active sound	if(actor->info->activesound && P_Random() < 6)	{		S_StartSound(actor, actor->info->activesound);	}}//----------------------------------------------------------------------------//// PROC A_MinotaurAtk1//// Melee attack.////----------------------------------------------------------------------------void A_MinotaurAtk1(mobj_t *actor){	if (!actor->target) return;	S_StartSound(actor, SFX_MAULATOR_HAMMER_SWING);	if(P_CheckMeleeRange(actor))	{		P_DamageMobj(actor->target, actor, actor, HITDICE(4));	}}//----------------------------------------------------------------------------//// PROC A_MinotaurDecide//// Choose a missile attack.////----------------------------------------------------------------------------#define MNTR_CHARGE_SPEED (23*FRACUNIT)void A_MinotaurDecide(mobj_t *actor){	angle_t angle;	mobj_t *target = actor->target;	int dist;	if (!target) return;	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 < 16*64*FRACUNIT		&& dist > 1*64*FRACUNIT		&& P_Random() < 230)	{ // 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->args[4] = 35/2; // Charge duration	}	else if(target->z == target->floorz		&& dist < 9*64*FRACUNIT		&& P_Random() < 100)	{ // 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->target) return;	if(actor->args[4] > 0)	{		puff = P_SpawnMobj(actor->x, actor->y, actor->z, MT_PUNCHPUFF);		puff->momz = 2*FRACUNIT;		actor->args[4]--;	}	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_MAULATOR_HAMMER_SWING);	if(P_CheckMeleeRange(actor))	{		P_DamageMobj(actor->target, actor, actor, HITDICE(3));		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(3));		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_MAULATOR_HAMMER_HIT);		}	}	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;	actor->z = actor->floorz;	mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<10),		actor->y+((P_Random()-P_Random())<<10), ONFLOORZ, MT_MNTRFX3);	mo->target = actor->target;	mo->momx = 1; // Force block checking	P_CheckMissileSpawn(mo);}//----------------------------------------------------------------------------//// PROC A_Scream////----------------------------------------------------------------------------void A_Scream(mobj_t *actor){	int sound;	S_StopSound(actor);	if(actor->player)	{		if(actor->player->morphTics)		{			S_StartSound(actor, actor->info->deathsound);		}		else		{			// Handle the different player death screams			if(actor->momz <= -39*FRACUNIT)			{ // Falling splat				sound = SFX_PLAYER_FALLING_SPLAT;			}			else if(actor->health > -50)			{ // Normal death sound				switch(actor->player->class)				{					case PCLASS_FIGHTER:						sound = SFX_PLAYER_FIGHTER_NORMAL_DEATH;						break;					case PCLASS_CLERIC:						sound = SFX_PLAYER_CLERIC_NORMAL_DEATH;						break;					case PCLASS_MAGE:						sound = SFX_PLAYER_MAGE_NORMAL_DEATH;						break;					default:						sound = SFX_NONE;						break;				}			}			else if(actor->health > -100)			{ // Crazy death sound				switch(actor->player->class)				{					case PCLASS_FIGHTER:						sound = SFX_PLAYER_FIGHTER_CRAZY_DEATH;						break;					case PCLASS_CLERIC:						sound = SFX_PLAYER_CLERIC_CRAZY_DEATH;						break;					case PCLASS_MAGE:						sound = SFX_PLAYER_MAGE_CRAZY_DEATH;						break;					default:						sound = SFX_NONE;						break;				}			}			else			{ // Extreme death sound				switch(actor->player->class)				{					case PCLASS_FIGHTER:						sound = SFX_PLAYER_FIGHTER_EXTREME1_DEATH;						break;					case PCLASS_CLERIC:						sound = SFX_PLAYER_CLERIC_EXTREME1_DEATH;						break;					case PCLASS_MAGE:						sound = SFX_PLAYER_MAGE_EXTREME1_DEATH;						break;					default:						sound = SFX_NONE;						break;				}				sound += P_Random()%3; // Three different extreme deaths			}			S_StartSound(actor, sound);		}	}	else	{		S_StartSound(actor, actor->info->deathsound);	}}//---------------------------------------------------------------------------//// PROC P_DropItem////---------------------------------------------------------------------------/*void P_DropItem(mobj_t *source, mobjtype_t type, int special, int chance){	mobj_t *mo;	if(P_Random() > chance)	{		return;	}	mo = P_SpawnMobj(source->x, source->y,		source->z+(source->height>>1), type);	mo->momx = (P_Random()-P_Random())<<8;	mo->momy = (P_Random()-P_Random())<<8;	mo->momz = FRACUNIT*5+(P_Random()<<10);	mo->flags2 |= MF2_DROPPED;	mo->health = special;}*///----------------------------------------------------------------------------//// PROC A_NoBlocking////----------------------------------------------------------------------------void A_NoBlocking(mobj_t *actor){	actor->flags &= ~MF_SOLID;	// Check for monsters dropping things/*	switch(actor->type)	{		// Add the monster dropped items here		case MT_MUMMYLEADERGHOST:			P_DropItem(actor, MT_AMGWNDWIMPY, 3, 84);			break;		default:			break;	}*/}//----------------------------------------------------------------------------//// PROC A_Explode//// Handles a bunch of exploding things.////----------------------------------------------------------------------------void A_Explode(mobj_t *actor){	int damage;	int distance;	boolean damageSelf;	damage = 128;	distance = 128;	damageSelf = true;	switch(actor->type)	{		case MT_FIREBOMB: // Time Bombs			actor->z += 32*FRACUNIT;			actor->flags &= ~MF_SHADOW;			break;		case MT_MNTRFX2: // Minotaur floor fire			damage = 24;			break;		case MT_BISHOP: // Bishop radius death			damage = 25+(P_Random()&15);			break;		case MT_HAMMER_MISSILE: // Fighter Hammer			damage = 128;			damageSelf = false;			break;		case MT_FSWORD_MISSILE: // Fighter Runesword			damage = 64;			damageSelf = false;			break;		case MT_CIRCLEFLAME: // Cleric Flame secondary flames			damage = 20;			damageSelf = false;			break;		case MT_SORCBALL1: 	// Sorcerer balls		case MT_SORCBALL2:		case MT_SORCBALL3:			distance = 255;			damage = 255;			actor->args[0] = 1;		// don't play bounce			break;		case MT_SORCFX1: 	// Sorcerer spell 1			damage = 30;			break;		case MT_SORCFX4: 	// Sorcerer spell 4			damage = 20;			break;		case MT_TREEDESTRUCTIBLE:			damage = 10;			break;		case MT_DRAGON_FX2:			damage = 80;			damageSelf = false;			break;		case MT_MSTAFF_FX:			damage = 64;			distance = 192;			damageSelf = false;			break;		case MT_MSTAFF_FX2:			damage = 80;			distance = 192;			damageSelf = false;			break;		case MT_POISONCLOUD:			damage = 4;			distance = 40;			break;		case MT_ZXMAS_TREE:		case MT_ZSHRUB2:			damage = 30;			distance = 64;			break;		default:			break;	}	P_RadiusAttack(actor, actor->target, damage, distance, damageSelf);	if(actor->z <= actor->floorz+(distance<<FRACBITS)		&& actor->type != MT_POISONCLOUD)	{ 		P_HitFloor(actor);	}}//----------------------------------------------------------------------------//// PROC P_Massacre//// Kills all monsters.////----------------------------------------------------------------------------int P_Massacre(void){	int count;	mobj_t *mo;	thinker_t *think;	count = 0;	for(think = thinkercap.next; think != &thinkercap;		think = think->next)	{		if(think->function != P_MobjThinker)		{ // Not a mobj thinker			continue;		}		mo = (mobj_t *)think;		if((mo->flags&MF_COUNTKILL) && (mo->health > 0))		{			mo->flags2 &= ~(MF2_NONSHOOTABLE+MF2_INVULNERABLE);			mo->flags |= MF_SHOOTABLE;			P_DamageMobj(mo, NULL, NULL, 10000);			count++;		}	}	return count;}//----------------------------------------------------------------------------//// PROC A_SkullPop////----------------------------------------------------------------------------void A_SkullPop(mobj_t *actor){	mobj_t *mo;	player_t *player;	if(!actor->player)	{		return;	}	actor->flags &= ~MF_SOLID;	mo = P_SpawnMobj(actor->x, actor->y, actor->z+48*FRACUNIT,		MT_BLOODYSKULL);	//mo->target = actor;	mo->momx = (P_Random()-P_Random())<<9;	mo->momy = (P_Random()-P_Random())<<9;	mo->momz = FRACUNIT*2+(P_Random()<<6);	// Attach player mobj to bloody skull	player = actor->player;	actor->player = NULL;	actor->special1 = player->class;	mo->player = player;	mo->health = actor->health;	mo->angle = actor->angle;	player->mo = mo;	player->lookdir = 0;	player->damagecount = 32;}//----------------------------------------------------------------------------//// PROC A_CheckSkullFloor////----------------------------------------------------------------------------void A_CheckSkullFloor(mobj_t *actor){	if(actor->z <= actor->floorz)	{		P_SetMobjState(actor, S_BLOODYSKULLX1);		S_StartSound(actor, SFX_DRIP);	}}//----------------------------------------------------------------------------//// PROC A_CheckSkullDone////----------------------------------------------------------------------------void A_CheckSkullDone(mobj_t *actor){	if(actor->special2 == 666)	{		P_SetMobjState(actor, S_BLOODYSKULLX2);	}}//----------------------------------------------------------------------------//// PROC A_CheckBurnGone////----------------------------------------------------------------------------void A_CheckBurnGone(mobj_t *actor){	if(actor->special2 == 666)	{		P_SetMobjState(actor, S_PLAY_FDTH20);	}}//----------------------------------------------------------------------------//// PROC A_FreeTargMobj////----------------------------------------------------------------------------void A_FreeTargMobj(mobj_t *mo){	mo->momx = mo->momy = mo->momz = 0;	mo->z = mo->ceilingz+4*FRACUNIT;	mo->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY|MF_SOLID|MF_COUNTKILL);	mo->flags |= MF_CORPSE|MF_DROPOFF|MF_NOGRAVITY;	mo->flags2 &= ~(MF2_PASSMOBJ|MF2_LOGRAV);	mo->flags2 |= MF2_DONTDRAW;	mo->player = NULL;	mo->health = -1000;		// Don't resurrect}//----------------------------------------------------------------------------//// CorpseQueue Routines////----------------------------------------------------------------------------// Corpse queue for monsters - this should be saved out#define CORPSEQUEUESIZE	64mobj_t *corpseQueue[CORPSEQUEUESIZE];int corpseQueueSlot;// throw another corpse on the queuevoid A_QueueCorpse(mobj_t *actor){	mobj_t *corpse;	if(corpseQueueSlot >= CORPSEQUEUESIZE)	{ // Too many corpses - remove an old one		corpse = corpseQueue[corpseQueueSlot%CORPSEQUEUESIZE];		if (corpse) P_RemoveMobj(corpse);	}	corpseQueue[corpseQueueSlot%CORPSEQUEUESIZE] = actor;	corpseQueueSlot++;}// Remove a mobj from the queue (for resurrection)void A_DeQueueCorpse(mobj_t *actor){	int slot;	for (slot=0; slot<CORPSEQUEUESIZE; slot++)	{		if (corpseQueue[slot] == actor)		{			corpseQueue[slot] = NULL;			break;		}	}}void P_InitCreatureCorpseQueue(boolean corpseScan){	thinker_t *think;	mobj_t *mo;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -