//Ent version. bool CMapEntityFilter::ShouldCreateEntity( CBaseEntity *pEnt ) { //Skip common castable ents. //All Defines. CBaseHL2MPCombatWeapon *Weapon = dynamic_cast<CBaseHL2MPCombatWeapon *>( pEnt ); CSpawnPoint *Spot = dynamic_cast<CSpawnPoint *>( pEnt ); if ( Spot || Weapon && Weapon->GetPlayerOwner() ) return false; // const char *pTargetname = STRING( pEnt->GetEntityName() ); for ( int x = 0; x < keepTargetnameList.Count(); x++ ) { if ( !Q_stricmp( keepTargetnameList[x], pTargetname ) ) return false; } return true; }
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 ); }