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

📄 p_mobj.c

📁 制作游戏 魔法师传奇 源代码设计 MOFASHICHUANQI 经典老游戏
💻 C
📖 第 1 页 / 共 4 页
字号:
//**************************************************************************//**//** p_mobj.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: p_mobj.c,v $//** $Revision: 1.133 $//** $Date: 96/01/12 12:31:43 $//** $Author: bgokey $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "p_local.h"#include "sounds.h"#include "soundst.h"// MACROS ------------------------------------------------------------------#define MAX_TID_COUNT 200// TYPES -------------------------------------------------------------------// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------void G_PlayerReborn(int player);void P_MarkAsLeaving(mobj_t *corpse);// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------void P_SpawnMapThing(mapthing_t *mthing);// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------static void PlayerLandedOnThing(mobj_t *mo, mobj_t *onmobj);// EXTERNAL DATA DECLARATIONS ----------------------------------------------extern mobj_t LavaInflictor;// PUBLIC DATA DEFINITIONS -------------------------------------------------mobjtype_t PuffType;mobj_t *MissileMobj;fixed_t FloatBobOffsets[64] ={	0, 51389, 102283, 152192,	200636, 247147, 291278, 332604,	370727, 405280, 435929, 462380,	484378, 501712, 514213, 521763,	524287, 521763, 514213, 501712,	484378, 462380, 435929, 405280,	370727, 332604, 291278, 247147,	200636, 152192, 102283, 51389,	-1, -51390, -102284, -152193,	-200637, -247148, -291279, -332605,	-370728, -405281, -435930, -462381,	-484380, -501713, -514215, -521764,	-524288, -521764, -514214, -501713,	-484379, -462381, -435930, -405280,	-370728, -332605, -291279, -247148,	-200637, -152193, -102284, -51389};// PRIVATE DATA DEFINITIONS ------------------------------------------------static int TIDList[MAX_TID_COUNT+1]; // +1 for termination markerstatic mobj_t *TIDMobj[MAX_TID_COUNT];// CODE --------------------------------------------------------------------//==========================================================================//// P_SetMobjState//// Returns true if the mobj is still present.////==========================================================================boolean P_SetMobjState(mobj_t *mobj, statenum_t state){	state_t *st;	if(state == S_NULL)	{ // Remove mobj		mobj->state = S_NULL;		P_RemoveMobj(mobj);		return(false);	}	st = &states[state];	mobj->state = st;	mobj->tics = st->tics;	mobj->sprite = st->sprite;	mobj->frame = st->frame;	if(st->action)	{ // Call action function		st->action(mobj);	}	return(true);}//==========================================================================//// P_SetMobjStateNF//// Same as P_SetMobjState, but does not call the state function.////==========================================================================boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state){	state_t *st;	if(state == S_NULL)	{ // Remove mobj		mobj->state = S_NULL;		P_RemoveMobj(mobj);		return(false);	}	st = &states[state];	mobj->state = st;	mobj->tics = st->tics;	mobj->sprite = st->sprite;	mobj->frame = st->frame;	return(true);}//----------------------------------------------------------------------------//// PROC P_ExplodeMissile////----------------------------------------------------------------------------void P_ExplodeMissile(mobj_t *mo){	mo->momx = mo->momy = mo->momz = 0;	P_SetMobjState(mo, mobjinfo[mo->type].deathstate);	//mo->tics -= P_Random()&3;	mo->flags &= ~MF_MISSILE;	switch(mo->type)	{		case MT_SORCBALL1:		case MT_SORCBALL2:		case MT_SORCBALL3:			S_StartSound(NULL, SFX_SORCERER_BIGBALLEXPLODE);			break;		case MT_SORCFX1:			S_StartSound(NULL, SFX_SORCERER_HEADSCREAM);			break;		default:			if(mo->info->deathsound)			{				S_StartSound(mo, mo->info->deathsound);			}			break;	}}//----------------------------------------------------------------------------//// PROC P_FloorBounceMissile////----------------------------------------------------------------------------void P_FloorBounceMissile(mobj_t *mo){	if(P_HitFloor(mo) >= FLOOR_LIQUID)	{		switch(mo->type)		{			case MT_SORCFX1:			case MT_SORCBALL1:			case MT_SORCBALL2:			case MT_SORCBALL3:				break;			default:				P_RemoveMobj(mo);				return;		}	}	switch(mo->type)	{		case MT_SORCFX1:			mo->momz = -mo->momz;		// no energy absorbed			break;		case MT_SGSHARD1:		case MT_SGSHARD2:		case MT_SGSHARD3:		case MT_SGSHARD4:		case MT_SGSHARD5:		case MT_SGSHARD6:		case MT_SGSHARD7:		case MT_SGSHARD8:		case MT_SGSHARD9:		case MT_SGSHARD0:			mo->momz = FixedMul(mo->momz, -0.3*FRACUNIT);			if(abs(mo->momz) < (FRACUNIT/2))			{				P_SetMobjState(mo, S_NULL);				return;			}			break;		default:			mo->momz = FixedMul(mo->momz, -0.7*FRACUNIT);			break;	}	mo->momx = 2*mo->momx/3;	mo->momy = 2*mo->momy/3;	if(mo->info->seesound)	{		switch(mo->type)		{			case MT_SORCBALL1:			case MT_SORCBALL2:			case MT_SORCBALL3:				if (!mo->args[0]) S_StartSound(mo, mo->info->seesound);				break;			default:				S_StartSound(mo, mo->info->seesound);				break;		}		S_StartSound(mo, mo->info->seesound);	}//	P_SetMobjState(mo, mobjinfo[mo->type].deathstate);}//----------------------------------------------------------------------------//// PROC P_ThrustMobj////----------------------------------------------------------------------------void P_ThrustMobj(mobj_t *mo, angle_t angle, fixed_t move){	angle >>= ANGLETOFINESHIFT;	mo->momx += FixedMul(move, finecosine[angle]);	mo->momy += FixedMul(move, finesine[angle]);}//----------------------------------------------------------------------------//// FUNC P_FaceMobj//// Returns 1 if 'source' needs to turn clockwise, or 0 if 'source' needs// to turn counter clockwise.  'delta' is set to the amount 'source'// needs to turn.////----------------------------------------------------------------------------int P_FaceMobj(mobj_t *source, mobj_t *target, angle_t *delta){	angle_t diff;	angle_t angle1;	angle_t angle2;	angle1 = source->angle;	angle2 = R_PointToAngle2(source->x, source->y, target->x, target->y);	if(angle2 > angle1)	{		diff = angle2-angle1;		if(diff > ANGLE_180)		{			*delta = ANGLE_MAX-diff;			return(0);		}		else		{			*delta = diff;			return(1);		}	}	else	{		diff = angle1-angle2;		if(diff > ANGLE_180)		{			*delta = ANGLE_MAX-diff;			return(1);		}		else		{			*delta = diff;			return(0);		}	}}//----------------------------------------------------------------------------////// The missile special1 field must be mobj_t *target.  Returns true if// target was tracked, false if not.////----------------------------------------------------------------------------boolean P_SeekerMissile(mobj_t *actor, angle_t thresh, angle_t turnMax){	int dir;	int dist;	angle_t delta;	angle_t angle;	mobj_t *target;	target = (mobj_t *)actor->special1;	if(target == NULL)	{		return(false);	}	if(!(target->flags&MF_SHOOTABLE))	{ // Target died		actor->special1 = 0;		return(false);	}	dir = P_FaceMobj(actor, target, &delta);	if(delta > thresh)	{		delta >>= 1;		if(delta > turnMax)		{			delta = turnMax;		}	}	if(dir)	{ // Turn clockwise		actor->angle += delta;	}	else	{ // Turn counter clockwise		actor->angle -= delta;	}	angle = actor->angle>>ANGLETOFINESHIFT;	actor->momx = FixedMul(actor->info->speed, finecosine[angle]);	actor->momy = FixedMul(actor->info->speed, finesine[angle]);	if(actor->z+actor->height < target->z 		|| target->z+target->height < actor->z)	{ // Need to seek vertically		dist = P_AproxDistance(target->x-actor->x, target->y-actor->y);		dist = dist/actor->info->speed;		if(dist < 1)		{			dist = 1;		}		actor->momz = (target->z+(target->height>>1)			-(actor->z+(actor->height>>1)))/dist;	}	return(true);}//----------------------------------------------------------------------------//// PROC P_XYMovement////----------------------------------------------------------------------------#define STOPSPEED			0x1000#define FRICTION_NORMAL		0xe800#define FRICTION_LOW		0xf900#define FRICTION_FLY		0xeb00void P_XYMovement(mobj_t *mo){	fixed_t ptryx, ptryy;	player_t *player;	fixed_t xmove, ymove;	int special;	angle_t angle;	static int windTab[3] = {2048*5, 2048*10, 2048*25};	if(!mo->momx && !mo->momy)	{		if(mo->flags&MF_SKULLFLY)		{ // A flying mobj slammed into something			mo->flags &= ~MF_SKULLFLY;			mo->momx = mo->momy = mo->momz = 0;			P_SetMobjState(mo, mo->info->seestate);		}		return;	}	special = mo->subsector->sector->special;	if(mo->flags2&MF2_WINDTHRUST)	{		switch(special)		{			case 40: case 41: case 42: // Wind_East				P_ThrustMobj(mo, 0, windTab[special-40]);				break;			case 43: case 44: case 45: // Wind_North				P_ThrustMobj(mo, ANG90, windTab[special-43]);				break;			case 46: case 47: case 48: // Wind_South				P_ThrustMobj(mo, ANG270, windTab[special-46]);				break;			case 49: case 50: case 51: // Wind_West				P_ThrustMobj(mo, ANG180, windTab[special-49]);				break;		}	}	player = mo->player;	if(mo->momx > MAXMOVE)	{		mo->momx = MAXMOVE;	}	else if(mo->momx < -MAXMOVE)	{		mo->momx = -MAXMOVE;	}	if(mo->momy > MAXMOVE)	{		mo->momy = MAXMOVE;	}	else if(mo->momy < -MAXMOVE)	{		mo->momy = -MAXMOVE;	}	xmove = mo->momx;	ymove = mo->momy;	do	{		if(xmove > MAXMOVE/2 || ymove > MAXMOVE/2)		{			ptryx = mo->x+xmove/2;			ptryy = mo->y+ymove/2;			xmove >>= 1;			ymove >>= 1;		}		else		{			ptryx = mo->x + xmove;			ptryy = mo->y + ymove;			xmove = ymove = 0;		}		if(!P_TryMove(mo, ptryx, ptryy))		{ // Blocked move			if(mo->flags2&MF2_SLIDE)			{ // Try to slide along it				if(BlockingMobj == NULL)				{ // Slide against wall					P_SlideMove(mo);				}				else				{ // Slide against mobj					//if(P_TryMove(mo, mo->x, mo->y+mo->momy))					if(P_TryMove(mo, mo->x, ptryy))					{						mo->momx = 0;					}					//else if(P_TryMove(mo, mo->x+mo->momx, mo->y))					else if(P_TryMove(mo, ptryx, mo->y))					{						mo->momy = 0;					}					else					{						mo->momx = mo->momy = 0;					}				}			}			else if(mo->flags&MF_MISSILE)			{ 				if(mo->flags2&MF2_FLOORBOUNCE)				{					if(BlockingMobj)					{						if ((BlockingMobj->flags2&MF2_REFLECTIVE) ||							((!BlockingMobj->player) &&							(!(BlockingMobj->flags&MF_COUNTKILL))))						{							fixed_t speed;								angle = R_PointToAngle2(BlockingMobj->x,								BlockingMobj->y, mo->x, mo->y)								+ANGLE_1*((P_Random()%16)-8);							speed = P_AproxDistance(mo->momx, mo->momy);							speed = FixedMul(speed, 0.75*FRACUNIT);							mo->angle = angle;							angle >>= ANGLETOFINESHIFT;							mo->momx = FixedMul(speed, finecosine[angle]);							mo->momy = FixedMul(speed, finesine[angle]);							if(mo->info->seesound)							{								S_StartSound(mo, mo->info->seesound);							}							return;						}						else						{ // Struck a player/creature 							P_ExplodeMissile(mo);						}					}					else					{ // Struck a wall						P_BounceWall(mo);						switch(mo->type)						{							case MT_SORCBALL1:							case MT_SORCBALL2:							case MT_SORCBALL3:							case MT_SORCFX1:								break;							default:								if(mo->info->seesound)								{									S_StartSound(mo, mo->info->seesound);								}								break;						}						return;					}					}				if(BlockingMobj &&					(BlockingMobj->flags2 & MF2_REFLECTIVE))				{					angle = R_PointToAngle2(BlockingMobj->x,													BlockingMobj->y,													mo->x, mo->y);					// Change angle for delflection/reflection					switch(BlockingMobj->type)					{						case MT_CENTAUR:						case MT_CENTAURLEADER:							if ( abs(angle-BlockingMobj->angle)>>24 > 45)								goto explode;							if (mo->type == MT_HOLY_FX)								goto explode;								// Drop through to sorcerer full reflection						case MT_SORCBOSS:							// Deflection							if (P_Random()<128)								angle += ANGLE_45;							else								angle -= ANGLE_45;							break;						default:							// Reflection							angle += ANGLE_1 * ((P_Random()%16)-8);							break;					}					// Reflect the missile along angle					mo->angle = angle;					angle >>= ANGLETOFINESHIFT;					mo->momx = FixedMul(mo->info->speed>>1, finecosine[angle]);					mo->momy = FixedMul(mo->info->speed>>1, finesine[angle]);//					mo->momz = -mo->momz;					if (mo->flags2 & MF2_SEEKERMISSILE)					{						mo->special1 = (int)(mo->target);					}					mo->target = BlockingMobj;					return;				}explode:				// Explode a missile				if(ceilingline && ceilingline->backsector					&& ceilingline->backsector->ceilingpic == skyflatnum)				{ // Hack to prevent missiles exploding against the sky					if(mo->type == MT_BLOODYSKULL)					{						mo->momx = mo->momy = 0;						mo->momz = -FRACUNIT;					}					else if(mo->type == MT_HOLY_FX)					{						P_ExplodeMissile(mo);					}					else					{						P_RemoveMobj(mo);					}					return;				}				P_ExplodeMissile(mo);			}			//else if(mo->info->crashstate)			//{			//	mo->momx = mo->momy = 0;			//	P_SetMobjState(mo, mo->info->crashstate);			//	return;			//}			else			{				mo->momx = mo->momy = 0;			}		}	} while(xmove || ymove);	// Friction	if(player && player->cheats&CF_NOMOMENTUM)	{ // Debug option for no sliding at all		mo->momx = mo->momy = 0;		return;	}	if(mo->flags&(MF_MISSILE|MF_SKULLFLY))	{ // No friction for missiles		return;	}	if(mo->z > mo->floorz && !(mo->flags2&MF2_FLY) && !(mo->flags2&MF2_ONMOBJ))	{ // No friction when falling		if (mo->type != MT_BLASTEFFECT)		return;	}	if(mo->flags&MF_CORPSE)	{ // Don't stop sliding if halfway off a step with some momentum		if(mo->momx > FRACUNIT/4 || mo->momx < -FRACUNIT/4			|| mo->momy > FRACUNIT/4 || mo->momy < -FRACUNIT/4)

⌨️ 快捷键说明

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