Example #1
0
void CG_CameraParse( void )
{
	const char *o;
	int int_data;
	vec3_t vector_data, vector2_data;
	float float_data, float2_data;
	vec4_t color, color2;
	int CGroup[16];

	o = CG_ConfigString( CS_CAMERA );
	if(strncmp("enable", o, 6) == 0)
	{
		CGCam_Enable();
	}
	else if(strncmp("move", o, 4) == 0)
	{
		sscanf(o, "%*s %f %f %f %f", &vector_data[0], &vector_data[1], &vector_data[2], &float_data);
		CGCam_Move(vector_data, float_data);
	}
	else if(strncmp("pan", o, 3) == 0)
	{
		sscanf(o, "%*s %f %f %f %f %f %f %f", &vector_data[0], &vector_data[1], 
			&vector_data[2], &vector2_data[0], &vector2_data[1], &vector2_data[2], &float_data);
		CGCam_Pan(vector_data, vector2_data, float_data);
	}
	else if(strncmp("fade", o, 4) == 0)
	{
		sscanf(o, "%*s %f %f %f %f %f %f %f %f %f", &color[0],
		&color[1], &color[2], &color[3], &color2[0], &color2[1], &color2[2], &color2[3], 
		&float_data);
		CGCam_Fade(color, color2, float_data);
	}
	else if(strncmp("zoom", o, 4) == 0)
	{
		sscanf(o, "%*s %f %f", &float_data, &float2_data);
		CGCam_Zoom(float_data, float2_data);
	}
	else if(strncmp("disable", o, 7) == 0)
	{
		CGCam_Disable();
	}
	else if(strncmp("shake", o, 5) == 0)
	{
		sscanf(o, "%*s %f %i", &float_data, &int_data);
		CGCam_Shake(float_data, int_data);
	}
	else if(strncmp("follow", o, 6) == 0)
	{
		sscanf(o, "%*s %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %f %f", &CGroup[0], 
			&CGroup[1], &CGroup[2], &CGroup[3], &CGroup[4], &CGroup[5], &CGroup[6], 
		&CGroup[7], &CGroup[8], &CGroup[9], &CGroup[10], &CGroup[11], &CGroup[12], &CGroup[13],
		&CGroup[14], &CGroup[15], &float_data, &float2_data);
		CGCam_Follow(CGroup, float_data, float2_data);
	}
	else
	{
		CG_Printf("Bad CS_CAMERA configstring in CG_CameraParse().\n");
	}
}
Example #2
0
void SandCreature_MoveEffect( void )
{
	vec3_t	up = {0,0,1};
	vec3_t	org = {NPC->currentOrigin[0], NPC->currentOrigin[1], NPC->absmin[2]+2};

	float playerDist = Distance( player->currentOrigin, NPC->currentOrigin );
	if ( playerDist < 256 )
	{
		CGCam_Shake( 0.75f*playerDist/256.0f, 250 );
	}

	if ( level.time-NPC->client->ps.lastStationary > 2000 )
	{//first time moving for at least 2 seconds
		//clear speakingtime
		TIMER_Set( NPC, "speaking", -level.time );
	}

	if ( TIMER_Done( NPC, "breaching" )
		&& TIMER_Done( NPC, "breachDebounce" )
		&& TIMER_Done( NPC, "pain" )
		&& TIMER_Done( NPC, "attacking" )
		&& !Q_irand( 0, 10 ) )
	{//Breach!
		//FIXME: only do this while moving forward?
		trace_t	trace;
		//make him solid here so he can be hit/gets blocked on stuff. Check clear first.
		gi.trace( &trace, NPC->currentOrigin, NPC->mins, NPC->maxs, NPC->currentOrigin, NPC->s.number, MASK_NPCSOLID, (EG2_Collision)0, 0 );
		if ( !trace.allsolid && !trace.startsolid )
		{
			NPC->clipmask = MASK_NPCSOLID;//turn solid for a little bit
			NPC->contents = CONTENTS_BODY;
			//NPC->takedamage = qtrue;//can be shot?

			//FIXME: Breach sound?
			//FIXME: Breach effect?
			NPC_SetAnim( NPC, SETANIM_LEGS, BOTH_WALK2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
			TIMER_Set( NPC, "breaching", NPC->client->ps.legsAnimTimer );
			TIMER_Set( NPC, "breachDebounce", NPC->client->ps.legsAnimTimer+Q_irand( 0, 10000 ) );
		}
	}
	if ( !TIMER_Done( NPC, "breaching" ) )
	{//different effect when breaching
		//FIXME: make effect
		G_PlayEffect( G_EffectIndex( "env/sand_move_breach" ), org, up );
	}
	else
	{
		G_PlayEffect( G_EffectIndex( "env/sand_move" ), org, up );
	}
	NPC->s.loopSound = G_SoundIndex( "sound/chars/sand_creature/slither.wav" );
}
Example #3
0
void NPC_SandCreature_Pain( gentity_t *self, gentity_t *inflictor, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc )
{
	if ( TIMER_Done( self, "pain" ) )
	{
		//FIXME: effect and sound
		//FIXME: shootable during this anim?
		NPC_SetAnim( self, SETANIM_LEGS, Q_irand(BOTH_ATTACK1,BOTH_ATTACK2), SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
		G_AddEvent( self, EV_PAIN, Q_irand( 0, 100 ) );
		TIMER_Set( self, "pain", self->client->ps.legsAnimTimer + Q_irand( 500, 2000 ) );
		float playerDist = Distance( player->currentOrigin, self->currentOrigin );
		if ( playerDist < 256 )
		{
			CGCam_Shake( 1.0f*playerDist/128.0f, self->client->ps.legsAnimTimer );
		}
	}
	self->enemy = self->NPC->goalEntity = NULL;
}
Example #4
0
void CG_ExplosionEffects( vec3_t origin, float intensity, int radius, int time )
{
	//FIXME: When exactly is the vieworg calculated in relation to the rest of the frame?s

	vec3_t	dir;
	float	dist, intensityScale;
	float	realIntensity;

	VectorSubtract( cg.refdef.vieworg, origin, dir );
	dist = VectorNormalize( dir );

	//Use the dir to add kick to the explosion

	if ( dist > radius )
		return;

	intensityScale = 1 - ( dist / (float) radius );
	realIntensity = intensity * intensityScale;

	CGCam_Shake( realIntensity, time );
}
Example #5
0
static void Howler_Howl( void )
{
	gentity_t	*radiusEnts[ 128 ];
	int			numEnts;
	const float	radius = (NPC->spawnflags&1)?256:128;
	const float	halfRadSquared = ((radius/2)*(radius/2));
	const float	radiusSquared = (radius*radius);
	float		distSq;
	int			i;
	vec3_t		boltOrg;

	AddSoundEvent( NPC, NPC->currentOrigin, 512, AEL_DANGER, qfalse, qtrue );

	numEnts = NPC_GetEntsNearBolt( radiusEnts, radius, NPC->handLBolt, boltOrg );

	for ( i = 0; i < numEnts; i++ )
	{
		if ( !radiusEnts[i]->inuse )
		{
			continue;
		}
		
		if ( radiusEnts[i] == NPC )
		{//Skip the rancor ent
			continue;
		}
		
		if ( radiusEnts[i]->client == NULL )
		{//must be a client
			continue;
		}

		if ( radiusEnts[i]->client->NPC_class == CLASS_HOWLER )
		{//other howlers immune
			continue;
		}

		distSq = DistanceSquared( radiusEnts[i]->currentOrigin, boltOrg );
		if ( distSq <= radiusSquared )
		{
			if ( distSq < halfRadSquared )
			{//close enough to do damage, too
				if ( Q_irand( 0, g_spskill->integer ) )
				{//does no damage on easy, does 1 point every other frame on medium, more often on hard
					G_Damage( radiusEnts[i], NPC, NPC, vec3_origin, NPC->currentOrigin, 1, DAMAGE_NO_KNOCKBACK, MOD_IMPACT );
				}
			}
			if ( radiusEnts[i]->health > 0 
				&& radiusEnts[i]->client
				&& radiusEnts[i]->client->NPC_class != CLASS_RANCOR
				&& radiusEnts[i]->client->NPC_class != CLASS_ATST 
				&& !PM_InKnockDown( &radiusEnts[i]->client->ps ) )
			{
				if ( PM_HasAnimation( radiusEnts[i], BOTH_SONICPAIN_START ) )
				{
					if ( radiusEnts[i]->client->ps.torsoAnim != BOTH_SONICPAIN_START 
						&& radiusEnts[i]->client->ps.torsoAnim != BOTH_SONICPAIN_HOLD )
					{
						NPC_SetAnim( radiusEnts[i], SETANIM_LEGS, BOTH_SONICPAIN_START, SETANIM_FLAG_NORMAL );
						NPC_SetAnim( radiusEnts[i], SETANIM_TORSO, BOTH_SONICPAIN_START, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
						radiusEnts[i]->client->ps.torsoAnimTimer += 100;
						radiusEnts[i]->client->ps.weaponTime = radiusEnts[i]->client->ps.torsoAnimTimer;
					}
					else if ( radiusEnts[i]->client->ps.torsoAnimTimer <= 100 )
					{//at the end of the sonic pain start or hold anim
						NPC_SetAnim( radiusEnts[i], SETANIM_LEGS, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_NORMAL );
						NPC_SetAnim( radiusEnts[i], SETANIM_TORSO, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
						radiusEnts[i]->client->ps.torsoAnimTimer += 100; 
						radiusEnts[i]->client->ps.weaponTime = radiusEnts[i]->client->ps.torsoAnimTimer;
					}
				}
				/*
				else if ( distSq < halfRadSquared 
					&& radiusEnts[i]->client->ps.groundEntityNum != ENTITYNUM_NONE 
					&& !Q_irand( 0, 10 ) )//FIXME: base on skill
				{//within range
					G_Knockdown( radiusEnts[i], NPC, vec3_origin, 500, qfalse );
				}
				*/
			}
		}
	}

	float playerDist = NPC_EntRangeFromBolt( player, NPC->genericBolt1 );
	if ( playerDist < 256.0f )
	{
		CGCam_Shake( 1.0f*playerDist/128.0f, 200 );
	}
}
Example #6
0
void SandCreature_Attack( qboolean miss )
{
	//FIXME: make it able to grab a thermal detonator, take it down,
	//		then have it explode inside them, killing them
	//		(or, do damage, making them stick half out of the ground and
	//		screech for a bit, giving you a chance to run for it!)

	//FIXME: effect and sound
	//FIXME: shootable during this anim?
	if ( !NPC->enemy->client )
	{
		NPC_SetAnim( NPC, SETANIM_LEGS, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
	}
	else
	{
		NPC_SetAnim( NPC, SETANIM_LEGS, Q_irand( BOTH_ATTACK1, BOTH_ATTACK2 ), SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
	}
	//don't do anything else while in this anim
	TIMER_Set( NPC, "attacking", NPC->client->ps.legsAnimTimer );
	float playerDist = Distance( player->currentOrigin, NPC->currentOrigin );
	if ( playerDist < 256 )
	{
		//FIXME: tone this down
		CGCam_Shake( 0.75f*playerDist/128.0f, NPC->client->ps.legsAnimTimer );
	}

	if ( miss )
	{//purposely missed him, chance of knocking him down
		//FIXME: if, during the attack anim, I do end up catching him close to my mouth, then snatch him anyway...
		if ( NPC->enemy && NPC->enemy->client )
		{
			vec3_t dir2Enemy;
			VectorSubtract( NPC->enemy->currentOrigin, NPC->currentOrigin, dir2Enemy );
			if ( dir2Enemy[2] < 30 )
			{
				dir2Enemy[2] = 30;
			}
			if ( g_spskill->integer > 0 )
			{
				float enemyDist = VectorNormalize( dir2Enemy );
				//FIXME: tone this down, smaller radius
				if ( enemyDist < 200 && NPC->enemy->client->ps.groundEntityNum != ENTITYNUM_NONE )
				{
					float throwStr = ((200-enemyDist)*0.4f)+20;
					if ( throwStr > 45 )
					{
						throwStr = 45;
					}
					G_Throw( NPC->enemy, dir2Enemy, throwStr );
					if ( g_spskill->integer > 1 )
					{//knock them down, too
						if ( NPC->enemy->health > 0
							&& Q_flrand( 50, 150 ) > enemyDist )
						{//knock them down
							G_Knockdown( NPC->enemy, NPC, dir2Enemy, 300, qtrue );
							if ( NPC->enemy->s.number < MAX_CLIENTS )
							{//make the player look up at me
								vec3_t vAng;
								vectoangles( dir2Enemy, vAng );
								VectorSet( vAng, AngleNormalize180(vAng[PITCH])*-1, NPC->enemy->client->ps.viewangles[YAW], 0 );
								SetClientViewAngle( NPC->enemy, vAng );
							}
						}
					}
				}
			}
		}
	}
	else
	{
		NPC->enemy->activator = NPC; // kind of dumb, but when we are locked to the Rancor, we are owned by it.
		NPC->activator = NPC->enemy;//remember him
		//this guy isn't going anywhere anymore
		NPC->enemy->contents = 0;
		NPC->enemy->clipmask = 0;

		if ( NPC->activator->client )
		{
			NPC->activator->client->ps.SaberDeactivate();
			NPC->activator->client->ps.eFlags |= EF_HELD_BY_SAND_CREATURE;
			if ( NPC->activator->health > 0 && NPC->activator->client )
			{
				G_AddEvent( NPC->activator, Q_irand(EV_DEATH1, EV_DEATH3), 0 );
				NPC_SetAnim( NPC->activator, SETANIM_LEGS, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				NPC_SetAnim( NPC->activator, SETANIM_TORSO, BOTH_FALLDEATH1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				TossClientItems( NPC );
				if ( NPC->activator->NPC )
				{//no more thinking for you
					NPC->activator->NPC->nextBStateThink = Q3_INFINITE;
				}
			}
			/*
			if ( !NPC->activator->s.number )
			{
				cg.overrides.active |= (CG_OVERRIDE_3RD_PERSON_CDP|CG_OVERRIDE_3RD_PERSON_RNG);
				cg.overrides.thirdPersonCameraDamp = 0;
				cg.overrides.thirdPersonRange = 120;
			}
			*/
		}
		else
		{
			NPC->activator->s.eFlags |= EF_HELD_BY_SAND_CREATURE;
		}
	}
}
Example #7
0
// Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
// The main player will have this called for BOTH cases, so effects like light and sound should only be done on the
//	world model case.
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent, int team, vector3 *newAngles, qboolean thirdPerson ) {
	refEntity_t gun, barrel, flash;
	vector3 angles;
	weapon_t weaponNum;
	weaponInfo_t *weapon;
	centity_t *nonPredictedCent;

	if ( !thirdPerson && cg_fakeGun.integer ) {
		weaponNum = (weapon_t)cg_fakeGun.integer;
	}
	else {
		weaponNum = (weapon_t)cent->currentState.weapon;
	}

	if ( weaponNum == WP_EMPLACED_GUN )
		return;

	// spectator mode, don't draw it...
	if ( cg.predictedPlayerState.pm_type == PM_SPECTATOR
		&& cent->currentState.number == cg.predictedPlayerState.clientNum )
	{
		return;
	}

	CG_RegisterWeapon( weaponNum );
	weapon = &cg_weapons[weaponNum];

	memset( &gun, 0, sizeof(gun) );

	// only do this if we are in first person, since world weapons are now handled on the server by Ghoul2
	if ( !thirdPerson ) {
		// add the weapon
		VectorCopy( &parent->lightingOrigin, &gun.lightingOrigin );
		gun.shadowPlane = parent->shadowPlane;
		gun.renderfx = parent->renderfx;

		// this player, in first person view
		if ( ps )
			gun.hModel = weapon->viewModel;
		else
			gun.hModel = weapon->weaponModel;
		if ( !gun.hModel )
			return;

		if ( !ps ) {
			// add weapon ready sound
			if ( (cent->currentState.eFlags & EF_FIRING) && weapon->firingSound ) {
				trap->S_AddLoopingSound( cent->currentState.number, &cent->lerpOrigin, &vec3_origin,
					weapon->firingSound
				);
			}
			else if ( weapon->readySound ) {
				trap->S_AddLoopingSound( cent->currentState.number, &cent->lerpOrigin, &vec3_origin,
					weapon->readySound
				);
			}
		}

		CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" );

		if ( !CG_IsMindTricked( cent->currentState.trickedEntIndex, cg.snap->ps.clientNum ) ) {
			// don't draw the weapon if the player is invisible
			CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );
		}

		if ( weaponNum == WP_STUN_BATON ) {
			int i;

			for ( i = 0; i < 3; i++ ) {
				memset( &barrel, 0, sizeof(barrel) );
				VectorCopy( &parent->lightingOrigin, &barrel.lightingOrigin );
				barrel.shadowPlane = parent->shadowPlane;
				barrel.renderfx = parent->renderfx;

				if ( i == 0 ) {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel.md3" );
				}
				else if ( i == 1 ) {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel2.md3" );
				}
				else {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel3.md3" );
				}
				angles.yaw = 0;
				angles.pitch = 0;
				angles.roll = 0;

				AnglesToAxis( &angles, barrel.axis );

				if ( i == 0 ) {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" );
				}
				else if ( i == 1 ) {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel2" );
				}
				else {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel3" );
				}
				CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
			}
		}
		else {
			// add the spinning barrel
			if ( weapon->barrelModel ) {
				memset( &barrel, 0, sizeof(barrel) );
				VectorCopy( &parent->lightingOrigin, &barrel.lightingOrigin );
				barrel.shadowPlane = parent->shadowPlane;
				barrel.renderfx = parent->renderfx;

				barrel.hModel = weapon->barrelModel;
				angles.yaw = 0;
				angles.pitch = 0;
				angles.roll = 0;

				AnglesToAxis( &angles, barrel.axis );

				CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" );

				CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
			}
		}
	}

	memset( &flash, 0, sizeof(flash) );
	CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash" );

	VectorCopy( &flash.origin, &cg.lastFPFlashPoint );

	// Do special charge bits
	// Make the guns do their charging visual in True View.
	if ( (ps || cg.renderingThirdPerson || cg.predictedPlayerState.clientNum != cent->currentState.number || cg_trueGuns.integer) &&
		((cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_PISTOL) ||
		(cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_OLD) ||
		(weaponNum == WP_BOWCASTER && cent->currentState.modelindex2 == WEAPON_CHARGING) ||
		(weaponNum == WP_DEMP2 && cent->currentState.modelindex2 == WEAPON_CHARGING_ALT)) ) {
		int shader = 0;
		float val = 0.0f;
		float scale = 1.0f;
		addspriteArgStruct_t fxSArgs;
		vector3 flashorigin, flashdir;

		if ( !thirdPerson ) {
			VectorCopy( &flash.origin, &flashorigin );
			VectorCopy( &flash.axis[0], &flashdir );
		}
		else {
			mdxaBone_t boltMatrix;

			// it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case
			if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) )
				return;

			// Couldn't find bolt point.
			if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, &cent->lerpOrigin, cg.time,
				cgs.gameModels, &cent->modelScale ) ) {
				return;
			}

			BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin );
			BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir );
		}

		if ( weaponNum == WP_BRYAR_PISTOL || weaponNum == WP_BRYAR_OLD ) {
			// Hardcoded max charge time of 1 second
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.bryarFrontFlash;
		}
		else if ( weaponNum == WP_BOWCASTER ) {
			// Hardcoded max charge time of 1 second
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.greenFrontFlash;
		}
		else if ( weaponNum == WP_DEMP2 ) {
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.lightningFlash;
			scale = 1.75f;
		}

		if ( val < 0.0f )
			val = 0.0f;
		else if ( val > 1.0f ) {
			val = 1.0f;
			if ( ps && cent->currentState.number == ps->clientNum )
				CGCam_Shake( 0.2f, 100 );
		}
		else if ( ps && cent->currentState.number == ps->clientNum )
			CGCam_Shake( val * val * 0.6f, 100 );

		val += random() * 0.5f;

		VectorCopy( &flashorigin, &fxSArgs.origin );
		VectorClear( &fxSArgs.vel );
		VectorClear( &fxSArgs.accel );
		fxSArgs.scale = 3.0f*val*scale;
		fxSArgs.dscale = 0.0f;
		fxSArgs.sAlpha = 0.7f;
		fxSArgs.eAlpha = 0.7f;
		fxSArgs.rotation = random() * 360;
		fxSArgs.bounce = 0.0f;
		fxSArgs.life = 1.0f;
		fxSArgs.shader = shader;
		fxSArgs.flags = 0x08000000;

		trap->FX_AddSprite( &fxSArgs );
	}

	// make sure we aren't looking at cg.predictedPlayerEntity for LG
	nonPredictedCent = &cg_entities[cent->currentState.clientNum];

	// if the index of the nonPredictedCent is not the same as the clientNum then this is a fake player (like on the
	//	single player podiums), so go ahead and use the cent
	if ( nonPredictedCent - cg_entities != cent->currentState.clientNum )
		nonPredictedCent = cent;

	// add the flash
	if ( weaponNum != WP_DEMP2 || (nonPredictedCent->currentState.eFlags & EF_FIRING) ) {
		// impulse flash
		if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME )
			return;
	}

	if ( ps || cg.renderingThirdPerson || cg_trueGuns.integer
		|| cent->currentState.number != cg.predictedPlayerState.clientNum ) {
		// Make sure we don't do the thirdperson model effects for the local player if we're in first person
		vector3 flashorigin, flashdir;
		refEntity_t	tpflash;

		memset( &tpflash, 0, sizeof(tpflash) );

		if ( !thirdPerson ) {
			CG_PositionEntityOnTag( &tpflash, &gun, gun.hModel, "tag_flash" );
			VectorCopy( &tpflash.origin, &flashorigin );
			VectorCopy( &tpflash.axis[0], &flashdir );
		}
		else {
			mdxaBone_t boltMatrix;

			// it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case
			if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) )
				return;

			// Couldn't find bolt point.
			if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, &cent->lerpOrigin, cg.time, cgs.gameModels, &cent->modelScale ) )
				return;

			BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin );
			BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir );
		}

		if ( cg.time - cent->muzzleFlashTime <= MUZZLE_FLASH_TIME + 10 ) {
			// Handle muzzle flashes
			if ( cent->currentState.eFlags & EF_ALT_FIRING ) {
				// Check the alt firing first.
				if ( weapon->altMuzzleEffect ) {
					if ( !thirdPerson )
						trap->FX_PlayEntityEffectID( weapon->altMuzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 );
					else
						trap->FX_PlayEffectID( weapon->altMuzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse );
				}
			}
			else {
				// Regular firing
				if ( weapon->muzzleEffect ) {
					if ( !thirdPerson )
						trap->FX_PlayEntityEffectID( weapon->muzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 );
					else
						trap->FX_PlayEffectID( weapon->muzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse );
				}
			}
		}

		if ( weapon->flashDlightColor.r || weapon->flashDlightColor.g || weapon->flashDlightColor.b ) {
			trap->R_AddLightToScene( &flashorigin, 300 + (rand() & 31), weapon->flashDlightColor.r, weapon->flashDlightColor.g,
				weapon->flashDlightColor.b );
		}
	}
}
Example #8
0
// Caused by an EV_FIRE_WEAPON event
void CG_FireWeapon( centity_t *cent, qboolean altFire ) {
	entityState_t *ent;
	int c;
	weaponInfo_t *weap;

	ent = &cent->currentState;
	if ( ent->weapon == WP_NONE )
		return;
	if ( ent->weapon >= WP_NUM_WEAPONS ) {
		trap->Error( ERR_DROP, "CG_FireWeapon: ent->weapon >= WP_NUM_WEAPONS" );
		return;
	}
	weap = &cg_weapons[ent->weapon];

	// mark the entity as muzzle flashing, so when it is added it will append the flash to the weapon model
	cent->muzzleFlashTime = cg.time;

	if ( cg.predictedPlayerState.clientNum == cent->currentState.number ) {
		if ( (altFire && (ent->weapon == WP_BRYAR_PISTOL || ent->weapon == WP_BRYAR_OLD || ent->weapon == WP_DEMP2)) ||
			(!altFire && ent->weapon == WP_BOWCASTER) ) {
			float val = (cg.time - cent->currentState.constantLight) * 0.001f;

			if ( val > 3 )
				val = 3;
			if ( val < 0.2f )
				val = 0.2f;

			val *= 2;

			CGCam_Shake( val, 250 );
		}
		else if ( ent->weapon == WP_ROCKET_LAUNCHER ||
			(ent->weapon == WP_REPEATER && altFire) ||
			ent->weapon == WP_FLECHETTE ||
			(ent->weapon == WP_CONCUSSION && !altFire) ) {
			if ( ent->weapon == WP_CONCUSSION ) {
				// gives an advantage to being in 3rd person, but would look silly otherwise
				if ( !cg.renderingThirdPerson ) {
					// kick the view back
					cg.kick_angles.pitch = flrand( -10, -15 );
					cg.kick_time = cg.time;
				}
			}
			else if ( ent->weapon == WP_ROCKET_LAUNCHER )
				CGCam_Shake( flrand( 2, 3 ), 350 );
			else if ( ent->weapon == WP_REPEATER )
				CGCam_Shake( flrand( 2, 3 ), 350 );
			else if ( ent->weapon == WP_FLECHETTE ) {
				if ( altFire )
					CGCam_Shake( flrand( 2, 3 ), 350 );
				else
					CGCam_Shake( 1.5f, 250 );
			}
		}
	}

	// play quad sound if needed
	if ( cent->currentState.powerups & (1 << PW_QUAD) ) {
		//	trap->S_StartSound( NULL, cent->currentState.number, CHAN_ITEM, media.snd.quad );
	}

	// play a sound
	if ( altFire ) {
		// play a sound
		for ( c = 0; c<4; c++ ) {
			if ( !weap->altFlashSound[c] )
				break;
		}
		if ( c > 0 ) {
			c = rand() % c;
			if ( weap->altFlashSound[c] )
				trap->S_StartSound( NULL, ent->number, CHAN_WEAPON, weap->altFlashSound[c] );
		}
	}
	else {
		// play a sound
		for ( c = 0; c<4; c++ ) {
			if ( !weap->flashSound[c] )
				break;
		}
		if ( c > 0 ) {
			c = rand() % c;
			if ( weap->flashSound[c] )
				trap->S_StartSound( NULL, ent->number, CHAN_WEAPON, weap->flashSound[c] );
		}
	}
}