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

📄 po_man.c

📁 魔法师传奇源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//**************************************************************************//**//** PO_MAN.C : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: po_man.c,v $//** $Revision: 1.22 $//** $Date: 95/09/28 18:20:56 $//** $Author: cjr $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "p_local.h"#include "r_local.h"// MACROS ------------------------------------------------------------------#define PO_MAXPOLYSEGS 64// TYPES -------------------------------------------------------------------// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------boolean PO_MovePolyobj(int num, int x, int y);boolean PO_RotatePolyobj(int num, angle_t angle);void PO_Init(int lump);// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------static polyobj_t *GetPolyobj(int polyNum);static int GetPolyobjMirror(int poly);static void ThrustMobj(mobj_t *mobj, seg_t *seg, polyobj_t *po);static void UpdateSegBBox(seg_t *seg);static void RotatePt(int an, fixed_t *x, fixed_t *y, fixed_t startSpotX,	fixed_t startSpotY);static void UnLinkPolyobj(polyobj_t *po);static void LinkPolyobj(polyobj_t *po);static boolean CheckMobjBlocking(seg_t *seg, polyobj_t *po);static void InitBlockMap(void);static void IterFindPolySegs(int x, int y, seg_t **segList);static void SpawnPolyobj(int index, int tag, boolean crush);static void TranslateToStartSpot(int tag, int originX, int originY);// EXTERNAL DATA DECLARATIONS ----------------------------------------------extern seg_t *segs;// PUBLIC DATA DEFINITIONS -------------------------------------------------polyblock_t **PolyBlockMap;polyobj_t *polyobjs; // list of all poly-objects on the levelint po_NumPolyobjs;// PRIVATE DATA DEFINITIONS ------------------------------------------------static int PolySegCount;static fixed_t PolyStartX;static fixed_t PolyStartY;// CODE --------------------------------------------------------------------// ===== Polyobj Event Code =====//==========================================================================//// T_RotatePoly////==========================================================================void T_RotatePoly(polyevent_t *pe){	int absSpeed;	polyobj_t *poly;	if(PO_RotatePolyobj(pe->polyobj, pe->speed))	{		absSpeed = abs(pe->speed);		if(pe->dist == -1)		{ // perpetual polyobj			return;		}		pe->dist -= absSpeed;		if(pe->dist <= 0)		{			poly = GetPolyobj(pe->polyobj);			if(poly->specialdata == pe)			{				poly->specialdata = NULL;			}			SN_StopSequence((mobj_t *)&poly->startSpot);			P_PolyobjFinished(poly->tag);			P_RemoveThinker(&pe->thinker);		}		if(pe->dist < absSpeed)		{			pe->speed = pe->dist*(pe->speed < 0 ? -1 : 1);		}	}}//==========================================================================//// EV_RotatePoly////==========================================================================boolean EV_RotatePoly(line_t *line, byte *args, int direction, boolean 	overRide){	int mirror;	int polyNum;	polyevent_t *pe;	polyobj_t *poly;	polyNum = args[0];	if(poly = GetPolyobj(polyNum))	{		if(poly->specialdata && !overRide)		{ // poly is already moving			return false;		}	}	else	{		I_Error("EV_RotatePoly:  Invalid polyobj num: %d\n", polyNum);	}	pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0);	P_AddThinker(&pe->thinker);	pe->thinker.function = T_RotatePoly;	pe->polyobj = polyNum;	if(args[2])	{		if(args[2] == 255)		{			pe->dist = -1;		}		else		{			pe->dist = args[2]*(ANGLE_90/64); // Angle		}	}	else	{		pe->dist = ANGLE_MAX-1;	}	pe->speed = (args[1]*direction*(ANGLE_90/64))>>3;	poly->specialdata = pe;	SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+		poly->seqType);		while(mirror = GetPolyobjMirror(polyNum))	{		poly = GetPolyobj(mirror);		if(poly && poly->specialdata && !overRide)		{ // mirroring poly is already in motion			break;		}		pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0);		P_AddThinker(&pe->thinker);		pe->thinker.function = T_RotatePoly;		poly->specialdata = pe;		pe->polyobj = mirror;		if(args[2])		{			if(args[2] == 255)			{				pe->dist = -1;			}			else			{				pe->dist = args[2]*(ANGLE_90/64); // Angle			}		}		else		{			pe->dist = ANGLE_MAX-1;		}		if(poly = GetPolyobj(polyNum))		{			poly->specialdata = pe;		}		else		{			I_Error("EV_RotatePoly:  Invalid polyobj num: %d\n", polyNum);		}		direction = -direction;		pe->speed = (args[1]*direction*(ANGLE_90/64))>>3;		polyNum = mirror;		SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+			poly->seqType);	}	return true;}//==========================================================================//// T_MovePoly////==========================================================================void T_MovePoly(polyevent_t *pe){	int absSpeed;	polyobj_t *poly;	if(PO_MovePolyobj(pe->polyobj, pe->xSpeed, pe->ySpeed))	{		absSpeed = abs(pe->speed);		pe->dist -= absSpeed;		if(pe->dist <= 0)		{			poly = GetPolyobj(pe->polyobj);			if(poly->specialdata == pe)			{				poly->specialdata = NULL;			}			SN_StopSequence((mobj_t *)&poly->startSpot);			P_PolyobjFinished(poly->tag);			P_RemoveThinker(&pe->thinker);		}		if(pe->dist < absSpeed)		{			pe->speed = pe->dist*(pe->speed < 0 ? -1 : 1);			pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]);			pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]);		}	}}//==========================================================================//// EV_MovePoly////==========================================================================boolean EV_MovePoly(line_t *line, byte *args, boolean timesEight, boolean 	overRide){	int mirror;	int polyNum;	polyevent_t *pe;	polyobj_t *poly;	angle_t an;	polyNum = args[0];	if(poly = GetPolyobj(polyNum))	{		if(poly->specialdata && !overRide)		{ // poly is already moving			return false;		}	}	else	{		I_Error("EV_MovePoly:  Invalid polyobj num: %d\n", polyNum);	}	pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0);	P_AddThinker(&pe->thinker);	pe->thinker.function = T_MovePoly;	pe->polyobj = polyNum;	if(timesEight)	{		pe->dist = args[3]*8*FRACUNIT;	}	else	{		pe->dist = args[3]*FRACUNIT; // Distance	}	pe->speed = args[1]*(FRACUNIT/8);	poly->specialdata = pe;	an = args[2]*(ANGLE_90/64);	pe->angle = an>>ANGLETOFINESHIFT;	pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]);	pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]);	SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+		poly->seqType);	while(mirror = GetPolyobjMirror(polyNum))	{		poly = GetPolyobj(mirror);		if(poly && poly->specialdata && !overRide)		{ // mirroring poly is already in motion			break;		}		pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0);		P_AddThinker(&pe->thinker);		pe->thinker.function = T_MovePoly;		pe->polyobj = mirror;		poly->specialdata = pe;		if(timesEight)		{			pe->dist = args[3]*8*FRACUNIT;		}		else		{			pe->dist = args[3]*FRACUNIT; // Distance		}		pe->speed = args[1]*(FRACUNIT/8);		an = an+ANGLE_180; // reverse the angle		pe->angle = an>>ANGLETOFINESHIFT;		pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]);		pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]);		polyNum = mirror;		SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+			poly->seqType);	}	return true;}//==========================================================================//// T_PolyDoor////==========================================================================void T_PolyDoor(polydoor_t *pd){	int absSpeed;	polyobj_t *poly;	if(pd->tics)	{		if(!--pd->tics)		{			poly = GetPolyobj(pd->polyobj);			SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+				poly->seqType);		}		return;	}	switch(pd->type)	{		case PODOOR_SLIDE:			if(PO_MovePolyobj(pd->polyobj, pd->xSpeed, pd->ySpeed))			{				absSpeed = abs(pd->speed);				pd->dist -= absSpeed;				if(pd->dist <= 0)				{					poly = GetPolyobj(pd->polyobj);					SN_StopSequence((mobj_t *)&poly->startSpot);					if(!pd->close)					{						pd->dist = pd->totalDist;						pd->close = true;						pd->tics = pd->waitTics;						pd->direction = (ANGLE_MAX>>ANGLETOFINESHIFT)-							pd->direction;						pd->xSpeed = -pd->xSpeed;						pd->ySpeed = -pd->ySpeed;										}					else					{						if(poly->specialdata == pd)						{							poly->specialdata = NULL;						}						P_PolyobjFinished(poly->tag);						P_RemoveThinker(&pd->thinker);					}				}			}			else			{				poly = GetPolyobj(pd->polyobj);				if(poly->crush || !pd->close)				{ // continue moving if the poly is a crusher, or is opening					return;				}				else				{ // open back up					pd->dist = pd->totalDist-pd->dist;					pd->direction = (ANGLE_MAX>>ANGLETOFINESHIFT)-						pd->direction;					pd->xSpeed = -pd->xSpeed;					pd->ySpeed = -pd->ySpeed;					pd->close = false;					SN_StartSequence((mobj_t *)&poly->startSpot,						SEQ_DOOR_STONE+poly->seqType);				}			}			break;		case PODOOR_SWING:			if(PO_RotatePolyobj(pd->polyobj, pd->speed))			{				absSpeed = abs(pd->speed);				if(pd->dist == -1)				{ // perpetual polyobj					return;				}				pd->dist -= absSpeed;				if(pd->dist <= 0)				{					poly = GetPolyobj(pd->polyobj);					SN_StopSequence((mobj_t *)&poly->startSpot);					if(!pd->close)					{						pd->dist = pd->totalDist;						pd->close = true;						pd->tics = pd->waitTics;						pd->speed = -pd->speed;					}					else					{						if(poly->specialdata == pd)						{							poly->specialdata = NULL;						}						P_PolyobjFinished(poly->tag);						P_RemoveThinker(&pd->thinker);					}				}			}			else			{				poly = GetPolyobj(pd->polyobj);				if(poly->crush || !pd->close)				{ // continue moving if the poly is a crusher, or is opening					return;				}				else				{ // open back up and rewait					pd->dist = pd->totalDist-pd->dist;					pd->speed = -pd->speed;					pd->close = false;					SN_StartSequence((mobj_t *)&poly->startSpot,						SEQ_DOOR_STONE+poly->seqType);				}			}						break;		default:			break;	}}//==========================================================================//// EV_OpenPolyDoor////==========================================================================boolean EV_OpenPolyDoor(line_t *line, byte *args, podoortype_t type){	int mirror;	int polyNum;	polydoor_t *pd;	polyobj_t *poly;	angle_t an;	polyNum = args[0];	if(poly = GetPolyobj(polyNum))	{		if(poly->specialdata)		{ // poly is already moving			return false;		}	}	else	{		I_Error("EV_OpenPolyDoor:  Invalid polyobj num: %d\n", polyNum);	}	pd = Z_Malloc(sizeof(polydoor_t), PU_LEVSPEC, 0);	memset(pd, 0, sizeof(polydoor_t));	P_AddThinker(&pd->thinker);	pd->thinker.function = T_PolyDoor;	pd->type = type;	pd->polyobj = polyNum;	if(type == PODOOR_SLIDE)	{		pd->waitTics = args[4];		pd->speed = args[1]*(FRACUNIT/8);		pd->totalDist = args[3]*FRACUNIT; // Distance		pd->dist = pd->totalDist;		an = args[2]*(ANGLE_90/64);		pd->direction = an>>ANGLETOFINESHIFT;		pd->xSpeed = FixedMul(pd->speed, finecosine[pd->direction]);		pd->ySpeed = FixedMul(pd->speed, finesine[pd->direction]);		SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+			poly->seqType);	}	else if(type == PODOOR_SWING)	{		pd->waitTics = args[3];		pd->direction = 1; // ADD:  PODOOR_SWINGL, PODOOR_SWINGR		pd->speed = (args[1]*pd->direction*(ANGLE_90/64))>>3;		pd->totalDist = args[2]*(ANGLE_90/64);		pd->dist = pd->totalDist;		SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+			poly->seqType);

⌨️ 快捷键说明

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