summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_fx_blood.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_fx_blood.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_fx_blood.cpp')
-rw-r--r--game/client/tf/tf_fx_blood.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/game/client/tf/tf_fx_blood.cpp b/game/client/tf/tf_fx_blood.cpp
new file mode 100644
index 0000000..2860ca8
--- /dev/null
+++ b/game/client/tf/tf_fx_blood.cpp
@@ -0,0 +1,180 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A blood spray effect to expose successful hits.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "clienteffectprecachesystem.h"
+#include "fx_sparks.h"
+#include "iefx.h"
+#include "c_te_effect_dispatch.h"
+#include "particles_ez.h"
+#include "decals.h"
+#include "engine/IEngineSound.h"
+#include "fx_quad.h"
+#include "engine/ivdebugoverlay.h"
+#include "shareddefs.h"
+#include "fx_blood.h"
+#include "view.h"
+#include "c_tf_player.h"
+#include "debugoverlay_shared.h"
+#include "tf_gamerules.h"
+#include "c_basetempentity.h"
+#include "tier0/vprof.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Intercepts the blood spray message.
+//-----------------------------------------------------------------------------
+void TFBloodSprayCallback( Vector vecOrigin, Vector vecNormal, ClientEntityHandle_t hEntity )
+{
+ QAngle vecAngles;
+ VectorAngles( -vecNormal, vecAngles );
+
+ // determine if the bleeding player is underwater
+ bool bUnderwater = false;
+ C_TFPlayer *pPlayer = dynamic_cast<C_TFPlayer*>( ClientEntityList().GetBaseEntityFromHandle( hEntity ) );
+ if ( pPlayer && ( WL_Eyes == pPlayer->GetWaterLevel() ) )
+ {
+ bUnderwater = true;
+ }
+
+ bool bPyroVision = false;
+#ifdef CLIENT_DLL
+ // Use birthday fun if the local player has an item that allows them to see it (Pyro Goggles)
+ if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_PYRO ) )
+ {
+ bPyroVision = true;
+ }
+#endif
+
+ if ( !bUnderwater && TFGameRules() && TFGameRules()->IsBirthday() && RandomFloat(0,1) < 0.2 )
+ {
+ DispatchParticleEffect( "bday_blood", vecOrigin, vecAngles, pPlayer );
+ }
+ else if ( TFGameRules() && bPyroVision )
+ {
+ DispatchParticleEffect( "pyrovision_blood", vecOrigin, vecAngles, pPlayer );
+ }
+ else if ( UTIL_IsLowViolence() )
+ {
+ DispatchParticleEffect( bUnderwater ? "lowV_water_blood_impact_red_01" : "lowV_blood_impact_red_01", vecOrigin, vecAngles, pPlayer );
+ }
+ else
+ {
+ DispatchParticleEffect( bUnderwater ? "water_blood_impact_red_01" : "blood_impact_red_01", vecOrigin, vecAngles, pPlayer );
+ }
+
+ // if underwater, don't add additional spray
+ if ( bUnderwater )
+ return;
+
+ // Now throw out a spray away from the view
+ // Get the distance to the view
+ float flDistance = (vecOrigin - MainViewOrigin()).Length();
+ float flLODDistance = 0.25 * (flDistance / 512);
+
+ Vector right, up;
+ if (vecNormal != Vector(0, 0, 1) )
+ {
+ right = vecNormal.Cross( Vector(0, 0, 1) );
+ up = right.Cross( vecNormal );
+ }
+ else
+ {
+ right = Vector(0, 0, 1);
+ up = right.Cross( vecNormal );
+ }
+
+ // If the normal's too close to being along the view, push it out
+ Vector vecForward, vecRight;
+ AngleVectors( MainViewAngles(), &vecForward, &vecRight, NULL );
+ float flDot = DotProduct( vecNormal, vecForward );
+ if ( fabs(flDot) > 0.5 )
+ {
+ float flPush = random->RandomFloat(0.5, 1.5) + flLODDistance;
+ float flRightDot = DotProduct( vecNormal, vecRight );
+
+ // If we're up close, randomly move it around. If we're at a distance, always push it to the side
+ // Up close, this can move it back towards the view, but the random chance still looks better
+ if ( ( flDistance >= 512 && flRightDot > 0 ) || ( flDistance < 512 && RandomFloat(0,1) > 0.5 ) )
+ {
+ // Turn it to the right
+ vecNormal += (vecRight * flPush);
+ }
+ else
+ {
+ // Turn it to the left
+ vecNormal -= (vecRight * flPush);
+ }
+ }
+
+ VectorAngles( vecNormal, vecAngles );
+
+ if ( flDistance < 400 )
+ {
+
+ DispatchParticleEffect( UTIL_IsLowViolence() ? "lowV_blood_spray_red_01" : "blood_spray_red_01", vecOrigin, vecAngles, pPlayer );
+ }
+ else
+ {
+ DispatchParticleEffect( UTIL_IsLowViolence() ? "lowV_blood_spray_red_01_far" : "blood_spray_red_01_far", vecOrigin, vecAngles, pPlayer );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_TETFBlood : public C_BaseTempEntity
+{
+public:
+ DECLARE_CLASS( C_TETFBlood, C_BaseTempEntity );
+
+ DECLARE_CLIENTCLASS();
+
+ C_TETFBlood( void );
+
+ virtual void PostDataUpdate( DataUpdateType_t updateType );
+
+public:
+ Vector m_vecOrigin;
+ Vector m_vecNormal;
+ ClientEntityHandle_t m_hEntity;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_TETFBlood::C_TETFBlood( void )
+{
+ m_vecOrigin.Init();
+ m_vecNormal.Init();
+ m_hEntity = INVALID_EHANDLE_INDEX;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_TETFBlood::PostDataUpdate( DataUpdateType_t updateType )
+{
+ VPROF( "C_TETFBlood::PostDataUpdate" );
+
+ TFBloodSprayCallback( m_vecOrigin, m_vecNormal, m_hEntity );
+}
+
+static void RecvProxy_BloodEntIndex( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ int nEntIndex = pData->m_Value.m_Int;
+ ((C_TETFBlood*)pStruct)->m_hEntity = (nEntIndex < 0) ? INVALID_EHANDLE_INDEX : ClientEntityList().EntIndexToHandle( nEntIndex );
+}
+
+IMPLEMENT_CLIENTCLASS_EVENT_DT(C_TETFBlood, DT_TETFBlood, CTETFBlood)
+ RecvPropFloat( RECVINFO( m_vecOrigin[0] ) ),
+ RecvPropFloat( RECVINFO( m_vecOrigin[1] ) ),
+ RecvPropFloat( RECVINFO( m_vecOrigin[2] ) ),
+ RecvPropVector( RECVINFO(m_vecNormal)),
+ RecvPropInt( "entindex", 0, SIZEOF_IGNORE, 0, RecvProxy_BloodEntIndex ),
+END_RECV_TABLE()
+
+
+