📄 tf_shield_mobile.cpp
字号:
//=========== (C) Copyright 2000 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: The Escort's Shield weapon
//
// $Revision: $
// $NoKeywords: $
//=============================================================================
#include "cbase.h"
#include "tf_shield.h"
#include "in_buttons.h"
#include "gamerules.h"
#include "tf_shieldshared.h"
#include "tf_shareddefs.h"
ConVar shield_mobile_power( "shield_mobile_power","30", FCVAR_NONE, "Max power level of a escort's mobile projected shield." );
ConVar shield_mobile_recharge_delay( "shield_mobile_recharge_delay","0.1", FCVAR_NONE, "Time after taking damage before mobile projected shields begin to recharge." );
ConVar shield_mobile_recharge_amount( "shield_mobile_recharge_amount","2", FCVAR_NONE, "Power recharged each recharge tick for mobile projected shields." );
ConVar shield_mobile_recharge_time( "shield_mobile_recharge_time","0.5", FCVAR_NONE, "Time between each recharge tick for mobile projected shields." );
//-----------------------------------------------------------------------------
// This is the version of the shield used by the
//-----------------------------------------------------------------------------
class CShieldMobile;
class CShieldMobileActiveVertList : public IActiveVertList
{
public:
void Init( CShieldMobile *pShield );
// IActiveVertList overrides.
public:
virtual int GetActiveVertState( int iVert );
virtual void SetActiveVertState( int iVert, int bOn );
private:
CShieldMobile *m_pShield;
};
class CShieldMobile : public CShield, public IEntityEnumerator
{
public:
DECLARE_CLASS( CShieldMobile, CShield );
DECLARE_SERVERCLASS();
friend class CShieldMobileActiveVertList;
CShieldMobile();
DECLARE_DATADESC();
public:
void Spawn( void );
void Precache( void );
void ShieldThink( void );
void SetCenterAngles( const QAngle &angles );
virtual void SetAngularSpringConstant( float flConstant );
virtual void SetFrontDistance( float flDistance );
virtual void SetEMPed( bool isEmped );
virtual void SetAlwaysOrient( bool bOrient ) { m_bAlwaysOrientToOwner = bOrient; }
virtual int Width() { return SHIELD_NUM_HORIZONTAL_POINTS; }
virtual int Height() { return SHIELD_NUM_VERTICAL_POINTS; }
virtual bool IsPanelActive( int x, int y ) { return m_ShieldEffect.IsPanelActive( x, y ); }
virtual const Vector& GetPoint( int x, int y ) { return m_ShieldEffect.GetPoint( x, y ); }
virtual void SetThetaPhi( float flTheta, float flPhi );
public:
// Inherited from IEntityEnumerator
virtual bool EnumEntity( IHandleEntity *pHandleEntity );
private:
// Teleport!
void Teleported( );
// Bitfield indicating which vertices are active
CNetworkArray( unsigned char, m_pVertsActive, SHIELD_NUM_CONTROL_POINTS >> 3 );
CNetworkVar( unsigned char, m_ShieldState );
private:
struct SweepContext_t
{
SweepContext_t( const CBaseEntity *passentity, int collisionGroup ) :
m_Filter( passentity, collisionGroup ) {}
CTraceFilterSimple m_Filter;
Vector m_vecStartDelta;
Vector m_vecEndDelta;
};
void ComputeBoundingBox( void );
void DetermineObstructions( );
virtual void SetObjectCollisionBox( void );
private:
CShieldEffect m_ShieldEffect;
CShieldMobileActiveVertList m_VertList;
bool m_bAlwaysOrientToOwner;
float m_flFrontDistance;
CNetworkVar( float, m_flTheta );
CNetworkVar( float, m_flPhi );
SweepContext_t *m_pEnumCtx;
};
//=============================================================================
// Shield effect
//=============================================================================
BEGIN_DATADESC( CShieldMobile )
DEFINE_THINKFUNC( CShieldMobile, ShieldThink ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( shield_mobile, CShieldMobile );
//PRECACHE_WEAPON_REGISTER(shield_effect);
IMPLEMENT_SERVERCLASS_ST(CShieldMobile, DT_Shield_Mobile)
SendPropInt (SENDINFO(m_ShieldState), 1, SPROP_UNSIGNED ),
SendPropArray(
SendPropInt( SENDINFO_ARRAY(m_pVertsActive), 8, SPROP_UNSIGNED),
m_pVertsActive),
SendPropFloat( SENDINFO(m_flTheta), 8, SPROP_UNSIGNED ),
SendPropFloat( SENDINFO(m_flPhi), 8, SPROP_UNSIGNED ),
END_SEND_TABLE()
static void ShieldTraceLine(const Vector &vecStart, const Vector &vecEnd,
unsigned int mask, int collisionGroup, trace_t *ptr)
{
UTIL_TraceLine(vecStart, vecEnd, mask, 0, COLLISION_GROUP_NONE, ptr );
}
static void ShieldTraceHull(const Vector &vecStart, const Vector &vecEnd,
const Vector &hullMin, const Vector &hullMax,
unsigned int mask, int collisionGroup, trace_t *ptr)
{
UTIL_TraceHull( vecStart, vecEnd, hullMin, hullMax, mask, 0, collisionGroup, ptr );
}
//-----------------------------------------------------------------------------
// CShieldMobileActiveVertList functions
//-----------------------------------------------------------------------------
void CShieldMobileActiveVertList::Init( CShieldMobile *pShield )
{
m_pShield = pShield;
}
int CShieldMobileActiveVertList::GetActiveVertState( int iVert )
{
return m_pShield->m_pVertsActive[iVert>>3] & (1 << (iVert & 7));
}
void CShieldMobileActiveVertList::SetActiveVertState( int iVert, int bOn )
{
m_pShield->NetworkStateChanged();
unsigned char val;
if ( bOn )
val = m_pShield->m_pVertsActive[iVert>>3] | (1 << (iVert & 7));
else
val = m_pShield->m_pVertsActive[iVert>>3] & ~(1 << (iVert & 7));
m_pShield->m_pVertsActive.Set( iVert>>3, val );
}
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CShieldMobile::CShieldMobile() : m_ShieldEffect( ShieldTraceLine, ShieldTraceHull )
{
m_VertList.Init( this );
m_flFrontDistance = 0;
SetThetaPhi( SHIELD_INITIAL_THETA, SHIELD_INITIAL_PHI );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CShieldMobile::Precache( void )
{
m_ShieldEffect.SetActiveVertexList( &m_VertList );
m_ShieldEffect.SetCollisionGroup( TFCOLLISION_GROUP_SHIELD );
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CShieldMobile::Spawn( void )
{
Precache();
BaseClass::Spawn();
m_ShieldEffect.Spawn(GetAbsOrigin(), GetAbsAngles());
m_ShieldState = 0;
SetAlwaysOrient( false );
// All movement occurs during think
SetMoveType( MOVETYPE_NONE );
SetThink( ShieldThink );
SetNextThink( gpGlobals->curtime + 0.01f );
}
//-----------------------------------------------------------------------------
// Called when the shield is EMPed
//-----------------------------------------------------------------------------
void CShieldMobile::SetEMPed( bool isEmped )
{
CShield::SetEMPed(isEmped);
if (IsEMPed())
m_ShieldState |= SHIELD_MOBILE_EMP;
else
m_ShieldState &= ~SHIELD_MOBILE_EMP;
}
void CShieldMobile::SetThetaPhi( float flTheta, float flPhi )
{
m_flTheta = flTheta;
m_flPhi = flPhi;
m_ShieldEffect.SetThetaPhi( m_flTheta, m_flPhi );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -