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

📄 p_inter.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
		{			superSlot = i;			superCount = player->inventory[i].count;		}	}	if((gameskill == sk_baby) && (normalCount*25 >= saveHealth))	{ // Use quartz flasks		count = (saveHealth+24)/25;		for(i = 0; i < count; i++)		{			player->health += 25;			P_PlayerRemoveArtifact(player, normalSlot);		}	}	else if(superCount*100 >= saveHealth)	{ // Use mystic urns		count = (saveHealth+99)/100;		for(i = 0; i < count; i++)		{			player->health += 100;			P_PlayerRemoveArtifact(player, superSlot);		}	}	else if((gameskill == sk_baby)		&& (superCount*100+normalCount*25 >= saveHealth))	{ // Use mystic urns and quartz flasks		count = (saveHealth+24)/25;		saveHealth -= count*25;		for(i = 0; i < count; i++)		{			player->health += 25;			P_PlayerRemoveArtifact(player, normalSlot);		}		count = (saveHealth+99)/100;		for(i = 0; i < count; i++)		{			player->health += 100;			P_PlayerRemoveArtifact(player, normalSlot);		}	}	player->mo->health = player->health;}/*=================== P_DamageMobj== Damages both enemies and players= inflictor is the thing that caused the damage= 		creature or missile, can be NULL (slime, etc)= source is the thing to target after taking damage=		creature or NULL= Source and inflictor are the same for melee attacks= source can be null for barrel explosions and other environmental stuff==================*/void P_DamageMobj(	mobj_t *target,	mobj_t *inflictor,	mobj_t *source,	int	damage){	unsigned ang;	int saved;	fixed_t savedPercent;	player_t *player;	mobj_t *master;	fixed_t thrust;	int temp;	int i;	if(!(target->flags&MF_SHOOTABLE))	{		// Shouldn't happen		return;	}	if(target->health <= 0)	{		if (inflictor && inflictor->flags2&MF2_ICEDAMAGE)		{			return;		}		else if (target->flags&MF_ICECORPSE) // frozen		{			target->tics = 1;			target->momx = target->momy = 0;		}		return;	}	if ((target->flags2&MF2_INVULNERABLE) && damage < 10000)	{ // mobj is invulnerable		if(target->player) return;	// for player, no exceptions		if(inflictor)		{			switch(inflictor->type)			{				// These inflictors aren't foiled by invulnerability				case MT_HOLY_FX:				case MT_POISONCLOUD:				case MT_FIREBOMB:					break;				default:					return;			}		}		else		{			return;		}	}	if(target->player)	{		if(damage < 1000 && ((target->player->cheats&CF_GODMODE)			|| target->player->powers[pw_invulnerability]))		{			return;		}	}	if(target->flags&MF_SKULLFLY)	{		target->momx = target->momy = target->momz = 0;	}	if(target->flags2&MF2_DORMANT)	{		// Invulnerable, and won't wake up		return;	}	player = target->player;	if(player && gameskill == sk_baby)	{		// Take half damage in trainer mode		damage >>= 1;	}	// Special damage types	if(inflictor)	{		switch(inflictor->type)		{			case MT_EGGFX:				if(player)				{					P_MorphPlayer(player);				}				else				{					P_MorphMonster(target);				}				return; // Always return			case MT_TELOTHER_FX1:			case MT_TELOTHER_FX2:			case MT_TELOTHER_FX3:			case MT_TELOTHER_FX4:			case MT_TELOTHER_FX5:				if ((target->flags&MF_COUNTKILL) &&					(target->type != MT_SERPENT) &&					(target->type != MT_SERPENTLEADER) &&					(!(target->flags2 & MF2_BOSS)))				{					P_TeleportOther(target);				}				return;			case MT_MINOTAUR:				if(inflictor->flags&MF_SKULLFLY)				{ // Slam only when in charge mode					P_MinotaurSlam(inflictor, target);					return;				}				break;			case MT_BISH_FX:				// Bishops are just too nasty				damage >>= 1;				break;			case MT_SHARDFX1:				switch(inflictor->special2)				{					case 3:						damage <<= 3;						break;					case 2:						damage <<= 2;						break;					case 1:						damage <<= 1;						break;					default:						break;				}				break;			case MT_CSTAFF_MISSILE:				// Cleric Serpent Staff does poison damage				if(target->player)				{					P_PoisonPlayer(target->player, source, 20);					damage >>= 1;				}				break;			case MT_ICEGUY_FX2:				damage >>= 1;				break;			case MT_POISONDART:				if(target->player)				{					P_PoisonPlayer(target->player, source, 20);					damage >>= 1;				}				break;			case MT_POISONCLOUD:				if(target->player)				{					if(target->player->poisoncount < 4)					{						P_PoisonDamage(target->player, source,							15+(P_Random()&15), false); // Don't play painsound						P_PoisonPlayer(target->player, source, 50);						S_StartSound(target, SFX_PLAYER_POISONCOUGH);					}						return;				}				else if(!(target->flags&MF_COUNTKILL))				{ // only damage monsters/players with the poison cloud					return;				}				break;			case MT_FSWORD_MISSILE:				if(target->player)				{					damage -= damage>>2;				}				break;			default:				break;		}	}	// Push the target unless source is using the gauntlets	if(inflictor && (!source || !source->player)		&& !(inflictor->flags2&MF2_NODMGTHRUST))	{		ang = R_PointToAngle2(inflictor->x, inflictor->y,			target->x, target->y);		//thrust = damage*(FRACUNIT>>3)*100/target->info->mass;		thrust = damage*(FRACUNIT>>3)*150/target->info->mass;		// make fall forwards sometimes		if((damage < 40) && (damage > target->health)			&& (target->z-inflictor->z > 64*FRACUNIT) && (P_Random()&1))		{			ang += ANG180;			thrust *= 4;		}		ang >>= ANGLETOFINESHIFT;		target->momx += FixedMul(thrust, finecosine[ang]);		target->momy += FixedMul(thrust, finesine[ang]);	}	//	// player specific	//	if(player)	{		savedPercent = AutoArmorSave[player->class]			+player->armorpoints[ARMOR_ARMOR]+player->armorpoints[ARMOR_SHIELD]			+player->armorpoints[ARMOR_HELMET]			+player->armorpoints[ARMOR_AMULET];		if(savedPercent)		{ // armor absorbed some damage			if(savedPercent > 100*FRACUNIT)			{				savedPercent = 100*FRACUNIT;			}			for(i = 0; i < NUMARMOR; i++)			{				if(player->armorpoints[i])				{					player->armorpoints[i] -= 						FixedDiv(FixedMul(damage<<FRACBITS,						ArmorIncrement[player->class][i]), 300*FRACUNIT);					if(player->armorpoints[i] < 2*FRACUNIT)					{						player->armorpoints[i] = 0;					}				}			}			saved = FixedDiv(FixedMul(damage<<FRACBITS, savedPercent),				100*FRACUNIT);			if(saved > savedPercent*2)			{					saved = savedPercent*2;			}			damage -= saved>>FRACBITS;		}		if(damage >= player->health			&& ((gameskill == sk_baby) || deathmatch)			&& !player->morphTics)		{ // Try to use some inventory health			P_AutoUseHealth(player, damage-player->health+1);		}		player->health -= damage; // mirror mobj health here for Dave		if(player->health < 0)		{			player->health = 0;		}		player->attacker = source;		player->damagecount += damage; // add damage after armor / invuln		if(player->damagecount > 100)		{			player->damagecount = 100; // teleport stomp does 10k points...		}		temp = damage < 100 ? damage : 100;		if(player == &players[consoleplayer])		{			I_Tactile(40, 10, 40+temp*2);			SB_PaletteFlash(false);		}	}	//	// do the damage	//	target->health -= damage;	if(target->health <= 0)	{ // Death		if(inflictor)		{ // check for special fire damage or ice damage deaths			if(inflictor->flags2&MF2_FIREDAMAGE)			{				if(player && !player->morphTics)				{ // Check for flame death					if(target->health > -50 && damage > 25)					{						target->flags2 |= MF2_FIREDAMAGE;					}				}				else				{					target->flags2 |= MF2_FIREDAMAGE;				}			}			else if(inflictor->flags2&MF2_ICEDAMAGE)			{				target->flags2 |= MF2_ICEDAMAGE;			}		}		if(source && (source->type == MT_MINOTAUR))		{ // Minotaur's kills go to his master			master = (mobj_t *)(source->special1);			// Make sure still alive and not a pointer to fighter head			if (master->player && (master->player->mo == master))			{				source = master;			}		}		if(source && (source->player) &&			(source->player->readyweapon == WP_FOURTH))		{			// Always extreme death from fourth weapon			target->health = -5000;		}		P_KillMobj(source, target);		return;	}	if((P_Random() < target->info->painchance)		&& !(target->flags&MF_SKULLFLY))	{		if(inflictor && (inflictor->type >= MT_LIGHTNING_FLOOR			&& inflictor->type <= MT_LIGHTNING_ZAP))		{			if(P_Random() < 96)			{				target->flags |= MF_JUSTHIT; // fight back!				P_SetMobjState(target, target->info->painstate);			}			else			{ // "electrocute" the target				target->frame |= FF_FULLBRIGHT;				if(target->flags&MF_COUNTKILL && P_Random() < 128				&& !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT))				{					if ((target->type == MT_CENTAUR) ||						(target->type == MT_CENTAURLEADER) ||						(target->type == MT_ETTIN))					{						S_StartSound(target, SFX_PUPPYBEAT);					}				}			}		}		else		{			target->flags |= MF_JUSTHIT; // fight back!			P_SetMobjState(target, target->info->painstate);				if(inflictor && inflictor->type == MT_POISONCLOUD)			{				if(target->flags&MF_COUNTKILL && P_Random() < 128				&& !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT))				{					if ((target->type == MT_CENTAUR) ||						(target->type == MT_CENTAURLEADER) ||						(target->type == MT_ETTIN))					{						S_StartSound(target, SFX_PUPPYBEAT);					}				}			}		}	}	target->reactiontime = 0; // we're awake now...	if(!target->threshold && source && !(source->flags2&MF2_BOSS)		&& !(target->type == MT_BISHOP) && !(target->type == MT_MINOTAUR))	{		// Target actor is not intent on another actor,		// so make him chase after source		if((target->type == MT_CENTAUR && source->type == MT_CENTAURLEADER)			|| (target->type == MT_CENTAURLEADER 				&& source->type == MT_CENTAUR))		{			return;		}		target->target = source;		target->threshold = BASETHRESHOLD;		if(target->state == &states[target->info->spawnstate]			&& target->info->seestate != S_NULL)		{			P_SetMobjState(target, target->info->seestate);		}	}}//==========================================================================//// P_FallingDamage////==========================================================================void P_FallingDamage(player_t *player){	int damage;	int mom;	int dist;	mom = abs(player->mo->momz);		dist = FixedMul(mom, 16*FRACUNIT/23);	if(mom >= 63*FRACUNIT)	{ // automatic death		P_DamageMobj(player->mo, NULL, NULL, 10000);		return;	}	damage = ((FixedMul(dist, dist)/10)>>FRACBITS)-24;	if(player->mo->momz > -39*FRACUNIT && damage > player->mo->health		&& player->mo->health != 1)	{ // No-death threshold		damage = player->mo->health-1;	}	S_StartSound(player->mo, SFX_PLAYER_LAND);	P_DamageMobj(player->mo, NULL, NULL, damage);}//==========================================================================//// P_PoisonPlayer - Sets up all data concerning poisoning////==========================================================================void P_PoisonPlayer(player_t *player, mobj_t *poisoner, int poison){	if((player->cheats&CF_GODMODE) || player->powers[pw_invulnerability])	{		return;	}	player->poisoncount += poison;	player->poisoner = poisoner;	if(player->poisoncount > 100)	{		player->poisoncount = 100;	}}//==========================================================================//// P_PoisonDamage - Similar to P_DamageMobj////==========================================================================void P_PoisonDamage(player_t *player, mobj_t *source, int damage,	boolean playPainSound){	mobj_t *target;	mobj_t *inflictor;	target = player->mo;	inflictor = source;	if(target->health <= 0)	{		return;	}	if(target->flags2&MF2_INVULNERABLE && damage < 10000)	{ // mobj is invulnerable		return;	}	if(player && gameskill == sk_baby)	{		// Take half damage in trainer mode		damage >>= 1;	}	if(damage < 1000 && ((player->cheats&CF_GODMODE)		|| player->powers[pw_invulnerability]))	{		return;	}	if(damage >= player->health		&& ((gameskill == sk_baby) || deathmatch)		&& !player->morphTics)	{ // Try to use some inventory health		P_AutoUseHealth(player, damage-player->health+1);	}	player->health -= damage; // mirror mobj health here for Dave	if(player->health < 0)	{		player->health = 0;	}	player->attacker = source;	//	// do the damage	//	target->health -= damage;	if(target->health <= 0)	{ // Death		target->special1 = damage;		if(player && inflictor && !player->morphTics)		{ // Check for flame death			if((inflictor->flags2&MF2_FIREDAMAGE)				&& (target->health > -50) && (damage > 25))			{				target->flags2 |= MF2_FIREDAMAGE;			}			if(inflictor->flags2&MF2_ICEDAMAGE)			{				target->flags2 |= MF2_ICEDAMAGE;			}		}		P_KillMobj(source, target);		return;	}	if(!(leveltime&63) && playPainSound)	{		P_SetMobjState(target, target->info->painstate);	}/*	if((P_Random() < target->info->painchance)		&& !(target->flags&MF_SKULLFLY))	{		target->flags |= MF_JUSTHIT; // fight back!		P_SetMobjState(target, target->info->painstate);	}*/}

⌨️ 快捷键说明

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