Exemple #1
0
/*
* GClip_SetBrushModel
* 
* Also sets mins and maxs for inline bmodels
*/
void GClip_SetBrushModel( edict_t *ent, char *name )
{
	struct cmodel_s *cmodel;

	if( !name )
	{
		//racesow
		G_Printf( "Warning: GClip_SetBrushModel: NULL model in '%s'", ent->classname ? ent->classname : "no classname\n" );
		GClip_UnlinkEntity( ent );
		G_FreeEdict( ent );
		return;
		//!racesow
	}

	if( !name[0] )
	{
		ent->s.modelindex = 0;
		return;
	}

	if( name[0] != '*' )
	{
		ent->s.modelindex = trap_ModelIndex( name );
		return;
	}

	// if it is an inline model, get the size information for it

	// world model is special
	if( !strcmp( name, "*0" ) )
	{
		ent->s.modelindex = 0;
		cmodel = trap_CM_InlineModel( 0 );
		trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs );
		return;
	}

	// racesow: THIS IS A VERY DIRTY "FIX": it assigns normally unreachable models (the ones over MAX_MODELS) to unrelated models..
	// normally this only affects buggy maps that otherwise wouldn't load (like amt-freestyle3)
	// brush model
	//ent->s.modelindex = trap_ModelIndex( name ); // <- This is the unmodified version 
	ent->s.modelindex = atoi( name+1 );
	// !racesow
	assert( ent->s.modelindex == (unsigned int)atoi( name + 1 ) );
	cmodel = trap_CM_InlineModel( ent->s.modelindex );
	trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs );
	GClip_LinkEntity( ent );
}
/*
================
CG_PointContents
================
*/
int		CG_PointContents( const vec3_t point, int passEntityNum ) {
	int			i;
	entityState_t	*ent;
	centity_t	*cent;
	clipHandle_t cmodel;
	int			contents;

	contents = trap_CM_PointContents (point, 0);

	for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
		cent = cg_solidEntities[ i ];

		ent = &cent->currentState;

		if ( ent->number == passEntityNum ) {
			continue;
		}

		if ( ent->collisionType != CT_SUBMODEL ) {
			continue;
		}

		cmodel = trap_CM_InlineModel( ent->modelindex );
		if ( !cmodel ) {
			continue;
		}

		contents |= trap_CM_TransformedPointContents( point, cmodel, cent->lerpOrigin, cent->lerpAngles );
	}

	return contents;
}
Exemple #3
0
/*
* GClip_SetBrushModel
* 
* Also sets mins and maxs for inline bmodels
*/
void GClip_SetBrushModel( edict_t *ent, const char *name )
{
	struct cmodel_s *cmodel;

	if( !name )
	{
		G_Error( "GClip_SetBrushModel: NULL model in '%s'", 
		ent->classname ? ent->classname : "no classname" );
		// racesow
		GClip_UnlinkEntity( ent );
		G_FreeEdict( ent );
		return;
		// !racesow
	}

	if( !name[0] )
	{
		ent->s.modelindex = 0;
		return;
	}

	if( name[0] != '*' )
	{
		ent->s.modelindex = trap_ModelIndex( name );
		return;
	}

	// if it is an inline model, get the size information for it

	// world model is special
	if( !strcmp( name, "*0" ) )
	{
		ent->s.modelindex = 0;
		cmodel = trap_CM_InlineModel( 0 );
		trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs );
		return;
	}

	// brush model
	ent->s.modelindex = trap_ModelIndex( name );
	assert( ent->s.modelindex == (unsigned int)atoi( name + 1 ) );
	cmodel = trap_CM_InlineModel( ent->s.modelindex );
	trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs );
	GClip_LinkEntity( ent );
}
Exemple #4
0
/*
* GClip_ClearWorld
* called after the world model has been loaded, before linking any entities
*/
void GClip_ClearWorld( void )
{
	vec3_t world_mins, world_maxs;
	struct cmodel_s *world_model;

	world_model = trap_CM_InlineModel( 0 );
	trap_CM_InlineModelBounds( world_model, world_mins, world_maxs );

	GClip_Init_AreaGrid( &g_areagrid, world_mins, world_maxs );
}
Exemple #5
0
/*
* GClip_ClearWorld
* called after the world model has been loaded, before linking any entities
*/
void GClip_ClearWorld( void )
{
	vec3_t mins, maxs;
	struct cmodel_s *cmodel;

	memset( sv_areanodes, 0, sizeof( sv_areanodes ) );
	sv_numareanodes = 0;

	cmodel = trap_CM_InlineModel( 0 );
	trap_CM_InlineModelBounds( cmodel, mins, maxs );
	GClip_CreateAreaNode( 0, mins, maxs );
}
Exemple #6
0
/*
* GClip_CollisionModelForEntity
* 
* Returns a collision model that can be used for testing or clipping an
* object of mins/maxs size.
*/
static struct cmodel_s *GClip_CollisionModelForEntity( entity_state_t *s, entity_shared_t *r )
{
	struct cmodel_s	*model;

	if( ISBRUSHMODEL( s->modelindex ) )
	{ 
		// explicit hulls in the BSP model
		model = trap_CM_InlineModel( s->modelindex );
		if( !model )
			G_Error( "MOVETYPE_PUSH with a non bsp model" );

		return model;
	}

	// create a temp hull from bounding box sizes
	if( s->type == ET_PLAYER || s->type == ET_CORPSE )
		return trap_CM_OctagonModelForBBox( r->mins, r->maxs );
	else
		return trap_CM_ModelForBBox( r->mins, r->maxs );
}
Exemple #7
0
/*
* GClip_EntityContact
*/
static qboolean GClip_EntityContact( vec3_t mins, vec3_t maxs, edict_t *ent )
{
	trace_t tr;
	struct cmodel_s *model;

	if( !mins )
		mins = vec3_origin;
	if( !maxs )
		maxs = vec3_origin;

	if( ISBRUSHMODEL( ent->s.modelindex ) )
	{
		model = trap_CM_InlineModel( ent->s.modelindex );
		if( !model )
			G_Error( "MOVETYPE_PUSH with a non bsp model" );

		trap_CM_TransformedBoxTrace( &tr, vec3_origin, vec3_origin, mins, maxs, model, MASK_ALL, ent->s.origin, ent->s.angles );

		return tr.startsolid || tr.allsolid;
	}

	return ( BoundsIntersect( mins, maxs, ent->r.absmin, ent->r.absmax ) );
}
/*
=========================
CG_TouchTriggerPrediction

Predict push triggers and items
=========================
*/
static void CG_TouchTriggerPrediction( void ) {
	int			i;
	trace_t		trace;
	entityState_t	*ent;
	clipHandle_t cmodel;
	centity_t	*cent;
	qboolean	spectator;

	// dead players don't activate triggers
	if ( cg.cur_lc->predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
		return;
	}

	spectator = ( cg.cur_lc->predictedPlayerState.pm_type == PM_SPECTATOR );

	if ( cg.cur_lc->predictedPlayerState.pm_type != PM_NORMAL && !spectator ) {
		return;
	}

	for ( i = 0 ; i < cg_numTriggerEntities ; i++ ) {
		cent = cg_triggerEntities[ i ];
		ent = &cent->currentState;

		if ( ent->eType == ET_ITEM && !spectator ) {
			CG_TouchItem( cent );
			continue;
		}

		if ( ent->collisionType != CT_SUBMODEL ) {
			continue;
		}

		cmodel = trap_CM_InlineModel( ent->modelindex );
		if ( !cmodel ) {
			continue;
		}

		if ( cg.cur_lc->predictedPlayerState.collisionType == CT_CAPSULE ) {
			trap_CM_CapsuleTrace( &trace, cg.cur_lc->predictedPlayerState.origin, cg.cur_lc->predictedPlayerState.origin,
					cg.cur_lc->predictedPlayerState.mins, cg.cur_lc->predictedPlayerState.maxs, cmodel, -1 );
		} else {
			trap_CM_BoxTrace( &trace, cg.cur_lc->predictedPlayerState.origin, cg.cur_lc->predictedPlayerState.origin,
					cg.cur_lc->predictedPlayerState.mins, cg.cur_lc->predictedPlayerState.maxs, cmodel, -1 );
		}

		if ( !trace.startsolid ) {
			continue;
		}

		if ( ent->eType == ET_TELEPORT_TRIGGER ) {
			cg.cur_lc->hyperspace = qtrue;
		} else if ( ent->eType == ET_PUSH_TRIGGER ) {
			BG_TouchJumpPad( &cg.cur_lc->predictedPlayerState, ent );
		}
	}

	// if we didn't touch a jump pad this pmove frame
	if ( cg.cur_lc->predictedPlayerState.jumppad_frame != cg.cur_lc->predictedPlayerState.pmove_framecount ) {
		cg.cur_lc->predictedPlayerState.jumppad_frame = 0;
		cg.cur_lc->predictedPlayerState.jumppad_ent = 0;
	}
}
/*
====================
CG_ClipMoveToEntities

====================
*/
static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins,
		const vec3_t maxs, const vec3_t end, int skipNumber,
		int mask, trace_t *tr, traceType_t traceType )
{
	int			i;
	trace_t		trace;
	entityState_t	*ent;
	clipHandle_t 	cmodel;
	vec3_t		origin, angles;
	centity_t	*cent;

	for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
		cent = cg_solidEntities[ i ];
		ent = &cent->currentState;

		if ( ent->number == skipNumber ) {
			continue;
		}

		// if it doesn't have any brushes of a type we
		// are looking for, ignore it
		if ( !(mask & ent->contents) ) {
			continue;
		}

		if ( ent->collisionType == CT_SUBMODEL ) {
			cmodel = trap_CM_InlineModel( ent->modelindex );
			VectorCopy( cent->lerpAngles, angles );
			BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
		} else if ( ent->collisionType == CT_CAPSULE ) {
			cmodel = trap_CM_TempCapsuleModel( ent->mins, ent->maxs, ent->contents );
			VectorCopy( vec3_origin, angles );
			VectorCopy( cent->lerpOrigin, origin );
		} else /* if ( ent->collisionType == CT_AABB ) */ {
			cmodel = trap_CM_TempBoxModel( ent->mins, ent->maxs, ent->contents );
			VectorCopy( vec3_origin, angles );
			VectorCopy( cent->lerpOrigin, origin );
		}


		if ( traceType == TT_BISPHERE ) {
			trap_CM_TransformedBiSphereTrace( &trace, start, end,
					mins[ 0 ], maxs[ 0 ], cmodel, mask, origin );
		} else if ( traceType == TT_CAPSULE ) {
			trap_CM_TransformedCapsuleTrace ( &trace, start, end,
					mins, maxs, cmodel,  mask, origin, angles );
		} else /* if ( traceType == TT_AABB ) */ {
			trap_CM_TransformedBoxTrace ( &trace, start, end,
					mins, maxs, cmodel,  mask, origin, angles );
		}

		if (trace.allsolid || trace.fraction < tr->fraction) {
			trace.entityNum = ent->number;
			if( tr->lateralFraction < trace.lateralFraction )
			{
				float oldLateralFraction = tr->lateralFraction;
				*tr = trace;
				tr->lateralFraction = oldLateralFraction;
			} else {
				*tr = trace;
			}
		} else if (trace.startsolid) {
			tr->startsolid = qtrue;
			tr->entityNum = ent->number;
		}
		if ( tr->allsolid ) {
			return;
		}
	}
}