Esempio n. 1
0
void AvHBaseBuildable::UpdateDamageEffects()
{
	if(GetGameRules()->GetGameStarted() && this->GetIsBuilt())
	{
		// Add special effects for structures that are hurt or almost dead
		float theMaxHealth = GetGameRules()->GetBaseHealthForMessageID(this->GetMessageID());
		float theHealthScalar = this->pev->health/theMaxHealth;
		float theTimeInterval = max(gpGlobals->time - this->mTimeOfLastDamageUpdate, .1f);

		const float kParticleSystemLifetime = 5.0f;
		int theAverageSoundInterval = -1;
		
		// If we're at 25% health or less, emit black smoke
		if(gpGlobals->time > (this->mTimeOfLastDamageEffect + kParticleSystemLifetime))
		{
			if(theHealthScalar < .25f)
			{
				AvHSUPlayParticleEvent(kpsBuildableLightDamage, this->edict(), this->pev->origin);
				this->mTimeOfLastDamageEffect = gpGlobals->time;
				theAverageSoundInterval = 3;
			}
			// If we're at 50% health or less, emit light smoke
			else if(theHealthScalar < .5f)
			{
				AvHSUPlayParticleEvent(kpsBuildableLightDamage, this->edict(), this->pev->origin);
				this->mTimeOfLastDamageEffect = gpGlobals->time;
				theAverageSoundInterval = 5;
			}
		}
		
		// If we're at less then 75% health, spark occasionally
		if(theHealthScalar < .75f)
		{
			int theRandomChance = RANDOM_LONG(0, (float)8/theTimeInterval);
			if(theRandomChance == 0)
			{
				UTIL_Sparks(this->pev->origin);
				UTIL_Sparks(this->pev->origin);

				const char* theHurtSoundToPlay = kBuildableHurt1Sound;
				if(RANDOM_LONG(0, 1) == 1)
				{
					theHurtSoundToPlay = kBuildableHurt2Sound;
				}
				
				float theVolume = .3f;
				EMIT_SOUND(this->edict(), CHAN_AUTO, theHurtSoundToPlay, theVolume, ATTN_NORM);
			}
		}
		
		this->mTimeOfLastDamageUpdate = gpGlobals->time;
	}
}
Esempio n. 2
0
void CBeam::DoSparks( const Vector &start, const Vector &end )
{
	if( pev->spawnflags & ( SF_BEAM_SPARKSTART | SF_BEAM_SPARKEND ) )
	{
		if( pev->spawnflags & SF_BEAM_SPARKSTART )
		{
			UTIL_Sparks( start );
		}
		if( pev->spawnflags & SF_BEAM_SPARKEND )
		{
			UTIL_Sparks( end );
		}
	}
}
Esempio n. 3
0
void CFuncLight :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
	if( pev->takedamage == DAMAGE_NO )
		return;

	if( m_iState == STATE_DEAD )
		return;

	const char *pTextureName = NULL;
	Vector start = pevAttacker->origin + pevAttacker->view_ofs;
	Vector end = start + vecDir * 1024;
	edict_t *pHit = ptr->pHit;

	if( pHit )
		pTextureName = TRACE_TEXTURE( pHit, start, end );

	if( pTextureName != NULL && ( !Q_strncmp( pTextureName, "+0~", 3 ) || *pTextureName == '~' ))
	{
		// take damage only at light texture
		UTIL_Sparks( ptr->vecEndPos );
		m_vecLastDmgPoint = ptr->vecEndPos;
	}

	CBreakable::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
Esempio n. 4
0
//=========================================================
// FScheduleValid - returns TRUE as long as the current
// schedule is still the proper schedule to be executing,
// taking into account all conditions
//=========================================================
BOOL CBaseMonster :: FScheduleValid ( void )
{
	if ( m_pSchedule == NULL )
	{
		// schedule is empty, and therefore not valid.
		return FALSE;
	}

	if ( HasConditions( m_pSchedule->iInterruptMask | bits_COND_SCHEDULE_DONE | bits_COND_TASK_FAILED ) )
	{
#ifdef DEBUG
		if ( HasConditions ( bits_COND_TASK_FAILED ) && m_failSchedule == SCHED_NONE )
		{
			// fail! Send a visual indicator.
			Vector tmp = pev->origin;
			tmp.z = pev->absmax.z + 16;
			UTIL_Sparks( tmp );
		}
#endif // DEBUG

		// some condition has interrupted the schedule, or the schedule is done
		return FALSE;
	}
	
	return TRUE;
}
Esempio n. 5
0
void CBreakable::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
	// random spark if this is a 'computer' object
	if (RANDOM_LONG(0,1) )
	{
		switch( m_Material )
		{
			case matComputer:
			{
				UTIL_Sparks( ptr->vecEndPos );

				float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range
				switch ( RANDOM_LONG(0,1) )
				{
					case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM);	break;
					case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM);	break;
				}
			}
			break;
			
			case matUnbreakableGlass:
				UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) );
			break;
		}
	}

	CBaseDelay::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
Esempio n. 6
0
void COsprey::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
	// ALERT( at_console, "%d %.0f\n", ptr->iHitgroup, flDamage );

	// only so much per engine
	if (ptr->iHitgroup == 3)
	{
		if (m_flRightHealth < 0)
			return;
		else
			m_flRightHealth -= flDamage;
		m_iDoLeftSmokePuff = 3 + (flDamage / 5.0);
	}

	if (ptr->iHitgroup == 2)
	{
		if (m_flLeftHealth < 0)
			return;
		else
			m_flLeftHealth -= flDamage;
		m_iDoRightSmokePuff = 3 + (flDamage / 5.0);
	}

	// hit hard, hits cockpit, hits engines
	if (flDamage > 50 || ptr->iHitgroup == 1 || ptr->iHitgroup == 2 || ptr->iHitgroup == 3)
	{
		// ALERT( at_console, "%.0f\n", flDamage );
		AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType );
	}
	else
	{
		UTIL_Sparks( ptr->vecEndPos );
	}
}
Esempio n. 7
0
void DoSpark(entvars_t *pev, const Vector &location)
{
	Vector tmp = location + pev->size * 0.5;
	UTIL_Sparks(tmp);

	float flVolume = RANDOM_FLOAT(0.25, 0.75) * 0.4; //random volume range
	switch((int)(RANDOM_FLOAT(0, 1) * 6))
	{
	case 0:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark1.wav", flVolume, ATTN_NORM);
		break;
	case 1:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark2.wav", flVolume, ATTN_NORM);
		break;
	case 2:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark3.wav", flVolume, ATTN_NORM);
		break;
	case 3:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark4.wav", flVolume, ATTN_NORM);
		break;
	case 4:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM);
		break;
	case 5:
		EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM);
		break;
	}
}
Esempio n. 8
0
void CFuncLight :: Flicker( void )
{
	if( m_iState == STATE_TURN_ON )
	{
		LIGHT_STYLE( m_iStyle, "k" );
		UTIL_FireTargets( pev->target, this, this, USE_ON );
		m_iState = STATE_ON;
		DontThink();
		return;
	}

	if( m_iFlickerMode == 1 )
	{
		pev->frame = 1;
		LIGHT_STYLE( m_iStyle, "a" );
		SetThink( NULL );
		return;
	}

	if( m_iFlickerMode == 2 )
	{
		switch( RANDOM_LONG( 0, 3 ))
		{
		case 0:
			LIGHT_STYLE( m_iStyle, "abcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
			break;
		case 1:
			LIGHT_STYLE( m_iStyle, "acaaabaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
			break;
		case 2:
			LIGHT_STYLE( m_iStyle, "aaafbaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
			break;
		case 3:
			LIGHT_STYLE( m_iStyle, "aaaaaaaaaaaaagaaaaaaaaacaaaacaaaa" );
			break;
		}		

		m_flNextFlickerTime = RANDOM_FLOAT( 0.5f, 10.0f );
                   	UTIL_Sparks( m_vecLastDmgPoint );

		switch( RANDOM_LONG( 0, 2 ))
		{
		case 0:
			EMIT_SOUND( edict(), CHAN_VOICE, "buttons/spark1.wav", 0.4, ATTN_IDLE );
			break;
		case 1:
			EMIT_SOUND( edict(), CHAN_VOICE, "buttons/spark2.wav", 0.3, ATTN_IDLE );
			break;
		case 2:
			EMIT_SOUND( edict(), CHAN_VOICE, "buttons/spark3.wav", 0.35, ATTN_IDLE );
			break;
		}

		if( m_flNextFlickerTime > 6.5f )
			m_iFlickerMode = 1; // stop sparking
	}

	SetNextThink( m_flNextFlickerTime ); 
}
Esempio n. 9
0
void CShower::Think( void )
{
	UTIL_Sparks( pev->origin );

	pev->speed -= 0.1;
	if ( pev->speed > 0 )
		SetNextThink( 0.1 );
	else
		UTIL_Remove( this );
	pev->flags &= ~FL_ONGROUND;
}
Esempio n. 10
0
void CShower::Think( void )
{
	UTIL_Sparks( GetAbsOrigin() );

	SetSpeed( GetSpeed() - 0.1 );
	if( GetSpeed() > 0 )
		SetNextThink( gpGlobals->time + 0.1 );
	else
		UTIL_Remove( this );
	GetFlags().ClearFlags( FL_ONGROUND );
}
Esempio n. 11
0
void CShower::Think( void )
{
	UTIL_Sparks( pev->origin );

	pev->speed -= 0.1;
	if ( pev->speed > 0 )
		pev->nextthink = gpGlobals->time + 0.1;
	else
		UTIL_Remove( this );
	pev->flags &= ~FL_ONGROUND;
}
Esempio n. 12
0
void AvHBaseBuildable::Killed(entvars_t* pevAttacker, int iGib)
{
	bool theInReset = GetGameRules()->GetIsGameInReset();
	
	AvHBaseBuildable::SetHasBeenKilled();
	GetGameRules()->RemoveEntityUnderAttack( this->entindex() );

	this->mKilled = true;
    this->mInternalSetConstructionComplete = false;
	this->mTimeOfLastAutoHeal = -1;

	if (!theInReset)
	{
		// : 980
		// Less smoke for recycled buildings
		this->TriggerDeathAudioVisuals(iGib == GIB_RECYCLED);
		
		if(!this->GetIsOrganic())
		{
			// More sparks for recycled buildings
			int numSparks = ( iGib == GIB_RECYCLED ) ? 7 : 3;
			for ( int i=0; i < numSparks; i++ ) {
				Vector vecSrc = Vector( (float)RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ), (float)RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ), (float)0 );
				vecSrc = vecSrc + Vector( (float)0, (float)0, (float)RANDOM_FLOAT( pev->origin.z, pev->absmax.z ) );
				UTIL_Sparks(vecSrc);
			}
		}
		// :
	}
	this->TriggerRemoveTech();

	AvHSURemoveEntityFromHotgroupsAndSelection(this->entindex());

	if(pevAttacker)
	{
		const char* theClassName = STRING(this->pev->classname);
		AvHPlayer* inPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(ENT(pevAttacker)));
		if(inPlayer && theClassName)
		{
			inPlayer->LogPlayerAction("structure_destroyed", theClassName);
			GetGameRules()->RewardPlayerForKill(inPlayer, this);
		}
	}
	
	if(this->GetIsPersistent())
	{
        this->SetInactive();
	}
	else
	{
		CBaseAnimating::Killed(pevAttacker, iGib);
	}
}
Esempio n. 13
0
void CShower::__MAKE_VHOOK(Think)()
{
	UTIL_Sparks(pev->origin);

	pev->speed -= 0.1f;

	if (pev->speed > 0)
		pev->nextthink = gpGlobals->time + 0.1f;
	else
		UTIL_Remove(this);

	pev->flags &= ~FL_ONGROUND;
}
Esempio n. 14
0
void CBreakable::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
	// random spark if this is a 'computer' object
	if (RANDOM_LONG(0,1) )
	{
		switch( m_Material )
		{
			case matComputer:
			{
				UTIL_Sparks( ptr->vecEndPos );

				float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range
				switch ( RANDOM_LONG(0,1) )
				{
					case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM);	break;
					case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM);	break;
				}
			}
			break;

			case matUnbreakableGlass:
				UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) );
			break;
		}
	}

	//LRC
	if (m_iszWhenHit)
	{
		if(m_pHitProxy==NULL){		//AJH may need to reset this as it's null after save/load
			m_pHitProxy = GetClassPtr( (CPointEntity*)NULL );
		}

		m_pHitProxy->pev->origin = ptr->vecEndPos;
		if (pev->spawnflags&SF_BREAKABLE_INVERT){	//AJH 
			vecDir.y=-vecDir.y;
			//vecDir.z=-vecDir.z;
			vecDir.x=-vecDir.x;
			//ALERT(at_debug,"INVERTING Breakables 'hit' vector (x&y components only) \n");
		}
		m_pHitProxy->pev->velocity = vecDir;		
		m_pHitProxy->pev->angles = UTIL_VecToAngles(vecDir);	//AJH
	
	  //ALERT(at_debug,"Func_breakable fires %s \n",STRING(m_iszWhenHit));
		FireTargets( STRING(m_iszWhenHit), m_pHitProxy, this, USE_TOGGLE, 0 );
	}

	CBaseDelay::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
Esempio n. 15
0
void CElectrifiedWire::DoSpark( const size_t uiSegment, const bool bExertForce )
{
	const Vector vecOrigin = GetSegmentAttachmentPoint( uiSegment );

	UTIL_Sparks( vecOrigin );

	if( bExertForce )
	{
		const Vector vecSparkForce(
			UTIL_RandomFloat( -m_iXJoltForce, m_iXJoltForce ),
			UTIL_RandomFloat( -m_iYJoltForce, m_iYJoltForce ),
			UTIL_RandomFloat( -m_iZJoltForce, m_iZJoltForce )
		);

		ApplyForceToSegment( vecSparkForce, uiSegment );
	}
}
Esempio n. 16
0
void CGenericMonster::MakeGas( void )
{
	Vector posGun, angleGun;
	TraceResult tr;
	UTIL_MakeVectors( pev->angles );
	{
	KillGas();
		m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 7 );
		if ( m_pBeam )
		{
			GetAttachment( 4, posGun, angleGun );
			GetAttachment( 3, posGun, angleGun );

			Vector vecEnd = (gpGlobals->v_forward * 5) + posGun;
			UTIL_TraceLine( posGun, vecEnd, dont_ignore_monsters, edict(), &tr );

			m_pBeam->EntsInit( edict(), edict() );
			m_pBeam->SetColor( 24, 121, 239 );
			m_pBeam->SetBrightness( 190 );
		         	m_pBeam->SetScrollRate( 20 );
			m_pBeam->SetStartAttachment( 4 );
			m_pBeam->SetEndAttachment( 3 );
			m_pBeam->DamageDecal( 28 );
			m_pBeam->DoSparks( tr.vecEndPos, posGun );
			m_pBeam->SetFlags( FBEAM_SHADEIN );
			m_pBeam->RelinkBeam();

			UTIL_Sparks( tr.vecEndPos );
			UTIL_DecalTrace(&tr, 28 + RANDOM_LONG(0,4));
		}
	}
	// m_flNextAttack = gpGlobals->time + RANDOM_FLOAT( 0.5, 4.0 );
	if ( int gas = 1 )
	{
		pev->nextthink = gpGlobals->time;
	}
}
Esempio n. 17
0
void CBreakable::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
	// random spark if this is a 'computer' object
	if (RANDOM_LONG(0,1) )
	{
		switch( m_Material )
		{
			case matComputer:
			{
				UTIL_Sparks( ptr->vecEndPos );

				float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range
				switch ( RANDOM_LONG(0,1) )
				{
					case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM);	break;
					case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM);	break;
				}
			}
			break;
			
			case matUnbreakableGlass:
				UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) );
			break;
		}
	}

	//LRC
	if (m_iszWhenHit)
	{
		m_pHitProxy->pev->origin = ptr->vecEndPos;
		m_pHitProxy->pev->velocity = vecDir;
		FireTargets( STRING(m_iszWhenHit), m_pHitProxy, this, USE_TOGGLE, 0 );
	}

	CBaseDelay::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
Esempio n. 18
0
void CFriend::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
	// check for helmet shot	
	if (ptr->iHitgroup == HITGROUP_HEAD) // si el daño es en la cabeza
	{
		if (GetBodygroup( 1 ) == HEAD_MASK && (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB)))
		{
			// absorb damage
			flDamage -= 20;
			if (flDamage <= 0)
			{
				UTIL_Ricochet( ptr->vecEndPos, 1.0 );
				UTIL_Sparks( ptr->vecEndPos );
				// Sonidos (precache en world.cpp)
				switch (RANDOM_LONG(0,2)) 
				{
					case 0:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet1.wav", 0.9, ATTN_NORM); break;
					case 1:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet2.wav", 0.9, ATTN_NORM); break;
					case 2:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet3.wav", 0.9, ATTN_NORM); break;
				}
				flDamage = 0.01;
			}
		}
		else if (GetBodygroup( 1 ) == HEAD_GRUNT && (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB)))
		{
			// absorb damage
			flDamage -= 20;
			if (flDamage <= 0)
			{
				UTIL_Ricochet( ptr->vecEndPos, 1.0 );
				UTIL_Sparks( ptr->vecEndPos );
				// Sonidos (precache en world.cpp)
				switch (RANDOM_LONG(0,2)) 
				{
					case 0:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet1.wav", 0.9, ATTN_NORM); break;
					case 1:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet2.wav", 0.9, ATTN_NORM); break;
					case 2:	EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/damage/helmet3.wav", 0.9, ATTN_NORM); break;
				}
				flDamage = 0.01;
			}
		}
		else
		{
			ALERT( at_console, "Human Grunt Headshot!\n" );
			UTIL_BloodStream( ptr->vecEndPos,
						gpGlobals->v_forward * 10 +  // -5
						gpGlobals->v_up * 2, 
						(unsigned short)73, 100 );	
			//-35
			switch (RANDOM_LONG(0,2)) //ejecuta los siguientes sonidos al azar
			{
			case 0: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_headshot1.wav", 1, ATTN_NORM ); break;
			case 1: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_headshot2.wav", 1, ATTN_NORM ); break;
			case 2: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_headshot3.wav", 1, ATTN_NORM ); break;
			}
		}
	}
	else
	{
		switch (RANDOM_LONG(0,2)) //ejecuta los siguientes sonidos al azar
		{
			case 0: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_hit1.wav", 1, ATTN_NORM ); break;
			case 1: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_hit2.wav", 1, ATTN_NORM ); break;
			case 2: EMIT_SOUND (ENT(pev), CHAN_BODY, "fvox/m_hit3.wav", 1, ATTN_NORM ); break;
		}
	}

	CTalkMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
Esempio n. 19
0
void CBaseTurret ::	TurretDeath( void )
{
	BOOL iActive = FALSE;

	StudioFrameAdvance( );
	pev->nextthink = gpGlobals->time + 0.1;

	if (pev->deadflag != DEAD_DEAD)
	{
		pev->deadflag = DEAD_DEAD;

		float flRndSound = RANDOM_FLOAT ( 0 , 1 );

		if ( flRndSound <= 0.33 )
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM);
		else if ( flRndSound <= 0.66 )
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM);
		else 
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM);

		EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100);

		if (m_iOrientation == 0)
			m_vecGoalAngles.x = -15;
		else
			m_vecGoalAngles.x = -90;

		SetTurretAnim(TURRET_ANIM_DIE); 

		EyeOn( );	
	}

	EyeOff( );

	if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time)
	{
		// lots of smoke
		MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
			WRITE_BYTE( TE_SMOKE );
			WRITE_COORD( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ) );
			WRITE_COORD( RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ) );
			WRITE_COORD( pev->origin.z - m_iOrientation * 64 );
			WRITE_SHORT( g_sModelIndexSmoke );
			WRITE_BYTE( 25 ); // scale * 10
			WRITE_BYTE( 10 - m_iOrientation * 5); // framerate
		MESSAGE_END();
	}
	
	if (pev->dmgtime + RANDOM_FLOAT( 0, 5 ) > gpGlobals->time)
	{
		Vector vecSrc = Vector( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ), RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ), 0 );
		if (m_iOrientation == 0)
			vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->origin.z, pev->absmax.z ) );
		else
			vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->absmin.z, pev->origin.z ) );

		UTIL_Sparks( vecSrc );
	}

	if (m_fSequenceFinished && !MoveTurret( ) && pev->dmgtime + 5 < gpGlobals->time)
	{
		pev->framerate = 0;
		SetThink( NULL );
	}
}
Esempio n. 20
0
void CSentry ::	SentryDeath( void )
{
	BOOL iActive = FALSE;

	StudioFrameAdvance( );
	pev->nextthink = gpGlobals->time + 0.1;

	if (pev->deadflag != DEAD_DEAD)
	{
		pev->deadflag = DEAD_DEAD;

		float flRndSound = RANDOM_FLOAT ( 0 , 1 );

		if ( flRndSound <= 0.33 )
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM);
		else if ( flRndSound <= 0.66 )
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM);
		else 
			EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM);

		EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100);

		SetBoneController( 0, 0 );
		SetBoneController( 1, 0 );

		SetTurretAnim(TURRET_ANIM_DIE); 

		pev->solid = SOLID_NOT;
		pev->angles.y = UTIL_AngleMod( pev->angles.y + RANDOM_LONG( 0, 2 ) * 120 );

		EyeOn( );
	}

	EyeOff( );

	Vector vecSrc, vecAng;
	GetAttachment( 1, vecSrc, vecAng );

	if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time)
	{
		// lots of smoke
		MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
			WRITE_BYTE( TE_SMOKE );
			WRITE_COORD( vecSrc.x + RANDOM_FLOAT( -16, 16 ) );
			WRITE_COORD( vecSrc.y + RANDOM_FLOAT( -16, 16 ) );
			WRITE_COORD( vecSrc.z - 32 );
			WRITE_SHORT( g_sModelIndexSmoke );
			WRITE_BYTE( 15 ); // scale * 10
			WRITE_BYTE( 8 ); // framerate
		MESSAGE_END();
	}
	
	if (pev->dmgtime + RANDOM_FLOAT( 0, 8 ) > gpGlobals->time)
	{
		UTIL_Sparks( vecSrc );
	}

	if (m_fSequenceFinished && pev->dmgtime + 5 < gpGlobals->time)
	{
		pev->framerate = 0;
		SetThink( NULL );
	}
}
Esempio n. 21
0
// CS
Vector CBaseEntity::FireBullets3( Vector vecSrc, Vector vecDirShooting, float flSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand )
{
    int   originalPenetration = iPenetration;
    int   penetrationPower;
    float penetrationDistance;

    int   currentDamage = iDamage;
    float currentDistance;

    TraceResult tr;
    TraceResult tr2;

    Vector vecRight = gpGlobals->v_right;
    Vector vecUp    = gpGlobals->v_up;

    bool hitMetal = false;

    switch( iBulletType )
    {
        case BULLET_PLAYER_9MM:
        {
            penetrationPower    = 21;
            penetrationDistance = 800;
            break;
        }
        case BULLET_PLAYER_45ACP:
        {
            penetrationPower    = 15;
            penetrationDistance = 500;
            break;
        }
        case BULLET_PLAYER_50AE:
        {
            penetrationPower    = 30;
            penetrationDistance = 1000;
            break;
        }
        case BULLET_PLAYER_762MM:
        {
            penetrationPower    = 39;
            penetrationDistance = 5000;
            break;
        }
        case BULLET_PLAYER_556MM:
        {
            penetrationPower    = 35;
            penetrationDistance = 4000;
            break;
        }
        case BULLET_PLAYER_338MAG:
        {
            penetrationPower    = 45;
            penetrationDistance = 8000;
            break;
        }
        case BULLET_PLAYER_57MM:
        {
            penetrationPower    = 30;
            penetrationDistance = 2000;
            break;
        }
        case BULLET_PLAYER_357SIG:
        {
            penetrationPower    = 25;
            penetrationDistance = 800;
            break;
        }
        default:
        {
            penetrationPower    = 0;
            penetrationDistance = 0;
            break;
        }
    }

    if( !pevAttacker )
    {
        pevAttacker = pev;
    }

    gMultiDamage.type = DMG_BULLET | DMG_NEVERGIB;

    float x, y, z;

    if( IsPlayer() )
    {
        x = UTIL_SharedRandomFloat( shared_rand, -0.5, 0.5 ) + UTIL_SharedRandomFloat( shared_rand + 1, -0.5, 0.5 );
        y = UTIL_SharedRandomFloat (shared_rand + 2, -0.5, 0.5 ) + UTIL_SharedRandomFloat (shared_rand + 3, -0.5, 0.5 );
    }
    else
    {
        do
        {
            x = RANDOM_FLOAT( -0.5, 0.5 ) + RANDOM_FLOAT( -0.5, 0.5 );
            y = RANDOM_FLOAT( -0.5, 0.5 ) + RANDOM_FLOAT( -0.5, 0.5 );
            z = x * x + y * y;
        }
        while( z > 1 );
    }

    Vector vecDir = vecDirShooting + x * flSpread * vecRight + y * flSpread * vecUp;
    Vector vecEnd = vecSrc + vecDir * flDistance;

    float damageModifier = 0.5;

    while( iPenetration )
    {
        ClearMultiDamage();
        UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr );

        if( tr.flFraction != 1.0 )
        {
            // TODO:Implement me.
            // TheBots->OnEvent( EVENT_BULLET_IMPACT, this, NULL );
        }

        switch( UTIL_TextureHit( &tr, vecSrc, vecEnd ) )
        {
            case CHAR_TEX_METAL:
            {
                hitMetal = true;
                penetrationPower *= 0.15;
                damageModifier    = 0.2;
                break;
            }

            case CHAR_TEX_CONCRETE:
            {
                penetrationPower *= 0.25;
                break;
            }

            case CHAR_TEX_GRATE:
            {
                hitMetal = true;
                penetrationPower *= 0.5;
                damageModifier      = 0.4;
                break;
            }

            case CHAR_TEX_VENT:
            {
                hitMetal = true;
                penetrationPower *= 0.5;
                damageModifier = 0.45;
                break;
            }

            case CHAR_TEX_TILE:
            {
                penetrationPower *= 0.65;
                damageModifier    = 0.3;
                break;
            }

            case CHAR_TEX_COMPUTER:
            {
                hitMetal = true;
                penetrationPower *= 0.4;
                damageModifier    = 0.45;
                break;
            }

            case CHAR_TEX_WOOD:
            {
                damageModifier = 0.6;
                break;
            }
        }

        if( tr.flFraction != 1.0 )
        {
            CBaseEntity* pEntity = CBaseEntity::Instance( tr.pHit );

            iPenetration--;

            currentDistance = tr.flFraction * flDistance;
            currentDamage *= pow( flRangeModifier, currentDistance / 500 );

            if( currentDistance > penetrationDistance )
            {
                iPenetration = 0;
            }

            if( tr.iHitgroup == HITGROUP_SHIELD )
            {
                if( tr.flFraction != 1.0 )
                {
                    if( RANDOM_LONG( 0, 1 ) )
                        EMIT_SOUND( pEntity->edict(), CHAN_VOICE, "weapons/ric_metal-1.wav", VOL_NORM, ATTN_NORM );
                    else
                        EMIT_SOUND( pEntity->edict(), CHAN_VOICE, "weapons/ric_metal-2.wav", VOL_NORM, ATTN_NORM );

                    UTIL_Sparks( tr.vecEndPos );

                    pEntity->pev->punchangle.x = currentDamage * RANDOM_FLOAT( -0.15, 0.15 );
                    pEntity->pev->punchangle.z = currentDamage * RANDOM_FLOAT( -0.15, 0.15 );

                    if( pEntity->pev->punchangle.x < 4 )
                        pEntity->pev->punchangle.x = 4;

                    if( pEntity->pev->punchangle.z < -5 )
                        pEntity->pev->punchangle.z = -5;

                    else if( pEntity->pev->punchangle.z > 5 )
                        pEntity->pev->punchangle.z = 5;
                }

                break;
            }

            float distanceModifier;

            if( VARS( tr.pHit )->solid != SOLID_BSP || !iPenetration )
            {
                penetrationPower = 42.0;
                distanceModifier = 0.75;
                damageModifier   = 0.75;
            }
            else
            {
                distanceModifier = 0.75;
            }

            DecalGunshot( &tr, iBulletType, bPistol || RANDOM_LONG( 0, 3 ), pev, hitMetal );

            vecSrc = tr.vecEndPos + ( vecDir * penetrationPower );
            flDistance = ( flDistance - currentDistance ) * distanceModifier;
            vecEnd = vecSrc + ( vecDir * flDistance );

            pEntity->TraceAttack( pevAttacker, currentDamage, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB);
            currentDamage *= damageModifier;
        }
        else
        {
            iPenetration = 0;
        }

        ApplyMultiDamage( pev, pevAttacker );
    }

    return Vector( x * flSpread, y * flSpread, 0 );
}
Esempio n. 22
0
void AvHBaseBuildable::WorldUpdate()
{
	this->UpdateTechSlots();

	// Organic buildings heal themselves
	if(this->GetIsOrganic())
	{
		this->UpdateAutoHeal();
	}
	else
	{
		//this->UpdateDamageEffects();
	}

	// If we're electrified, set render mode
	if(GetHasUpgrade(this->pev->iuser4, MASK_UPGRADE_11))
	{
		// Base marine building
		const int kElectrifyRenderMode = kRenderFxGlowShell;
		const int kElectrifyRenderAmount = 40;

		this->pev->renderfx = kElectrifyRenderMode;
		this->pev->renderamt = kElectrifyRenderAmount;
		this->pev->rendercolor.x = kTeamColors[this->pev->team][0];
		this->pev->rendercolor.y = kTeamColors[this->pev->team][1];
		this->pev->rendercolor.z = kTeamColors[this->pev->team][2];

		// Check for enemy players/structures nearby
		CBaseEntity* theBaseEntity = NULL;
		int theNumEntsDamaged = 0;
		
		while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kElectricalRange))) != NULL) && (theNumEntsDamaged < BALANCE_VAR(kElectricalMaxTargets)))
		{
			// When "electric" cheat is enabled, shock all non-self entities, else shock enemies
			if((GetGameRules()->GetIsCheatEnabled(kcElectric) && (theBaseEntity != this)) || ((theBaseEntity->pev->team != this->pev->team) && theBaseEntity->IsAlive()))
			{
				// Make sure it's not blocked
				TraceResult theTraceResult;
				UTIL_TraceLine(this->pev->origin, theBaseEntity->pev->origin, ignore_monsters, dont_ignore_glass, this->edict(), &theTraceResult);
				if(theTraceResult.flFraction == 1.0f)
				{
					CBaseEntity* theAttacker = this->GetAttacker();
					ASSERT(theAttacker);

					if(theBaseEntity->TakeDamage(this->pev, theAttacker->pev, BALANCE_VAR(kElectricalDamage), DMG_GENERIC) > 0)
					{
							MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
								WRITE_BYTE(TE_BEAMENTPOINT);
								WRITE_SHORT(theBaseEntity->entindex());
								WRITE_COORD( this->pev->origin.x);
								WRITE_COORD( this->pev->origin.y);
								WRITE_COORD( this->pev->origin.z);
						
								WRITE_SHORT( this->mElectricalSprite );
								WRITE_BYTE( 0 ); // framestart
								WRITE_BYTE( (int)15); // framerate
								WRITE_BYTE( (int)(2) ); // life
								WRITE_BYTE( 60 );  // width
								WRITE_BYTE( 15 );   // noise
								WRITE_BYTE( (int)this->pev->rendercolor.x );   // r, g, b
								WRITE_BYTE( (int)this->pev->rendercolor.y );   // r, g, b
								WRITE_BYTE( (int)this->pev->rendercolor.z );   // r, g, b
								WRITE_BYTE( 200 );	// brightness
								WRITE_BYTE( 10 );	// speed
							MESSAGE_END();
						
							gSoundListManager.PlaySoundInList(kElectricSparkSoundList, this, CHAN_AUTO, .7f);
						
							UTIL_Sparks(theBaseEntity->pev->origin);
						
							theNumEntsDamaged++;
					}
				}
			}
		}
	}
}
Esempio n. 23
0
// this function only gets called in multiplayer
void CCrossbow::FireSniperBolt()
{
	m_flNextPrimaryAttack = gpGlobals->time + 0.75;

	if (m_iClip == 0)
	{
		PlayEmptySound( );
		return;
	}

	TraceResult tr;

	m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
	m_iClip--;

	// make twang sound
	EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/xbow_fire1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));

	if (m_iClip)
	{
		EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/xbow_reload1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));
		SendWeaponAnim( CROSSBOW_FIRE1 );
	}
	else if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] == 0)
	{
		SendWeaponAnim( CROSSBOW_FIRE3 );
	}

	// player "shoot" animation
	m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
	
	Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle;
	UTIL_MakeVectors( anglesAim );
	Vector vecSrc = m_pPlayer->GetGunPosition( ) - gpGlobals->v_up * 2;
	Vector vecDir = gpGlobals->v_forward;

	UTIL_TraceLine(vecSrc, vecSrc + vecDir * 8192, dont_ignore_monsters, m_pPlayer->edict(), &tr);

	if ( tr.pHit->v.takedamage )
	{
		switch( RANDOM_LONG(0,1) )
		{
		case 0:
			EMIT_SOUND( tr.pHit, CHAN_BODY, "weapons/xbow_hitbod1.wav", 1, ATTN_NORM); break;
		case 1:
			EMIT_SOUND( tr.pHit, CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM); break;
		}

		ClearMultiDamage( );
		CBaseEntity::Instance(tr.pHit)->TraceAttack(m_pPlayer->pev, 120, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB ); 
		ApplyMultiDamage( pev, m_pPlayer->pev );
	}
	else
	{
		// create a bolt
		CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate();
		pBolt->pev->origin = tr.vecEndPos - vecDir * 10;
		pBolt->pev->angles = UTIL_VecToAngles( vecDir );
		pBolt->pev->solid = SOLID_NOT;
		pBolt->SetTouch( NULL );
		pBolt->SetThink( SUB_Remove );

		EMIT_SOUND( pBolt->edict(), CHAN_WEAPON, "weapons/xbow_hit1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM );

		if (UTIL_PointContents(tr.vecEndPos) != CONTENTS_WATER)
		{
			UTIL_Sparks( tr.vecEndPos );
		}

		if ( FClassnameIs( tr.pHit, "worldspawn" ) )
		{
			// let the bolt sit around for a while if it hit static architecture
			pBolt->pev->nextthink = gpGlobals->time + 5.0;
		}
		else
		{
			pBolt->pev->nextthink = gpGlobals->time;
		}
	}
}
Esempio n. 24
0
void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
{
	SetTouch( NULL );
	SetThink( NULL );

	if (pOther->pev->takedamage)
	{
		TraceResult tr = UTIL_GetGlobalTrace( );
		entvars_t	*pevOwner;

		pevOwner = VARS( pev->owner );

		// UNDONE: this needs to call TraceAttack instead
		ClearMultiDamage( );

		if ( pOther->IsPlayer() )
		{
			pOther->TraceAttack(pevOwner, gSkillData.plrDmgCrossbowClient, pev->velocity.Normalize(), &tr, DMG_NEVERGIB ); 
		}
		else
		{
			pOther->TraceAttack(pevOwner, gSkillData.plrDmgCrossbowMonster, pev->velocity.Normalize(), &tr, DMG_BULLET | DMG_NEVERGIB ); 
		}

		ApplyMultiDamage( pev, pevOwner );

		pev->velocity = Vector( 0, 0, 0 );
		// play body "thwack" sound
		switch( RANDOM_LONG(0,1) )
		{
		case 0:
			EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_hitbod1.wav", 1, ATTN_NORM); break;
		case 1:
			EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM); break;
		}

		if ( !g_pGameRules->IsMultiplayer() )
		{
			Killed( pev, GIB_NEVER );
		}
	}
	else
	{
		EMIT_SOUND_DYN(ENT(pev), CHAN_BODY, "weapons/xbow_hit1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 98 + RANDOM_LONG(0,7));

		SetThink( &CCrossbowBolt::SUB_Remove );
		pev->nextthink = gpGlobals->time;// this will get changed below if the bolt is allowed to stick in what it hit.

		if ( FClassnameIs( pOther->pev, "worldspawn" ) )
		{
			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = pev->velocity.Normalize( );
			UTIL_SetOrigin( pev, pev->origin - vecDir * 12 );
			pev->angles = UTIL_VecToAngles( vecDir );
			pev->solid = SOLID_NOT;
			pev->movetype = MOVETYPE_FLY;
			pev->velocity = Vector( 0, 0, 0 );
			pev->avelocity.z = 0;
			pev->angles.z = RANDOM_LONG(0,360);
			pev->nextthink = gpGlobals->time + 10.0;
		}

		if (UTIL_PointContents(pev->origin) != CONTENTS_WATER)
		{
			UTIL_Sparks( pev->origin );
		}
	}

	if ( g_pGameRules->IsMultiplayer() )
	{
		SetThink( &CCrossbowBolt::ExplodeThink );
		pev->nextthink = gpGlobals->time + 0.1;
	}
}
Esempio n. 25
0
// Go to the trouble of combining multiple pellets into a single damage call.
// This version is used by Players, uses the random seed generator to sync client and server side shots.
Vector CBaseEntity::FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand)
{
	int iOriginalPenetration = iPenetration;
	int iPenetrationPower;
	float flPenetrationDistance;
	int iCurrentDamage = iDamage;
	float flCurrentDistance;

	TraceResult tr, tr2;
	Vector vecRight, vecUp;

	bool bHitMetal = false;
	int iSparksAmount = 1;

	vecRight = gpGlobals->v_right;
	vecUp = gpGlobals->v_up;

	switch (iBulletType)
	{
	case BULLET_PLAYER_9MM:
		iPenetrationPower = 21;
		flPenetrationDistance = 800;
		break;
	case BULLET_PLAYER_45ACP:
		iPenetrationPower = 15;
		flPenetrationDistance = 500;
		break;
	case BULLET_PLAYER_50AE:
		iPenetrationPower = 30;
		flPenetrationDistance = 1000;
		break;
	case BULLET_PLAYER_762MM:
		iPenetrationPower = 39;
		flPenetrationDistance = 5000;
		break;
	case BULLET_PLAYER_556MM:
		iPenetrationPower = 35;
		flPenetrationDistance = 4000;
		break;
	case BULLET_PLAYER_338MAG:
		iPenetrationPower = 45;
		flPenetrationDistance = 8000;
		break;
	case BULLET_PLAYER_57MM:
		iPenetrationPower = 30;
		flPenetrationDistance = 2000;
		break;
	case BULLET_PLAYER_357SIG:
		iPenetrationPower = 25;
		flPenetrationDistance = 800;
		break;
	default:
		iPenetrationPower = 0;
		flPenetrationDistance = 0;
		break;
	}

	if (!pevAttacker)
	{
		// the default attacker is ourselves
		pevAttacker = pev;
	}

	gMultiDamage.type = (DMG_BULLET | DMG_NEVERGIB);

	float x, y, z;

	if (IsPlayer())
	{
		// Use player's random seed.
		// get circular gaussian spread
		x = UTIL_SharedRandomFloat(shared_rand, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 1, -0.5, 0.5);
		y = UTIL_SharedRandomFloat(shared_rand + 2, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 3, -0.5, 0.5);
	}
	else
	{
		do
		{
			x = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
			y = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
			z = x * x + y * y;
		}
		while (z > 1);
	}

	Vector vecDir, vecEnd;
	Vector vecOldSrc, vecNewSrc;

	vecDir = vecDirShooting + x * vecSpread * vecRight + y * vecSpread * vecUp;
	vecEnd = vecSrc + vecDir * flDistance;

	float flDamageModifier = 0.5;

	while (iPenetration != 0)
	{
		ClearMultiDamage();
		UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);

		if (TheBots != NULL && tr.flFraction != 1.0f)
		{
			TheBots->OnEvent(EVENT_BULLET_IMPACT, this, (CBaseEntity *)&tr.vecEndPos);
		}

		char cTextureType = UTIL_TextureHit(&tr, vecSrc, vecEnd);
		bool bSparks = false;

		switch (cTextureType)
		{
		case CHAR_TEX_METAL:
			bHitMetal = true;
			bSparks = true;

			iPenetrationPower *= 0.15;
			flDamageModifier = 0.2;
			break;
		case CHAR_TEX_CONCRETE:
			iPenetrationPower *= 0.25;
			break;
		case CHAR_TEX_GRATE:
			bHitMetal = true;
			bSparks = true;

			iPenetrationPower *= 0.5;
			flDamageModifier = 0.4;
			break;
		case CHAR_TEX_VENT:
			bHitMetal = true;
			bSparks = true;

			iPenetrationPower *= 0.5;
			flDamageModifier = 0.45;
			break;
		case CHAR_TEX_TILE:
			iPenetrationPower *= 0.65;
			flDamageModifier = 0.3;
			break;
		case CHAR_TEX_COMPUTER:
			bHitMetal = true;
			bSparks = true;

			iPenetrationPower *= 0.4;
			flDamageModifier = 0.45;
			break;
		case CHAR_TEX_WOOD:
			flDamageModifier = 0.6;
			break;
		default:
			break;
		}
		if (tr.flFraction != 1.0f)
		{
			CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
			iPenetration--;

			flCurrentDistance = tr.flFraction * flDistance;
			iCurrentDamage *= Q_pow(flRangeModifier, flCurrentDistance / 500);

			if (flCurrentDistance > flPenetrationDistance)
			{
				iPenetration = 0;
			}

			if (tr.iHitgroup == HITGROUP_SHIELD)
			{
				EMIT_SOUND(pEntity->edict(), CHAN_VOICE, (RANDOM_LONG(0, 1) == 1) ? "weapons/ric_metal-1.wav" : "weapons/ric_metal-2.wav", VOL_NORM, ATTN_NORM);
				UTIL_Sparks(tr.vecEndPos);

				pEntity->pev->punchangle.x = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);
				pEntity->pev->punchangle.z = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);

				if (pEntity->pev->punchangle.x < 4)
				{
					pEntity->pev->punchangle.x = -4;
				}

				if (pEntity->pev->punchangle.z < -5)
				{
					pEntity->pev->punchangle.z = -5;
				}
				else if (pEntity->pev->punchangle.z > 5)
				{
					pEntity->pev->punchangle.z = 5;
				}

				break;
			}

			float flDistanceModifier;
			if (VARS(tr.pHit)->solid != SOLID_BSP || !iPenetration)
			{
				iPenetrationPower = 42;
				flDamageModifier = 0.75;
				flDistanceModifier = 0.75;
			}
			else
				flDistanceModifier = 0.5;

			DecalGunshot(&tr, iBulletType, (!bPistol && RANDOM_LONG(0, 3)), pev, bHitMetal);

			vecSrc = tr.vecEndPos + (vecDir * iPenetrationPower);
			flDistance = (flDistance - flCurrentDistance) * flDistanceModifier;
			vecEnd = vecSrc + (vecDir * flDistance);

			pEntity->TraceAttack(pevAttacker, iCurrentDamage, vecDir, &tr, (DMG_BULLET | DMG_NEVERGIB));
			iCurrentDamage *= flDamageModifier;
		}
		else
			iPenetration = 0;

		ApplyMultiDamage(pev, pevAttacker);
	}

	return Vector(x * vecSpread, y * vecSpread, 0);
}
Esempio n. 26
0
void CDisc::DiscTouch ( CBaseEntity *pOther )
{
	// Push players backwards
	if ( pOther->IsPlayer() )
	{
		if ( ((CBaseEntity*)m_hOwner) == pOther )
		{
			if (m_fDontTouchOwner < gpGlobals->time)
			{
				// Play catch sound
				EMIT_SOUND_DYN( pOther->edict(), CHAN_WEAPON, "items/gunpickup2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); 

				ReturnToThrower();
			}

			return;
		}
		else if ( m_fDontTouchEnemies < gpGlobals->time)
		{
			if ( pev->team != pOther->pev->team )
			{
				((CBasePlayer*)pOther)->m_LastHitGroup = HITGROUP_GENERIC;

				// Do freeze seperately so you can freeze and shatter a person with a single shot
				if ( m_iPowerupFlags & POW_FREEZE && ((CBasePlayer*)pOther)->m_iFrozen == FALSE )
				{
					// Freeze the player and make them glow blue
					EMIT_SOUND_DYN( pOther->edict(), CHAN_WEAPON, "weapons/electro5.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); 
					((CBasePlayer*)pOther)->Freeze();

					// If it's not a decap, return now. If it's a decap, continue to shatter
					if ( !m_bDecapitate )
					{
						m_fDontTouchEnemies = gpGlobals->time + 2.0;
						return;
					}
				}

				// Decap or push
				if (m_bDecapitate)
				{
					// Decapitate!
					if ( m_bTeleported )
						((CBasePlayer*)pOther)->m_flLastDiscHitTeleport = gpGlobals->time;
					((CBasePlayer*)pOther)->Decapitate( ((CBaseEntity*)m_hOwner)->pev );

					m_fDontTouchEnemies = gpGlobals->time + 0.5;
				}
				else 
				{
					// Play thwack sound
					switch( RANDOM_LONG(0,2) )
					{
					case 0:
						EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); 
						break;
					case 1:
						EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); 
						break;
					case 2:
						EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); 
						break;
					}

					// Push the player
					Vector vecDir = pev->velocity.Normalize();
					pOther->pev->flags &= ~FL_ONGROUND;
					((CBasePlayer*)pOther)->m_vecHitVelocity = vecDir * DISC_PUSH_MULTIPLIER;

					// Shield flash only if the player isnt frozen
					if ( ((CBasePlayer*)pOther)->m_iFrozen == false )
					{
						pOther->pev->renderfx = kRenderFxGlowShell;
						pOther->pev->rendercolor.x = 255;
						pOther->pev->renderamt = 150;
					}

					((CBasePlayer*)pOther)->m_hLastPlayerToHitMe = m_hOwner;
					((CBasePlayer*)pOther)->m_flLastDiscHit = gpGlobals->time;
					((CBasePlayer*)pOther)->m_iLastDiscBounces = m_iBounces;
					if ( m_bTeleported )
						((CBasePlayer*)pOther)->m_flLastDiscHitTeleport = gpGlobals->time;

					m_fDontTouchEnemies = gpGlobals->time + 2.0;
				}
			}
		}
	}
	// Hit a disc?
	else if ( pOther->pev->iuser4 ) 
	{
		// Enemy Discs destroy each other
		if ( pOther->pev->iuser4 != pev->iuser4 )
		{
			// Play a warp sound and sprite
			CSprite *pSprite = CSprite::SpriteCreate( "sprites/discreturn.spr", pev->origin, TRUE );
			pSprite->AnimateAndDie( 60 );
			pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation );
			pSprite->SetScale( 1 );
			EMIT_SOUND_DYN( edict(), CHAN_ITEM, "dischit.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));

			// Return both discs to their owners
			((CDisc*)pOther)->ReturnToThrower();
			ReturnToThrower();
		}
		else
		{
			// Friendly discs just pass through each other
		}
	}
	else
	{
		m_iBounces++;

		switch ( RANDOM_LONG( 0, 1 ) )
		{
		case 0:	EMIT_SOUND_DYN( edict(), CHAN_ITEM, "weapons/xbow_hit1.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));  break;
		case 1:	EMIT_SOUND_DYN( edict(), CHAN_ITEM, "weapons/xbow_hit2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));  break;
		}

		UTIL_Sparks( pev->origin, edict() );
	}
}