Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/game/client/c_baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,10 @@ class C_BaseEntity : public IClientEntity
MoveCollide_t GetMoveCollide( void ) const;
virtual SolidType_t GetSolid( void ) const;

#ifdef NEO
virtual void Splash() {}
#endif // NEO

virtual int GetSolidFlags( void ) const;
bool IsSolidFlagSet( int flagMask ) const;
void SetSolidFlags( int nFlags );
Expand Down
6 changes: 6 additions & 0 deletions src/game/client/c_baseplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ END_RECV_TABLE()

RecvPropFloat ( RECVINFO( m_flDeathTime )),

#ifndef NEO
RecvPropInt ( RECVINFO( m_nWaterLevel ) ),
#endif // NEO
RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )),

END_RECV_TABLE()
Expand Down Expand Up @@ -322,6 +324,10 @@ END_RECV_TABLE()

RecvPropString( RECVINFO(m_szLastPlaceName) ),

#ifdef NEO
RecvPropInt ( RECVINFO( m_nWaterLevel ) ),
#endif // NEO

#if defined USES_ECON_ITEMS
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, RecvPropEHandle(NULL, 0, 0) ),
#endif
Expand Down
189 changes: 189 additions & 0 deletions src/game/client/fx_water.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,139 @@ void FX_GunshotSplash( const Vector &origin, const Vector &normal, float scale )
C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep );
}

#ifdef NEO
void FX_PlayerSplash( const Vector &origin, const Vector &normal, float scale )
{
VPROF_BUDGET( "FX_PlayerSplash", VPROF_BUDGETGROUP_PARTICLE_RENDERING );

if ( cl_show_splashes.GetBool() == false )
return;

Vector color;
float luminosity;

// Get our lighting information
FX_GetSplashLighting( origin + ( normal * scale ), &color, &luminosity );

float flScale = scale / 8.0f;

if ( flScale > 4.0f )
{
flScale = 4.0f;
}

// Setup our trail emitter
CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" );

if ( !sparkEmitter )
return;

sparkEmitter->SetSortOrigin( origin );
sparkEmitter->m_ParticleCollision.SetGravity( 800.0f );
sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
sparkEmitter->SetVelocityDampen( 2.0f );
sparkEmitter->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) );

PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" );

TrailParticle *tParticle;

Vector offDir;
Vector offset;
float colorRamp;

//Dump out drops
for ( int i = 0; i < 16; i++ )
{
offset = origin;
offset[0] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
offset[1] += random->RandomFloat( -8.0f, 8.0f ) * flScale;

tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );

if ( tParticle == NULL )
break;

tParticle->m_flLifetime = 0.0f;
tParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );

offDir = normal + RandomVector( -0.8f, 0.8f );

tParticle->m_vecVelocity = offDir * random->RandomFloat( SPLASH_MIN_SPEED * flScale * 3.0f, SPLASH_MAX_SPEED * flScale * 3.0f );
tParticle->m_vecVelocity[2] += random->RandomFloat( 32.0f, 64.0f ) * flScale;

tParticle->m_flWidth = random->RandomFloat( 1.0f, 3.0f );
tParticle->m_flLength = random->RandomFloat( 0.025f, 0.05f );

colorRamp = random->RandomFloat( 0.75f, 1.25f );

tParticle->m_color.r = MIN( 1.0f, color[0] * colorRamp ) * 255;
tParticle->m_color.g = MIN( 1.0f, color[1] * colorRamp ) * 255;
tParticle->m_color.b = MIN( 1.0f, color[2] * colorRamp ) * 255;
tParticle->m_color.a = luminosity * 255;
}

// Setup the particle emitter
CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
Copy link
Copy Markdown
Contributor

@sunzenshen sunzenshen Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to sanity check, but is this intentionally not "splash" to not conflict with an exiting name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter is called debugName so I don't think it should matter, but CSplashParticle::Create uses splish everywhere far as I can tell

Image

pSimple->SetSortOrigin( origin );
pSimple->SetClipHeight( origin.z );
pSimple->SetParticleCullRadius( scale * 2.0f );
pSimple->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) );

SimpleParticle *pParticle;

//Main gout
for ( int i = 0; i < 8; i++ )
{
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, origin );

if ( pParticle == NULL )
break;

pParticle->m_flLifetime = 0.0f;
pParticle->m_flDieTime = 2.0f; //NOTENOTE: We use a clip plane to realistically control our lifespan

pParticle->m_vecVelocity.Random( -0.2f, 0.2f );
pParticle->m_vecVelocity += ( normal * random->RandomFloat( 4.0f, 6.0f ) );

VectorNormalize( pParticle->m_vecVelocity );

pParticle->m_vecVelocity *= 50 * flScale * (8-i);

colorRamp = random->RandomFloat( 0.75f, 1.25f );

pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;

pParticle->m_uchStartSize = 24 * flScale * RemapValClamped( i, 7, 0, 1, 0.5f );
pParticle->m_uchEndSize = MIN( 255, pParticle->m_uchStartSize * 2 );

pParticle->m_uchStartAlpha = RemapValClamped( i, 7, 0, 255, 32 ) * luminosity;
pParticle->m_uchEndAlpha = 0;

pParticle->m_flRoll = random->RandomInt( 0, 360 );
pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f );
}

// Do a ripple
FX_WaterRipple( origin, flScale, &color, 1.5f, luminosity );

//Play a sound
CLocalPlayerFilter filter;

EmitSound_t ep;
ep.m_nChannel = CHAN_VOICE;
ep.m_pSoundName = "Physics.WaterSplash";
ep.m_flVolume = 0.5f;
ep.m_SoundLevel = SNDLVL_NORM;
ep.m_pOrigin = &origin;


C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep );
}
#endif // NEO

//-----------------------------------------------------------------------------
// Purpose:
// Input : &origin -
Expand Down Expand Up @@ -409,6 +542,43 @@ void FX_GunshotSlimeSplash( const Vector &origin, const Vector &normal, float sc
C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep );
}

#ifdef NEO
void FX_PlayerSlimeSplash( const Vector &origin, const Vector &normal, float scale )
{
if ( cl_show_splashes.GetBool() == false )
return;

VPROF_BUDGET( "FX_PlayerSlimeSplash", VPROF_BUDGETGROUP_PARTICLE_RENDERING );

QAngle vecAngles;
VectorAngles( normal, vecAngles );
if ( scale < 2.0f )
{
DispatchParticleEffect( "slime_splash_01", origin, vecAngles );
}
else if ( scale < 4.0f )
{
DispatchParticleEffect( "slime_splash_02", origin, vecAngles );
}
else
{
DispatchParticleEffect( "slime_splash_03", origin, vecAngles );
}

//Play a sound
CLocalPlayerFilter filter;

EmitSound_t ep;
ep.m_nChannel = CHAN_VOICE;
ep.m_pSoundName = "Physics.WaterSplash";
ep.m_flVolume = 0.5f;
ep.m_SoundLevel = SNDLVL_NORM;
ep.m_pOrigin = &origin;

C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep );
}
#endif // NEO

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Expand All @@ -430,6 +600,25 @@ void SplashCallback( const CEffectData &data )

DECLARE_CLIENT_EFFECT( "watersplash", SplashCallback );

#ifdef NEO
void PlayerSplashCallback( const CEffectData &data )
{
Vector normal;

AngleVectors( data.m_vAngles, &normal );

if ( data.m_fFlags & FX_WATER_IN_SLIME )
{
FX_PlayerSlimeSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale );
}
else
{
FX_PlayerSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale );
}
}

DECLARE_CLIENT_EFFECT( "playersplash", PlayerSplashCallback );
#endif // NEO

//-----------------------------------------------------------------------------
// Purpose:
Expand Down
1 change: 1 addition & 0 deletions src/game/client/neo/c_neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class C_NEO_Player : public C_HL2MP_Player
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
const char* GetOverrideStepSound(const char* pBaseStepSound) override;
virtual void Splash() override;
virtual void DoImpactEffect( trace_t &tr, int nDamageType );
IRagdoll* GetRepresentativeRagdoll() const;
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
Expand Down
1 change: 1 addition & 0 deletions src/game/server/neo/neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class CNEO_Player : public CHL2MP_Player
virtual void PickupObject(CBaseEntity *pObject, bool bLimitMassAndSize) OVERRIDE;
virtual void PlayStepSound(Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force) OVERRIDE;
const char* GetOverrideStepSound(const char* pBaseStepSound) override;
virtual void Splash() override;
virtual void Weapon_Drop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL) OVERRIDE;
void Weapon_DropOnDeath(CNEOBaseCombatWeapon *pWeapon, Vector damageForce);
void Weapon_DropAllOnDeath(const CTakeDamageInfo &info);
Expand Down
6 changes: 6 additions & 0 deletions src/game/server/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8496,7 +8496,9 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi

SendPropFloat ( SENDINFO( m_flDeathTime ), 0, SPROP_NOSCALE ),

#ifndef NEO
SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ),
#endif // NEO
SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ),

END_SEND_TABLE()
Expand Down Expand Up @@ -8536,6 +8538,10 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi
SendPropArray ( SendPropEHandle( SENDINFO_ARRAY( m_hViewModel ) ), m_hViewModel ),
SendPropString (SENDINFO(m_szLastPlaceName) ),

#ifdef NEO
SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ),
#endif // NEO

#if defined USES_ECON_ITEMS
SendPropUtlVector( SENDINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, SendPropEHandle( NULL, 0 ) ),
#endif // USES_ECON_ITEMS
Expand Down
4 changes: 4 additions & 0 deletions src/game/shared/gamemovement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2251,9 +2251,13 @@ void CGameMovement::FullWalkMove( )
( m_nOldWaterLevel != WL_NotInWater && player->GetWaterLevel() == WL_NotInWater ) )
{
PlaySwimSound();
#ifdef NEO
player->Splash();
#else
#if !defined( CLIENT_DLL )
player->Splash();
#endif
#endif // NEO
}
}

Expand Down
40 changes: 40 additions & 0 deletions src/game/shared/neo/neo_player_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@

#include "weapon_neobasecombatweapon.h"

#include "effect_dispatch_data.h"
#ifdef GAME_DLL
#include "te_effect_dispatch.h"
#else
#include "c_te_effect_dispatch.h"
#endif // GAME_DLL

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

Expand Down Expand Up @@ -393,3 +400,36 @@ void CNEO_Player::CheckAimButtons()
Weapon_SetZoom(false);
}
}

void CNEO_Player::Splash()
{
CEffectData data;
data.m_fFlags = 0;
data.m_vOrigin = GetAbsOrigin();
data.m_vNormal = Vector(0,0,1);
data.m_vAngles = QAngle( 0, 0, 0 );

if ( GetWaterType() & CONTENTS_SLIME )
{
data.m_fFlags |= FX_WATER_IN_SLIME;
}

#ifdef GAME_DLL
CPASFilter filter( data.m_vOrigin );
#else
CLocalPlayerFilter filter;
#endif // GAME_DLL

float flSpeedSqr = GetAbsVelocity().LengthSqr();
constexpr int SPLASH_SPEED_THRESHOLD = 300;
if ( flSpeedSqr < SPLASH_SPEED_THRESHOLD * SPLASH_SPEED_THRESHOLD )
{
data.m_flScale = random->RandomFloat( 10, 12 );
DispatchEffect( "waterripple", data, filter );
}
else
{
data.m_flScale = random->RandomFloat( 6, 8 );
DispatchEffect( "playersplash", data, filter );
}
}
Loading