Exemple #1
0
void CG_Dash( entity_state_t *state )
{
	lentity_t *le;
	vec3_t pos, dvect, angle = { 0, 0, 0 };

	if( !(cg_cartoonEffects->integer & 4) )
		return;

	// KoFFiE: Calculate angle based on relative position of the previous origin state of the player entity
	VectorSubtract( state->origin, cg_entities[state->number].prev.origin, dvect );

	// ugly inline define -> Ignore when difference between 2 positions was less than this value.
#define IGNORE_DASH 6.0

	if( ( dvect[0] > -IGNORE_DASH ) && ( dvect[0] < IGNORE_DASH ) &&
		( dvect[1] > -IGNORE_DASH ) && ( dvect[1] < IGNORE_DASH ) )
		return;

	VecToAngles( dvect, angle );
	VectorCopy( state->origin, pos );
	angle[1] += 270; // Adjust angle
	pos[2] -= 24; // Adjust the position to ground height

	if( CG_PointContents( pos ) & MASK_WATER )
		return; // no smoke under water :)

	le = CG_AllocModel( LE_DASH_SCALE, pos, angle, 7, //5
		1.0, 1.0, 1.0, 1.0,
		0, 0, 0, 0,
		CG_MediaModel( cgs.media.modDash ),
		NULL
		);
	le->ent.scale = 0.01f;
	le->ent.axis[2][2] *= 2.0f;
}
Exemple #2
0
/*
* CG_BoltExplosionMode
*/
void CG_BoltExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags )
{
	lentity_t *le;
	vec3_t angles;

	if( !CG_SpawnDecal( pos, dir, random()*360, 12, 
		1, 1, 1, 1, 10, 1, true, CG_MediaShader( cgs.media.shaderElectroboltMark ) ) ) {
		if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) {
			return;
		}
	}

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_INVERSESCALE_ALPHA_FADE, pos, angles, 6, // 6 is time
		1, 1, 1, 1, //full white no inducted alpha
		250, 0.75, 0.75, 0.75, //white dlight
		CG_MediaModel( cgs.media.modElectroBoltWallHit ), NULL );

	le->ent.rotation = rand() % 360;
	le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f;
	
	// add white energy particles on the impact
	CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL );
	
	trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, 
		cg_volume_effects->value, ATTN_STATIC );
}
Exemple #3
0
static asvec3_t objectVec3_VecToAngles( asvec3_t *self )
{
	asvec3_t angles;

	VecToAngles( self->v, angles.v );
	return angles;
}
Exemple #4
0
/*
* CG_PlasmaExplosion
*/
void CG_PlasmaExplosion( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles;
	float model_radius = PLASMA_EXPLOSION_MODEL_RADIUS;

	VecToAngles( dir, angles );

	if( fire_mode == FIRE_MODE_STRONG )
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 4,
			1, 1, 1, 1,
			150, 0, 0.75, 0,
			CG_MediaModel( cgs.media.modPlasmaExplosion ),
			NULL );
		le->ent.scale = radius/model_radius;
	}
	else
	{

		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 4,
			1, 1, 1, 1,
			80, 0, 0.75, 0,
			CG_MediaModel( cgs.media.modPlasmaExplosion ),
			NULL );
		le->ent.scale = radius/model_radius;
	}

	le->ent.rotation = rand() % 360;

	CG_SpawnDecal( pos, dir, 90, 16,
		1, 1, 1, 1, 4, 1, qtrue,
		CG_MediaShader( cgs.media.shaderPlasmaMark ) );
}
Exemple #5
0
/*
* CG_InstaExplosionMode
*/
void CG_InstaExplosionMode( vec3_t pos, vec3_t dir, int fire_mode )
{
	lentity_t *le;
	vec3_t angles;

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 6, // 6 is time
		1, 1, 1, 1, //full white no inducted alpha
		250, 0.65, 0.65, 0.65, //white dlight
		CG_MediaModel( cgs.media.modInstagunWallHit ), NULL );

	le->ent.rotation = rand() % 360;

	if( fire_mode == FIRE_MODE_STRONG )
	{
		le->ent.scale = 1.5f;
		// add white energy particles on the impact
		CG_ImpactPuffParticles( pos, dir, 12, 1.25f, 1, 1, 1, 1, CG_MediaShader( cgs.media.shaderAdditiveParticleShine ) );
	}
	else
	{
		le->ent.scale = 1.0f;
		CG_ImpactPuffParticles( pos, dir, 12, 1.0f, 1, 1, 1, 1, NULL );
	}

	CG_SpawnDecal( pos, dir, random()*360, 8, 1, 1, 1, 1, 10, 1, qtrue, CG_MediaShader( cgs.media.shaderInstagunMark ) );
}
Exemple #6
0
void GS_TraceCurveLaserBeam( trace_t *trace, vec3_t origin, vec3_t angles, vec3_t blendPoint, int ignore, int timeDelta, void ( *impact )( trace_t *tr, vec3_t dir ) )
{
	float frac, subdivisions = CURVELASERBEAM_SUBDIVISIONS;
	float range = (float)GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.timeout;
	vec3_t from, dir, end;
	int passthrough = ignore;

	int i, j;
	vec3_t tmpangles, blendAngles;

	assert( trace );

	VectorCopy( origin, from );
	VectorSubtract( blendPoint, origin, dir );
	VecToAngles( dir, blendAngles );

	for( i = 1; i <= (int)subdivisions; i++ )
	{
		frac = ( ( range/subdivisions )*(float)i ) / (float)range;

		for( j = 0; j < 3; j++ )
			tmpangles[j] = LerpAngle( angles[j], blendAngles[j], frac );

		AngleVectors( tmpangles, dir, NULL, NULL );
		VectorMA( origin, range * frac, dir, end );

		GS_TraceLaserBeam( trace, from, tmpangles, DistanceFast( from, end ), passthrough, timeDelta, impact );
		if( trace->fraction != 1.0f )
			break;

		passthrough = trace->ent;
		VectorCopy( end, from );
	}
}
Exemple #7
0
/*
* CG_GunBladeBlastImpact
*/
void CG_GunBladeBlastImpact( vec3_t pos, vec3_t dir, float radius )
{
	lentity_t *le;
	lentity_t *le_explo;
	vec3_t angles;
	float model_radius = GUNBLADEBLAST_EXPLOSION_MODEL_RADIUS;

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 2, //3 frames
		1, 1, 1, 1, //full white no inducted alpha
		0, 0, 0, 0, //dlight
		CG_MediaModel( cgs.media.modBladeWallHit ),
		//"models/weapon_hits/gunblade/hit_blast.md3"
		NULL );
	le->ent.rotation = rand() % 360;
	le->ent.scale = 1.0f; // this is the small bullet impact


	le_explo = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 2 + ( radius/16.1f ),
		1, 1, 1, 1, //full white no inducted alpha
		0, 0, 0, 0, //dlight
		CG_MediaModel( cgs.media.modBladeWallExplo ),
		NULL );
	le_explo->ent.rotation = rand() % 360;
	le_explo->ent.scale = radius/model_radius;

	CG_SpawnDecal( pos, dir, random()*360, 3+( radius*0.5f ), 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
}
Exemple #8
0
/**
 * @note Think function
 */
static void LET_Projectile (le_t* le)
{
	if (cl.time >= le->endTime) {
		vec3_t impact;
		VectorCopy(le->origin, impact);
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
		if (Q_strvalid(le->ref1)) {
			VectorCopy(le->ptl->s, impact);
			le->ptl = CL_ParticleSpawn(le->ref1, 0, impact, bytedirs[le->angle]);
			VecToAngles(bytedirs[le->state], le->ptl->angles);
		}
		if (Q_strvalid(le->ref2)) {
			S_LoadAndPlaySample(le->ref2, impact, le->fd->impactAttenuation, SND_VOLUME_WEAPONS);
		}
		if (le->ref3) {
			/* Spawn blood particles (if defined) if actor(-body) was hit. Even if actor is dead. */
			/** @todo Special particles for stun attack (mind you that there is
			 * electrical and gas/chemical stunning)? */
			if (le->fd->obj->dmgtype != csi.damStunGas)
				LE_ActorBodyHit(le->ref3, impact, le->angle);
			CL_ActorPlaySound(le->ref3, SND_HURT);
		}
	} else if (CL_OutsideMap(le->ptl->s, UNIT_SIZE * 10)) {
		le->endTime = cl.time;
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
	}
}
Exemple #9
0
/*
* CG_DemoCam_LookAt
*/
bool CG_DemoCam_LookAt( int trackEnt, vec3_t vieworg, vec3_t viewangles ) {
	centity_t *cent;
	vec3_t dir;
	vec3_t origin;
	struct cmodel_s *cmodel;
	int i;

	if( trackEnt < 1 || trackEnt >= MAX_EDICTS ) {
		return false;
	}

	cent = &cg_entities[trackEnt];
	if( cent->serverFrame != cg.frame.serverFrame ) {
		return false;
	}

	// seems to be valid. Find the angles to look at this entity
	VectorLerp( cent->prev.origin, cg.lerpfrac, cent->current.origin, origin );

	// if having a bounding box, look to its center
	if( ( cmodel = CG_CModelForEntity( trackEnt ) ) != NULL ) {
		vec3_t mins, maxs;
		trap_CM_InlineModelBounds( cmodel, mins, maxs );
		for( i = 0; i < 3; i++ )
			origin[i] += ( mins[i] + maxs[i] );
	}

	VectorSubtract( origin, vieworg, dir );
	VectorNormalize( dir );
	VecToAngles( dir, viewangles );
	return true;
}
Exemple #10
0
Vec3 Ai::GetNewViewAngles( const vec3_t oldAngles, const Vec3 &desiredDirection,
						   unsigned frameTime, float angularSpeedMultiplier ) const {
	// Based on turret script code

	// For those trying to learn working with angles
	// Vec3.x is the PITCH angle (up and down rotation)
	// Vec3.y is the YAW angle (left and right rotation)
	// Vec3.z is the ROLL angle (left and right inclination)

	vec3_t newAngles, desiredAngles;
	VecToAngles( desiredDirection.Data(), desiredAngles );

	// Normalize180 all angles so they can be compared
	for( int i = 0; i < 3; ++i ) {
		newAngles[i] = AngleNormalize180( oldAngles[i] );
		desiredAngles[i] = AngleNormalize180( desiredAngles[i] );
	}

	// Rotate the entity angles to the desired angles
	if( !VectorCompare( newAngles, desiredAngles ) ) {
		for( auto angleNum: { YAW, PITCH } ) {
			newAngles[angleNum] = GetChangedAngle( newAngles[angleNum], desiredAngles[angleNum],
												   frameTime, angularSpeedMultiplier, angleNum );
		}
	}

	return Vec3( newAngles );
}
Exemple #11
0
/*
* G_LocalSpread
*/
static void G_LocalSpread( vec3_t angles, int spread, int seed )
{
	float r, u;
	vec3_t axis[3], dir;
	double alpha;
	double s;

	if( spread <= 0 )
		return;

	seed &= 255;

	alpha = M_PI * Q_crandom( &seed ); // [-PI ..+PI]
	s = fabs( Q_crandom( &seed ) ); // [0..1]

	r = s * cos( alpha ) * spread;
	u = s * sin( alpha ) * spread;

	AngleVectors( angles, axis[0], axis[1], axis[2] );

	VectorMA( vec3_origin, 8192, axis[0], dir );
	VectorMA( dir, r, axis[1], dir );
	VectorMA( dir, u, axis[2], dir );

	VecToAngles( dir, angles );
}
Exemple #12
0
/*
* CG_BladeImpact
*/
void CG_BladeImpact( const vec3_t pos, const vec3_t dir )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t end;
	vec3_t local_pos, local_dir;
	trace_t	trace;

	//find what are we hitting
	VectorCopy( pos, local_pos );
	VectorNormalize2( dir, local_dir );
	VectorMA( pos, -1.0, local_dir, end );
	CG_Trace( &trace, local_pos, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SHOT );
	if( trace.fraction == 1.0 )
		return;

	VecToAngles( local_dir, angles );

	if( trace.surfFlags & SURF_FLESH ||
		( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_PLAYER )
		|| ( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_CORPSE ) )
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 1, 1, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBladeWallHit ), NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;

		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeFleshHit[(int)( random()*3 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
	}
	else if( trace.surfFlags & SURF_DUST )
	{
		// throw particles on dust
		CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 30 );

		//fixme? would need a dust sound
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
	}
	else
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 1, 1, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBladeWallHit ), NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;

		CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 15 );

		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
		if( !( trace.surfFlags & SURF_NOMARKS ) )
			CG_SpawnDecal( pos, dir, random()*10, 8, 1, 1, 1, 1, 10, 1, false, CG_MediaShader( cgs.media.shaderBladeMark ) );
	}
}
Exemple #13
0
/*
* SelectSpawnPoint
* 
* Chooses a player start, deathmatch start, etc
*/
void SelectSpawnPoint( edict_t *ent, edict_t **spawnpoint, vec3_t origin, vec3_t angles )
{
	edict_t	*spot = NULL;

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
	{
		spot = G_SelectIntermissionSpawnPoint();
	}
	else 
	{
		if( game.asEngine != NULL )
			spot = GT_asCallSelectSpawnPoint( ent );

		if( !spot )
			spot = SelectDeathmatchSpawnPoint( ent );
	}

	// find a single player start spot
	if( !spot )
	{
		spot = G_Find( spot, FOFS( classname ), "info_player_start" );
		if( !spot )
		{
			spot = G_Find( spot, FOFS( classname ), "team_CTF_alphaspawn" );
			if( !spot )
				spot = G_Find( spot, FOFS( classname ), "team_CTF_betaspawn" );
			if( !spot )
				spot = world;
		}
	}

	*spawnpoint = spot;
	VectorCopy( spot->s.origin, origin );
	VectorCopy( spot->s.angles, angles );

	if( !Q_stricmp( spot->classname, "info_player_intermission" ) )
	{
		// if it has a target, look towards it
		if( spot->target )
		{
			vec3_t dir;
			edict_t *target;

			target = G_PickTarget( spot->target );
			if( target )
			{
				VectorSubtract( target->s.origin, origin, dir );
				VecToAngles( dir, angles );
			}
		}
	}

	// SPAWN TELEFRAGGING PROTECTION.
	if( ent->r.solid == SOLID_YES && ( level.gametype.spawnpointRadius > ( playerbox_stand_maxs[0] - playerbox_stand_mins[0] ) ) )
		G_OffsetSpawnPoint( origin, playerbox_stand_mins, playerbox_stand_maxs, level.gametype.spawnpointRadius, 
			!( spot->spawnflags & 1 ) ? true : false );
}
Exemple #14
0
/*
* W_Fire_LinearProjectile - Spawn a generic linear projectile without a model, touch func, sound nor mod
*/
static edict_t *W_Fire_LinearProjectile( edict_t *self, vec3_t start, vec3_t dir, int speed,
										 float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int timeout, int timeDelta ) {
	edict_t *projectile;
	vec3_t angles;

	projectile = G_Spawn();
	VectorCopy( start, projectile->s.origin );
	VectorCopy( start, projectile->olds.origin );

	VecToAngles( dir, angles );
	VectorCopy( angles, projectile->s.angles );
	VectorScale( dir, speed, projectile->velocity );

	projectile->movetype = MOVETYPE_LINEARPROJECTILE;

	projectile->r.solid = SOLID_YES;
	projectile->r.clipmask = ( !GS_RaceGametype() ) ? MASK_SHOT : MASK_SOLID;

	projectile->r.svflags = SVF_PROJECTILE;

	// enable me when drawing exception is added to cgame
	VectorClear( projectile->r.mins );
	VectorClear( projectile->r.maxs );
	projectile->s.modelindex = 0;
	projectile->r.owner = self;
	projectile->s.ownerNum = ENTNUM( self );
	projectile->touch = W_Touch_Projectile; //generic one. Should be replaced after calling this func
	projectile->nextThink = level.time + timeout;
	projectile->think = G_FreeEdict;
	projectile->classname = NULL; // should be replaced after calling this func.
	projectile->style = 0;
	projectile->s.sound = 0;
	projectile->timeStamp = level.time;
	projectile->timeDelta = timeDelta;

	projectile->projectileInfo.minDamage = min( minDamage, damage );
	projectile->projectileInfo.maxDamage = damage;
	projectile->projectileInfo.minKnockback = min( minKnockback, maxKnockback );
	projectile->projectileInfo.maxKnockback = maxKnockback;
	projectile->projectileInfo.stun = stun;
	projectile->projectileInfo.radius = radius;

	GClip_LinkEntity( projectile );

	// update some data required for the transmission
	projectile->s.linearMovement = true;
	VectorCopy( projectile->s.origin, projectile->s.linearMovementBegin );
	VectorCopy( projectile->velocity, projectile->s.linearMovementVelocity );
	projectile->s.linearMovementTimeStamp = game.serverTime;
	projectile->s.team = self->s.team;
	projectile->s.modelindex2 = ( abs( timeDelta ) > 255 ) ? 255 : (unsigned int)abs( timeDelta );
	return projectile;
}
Exemple #15
0
/*
* W_Fire_TossProjectile - Spawn a generic projectile without a model, touch func, sound nor mod
*/
static edict_t *W_Fire_TossProjectile( edict_t *self, vec3_t start, vec3_t dir, int speed,
									   float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int timeout, int timeDelta ) {
	edict_t *projectile;
	vec3_t angles;

	projectile = G_Spawn();
	VectorCopy( start, projectile->s.origin );
	VectorCopy( start, projectile->olds.origin );

	VecToAngles( dir, angles );
	VectorCopy( angles, projectile->s.angles );
	VectorScale( dir, speed, projectile->velocity );

	projectile->movetype = MOVETYPE_BOUNCEGRENADE;

	// make missile fly through players in race
	if( GS_RaceGametype() ) {
		projectile->r.clipmask = MASK_SOLID;
	} else {
		projectile->r.clipmask = MASK_SHOT;
	}

	projectile->r.solid = SOLID_YES;
	projectile->r.svflags = SVF_PROJECTILE;
	VectorClear( projectile->r.mins );
	VectorClear( projectile->r.maxs );

	//projectile->s.modelindex = trap_ModelIndex ("models/objects/projectile/plasmagun/proj_plasmagun2.md3");
	projectile->s.modelindex = 0;
	projectile->r.owner = self;
	projectile->touch = W_Touch_Projectile; //generic one. Should be replaced after calling this func
	projectile->nextThink = level.time + timeout;
	projectile->think = G_FreeEdict;
	projectile->classname = NULL; // should be replaced after calling this func.
	projectile->style = 0;
	projectile->s.sound = 0;
	projectile->timeStamp = level.time;
	projectile->timeDelta = timeDelta;
	projectile->s.team = self->s.team;

	projectile->projectileInfo.minDamage = min( minDamage, damage );
	projectile->projectileInfo.maxDamage = damage;
	projectile->projectileInfo.minKnockback = min( minKnockback, maxKnockback );
	projectile->projectileInfo.maxKnockback = maxKnockback;
	projectile->projectileInfo.stun = stun;
	projectile->projectileInfo.radius = radius;

	GClip_LinkEntity( projectile );

	return projectile;
}
Exemple #16
0
void SP_misc_particles_finish( edict_t *ent )
{
	// if it has a target, look towards it
	if( ent->target )
	{
		vec3_t dir;
		edict_t *target = G_PickTarget( ent->target );
		if( target )
		{
			VectorSubtract( target->s.origin, ent->s.origin, dir );
			VecToAngles( dir, ent->s.angles );
		}
	}

	ent->think = NULL;
}
Exemple #17
0
/*
===============
CL_TrackerTrail
===============
*/
void CL_TrackerTrail (const vec3_t start, const vec3_t end, int particleColor)
{
	vec3_t		move, vec;
	vec3_t		forward,right,up,angle_dir;
	float		len, dist;
	cparticle_t	*p;
	int			dec = 3;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	VectorCopy(vec, forward);
	VecToAngles(forward, angle_dir);
	AngleVectors(angle_dir, forward, right, up);

	VectorScale (vec, dec, vec);

	// FIXME: this is a really silly way to have a loop
	while (len > 0)
	{
		len -= dec;

		if (!free_particles)
			return;
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		VectorClear (p->accel);
		
		p->time = cl.time;

		p->alpha = 1.0f;
		p->alphavel = -2.0f;
		p->color = particleColor;
		dist = 8 * (float)cos(DotProduct(move, forward));
		VectorMA(move, dist, up, p->org);

		p->vel[0] = p->vel[1] = 0;
		p->vel[2] = 5;

		VectorAdd (move, vec, move);
	}
}
Exemple #18
0
void CLQ2_TrackerTrail( vec3_t start, vec3_t end, int particleColour ) {
	vec3_t move;
	VectorCopy( start, move );
	vec3_t vec;
	VectorSubtract( end, start, vec );
	float len = VectorNormalize( vec );

	vec3_t forward;
	VectorCopy( vec, forward );
	vec3_t angle_dir;
	VecToAngles( forward, angle_dir );
	vec3_t right, up;
	AngleVectors( angle_dir, forward, right, up );

	int dec = 3;
	VectorScale( vec, 3, vec );

	// FIXME: this is a really silly way to have a loop
	while ( len > 0 ) {
		len -= dec;

		cparticle_t* p = CL_AllocParticle();
		if ( !p ) {
			return;
		}
		p->type = pt_q2static;
		VectorClear( p->accel );

		p->alpha = 1.0;
		p->alphavel = -2.0;
		p->color = particleColour;
		float dist = DotProduct( move, forward );
		VectorMA( move, 8 * cos( dist ), up, p->org );
		for ( int j = 0; j < 3; j++ ) {
			p->vel[ j ] = 0;
			p->accel[ j ] = 0;
		}
		p->vel[ 2 ] = 5;

		VectorAdd( move, vec, move );
	}
}
Exemple #19
0
/*
* CG_FireBullet
*/
static void CG_FireBullet( int self, vec3_t start, vec3_t forward, int count, int spread, int seed, void ( *impact )(trace_t *tr /*, int impactnum*/) )
{
	int i;
	trace_t tr;
	vec3_t dir, axis[3];
	qboolean takedamage;

	// calculate normal vectors
	VecToAngles( forward, dir );
	AngleVectors( dir, axis[0], axis[1], axis[2] );

	for( i = 0; i < count; i++ )
	{
		CG_FireLead( self, start, axis, spread, spread, &seed, &tr );
		takedamage = tr.ent && ( cg_entities[tr.ent].current.effects & EF_TAKEDAMAGE );

		if( tr.fraction < 1.0f && !takedamage && !( tr.surfFlags & SURF_NOIMPACT ) )
			impact( &tr );
	}
}
Exemple #20
0
/*
* CG_LasertGunImpact
*/
void CG_LaserGunImpact( const vec3_t pos, const vec3_t dir, float radius, const vec3_t laser_dir, const vec4_t color )
{
	entity_t ent;
	vec3_t ndir;
	vec3_t angles;

	memset( &ent, 0, sizeof( ent ) );
	VectorCopy( pos, ent.origin );
	VectorMA( ent.origin, 2, dir, ent.origin );
	ent.renderfx = RF_FULLBRIGHT|RF_NOSHADOW;
	ent.scale = 1.45f;
	Vector4Set( ent.shaderRGBA, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255 );
	ent.model = CG_MediaModel( cgs.media.modLasergunWallExplo );
	VectorNegate( laser_dir, ndir );
	VecToAngles( ndir, angles );
	angles[2] = anglemod( -360.0f * cg.time * 0.001f );

	AnglesToAxis( angles, ent.axis );
				
	trap_R_AddEntityToScene( &ent );
}
Exemple #21
0
/*
* CG_InstaExplosionMode
*/
void CG_InstaExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags, int owner )
{
	int team = -1;
	vec4_t tcolor = { 0.65f, 0.0f, 0.26f, 1.0f };
	lentity_t *le;
	vec3_t angles;

	if( cg_teamColoredInstaBeams->integer && owner && ( owner < gs.maxclients + 1 ) )
		team = cg_entities[owner].current.team;
	if( ( team == TEAM_ALPHA ) || ( team == TEAM_BETA ) )
	{
		CG_TeamColor( team, tcolor );
		tcolor[0] *= 0.65f;
		tcolor[1] *= 0.65f;
		tcolor[2] *= 0.65f;
	}

	if( !CG_SpawnDecal( pos, dir, random()*360, 12, 
		tcolor[0], tcolor[1], tcolor[2], 1.0f,
		10, 1, true, CG_MediaShader( cgs.media.shaderInstagunMark ) ) ) {
		if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) {
			return;
		}
	}

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 6, // 6 is time
		tcolor[0], tcolor[1], tcolor[2], 1,
		250, 0.65, 0.65, 0.65, //white dlight
		CG_MediaModel( cgs.media.modInstagunWallHit ), NULL );

	le->ent.rotation = rand() % 360;
	le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f;
	// add white energy particles on the impact
	CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL );
	
	trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, 
		cg_volume_effects->value, ATTN_STATIC );
}
Exemple #22
0
void CG_AddShadeBoxes( void )
{
	// ok, what we have to do here is finding the light direction of each of the shadeboxes origins
	int i;
	cgshadebox_t *sb;
	vec3_t lightdir, end, sborigin;
	trace_t	trace;

	if( !cg_shadows->integer )
		return;

	for( i = 0, sb = cg_shadeBoxes; i < cg_numShadeBoxes; i++, sb++ )
	{
		VectorClear( lightdir );
		trap_R_LightForOrigin( sb->origin, lightdir, NULL, NULL, RadiusFromBounds( sb->mins, sb->maxs ) );

		// move the point we will project close to the bottom of the bbox (so shadow doesn't dance much to the sides)
		VectorSet( sborigin, sb->origin[0], sb->origin[1], sb->origin[2] + sb->mins[2] + 8 );
		VectorMA( sborigin, -SHADOW_PROJECTION_DISTANCE, lightdir, end );
		//CG_DrawTestLine( sb->origin, end ); // lightdir testline
		CG_Trace( &trace, sborigin, vec3_origin, vec3_origin, end, sb->entNum, MASK_OPAQUE );
		if( trace.fraction < 1.0f )
		{                     // we have a shadow
			float blobradius;
			float alpha, maxalpha = 0.95f;
			vec3_t shangles;

			VecToAngles( lightdir, shangles );
			blobradius = SHADOW_MIN_SIZE + trace.fraction * ( SHADOW_MAX_SIZE-SHADOW_MIN_SIZE );

			alpha = ( 1.0f - trace.fraction ) * maxalpha;

			CG_AddBlobShadow( trace.endpos, trace.plane.normal, shangles[YAW], blobradius,
				1, 1, 1, alpha, sb );
		}
	}

	// clean up the polygons list from old frames
	cg_numShadeBoxes = 0;
}
Exemple #23
0
/*
* CG_GenericExplosion
*/
void CG_GenericExplosion( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t decaldir;
	vec3_t origin, vec;
	float expvelocity = 8.0f;

	VectorCopy( dir, decaldir );
	VecToAngles( dir, angles );

	//if( CG_PointContents( pos ) & MASK_WATER )
	//jalfixme: (shouldn't we do the water sound variation?)

	if( fire_mode == FIRE_MODE_STRONG )
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	else
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );

	// animmap shader of the explosion
	VectorMA( pos, radius*0.15f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	// use the rocket explosion sounds
	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherStrongHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherWeakHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
}
Exemple #24
0
/*
* CG_SpawnPolyBeam
* Spawns a polygon from start to end points length and given width.
* shaderlenght makes reference to size of the texture it will draw, so it can be tiled.
*/
static cpoly_t *CG_SpawnPolyBeam( const vec3_t start, const vec3_t end, const vec4_t color, int width, unsigned int dietime, unsigned int fadetime, struct shader_s *shader, int shaderlength, int tag )
{
	cpoly_t *cgpoly;
	poly_t *poly;
	vec3_t angles, dir;
	int i;
	float xmin, ymin, xmax, ymax;
	float stx = 1.0f, sty = 1.0f;

	// find out beam polygon sizes
	VectorSubtract( end, start, dir );
	VecToAngles( dir, angles );

	xmin = 0;
	xmax = VectorNormalize( dir );
	ymin = -( width*0.5 );
	ymax = width*0.5;
	if( shaderlength && xmax > shaderlength )
		stx = xmax / (float)shaderlength;

	if( xmax - xmin < ymax - ymin ) {
		// do not render polybeams which have width longer than their length
		return NULL;
	}

	cgpoly = CG_SpawnPolygon( 1.0, 1.0, 1.0, 1.0, dietime ? dietime : cgs.snapFrameTime, fadetime, shader, tag );

	VectorCopy( angles, cgpoly->angles );
	VectorCopy( start, cgpoly->origin );
	if( color )
		Vector4Copy( color, cgpoly->color );

	// create the polygon inside the cgpolygon
	poly = cgpoly->poly;
	poly->shader = cgpoly->shader;
	poly->numverts = 0;

	// Vic: I think it's safe to assume there should be no fog applied to beams...
	poly->fognum = 0;

	// A
	Vector4Set( poly->verts[poly->numverts], xmin, 0, ymin, 1 );
	poly->stcoords[poly->numverts][0] = 0;
	poly->stcoords[poly->numverts][1] = 0;
	poly->colors[poly->numverts][0] = ( uint8_t )( cgpoly->color[0] * 255 );
	poly->colors[poly->numverts][1] = ( uint8_t )( cgpoly->color[1] * 255 );
	poly->colors[poly->numverts][2] = ( uint8_t )( cgpoly->color[2] * 255 );
	poly->colors[poly->numverts][3] = ( uint8_t )( cgpoly->color[3] * 255 );
	poly->numverts++;

	// B
	Vector4Set( poly->verts[poly->numverts], xmin, 0, ymax, 1 );
	poly->stcoords[poly->numverts][0] = 0;
	poly->stcoords[poly->numverts][1] = sty;
	poly->colors[poly->numverts][0] = ( uint8_t )( cgpoly->color[0] * 255 );
	poly->colors[poly->numverts][1] = ( uint8_t )( cgpoly->color[1] * 255 );
	poly->colors[poly->numverts][2] = ( uint8_t )( cgpoly->color[2] * 255 );
	poly->colors[poly->numverts][3] = ( uint8_t )( cgpoly->color[3] * 255 );
	poly->numverts++;

	// C
	Vector4Set( poly->verts[poly->numverts], xmax, 0, ymax, 1 );
	poly->stcoords[poly->numverts][0] = stx;
	poly->stcoords[poly->numverts][1] = sty;
	poly->colors[poly->numverts][0] = ( uint8_t )( cgpoly->color[0] * 255 );
	poly->colors[poly->numverts][1] = ( uint8_t )( cgpoly->color[1] * 255 );
	poly->colors[poly->numverts][2] = ( uint8_t )( cgpoly->color[2] * 255 );
	poly->colors[poly->numverts][3] = ( uint8_t )( cgpoly->color[3] * 255 );
	poly->numverts++;

	// D
	Vector4Set( poly->verts[poly->numverts], xmax, 0, ymin, 1 );
	poly->stcoords[poly->numverts][0] = stx;
	poly->stcoords[poly->numverts][1] = 0;
	poly->colors[poly->numverts][0] = ( uint8_t )( cgpoly->color[0] * 255 );
	poly->colors[poly->numverts][1] = ( uint8_t )( cgpoly->color[1] * 255 );
	poly->colors[poly->numverts][2] = ( uint8_t )( cgpoly->color[2] * 255 );
	poly->colors[poly->numverts][3] = ( uint8_t )( cgpoly->color[3] * 255 );
	poly->numverts++;

	// the verts data is stored inside cgpoly, cause it can be moved later
	for( i = 0; i < poly->numverts; i++ )
		Vector4Copy( poly->verts[i], cgpoly->verts[i] );

	return cgpoly;
}
Exemple #25
0
/*
* CG_Democam_CalcView
*/
static int CG_Democam_CalcView( void ) {
	int i, viewType;
	float lerpfrac;
	vec3_t v;

	viewType = VIEWDEF_PLAYERVIEW;
	VectorClear( cam_velocity );

	if( currentcam ) {
		if( !nextcam ) {
			lerpfrac = 0;
		} else {
			lerpfrac = (float)( demo_time - currentcam->timeStamp ) / (float)( nextcam->timeStamp - currentcam->timeStamp );
		}

		switch( currentcam->type ) {
			case DEMOCAM_FIRSTPERSON:
				VectorCopy( cg.view.origin, cam_origin );
				VectorCopy( cg.view.angles, cam_angles );
				VectorCopy( cg.view.velocity, cam_velocity );
				cam_fov = cg.view.fov_y;
				break;

			case DEMOCAM_THIRDPERSON:
				VectorCopy( cg.view.origin, cam_origin );
				VectorCopy( cg.view.angles, cam_angles );
				VectorCopy( cg.view.velocity, cam_velocity );
				cam_fov = cg.view.fov_y;
				cam_3dPerson = true;
				break;

			case DEMOCAM_POSITIONAL:
				viewType = VIEWDEF_DEMOCAM;
				cam_POVent = 0;
				VectorCopy( currentcam->origin, cam_origin );
				if( !CG_DemoCam_LookAt( currentcam->trackEnt, cam_origin, cam_angles ) ) {
					VectorCopy( currentcam->angles, cam_angles );
				}
				cam_fov = currentcam->fov;
				break;

			case DEMOCAM_PATH_LINEAR:
				viewType = VIEWDEF_DEMOCAM;
				cam_POVent = 0;
				VectorCopy( cam_origin, v );

				if( !nextcam || nextcam->type == DEMOCAM_FIRSTPERSON || nextcam->type == DEMOCAM_THIRDPERSON ) {
					CG_Printf( "Warning: CG_DemoCam: path_linear cam without a valid next cam\n" );
					VectorCopy( currentcam->origin, cam_origin );
					if( !CG_DemoCam_LookAt( currentcam->trackEnt, cam_origin, cam_angles ) ) {
						VectorCopy( currentcam->angles, cam_angles );
					}
					cam_fov = currentcam->fov;
				} else {
					VectorLerp( currentcam->origin, lerpfrac, nextcam->origin, cam_origin );
					if( !CG_DemoCam_LookAt( currentcam->trackEnt, cam_origin, cam_angles ) ) {
						for( i = 0; i < 3; i++ ) cam_angles[i] = LerpAngle( currentcam->angles[i], nextcam->angles[i], lerpfrac );
					}
					cam_fov = (float)currentcam->fov + (float)( nextcam->fov - currentcam->fov ) * lerpfrac;
				}

				// set velocity
				VectorSubtract( cam_origin, v, cam_velocity );
				VectorScale( cam_velocity, 1.0f / (float)cg.frameTime, cam_velocity );
				break;

			case DEMOCAM_PATH_SPLINE:
				viewType = VIEWDEF_DEMOCAM;
				cam_POVent = 0;
				clamp( lerpfrac, 0, 1 );
				VectorCopy( cam_origin, v );

				if( !nextcam || nextcam->type == DEMOCAM_FIRSTPERSON || nextcam->type == DEMOCAM_THIRDPERSON ) {
					CG_Printf( "Warning: CG_DemoCam: path_spline cam without a valid next cam\n" );
					VectorCopy( currentcam->origin, cam_origin );
					if( !CG_DemoCam_LookAt( currentcam->trackEnt, cam_origin, cam_angles ) ) {
						VectorCopy( currentcam->angles, cam_angles );
					}
					cam_fov = currentcam->fov;
				} else {  // valid spline path
#define VectorHermiteInterp( a, at, b, bt, c, v )  ( ( v )[0] = ( 2 * pow( c, 3 ) - 3 * pow( c, 2 ) + 1 ) * a[0] + ( pow( c, 3 ) - 2 * pow( c, 2 ) + c ) * 2 * at[0] + ( -2 * pow( c, 3 ) + 3 * pow( c, 2 ) ) * b[0] + ( pow( c, 3 ) - pow( c, 2 ) ) * 2 * bt[0], ( v )[1] = ( 2 * pow( c, 3 ) - 3 * pow( c, 2 ) + 1 ) * a[1] + ( pow( c, 3 ) - 2 * pow( c, 2 ) + c ) * 2 * at[1] + ( -2 * pow( c, 3 ) + 3 * pow( c, 2 ) ) * b[1] + ( pow( c, 3 ) - pow( c, 2 ) ) * 2 * bt[1], ( v )[2] = ( 2 * pow( c, 3 ) - 3 * pow( c, 2 ) + 1 ) * a[2] + ( pow( c, 3 ) - 2 * pow( c, 2 ) + c ) * 2 * at[2] + ( -2 * pow( c, 3 ) + 3 * pow( c, 2 ) ) * b[2] + ( pow( c, 3 ) - pow( c, 2 ) ) * 2 * bt[2] )

					float lerpspline, A, B, C, n1, n2, n3;
					cg_democam_t *previouscam = NULL;
					cg_democam_t *secondnextcam = NULL;

					if( nextcam ) {
						secondnextcam = CG_Democam_FindNext( nextcam->timeStamp );
					}
					if( currentcam->timeStamp > 0 ) {
						previouscam = CG_Democam_FindCurrent( currentcam->timeStamp - 1 );
					}

					if( !previouscam && nextcam && !secondnextcam ) {
						lerpfrac = (float)( demo_time - currentcam->timeStamp ) / (float)( nextcam->timeStamp - currentcam->timeStamp );
						lerpspline = lerpfrac;
					} else if( !previouscam && nextcam && secondnextcam ) {
						n1 = nextcam->timeStamp - currentcam->timeStamp;
						n2 = secondnextcam->timeStamp - nextcam->timeStamp;
						A = n1 * ( n1 - n2 ) / ( pow( n1, 2 ) + n1 * n2 - n1 - n2 );
						B = ( 2 * n1 * n2 - n1 - n2 ) / ( pow( n1, 2 ) + n1 * n2 - n1 - n2 );
						lerpfrac = (float)( demo_time - currentcam->timeStamp ) / (float)( nextcam->timeStamp - currentcam->timeStamp );
						lerpspline = A * pow( lerpfrac, 2 ) + B * lerpfrac;
					} else if( previouscam && nextcam && !secondnextcam ) {
						n2 = currentcam->timeStamp - previouscam->timeStamp;
						n3 = nextcam->timeStamp - currentcam->timeStamp;
						A = n3 * ( n2 - n3 ) / ( -n2 - n3 + n2 * n3 + pow( n3, 2 ) );
						B = -1 / ( -n2 - n3 + n2 * n3 + pow( n3, 2 ) ) * ( n2 + n3 - 2 * pow( n3, 2 ) );
						lerpfrac = (float)( demo_time - currentcam->timeStamp ) / (float)( nextcam->timeStamp - currentcam->timeStamp );
						lerpspline = A * pow( lerpfrac, 2 ) + B * lerpfrac;
					} else if( previouscam && nextcam && secondnextcam ) {
						n1 = currentcam->timeStamp - previouscam->timeStamp;
						n2 = nextcam->timeStamp - currentcam->timeStamp;
						n3 = secondnextcam->timeStamp - nextcam->timeStamp;
						A = -2 * pow( n2, 2 ) * ( -pow( n2, 2 ) + n1 * n3 ) / ( 2 * n2 * n3 + pow( n2, 3 ) * n3 - 3 * pow( n2, 2 ) * n1 + n1 * pow( n2, 3 ) + 2 * n1 * n2 - 3 * pow( n2, 2 ) * n3 - 3 * pow( n2, 3 ) + 2 * pow( n2, 2 ) + pow( n2, 4 ) + n1 * pow( n2, 2 ) * n3 - 3 * n1 * n2 * n3 + 2 * n1 * n3 );
						B = pow( n2, 2 ) * ( -2 * n1 - 3 * pow( n2, 2 ) - n2 * n3 + 2 * n3 + 3 * n1 * n3 + n1 * n2 ) / ( 2 * n2 * n3 + pow( n2, 3 ) * n3 - 3 * pow( n2, 2 ) * n1 + n1 * pow( n2, 3 ) + 2 * n1 * n2 - 3 * pow( n2, 2 ) * n3 - 3 * pow( n2, 3 ) + 2 * pow( n2, 2 ) + pow( n2, 4 ) + n1 * pow( n2, 2 ) * n3 - 3 * n1 * n2 * n3 + 2 * n1 * n3 );
						C = -( pow( n2, 2 ) * n1 - 2 * n1 * n2 + 3 * n1 * n2 * n3 - 2 * n1 * n3 - 2 * pow( n2, 4 ) + 3 * pow( n2, 3 ) - 2 * pow( n2, 3 ) * n3 + 5 * pow( n2, 2 ) * n3 - 2 * pow( n2, 2 ) - 2 * n2 * n3 ) / ( 2 * n2 * n3 + pow( n2, 3 ) * n3 - 3 * pow( n2, 2 ) * n1 + n1 * pow( n2, 3 ) + 2 * n1 * n2 - 3 * pow( n2, 2 ) * n3 - 3 * pow( n2, 3 ) + 2 * pow( n2, 2 ) + pow( n2, 4 ) + n1 * pow( n2, 2 ) * n3 - 3 * n1 * n2 * n3 + 2 * n1 * n3 );
						lerpfrac = (float)( demo_time - currentcam->timeStamp ) / (float)( nextcam->timeStamp - currentcam->timeStamp );
						lerpspline = A * pow( lerpfrac, 3 ) + B * pow( lerpfrac, 2 ) + C * lerpfrac;
					} else {
						lerpfrac = 0;
						lerpspline = 0;
					}


					VectorHermiteInterp( currentcam->origin, currentcam->tangent, nextcam->origin, nextcam->tangent, lerpspline, cam_origin );
					if( !CG_DemoCam_LookAt( currentcam->trackEnt, cam_origin, cam_angles ) ) {
						VectorHermiteInterp( currentcam->angles, currentcam->angles_tangent, nextcam->angles, nextcam->angles_tangent, lerpspline, cam_angles );
					}
					cam_fov = (float)currentcam->fov + (float)( nextcam->fov - currentcam->fov ) * lerpfrac;
#undef VectorHermiteInterp
				}

				// set velocity
				VectorSubtract( cam_origin, v, cam_velocity );
				VectorScale( cam_velocity, 1.0f / (float)cg.frameTime, cam_velocity );
				break;

			case DEMOCAM_ORBITAL:
				viewType = VIEWDEF_DEMOCAM;
				cam_POVent = 0;
				cam_fov = currentcam->fov;
				VectorCopy( cam_origin, v );

				if( !currentcam->trackEnt || currentcam->trackEnt >= MAX_EDICTS ) {
					CG_Printf( "Warning: CG_DemoCam: orbital cam needs a track entity set\n" );
					VectorCopy( currentcam->origin, cam_origin );
					VectorClear( cam_angles );
					VectorClear( cam_velocity );
				} else {
					vec3_t center, forward;
					struct cmodel_s *cmodel;
					const float ft = (float)cg.frameTime * 0.001f;

					// find the trackEnt origin
					VectorLerp( cg_entities[currentcam->trackEnt].prev.origin, cg.lerpfrac, cg_entities[currentcam->trackEnt].current.origin, center );

					// if having a bounding box, look to its center
					if( ( cmodel = CG_CModelForEntity( currentcam->trackEnt ) ) != NULL ) {
						vec3_t mins, maxs;
						trap_CM_InlineModelBounds( cmodel, mins, maxs );
						for( i = 0; i < 3; i++ )
							center[i] += ( mins[i] + maxs[i] );
					}

					if( !cam_orbital_radius ) {
						// cam is just started, find distance from cam to trackEnt and keep it as radius
						VectorSubtract( currentcam->origin, center, forward );
						cam_orbital_radius = VectorNormalize( forward );
						VecToAngles( forward, cam_orbital_angles );
					}

					for( i = 0; i < 3; i++ ) {
						cam_orbital_angles[i] += currentcam->angles[i] * ft;
						cam_orbital_angles[i] = AngleNormalize360( cam_orbital_angles[i] );
					}

					AngleVectors( cam_orbital_angles, forward, NULL, NULL );
					VectorMA( center, cam_orbital_radius, forward, cam_origin );

					// lookat
					VectorInverse( forward );
					VecToAngles( forward, cam_angles );
				}

				// set velocity
				VectorSubtract( cam_origin, v, cam_velocity );
				VectorScale( cam_velocity, 1.0f / ( cg.frameTime * 1000.0f ), cam_velocity );
				break;

			default:
				break;
		}

		if( currentcam->type != DEMOCAM_ORBITAL ) {
			VectorClear( cam_orbital_angles );
			cam_orbital_radius = 0;
		}
	}

	return viewType;
}
Exemple #26
0
/*
* CG_RocketExplosionMode
*/
void CG_RocketExplosionMode( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles, vec;
	vec3_t origin;
	float expvelocity = 8.0f;

	VecToAngles( dir, angles );

	if( fire_mode == FIRE_MODE_STRONG )
	{
		//trap_S_StartSound ( pos, 0, 0, CG_MediaSfx (cgs.media.sfxRocketLauncherStrongHit), cg_volume_effects->value, ATTN_NORM, 0 );
		CG_SpawnDecal( pos, dir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );

	}
	else
	{
		//trap_S_StartSound ( pos, 0, 0, CG_MediaSfx (cgs.media.sfxRocketLauncherWeakHit), cg_volume_effects->value, ATTN_NORM, 0 );
		CG_SpawnDecal( pos, dir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}

	// animmap shader of the explosion
	VectorMA( pos, radius*0.12f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	if( cg_explosionsRing->integer )
	{
		// explosion ring sprite
		VectorMA( pos, radius*0.20f, dir, origin );
		le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius, 3,
			1, 1, 1, 1,
			0, 0, 0, 0, // no dlight
			CG_MediaShader( cgs.media.shaderRocketExplosionRing ) );

		le->ent.rotation = rand() % 360;
	}

	if( cg_explosionsDust->integer == 1 )
	{
		// dust ring parallel to the contact surface
		CG_ExplosionsDust(pos, dir, radius);
	}

	// Explosion particles
	CG_ParticleExplosionEffect( pos, dir, 1, 0.5, 0, 32 );

	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherStrongHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherWeakHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );

	//jalfixme: add sound at water?
}
Exemple #27
0
/*
* CG_BulletExplosion
*/
void CG_BulletExplosion( vec3_t pos, vec_t *dir, trace_t *trace )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t local_dir, end;
	trace_t	local_trace, *tr;

	assert( dir || trace );

	if( dir )
	{
		// find what are we hitting
		tr = &local_trace;
		VectorMA( pos, -1.0, dir, end );
		CG_Trace( tr, pos, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SHOT );
		if( tr->fraction == 1.0 )
			return;
	}
	else
	{
		tr = trace;
		dir = local_dir;
		VectorCopy( tr->plane.normal, dir );
	}

	VecToAngles( dir, angles );

	if( tr->surfFlags & SURF_FLESH ||
		( tr->ent > 0 && cg_entities[tr->ent].current.type == ET_PLAYER ) ||
		( tr->ent > 0 && cg_entities[tr->ent].current.type == ET_CORPSE ) )
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 0, 0, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBulletExplode ),
			NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;
		if( ISVIEWERENTITY( tr->ent ) )
			le->ent.renderfx |= RF_VIEWERMODEL;
	}
	else if( tr->surfFlags & SURF_DUST )
	{
		// throw particles on dust
		CG_ImpactSmokePuff( tr->endpos, tr->plane.normal, 4, 0.6f, 6, 8 );
	}
	else
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 1, 1, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBulletExplode ),
			NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;

		CG_ImpactSmokePuff( tr->endpos, tr->plane.normal, 2, 0.6f, 6, 8 );

		if( !( tr->surfFlags & SURF_NOMARKS ) )
			CG_SpawnDecal( pos, dir, random()*360, 8, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderBulletMark ) );
	}
}
Exemple #28
0
/*
* CG_GrenadeExplosionMode
*/
void CG_GrenadeExplosionMode( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t decaldir;
	vec3_t origin, vec;
	float expvelocity = 8.0f;

	VectorCopy( dir, decaldir );
	VecToAngles( dir, angles );

	//if( CG_PointContents( pos ) & MASK_WATER )
	//jalfixme: (shouldn't we do the water sound variation?)

	if( fire_mode == FIRE_MODE_STRONG )
	{
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}
	else
	{
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}

	// animmap shader of the explosion
	VectorMA( pos, radius*0.15f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	// explosion ring sprite
	if( cg_explosionsRing->integer )
	{
		VectorMA( pos, radius*0.25f, dir, origin );
		le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius, 3,
			1, 1, 1, 1,
			0, 0, 0, 0, // no dlight
			CG_MediaShader( cgs.media.shaderRocketExplosionRing ) );

		le->ent.rotation = rand() % 360;
	}

	if( cg_explosionsDust->integer == 1 )
	{
		// dust ring parallel to the contact surface
		CG_ExplosionsDust(pos, dir, radius);
	}

	// Explosion particles
	CG_ParticleExplosionEffect( pos, dir, 1, 0.5, 0, 32 );	

	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGrenadeStrongExplosion ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGrenadeWeakExplosion ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
}
Exemple #29
0
/*
* W_Fire_Lead
* the seed is important to be as pointer for cgame prediction accuracy
*/
static void W_Fire_Lead( edict_t *self, vec3_t start, vec3_t aimdir, vec3_t axis[3], int damage, 
						int knockback, int stun, int hspread, int vspread, int *seed, int dflags,
						int mod, int timeDelta )
{
	trace_t	tr;
	vec3_t dir;
	vec3_t end;
	float r;
	float u;
	vec3_t water_start;
	int content_mask = MASK_SHOT | MASK_WATER;

	G_Trace4D( &tr, self->s.origin, NULL, NULL, start, self, MASK_SHOT, timeDelta );
	if( !( tr.fraction < 1.0 ) )
	{
#if 1
		// circle
		double alpha = M_PI * Q_crandom( seed ); // [-PI ..+PI]
		double s = fabs( Q_crandom( seed ) ); // [0..1]
		r = s * cos( alpha ) * hspread;
		u = s * sin( alpha ) * vspread;
#else
		// square
		r = Q_crandom( seed ) * hspread;
		u = Q_crandom( seed ) * vspread;
#endif
		VectorMA( start, 8192, axis[0], end );
		VectorMA( end, r, axis[1], end );
		VectorMA( end, u, axis[2], end );

		if( G_PointContents4D( start, timeDelta ) & MASK_WATER )
		{
			VectorCopy( start, water_start );
			content_mask &= ~MASK_WATER;
		}

		G_Trace4D( &tr, start, NULL, NULL, end, self, content_mask, timeDelta );

		// see if we hit water
		if( tr.contents & MASK_WATER )
		{
			VectorCopy( tr.endpos, water_start );

			if( !VectorCompare( start, tr.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 );
#if 1
				// circle
				alpha = M_PI *Q_crandom( seed ); // [-PI ..+PI]
				s = fabs( Q_crandom( seed ) ); // [0..1]
				r = s *cos( alpha )*hspread*1.5;
				u = s *sin( alpha )*vspread*1.5;
#else
				r = Q_crandom( seed ) * hspread * 2;
				u = Q_crandom( seed ) * vspread * 2;
#endif
				VectorMA( water_start, 8192, forward, end );
				VectorMA( end, r, right, end );
				VectorMA( end, u, up, end );
			}

			// re-trace ignoring water this time
			G_Trace4D( &tr, water_start, NULL, NULL, end, self, MASK_SHOT, timeDelta );
		}
	}

	// send gun puff / flash
	if( tr.fraction < 1.0 && tr.ent != -1 )
	{
		if( game.edicts[tr.ent].takedamage )
		{
			G_Damage( &game.edicts[tr.ent], self, self, aimdir, aimdir, tr.endpos, tr.plane.normal, damage, knockback, stun, dflags, mod );
		}
		else
		{
			if( !( tr.surfFlags & SURF_NOIMPACT ) )
			{
			}
		}
	}
}
Exemple #30
0
/*
* CG_AddLocalEntities
*/
void CG_AddLocalEntities( void )
{
#define FADEINFRAMES 2
	int f;
	lentity_t *le, *next, *hnode;
	entity_t *ent;
	float scale, frac, fade, time, scaleIn, fadeIn;
	float backlerp;
	vec3_t angles;

	time = cg.frameTime;
	backlerp = 1.0f - cg.lerpfrac;

	hnode = &cg_localents_headnode;
	for( le = hnode->next; le != hnode; le = next )
	{
		next = le->next;

		frac = ( cg.time - le->start ) * 0.01f;
		f = ( int )floor( frac );
		clamp_low( f, 0 );

		// it's time to DIE
		if( f >= le->frames - 1 )
		{
			le->type = LE_FREE;
			CG_FreeLocalEntity( le );
			continue;
		}

		if( le->frames > 1 )
		{
			scale = 1.0f - frac / ( le->frames - 1 );
			scale = bound( 0.0f, scale, 1.0f );
			fade = scale * 255.0f;

			// quick fade in, if time enough
			if( le->frames > FADEINFRAMES * 2 )
			{
				scaleIn = frac / (float)FADEINFRAMES;
				clamp( scaleIn, 0.0f, 1.0f );
				fadeIn = scaleIn * 255.0f;
			}
			else
				fadeIn = 255.0f;
		}
		else
		{
			scale = 1.0f;
			fade = 255.0f;
			fadeIn = 255.0f;
		}

		ent = &le->ent;

		if( le->light && scale )
			CG_AddLightToScene( ent->origin, le->light * scale, le->lightcolor[0], le->lightcolor[1], le->lightcolor[2], NULL );

		if( le->type == LE_LASER )
		{
			CG_QuickPolyBeam( ent->origin, ent->origin2, ent->radius, ent->customShader ); // wsw : jalfixme: missing the color (comes inside ent->skinnum)
			continue;
		}

		if( le->type == LE_DASH_SCALE )
		{
			if( f < 1 ) ent->scale = 0.2 * frac;
			else
			{
				VecToAngles( ent->axis[1], angles );
				ent->axis[1][1] += 0.005f *sin( DEG2RAD ( angles[YAW] ) ); //length
				ent->axis[1][0] += 0.005f *cos( DEG2RAD ( angles[YAW] ) ); //length
				ent->axis[0][1] += 0.008f *cos( DEG2RAD ( angles[YAW] ) ); //width
				ent->axis[0][0] -= 0.008f *sin( DEG2RAD ( angles[YAW] ) ); //width
				ent->axis[2][2] -= 0.052f;              //height

				if( ent->axis[2][2] <= 0 )
				{
					le->type = LE_FREE;
					CG_FreeLocalEntity( le );
				}
			}
		}
		if( le->type == LE_DASH_SCALE_2 )
		{
			if( f < 1 ) ent->scale = 0.25 * frac;
			else
			{
				VecToAngles( ent->axis[1], angles );
				ent->axis[1][1] += 0.005f *sin( DEG2RAD ( angles[YAW] ) ); //length
				ent->axis[1][0] += 0.005f *cos( DEG2RAD ( angles[YAW] ) ); //length
				ent->axis[0][1] += 0.008f *cos( DEG2RAD ( angles[YAW] ) ); //width
				ent->axis[0][0] -= 0.008f *sin( DEG2RAD ( angles[YAW] ) ); //width
				ent->axis[2][2] -= 0.018f;              //height

				ent->origin[1]  -= 0.6f *sin( DEG2RAD ( angles[YAW] ) ); //velocity
				ent->origin[0]  -= 0.6f *cos( DEG2RAD ( angles[YAW] ) ); //velocity

				if( ent->axis[2][2] <= 0 )
				{
					le->type = LE_FREE;
					CG_FreeLocalEntity( le );
				}
			}
		}
		if( le->type == LE_PUFF_SCALE )
		{
			if( frac < 1 ) ent->scale = 7.0f*frac;
			else ent->scale = 7.0f - 4.0f*( frac-1 );
			if( ent->scale < 0 )
			{
				le->type = LE_FREE;
				CG_FreeLocalEntity( le );
			}

		}
		if( le->type == LE_PUFF_SCALE_2 )
		{
			if( le->frames - f < 4 )
				ent->scale = 1.0f - 1.0f * ( frac - abs( 4-le->frames ) )/4;
		}
		if( le->type == LE_PUFF_SHRINK )
		{
			if( frac < 3 )
				ent->scale = 1.0f - 0.2f * frac/4;
			else
			{
				ent->scale = 0.8 - 0.8*( frac-3 )/3;
				VectorScale( le->velocity, 0.85f, le->velocity );
			}
		}

		if( le->type == LE_EXPLOSION_TRACER )
		{
			if( cg.time - ent->rotation > 10.0f )
			{
				ent->rotation = cg.time;
				if( ent->radius - 16*frac > 4 )
					CG_Explosion_Puff( ent->origin, ent->radius-16*frac, le->frames - f );
			}
		}

		switch( le->type )
		{
		case LE_NO_FADE:
			break;
		case LE_RGB_FADE:
			fade = min( fade, fadeIn );
			ent->shaderRGBA[0] = ( qbyte )( fade * le->color[0] );
			ent->shaderRGBA[1] = ( qbyte )( fade * le->color[1] );
			ent->shaderRGBA[2] = ( qbyte )( fade * le->color[2] );
			break;
		case LE_SCALE_ALPHA_FADE:
			fade = min( fade, fadeIn );
			ent->scale = 1.0f + 1.0f / scale;
			ent->scale = min( ent->scale, 5.0f );
			ent->shaderRGBA[3] = ( qbyte )( fade * le->color[3] );
			break;
		case LE_INVERSESCALE_ALPHA_FADE:
			fade = min( fade, fadeIn );
			ent->scale = scale + 0.1f;
			clamp( ent->scale, 0.1f, 1.0f );
			ent->shaderRGBA[3] = ( qbyte )( fade * le->color[3] );
			break;
		case LE_ALPHA_FADE:
			fade = min( fade, fadeIn );
			ent->shaderRGBA[3] = ( qbyte )( fade * le->color[3] );
			break;
		default:
			break;
		}

		ent->backlerp = backlerp;

		if( le->bounce )
		{
			trace_t	trace;
			vec3_t next_origin;

			VectorMA( ent->origin, time, le->velocity, next_origin );

			CG_Trace( &trace, ent->origin, debris_mins, debris_maxs, next_origin, 0, MASK_SOLID );

			// remove the particle when going out of the map
			if( ( trace.contents & CONTENTS_NODROP ) || ( trace.surfFlags & SURF_SKY ) )
			{
				le->frames = 0;
			}
			else if( trace.fraction != 1.0 ) // found solid
			{
				float dot;
				vec3_t vel;
				float xzyspeed;

				// Reflect velocity
				VectorSubtract( next_origin, ent->origin, vel );
				dot = -2 *DotProduct( vel, trace.plane.normal );
				VectorMA( vel, dot, trace.plane.normal, le->velocity );
				//put new origin in the impact point, but move it out a bit along the normal
				VectorMA( trace.endpos, 1, trace.plane.normal, ent->origin );

				//the entity has not speed enough. Stop checks
				xzyspeed = sqrt( le->velocity[0]*le->velocity[0] + le->velocity[1]*le->velocity[1] + le->velocity[2]*le->velocity[2] );
				if( xzyspeed * time < 1.0f )
				{
					trace_t traceground;
					vec3_t ground_origin;
					//see if we have ground
					VectorCopy( ent->origin, ground_origin );
					ground_origin[2] += ( debris_mins[2] - 4 );
					CG_Trace( &traceground, ent->origin, debris_mins, debris_maxs, ground_origin, 0, MASK_SOLID );
					if( traceground.fraction != 1.0 )
					{
						le->bounce = qfalse;
						VectorClear( le->velocity );
						VectorClear( le->accel );
						if( le->type == LE_EXPLOSION_TRACER )
						{               // blx
							le->type = LE_FREE;
							CG_FreeLocalEntity( le );
						}
					}
				}
				else
					VectorScale( le->velocity, le->bounce * time, le->velocity );
			}
			else
			{
				VectorCopy( ent->origin, ent->origin2 );
				VectorCopy( next_origin, ent->origin );
			}
		}
		else
		{
			VectorCopy( ent->origin, ent->origin2 );
			VectorMA( ent->origin, time, le->velocity, ent->origin );
		}

		VectorCopy( ent->origin, ent->lightingOrigin );
		VectorMA( le->velocity, time, le->accel, le->velocity );

		CG_AddEntityToScene( ent );
	}
}