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

📄 p_maputl.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
	if ( trace.dx > FRACUNIT*16 || trace.dy > FRACUNIT*16	|| trace.dx < -FRACUNIT*16 || trace.dy < -FRACUNIT*16)	{		s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);		s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);	}	else	{		s1 = P_PointOnLineSide (trace.x, trace.y, ld);		s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld);	}	if (s1 == s2)		return true;            // line isn't crossed//// hit the line//	P_MakeDivline (ld, &dl);	frac = P_InterceptVector (&trace, &dl);	if (frac < 0)		return true;            // behind source// try to early out the check	if (earlyout && frac < FRACUNIT && !ld->backsector)		return false;   // stop checking	intercept_p->frac = frac;	intercept_p->isaline = true;	intercept_p->d.line = ld;	intercept_p++;	return true;            // continue}/*==================== PIT_AddThingIntercepts===================*/boolean PIT_AddThingIntercepts (mobj_t  *thing){	fixed_t         x1,y1, x2,y2;	int                     s1, s2;	boolean         tracepositive;	divline_t       dl;	fixed_t         frac;	tracepositive = (trace.dx ^ trace.dy)>0;	// check a corner to corner crossection for hit	if (tracepositive)	{		x1 = thing->x - thing->radius;		y1 = thing->y + thing->radius;		x2 = thing->x + thing->radius;		y2 = thing->y - thing->radius;	}	else	{		x1 = thing->x - thing->radius;		y1 = thing->y - thing->radius;		x2 = thing->x + thing->radius;		y2 = thing->y + thing->radius;	}	s1 = P_PointOnDivlineSide (x1, y1, &trace);	s2 = P_PointOnDivlineSide (x2, y2, &trace);	if (s1 == s2)		return true;    // line isn't crossed	dl.x = x1;	dl.y = y1;	dl.dx = x2-x1;	dl.dy = y2-y1;	frac = P_InterceptVector (&trace, &dl);	if (frac < 0)		return true;            // behind source	intercept_p->frac = frac;	intercept_p->isaline = false;	intercept_p->d.thing = thing;	intercept_p++;	return true;                    // keep going}/*====================== P_TraverseIntercepts== Returns true if the traverser function returns true for all lines====================*/boolean P_TraverseIntercepts ( traverser_t func, fixed_t maxfrac ){	int                             count;	fixed_t                 dist;	intercept_t             *scan, *in;	count = intercept_p - intercepts;	in = 0;                 // shut up compiler warning	while (count--)	{		dist = MAXINT;		for (scan = intercepts ; scan<intercept_p ; scan++)			if (scan->frac < dist)			{				dist = scan->frac;				in = scan;			}		if (dist > maxfrac)			return true;                    // checked everything in range#if 0		{       // don't check these yet, ther may be others inserted			in = scan = intercepts;			for ( scan = intercepts ; scan<intercept_p ; scan++)				if (scan->frac > maxfrac)					*in++ = *scan;			intercept_p = in;			return false;		}#endif		if ( !func (in) )			return false;                   // don't bother going farther		in->frac = MAXINT;	}	return true;            // everything was traversed}/*==================== P_PathTraverse== Traces a line from x1,y1 to x2,y2, calling the traverser function for each= Returns true if the traverser function returns true for all lines==================*/boolean P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2,	int flags, boolean (*trav) (intercept_t *)){	fixed_t xt1,yt1,xt2,yt2;	fixed_t xstep,ystep;	fixed_t partial;	fixed_t xintercept, yintercept;	int             mapx, mapy, mapxstep, mapystep;	int             count;	earlyout = flags & PT_EARLYOUT;	validcount++;	intercept_p = intercepts;	if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0)		x1 += FRACUNIT;                         // don't side exactly on a line	if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0)		y1 += FRACUNIT;                         // don't side exactly on a line	trace.x = x1;	trace.y = y1;	trace.dx = x2 - x1;	trace.dy = y2 - y1;	x1 -= bmaporgx;	y1 -= bmaporgy;	xt1 = x1>>MAPBLOCKSHIFT;	yt1 = y1>>MAPBLOCKSHIFT;	x2 -= bmaporgx;	y2 -= bmaporgy;	xt2 = x2>>MAPBLOCKSHIFT;	yt2 = y2>>MAPBLOCKSHIFT;	if (xt2 > xt1)	{		mapxstep = 1;		partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));		ystep = FixedDiv (y2-y1,abs(x2-x1));	}	else if (xt2 < xt1)	{		mapxstep = -1;		partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1);		ystep = FixedDiv (y2-y1,abs(x2-x1));	}	else	{		mapxstep = 0;		partial = FRACUNIT;		ystep = 256*FRACUNIT;	}	yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep);	if (yt2 > yt1)	{		mapystep = 1;		partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));		xstep = FixedDiv (x2-x1,abs(y2-y1));	}	else if (yt2 < yt1)	{		mapystep = -1;		partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1);		xstep = FixedDiv (x2-x1,abs(y2-y1));	}	else	{		mapystep = 0;		partial = FRACUNIT;		xstep = 256*FRACUNIT;	}       	xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep);	//// step through map blocks// Count is present to prevent a round off error from skipping the break	mapx = xt1;	mapy = yt1;		for (count = 0 ; count < 64 ; count++)	{		if (flags & PT_ADDLINES)		{			if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts))				return false;   // early out		}		if (flags & PT_ADDTHINGS)		{			if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts))				return false;   // early out		}				if (mapx == xt2 && mapy == yt2)			break;					if ( (yintercept >> FRACBITS) == mapy)		{			yintercept += ystep;			mapx += mapxstep;		}		else if ( (xintercept >> FRACBITS) == mapx)		{			xintercept += xstep;			mapy += mapystep;		}			}//// go through the sorted list//	return P_TraverseIntercepts ( trav, FRACUNIT );}//===========================================================================//// P_RoughMonsterSearch//// Searches though the surrounding mapblocks for monsters/players//		distance is in MAPBLOCKUNITS//===========================================================================mobj_t *P_RoughMonsterSearch(mobj_t *mo, int distance){	int blockX;	int blockY;	int startX, startY;	int blockIndex;	int firstStop;	int secondStop;	int thirdStop;	int finalStop;	int count;	mobj_t *target;	startX = (mo->x-bmaporgx)>>MAPBLOCKSHIFT;	startY = (mo->y-bmaporgy)>>MAPBLOCKSHIFT;		if(startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight)	{		if(target = RoughBlockCheck(mo, startY*bmapwidth+startX))		{ // found a target right away			return target;		}	}	for(count = 1; count <= distance; count++)	{		blockX = startX-count;		blockY = startY-count;		if(blockY < 0)		{			blockY = 0;		}		else if(blockY >= bmapheight)		{			blockY = bmapheight-1;		}		if(blockX < 0)		{			blockX = 0;		}		else if(blockX >= bmapwidth)		{			blockX = bmapwidth-1;		}		blockIndex = blockY*bmapwidth+blockX;		firstStop = startX+count;		if(firstStop < 0)		{			continue;		}		if(firstStop >= bmapwidth)		{			firstStop = bmapwidth-1;		}		secondStop = startY+count;		if(secondStop < 0)		{			continue;		}		if(secondStop >= bmapheight)		{			secondStop = bmapheight-1;		}		thirdStop = secondStop*bmapwidth+blockX;		secondStop = secondStop*bmapwidth+firstStop;		firstStop += blockY*bmapwidth;		finalStop = blockIndex;				// Trace the first block section (along the top)		for(; blockIndex <= firstStop; blockIndex++)		{			if(target = RoughBlockCheck(mo, blockIndex))			{				return target;			}		}		// Trace the second block section (right edge)		for(blockIndex--; blockIndex <= secondStop; blockIndex += bmapwidth)		{			if(target = RoughBlockCheck(mo, blockIndex))			{				return target;			}		}				// Trace the third block section (bottom edge)		for(blockIndex -= bmapwidth; blockIndex >= thirdStop; blockIndex--)		{			if(target = RoughBlockCheck(mo, blockIndex))			{				return target;			}		}		// Trace the final block section (left edge)		for(blockIndex++; blockIndex > finalStop; blockIndex -= bmapwidth)		{			if(target = RoughBlockCheck(mo, blockIndex))			{				return target;			}		}	}	return NULL;	}//===========================================================================//// RoughBlockCheck////===========================================================================static mobj_t *RoughBlockCheck(mobj_t *mo, int index){	mobj_t *link;	mobj_t *master;	angle_t angle;	link = blocklinks[index];	while(link)	{		if (mo->player)				// Minotaur looking around player		{			if ((link->flags&MF_COUNTKILL) ||				(link->player && (link != mo)))			{				if (!(link->flags&MF_SHOOTABLE))				{					link = link->bnext;					continue;				}				if (link->flags2&MF2_DORMANT)				{					link = link->bnext;					continue;				}				if ((link->type == MT_MINOTAUR) &&					(((mobj_t *)link->special1) == mo))				{					link = link->bnext;					continue;				}				if(netgame && !deathmatch && link->player)				{					link = link->bnext;					continue;				}				if(P_CheckSight(mo, link))				{					return link;				}			}			link = link->bnext;		}		else if (mo->type == MT_MINOTAUR)	// looking around minotaur		{			master = (mobj_t *)mo->special1;			if ((link->flags&MF_COUNTKILL) ||				(link->player && (link != master)))			{				if (!(link->flags&MF_SHOOTABLE))				{					link = link->bnext;					continue;				}				if (link->flags2&MF2_DORMANT)				{					link = link->bnext;					continue;				}				if ((link->type == MT_MINOTAUR) &&					(link->special1 == mo->special1))				{					link = link->bnext;					continue;				}				if(netgame && !deathmatch && link->player)				{					link = link->bnext;					continue;				}				if(P_CheckSight(mo, link))				{					return link;				}			}			link = link->bnext;		}		else if (mo->type == MT_MSTAFF_FX2)		// bloodscourge		{			if ((link->flags&MF_COUNTKILL ||				(link->player && link != mo->target))				&& !(link->flags2&MF2_DORMANT))			{				if (!(link->flags&MF_SHOOTABLE))				{					link = link->bnext;					continue;				}				if(netgame && !deathmatch && link->player)				{					link = link->bnext;					continue;				}				else if(P_CheckSight(mo, link))				{					master = mo->target;					angle = R_PointToAngle2(master->x, master->y,									link->x, link->y) - master->angle;					angle >>= 24;					if (angle>226 || angle<30)					{						return link;					}				}			}			link = link->bnext;		}		else								// spirits		{			if ((link->flags&MF_COUNTKILL ||				(link->player && link != mo->target))				&& !(link->flags2&MF2_DORMANT))			{				if (!(link->flags&MF_SHOOTABLE))				{					link = link->bnext;					continue;				}				if(netgame && !deathmatch && link->player)				{					link = link->bnext;					continue;				}				if (link == mo->target)				{					link = link->bnext;					continue;				}				else if(P_CheckSight(mo, link))				{					return link;				}			}			link = link->bnext;		}	}	return NULL;}

⌨️ 快捷键说明

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