General SDK Snippets & Fixes
Contents
- 1 Snippets
- 1.1 Fixing imported CS:S weapons in HL2 based mods
- 1.2 Crossbow bolt going through glass (func_breakable)
- 1.3 Ignite ragdolls
- 1.4 Control height and width of icon progress bars
- 1.5 Enabling func_precipitation rendering whilst in a point_viewcontrol
- 1.6 Randomizing models
- 1.7 Simple camera animation implementation for weapons
- 1.8 A way to suppress the "Node Graph out of Date. Rebuilding..." message
- 1.9 Self casting player shadows
- 1.10 Enabling shadow receiving on viewmodels
- 1.11 Seamless cubemaps hack
- 1.12 Remove ear ringing from explosions
- 2 Fixes
- 2.1 Stopping viewmodels from getting rotated when zooming
- 2.2 Restoring the Combine Elite Soldier's ability to use the alt-fire of the SMG1
- 2.3 Restoring Dropship container gun rotation functionality
- 2.4 Fixing the acid damage white flash sticking around bug
- 2.5 Schrodinger's/Quantum crouch fix
- 2.6 Fixing the NPC not blinking bug
- 2.7 Fix smooth friction sounds using the incorrect soundhandle
- 2.8 Restoring the Combine Soldier's ability to emit pain sounds
- 2.9 Restoring ability to disallow player holstering weapons in Multiplayer
- 2.10 Fix env_sun sprite disappearing in sky when you look at it
- 2.11 Fix for viewmodel FOV going into negative integers
Snippets
Fixing imported CS:S weapons in HL2 based mods
Crossbow bolt going through glass (func_breakable)
Open src/game/server/hl2/weapon_crossbow.cpp
Start off by adding #include "func_break.h"
Then in
, after:
CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
return;
Insert the following code:
if ( FClassnameIs(pOther, "func_breakable") )
{
CBreakable* pOtherEntity = static_cast<CBreakable*>( pOther );
if ( pOtherEntity->GetMaterialType() == matGlass )
return;
}
matWeb
or through any func_breakable_surf for example.Ignite ragdolls
In your player's class (CSDKPlayer
or CBasePlayer
) find the Event_Killed()
function. Add this inside of it:
if( info.GetDamageType() & (DMG_BLAST|DMG_BURN) )
{
if( m_hRagdoll )
{
CBaseAnimating *pRagdoll = (CBaseAnimating *)CBaseEntity::Instance(m_hRagdoll);
if( info.GetDamageType() & (DMG_BURN|DMG_BLAST) )
{
pRagdoll->Ignite(45, false, 10 );
}
}
}
If you don't have a ragdoll to ignite before that is called, make sure that code is placed after a call to CreateRagdollEntity()
.
If you're not doing that, add it in right above the if( info.GetDamageType() & (DMG_BLAST|DMG_BURN) )
line.
Control height and width of icon progress bars
This allows you to control the height and width of progress bars drawn with icons instead of the bars being the same dimensions as the textures.
In the file src/game/client/hud.h
add the function declaration:
void DrawIconProgressBarExt( int x, int y, int w, int h, CHudTexture *icon, CHudTexture *icon2, float percentage, Color &clr, int type );
Underneath the old declaration:
void DrawIconProgressBar( int x, int y, CHudTexture *icon, CHudTexture *icon2, float percentage, Color& clr, int type );
Then in src/game/client/hud_redraw.cpp
add the function itself:
void CHud::DrawIconProgressBarExt( int x, int y, int w, int h, CHudTexture *icon, CHudTexture *icon2, float percentage, Color& clr, int type )
{
if ( icon == NULL )
return;
//Clamp our percentage
percentage = min( 1.0f, percentage );
percentage = max( 0.0f, percentage );
int height = icon->Height();
int width = icon->Width();
//Draw a vertical progress bar
if ( type == HUDPB_VERTICAL )
{
int barOfs = height * percentage;
icon2->DrawSelfCropped(
x, y, // Pos
0, 0, width, barOfs, // Cropped subrect
w, (h * percentage), clr );
icon->DrawSelfCropped(
x, y + (h * percentage),
0, barOfs, width, height - barOfs, // Cropped subrect
w, h - (h * percentage), clr );
}
}
This was tested with vertical bars, horizontal bars haven't been tested.
Enabling func_precipitation rendering whilst in a point_viewcontrol
In src/game/client/viewrender.cpp
find and delete:
if ( CurrentViewID() == VIEW_MONITOR )
return;
Randomizing models
Have some global constant char* of every model:
static const char* modelnames[] = {
"Model1", // 0
"Model2", // 1
"Model3", // 2
};
And choose one at random in the
function:
Spawn()
SetModel (modelnames[ random->RandomInt( 0, ARRAYSIZE(modelnames) - 1 ) ]);
And if you wish to have a different skin for each model (provided your model was compiled with multiple skins), then you can add:
m_nSkin = random->RandomInt( 0, GetModelPtr()->numskinfamilies() - 1 );
Simple camera animation implementation for weapons
Go to src/game/client/view.cpp
then head over to void CViewRender::Render( vrect_t *rect )
Scroll down until you find
, then paste this code above it:
RenderView( view, nClearFlags, flags );
if ( pPlayer && pPlayer->InFirstPersonView() && pPlayer->GetViewModel( 0 ) )
{
int iCamAttachment = pPlayer->GetViewModel( 0 )->LookupAttachment( "camera" );
if ( iCamAttachment != -1 )
{
Vector cameraOrigin = Vector(0, 0, 0);
QAngle cameraAngles = QAngle(0, 0, 0);
pPlayer->GetViewModel( 0 )->GetAttachmentLocal( iCamAttachment, cameraOrigin, cameraAngles );
view.angles += cameraAngles;
view.origin += cameraOrigin;
}
}
A way to suppress the "Node Graph out of Date. Rebuilding..." message
This snippet will hide the message from appearing unless developer mode is enabled.
Go to src/game/server/ai_networkmanager.cpp
then head over to void CAI_NetworkManager::DelayedInit( void )
Scroll down until you find this line of code: (Should be near line 1113)
UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" );
And simply change it this:
if ( developer.GetBool() )
UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" );
Self casting player shadows
Go to src/game/client/c_baseplayer.h
, scroll down until you find
virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
and simply change that to:
virtual ShadowType_t ShadowCastType() { return SHADOWS_RENDER_TO_TEXTURE_DYNAMIC; }
Your playermodel (by default player.mdl) should now cast shadows.
Enabling shadow receiving on viewmodels
Go to src/game/shared/baseviewmodel_shared.h
, scroll down until you find
virtual bool ShouldReceiveProjectedTextures( int flags )
{
return false;
}
and simply change that to:
virtual bool ShouldReceiveProjectedTextures( int flags )
{
return true;
}
Your viewmodels should now be able to receive shadows.
Seamless cubemaps hack
Go to src/game/client/viewrender.cpp
, scroll down until you find the
function, then add this snippet:
RenderView( ... )
void CViewRender::RenderView( const CViewSetup &viewIn, int nClearFlags, int whatToDraw )
{
m_UnderWaterOverlayMaterial.Shutdown(); // underwater view will set
m_CurrentView = view;
if ( building_cubemaps.GetBool() )
m_CurrentView.fov = RAD2DEG( 2.0f * atanf( 64.0f / ( 64 - 0.5f ) ) );
}
You should now have seamless cubemaps!
Remove ear ringing from explosions
If you find the ear ringing to be annoying and want to remove it, simply go to src/game/server/player.cpp
, go to
, find this line:
void CBasePlayer::OnDamagedByExplosion
int effect = shock ?
random->RandomInt( 35, 37 ) :
random->RandomInt( 32, 34 );
and replace it with this:
int effect = random->RandomInt( 32, 34 );
Fixes
Stopping viewmodels from getting rotated when zooming
In src/game/client/view.cpp
find
and search for the line
void CViewRender::SetUpViews()
view.fovViewmodel = g_pClientMode->GetViewModelFOV() - flFOVOffset;
and replace it with
view.fovViewmodel = fabs( g_pClientMode->GetViewModelFOV() - flFOVOffset );
That will simply stop negative FOVs to occur, which were causing a rotating of 180ยฐ.
Restoring the Combine Elite Soldier's ability to use the alt-fire of the SMG1
In src/game/server/hl2/weapon_smg1.cpp
, go to line 48 and replace
with this:
WeaponRangeAttack2Condition( float flDot, float flDist )
int WeaponRangeAttack2Condition();
Now from the lines 249 to 274 (all the disabled code) replace it with this code:
case EVENT_WEAPON_AR2_ALTFIRE:
{
CAI_BaseNPC *npc = pOperator->MyNPCPointer();
Vector vecShootOrigin, vecShootDir;
vecShootOrigin = pOperator->Weapon_ShootPosition();
//vecShootDir = npc->GetShootEnemyDir( vecShootOrigin );
//Checks if it can fire the grenade
WeaponRangeAttack2Condition();
Vector vecThrow = m_vecTossVelocity;
//If on the rare case the vector is 0 0 0, cancel for avoid launching the grenade without speed
//This should be on WeaponRangeAttack2Condition(), but for some unknown reason return CASE_NONE
//doesn't stop the launch
if (vecThrow == Vector(0, 0, 0)){
break;
}
CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create("grenade_ar2", vecShootOrigin, vec3_angle, npc);
pGrenade->SetAbsVelocity( vecThrow );
pGrenade->SetLocalAngularVelocity(RandomAngle(-400, 400)); //tumble in air
pGrenade->SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
pGrenade->SetThrower(GetOwner());
pGrenade->SetGravity(0.5); // lower gravity since grenade is aerodynamic and engine doesn't know it.
pGrenade->SetDamage(sk_plr_dmg_smg1_grenade.GetFloat());
if (g_pGameRules->IsSkillLevel(SKILL_HARD))
{
m_flNextGrenadeCheck = gpGlobals->curtime + RandomFloat(2, 3);
}
else{
m_flNextGrenadeCheck = gpGlobals->curtime + 6;// wait six seconds before even looking again to see if a grenade can be thrown.
}
m_iClip2--;
}
break;
Now go to the
function and replace it with this:
int CWeaponSMG1::WeaponRangeAttack2Condition( float flDot, float flDist )
int CWeaponSMG1::WeaponRangeAttack2Condition()
And near the top of the function, comment out return COND_NONE;
like so:
//return COND_NONE;
For the last step, since this is only cosmetic, go to src/game/server/hl2/npc_combine.cpp
.
On line 381, disable the DevWarning
(only in case you don't want to see it neither on DEV mode):
//DevWarning("**Combine Elite Soldier MUST be equipped with AR2\n");
Between lines 2321 and 2325, you can replace that part of the code with the following, so you no longer hear the AR2 effect when using the SMG1:
if ( pEvent->event == COMBINE_AE_BEGIN_ALTFIRE )
{
//We want it to use different sounds depending on the weapon
if ( FClassnameIs(GetActiveWeapon(), "weapon_ar2") )
{
EmitSound( "Weapon_CombineGuard.Special1" );
}
else if ( FClassnameIs(GetActiveWeapon(), "weapon_smg1") )
{
EmitSound( "Weapon_SMG1.Double" );
}
else
{
EmitSound( "Weapon_CombineGuard.Special1" ); // We let this play by default
}
handledEvent = true;
}
Restoring Dropship container gun rotation functionality
This bug has been fixed in the 2022 Steam Deck update for Half-Life 2 (and it's episodes), but the SDK 2013 code still remains unfixed.
This is to make it so that the gun on the combine dropship can rotate again
Go to line 898 in src/game/server/hl2/npc_combinedropship.cpp
and in the
function insert the following lines
Spawn( void )
// Store spawned container weapon pitch and yaw pose parameters to allow weapon point to the player
m_poseWeapon_Pitch = m_hContainer->LookupPoseParameter( "weapon_pitch" );
m_poseWeapon_Yaw = m_hContainer->LookupPoseParameter( "weapon_yaw" );
so the Spawn( void )
function code fragment will look like this
m_iMachineGunBaseAttachment = m_hContainer->LookupAttachment( "gun_base" );
// NOTE: gun_ref must have the same position as gun_base, but rotates with the gun
m_iMachineGunRefAttachment = m_hContainer->LookupAttachment( "gun_ref" );
// Store spawned container weapon pitch and yaw pose parameters to allow weapon point to the player
m_poseWeapon_Pitch = m_hContainer->LookupPoseParameter( "weapon_pitch" );
m_poseWeapon_Yaw = m_hContainer->LookupPoseParameter( "weapon_yaw" );
Go to line 864 in src/game/server/hl2/npc_combinedropship.cpp
and in the
function insert the following lines
Spawn( void )
m_poseWeapon_Pitch = -1;
m_poseWeapon_Yaw = -1;
so the Spawn( void )
function code fragment will look like this
m_iAttachmentTroopDeploy = -1;
m_iAttachmentDeployStart = -1;
m_poseWeapon_Pitch = -1;
m_poseWeapon_Yaw = -1;
// create the correct bin for the ship to carry
switch ( m_iCrateType )
{
case CRATE_ROLLER_HOPPER:
break;
Go to line 397 in src/game/server/hl2/npc_combinedropship.cpp
and in the
function add the following lines
PopulatePoseParameters( void )
// Dropship has any kind of container
if ( m_hContainer )
{
// Restore container weapon pose parameters on load if any found
m_poseWeapon_Pitch = m_hContainer->LookupPoseParameter( "weapon_pitch" );
m_poseWeapon_Yaw = m_hContainer->LookupPoseParameter( "weapon_yaw" );
}
Go to line 392 in src/game/server/hl2/npc_combinedropship.cpp
and in the
function remove the following lines
PopulatePoseParameters( void )
m_poseWeapon_Pitch = LookupPoseParameter( "weapon_pitch" );
m_poseWeapon_Yaw = LookupPoseParameter( "weapon_yaw" );
so the final PopulatePoseParameters( void )
function will look like this
void CNPC_CombineDropship::PopulatePoseParameters( void )
{
if (!m_sbStaticPoseParamsLoaded)
{
m_poseBody_Accel = LookupPoseParameter( "body_accel");
m_poseBody_Sway = LookupPoseParameter( "body_sway" );
m_poseCargo_Body_Accel = LookupPoseParameter( "cargo_body_accel" );
m_poseCargo_Body_Sway = LookupPoseParameter( "cargo_body_sway" );
m_sbStaticPoseParamsLoaded = true;
}
// Dropship has any kind of container
if ( m_hContainer )
{
// Restore container weapon pose parameters on load if any found
m_poseWeapon_Pitch = m_hContainer->LookupPoseParameter( "weapon_pitch" );
m_poseWeapon_Yaw = m_hContainer->LookupPoseParameter( "weapon_yaw" );
}
BaseClass::PopulatePoseParameters();
}
Go to line 378 in src/game/server/hl2/npc_combinedropship.cpp
and remove the following lines
int CNPC_CombineDropship::m_poseWeapon_Pitch = 0;
int CNPC_CombineDropship::m_poseWeapon_Yaw = 0;
Go to line 366 in src/game/server/hl2/npc_combinedropship.cpp
and remove trailing ,
and the following lines
m_poseWeapon_Pitch, m_poseWeapon_Yaw
so the code will look like this
static int m_poseBody_Accel, m_poseBody_Sway, m_poseCargo_Body_Accel, m_poseCargo_Body_Sway;
static bool m_sbStaticPoseParamsLoaded;
Go to line 346 in src/game/server/hl2/npc_combinedropship.cpp
and add the following lines after int m_iAttachmentDeployStart;
// Cached container weapon pose parameters
int m_poseWeapon_Pitch;
int m_poseWeapon_Yaw;
so the code will look like this
int m_iAttachmentTroopDeploy;
int m_iAttachmentDeployStart;
// Cached container weapon pose parameters
int m_poseWeapon_Pitch;
int m_poseWeapon_Yaw;
Now your gun should rotate and shoot again!
Fixing the acid damage white flash sticking around bug
This is a very easy fix, I'm surprised no one has patched this.
Go to src/game/shared/hl2/hl2_gamerules.cpp
and at line 209 add DMG_ACID
, like so:
return ( ( iDmgType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) ) != 0 );
And it's fixed. Someone, please spread this knowledge.
Schrodinger's/Quantum crouch fix
See: https://wiki.sourceruns.org/wiki/Schrodinger's_Crouch
Another easy fix.
Go to src/game/shared/gamemovement.cpp
then head over to void CGameMovement::FinishDuck( void )
(Line 4194)
At the very top, you should see this:
if ( player->GetFlags() & FL_DUCKING )
return;
Now all you have to do is comment it out, that's it!
Fixing the NPC not blinking bug
NPCs not being able to blink has been a bug for mods ever since the Steampipe update. It was fixed in an update for Half-Life 2 + its Episodes (/) on the 26th of September 2019, but the code was never pushed to the Source 2013 public repo.
Fixing this is as easy as correcting a single line of code.
Go to src/game/client/c_baseflex.cpp
then head over to the void C_BaseFlex::SetupWeights( ... )
function.
Then at line 1152 correct the following line of code from:
m_iBlink = AddGlobalFlexController( "UH" );
to
m_iBlink = AddGlobalFlexController( "blink" );
Congratulations! You have successfully fixed NPC blinking, it was as easy as that.
Fix smooth friction sounds using the incorrect soundhandle
Fixes a tiny inconsistency. The bug causes the incorrect sound params to be used.
Go to src/game/shared/physics_shared.cpp
then head over to void PhysFrictionSound( ... )
Near the bottom of the function, you should see this line of code within an if
statement:
soundHandle = &psurf->soundhandles.scrapeRough;
Now all you have to do is change that to this:
soundHandle = &psurf->soundhandles.scrapeSmooth;
Restoring the Combine Soldier's ability to emit pain sounds
Go to src/game/server/hl2/npc_combine.h and find void PainSound( void );
And change it to this:
void PainSound( const CTakeDamageInfo &info );
Now head over to src/game/server/hl2/npc_combine.cpp
and find void CNPC_Combine::PainSound ( void )
And like before, change it to this:
void CNPC_Combine::PainSound( const CTakeDamageInfo &info )
Restoring ability to disallow player holstering weapons in Multiplayer
Everyone knows about this bug, but fix here is very simple, go to src/game/shared/basecombatweapon_shared.h, then remove const
at 248 line.
Now it should look like:
virtual bool CanHolster( void ) { return TRUE; }; // returns true if the weapon can be holstered
That's it, now you can use CanHolster for weapons!
Fix env_sun sprite disappearing in sky when you look at it
Yet another famous glitch, fix for it is very easy, go to src/game/client/glow_overlay.cpp
, find 162 line then replace zFar * 0.999f; with 0.99f;
Now it should look like:
Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.99f;
Now env_sun sprite shouldn't disappear when you look at it.
Fix for viewmodel FOV going into negative integers
This glitch is most obvious when using zoom on higher than normal fov's like 120 or 150.
To fix; go to src/game/client/view.cpp
and on line 739 change this:
//Adjust the viewmodel's FOV to move with any FOV offsets on the viewer's end
view.fovViewmodel = g_pClientMode->GetViewModelFOV() - flFOVOffset;
To this:
//Adjust the viewmodel's FOV to move with any FOV offsets on the viewer's end
view.fovViewmodel = fabs( g_pClientMode->GetViewModelFOV() - MIN( flFOVOffset, g_pClientMode->GetViewModelFOV() ) );
Now viewmodels won't look super wonky when zooming with higher than normal fov's!