예제 #1
0
파일: bg_slidemove.c 프로젝트: Chedo/OpenJK
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove( qboolean gravity ) { 
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	trace_t		trace;
//	float		down_dist, up_dist;
//	vec3_t		delta, delta2;
	vec3_t		up, down;
	float		stepSize;
	qboolean	isGiant = qfalse;
	bgEntity_t	*pEnt;
	qboolean skipStep = qfalse;

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( BG_InReboundHold( pm->ps->legsAnim ) )
	{
		gravity = qfalse;
	}

	if ( PM_SlideMove( gravity ) == 0 ) {
		return;		// we got exactly where we wanted to go first try	
	}

	pEnt = pm_entSelf;

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
			pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
		{
			return;
		}
	}

	VectorCopy(start_o, down);
	down[2] -= STEPSIZE;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
										DotProduct(trace.plane.normal, up) < 0.7))
	{
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		// apply ground friction, even if on ladder
		if (pEnt &&
			pEnt->s.NPC_class == CLASS_ATST ||
				(pEnt->s.NPC_class == CLASS_VEHICLE &&
					pEnt->m_pVehicle &&
					pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER)
			)
		{//AT-STs can step high
			up[2] += 66.0f;
			isGiant = qtrue;
		}
		else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
		{//also can step up high
			up[2] += 64.0f;
			isGiant = qtrue;
		}
		else
		{
			up[2] += STEPSIZE;
		}
	}
	else
	{
		up[2] += STEPSIZE;
	}

	// test the player position if they were a stepheight higher
	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
	if ( trace.allsolid ) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up
	}

	stepSize = trace.endpos[2] - start_o[2];
	// try slidemove from this position
	VectorCopy (trace.endpos, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	PM_SlideMove( gravity );

	// push down the final amount
	VectorCopy (pm->ps->origin, down);
	down[2] -= stepSize;
	pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);

	if ( pm->stepSlideFix )
	{
		if ( pm->ps->clientNum < MAX_CLIENTS
			&& trace.plane.normal[2] < MIN_WALK_NORMAL )
		{//normal players cannot step up slopes that are too steep to walk on!
			vec3_t stepVec;
			//okay, the step up ends on a slope that it too steep to step up onto,
			//BUT:
			//If the step looks like this:
			//  (B)\__
			//        \_____(A)
			//Then it might still be okay, so we figure out the slope of the entire move
			//from (A) to (B) and if that slope is walk-upabble, then it's okay
			VectorSubtract( trace.endpos, down_o, stepVec );
			VectorNormalize( stepVec ); 
			if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
			{
				skipStep = qtrue;
			}
		}
	}

	if ( !trace.allsolid 
		&& !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
	{ 
		if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_RANCOR )
		{//Rancor don't step on clients
			if ( pm->stepSlideFix )
			{
				VectorCopy (down_o, pm->ps->origin);
				VectorCopy (down_v, pm->ps->velocity);
			}
			else
			{
				VectorCopy (start_o, pm->ps->origin);
				VectorCopy (start_v, pm->ps->velocity);
			}
		}
		/*
		else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_ATST 
			&& OnSameTeam( pEnt, traceEnt) )
		{//NPC AT-ST's don't step up on allies
			VectorCopy (start_o, pm->ps->origin);
			VectorCopy (start_v, pm->ps->velocity);
		}
		*/
		else
		{
			VectorCopy (trace.endpos, pm->ps->origin);
			if ( pm->stepSlideFix )
			{
				if ( trace.fraction < 1.0 ) {
					PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
				}
			}
		}
	}
	else
	{
		if ( pm->stepSlideFix )
		{
			VectorCopy (down_o, pm->ps->origin);
			VectorCopy (down_v, pm->ps->velocity);
		}
	}
	if ( !pm->stepSlideFix )
	{
		if ( trace.fraction < 1.0 ) {
			PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
		}
	}

#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
예제 #2
0
void PM_StepSlideMove( qboolean gravity ) { 
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	trace_t		trace;
//	float		down_dist, up_dist;
//	vec3_t		delta, delta2;
	vec3_t		up, down;
	float		stepSize;
	qboolean	isGiant = qfalse;
	bgEntity_t	*pEnt;
	qboolean skipStep = qfalse;
	int NEW_STEPSIZE = STEPSIZE;
	const int moveStyle = PM_GetMovePhysics();

	if (moveStyle == MV_CPM || moveStyle == MV_Q3 || moveStyle == MV_WSW || moveStyle == MV_RJQ3 || moveStyle == MV_RJCPM || moveStyle == MV_SLICK || moveStyle == MV_BOTCPM) {
		if (pm->ps->velocity[2] > 0 && pm->cmd.upmove > 0) {
			int jumpHeight = pm->ps->origin[2] - pm->ps->fd.forceJumpZStart;

			if (jumpHeight > 48)
				jumpHeight = 48;
			else if (jumpHeight < 22)
				jumpHeight = 22;

			NEW_STEPSIZE = 48 - jumpHeight + 22;

			//trap->SendServerCommand(-1, va("print \"new stepsize: %i, expected max end height: %i\n\"", NEW_STEPSIZE, NEW_STEPSIZE + (int)(pm->ps->origin[2] - pm->ps->fd.forceJumpZStart)));
			
			//This means that we can always clip things up to 48 units tall, if we are moving up when we hit it and from a bhop..
			//It means we can sometimes clip things up to 70 units tall, if we hit it in right part of jump
			//Should it be higher..? some of the things in q3 are 56 units tall..

			//NEW_STEPSIZE = 46;
			//Make stepsize equal to.. our current 48 - our current jumpheight ?
		}
		else 
			NEW_STEPSIZE = 22;
	}

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( BG_InReboundHold( pm->ps->legsAnim ) )
	{
		gravity = qfalse;
	}

	if ( PM_SlideMove( gravity ) == 0 ) {
		return;		// we got exactly where we wanted to go first try, nospeed ramp returns here maybe	
	}

	pEnt = pm_entSelf;

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
			pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
		{
			return;
		}
	}

	VectorCopy(start_o, down);
	down[2] -= NEW_STEPSIZE;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
										DotProduct(trace.plane.normal, up) < 0.7))
	{
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		// apply ground friction, even if on ladder
		if (pEnt &&
			(pEnt->s.NPC_class == CLASS_ATST ||
			(pEnt->s.NPC_class == CLASS_VEHICLE && pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER) ) )
		{//AT-STs can step high
			up[2] += 66.0f;
			isGiant = qtrue;
		}
		else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
		{//also can step up high
			up[2] += 64.0f;
			isGiant = qtrue;
		}
		else
		{
			up[2] += NEW_STEPSIZE;
		}
	}
	else
	{
		up[2] += NEW_STEPSIZE;
	}

	// test the player position if they were a stepheight higher
	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
	if ( trace.allsolid ) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up, nospeed ramp returns here maybe
	}

	stepSize = trace.endpos[2] - start_o[2];
	// try slidemove from this position
	VectorCopy (trace.endpos, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	PM_SlideMove( gravity );

	pml.clipped = qtrue; //nospeed ramp fix, if we made it to this point there wont be a nospeed ramp

	// push down the final amount
	VectorCopy (pm->ps->origin, down);
	down[2] -= stepSize;
	pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);

	if ( pm->stepSlideFix )
	{
		if ( pm->ps->clientNum < MAX_CLIENTS
			&& trace.plane.normal[2] < MIN_WALK_NORMAL )
		{//normal players cannot step up slopes that are too steep to walk on!
			vec3_t stepVec;
			//okay, the step up ends on a slope that it too steep to step up onto,
			//BUT:
			//If the step looks like this:
			//  (B)\__
			//        \_____(A)
			//Then it might still be okay, so we figure out the slope of the entire move
			//from (A) to (B) and if that slope is walk-upabble, then it's okay
			VectorSubtract( trace.endpos, down_o, stepVec );
			VectorNormalize( stepVec ); 
			if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
			{
				skipStep = qtrue;
			}
		}
	}

	if ( !trace.allsolid 
		&& !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
	{ 
		if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_RANCOR )
		{//Rancor don't step on clients
			if ( pm->stepSlideFix )
			{
				VectorCopy (down_o, pm->ps->origin);
				VectorCopy (down_v, pm->ps->velocity);
			}
			else
			{
				VectorCopy (start_o, pm->ps->origin);
				VectorCopy (start_v, pm->ps->velocity);
			}
		}
		/*
		else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_ATST 
			&& OnSameTeam( pEnt, traceEnt) )
		{//NPC AT-ST's don't step up on allies
			VectorCopy (start_o, pm->ps->origin);
			VectorCopy (start_v, pm->ps->velocity);
		}
		*/
		else
		{
			VectorCopy (trace.endpos, pm->ps->origin);
			if (pm->stepSlideFix)
			{
				if (trace.fraction < 1.0) {
					if (moveStyle == MV_WSW || moveStyle == MV_SLICK) { //Make Warsow Rampjump not slow down your XY speed
						vec3_t oldVel, clipped_velocity, newVel;
						float oldSpeed, newSpeed;

						VectorCopy(pm->ps->velocity, oldVel);
						oldSpeed = oldVel[0] * oldVel[0] + oldVel[1] * oldVel[1]; 

						PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, clipped_velocity, OVERCLIP ); //WSW RAMPJUMP 3

						VectorCopy(clipped_velocity, newVel);
						newVel[2] = 0;
						newSpeed = newVel[0] * newVel[0] + newVel[1] * newVel[1]; 

						if (newSpeed > oldSpeed)
							VectorCopy(clipped_velocity, pm->ps->velocity);
					}
					else {
						PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
					}
				}
			}
		}
	}
	else
	{
		if ( pm->stepSlideFix )
		{
			VectorCopy (down_o, pm->ps->origin);
			VectorCopy (down_v, pm->ps->velocity);
		}
	}
	if ( !pm->stepSlideFix )
	{
		if ( trace.fraction < 1.0 ) {
			if (moveStyle == MV_WSW || moveStyle == MV_SLICK) {
				vec3_t oldVel, clipped_velocity, newVel;
				float oldSpeed, newSpeed;

				VectorCopy(pm->ps->velocity, oldVel);
				oldSpeed = oldVel[0] * oldVel[0] + oldVel[1] * oldVel[1]; 

				PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, clipped_velocity, OVERCLIP ); //WSW RAMPJUMP 2

				VectorCopy(clipped_velocity, newVel);
				newVel[2] = 0;
				newSpeed = newVel[0] * newVel[0] + newVel[1] * newVel[1]; 

				if (newSpeed > oldSpeed)
					VectorCopy(clipped_velocity, pm->ps->velocity);
			}
			else {
				PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
			}
		}
	}

#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}