Ejemplo n.º 1
0
	void FrameUpdatePostEntityThink()
	{
		g_TouchManager.FrameUpdatePostEntityThink();

		if ( m_bRespawnAllEntities )
		{
			m_bRespawnAllEntities = false;

			// Don't change globalstate owing to deletion here
			GlobalEntity_EnableStateUpdates( false );

			// Remove all entities
			int nPlayerIndex = -1;
			CBaseEntity *pEnt = gEntList.FirstEnt();
			while ( pEnt )
			{
				CBaseEntity *pNextEnt = gEntList.NextEnt( pEnt );
				if ( pEnt->IsPlayer() )
				{
					nPlayerIndex = pEnt->entindex();
				}
				if ( !pEnt->IsEFlagSet( EFL_KEEP_ON_RECREATE_ENTITIES ) )
				{
					UTIL_Remove( pEnt );
				}
				pEnt = pNextEnt;
			}
			
			gEntList.CleanupDeleteList();

			GlobalEntity_EnableStateUpdates( true );

			// Allows us to immediately re-use the edict indices we just freed to avoid edict overflow
			engine->AllowImmediateEdictReuse();

			// Reset node counter used during load
			CNodeEnt::m_nNodeCount = 0;

			CRespawnEntitiesFilter filter;
			MapEntity_ParseAllEntities( engine->GetMapEntitiesString(), &filter, true );

			// Allocate a CBasePlayer for pev, and call spawn
			if ( nPlayerIndex >= 0 )
			{
				edict_t *pEdict = engine->PEntityOfEntIndex( nPlayerIndex );
				ClientPutInServer( pEdict, "unnamed" );
				ClientActive( pEdict, false );

				CBasePlayer *pPlayer = ( CBasePlayer * )CBaseEntity::Instance( pEdict );
				SceneManager_ClientActive( pPlayer );
			}
		}
	}
Ejemplo n.º 2
0
void CHL2MPRules::CleanUpMap()
{
    // Recreate all the map entities from the map data (preserving their indices),
    // then remove everything else except the players.

    // Get rid of all entities except players.
    CBaseEntity *pCur = gEntList.FirstEnt();
    while ( pCur )
    {
        CBaseHL2MPCombatWeapon *pWeapon = dynamic_cast< CBaseHL2MPCombatWeapon* >( pCur );
        // Weapons with owners don't want to be removed..
        if ( pWeapon )
        {
            if ( !pWeapon->GetPlayerOwner() )
            {
                UTIL_Remove( pCur );
            }
        }
        // remove entities that has to be restored on roundrestart (breakables etc)
        else if ( !FindInList( s_PreserveEnts, pCur->GetClassname() ) )
        {
            UTIL_Remove( pCur );
        }

        pCur = gEntList.NextEnt( pCur );
    }

    // Really remove the entities so we can have access to their slots below.
    gEntList.CleanupDeleteList();

    // Cancel all queued events, in case a func_bomb_target fired some delayed outputs that
    // could kill respawning CTs
    g_EventQueue.Clear();

    // Now reload the map entities.
    class CHL2MPMapEntityFilter : public IMapEntityFilter
    {
    public:
        virtual bool ShouldCreateEntity( const char *pClassname )
        {
            // Don't recreate the preserved entities.
            if ( !FindInList( s_PreserveEnts, pClassname ) )
            {
                return true;
            }
            else
            {
                // Increment our iterator since it's not going to call CreateNextEntity for this ent.
                if ( m_iIterator != g_MapEntityRefs.InvalidIndex() )
                    m_iIterator = g_MapEntityRefs.Next( m_iIterator );

                return false;
            }
        }


        virtual CBaseEntity* CreateNextEntity( const char *pClassname )
        {
            if ( m_iIterator == g_MapEntityRefs.InvalidIndex() )
            {
                // This shouldn't be possible. When we loaded the map, it should have used
                // CCSMapLoadEntityFilter, which should have built the g_MapEntityRefs list
                // with the same list of entities we're referring to here.
                Assert( false );
                return NULL;
            }
            else
            {
                CMapEntityRef &ref = g_MapEntityRefs[m_iIterator];
                m_iIterator = g_MapEntityRefs.Next( m_iIterator );	// Seek to the next entity.

                if ( ref.m_iEdict == -1 || engine->PEntityOfEntIndex( ref.m_iEdict ) )
                {
                    // Doh! The entity was delete and its slot was reused.
                    // Just use any old edict slot. This case sucks because we lose the baseline.
                    return CreateEntityByName( pClassname );
                }
                else
                {
                    // Cool, the slot where this entity was is free again (most likely, the entity was
                    // freed above). Now create an entity with this specific index.
                    return CreateEntityByName( pClassname, ref.m_iEdict );
                }
            }
        }

    public:
        int m_iIterator; // Iterator into g_MapEntityRefs.
    };
    CHL2MPMapEntityFilter filter;
    filter.m_iIterator = g_MapEntityRefs.Head();

    // DO NOT CALL SPAWN ON info_node ENTITIES!

    MapEntity_ParseAllEntities( engine->GetMapEntitiesString(), &filter, true );
}