@@ -1910,7 +1910,14 @@ bool CSpyInvisProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues )
19101910 return ( bInvis && bTint );
19111911}
19121912
1913- ConVar tf_teammate_max_invis ( " tf_teammate_max_invis" , " 0.95" , FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY );
1913+ #ifdef BDSBASE
1914+ ConVar tf_teammate_max_invis (" tf_teammate_max_invis" , " 0.75" , FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY);
1915+
1916+ Vector cloakTintRed = Vector(1 .0f , 0 .5f , 0 .4f );
1917+ Vector cloakTintBlue = Vector(0 .4f , 0 .5f , 1 .0f );
1918+ #else
1919+ ConVar tf_teammate_max_invis (" tf_teammate_max_invis" , " 0.95" , FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY);
1920+ #endif
19141921
19151922// -----------------------------------------------------------------------------
19161923// Purpose:
@@ -1942,22 +1949,38 @@ void CSpyInvisProxy::OnBind( C_BaseEntity *pBaseEntity )
19421949 }
19431950 else
19441951 {
1952+ #ifdef BDSBASE
1953+ Vector vecColor{ 1 .0f , 1 .0f , 1 .0f };
1954+ #else
19451955 float r = 1 .0f , g = 1 .0f , b = 1 .0f ;
1956+ #endif
19461957 fInvis = pPlayer->GetEffectiveInvisibilityLevel ();
19471958
19481959 switch ( pPlayer->GetTeamNumber () )
19491960 {
19501961 case TF_TEAM_RED:
1962+ #ifdef BDSBASE
1963+ vecColor = cloakTintRed;
1964+ #else
19511965 r = 1.0 ; g = 0.5 ; b = 0.4 ;
1966+ #endif
19521967 break ;
19531968
19541969 case TF_TEAM_BLUE:
19551970 default :
1971+ #ifdef BDSBASE
1972+ vecColor = cloakTintBlue;
1973+ #else
19561974 r = 0.4 ; g = 0.5 ; b = 1.0 ;
1975+ #endif
19571976 break ;
19581977 }
19591978
1979+ #ifdef BDSBASE
1980+ m_pCloakColorTint->SetVecValue (vecColor.Base (), 3 );
1981+ #else
19601982 m_pCloakColorTint->SetVecValue ( r, g, b );
1983+ #endif
19611984 }
19621985
19631986 m_pPercentInvisible->SetFloatValue ( fInvis );
@@ -1975,6 +1998,171 @@ void CSpyInvisProxy::OnBindNotEntity( void *pRenderable )
19751998
19761999EXPOSE_INTERFACE ( CSpyInvisProxy, IMaterialProxy, " spy_invis" IMATERIAL_PROXY_INTERFACE_VERSION );
19772000
2001+ #ifdef BDSBASE
2002+ // -----------------------------------------------------------------------------
2003+ // Purpose: Generic invis proxy that can handle invis for both weapons & viewmodels.
2004+ // Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
2005+ // -----------------------------------------------------------------------------
2006+ class CInvisProxy : public CBaseInvisMaterialProxy
2007+ {
2008+ public:
2009+ CInvisProxy (void );
2010+ virtual bool Init (IMaterial* pMaterial, KeyValues* pKeyValues) OVERRIDE;
2011+ virtual void OnBind (C_BaseEntity* pC_BaseEntity) OVERRIDE;
2012+
2013+ private:
2014+ IMaterialVar* m_pCloakColorTint;
2015+ };
2016+
2017+ // -----------------------------------------------------------------------------
2018+ // Purpose:
2019+ // -----------------------------------------------------------------------------
2020+ CInvisProxy::CInvisProxy (void )
2021+ {
2022+ m_pCloakColorTint = NULL ;
2023+ }
2024+
2025+ // -----------------------------------------------------------------------------
2026+ // Purpose: Get pointer to the color value
2027+ // Input : *pMaterial -
2028+ // -----------------------------------------------------------------------------
2029+ bool CInvisProxy::Init (IMaterial* pMaterial, KeyValues* pKeyValues)
2030+ {
2031+ // Need to get the material var
2032+ bool bInvis = CBaseInvisMaterialProxy::Init (pMaterial, pKeyValues);
2033+
2034+ bool bTint;
2035+ m_pCloakColorTint = pMaterial->FindVar (" $cloakColorTint" , &bTint);
2036+
2037+ return (bInvis && bTint);
2038+ }
2039+
2040+ 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 );
2041+
2042+ // -----------------------------------------------------------------------------
2043+ // Purpose:
2044+ // -----------------------------------------------------------------------------
2045+ void CInvisProxy::OnBind (C_BaseEntity* pC_BaseEntity)
2046+ {
2047+ if (!m_pPercentInvisible)
2048+ return ;
2049+
2050+ C_BaseEntity* pEnt = pC_BaseEntity;
2051+
2052+ C_TFPlayer* pPlayer = NULL ;
2053+ float flCloakTintFactor = 1 .0f ;
2054+
2055+ // Check if we are parented to a player
2056+ C_BaseEntity* pMoveParent = pEnt->GetMoveParent ();
2057+ if (pMoveParent && pMoveParent->IsPlayer ())
2058+ {
2059+ pPlayer = ToTFPlayer (pMoveParent);
2060+ }
2061+
2062+ // Check if we are a viewmodel
2063+ if (!pPlayer)
2064+ {
2065+ CBaseEntity* pEntParent = pMoveParent ? pMoveParent : pEnt;
2066+
2067+ CTFViewModel* pVM = dynamic_cast <CTFViewModel*>(pEntParent);
2068+ if (pVM)
2069+ {
2070+ pPlayer = ToTFPlayer (pVM->GetOwner ());
2071+
2072+ // Viewmodels use a convar for cloak tint factor
2073+ flCloakTintFactor = tf_viewmodel_cloak_tint.GetFloat ();
2074+ }
2075+ }
2076+
2077+ // Check if we are a player
2078+ if (!pPlayer)
2079+ {
2080+ if (pEnt->IsPlayer ())
2081+ {
2082+ pPlayer = dynamic_cast <C_TFPlayer*>(pEnt);
2083+ }
2084+ else
2085+ {
2086+ IHasOwner* pOwnerInterface = dynamic_cast <IHasOwner*>(pEnt);
2087+ if (pOwnerInterface)
2088+ {
2089+ pPlayer = ToTFPlayer (pOwnerInterface->GetOwnerViaInterface ());
2090+ }
2091+ }
2092+ }
2093+
2094+ // Check if we are a ragdoll, otherwise give up
2095+ if (!pPlayer)
2096+ {
2097+ C_TFRagdoll* pRagdoll = dynamic_cast <C_TFRagdoll*>(pEnt);
2098+ if (pRagdoll && pRagdoll->IsCloaked ())
2099+ {
2100+ m_pPercentInvisible->SetFloatValue (pRagdoll->GetPercentInvisible ());
2101+ }
2102+ else
2103+ {
2104+ m_pPercentInvisible->SetFloatValue (0 .0f );
2105+ }
2106+ return ;
2107+ }
2108+
2109+ // Cloak tinting
2110+ Vector vecColor{ 1 .0f , 1 .0f , 1 .0f };
2111+
2112+ if (pPlayer)
2113+ {
2114+ // We were validated, color as necessary
2115+ switch (pPlayer->GetTeamNumber ())
2116+ {
2117+ case TF_TEAM_RED:
2118+ vecColor = cloakTintRed;
2119+ break ;
2120+ case TF_TEAM_BLUE:
2121+ default :
2122+ vecColor = cloakTintBlue;
2123+ break ;
2124+ }
2125+ }
2126+
2127+ // Blend the color based on cloak tint factor, if applicable
2128+ if (flCloakTintFactor != 1 .0f )
2129+ {
2130+ VectorLerp (Vector (1 .0f , 1 .0f , 1 .0f ), vecColor, flCloakTintFactor, vecColor);
2131+ }
2132+ m_pCloakColorTint->SetVecValue (vecColor.Base (), 3 );
2133+
2134+ // Handle the local player
2135+ if (pPlayer->IsLocalPlayer ())
2136+ {
2137+ float flPercentInvisible = pPlayer->GetEffectiveInvisibilityLevel ();
2138+ float flWeaponInvis = flPercentInvisible;
2139+
2140+ // Reveal ourself a little when bumping into players
2141+ if (pPlayer->m_Shared .InCond (TF_COND_STEALTHED_BLINK))
2142+ {
2143+ flWeaponInvis = 0 .3f ;
2144+ }
2145+
2146+ // Reveal ourself a little if we're using motion cloak and our well has run dry
2147+ CTFWeaponInvis* pWpn = (CTFWeaponInvis*)pPlayer->Weapon_OwnsThisID (TF_WEAPON_INVIS);
2148+ if (pWpn && pWpn->HasMotionCloak () && (pPlayer->m_Shared .GetSpyCloakMeter () <= 0 .f ))
2149+ {
2150+ flWeaponInvis = 0 .3f ;
2151+ }
2152+
2153+ m_pPercentInvisible->SetFloatValue (flWeaponInvis);
2154+ }
2155+ else
2156+ {
2157+ m_pPercentInvisible->SetFloatValue (pPlayer->GetEffectiveInvisibilityLevel ());
2158+ }
2159+ }
2160+
2161+ // Generic invis proxy that can handle invis for both weapons & viewmodels.
2162+ // Makes the vm_invis & weapon_invis proxies obsolete, do not use them.
2163+ EXPOSE_INTERFACE (CInvisProxy, IMaterialProxy, " invis" IMATERIAL_PROXY_INTERFACE_VERSION);
2164+ #endif
2165+
19782166// -----------------------------------------------------------------------------
19792167// Purpose: Used for invulnerability material
19802168// Returns 1 if the player is invulnerable, and 0 if the player is losing / doesn't have invuln.
@@ -7111,6 +7299,7 @@ float C_TFPlayer::GetEffectiveInvisibilityLevel( void )
71117299 }
71127300 }
71137301
7302+ #ifndef BDSBASE
71147303 // stomp invis level with taunt invis if there's one
71157304 if ( IsTaunting () )
71167305 {
@@ -7121,6 +7310,7 @@ float C_TFPlayer::GetEffectiveInvisibilityLevel( void )
71217310 flPercentInvisible = flTauntInvis;
71227311 }
71237312 }
7313+ #endif
71247314
71257315 return flPercentInvisible;
71267316}
0 commit comments