From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/server/ServerNetworkProperty.cpp | 305 +++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 mp/src/game/server/ServerNetworkProperty.cpp (limited to 'mp/src/game/server/ServerNetworkProperty.cpp') diff --git a/mp/src/game/server/ServerNetworkProperty.cpp b/mp/src/game/server/ServerNetworkProperty.cpp new file mode 100644 index 00000000..00cba04e --- /dev/null +++ b/mp/src/game/server/ServerNetworkProperty.cpp @@ -0,0 +1,305 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "cbase.h" +#include "ServerNetworkProperty.h" +#include "tier0/dbg.h" +#include "gameinterface.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern CTimedEventMgr g_NetworkPropertyEventMgr; + + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- +BEGIN_DATADESC_NO_BASE( CServerNetworkProperty ) +// DEFINE_FIELD( m_pOuter, FIELD_CLASSPTR ), +// DEFINE_FIELD( m_pPev, FIELD_CLASSPTR ), +// DEFINE_FIELD( m_PVSInfo, PVSInfo_t ), +// DEFINE_FIELD( m_pServerClass, FIELD_CLASSPTR ), + DEFINE_GLOBAL_FIELD( m_hParent, FIELD_EHANDLE ), +// DEFINE_FIELD( m_TimerEvent, CEventRegister ), +// DEFINE_FIELD( m_bPendingStateChange, FIELD_BOOLEAN ), +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +CServerNetworkProperty::CServerNetworkProperty() +{ + Init( NULL ); +} + + +CServerNetworkProperty::~CServerNetworkProperty() +{ + /* Free our transmit proxy. + if ( m_pTransmitProxy ) + { + m_pTransmitProxy->Release(); + }*/ + + engine->CleanUpEntityClusterList( &m_PVSInfo ); + + // remove the attached edict if it exists + DetachEdict(); +} + + +//----------------------------------------------------------------------------- +// Initialization +//----------------------------------------------------------------------------- +void CServerNetworkProperty::Init( CBaseEntity *pEntity ) +{ + m_pPev = NULL; + m_pOuter = pEntity; + m_pServerClass = NULL; +// m_pTransmitProxy = NULL; + m_bPendingStateChange = false; + m_PVSInfo.m_nClusterCount = 0; + m_TimerEvent.Init( &g_NetworkPropertyEventMgr, this ); +} + + +//----------------------------------------------------------------------------- +// Connects, disconnects edicts +//----------------------------------------------------------------------------- +void CServerNetworkProperty::AttachEdict( edict_t *pRequiredEdict ) +{ + Assert ( !m_pPev ); + + // see if there is an edict allocated for it, otherwise get one from the engine + if ( !pRequiredEdict ) + { + pRequiredEdict = engine->CreateEdict(); + } + + m_pPev = pRequiredEdict; + m_pPev->SetEdict( GetBaseEntity(), true ); +} + +void CServerNetworkProperty::DetachEdict() +{ + if ( m_pPev ) + { + m_pPev->SetEdict( NULL, false ); + engine->RemoveEdict( m_pPev ); + m_pPev = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Entity handles +//----------------------------------------------------------------------------- +IHandleEntity *CServerNetworkProperty::GetEntityHandle( ) +{ + return m_pOuter; +} + +void CServerNetworkProperty::Release() +{ + delete m_pOuter; +} + + +//----------------------------------------------------------------------------- +// Returns the network parent +//----------------------------------------------------------------------------- +CServerNetworkProperty* CServerNetworkProperty::GetNetworkParent() +{ + CBaseEntity *pParent = m_hParent.Get(); + return pParent ? pParent->NetworkProp() : NULL; +} + + +//----------------------------------------------------------------------------- +// Marks for deletion +//----------------------------------------------------------------------------- +void CServerNetworkProperty::MarkForDeletion() +{ + m_pOuter->AddEFlags( EFL_KILLME ); +} + +bool CServerNetworkProperty::IsMarkedForDeletion() const +{ + return ( m_pOuter->GetEFlags() & EFL_KILLME ) != 0; +} + + +//----------------------------------------------------------------------------- +// PVS information +//----------------------------------------------------------------------------- +void CServerNetworkProperty::RecomputePVSInformation() +{ + if ( m_pPev && ( ( m_pPev->m_fStateFlags & FL_EDICT_DIRTY_PVS_INFORMATION ) != 0 ) ) + { + m_pPev->m_fStateFlags &= ~FL_EDICT_DIRTY_PVS_INFORMATION; + engine->BuildEntityClusterList( edict(), &m_PVSInfo ); + } +} + + +//----------------------------------------------------------------------------- +// Serverclass +//----------------------------------------------------------------------------- +ServerClass* CServerNetworkProperty::GetServerClass() +{ + if ( !m_pServerClass ) + m_pServerClass = m_pOuter->GetServerClass(); + return m_pServerClass; +} + +const char* CServerNetworkProperty::GetClassName() const +{ + return STRING(m_pOuter->m_iClassname); +} + + +//----------------------------------------------------------------------------- +// Transmit proxies +/*----------------------------------------------------------------------------- +void CServerNetworkProperty::SetTransmitProxy( CBaseTransmitProxy *pProxy ) +{ + if ( m_pTransmitProxy ) + { + m_pTransmitProxy->Release(); + } + + m_pTransmitProxy = pProxy; + + if ( m_pTransmitProxy ) + { + m_pTransmitProxy->AddRef(); + } +}*/ + +//----------------------------------------------------------------------------- +// PVS rules +//----------------------------------------------------------------------------- +bool CServerNetworkProperty::IsInPVS( const edict_t *pRecipient, const void *pvs, int pvssize ) +{ + RecomputePVSInformation(); + + // ignore if not touching a PV leaf + // negative leaf count is a node number + // If no pvs, add any entity + + Assert( pvs && ( edict() != pRecipient ) ); + + unsigned char *pPVS = ( unsigned char * )pvs; + + if ( m_PVSInfo.m_nClusterCount < 0 ) // too many clusters, use headnode + { + return ( engine->CheckHeadnodeVisible( m_PVSInfo.m_nHeadNode, pPVS, pvssize ) != 0); + } + + for ( int i = m_PVSInfo.m_nClusterCount; --i >= 0; ) + { + if (pPVS[m_PVSInfo.m_pClusters[i] >> 3] & (1 << (m_PVSInfo.m_pClusters[i] & 7) )) + return true; + } + + return false; // not visible +} + + +//----------------------------------------------------------------------------- +// PVS: this function is called a lot, so it avoids function calls +//----------------------------------------------------------------------------- +bool CServerNetworkProperty::IsInPVS( const CCheckTransmitInfo *pInfo ) +{ + // PVS data must be up to date + Assert( !m_pPev || ( ( m_pPev->m_fStateFlags & FL_EDICT_DIRTY_PVS_INFORMATION ) == 0 ) ); + + int i; + + // Early out if the areas are connected + if ( !m_PVSInfo.m_nAreaNum2 ) + { + for ( i=0; i< pInfo->m_AreasNetworked; i++ ) + { + int clientArea = pInfo->m_Areas[i]; + if ( clientArea == m_PVSInfo.m_nAreaNum || engine->CheckAreasConnected( clientArea, m_PVSInfo.m_nAreaNum ) ) + break; + } + } + else + { + // doors can legally straddle two areas, so + // we may need to check another one + for ( i=0; i< pInfo->m_AreasNetworked; i++ ) + { + int clientArea = pInfo->m_Areas[i]; + if ( clientArea == m_PVSInfo.m_nAreaNum || clientArea == m_PVSInfo.m_nAreaNum2 ) + break; + + if ( engine->CheckAreasConnected( clientArea, m_PVSInfo.m_nAreaNum ) ) + break; + + if ( engine->CheckAreasConnected( clientArea, m_PVSInfo.m_nAreaNum2 ) ) + break; + } + } + + if ( i == pInfo->m_AreasNetworked ) + { + // areas not connected + return false; + } + + // ignore if not touching a PV leaf + // negative leaf count is a node number + // If no pvs, add any entity + + Assert( edict() != pInfo->m_pClientEnt ); + + unsigned char *pPVS = ( unsigned char * )pInfo->m_PVS; + + if ( m_PVSInfo.m_nClusterCount < 0 ) // too many clusters, use headnode + { + return (engine->CheckHeadnodeVisible( m_PVSInfo.m_nHeadNode, pPVS, pInfo->m_nPVSSize ) != 0); + } + + for ( i = m_PVSInfo.m_nClusterCount; --i >= 0; ) + { + int nCluster = m_PVSInfo.m_pClusters[i]; + if ( ((int)(pPVS[nCluster >> 3])) & BitVec_BitInByte( nCluster ) ) + return true; + } + + return false; // not visible + +} + + +void CServerNetworkProperty::SetUpdateInterval( float val ) +{ + if ( val == 0 ) + m_TimerEvent.StopUpdates(); + else + m_TimerEvent.SetUpdateInterval( val ); +} + + +void CServerNetworkProperty::FireEvent() +{ + // Our timer went off. If our state has changed in the background, then + // trigger a state change in the edict. + if ( m_bPendingStateChange ) + { + m_pPev->StateChanged(); + m_bPendingStateChange = false; + } +} + + + -- cgit v1.2.3