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

📄 p_map.c

📁 Nxdoom真的满好用的
💻 C
📖 第 1 页 / 共 2 页
字号:
    // this line doesn't block movement    return true;			    // the line does block movement,    // see if it is closer than best so far  isblocking:		    if (in->frac < bestslidefrac)    {	secondslidefrac = bestslidefrac;	secondslideline = bestslideline;	bestslidefrac = in->frac;	bestslideline = li;    }	    return false;	// stop}//// P_SlideMove// The momx / momy move is bad, so try to slide// along a wall.// Find the first line hit, move flush to it,// and slide along it//// This is a kludgy mess.//void P_SlideMove (mobj_t* mo){    fixed_t		leadx;    fixed_t		leady;    fixed_t		trailx;    fixed_t		traily;    fixed_t		newx;    fixed_t		newy;    int			hitcount;		    slidemo = mo;    hitcount = 0;      retry:    if (++hitcount == 3)	goto stairstep;		// don't loop forever        // trace along the three leading corners    if (mo->momx > 0)    {	leadx = mo->x + mo->radius;	trailx = mo->x - mo->radius;    }    else    {	leadx = mo->x - mo->radius;	trailx = mo->x + mo->radius;    }	    if (mo->momy > 0)    {	leady = mo->y + mo->radius;	traily = mo->y - mo->radius;    }    else    {	leady = mo->y - mo->radius;	traily = mo->y + mo->radius;    }		    bestslidefrac = FRACUNIT+1;	    P_PathTraverse ( leadx, leady, leadx+mo->momx, leady+mo->momy,		     PT_ADDLINES, PTR_SlideTraverse );    P_PathTraverse ( trailx, leady, trailx+mo->momx, leady+mo->momy,		     PT_ADDLINES, PTR_SlideTraverse );    P_PathTraverse ( leadx, traily, leadx+mo->momx, traily+mo->momy,		     PT_ADDLINES, PTR_SlideTraverse );        // move up to the wall    if (bestslidefrac == FRACUNIT+1)    {	// the move most have hit the middle, so stairstep      stairstep:	if (!P_TryMove (mo, mo->x, mo->y + mo->momy))	    P_TryMove (mo, mo->x + mo->momx, mo->y);	return;    }    // fudge a bit to make sure it doesn't hit    bestslidefrac -= 0x800;	    if (bestslidefrac > 0)    {	newx = FixedMul (mo->momx, bestslidefrac);	newy = FixedMul (mo->momy, bestslidefrac);		if (!P_TryMove (mo, mo->x+newx, mo->y+newy))	    goto stairstep;    }        // Now continue along the wall.    // First calculate remainder.    bestslidefrac = FRACUNIT-(bestslidefrac+0x800);        if (bestslidefrac > FRACUNIT)	bestslidefrac = FRACUNIT;        if (bestslidefrac <= 0)	return;        tmxmove = FixedMul (mo->momx, bestslidefrac);    tmymove = FixedMul (mo->momy, bestslidefrac);    P_HitSlideLine (bestslideline);	// clip the moves    mo->momx = tmxmove;    mo->momy = tmymove;		    if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove))    {	goto retry;    }}//// P_LineAttack//mobj_t*		linetarget;	// who got hit (or NULL)mobj_t*		shootthing;// Height if not aiming up or down// ???: use slope for monsters?fixed_t		shootz;	int		la_damage;fixed_t		attackrange;fixed_t		aimslope;// slopes to top and bottom of targetextern fixed_t	topslope;extern fixed_t	bottomslope;	//// PTR_AimTraverse// Sets linetaget and aimslope when a target is aimed at.//booleanPTR_AimTraverse (intercept_t* in){    line_t*		li;    mobj_t*		th;    fixed_t		slope;    fixed_t		thingtopslope;    fixed_t		thingbottomslope;    fixed_t		dist;		    if (in->isaline)    {	li = in->d.line;		if ( !(li->flags & ML_TWOSIDED) )	    return false;		// stop		// Crosses a two sided line.	// A two sided line will restrict	// the possible target ranges.	P_LineOpening (li);		if (openbottom >= opentop)	    return false;		// stop		dist = FixedMul (attackrange, in->frac);	if (li->frontsector->floorheight != li->backsector->floorheight)	{	    slope = FixedDiv (openbottom - shootz , dist);	    if (slope > bottomslope)		bottomslope = slope;	}			if (li->frontsector->ceilingheight != li->backsector->ceilingheight)	{	    slope = FixedDiv (opentop - shootz , dist);	    if (slope < topslope)		topslope = slope;	}			if (topslope <= bottomslope)	    return false;		// stop				return true;			// shot continues    }        // shoot a thing    th = in->d.thing;    if (th == shootthing)	return true;			// can't shoot self        if (!(th->flags&MF_SHOOTABLE))	return true;			// corpse or something    // check angles to see if the thing can be aimed at    dist = FixedMul (attackrange, in->frac);    thingtopslope = FixedDiv (th->z+th->height - shootz , dist);    if (thingtopslope < bottomslope)	return true;			// shot over the thing    thingbottomslope = FixedDiv (th->z - shootz, dist);    if (thingbottomslope > topslope)	return true;			// shot under the thing        // this thing can be hit!    if (thingtopslope > topslope)	thingtopslope = topslope;        if (thingbottomslope < bottomslope)	thingbottomslope = bottomslope;    aimslope = (thingtopslope+thingbottomslope)/2;    linetarget = th;    return false;			// don't go any farther}//// PTR_ShootTraverse//boolean PTR_ShootTraverse (intercept_t* in){    fixed_t		x;    fixed_t		y;    fixed_t		z;    fixed_t		frac;        line_t*		li;        mobj_t*		th;    fixed_t		slope;    fixed_t		dist;    fixed_t		thingtopslope;    fixed_t		thingbottomslope;		    if (in->isaline)    {	li = in->d.line;		if (li->special)	    P_ShootSpecialLine (shootthing, li);	if ( !(li->flags & ML_TWOSIDED) )	    goto hitline;		// crosses a two sided line	P_LineOpening (li);			dist = FixedMul (attackrange, in->frac);	if (li->frontsector->floorheight != li->backsector->floorheight)	{	    slope = FixedDiv (openbottom - shootz , dist);	    if (slope > aimslope)		goto hitline;	}			if (li->frontsector->ceilingheight != li->backsector->ceilingheight)	{	    slope = FixedDiv (opentop - shootz , dist);	    if (slope < aimslope)		goto hitline;	}	// shot continues	return true;			// hit line      hitline:	// position a bit closer	frac = in->frac - FixedDiv (4*FRACUNIT,attackrange);	x = trace.x + FixedMul (trace.dx, frac);	y = trace.y + FixedMul (trace.dy, frac);	z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange));	if (li->frontsector->ceilingpic == skyflatnum)	{	    // don't shoot the sky!	    if (z > li->frontsector->ceilingheight)		return false;	    	    // it's a sky hack wall	    if	(li->backsector && li->backsector->ceilingpic == skyflatnum)		return false;			}	// Spawn bullet puffs.	P_SpawnPuff (x,y,z);		// don't go any farther	return false;	    }        // shoot a thing    th = in->d.thing;    if (th == shootthing)	return true;		// can't shoot self        if (!(th->flags&MF_SHOOTABLE))	return true;		// corpse or something		    // check angles to see if the thing can be aimed at    dist = FixedMul (attackrange, in->frac);    thingtopslope = FixedDiv (th->z+th->height - shootz , dist);    if (thingtopslope < aimslope)	return true;		// shot over the thing    thingbottomslope = FixedDiv (th->z - shootz, dist);    if (thingbottomslope > aimslope)	return true;		// shot under the thing        // hit thing    // position a bit closer    frac = in->frac - FixedDiv (10*FRACUNIT,attackrange);    x = trace.x + FixedMul (trace.dx, frac);    y = trace.y + FixedMul (trace.dy, frac);    z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange));    // Spawn bullet puffs or blod spots,    // depending on target type.    if (in->d.thing->flags & MF_NOBLOOD)	P_SpawnPuff (x,y,z);    else	P_SpawnBlood (x,y,z, la_damage);    if (la_damage)	P_DamageMobj (th, shootthing, shootthing, la_damage);    // don't go any farther    return false;	}//// P_AimLineAttack//fixed_tP_AimLineAttack( mobj_t*	t1,  angle_t	angle,  fixed_t	distance ){    fixed_t	x2;    fixed_t	y2;	    angle >>= ANGLETOFINESHIFT;    shootthing = t1;        x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];    y2 = t1->y + (distance>>FRACBITS)*finesine[angle];    shootz = t1->z + (t1->height>>1) + 8*FRACUNIT;    // can't shoot outside view angles    topslope = 100*FRACUNIT/160;	    bottomslope = -100*FRACUNIT/160;        attackrange = distance;    linetarget = NULL;	    P_PathTraverse ( t1->x, t1->y,		     x2, y2,		     PT_ADDLINES|PT_ADDTHINGS,		     PTR_AimTraverse );		    if (linetarget)	return aimslope;    return 0;} //// P_LineAttack// If damage == 0, it is just a test trace// that will leave linetarget set.//voidP_LineAttack( mobj_t*	t1,  angle_t	angle,  fixed_t	distance,  fixed_t	slope,  int		damage ){    fixed_t	x2;    fixed_t	y2;	    angle >>= ANGLETOFINESHIFT;    shootthing = t1;    la_damage = damage;    x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];    y2 = t1->y + (distance>>FRACBITS)*finesine[angle];    shootz = t1->z + (t1->height>>1) + 8*FRACUNIT;    attackrange = distance;    aimslope = slope;		    P_PathTraverse ( t1->x, t1->y,		     x2, y2,		     PT_ADDLINES|PT_ADDTHINGS,		     PTR_ShootTraverse );} //// USE LINES//mobj_t*		usething;boolean	PTR_UseTraverse (intercept_t* in){    int		side;	    if (!in->d.line->special)    {	P_LineOpening (in->d.line);	if (openrange <= 0)	{	    S_StartSound (usething, sfx_noway);	    	    // can't use through a wall	    return false;		}	// not a special line, but keep checking	return true ;		    }	    side = 0;    if (P_PointOnLineSide (usething->x, usething->y, in->d.line) == 1)	side = 1;        //	return false;		// don't use back side	    P_UseSpecialLine (usething, in->d.line, side);    // can't use for than one special line in a row    return false;}//// P_UseLines// Looks for special lines in front of the player to activate.//void P_UseLines (player_t*	player) {    int		angle;    fixed_t	x1;    fixed_t	y1;    fixed_t	x2;    fixed_t	y2;	    usething = player->mo;		    angle = player->mo->angle >> ANGLETOFINESHIFT;    x1 = player->mo->x;    y1 = player->mo->y;    x2 = x1 + (USERANGE>>FRACBITS)*finecosine[angle];    y2 = y1 + (USERANGE>>FRACBITS)*finesine[angle];	    P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse );}//// RADIUS ATTACK//mobj_t*		bombsource;mobj_t*		bombspot;int		bombdamage;//// PIT_RadiusAttack// "bombsource" is the creature// that caused the explosion at "bombspot".//boolean PIT_RadiusAttack (mobj_t* thing){    fixed_t	dx;    fixed_t	dy;    fixed_t	dist;	    if (!(thing->flags & MF_SHOOTABLE) )	return true;    // Boss spider and cyborg    // take no damage from concussion.    if (thing->type == MT_CYBORG	|| thing->type == MT_SPIDER)	return true;			    dx = abs(thing->x - bombspot->x);    dy = abs(thing->y - bombspot->y);        dist = dx>dy ? dx : dy;    dist = (dist - thing->radius) >> FRACBITS;    if (dist < 0)	dist = 0;    if (dist >= bombdamage)	return true;	// out of range    if ( P_CheckSight (thing, bombspot) )    {	// must be in direct path	P_DamageMobj (thing, bombspot, bombsource, bombdamage - dist);    }        return true;}//// P_RadiusAttack// Source is the creature that caused the explosion at spot.//voidP_RadiusAttack( mobj_t*	spot,  mobj_t*	source,  int		damage ){    int		x;    int		y;        int		xl;    int		xh;    int		yl;    int		yh;        fixed_t	dist;	    dist = (damage+MAXRADIUS)<<FRACBITS;    yh = (spot->y + dist - bmaporgy)>>MAPBLOCKSHIFT;    yl = (spot->y - dist - bmaporgy)>>MAPBLOCKSHIFT;    xh = (spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT;    xl = (spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT;    bombspot = spot;    bombsource = source;    bombdamage = damage;	    for (y=yl ; y<=yh ; y++)	for (x=xl ; x<=xh ; x++)	    P_BlockThingsIterator (x, y, PIT_RadiusAttack );}//// SECTOR HEIGHT CHANGING// After modifying a sectors floor or ceiling height,// call this routine to adjust the positions// of all things that touch the sector.//// If anything doesn't fit anymore, true will be returned.// If crunch is true, they will take damage//  as they are being crushed.// If Crunch is false, you should set the sector height back//  the way it was and call P_ChangeSector again//  to undo the changes.//boolean		crushchange;boolean		nofit;//// PIT_ChangeSector//boolean PIT_ChangeSector (mobj_t*	thing){    mobj_t*	mo;	    if (P_ThingHeightClip (thing))    {	// keep checking	return true;    }        // crunch bodies to giblets    if (thing->health <= 0)    {	P_SetMobjState (thing, S_GIBS);	thing->flags &= ~MF_SOLID;	thing->height = 0;	thing->radius = 0;	// keep checking	return true;		    }    // crunch dropped items    if (thing->flags & MF_DROPPED)    {	P_RemoveMobj (thing);		// keep checking	return true;		    }    if (! (thing->flags & MF_SHOOTABLE) )    {	// assume it is bloody gibs or something	return true;			    }        nofit = true;    if (crushchange && !(leveltime&3) )    {	P_DamageMobj(thing,NULL,NULL,10);	// spray blood in a random direction	mo = P_SpawnMobj (thing->x,			  thing->y,			  thing->z + thing->height/2, MT_BLOOD);		mo->momx = (P_Random() - P_Random ())<<12;	mo->momy = (P_Random() - P_Random ())<<12;    }    // keep checking (crush other things)	    return true;	}//// P_ChangeSector//booleanP_ChangeSector( sector_t*	sector,  boolean	crunch ){    int		x;    int		y;	    nofit = false;    crushchange = crunch;	    // re-check heights for all things near the moving sector    for (x=sector->blockbox[BOXLEFT] ; x<= sector->blockbox[BOXRIGHT] ; x++)	for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++)	    P_BlockThingsIterator (x, y, PIT_ChangeSector);		    return nofit;}

⌨️ 快捷键说明

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