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

📄 p_user.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
		mo->flags2 &= ~MF2_SLIDE;	}}void P_BlastMobj(mobj_t *source, mobj_t *victim, fixed_t strength){	angle_t angle,ang;	mobj_t *mo;	fixed_t x,y,z;	angle = R_PointToAngle2(source->x, source->y, victim->x, victim->y);	angle >>= ANGLETOFINESHIFT;	if (strength < BLAST_FULLSTRENGTH)	{		victim->momx = FixedMul(strength, finecosine[angle]);		victim->momy = FixedMul(strength, finesine[angle]);		if (victim->player)		{			// Players handled automatically		}		else		{			victim->flags2 |= MF2_SLIDE;			victim->flags2 |= MF2_BLASTED;		}	}	else		// full strength blast from artifact	{		if (victim->flags&MF_MISSILE)		{			switch(victim->type)			{				case MT_SORCBALL1:	// don't blast sorcerer balls				case MT_SORCBALL2:				case MT_SORCBALL3:					return;					break;				case MT_MSTAFF_FX2:	// Reflect to originator					victim->special1 = (int)victim->target;						victim->target = source;					break;				default:					break;			}		}		if (victim->type == MT_HOLY_FX)		{			if ((mobj_t *)(victim->special1) == source)			{				victim->special1 = (int)victim->target;					victim->target = source;			}		}		victim->momx = FixedMul(BLAST_SPEED, finecosine[angle]);		victim->momy = FixedMul(BLAST_SPEED, finesine[angle]);		// Spawn blast puff		ang = R_PointToAngle2(victim->x, victim->y, source->x, source->y);		ang >>= ANGLETOFINESHIFT;		x = victim->x + FixedMul(victim->radius+FRACUNIT, finecosine[ang]);		y = victim->y + FixedMul(victim->radius+FRACUNIT, finesine[ang]);		z = victim->z - victim->floorclip + (victim->height>>1);		mo=P_SpawnMobj(x, y, z, MT_BLASTEFFECT);		if (mo)		{			mo->momx = victim->momx;			mo->momy = victim->momy;		}		if (victim->flags&MF_MISSILE)		{			victim->momz = 8*FRACUNIT;			mo->momz = victim->momz;		}		else		{			victim->momz = (1000/victim->info->mass)<<FRACBITS;		}		if (victim->player)		{			// Players handled automatically		}		else		{			victim->flags2 |= MF2_SLIDE;			victim->flags2 |= MF2_BLASTED;		}	}}// Blast all mobj things awayvoid P_BlastRadius(player_t *player){	mobj_t *mo;	mobj_t *pmo=player->mo;	thinker_t *think;	fixed_t dist;	S_StartSound(pmo, SFX_ARTIFACT_BLAST);	P_NoiseAlert(player->mo, player->mo);	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 == pmo) || (mo->flags2&MF2_BOSS))		{ // Not a valid monster			continue;		}		if ((mo->type == MT_POISONCLOUD) ||		// poison cloud			(mo->type == MT_HOLY_FX) ||			// holy fx			(mo->flags&MF_ICECORPSE))			// frozen corpse		{			// Let these special cases go		}		else if ((mo->flags&MF_COUNTKILL) &&			(mo->health <= 0))		{			continue;		}		else if (!(mo->flags&MF_COUNTKILL) &&			!(mo->player) &&			!(mo->flags&MF_MISSILE))		{	// Must be monster, player, or missile			continue;		}		if (mo->flags2&MF2_DORMANT)		{			continue;		// no dormant creatures		}		if ((mo->type == MT_WRAITHB) && (mo->flags2&MF2_DONTDRAW))		{			continue;		// no underground wraiths		}		if ((mo->type == MT_SPLASHBASE) ||			(mo->type == MT_SPLASH))		{			continue;		}		if(mo->type == MT_SERPENT || mo->type == MT_SERPENTLEADER)		{			continue;		}		dist = P_AproxDistance(pmo->x - mo->x, pmo->y - mo->y);		if(dist > BLAST_RADIUS_DIST)		{ // Out of range			continue;		}		P_BlastMobj(pmo, mo, BLAST_FULLSTRENGTH);	}}#define HEAL_RADIUS_DIST	255*FRACUNIT// Do class specific effect for everyone in radiusboolean P_HealRadius(player_t *player){	mobj_t *mo;	mobj_t *pmo=player->mo;	thinker_t *think;	fixed_t dist;	int effective=false;	int amount;	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->player) continue;		if (mo->health <= 0) continue;		dist = P_AproxDistance(pmo->x - mo->x, pmo->y - mo->y);		if(dist > HEAL_RADIUS_DIST)		{ // Out of range			continue;		}		switch(player->class)		{			case PCLASS_FIGHTER:		// Radius armor boost				if ((P_GiveArmor(mo->player, ARMOR_ARMOR, 1)) ||					(P_GiveArmor(mo->player, ARMOR_SHIELD, 1)) ||					(P_GiveArmor(mo->player, ARMOR_HELMET, 1)) ||					(P_GiveArmor(mo->player, ARMOR_AMULET, 1)))				{					effective=true;					S_StartSound(mo, SFX_MYSTICINCANT);				}				break;			case PCLASS_CLERIC:			// Radius heal				amount = 50 + (P_Random()%50);				if (P_GiveBody(mo->player, amount))				{					effective=true;					S_StartSound(mo, SFX_MYSTICINCANT);				}				break;			case PCLASS_MAGE:			// Radius mana boost				amount = 50 + (P_Random()%50);				if ((P_GiveMana(mo->player, MANA_1, amount)) ||					(P_GiveMana(mo->player, MANA_2, amount)))				{					effective=true;					S_StartSound(mo, SFX_MYSTICINCANT);				}				break;			case PCLASS_PIG:			default:				break;		}	}	return(effective);}//----------------------------------------------------------------------------//// PROC P_PlayerNextArtifact////----------------------------------------------------------------------------void P_PlayerNextArtifact(player_t *player){	extern int inv_ptr;	extern int curpos;	if(player == &players[consoleplayer])	{		inv_ptr--;		if(inv_ptr < 6)		{			curpos--;			if(curpos < 0)			{				curpos = 0;			}		}		if(inv_ptr < 0)		{			inv_ptr = player->inventorySlotNum-1;			if(inv_ptr < 6)			{				curpos = inv_ptr;			}			else			{				curpos = 6;			}		}		player->readyArtifact =			player->inventory[inv_ptr].type;	}}//----------------------------------------------------------------------------//// PROC P_PlayerRemoveArtifact////----------------------------------------------------------------------------void P_PlayerRemoveArtifact(player_t *player, int slot){	int i;	extern int inv_ptr;	extern int curpos;	player->artifactCount--;	if(!(--player->inventory[slot].count))	{ // Used last of a type - compact the artifact list		player->readyArtifact = arti_none;		player->inventory[slot].type = arti_none;		for(i = slot+1; i < player->inventorySlotNum; i++)		{			player->inventory[i-1] = player->inventory[i];		}		player->inventorySlotNum--;		if(player == &players[consoleplayer])		{ // Set position markers and get next readyArtifact			inv_ptr--;			if(inv_ptr < 6)			{				curpos--;				if(curpos < 0)				{					curpos = 0;				}			}			if(inv_ptr >= player->inventorySlotNum)			{				inv_ptr = player->inventorySlotNum-1;			}			if(inv_ptr < 0)			{				inv_ptr = 0;			}			player->readyArtifact =				player->inventory[inv_ptr].type;		}	}}//----------------------------------------------------------------------------//// PROC P_PlayerUseArtifact////----------------------------------------------------------------------------void P_PlayerUseArtifact(player_t *player, artitype_t arti){	int i;	for(i = 0; i < player->inventorySlotNum; i++)	{		if(player->inventory[i].type == arti)		{ // Found match - try to use			if(P_UseArtifact(player, arti))			{ // Artifact was used - remove it from inventory				P_PlayerRemoveArtifact(player, i);				if(player == &players[consoleplayer])				{					if(arti < arti_firstpuzzitem)					{						S_StartSound(NULL, SFX_ARTIFACT_USE);					}					else					{						S_StartSound(NULL, SFX_PUZZLE_SUCCESS);					}					ArtifactFlash = 4;				}			}			else if(arti < arti_firstpuzzitem)			{ // Unable to use artifact, advance pointer				P_PlayerNextArtifact(player);			}			break;		}	}}//==========================================================================//// P_UseArtifact//// Returns true if the artifact was used.////==========================================================================boolean P_UseArtifact(player_t *player, artitype_t arti){	mobj_t *mo;	angle_t angle;	int i;	int count;	switch(arti)	{		case arti_invulnerability:			if(!P_GivePower(player, pw_invulnerability))			{				return(false);			}			break;		case arti_health:			if(!P_GiveBody(player, 25))			{				return(false);			}			break;		case arti_superhealth:			if(!P_GiveBody(player, 100))			{				return(false);			}			break;		case arti_healingradius:			if (!P_HealRadius(player))			{				return(false);			}			break;		case arti_torch:			if(!P_GivePower(player, pw_infrared))			{				return(false);			}			break;		case arti_egg:			mo = player->mo;			P_SpawnPlayerMissile(mo, MT_EGGFX);			P_SPMAngle(mo, MT_EGGFX, mo->angle-(ANG45/6));			P_SPMAngle(mo, MT_EGGFX, mo->angle+(ANG45/6));			P_SPMAngle(mo, MT_EGGFX, mo->angle-(ANG45/3));			P_SPMAngle(mo, MT_EGGFX, mo->angle+(ANG45/3));			break;		case arti_fly:			if(!P_GivePower(player, pw_flight))			{				return(false);			}			if(player->mo->momz <= -35*FRACUNIT)			{ // stop falling scream				S_StopSound(player->mo);			}			break;		case arti_summon:			mo = P_SpawnPlayerMissile(player->mo, MT_SUMMON_FX);			if (mo)			{				mo->target = player->mo;				mo->special1 = (int)(player->mo);				mo->momz = 5*FRACUNIT;			}			break;		case arti_teleport:			P_ArtiTele(player);			break;		case arti_teleportother:			P_ArtiTeleportOther(player);			break;		case arti_poisonbag:			angle = player->mo->angle>>ANGLETOFINESHIFT;			if(player->class == PCLASS_CLERIC)			{				mo = P_SpawnMobj(player->mo->x+16*finecosine[angle],					player->mo->y+24*finesine[angle], player->mo->z-					player->mo->floorclip+8*FRACUNIT, MT_POISONBAG);				if(mo)				{					mo->target = player->mo;				}			}			else if(player->class == PCLASS_MAGE)			{				mo = P_SpawnMobj(player->mo->x+16*finecosine[angle],					player->mo->y+24*finesine[angle], player->mo->z-					player->mo->floorclip+8*FRACUNIT, MT_FIREBOMB);				if(mo)				{					mo->target = player->mo;				}			}						else // PCLASS_FIGHTER, obviously (also pig, not so obviously)			{				mo = P_SpawnMobj(player->mo->x, player->mo->y, 					player->mo->z-player->mo->floorclip+35*FRACUNIT,					MT_THROWINGBOMB);				if(mo)				{					mo->angle = player->mo->angle+(((P_Random()&7)-4)<<24);					mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4));					mo->z += player->lookdir<<(FRACBITS-4);					P_ThrustMobj(mo, mo->angle, mo->info->speed);					mo->momx += player->mo->momx>>1;					mo->momy += player->mo->momy>>1;					mo->target = player->mo;					mo->tics -= P_Random()&3;					P_CheckMissileSpawn(mo);															} 			}			break;		case arti_speed:			if(!P_GivePower(player, pw_speed))			{				return(false);			}			break;		case arti_boostmana:			if(!P_GiveMana(player, MANA_1, MAX_MANA))			{				if(!P_GiveMana(player, MANA_2, MAX_MANA))				{					return false;				}							}			else 			{				P_GiveMana(player, MANA_2, MAX_MANA);			}			break;		case arti_boostarmor:			count = 0;			for(i = 0; i < NUMARMOR; i++)			{				count += P_GiveArmor(player, i, 1); // 1 point per armor type			}			if(!count)			{				return false;			}			break;		case arti_blastradius:			P_BlastRadius(player);			break;		case arti_puzzskull:		case arti_puzzgembig:		case arti_puzzgemred:		case arti_puzzgemgreen1:		case arti_puzzgemgreen2:		case arti_puzzgemblue1:		case arti_puzzgemblue2:		case arti_puzzbook1:		case arti_puzzbook2:		case arti_puzzskull2:		case arti_puzzfweapon:		case arti_puzzcweapon:		case arti_puzzmweapon:		case arti_puzzgear1:		case arti_puzzgear2:		case arti_puzzgear3:		case arti_puzzgear4:			if(P_UsePuzzleItem(player, arti-arti_firstpuzzitem))			{				return true;			}			else			{				P_SetYellowMessage(player, TXT_USEPUZZLEFAILED, false);				return false;			}			break;		default:			return false;	}	return true;}//============================================================================//// A_SpeedFade////============================================================================void A_SpeedFade(mobj_t *actor){	actor->flags |= MF_SHADOW;	actor->flags &= ~MF_ALTSHADOW;	actor->sprite = actor->target->sprite;}

⌨️ 快捷键说明

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