//-----------------------------------------------------------------------------
// Purpose: Recurses an entity hierarchy and fills out a list of all entities
// in the hierarchy with their current origins and angles.
//
// This list is necessary to keep lazy updates of abs origins and angles
// from messing up our child/constrained entity fixup.
//-----------------------------------------------------------------------------
static void BuildTeleportList_r( CBaseEntity *pTeleport, CUtlVector<TeleportListEntry_t> &teleportList )
{
TeleportListEntry_t entry;
entry.pEntity = pTeleport;
entry.prevAbsOrigin = pTeleport->GetAbsOrigin();
entry.prevAbsAngles = pTeleport->GetAbsAngles();
teleportList.AddToTail( entry );
CBaseEntity *pList = pTeleport->FirstMoveChild();
while ( pList )
{
BuildTeleportList_r( pList, teleportList );
pList = pList->NextMovePeer();
}
}
static CUtlVector<CBaseEntity *> g_TeleportStack;
void CBaseEntity::Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
{
if ( g_TeleportStack.Find( this ) >= 0 )
return;
int index = g_TeleportStack.AddToTail( this );
CUtlVector<TeleportListEntry_t> teleportList;
BuildTeleportList_r( this, teleportList );
int i;
for ( i = 0; i < teleportList.Count(); i++)
{
TeleportEntity( this, teleportList[i], newPosition, newAngles, newVelocity );
}
for (i = 0; i < teleportList.Count(); i++)
{
teleportList[i].pEntity->CollisionRulesChanged();
}
Assert( g_TeleportStack[index] == this );
g_TeleportStack.FastRemove( index );
// FIXME: add an initializer function to StepSimulationData
StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION );
if (step)
{
Q_memset( step, 0, sizeof( *step ) );
}
}