mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's sheild entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_Shield.h"
|
||||
#include "tf_shieldshared.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SUBDIVISIONS = 21,
|
||||
};
|
||||
|
||||
#define EMP_WAVE_AMPLITUDE 8.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mobile version of the shield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_ShieldMobile;
|
||||
class C_ShieldMobileActiveVertList : public IActiveVertList
|
||||
{
|
||||
public:
|
||||
void Init( C_ShieldMobile *pShield, unsigned char *pVertList );
|
||||
|
||||
// IActiveVertList overrides.
|
||||
public:
|
||||
|
||||
virtual int GetActiveVertState( int iVert );
|
||||
virtual void SetActiveVertState( int iVert, int bOn );
|
||||
|
||||
private:
|
||||
C_ShieldMobile *m_pShield;
|
||||
unsigned char *m_pVertsActive;
|
||||
};
|
||||
|
||||
|
||||
class C_ShieldMobile : public C_Shield
|
||||
{
|
||||
DECLARE_CLASS( C_ShieldMobile, C_Shield );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ShieldMobile();
|
||||
~C_ShieldMobile();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void GetBounds( Vector& mins, Vector& maxs );
|
||||
|
||||
virtual void AddEntity( );
|
||||
|
||||
// Return true if the panel is active
|
||||
virtual bool IsPanelActive( int x, int y );
|
||||
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
virtual void GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend );
|
||||
virtual const Vector& GetPoint( int x, int y ) { return m_ShieldEffect.GetPoint( x, y ); }
|
||||
|
||||
virtual void SetThetaPhi( float flTheta, float flPhi ) { m_ShieldEffect.SetThetaPhi(flTheta,flPhi); }
|
||||
|
||||
public:
|
||||
// networked data
|
||||
unsigned char m_pVertsActive[SHIELD_VERTEX_BYTES];
|
||||
unsigned char m_ShieldState;
|
||||
|
||||
private:
|
||||
C_ShieldMobile( const C_ShieldMobile& );
|
||||
|
||||
// Is a particular panel an edge?
|
||||
bool IsVertexValid( float s, float t ) const;
|
||||
void PreRender( );
|
||||
|
||||
private:
|
||||
CShieldEffect m_ShieldEffect;
|
||||
C_ShieldMobileActiveVertList m_VertList;
|
||||
float m_flTheta;
|
||||
float m_flPhi;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C_ShieldMobileActiveVertList functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobileActiveVertList::Init( C_ShieldMobile *pShield, unsigned char *pVertList )
|
||||
{
|
||||
m_pShield = pShield;
|
||||
m_pVertsActive = pVertList;
|
||||
}
|
||||
|
||||
|
||||
int C_ShieldMobileActiveVertList::GetActiveVertState( int iVert )
|
||||
{
|
||||
return m_pVertsActive[iVert>>3] & (1 << (iVert & 7));
|
||||
}
|
||||
|
||||
|
||||
void C_ShieldMobileActiveVertList::SetActiveVertState( int iVert, int bOn )
|
||||
{
|
||||
if ( bOn )
|
||||
m_pVertsActive[iVert>>3] |= (1 << (iVert & 7));
|
||||
else
|
||||
m_pVertsActive[iVert>>3] &= ~(1 << (iVert & 7));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Data table
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ShieldMobile, DT_Shield_Mobile, CShieldMobile)
|
||||
|
||||
RecvPropInt( RECVINFO(m_ShieldState) ),
|
||||
RecvPropArray(
|
||||
RecvPropInt( RECVINFO(m_pVertsActive[0])),
|
||||
m_pVertsActive
|
||||
),
|
||||
RecvPropFloat( RECVINFO(m_flTheta) ),
|
||||
RecvPropFloat( RECVINFO(m_flPhi) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various raycasting routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void ShieldTraceLine(const Vector &vecStart, const Vector &vecEnd,
|
||||
unsigned int mask, int collisionGroup, trace_t *ptr)
|
||||
{
|
||||
UTIL_TraceLine(vecStart, vecEnd, mask, NULL, collisionGroup, ptr );
|
||||
}
|
||||
|
||||
void ShieldTraceHull(const Vector &vecStart, const Vector &vecEnd,
|
||||
const Vector &hullMin, const Vector &hullMax,
|
||||
unsigned int mask, int collisionGroup, trace_t *ptr)
|
||||
{
|
||||
CTraceFilterWorldOnly traceFilter;
|
||||
enginetrace->TraceHull( vecStart, vecEnd, hullMin, hullMax, mask, &traceFilter, ptr );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
C_ShieldMobile::C_ShieldMobile() : m_ShieldEffect(ShieldTraceLine, ShieldTraceHull)
|
||||
{
|
||||
m_VertList.Init( this, m_pVertsActive );
|
||||
m_ShieldEffect.SetActiveVertexList( &m_VertList );
|
||||
m_ShieldEffect.Spawn(vec3_origin, vec3_angle);
|
||||
InitShield( SHIELD_NUM_HORIZONTAL_POINTS, SHIELD_NUM_VERTICAL_POINTS, NUM_SUBDIVISIONS );
|
||||
}
|
||||
|
||||
C_ShieldMobile::~C_ShieldMobile()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get this after the data changes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
m_ShieldEffect.SetCurrentPosition( GetAbsOrigin() );
|
||||
m_ShieldEffect.SetCurrentAngles( GetAbsAngles() );
|
||||
m_ShieldEffect.SetThetaPhi( m_flTheta, m_flPhi );
|
||||
|
||||
// No need to simulate, just compute active panels from network data
|
||||
m_ShieldEffect.ComputeControlPoints();
|
||||
m_ShieldEffect.ComputePanelActivity();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A little pre-render processing
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::PreRender( )
|
||||
{
|
||||
if (m_ShieldState & SHIELD_MOBILE_EMP)
|
||||
{
|
||||
// Decay fade if we've been EMPed or if we're inactive
|
||||
if (m_FadeValue > 0.0f)
|
||||
{
|
||||
m_FadeValue -= gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_FadeValue < 0.0f)
|
||||
{
|
||||
m_FadeValue = 0.0f;
|
||||
|
||||
// Reset the shield to un-wobbled state
|
||||
m_ShieldEffect.ComputeControlPoints();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector dir;
|
||||
AngleVectors( m_ShieldEffect.GetCurrentAngles(), & dir );
|
||||
|
||||
// Futz with the control points if we've been EMPed
|
||||
for (int i = 0; i < SHIELD_NUM_CONTROL_POINTS; ++i)
|
||||
{
|
||||
// Get the direction for the point
|
||||
float factor = -EMP_WAVE_AMPLITUDE * sin( i * M_PI * 0.5f + gpGlobals->curtime * M_PI / SHIELD_EMP_WOBBLE_TIME );
|
||||
m_ShieldEffect.GetPoint(i) += dir * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fade back in, no longer EMPed
|
||||
if (m_FadeValue < 1.0f)
|
||||
{
|
||||
m_FadeValue += gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_FadeValue >= 1.0f)
|
||||
{
|
||||
m_FadeValue = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_ShieldMobile::AddEntity( )
|
||||
{
|
||||
BaseClass::AddEntity( );
|
||||
PreRender();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bounds computation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::GetBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
m_ShieldEffect.ComputeBounds( mins, maxs );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return true if the panel is active
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool C_ShieldMobile::IsPanelActive( int x, int y )
|
||||
{
|
||||
return m_ShieldEffect.IsPanelActive(x, y);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend )
|
||||
{
|
||||
for ( int i = 0; i < SHIELD_NUM_CONTROL_POINTS; ++i )
|
||||
{
|
||||
ppVerts[i] = &m_ShieldEffect.GetControlPoint(i);
|
||||
|
||||
if ( m_pVertsActive[i >> 3] & (1 << (i & 0x7)) )
|
||||
{
|
||||
pOpacity[i] = m_ShieldEffect.ComputeOpacity( *ppVerts[i], GetAbsOrigin() );
|
||||
pBlend[i] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOpacity[i] = 192.0f;
|
||||
pBlend[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user