TF2 Glow Effect (2013 SDK): Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
m (→‎Usage: Substituted IO templates)
 
(13 intermediate revisions by 7 users not shown)
Line 1: Line 1:
= Activation =
__FORCETOC__
<!-- {{screenshot}} -->
[[File:glow_tutorial_2013_finalres.png|thumb|The glow effect applied with this tutorial.]]
=Activation=


* Add GLOWS_ENABLE to the preprocessor directives on your client and server projects (don't forget to add it for release and debug, too!)
* Add {{Key|GLOWS_ENABLE}} to the preprocessor directives on your client and server projects (don't forget to add it for release and debug, too!)
* Add the following line to '''ClientModeShared::DoPostScreenSpaceEffects''':
* Add the following line to '''ClientModeShared::DoPostScreenSpaceEffects''':


Line 8: Line 11:
</source>
</source>


* Create a .VMT file in /materials/dev/ called "glow_color.vmt" with the following contents:
 
<source>
'''Materials Required:'''
UnlitGeneric
[https://www.dropbox.com/s/ltyomrglekrhriv/sdk2013_tf2_glowoutlinematerials.zip?dl=0 SDK2013_TF2_GlowOutlineMaterials.zip]
{
 
    $basetexture red // or white, or whatever you like
    $ignorez 1
    $model 1
    $linearwrite 1
}
</source>


* Precache the effect by placing this code in '''clientmode_shared.cpp''' (search for other references of '''CLIENTEFFECT_REGISTER_BEGIN''' for usage example):
* Precache the effect by placing this code in '''clientmode_shared.cpp''' (search for other references of '''CLIENTEFFECT_REGISTER_BEGIN''' for usage example):
Line 24: Line 21:
CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffectsGlow )
CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffectsGlow )
CLIENTEFFECT_MATERIAL( "dev/glow_color" )
CLIENTEFFECT_MATERIAL( "dev/glow_color" )
CLIENTEFFECT_MATERIAL( "dev/halo_add_to_screen" )
CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 )
CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 )
</source>
</source>


= Usage =
Don't forget to add the include defintion for the precache system!
<source lang=cpp>
#include "clienteffectprecachesystem.h"
</source>
 
=(Optional) Transferring getters and setters from CBaseCombatCharacter=
{{Important|This part is completely optional if you're okay with how glow works by default you can skip to [[#Usage|usage]] section.}}
{{Note|[[#Adding_color_control_for_glow|Color control]] and [[#I.2FO_control|I/O control]] is possible without following entire transferring tutorial, however both of these subsections assume you have completed transferring tutorial and it's recommended since it allows to use glow on objects like '''prop_dynamic''', etc.}}
By default objects derived from {{Key|CBaseCombatCharacter}} have getters and setters which can be problematic. <br>This section shows how to transfer setters and getters from {{Key|CBaseCombatCharacter}} to {{Key|CBaseAnimating}} since most entities are derived from {{Key|CBaseAnimating}} e.g. {{Key|CBaseCombatCharacter}}, {{Key|CDynamicProp}}, {{Key|CBaseProp}} and more.
 
There are two parts: Server and Client, where we'll start with server first.<br>
Firstly delete this part of code from '''basecombatcharacter.h''' (lines 415-420) and put it into '''baseanimating.h''' (recommended lines 54-58):
<source lang=cpp>
#ifdef GLOWS_ENABLE
public:
void AddGlowEffect(void);
void RemoveGlowEffect(void);
bool IsGlowEffectActive(void);
#endif
</source>
 
After that, do the same thing to this part of code ('''basecombatcharacter.h''', lines 459-462, '''baseanimating.h''' recommended lines 171-174):
<source lang=cpp>
#ifdef GLOWS_ENABLE
protected:
CNetworkVar(bool, m_bGlowEnabled);
#endif
</source>
{{Note|This part of code needs to be in '''protected:''' modifier. If there's no protected modifier make one}}
 
And finally repeat that with this part of code ('''basecombatcharacter.h''', lines 467-468, '''baseanimating.h''' recommended lines 355-356)
<source lang=cpp>
void UpdateGlowEffect( void );
void DestroyGlowEffect( void );
</source>
{{Note|This part of code needs to be in '''private:''' modifier}}
 
Now move to '''basecombatcharacter.cpp''' and '''baseanimating.cpp'''
First part of code to delete from '''basecombatcharacter.cpp''' (lines 193-195) and put it into '''baseanimating.cpp''' (line 230):
<source lang=cpp>
#ifdef GLOWS_ENABLE
SendPropBool( SENDINFO( m_bGlowEnabled ) ),
#endif
</source>
 
Next, from '''basecombatcharacter.cpp''' (lines 744-746) put this part of code into '''baseanimating.cpp''' '''CBaseAnimating::CBaseAnimating'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set( false );
#endif
</source>
 
Lastly delete this from '''basecombatcharacter.cpp''' (lines 3227-3252)
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::AddGlowEffect( void )
{
SetTransmitState( FL_EDICT_ALWAYS );
m_bGlowEnabled.Set( true );
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::RemoveGlowEffect( void )
{
m_bGlowEnabled.Set( false );
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatCharacter::IsGlowEffectActive( void )
{
return m_bGlowEnabled;
}
#endif // GLOWS_ENABLE
</source>
 
and put this part somewhere under '''CBaseAnimating::~CBaseAnimating''' in '''baseanimating.cpp'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::AddGlowEffect(void)
{
SetTransmitState(FL_EDICT_ALWAYS);
m_bGlowEnabled.Set(true);
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::RemoveGlowEffect(void)
{
m_bGlowEnabled.Set(false);
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseAnimating::IsGlowEffectActive(void)
{
return m_bGlowEnabled;
}
#endif
</source>
 
This is the end of server part, now onto client part. We'll be mainly operating on two files '''c_baseanimating.cpp/.h''' and '''c_basecombatcharacter.cpp/.h'''
Firstly delete this part from '''c_basecombatcharacter.h''' (lines 17-19) and put at the top of '''c_baseanimating.h'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
#include "glow_outline_effect.h"
#endif
</source>
 
Secondly is to delete this part of code from '''c_basecombatcharacter.h''' (lines 94-97) and put it into '''c_baseanimating.h''' (recommended lines 149-152)
<source lang=cpp>
#ifdef GLOWS_ENABLE
CGlowObject *GetGlowObject( void ){ return m_pGlowEffect; }
virtual void GetGlowEffectColor( float *r, float *g, float *b );
#endif // GLOWS_ENABLE
</source>
Then repeat that for this for this part of code (from '''c_basecombatcharacter.h''', lines 100-103 to '''c_baseanimating.h''', recommended lines 458-461):
<source lang=cpp>
#ifdef GLOWS_ENABLE
virtual void UpdateGlowEffect(void);
virtual void DestroyGlowEffect(void);
#endif // GLOWS_ENABLE
</source>
And this (from '''c_basecombatcharacter.h''', lines 110-114 to '''c_baseanimating.h''', recommended lines 481-485):
<source lang=cpp>
#ifdef GLOWS_ENABLE
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject *m_pGlowEffect;
#endif
</source>
 
Now go into '''c_basecombatcharacter.cpp''' and '''c_baseanimating.cpp'''
Firstly delete this part of code from '''c_basecombatcharacter.cpp''' (lines 33-37) and put it into '''c_baseanimating.cpp''' (recommended lines 737-741):
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE
</source>
Then delete this part of code from '''C_BaseCombatCharacter::~C_BaseCombatCharacter''' and put it into '''C_BaseAnimating::~C_BaseAnimating'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
DestroyGlowEffect();
#endif // GLOWS_ENABLE
</source>
 
and repeat this for this part of code (from '''c_basecombatcharacter.cpp''', lines 58-60 to '''c_baseanimating.cpp''', recommended lines 4528-4530):
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_bOldGlowEnabled = m_bGlowEnabled;
#endif // GLOWS_ENABLE
</source>
 
and again (from '''c_basecombatcharacter.cpp''', lines 66-71 to '''c_baseanimating.cpp''', recommended lines 4716-4721):
<source lang=cpp>
#ifdef GLOWS_ENABLE
if ( m_bOldGlowEnabled != m_bGlowEnabled )
{
UpdateGlowEffect();
}
#endif // GLOWS_ENABLE
</source>
 
Remove this section of code from '''c_basecombatcharacter.cpp''' (lines 85-128)
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b )
{
*r = 0.76f;
*g = 0.76f;
*b = 0.76f;
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::UpdateGlowEffect( void )
{
// destroy the existing effect
if ( m_pGlowEffect )
{
DestroyGlowEffect();
}
 
// create a new effect
if ( m_bGlowEnabled )
{
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
 
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
}
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::DestroyGlowEffect( void )
{
if ( m_pGlowEffect )
{
delete m_pGlowEffect;
m_pGlowEffect = NULL;
}
}
#endif // GLOWS_ENABLE
</source>
and put this section in '''c_baseanimating.cpp''' (recommended start on line 4387):
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::GetGlowEffectColor( float *r, float *g, float *b )
{
*r = 0.76f;
*g = 0.76f;
*b = 0.76f;
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::UpdateGlowEffect( void )
{
// destroy the existing effect
if ( m_pGlowEffect )
{
DestroyGlowEffect();
}
 
// create a new effect
if ( m_bGlowEnabled )
{
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
 
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
}
}


Objects derived from CBaseEntity are able to glow, but setters and getters for the glow effect only appear to be defined from CBaseCombatCharacter onwards.
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::DestroyGlowEffect( void )
{
if ( m_pGlowEffect )
{
delete m_pGlowEffect;
m_pGlowEffect = NULL;
}
}
#endif // GLOWS_ENABLE
</source>


To start a glow, call:  
and lastly get this part of code from '''c_basecombatcharacter.cpp''' (lines 97-99) and put it into '''c_baseanimating.cpp''' (recommended lines 203-205):
<source lang=cpp>
#ifdef GLOWS_ENABLE
RecvPropBool( RECVINFO( m_bGlowEnabled ) ),
#endif // GLOWS_ENABLE
</source>
And you're done. Now you can create entities with glow (e.g. prop_dynamic, npcs, etc.) as long as they're derived from {{Key|CBaseAnimating}} onwards.
===Adding color control for glow===
This subsection will explain how to add glow color control so you can change color in code.
Firstly open '''baseanimating.h''' and add {{Key|void SetGlowEffectColor(float r, float g, float b);}} like this:
<source lang=cpp>
#ifdef GLOWS_ENABLE
void SetGlowEffectColor(float r, float g, float b);
void AddGlowEffect(void);
void RemoveGlowEffect(void);
bool IsGlowEffectActive(void);
#endif
</source>
then add {{Key|CNetworkVar(float, m_flGlowR);}}, {{Key|CNetworkVar(float, m_flGlowG);}}, {{Key|CNetworkVar(float, m_flGlowB);}} like this:
<source lang=cpp>
// this should be around line 172
#ifdef GLOWS_ENABLE
protected:
CNetworkVar(bool, m_bGlowEnabled);
CNetworkVar(float, m_flGlowR);
CNetworkVar(float, m_flGlowG);
CNetworkVar(float, m_flGlowB);
#endif
</source>
Now in '''baseanimating.cpp''' add {{Key|SendPropFloat(SENDINFO(m_flGlowR)),}}, {{Key|SendPropFloat(SENDINFO(m_flGlowG)),}}, {{Key|SendPropFloat(SENDINFO(m_flGlowB)),}} like this:
<source lang=cpp>
// this should be around line 229
IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating)
#ifdef GLOWS_ENABLE
SendPropBool(SENDINFO(m_bGlowEnabled)),
SendPropFloat(SENDINFO(m_flGlowR)),
SendPropFloat(SENDINFO(m_flGlowG)),
SendPropFloat(SENDINFO(m_flGlowB)),
#endif
</source>
In '''baseanimating.cpp''' add {{Key|m_flGlowR.Set(0.76f);}}, {{Key|m_flGlowG.Set(0.76f);}}, {{Key|m_flGlowB.Set(0.76f);}} like this:
<source lang=cpp>
// this should be around line 299
#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set(false);
m_flGlowR.Set(0.76f);
m_flGlowG.Set(0.76f);
m_flGlowB.Set(0.76f);
#endif
</source>
Add this section of code in '''baseanimating.cpp''' like this:
<source lang=cpp>
// this should be around line 318
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::SetGlowEffectColor(float r, float g, float b)
{
m_flGlowR.Set(r);
m_flGlowG.Set(g);
m_flGlowB.Set(b);
}
</source>
That's it for the server side, now it's time for client side.<br>
Firstly, inside '''c_baseanimating.h''' add {{Key|float m_flGlowR}}, {{Key|float m_flGlowG}}, {{Key|float m_flGlowB}} like this:
<source lang=cpp>
// This should be around line 481
#ifdef GLOWS_ENABLE
float m_flGlowR;
float m_flGlowG;
float m_flGlowB;
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject* m_pGlowEffect;
#endif
</source>
Then in '''c_baseanimating.cpp''' add {{Key|RecvPropFloat(RECVINFO(m_flGlowR)),}}, {{Key|RecvPropFloat(RECVINFO(m_flGlowG)),}}, {{Key|RecvPropFloat(RECVINFO(m_flGlowB)),}} like this:
<source lang=cpp>
<source lang=cpp>
myObject->AddGlowEffect(); //Make it glow
// this should be around line 203
#ifdef GLOWS_ENABLE
RecvPropBool(RECVINFO(m_bGlowEnabled)),
RecvPropFloat(RECVINFO(m_flGlowR)),
RecvPropFloat(RECVINFO(m_flGlowG)),
RecvPropFloat(RECVINFO(m_flGlowB)),
#endif // GLOWS_ENABLE
</source>
</source>


To update a glow, call:
Add {{Key|m_flGlowR {{=}} 0.76f}}, {{Key|m_flGlowG {{=}} 0.76f}}, {{Key|m_flGlowB {{=}} 0.76f}} in '''c_baseanimating.cpp''' like this:
<source lang=cpp>
<source lang=cpp>
myObject->UpdateGlowEffect(); //Update glow
// this should be around line 742
#ifdef GLOWS_ENABLE
m_flGlowR = 0.76f;
m_flGlowG = 0.76f;
m_flGlowB = 0.76f;
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE
</source>
</source>


To stop a glow, call:
Now change '''C_BaseAnimating::GetGlowEffectColor''' to look like this:
<source lang=cpp>
void C_BaseAnimating::GetGlowEffectColor(float* r, float* g, float* b)
{
*r = m_flGlowR;
*g = m_flGlowG;
*b = m_flGlowB;
}
</source>
[[File:Glow_tutorial_2013_finalres_color.png|500px|thumb|left|Expected result with red outline as example]]{{clr}}
Now you can change the color of glow from white to any color you want. If you don't what values you should type in I suggest [https://harry7557558.github.io/tools/colorpicker.html this picker]. Most important is {{Key|RGB (float)}} field, since it's the value we want.
===I/O control===
This subsection will explain how to add Input/Output control for glow.
Firstly add this part of code in '''baseanimating.h''' (recommended around line 300-302):
<source lang=cpp>
#ifdef GLOWS_ENABLE
void ReloadGlow(inputdata_t& inputdata);
void SetGlowEnabled(inputdata_t& inputdata);
void SetGlowDisabled(inputdata_t& inputdata);
void SetGlowColorRed(inputdata_t& inputdata);
void SetGlowColorGreen(inputdata_t& inputdata);
void SetGlowColorBlue(inputdata_t& inputdata);
void SetGlowColor(inputdata_t& inputdata);
#endif
</source>
Next put this part of code in '''baseanimating.cpp''' (around line 200):
<source lang=cpp>
DEFINE_INPUTFUNC(FIELD_VOID, "SetGlowEnabled", SetGlowEnabled),
DEFINE_INPUTFUNC(FIELD_VOID, "SetGlowDisabled", SetGlowDisabled),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorRed", SetGlowColorRed),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorGreen", SetGlowColorGreen),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorBlue", SetGlowColorBlue),
DEFINE_INPUTFUNC(FIELD_COLOR32, "SetGlowColor", SetGlowColor),
</source>
Lastly add this part of code in '''baseanimating.cpp''' (in the same #ifdef block as '''CBaseAnimating::SetGlowEffectColor(...)'''):
<source lang=cpp>
<source lang=cpp>
myObject->RemoveGlowEffect(); //Make it stop glowing
void CBaseAnimating::SetGlowEnabled(inputdata_t& inputdata)
{
m_bGlowEnabled.Set(true);
}
void CBaseAnimating::SetGlowDisabled(inputdata_t& inputdata)
{
m_bGlowEnabled.Set(false);
}
void CBaseAnimating::SetGlowColorRed(inputdata_t& inputdata)
{
m_flGlowR.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColorGreen(inputdata_t& inputdata)
{
m_flGlowG.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColorBlue(inputdata_t& inputdata)
{
m_flGlowB.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColor(inputdata_t& inputdata)
{
color32 color = inputdata.value.Color32();
SetGlowEffectColor(color.r/255, color.g/255, color.b/255);
}
</source>
</source>
Now you can test it out by jumping into game and running {{Ent|ent_fire}} command e.g. on prop_dynamic.<br>
Inputs/Outputs created:
{{Note|For now only way to apply new color is to call {{Key|SetGlowDisabled}} first to disable glow and then {{Key|SetGlowEnabled}} to reenable glow}}
=Usage=
If you have only followed [[#Activation|activation]] then those are methods you can use:
{{Note|By default, only objects derived from {{Key|CBaseCombatCharacter}} to change it see [[#.28Optional.29_Transferring_getters_and_setters_from_CBaseCombatCharacter|this]]}}
<source lang=cpp>myObject->AddGlowEffect(); //Make it glow</source>
<source lang=cpp>myObject->UpdateGlowEffect(); //Update glow</source>
<source lang=cpp>myObject->RemoveGlowEffect(); //Make it stop glowing</source>
However if you have also followed [[#Adding_color_control_for_glow|color control]] subsection you can additionally use:
<source lang=cpp>myObject->SetGlowEffectColor(float r, float g, float b); //Set color of glow</source>
And if you have followed [[#I.2FO_control|I/O control]] you can use these inputs/outputs:
{{I|SetGlowEnabled|Enables glow}}
{{I|SetGlowDisabled|Disables glow}}
{{I|SetGlowColorRed|Sets the red value of glow color|param=float}}
{{I|SetGlowColorGreen|Sets the green value of glow color|param=float}}
{{I|SetGlowColorBlue|Sets the blue value of glow color|param=float}}
{{I|SetGlowColor|Sets the full glow color (RGB)|param=color255}}
[[Category:Programming]]
[[Category:Snippets]]

Latest revision as of 11:19, 21 April 2025

The glow effect applied with this tutorial.

Activation

  • Add GLOWS_ENABLE to the preprocessor directives on your client and server projects (don't forget to add it for release and debug, too!)
  • Add the following line to ClientModeShared::DoPostScreenSpaceEffects:
g_GlowObjectManager.RenderGlowEffects( pSetup, 0 );


Materials Required: SDK2013_TF2_GlowOutlineMaterials.zip


  • Precache the effect by placing this code in clientmode_shared.cpp (search for other references of CLIENTEFFECT_REGISTER_BEGIN for usage example):
CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffectsGlow )
CLIENTEFFECT_MATERIAL( "dev/glow_color" )
CLIENTEFFECT_MATERIAL( "dev/halo_add_to_screen" )
CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 )

Don't forget to add the include defintion for the precache system!

#include "clienteffectprecachesystem.h"

(Optional) Transferring getters and setters from CBaseCombatCharacter

Icon-Important.pngImportant:This part is completely optional if you're okay with how glow works by default you can skip to usage section.
Note.pngNote:Color control and I/O control is possible without following entire transferring tutorial, however both of these subsections assume you have completed transferring tutorial and it's recommended since it allows to use glow on objects like prop_dynamic, etc.

By default objects derived from CBaseCombatCharacter have getters and setters which can be problematic.
This section shows how to transfer setters and getters from CBaseCombatCharacter to CBaseAnimating since most entities are derived from CBaseAnimating e.g. CBaseCombatCharacter, CDynamicProp, CBaseProp and more.

There are two parts: Server and Client, where we'll start with server first.
Firstly delete this part of code from basecombatcharacter.h (lines 415-420) and put it into baseanimating.h (recommended lines 54-58):

#ifdef GLOWS_ENABLE
public:
void				AddGlowEffect(void);
void				RemoveGlowEffect(void);
bool				IsGlowEffectActive(void);
#endif

After that, do the same thing to this part of code (basecombatcharacter.h, lines 459-462, baseanimating.h recommended lines 171-174):

#ifdef GLOWS_ENABLE
protected:
CNetworkVar(bool, m_bGlowEnabled);
#endif
Note.pngNote:This part of code needs to be in protected: modifier. If there's no protected modifier make one

And finally repeat that with this part of code (basecombatcharacter.h, lines 467-468, baseanimating.h recommended lines 355-356)

void				UpdateGlowEffect( void );
void				DestroyGlowEffect( void );
Note.pngNote:This part of code needs to be in private: modifier

Now move to basecombatcharacter.cpp and baseanimating.cpp First part of code to delete from basecombatcharacter.cpp (lines 193-195) and put it into baseanimating.cpp (line 230):

#ifdef GLOWS_ENABLE
SendPropBool( SENDINFO( m_bGlowEnabled ) ),
#endif

Next, from basecombatcharacter.cpp (lines 744-746) put this part of code into baseanimating.cpp CBaseAnimating::CBaseAnimating

#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set( false );
#endif

Lastly delete this from basecombatcharacter.cpp (lines 3227-3252)

#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::AddGlowEffect( void )
{
	SetTransmitState( FL_EDICT_ALWAYS );
	m_bGlowEnabled.Set( true );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::RemoveGlowEffect( void )
{
	m_bGlowEnabled.Set( false );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CBaseCombatCharacter::IsGlowEffectActive( void )
{
	return m_bGlowEnabled;
}
#endif // GLOWS_ENABLE

and put this part somewhere under CBaseAnimating::~CBaseAnimating in baseanimating.cpp

#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseAnimating::AddGlowEffect(void)
{
	SetTransmitState(FL_EDICT_ALWAYS);
	m_bGlowEnabled.Set(true);
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseAnimating::RemoveGlowEffect(void)
{
	m_bGlowEnabled.Set(false);
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CBaseAnimating::IsGlowEffectActive(void)
{
	return m_bGlowEnabled;
}
#endif

This is the end of server part, now onto client part. We'll be mainly operating on two files c_baseanimating.cpp/.h and c_basecombatcharacter.cpp/.h Firstly delete this part from c_basecombatcharacter.h (lines 17-19) and put at the top of c_baseanimating.h

#ifdef GLOWS_ENABLE
#include "glow_outline_effect.h"
#endif

Secondly is to delete this part of code from c_basecombatcharacter.h (lines 94-97) and put it into c_baseanimating.h (recommended lines 149-152)

#ifdef GLOWS_ENABLE
CGlowObject			*GetGlowObject( void ){ return m_pGlowEffect; }
virtual void		GetGlowEffectColor( float *r, float *g, float *b );
#endif // GLOWS_ENABLE

Then repeat that for this for this part of code (from c_basecombatcharacter.h, lines 100-103 to c_baseanimating.h, recommended lines 458-461):

#ifdef GLOWS_ENABLE	
	virtual void		UpdateGlowEffect(void);
	virtual void		DestroyGlowEffect(void);
#endif // GLOWS_ENABLE

And this (from c_basecombatcharacter.h, lines 110-114 to c_baseanimating.h, recommended lines 481-485):

#ifdef GLOWS_ENABLE
	bool				m_bGlowEnabled;
	bool				m_bOldGlowEnabled;
	CGlowObject			*m_pGlowEffect;
#endif

Now go into c_basecombatcharacter.cpp and c_baseanimating.cpp Firstly delete this part of code from c_basecombatcharacter.cpp (lines 33-37) and put it into c_baseanimating.cpp (recommended lines 737-741):

#ifdef GLOWS_ENABLE
	m_pGlowEffect = NULL;
	m_bGlowEnabled = false;
	m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE

Then delete this part of code from C_BaseCombatCharacter::~C_BaseCombatCharacter and put it into C_BaseAnimating::~C_BaseAnimating

#ifdef GLOWS_ENABLE
	DestroyGlowEffect();
#endif // GLOWS_ENABLE

and repeat this for this part of code (from c_basecombatcharacter.cpp, lines 58-60 to c_baseanimating.cpp, recommended lines 4528-4530):

#ifdef GLOWS_ENABLE
	m_bOldGlowEnabled = m_bGlowEnabled;
#endif // GLOWS_ENABLE

and again (from c_basecombatcharacter.cpp, lines 66-71 to c_baseanimating.cpp, recommended lines 4716-4721):

#ifdef GLOWS_ENABLE
	if ( m_bOldGlowEnabled != m_bGlowEnabled )
	{
		UpdateGlowEffect();
	}
#endif // GLOWS_ENABLE

Remove this section of code from c_basecombatcharacter.cpp (lines 85-128)

#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b )
{
	*r = 0.76f;
	*g = 0.76f;
	*b = 0.76f;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::UpdateGlowEffect( void )
{
	// destroy the existing effect
	if ( m_pGlowEffect )
	{
		DestroyGlowEffect();
	}

	// create a new effect
	if ( m_bGlowEnabled )
	{
		float r, g, b;
		GetGlowEffectColor( &r, &g, &b );

		m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::DestroyGlowEffect( void )
{
	if ( m_pGlowEffect )
	{
		delete m_pGlowEffect;
		m_pGlowEffect = NULL;
	}
}
#endif // GLOWS_ENABLE

and put this section in c_baseanimating.cpp (recommended start on line 4387):

#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseAnimating::GetGlowEffectColor( float *r, float *g, float *b )
{
	*r = 0.76f;
	*g = 0.76f;
	*b = 0.76f;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseAnimating::UpdateGlowEffect( void )
{
	// destroy the existing effect
	if ( m_pGlowEffect )
	{
		DestroyGlowEffect();
	}

	// create a new effect
	if ( m_bGlowEnabled )
	{
		float r, g, b;
		GetGlowEffectColor( &r, &g, &b );

		m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseAnimating::DestroyGlowEffect( void )
{
	if ( m_pGlowEffect )
	{
		delete m_pGlowEffect;
		m_pGlowEffect = NULL;
	}
}
#endif // GLOWS_ENABLE

and lastly get this part of code from c_basecombatcharacter.cpp (lines 97-99) and put it into c_baseanimating.cpp (recommended lines 203-205):

#ifdef GLOWS_ENABLE
	RecvPropBool( RECVINFO( m_bGlowEnabled ) ),
#endif // GLOWS_ENABLE

And you're done. Now you can create entities with glow (e.g. prop_dynamic, npcs, etc.) as long as they're derived from CBaseAnimating onwards.

Adding color control for glow

This subsection will explain how to add glow color control so you can change color in code. Firstly open baseanimating.h and add void SetGlowEffectColor(float r, float g, float b); like this:

#ifdef GLOWS_ENABLE
	void				SetGlowEffectColor(float r, float g, float b);
	void				AddGlowEffect(void);
	void				RemoveGlowEffect(void);
	bool				IsGlowEffectActive(void);
#endif

then add CNetworkVar(float, m_flGlowR);, CNetworkVar(float, m_flGlowG);, CNetworkVar(float, m_flGlowB); like this:

// this should be around line 172
#ifdef GLOWS_ENABLE
protected:
	CNetworkVar(bool, m_bGlowEnabled);
	CNetworkVar(float, m_flGlowR);
	CNetworkVar(float, m_flGlowG);
	CNetworkVar(float, m_flGlowB);
#endif

Now in baseanimating.cpp add SendPropFloat(SENDINFO(m_flGlowR)),, SendPropFloat(SENDINFO(m_flGlowG)),, SendPropFloat(SENDINFO(m_flGlowB)), like this:

// this should be around line 229
IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating)
#ifdef GLOWS_ENABLE
	SendPropBool(SENDINFO(m_bGlowEnabled)),
	SendPropFloat(SENDINFO(m_flGlowR)),
	SendPropFloat(SENDINFO(m_flGlowG)),
	SendPropFloat(SENDINFO(m_flGlowB)),
#endif

In baseanimating.cpp add m_flGlowR.Set(0.76f);, m_flGlowG.Set(0.76f);, m_flGlowB.Set(0.76f); like this:

// this should be around line 299
#ifdef GLOWS_ENABLE
	m_bGlowEnabled.Set(false);
	m_flGlowR.Set(0.76f);
	m_flGlowG.Set(0.76f);
	m_flGlowB.Set(0.76f);
#endif

Add this section of code in baseanimating.cpp like this:

// this should be around line 318
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseAnimating::SetGlowEffectColor(float r, float g, float b)
{
	m_flGlowR.Set(r);
	m_flGlowG.Set(g);
	m_flGlowB.Set(b);
}

That's it for the server side, now it's time for client side.
Firstly, inside c_baseanimating.h add float m_flGlowR, float m_flGlowG, float m_flGlowB like this:

// This should be around line 481
#ifdef GLOWS_ENABLE
	float				m_flGlowR;
	float				m_flGlowG;
	float				m_flGlowB;
	bool				m_bGlowEnabled;
	bool				m_bOldGlowEnabled;
	CGlowObject* m_pGlowEffect;
#endif

Then in c_baseanimating.cpp add RecvPropFloat(RECVINFO(m_flGlowR)),, RecvPropFloat(RECVINFO(m_flGlowG)),, RecvPropFloat(RECVINFO(m_flGlowB)), like this:

// this should be around line 203
#ifdef GLOWS_ENABLE
	RecvPropBool(RECVINFO(m_bGlowEnabled)),
	RecvPropFloat(RECVINFO(m_flGlowR)),
	RecvPropFloat(RECVINFO(m_flGlowG)),
	RecvPropFloat(RECVINFO(m_flGlowB)),
#endif // GLOWS_ENABLE

Add m_flGlowR = 0.76f, m_flGlowG = 0.76f, m_flGlowB = 0.76f in c_baseanimating.cpp like this:

// this should be around line 742
#ifdef GLOWS_ENABLE
	m_flGlowR = 0.76f;
	m_flGlowG = 0.76f;
	m_flGlowB = 0.76f;
	m_pGlowEffect = NULL;
	m_bGlowEnabled = false;
	m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE

Now change C_BaseAnimating::GetGlowEffectColor to look like this:

void C_BaseAnimating::GetGlowEffectColor(float* r, float* g, float* b)
{
	*r = m_flGlowR;
	*g = m_flGlowG;
	*b = m_flGlowB;
}
Expected result with red outline as example

Now you can change the color of glow from white to any color you want. If you don't what values you should type in I suggest this picker. Most important is RGB (float) field, since it's the value we want.

I/O control

This subsection will explain how to add Input/Output control for glow. Firstly add this part of code in baseanimating.h (recommended around line 300-302):

#ifdef GLOWS_ENABLE
void ReloadGlow(inputdata_t& inputdata);
void SetGlowEnabled(inputdata_t& inputdata);
void SetGlowDisabled(inputdata_t& inputdata);
void SetGlowColorRed(inputdata_t& inputdata);
void SetGlowColorGreen(inputdata_t& inputdata);
void SetGlowColorBlue(inputdata_t& inputdata);
void SetGlowColor(inputdata_t& inputdata);
#endif

Next put this part of code in baseanimating.cpp (around line 200):

DEFINE_INPUTFUNC(FIELD_VOID, "SetGlowEnabled", SetGlowEnabled),
DEFINE_INPUTFUNC(FIELD_VOID, "SetGlowDisabled", SetGlowDisabled),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorRed", SetGlowColorRed),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorGreen", SetGlowColorGreen),
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetGlowColorBlue", SetGlowColorBlue),
DEFINE_INPUTFUNC(FIELD_COLOR32, "SetGlowColor", SetGlowColor),

Lastly add this part of code in baseanimating.cpp (in the same #ifdef block as CBaseAnimating::SetGlowEffectColor(...)):

void CBaseAnimating::SetGlowEnabled(inputdata_t& inputdata)
{
	m_bGlowEnabled.Set(true);
}
void CBaseAnimating::SetGlowDisabled(inputdata_t& inputdata)
{
	m_bGlowEnabled.Set(false);
}
void CBaseAnimating::SetGlowColorRed(inputdata_t& inputdata)
{
	m_flGlowR.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColorGreen(inputdata_t& inputdata)
{
	m_flGlowG.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColorBlue(inputdata_t& inputdata)
{
	m_flGlowB.Set(inputdata.value.Float());
}
void CBaseAnimating::SetGlowColor(inputdata_t& inputdata)
{
	color32 color = inputdata.value.Color32();
	SetGlowEffectColor(color.r/255, color.g/255, color.b/255);
}

Now you can test it out by jumping into game and running ent_fire command e.g. on prop_dynamic.
Inputs/Outputs created:

Note.pngNote:For now only way to apply new color is to call SetGlowDisabled first to disable glow and then SetGlowEnabled to reenable glow

Usage

If you have only followed activation then those are methods you can use:

Note.pngNote:By default, only objects derived from CBaseCombatCharacter to change it see this
myObject->AddGlowEffect(); //Make it glow
myObject->UpdateGlowEffect(); //Update glow
myObject->RemoveGlowEffect(); //Make it stop glowing

However if you have also followed color control subsection you can additionally use:

myObject->SetGlowEffectColor(float r, float g, float b); //Set color of glow

And if you have followed I/O control you can use these inputs/outputs:

SetGlowEnabled
Enables glow
SetGlowDisabled
Disables glow
SetGlowColorRed <floatRedirectInput/float>
Sets the red value of glow color
SetGlowColorGreen <floatRedirectInput/float>
Sets the green value of glow color
SetGlowColorBlue <floatRedirectInput/float>
Sets the blue value of glow color
SetGlowColor <color255RedirectInput/color32>
Sets the full glow color (RGB)