Exemple #1
0
static qboolean GS_CheckBladeAutoAttack( player_state_t *playerState, int timeDelta )
{
	vec3_t origin, dir, end;
	trace_t trace;
	entity_state_t *targ, *player;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );

	if( playerState->POVnum <= 0 || (int)playerState->POVnum > gs.maxclients )
		return qfalse;

	if( !( playerState->pmove.stats[PM_STAT_FEATURES] & PMFEAT_GUNBLADEAUTOATTACK ) )
		return qfalse;

	VectorCopy( playerState->pmove.origin, origin );
	origin[2] += playerState->viewheight;
	AngleVectors( playerState->viewangles, dir, NULL, NULL );
	VectorMA( origin, weapondef->firedef_weak.timeout, dir, end );

	// check for a player to touch
	module_Trace( &trace, origin, vec3_origin, vec3_origin, end, playerState->POVnum, CONTENTS_BODY, timeDelta );
	if( trace.ent <= 0 || trace.ent > gs.maxclients )
		return qfalse;

	player = module_GetEntityState( playerState->POVnum, 0 );
	targ = module_GetEntityState( trace.ent, 0 );
	if( !( targ->effects & EF_TAKEDAMAGE ) || targ->type != ET_PLAYER )
		return qfalse;

	if( GS_TeamBasedGametype() && ( targ->team == player->team ) )
		return qfalse;

	return qtrue;
}
Exemple #2
0
//=================
//GS_SlideMoveClipMove
//=================
static int GS_SlideMoveClipMove( move_t *move /*, const qboolean stepping*/ )
{
	vec3_t endpos, startingOrigin, startingVelocity;
	trace_t	trace;
	int blockedmask = 0;

	VectorCopy( move->origin, startingOrigin );
	VectorCopy( move->velocity, startingVelocity );

	VectorMA( move->origin, move->remainingTime, move->velocity, endpos );
	module_Trace( &trace, move->origin, move->mins, move->maxs, endpos, move->passent, move->contentmask, 0 );
	if( trace.allsolid )
	{
		if( trace.ent > 0 )
			GS_AddTouchEnt( move, trace.ent );
		return blockedmask|SLIDEMOVEFLAG_TRAPPED;
	}

	if( trace.fraction == 1.0f )
	{                          // was able to cleanly perform the full move
		VectorCopy( trace.endpos, move->origin );
		move->remainingTime -= ( trace.fraction * move->remainingTime );
		return blockedmask|SLIDEMOVEFLAG_MOVED;
	}

	if( trace.fraction < 1.0f )
	{                         // wasn't able to make the full move
		GS_AddTouchEnt( move, trace.ent );
		blockedmask |= SLIDEMOVEFLAG_PLANE_TOUCHED;

		// move what can be moved
		if( trace.fraction > 0.0 )
		{
			VectorCopy( trace.endpos, move->origin );
			move->remainingTime -= ( trace.fraction * move->remainingTime );
			blockedmask |= SLIDEMOVEFLAG_MOVED;
		}

		// if the plane is a wall and stepping, try to step it up
		if( !ISWALKABLEPLANE( trace.plane.normal ) )
		{
			//if( stepping && GS_StepUp( move ) ) {
			//	return blockedmask;  // solved : don't add the clipping plane
			//}
			//else {
			blockedmask |= SLIDEMOVEFLAG_WALL_BLOCKED;
			//}
		}

		GS_AddClippingPlane( move, trace.plane.normal );
	}

	return blockedmask;
}
Exemple #3
0
/*
* GS_GoodPosition
*/
static qboolean GS_GoodPosition( int snaptorigin[3], vec3_t mins, vec3_t maxs, int passent, int contentmask )
{
	trace_t	trace;
	vec3_t point;
	int i;

	if( !( contentmask & MASK_SOLID ) )
		return qtrue;

	for( i = 0; i < 3; i++ )
		point[i] = (float)snaptorigin[i] * ( 1.0/PM_VECTOR_SNAP );

	module_Trace( &trace, point, mins, maxs, point, passent, contentmask, 0 );
	return !trace.allsolid ? qtrue : qfalse;
}
Exemple #4
0
/*
* GS_SlideMove
*/
int GS_SlideMove( move_t *move )
{
#define MAX_SLIDEMOVE_ATTEMPTS	8
	int count;
	int blockedmask = 0;
	vec3_t lastValidOrigin, originalVelocity;

	// if the velocity is too small, just stop
	if( VectorLength( move->velocity ) < STOP_EPSILON )
	{
		VectorClear( move->velocity );
		move->remainingTime = 0;
		return 0;
	}

	VectorCopy( move->velocity, originalVelocity );
	VectorCopy( move->origin, lastValidOrigin );

	GS_ClearClippingPlanes( move );
	move->numtouch = 0;

	for( count = 0; count < MAX_SLIDEMOVE_ATTEMPTS; count++ )
	{
		// get the original velocity and clip it to all the planes we got in the list
		VectorCopy( originalVelocity, move->velocity );
		GS_ClipVelocityToClippingPlanes( move );
		blockedmask = GS_SlideMoveClipMove( move /*, stepping*/ );

#ifdef CHECK_TRAPPED
		{
			trace_t	trace;
			module_Trace( &trace, move->origin, move->mins, move->maxs, move->origin, move->passent, move->contentmask, 0 );
			if( trace.startsolid )
			{
				blockedmask |= SLIDEMOVEFLAG_TRAPPED;
			}
		}
#endif

		// can't continue
		if( blockedmask & SLIDEMOVEFLAG_TRAPPED )
		{
#ifdef CHECK_TRAPPED
			module_Printf( "GS_SlideMove SLIDEMOVEFLAG_TRAPPED\n" );
#endif
			move->remainingTime = 0.0f;
			VectorCopy( lastValidOrigin, move->origin );
			return blockedmask;
		}

		VectorCopy( move->origin, lastValidOrigin );

		// touched a plane, re-clip velocity and retry
		if( blockedmask & SLIDEMOVEFLAG_PLANE_TOUCHED )
		{
			continue;
		}

		// if it didn't touch anything the move should be completed
		if( move->remainingTime > 0.0f )
		{
			module_Printf( "slidemove finished with remaining time\n" );
			move->remainingTime = 0.0f;
		}

		break;
	}

	// snap
	GS_SnapPosition( move->origin, move->mins, move->maxs, move->passent, move->contentmask );
	GS_SnapVelocity( move->velocity );

	return blockedmask;
}
Exemple #5
0
/*
* GS_TraceBullet
*/
trace_t *GS_TraceBullet( trace_t *trace, vec3_t start, vec3_t dir, float r, float u, int range, int ignore, int timeDelta )
{
	mat3_t axis;
	vec3_t end;
	qboolean water = qfalse;
	vec3_t water_start;
	int content_mask = MASK_SHOT | MASK_WATER;
	static trace_t water_trace;

	assert( trace );

	VectorNormalizeFast( dir );
	NormalVectorToAxis( dir, axis );

	if( module_PointContents( start, timeDelta ) & MASK_WATER )
	{
		water = qtrue;
		VectorCopy( start, water_start );
		content_mask &= ~MASK_WATER;

		// ok, this isn't randomized, but I think we can live with it
		// the effect on water has never been properly noticed anyway
		//r *= BULLET_WATER_REFRACTION;
		//u *= BULLET_WATER_REFRACTION;
	}

	VectorMA( start, range, &axis[AXIS_FORWARD], end );
	if( r ) VectorMA( end, r, &axis[AXIS_RIGHT], end );
	if( u ) VectorMA( end, u, &axis[AXIS_UP], end );

	module_Trace( trace, start, vec3_origin, vec3_origin, end, ignore, content_mask, timeDelta );

	// see if we hit water
	if( trace->contents & MASK_WATER )
	{
		water_trace = *trace;

		VectorCopy( trace->endpos, water_start );
#if 0
		if( !VectorCompare( start, trace->endpos ) )
		{
			vec3_t forward, right, up;

			// change bullet's course when it enters water
			VectorSubtract( end, start, dir );
			VecToAngles( dir, dir );
			AngleVectors( dir, forward, right, up );

			// ok, this isn't randomized, but I think we can live with it
			// the effect on water has never been properly noticed anyway
			r *= BULLET_WATER_REFRACTION;
			u *= BULLET_WATER_REFRACTION;

			VectorMA( water_start, range, forward, end );
			VectorMA( end, r, right, end );
			VectorMA( end, u, up, end );
		}
#endif

		// re-trace ignoring water this time
		module_Trace( trace, water_start, vec3_origin, vec3_origin, end, ignore, MASK_SHOT, timeDelta );

		return &water_trace;
	}

	if( water )
	{
		water_trace = *trace;
		VectorCopy( water_start, water_trace.endpos );
		return &water_trace;
	}

	return NULL;
}
Exemple #6
0
void GS_TraceLaserBeam( trace_t *trace, vec3_t origin, vec3_t angles, float range, int ignore, int timeDelta, void ( *impact )( trace_t *tr, vec3_t dir ) )
{
	vec3_t from, dir, end;
	int mask = MASK_SHOT;
	int passthrough = ignore;
	entity_state_t *hit;
	vec3_t mins = { -0.5, -0.5, -0.5 };
	vec3_t maxs = { 0.5, 0.5, 0.5 };
	int hits[MAX_BEAM_HIT_ENTITIES];
	int j, numhits;

	assert( trace );

	AngleVectors( angles, dir, NULL, NULL );
	VectorCopy( origin, from );
	VectorMA( origin, range, dir, end );

	trace->ent = 0;

	numhits = 0;
	while( trace->ent != -1 )
	{
		module_Trace( trace, from, mins, maxs, end, passthrough, mask, timeDelta );
		if( trace->ent != -1 )
		{
			// prevent endless loops by checking whether we have already impacted this entity
			for( j = 0; j < numhits; j++ )
			{
				if( trace->ent == hits[j] )
					break;
			}
			if( j < numhits )
				break;

			// callback impact
			if( impact )
				impact( trace, dir );

			// check for pass-through
			hit = module_GetEntityState( trace->ent, timeDelta );
			if( trace->ent == 0 || !hit || hit->solid == SOLID_BMODEL ) // can't pass through brush models
				break;

			// if trapped inside solid, just forget about it
			if( trace->fraction == 0 || trace->allsolid || trace->startsolid )
				break;

			// put a limit on number of hit entities
			if( numhits < MAX_BEAM_HIT_ENTITIES )
				hits[numhits++] = trace->ent;
			else
				break;

			passthrough = trace->ent;
			VectorCopy( trace->endpos, from );
		}
	}

	if( trace->ent != -1 ) // was interrupted by a brush model impact
	{
	}
}