diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/hierarchy.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/hierarchy.cpp')
| -rw-r--r-- | mp/src/game/server/hierarchy.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/mp/src/game/server/hierarchy.cpp b/mp/src/game/server/hierarchy.cpp new file mode 100644 index 00000000..df3126a1 --- /dev/null +++ b/mp/src/game/server/hierarchy.cpp @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Contains the set of functions for manipulating entity hierarchies.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+// UNDONE: Reconcile this with SetParent()
+
+#include "cbase.h"
+#include "hierarchy.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Does the linked list work of removing a child object from the hierarchy.
+// Input : pParent -
+// pChild -
+//-----------------------------------------------------------------------------
+void UnlinkChild( CBaseEntity *pParent, CBaseEntity *pChild )
+{
+ CBaseEntity *pList;
+ EHANDLE *pPrev;
+
+ pList = pParent->m_hMoveChild;
+ pPrev = &pParent->m_hMoveChild;
+ while ( pList )
+ {
+ CBaseEntity *pNext = pList->m_hMovePeer;
+ if ( pList == pChild )
+ {
+ // patch up the list
+ pPrev->Set( pNext );
+
+ // Clear hierarchy bits for this guy
+ pList->m_hMoveParent.Set( NULL );
+ pList->m_hMovePeer.Set( NULL );
+ pList->NetworkProp()->SetNetworkParent( CBaseHandle() );
+ pList->DispatchUpdateTransmitState();
+ pList->OnEntityEvent( ENTITY_EVENT_PARENT_CHANGED, NULL );
+
+ pParent->RecalcHasPlayerChildBit();
+ return;
+ }
+ else
+ {
+ pPrev = &pList->m_hMovePeer;
+ pList = pNext;
+ }
+ }
+
+ // This only happens if the child wasn't found in the parent's child list
+ Assert(0);
+}
+
+void LinkChild( CBaseEntity *pParent, CBaseEntity *pChild )
+{
+ EHANDLE hParent;
+ hParent.Set( pParent );
+ pChild->m_hMovePeer.Set( pParent->FirstMoveChild() );
+ pParent->m_hMoveChild.Set( pChild );
+ pChild->m_hMoveParent = hParent;
+ pChild->NetworkProp()->SetNetworkParent( hParent );
+ pChild->DispatchUpdateTransmitState();
+ pChild->OnEntityEvent( ENTITY_EVENT_PARENT_CHANGED, NULL );
+ pParent->RecalcHasPlayerChildBit();
+}
+
+void TransferChildren( CBaseEntity *pOldParent, CBaseEntity *pNewParent )
+{
+ CBaseEntity *pChild = pOldParent->FirstMoveChild();
+ while ( pChild )
+ {
+ // NOTE: Have to do this before the unlink to ensure local coords are valid
+ Vector vecAbsOrigin = pChild->GetAbsOrigin();
+ QAngle angAbsRotation = pChild->GetAbsAngles();
+ Vector vecAbsVelocity = pChild->GetAbsVelocity();
+// QAngle vecAbsAngVelocity = pChild->GetAbsAngularVelocity();
+
+ UnlinkChild( pOldParent, pChild );
+ LinkChild( pNewParent, pChild );
+
+ // FIXME: This is a hack to guarantee update of the local origin, angles, etc.
+ pChild->m_vecAbsOrigin.Init( FLT_MAX, FLT_MAX, FLT_MAX );
+ pChild->m_angAbsRotation.Init( FLT_MAX, FLT_MAX, FLT_MAX );
+ pChild->m_vecAbsVelocity.Init( FLT_MAX, FLT_MAX, FLT_MAX );
+
+ pChild->SetAbsOrigin(vecAbsOrigin);
+ pChild->SetAbsAngles(angAbsRotation);
+ pChild->SetAbsVelocity(vecAbsVelocity);
+// pChild->SetAbsAngularVelocity(vecAbsAngVelocity);
+
+ pChild = pOldParent->FirstMoveChild();
+ }
+}
+
+void UnlinkFromParent( CBaseEntity *pRemove )
+{
+ if ( pRemove->GetMoveParent() )
+ {
+ // NOTE: Have to do this before the unlink to ensure local coords are valid
+ Vector vecAbsOrigin = pRemove->GetAbsOrigin();
+ QAngle angAbsRotation = pRemove->GetAbsAngles();
+ Vector vecAbsVelocity = pRemove->GetAbsVelocity();
+// QAngle vecAbsAngVelocity = pRemove->GetAbsAngularVelocity();
+
+ UnlinkChild( pRemove->GetMoveParent(), pRemove );
+
+ pRemove->SetLocalOrigin(vecAbsOrigin);
+ pRemove->SetLocalAngles(angAbsRotation);
+ pRemove->SetLocalVelocity(vecAbsVelocity);
+// pRemove->SetLocalAngularVelocity(vecAbsAngVelocity);
+ pRemove->UpdateWaterState();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Clears the parent of all the children of the given object.
+//-----------------------------------------------------------------------------
+void UnlinkAllChildren( CBaseEntity *pParent )
+{
+ CBaseEntity *pChild = pParent->FirstMoveChild();
+ while ( pChild )
+ {
+ CBaseEntity *pNext = pChild->NextMovePeer();
+ UnlinkFromParent( pChild );
+ pChild = pNext;
+ }
+}
+
+bool EntityIsParentOf( CBaseEntity *pParent, CBaseEntity *pEntity )
+{
+ while ( pEntity->GetMoveParent() )
+ {
+ pEntity = pEntity->GetMoveParent();
+ if ( pParent == pEntity )
+ return true;
+ }
+
+ return false;
+}
+
+static void GetAllChildren_r( CBaseEntity *pEntity, CUtlVector<CBaseEntity *> &list )
+{
+ for ( ; pEntity != NULL; pEntity = pEntity->NextMovePeer() )
+ {
+ list.AddToTail( pEntity );
+ GetAllChildren_r( pEntity->FirstMoveChild(), list );
+ }
+}
+
+int GetAllChildren( CBaseEntity *pParent, CUtlVector<CBaseEntity *> &list )
+{
+ if ( !pParent )
+ return 0;
+
+ GetAllChildren_r( pParent->FirstMoveChild(), list );
+ return list.Count();
+}
+
+int GetAllInHierarchy( CBaseEntity *pParent, CUtlVector<CBaseEntity *> &list )
+{
+ if (!pParent)
+ return 0;
+ list.AddToTail( pParent );
+ return GetAllChildren( pParent, list ) + 1;
+}
|