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
182 changes: 174 additions & 8 deletions src/game/client/tf/c_tf_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,10 @@ bool CSpyInvisProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues )
return ( bInvis && bTint );
}

ConVar tf_teammate_max_invis( "tf_teammate_max_invis", "0.95", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY );
ConVar tf_teammate_max_invis( "tf_teammate_max_invis", "0.75", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY );

Vector cloakTintRed = Vector( 1.0f, 0.5f, 0.4f );
Vector cloakTintBlue = Vector( 0.4f, 0.5f, 1.0f );

//-----------------------------------------------------------------------------
// Purpose:
Expand Down Expand Up @@ -1728,22 +1731,21 @@ void CSpyInvisProxy::OnBind( C_BaseEntity *pBaseEntity )
}
else
{
float r = 1.0f, g = 1.0f, b = 1.0f;
Vector vecColor{ 1.0f, 1.0f, 1.0f };
fInvis = pPlayer->GetEffectiveInvisibilityLevel();

switch( pPlayer->GetTeamNumber() )
{
case TF_TEAM_RED:
r = 1.0; g = 0.5; b = 0.4;
vecColor = cloakTintRed;
break;

case TF_TEAM_BLUE:
default:
r = 0.4; g = 0.5; b = 1.0;
vecColor = cloakTintBlue;
break;
}

m_pCloakColorTint->SetVecValue( r, g, b );
m_pCloakColorTint->SetVecValue( vecColor.Base(), 3 );
}

m_pPercentInvisible->SetFloatValue( fInvis );
Expand All @@ -1761,6 +1763,169 @@ void CSpyInvisProxy::OnBindNotEntity( void *pRenderable )

EXPOSE_INTERFACE( CSpyInvisProxy, IMaterialProxy, "spy_invis" IMATERIAL_PROXY_INTERFACE_VERSION );

//-----------------------------------------------------------------------------
// Purpose: Generic invis proxy that can handle invis for both weapons & viewmodels.
// Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
//-----------------------------------------------------------------------------
class CInvisProxy : public CBaseInvisMaterialProxy
{
public:
CInvisProxy( void );
virtual bool Init( IMaterial* pMaterial, KeyValues* pKeyValues ) OVERRIDE;
virtual void OnBind( C_BaseEntity *pC_BaseEntity ) OVERRIDE;

private:
IMaterialVar* m_pCloakColorTint;
};

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CInvisProxy::CInvisProxy( void )
{
m_pCloakColorTint = NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Get pointer to the color value
// Input : *pMaterial -
//-----------------------------------------------------------------------------
bool CInvisProxy::Init( IMaterial* pMaterial, KeyValues* pKeyValues )
{
// Need to get the material var
bool bInvis = CBaseInvisMaterialProxy::Init( pMaterial, pKeyValues );

bool bTint;
m_pCloakColorTint = pMaterial->FindVar( "$cloakColorTint", &bTint );

return ( bInvis && bTint );
}

ConVar tf_viewmodel_cloak_tint( "tf_viewmodel_cloak_tint", "0", FCVAR_ARCHIVE, "Allow viewmodels to be tinted while cloaked.", true, 0.0f, true, 1.0f );

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInvisProxy::OnBind( C_BaseEntity *pC_BaseEntity )
{
if( !m_pPercentInvisible )
return;

C_BaseEntity *pEnt = pC_BaseEntity;

C_TFPlayer *pPlayer = NULL;
float flCloakTintFactor = 1.0f;

// Check if we are parented to a player
C_BaseEntity *pMoveParent = pEnt->GetMoveParent();
if ( pMoveParent && pMoveParent->IsPlayer() )
{
pPlayer = ToTFPlayer( pMoveParent );
}

// Check if we are a viewmodel
if ( !pPlayer )
{
CBaseEntity *pEntParent = pMoveParent ? pMoveParent : pEnt;

CTFViewModel *pVM = dynamic_cast<CTFViewModel *>( pEntParent );
if ( pVM )
{
pPlayer = ToTFPlayer( pVM->GetOwner() );

// Viewmodels use a convar for cloak tint factor
flCloakTintFactor = tf_viewmodel_cloak_tint.GetFloat();
}
}

// Check if we are a player
if ( !pPlayer )
{
if ( pEnt->IsPlayer() )
{
pPlayer = dynamic_cast<C_TFPlayer*>( pEnt );
}
else
{
IHasOwner *pOwnerInterface = dynamic_cast<IHasOwner*>( pEnt );
if ( pOwnerInterface )
{
pPlayer = ToTFPlayer( pOwnerInterface->GetOwnerViaInterface() );
}
}
}

// Check if we are a ragdoll, otherwise give up
if ( !pPlayer )
{
C_TFRagdoll *pRagdoll = dynamic_cast<C_TFRagdoll*>( pEnt );
if ( pRagdoll && pRagdoll->IsCloaked() )
{
m_pPercentInvisible->SetFloatValue( pRagdoll->GetPercentInvisible() );
}
else
{
m_pPercentInvisible->SetFloatValue( 0.0f );
}
return;
}

// Cloak tinting
Vector vecColor{ 1.0f, 1.0f, 1.0f };

if ( pPlayer )
{
// We were validated, color as necessary
switch ( pPlayer->GetTeamNumber() )
{
case TF_TEAM_RED:
vecColor = cloakTintRed;
break;
case TF_TEAM_BLUE:
default:
vecColor = cloakTintBlue;
break;
}
}

// Blend the color based on cloak tint factor, if applicable
if( flCloakTintFactor != 1.0f )
{
VectorLerp( Vector( 1.0f, 1.0f, 1.0f ), vecColor, flCloakTintFactor, vecColor );
}
m_pCloakColorTint->SetVecValue( vecColor.Base(), 3 );

// Handle the local player
if ( pPlayer->IsLocalPlayer() )
{
float flPercentInvisible = pPlayer->GetEffectiveInvisibilityLevel();
float flWeaponInvis = flPercentInvisible;

// Reveal ourself a little when bumping into players
if ( pPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK ) )
{
flWeaponInvis = 0.3f;
}

// Reveal ourself a little if we're using motion cloak and our well has run dry
CTFWeaponInvis *pWpn = (CTFWeaponInvis *) pPlayer->Weapon_OwnsThisID( TF_WEAPON_INVIS );
if ( pWpn && pWpn->HasMotionCloak() && (pPlayer->m_Shared.GetSpyCloakMeter() <= 0.f ) )
{
flWeaponInvis = 0.3f;
}

m_pPercentInvisible->SetFloatValue( flWeaponInvis );
}
else
{
m_pPercentInvisible->SetFloatValue( pPlayer->GetEffectiveInvisibilityLevel() );
}
}

// Generic invis proxy that can handle invis for both weapons & viewmodels.
// Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
EXPOSE_INTERFACE( CInvisProxy, IMaterialProxy, "invis" IMATERIAL_PROXY_INTERFACE_VERSION );

//-----------------------------------------------------------------------------
// Purpose: Used for invulnerability material
// Returns 1 if the player is invulnerable, and 0 if the player is losing / doesn't have invuln.
Expand Down Expand Up @@ -6790,15 +6955,16 @@ float C_TFPlayer::GetEffectiveInvisibilityLevel( void )
}

// stomp invis level with taunt invis if there's one
if ( IsTaunting() )
// boba: unused attribute, adds needless expense to GetEffectiveInvisibilityLevel() every frame
/*if (IsTaunting())
{
float flTauntInvis = 0.f;
CALL_ATTRIB_HOOK_FLOAT( flTauntInvis, taunt_attr_player_invis_percent );
if ( flTauntInvis > 0.f )
{
flPercentInvisible = flTauntInvis;
}
}
}*/

return flPercentInvisible;
}
Expand Down
112 changes: 3 additions & 109 deletions src/game/shared/tf/tf_viewmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,16 +474,16 @@ void CViewModelInvisProxy::OnBind( C_BaseEntity *pEnt )
return;
}

float flPercentInvisible = pPlayer->GetPercentInvisible();
float flPercentInvisible = pPlayer->GetEffectiveInvisibilityLevel();
float flWeaponInvis = flPercentInvisible;

if ( bIsViewModel == true )
{
// remap from 0.22 to 0.5
// but drop to 0.0 if we're not invis at all
flWeaponInvis = ( flPercentInvisible < 0.01 ) ?
flWeaponInvis = (flPercentInvisible < 0.01) ?
0.0 :
RemapVal( flPercentInvisible, 0.0, 1.0, TF_VM_MIN_INVIS, TF_VM_MAX_INVIS );
RemapVal(flPercentInvisible, 0.0, 1.0, TF_VM_MIN_INVIS, TF_VM_MAX_INVIS);

// Exaggerated blink effect on bump.
if ( pPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK ) )
Expand All @@ -504,110 +504,4 @@ void CViewModelInvisProxy::OnBind( C_BaseEntity *pEnt )

EXPOSE_INTERFACE( CViewModelInvisProxy, IMaterialProxy, "vm_invis" IMATERIAL_PROXY_INTERFACE_VERSION );


//-----------------------------------------------------------------------------
// Purpose: Generic invis proxy that can handle invis for both weapons & viewmodels.
// Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
//-----------------------------------------------------------------------------
class CInvisProxy : public CBaseInvisMaterialProxy
{
public:
virtual void OnBind( C_BaseEntity *pC_BaseEntity ) OVERRIDE;
};

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInvisProxy::OnBind( C_BaseEntity *pC_BaseEntity )
{
if( !m_pPercentInvisible )
return;

C_BaseEntity *pEnt = pC_BaseEntity;

CTFPlayer *pPlayer = NULL;

// Check if we have a move parent and if it's a player
C_BaseEntity *pMoveParent = pEnt->GetMoveParent();
if ( pMoveParent && pMoveParent->IsPlayer() )
{
pPlayer = ToTFPlayer( pMoveParent );
}

// If it's not a player then check for viewmodel.
if ( !pPlayer )
{
CBaseEntity *pEntParent = pMoveParent ? pMoveParent : pEnt;

CTFViewModel *pVM = dynamic_cast<CTFViewModel *>( pEntParent );
if ( pVM )
{
pPlayer = ToTFPlayer( pVM->GetOwner() );
}
}

if ( !pPlayer )
{
if ( pEnt->IsPlayer() )
{
pPlayer = dynamic_cast<C_TFPlayer*>( pEnt );
}
else
{
IHasOwner *pOwnerInterface = dynamic_cast<IHasOwner*>( pEnt );
if ( pOwnerInterface )
{
pPlayer = ToTFPlayer( pOwnerInterface->GetOwnerViaInterface() );
}
}
}

if ( !pPlayer )
{
C_TFRagdoll *pRagdoll = dynamic_cast<C_TFRagdoll*>( pEnt );
if ( !pRagdoll || !pRagdoll->IsCloaked() )
{
m_pPercentInvisible->SetFloatValue( 0.0f );
}
return;
}

// If we're the local player, use the old "vm_invis" code. Otherwise, use the "weapon_invis".
if ( pPlayer->IsLocalPlayer() )
{
float flPercentInvisible = pPlayer->GetPercentInvisible();
float flWeaponInvis = flPercentInvisible;

// remap from 0.22 to 0.5
// but drop to 0.0 if we're not invis at all
flWeaponInvis = ( flPercentInvisible < 0.01 ) ?
0.0 :
RemapVal( flPercentInvisible, 0.0, 1.0, TF_VM_MIN_INVIS, TF_VM_MAX_INVIS );

// Exaggerated blink effect on bump.
if ( pPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK ) )
{
flWeaponInvis = 0.3f;
}

// Also exaggerate the effect if we're using motion cloak and our well has run dry.
CTFWeaponInvis *pWpn = (CTFWeaponInvis *) pPlayer->Weapon_OwnsThisID( TF_WEAPON_INVIS );
if ( pWpn && pWpn->HasMotionCloak() && (pPlayer->m_Shared.GetSpyCloakMeter() <= 0.f ) )
{
flWeaponInvis = 0.3f;
}

m_pPercentInvisible->SetFloatValue( flWeaponInvis );
}
else
{
m_pPercentInvisible->SetFloatValue( pPlayer->GetEffectiveInvisibilityLevel() );
}
}

// Generic invis proxy that can handle invis for both weapons & viewmodels.
// Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
EXPOSE_INTERFACE( CInvisProxy, IMaterialProxy, "invis" IMATERIAL_PROXY_INTERFACE_VERSION );


#endif // CLIENT_DLL