// creates an entity by string name, but does not spawn it CBaseEntity *CreateEntityByName( const char *className, int iForceEdictIndex ) { if ( iForceEdictIndex != -1 ) { g_pForceAttachEdict = engine->CreateEdict( iForceEdictIndex ); if ( !g_pForceAttachEdict ) Error( "CreateEntityByName( %s, %d ) - CreateEdict failed.", className, iForceEdictIndex ); } IServerNetworkable *pNetwork = EntityFactoryDictionary()->Create( className ); g_pForceAttachEdict = NULL; if ( !pNetwork ) return NULL; CBaseEntity *pEntity = pNetwork->GetBaseEntity(); Assert( pEntity ); return pEntity; }
IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity ) { if ( pClientEntity == NULL ) return NULL; CBaseHandle ehandle = pClientEntity->GetRefEHandle(); if ( ehandle.GetEntryIndex() >= MAX_EDICTS ) return NULL; // the first MAX_EDICTS entities are networked, the rest are client or server only #if 0 // this fails, since the server entities have extra bits in their serial numbers, // since 20 bits are reserved for serial numbers, except for networked entities, which are restricted to 10 // Brian believes that everything should just restrict itself to 10 to make things simpler, // so if/when he changes NUM_SERIAL_NUM_BITS to 10, we can switch back to this simpler code IServerNetworkable *pNet = gEntList.GetServerNetworkable( ehandle ); if ( pNet == NULL ) return NULL; CBaseEntity *pServerEnt = pNet->GetBaseEntity(); return pServerEnt; #else IHandleEntity *pEnt = gEntList.LookupEntityByNetworkIndex( ehandle.GetEntryIndex() ); if ( pEnt == NULL ) return NULL; CBaseHandle h = gEntList.GetNetworkableHandle( ehandle.GetEntryIndex() ); const int mask = ( 1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS ) - 1; if ( !h.IsValid() || ( ( h.GetSerialNumber() & mask ) != ( ehandle.GetSerialNumber() & mask ) ) ) return NULL; IServerUnknown *pUnk = static_cast< IServerUnknown* >( pEnt ); return pUnk->GetBaseEntity(); #endif }