Dynamic NPC Footsteps
Jump to navigation
Jump to search
Similarly to Half-Life, Half-Life 2 contained no dynamic footsteps; dynamic footsteps meaning that they change when different surfaces are walked on.
src\cl_dll\c_baseanimating.h
Includes
- vphysics_interface.h
Private Prototypes
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity, bool left ); virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool left ); virtual surfacedata_t* GetGroundSurface();
src\cl_dll\c_baseanimating.cpp
-
Includes
- decals.h
- soundemittersystem/isoundemittersystembase.h
Player Cloned Functions
extern ConVar sv_footsteps; void C_BaseAnimating::UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity, bool left ) { int fWalking; float fvol; Vector knee; Vector feet; float height; float velrun; float velwalk; if ( GetFlags() & (FL_FROZEN|FL_ATCONTROLS)) return; if ( !sv_footsteps.GetFloat() ) return; float groundspeed = vecVelocity.Length2DSqr() bool movingalongground = ( groundspeed > 0.0f ); // To hear step sounds you must be either on a ladder or moving along the ground AND // You must be moving fast enough if ( !movingalongground ) return; fWalking = groundspeed < RUN_SPEED_ESTIMATE_SQR; VectorCopy( vecOrigin, knee ); VectorCopy( vecOrigin, feet ); height = GetCollideable()->OBBMaxs()[ 2 ] - GetCollideable()->OBBMins()[ 2 ]; knee[2] = vecOrigin[2] + 0.2 * height; // find out what we're stepping in or on... if ( enginetrace->GetPointContents( knee ) & MASK_WATER ) { static int iSkipStep = 0; if ( iSkipStep == 0 ) { iSkipStep++; return; } if ( iSkipStep++ == 3 ) { iSkipStep = 0; } psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "wade" ) ); fvol = 0.65; } else if ( enginetrace->GetPointContents( feet ) & MASK_WATER ) { psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "water" ) ); fvol = fWalking ? 0.2 : 0.5; } else { if ( !psurface ) return; switch ( psurface->game.material ) { default: case CHAR_TEX_CONCRETE: fvol = fWalking ? 0.2 : 0.5; break; case CHAR_TEX_METAL: fvol = fWalking ? 0.2 : 0.5; break; case CHAR_TEX_DIRT: fvol = fWalking ? 0.25 : 0.55; break; case CHAR_TEX_VENT: fvol = fWalking ? 0.4 : 0.7; break; case CHAR_TEX_GRATE: fvol = fWalking ? 0.2 : 0.5; break; case CHAR_TEX_TILE: fvol = fWalking ? 0.2 : 0.5; break; case CHAR_TEX_SLOSH: fvol = fWalking ? 0.2 : 0.5; break; } } // play the sound // 65% volume if ducking if ( GetFlags() & FL_DUCKING ) { fvol *= 0.65; } PlayStepSound( feet, psurface, fvol, left ); } void C_BaseAnimating::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool left ) { if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() ) return; if ( !psurface ) return; unsigned short stepSoundName = left ? psurface->sounds.stepleft : psurface->sounds.stepright; if ( !stepSoundName ) return; const char *pSoundName = physprops->GetString( stepSoundName ); CSoundParameters params; if ( !CBaseEntity::GetParametersForSound( pSoundName, params, NULL ) ) return; CPASFilter filter(vecOrigin); EmitSound_t ep; ep.m_nChannel = CHAN_BODY; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nFlags = 0; ep.m_nPitch = params.pitch; ep.m_pOrigin = &vecOrigin; EmitSound( filter, entindex(), ep ); } surfacedata_t* C_BaseAnimating::GetGroundSurface() { // // Find the name of the material that lies beneath the player. // Vector start, end; VectorCopy( GetAbsOrigin(), start ); VectorCopy( start, end ); // Straight down end.z -= 64; // Fill in default values, just in case. Ray_t ray; ray.Init( start, end, GetCollideable()->OBBMins(), GetCollideable()->OBBMaxs() ); trace_t trace; UTIL_TraceRay( ray, MASK_NPCSOLID, this, COLLISION_GROUP_NPC, &trace ); if ( trace.fraction == 1.0f ) return NULL; // no ground return physprops->GetSurfaceData( trace.surface.surfaceProps ); }
Left Foot
Note:This overrides all NPC footsteps; this means the Combine will not sound like they used to when they walk. An extra addition would need to be taken regarding another
EmitSound
to still include the original sound.#ifndef HL2MP char pSoundName[256]; if ( !options || !options[0] ) { options = "NPC_CombineS"; } Vector vel; EstimateAbsVelocity( vel ); // If he's moving fast enough, play the run sound if ( vel.Length2DSqr() > RUN_SPEED_ESTIMATE_SQR ) { Q_snprintf( pSoundName, 256, "%s.RunFootstepLeft", options ); } else { Q_snprintf( pSoundName, 256, "%s.FootstepLeft", options ); } EmitSound( pSoundName ); #endif
↓ if(IsNPC()) { Vector vel; EstimateAbsVelocity( vel ); UpdateStepSound( GetGroundSurface(), GetAbsOrigin(), vel, true ); }
Right Foot
Note:This overrides all NPC footsteps; this means the Combine will not sound like they used to when they walk. An extra addition would need to be taken regarding another
EmitSound
to still include the original sound.#ifndef HL2MP char pSoundName[256]; if ( !options || !options[0] ) { options = "NPC_CombineS"; } Vector vel; EstimateAbsVelocity( vel ); // If he's moving fast enough, play the run sound if ( vel.Length2DSqr() > RUN_SPEED_ESTIMATE_SQR ) { Q_snprintf( pSoundName, 256, "%s.RunFootstepRight", options ); } else { Q_snprintf( pSoundName, 256, "%s.FootstepRight", options ); } EmitSound( pSoundName ); #endif
↓ if(IsNPC()) { Vector vel; EstimateAbsVelocity( vel ); UpdateStepSound( GetGroundSurface(), GetAbsOrigin(), vel, false); }