mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 03:56:10 +08:00
Add CEntityKeyValues, EntityInstanceIter_t, EntityInstanceByNameIter_t, EntityInstanceByClassIter_t & other stuff (#183)
* Replace g_pEntitySystem with GameEntitySystem() function; * KeyValues3, CGameSystem & CVariant updates;
This commit is contained in:
16
entity2/entityidentity.cpp
Normal file
16
entity2/entityidentity.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "entityidentity.h"
|
||||
#include "entitysystem.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
bool CEntityIdentity::NameMatches( const char* szName ) const
|
||||
{
|
||||
if ( szName && szName[0] == '!' )
|
||||
return GameEntitySystem()->FindEntityProcedural( szName ) == m_pInstance;
|
||||
|
||||
return V_CompareNameWithWildcards( szName, m_name.String() ) == 0;
|
||||
}
|
||||
|
||||
bool CEntityIdentity::ClassMatches( const char* szClassName ) const
|
||||
{
|
||||
return V_CompareNameWithWildcards( szClassName, m_designerName.String() ) == 0;
|
||||
}
|
335
entity2/entitykeyvalues.cpp
Normal file
335
entity2/entitykeyvalues.cpp
Normal file
@ -0,0 +1,335 @@
|
||||
#include "entity2/entitykeyvalues.h"
|
||||
#include "tier0/logging.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CEntityKeyValues::CEntityKeyValues( CKeyValues3Context* allocator, EntityKVAllocatorType_t allocator_type ) :
|
||||
m_pComplexKeys( NULL ),
|
||||
m_nRefCount( 0 ),
|
||||
m_nQueuedForSpawnCount( 0 ),
|
||||
m_bAllowLogging( false ),
|
||||
m_eAllocatorType( allocator_type )
|
||||
{
|
||||
if ( allocator )
|
||||
{
|
||||
m_pAllocator = allocator;
|
||||
|
||||
if ( GameEntitySystem() && m_pAllocator == GameEntitySystem()->GetEntityKeyValuesAllocator() )
|
||||
GameEntitySystem()->AddEntityKeyValuesAllocatorRef();
|
||||
|
||||
m_pValues = m_pAllocator->AllocKV();
|
||||
m_pAttributes = m_pAllocator->AllocKV();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !GameEntitySystem() && ( m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_1 || m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_2 ) )
|
||||
m_eAllocatorType = EKV_ALLOCATOR_NORMAL;
|
||||
|
||||
m_pAllocator = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CEntityKeyValues::~CEntityKeyValues()
|
||||
{
|
||||
ReleaseAllComplexKeys();
|
||||
|
||||
if ( m_pAllocator )
|
||||
{
|
||||
if ( m_eAllocatorType != EKV_ALLOCATOR_NORMAL )
|
||||
{
|
||||
m_pAllocator->FreeKV( m_pValues );
|
||||
m_pAllocator->FreeKV( m_pAttributes );
|
||||
|
||||
if ( GameEntitySystem() && m_pAllocator == GameEntitySystem()->GetEntityKeyValuesAllocator() )
|
||||
GameEntitySystem()->ReleaseEntityKeyValuesAllocatorRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_pAllocator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityKeyValues::ValidateAllocator()
|
||||
{
|
||||
if ( !m_pAllocator )
|
||||
{
|
||||
if ( m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_1 || m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_2 )
|
||||
{
|
||||
Assert( GameEntitySystem() );
|
||||
m_pAllocator = GameEntitySystem()->GetEntityKeyValuesAllocator();
|
||||
GameEntitySystem()->AddEntityKeyValuesAllocatorRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( m_eAllocatorType != EKV_ALLOCATOR_EXTERNAL );
|
||||
m_pAllocator = new CKeyValues3Context( true );
|
||||
}
|
||||
|
||||
m_pValues = m_pAllocator->AllocKV();
|
||||
m_pAttributes = m_pAllocator->AllocKV();
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityKeyValues::AddRef()
|
||||
{
|
||||
++m_nRefCount;
|
||||
|
||||
if ( m_bAllowLogging )
|
||||
Log_Msg( LOG_GENERAL, "kv 0x%p AddRef refcount == %d\n", this, m_nRefCount );
|
||||
}
|
||||
|
||||
void CEntityKeyValues::Release()
|
||||
{
|
||||
--m_nRefCount;
|
||||
|
||||
if ( m_bAllowLogging )
|
||||
Log_Msg( LOG_GENERAL, "kv 0x%p Release refcount == %d\n", this, m_nRefCount );
|
||||
|
||||
if ( m_nRefCount <= 0 )
|
||||
delete this;
|
||||
}
|
||||
|
||||
const KeyValues3* CEntityKeyValues::GetKeyValue( const EntityKeyId_t &id, bool* pIsAttribute ) const
|
||||
{
|
||||
if ( !m_pAllocator )
|
||||
return NULL;
|
||||
|
||||
const KeyValues3* kv = m_pValues->FindMember( id );
|
||||
|
||||
if ( kv )
|
||||
{
|
||||
if ( pIsAttribute )
|
||||
*pIsAttribute = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
kv = m_pAttributes->FindMember( id );
|
||||
|
||||
if ( kv )
|
||||
{
|
||||
if ( pIsAttribute )
|
||||
*pIsAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
KeyValues3* CEntityKeyValues::SetKeyValue( const EntityKeyId_t &id, const char* pAttributeName )
|
||||
{
|
||||
if ( m_nQueuedForSpawnCount > 0 )
|
||||
return NULL;
|
||||
|
||||
ValidateAllocator();
|
||||
|
||||
bool bIsAttribute;
|
||||
KeyValues3* kv = const_cast<KeyValues3*>( GetKeyValue( id, &bIsAttribute ) );
|
||||
|
||||
if ( kv )
|
||||
{
|
||||
if ( !bIsAttribute && pAttributeName )
|
||||
{
|
||||
kv = NULL;
|
||||
Warning( "Attempted to set non-attribute value %s as if it was an attribute!\n", pAttributeName );
|
||||
}
|
||||
else if ( bIsAttribute && !pAttributeName )
|
||||
{
|
||||
pAttributeName = "<none>";
|
||||
|
||||
for ( int i = 0; i < m_pAttributes->GetMemberCount(); ++i )
|
||||
{
|
||||
if ( m_pAttributes->GetMember( i ) != kv )
|
||||
continue;
|
||||
|
||||
pAttributeName = m_pAttributes->GetMemberName( i );
|
||||
break;
|
||||
}
|
||||
|
||||
kv = NULL;
|
||||
Warning( "Attempted to set attribute %s as if it was a non-attribute key!\n", pAttributeName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pAttributeName )
|
||||
kv = m_pAttributes->FindOrCreateMember( id );
|
||||
else
|
||||
kv = m_pValues->FindOrCreateMember( id );
|
||||
}
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
void CEntityKeyValues::AddConnectionDesc(
|
||||
const char* pszOutputName,
|
||||
EntityIOTargetType_t eTargetType,
|
||||
const char* pszTargetName,
|
||||
const char* pszInputName,
|
||||
const char* pszOverrideParam,
|
||||
float flDelay,
|
||||
int32 nTimesToFire )
|
||||
{
|
||||
if ( m_nQueuedForSpawnCount > 0 )
|
||||
return;
|
||||
|
||||
ValidateAllocator();
|
||||
|
||||
EntityIOConnectionDescFat_t* desc = m_connectionDescs.AddToTailGetPtr();
|
||||
|
||||
desc->m_pszOutputName = m_pAllocator->AllocString( pszOutputName ? pszOutputName : "" );
|
||||
desc->m_eTargetType = eTargetType;
|
||||
desc->m_pszTargetName = m_pAllocator->AllocString( pszTargetName ? pszTargetName : "" );
|
||||
desc->m_pszInputName = m_pAllocator->AllocString( pszInputName ? pszInputName : "" );
|
||||
desc->m_pszOverrideParam = m_pAllocator->AllocString( pszOverrideParam ? pszOverrideParam : "" );
|
||||
desc->m_flDelay = flDelay;
|
||||
desc->m_nTimesToFire = nTimesToFire;
|
||||
}
|
||||
|
||||
void CEntityKeyValues::CopyFrom( const CEntityKeyValues* pSrc, bool bRemoveAllKeys, bool bSkipEHandles )
|
||||
{
|
||||
if ( bRemoveAllKeys )
|
||||
RemoveAllKeys();
|
||||
|
||||
for ( EntityComplexKeyListElem_t* pListElem = pSrc->m_pComplexKeys; pListElem != NULL; pListElem = pListElem->m_pNext )
|
||||
{
|
||||
m_pComplexKeys = new EntityComplexKeyListElem_t( pListElem->m_pKey, m_pComplexKeys );
|
||||
pListElem->m_pKey->AddRef();
|
||||
}
|
||||
|
||||
FOR_EACH_ENTITYKEY( pSrc, iter )
|
||||
{
|
||||
const char* pAttributeName = NULL;
|
||||
|
||||
if ( pSrc->IsAttribute( iter ) )
|
||||
{
|
||||
pAttributeName = pSrc->GetAttributeName( iter );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bSkipEHandles && pSrc->GetKeyValue( iter )->GetSubType() == KV3_SUBTYPE_EHANDLE )
|
||||
continue;
|
||||
}
|
||||
|
||||
KeyValues3* kv = SetKeyValue( pSrc->GetEntityKeyId( iter ), pAttributeName );
|
||||
|
||||
if ( kv )
|
||||
*kv = *pSrc->GetKeyValue( iter );
|
||||
}
|
||||
|
||||
m_connectionDescs.RemoveAll();
|
||||
m_connectionDescs.EnsureCapacity( pSrc->m_connectionDescs.Count() );
|
||||
|
||||
FOR_EACH_LEANVEC( pSrc->m_connectionDescs, iter )
|
||||
{
|
||||
AddConnectionDesc(
|
||||
pSrc->m_connectionDescs[ iter ].m_pszOutputName,
|
||||
pSrc->m_connectionDescs[ iter ].m_eTargetType,
|
||||
pSrc->m_connectionDescs[ iter ].m_pszTargetName,
|
||||
pSrc->m_connectionDescs[ iter ].m_pszInputName,
|
||||
pSrc->m_connectionDescs[ iter ].m_pszOverrideParam,
|
||||
pSrc->m_connectionDescs[ iter ].m_flDelay,
|
||||
pSrc->m_connectionDescs[ iter ].m_nTimesToFire );
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityKeyValues::RemoveKeyValue( const EntityKeyId_t &id )
|
||||
{
|
||||
if ( m_nQueuedForSpawnCount > 0 || !m_pAllocator )
|
||||
return;
|
||||
|
||||
if ( !m_pValues->RemoveMember( id ) )
|
||||
m_pAttributes->RemoveMember( id );
|
||||
}
|
||||
|
||||
void CEntityKeyValues::RemoveAllKeys()
|
||||
{
|
||||
if ( m_nQueuedForSpawnCount > 0 )
|
||||
return;
|
||||
|
||||
ReleaseAllComplexKeys();
|
||||
|
||||
if ( m_pAllocator )
|
||||
{
|
||||
if ( m_eAllocatorType != EKV_ALLOCATOR_NORMAL )
|
||||
{
|
||||
m_pValues->SetToEmptyTable();
|
||||
m_pAttributes->SetToEmptyTable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pAllocator->Clear();
|
||||
m_pValues = m_pAllocator->AllocKV();
|
||||
m_pAttributes = m_pAllocator->AllocKV();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CEntityKeyValues::IsEmpty() const
|
||||
{
|
||||
if ( !m_pAllocator )
|
||||
return true;
|
||||
|
||||
if ( !m_pValues->GetMemberCount() && !m_pAttributes->GetMemberCount() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEntityKeyValues::ValuesHasBadNames() const
|
||||
{
|
||||
if ( !m_pAllocator )
|
||||
return false;
|
||||
|
||||
return m_pValues->TableHasBadNames();
|
||||
}
|
||||
|
||||
bool CEntityKeyValues::AttributesHasBadNames() const
|
||||
{
|
||||
if ( !m_pAllocator )
|
||||
return false;
|
||||
|
||||
return m_pAttributes->TableHasBadNames();
|
||||
}
|
||||
|
||||
void CEntityKeyValues::ReleaseAllComplexKeys()
|
||||
{
|
||||
EntityComplexKeyListElem_t* pListElem = m_pComplexKeys;
|
||||
|
||||
while ( pListElem != NULL )
|
||||
{
|
||||
EntityComplexKeyListElem_t* pListElemForRelease = pListElem;
|
||||
pListElem = pListElem->m_pNext;
|
||||
pListElemForRelease->m_pKey->Release();
|
||||
delete pListElemForRelease;
|
||||
}
|
||||
|
||||
m_pComplexKeys = NULL;
|
||||
}
|
||||
|
||||
CEntityHandle CEntityKeyValues::GetEHandle( const EntityKeyId_t &id, WorldGroupId_t worldGroupId, CEntityHandle defaultValue ) const
|
||||
{
|
||||
const KeyValues3* kv = GetKeyValue( id );
|
||||
|
||||
if ( !kv )
|
||||
return defaultValue;
|
||||
|
||||
switch ( kv->GetType() )
|
||||
{
|
||||
case KV3_TYPE_UINT:
|
||||
return kv->GetEHandle( defaultValue );
|
||||
case KV3_TYPE_STRING:
|
||||
Assert( GameEntitySystem() );
|
||||
return GameEntitySystem()->FindFirstEntityHandleByName( kv->GetString(), worldGroupId );
|
||||
default:
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityKeyValues::SetString( KeyValues3* kv, const char* string )
|
||||
{
|
||||
ValidateAllocator();
|
||||
|
||||
kv->SetStringExternal( m_pAllocator->AllocString( string ) );
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
#include "const.h"
|
||||
#include "entity2/entitysystem.h"
|
||||
#include "entity2/entityclass.h"
|
||||
|
||||
CBaseEntity* CEntitySystem::GetBaseEntity(CEntityIndex entnum)
|
||||
CEntityIdentity* CEntitySystem::GetEntityIdentity(CEntityIndex entnum)
|
||||
{
|
||||
if (entnum.Get() <= -1 || entnum.Get() >= (MAX_TOTAL_ENTITIES - 1))
|
||||
return nullptr;
|
||||
@ -17,10 +18,10 @@ CBaseEntity* CEntitySystem::GetBaseEntity(CEntityIndex entnum)
|
||||
if (pIdentity->GetEntityIndex() != entnum)
|
||||
return nullptr;
|
||||
|
||||
return static_cast<CBaseEntity*>(pIdentity->m_pInstance);
|
||||
return pIdentity;
|
||||
}
|
||||
|
||||
CBaseEntity* CEntitySystem::GetBaseEntity(const CEntityHandle& hEnt)
|
||||
CEntityIdentity* CEntitySystem::GetEntityIdentity(const CEntityHandle& hEnt)
|
||||
{
|
||||
if (!hEnt.IsValid())
|
||||
return nullptr;
|
||||
@ -36,7 +37,68 @@ CBaseEntity* CEntitySystem::GetBaseEntity(const CEntityHandle& hEnt)
|
||||
if (pIdentity->GetRefEHandle() != hEnt)
|
||||
return nullptr;
|
||||
|
||||
return static_cast<CBaseEntity*>(pIdentity->m_pInstance);
|
||||
return pIdentity;
|
||||
}
|
||||
|
||||
CEntityClass* CEntitySystem::FindClassByName(const char* szClassName)
|
||||
{
|
||||
if (!szClassName || !*szClassName)
|
||||
return nullptr;
|
||||
|
||||
unsigned short idx = m_entClassesByCPPClassname.Find(szClassName);
|
||||
if (idx == m_entClassesByCPPClassname.InvalidIndex())
|
||||
{
|
||||
// vscript stuff is skipped here
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_entClassesByCPPClassname[ idx ];
|
||||
}
|
||||
|
||||
CEntityClass* CEntitySystem::FindClassByDesignName(const char* szClassName)
|
||||
{
|
||||
if (!szClassName || !*szClassName)
|
||||
return nullptr;
|
||||
|
||||
unsigned short idx = m_entClassesByClassname.Find(szClassName);
|
||||
if (idx == m_entClassesByClassname.InvalidIndex())
|
||||
{
|
||||
// vscript stuff is skipped here
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_entClassesByClassname[ idx ];
|
||||
}
|
||||
|
||||
CEntityHandle CEntitySystem::FindFirstEntityHandleByName(const char* szName, WorldGroupId_t hWorldGroupId)
|
||||
{
|
||||
if (!szName || !*szName)
|
||||
return CEntityHandle();
|
||||
|
||||
EntityInstanceByNameIter_t iter(szName);
|
||||
iter.SetWorldGroupId(hWorldGroupId);
|
||||
|
||||
CEntityInstance* pEntity = iter.First();
|
||||
if (!pEntity)
|
||||
return CEntityHandle();
|
||||
|
||||
return pEntity->GetRefEHandle();
|
||||
}
|
||||
|
||||
CUtlSymbolLarge CEntitySystem::AllocPooledString(const char* pString)
|
||||
{
|
||||
if (!pString || !*pString)
|
||||
return CUtlSymbolLarge();
|
||||
|
||||
return m_Symbols.AddString(pString);
|
||||
}
|
||||
|
||||
CUtlSymbolLarge CEntitySystem::FindPooledString(const char* pString)
|
||||
{
|
||||
if (!pString || !*pString)
|
||||
return CUtlSymbolLarge();
|
||||
|
||||
return m_Symbols.Find(pString);
|
||||
}
|
||||
|
||||
void CGameEntitySystem::AddListenerEntity(IEntityListener* pListener)
|
||||
@ -51,3 +113,265 @@ void CGameEntitySystem::RemoveListenerEntity(IEntityListener* pListener)
|
||||
{
|
||||
m_entityListeners.FindAndRemove(pListener);
|
||||
}
|
||||
|
||||
EntityInstanceIter_t::EntityInstanceIter_t(IEntityFindFilter* pFilter, EntityIterType_t eIterType)
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
m_pFilter = pFilter;
|
||||
m_eIterType = eIterType;
|
||||
m_hWorldGroupId = WorldGroupId_t();
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceIter_t::First()
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
return Next();
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceIter_t::Next()
|
||||
{
|
||||
if (m_pCurrentEnt)
|
||||
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
|
||||
else
|
||||
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
|
||||
|
||||
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
|
||||
{
|
||||
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
|
||||
continue;
|
||||
|
||||
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
|
||||
continue;
|
||||
|
||||
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_pCurrentEnt)
|
||||
return m_pCurrentEnt->m_pInstance;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EntityInstanceByNameIter_t::EntityInstanceByNameIter_t(const char* szName, CEntityInstance* pSearchingEntity, CEntityInstance* pActivator, CEntityInstance* pCaller, IEntityFindFilter* pFilter, EntityIterType_t eIterType)
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
m_pFilter = pFilter;
|
||||
m_eIterType = eIterType;
|
||||
m_hWorldGroupId = WorldGroupId_t();
|
||||
|
||||
if (szName[0] == '!')
|
||||
{
|
||||
m_pszEntityName = nullptr;
|
||||
m_pEntityHandles = nullptr;
|
||||
m_nCurEntHandle = 0;
|
||||
m_nNumEntHandles = 0;
|
||||
m_pProceduralEnt = GameEntitySystem()->FindEntityProcedural(szName, pSearchingEntity, pActivator, pCaller);
|
||||
}
|
||||
else if (strchr(szName, '*') || eIterType == ENTITY_ITER_OVER_DORMANT)
|
||||
{
|
||||
m_pszEntityName = szName;
|
||||
m_pEntityHandles = nullptr;
|
||||
m_nCurEntHandle = 0;
|
||||
m_nNumEntHandles = 0;
|
||||
m_pProceduralEnt = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pszEntityName = nullptr;
|
||||
m_pProceduralEnt = nullptr;
|
||||
|
||||
CUtlSymbolLarge nameSymbol = GameEntitySystem()->FindPooledString(szName);
|
||||
|
||||
unsigned short idx = GameEntitySystem()->m_entityNames.Find(nameSymbol);
|
||||
if (idx == GameEntitySystem()->m_entityNames.InvalidIndex())
|
||||
{
|
||||
m_pEntityHandles = nullptr;
|
||||
m_nCurEntHandle = 0;
|
||||
m_nNumEntHandles = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEntityHandles = GameEntitySystem()->m_entityNames[ idx ];
|
||||
m_nCurEntHandle = 0;
|
||||
|
||||
if (m_pEntityHandles)
|
||||
{
|
||||
m_nNumEntHandles = m_pEntityHandles->Count();
|
||||
|
||||
if (!m_nNumEntHandles)
|
||||
m_pEntityHandles = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nNumEntHandles = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceByNameIter_t::First()
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
return Next();
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceByNameIter_t::Next()
|
||||
{
|
||||
if (m_pProceduralEnt)
|
||||
{
|
||||
if (m_pCurrentEnt)
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_pFilter || m_pFilter->ShouldFindEntity(m_pProceduralEnt))
|
||||
m_pCurrentEnt = m_pProceduralEnt->m_pEntity;
|
||||
}
|
||||
}
|
||||
else if (m_pEntityHandles)
|
||||
{
|
||||
if ( !m_pCurrentEnt )
|
||||
m_nCurEntHandle = m_nNumEntHandles;
|
||||
|
||||
for (--m_nCurEntHandle; m_nCurEntHandle >= 0; --m_nCurEntHandle)
|
||||
{
|
||||
m_pCurrentEnt = GameEntitySystem()->GetEntityIdentity(m_pEntityHandles->Element(m_nCurEntHandle));
|
||||
|
||||
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
|
||||
continue;
|
||||
|
||||
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
|
||||
continue;
|
||||
|
||||
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_nCurEntHandle < 0)
|
||||
m_pCurrentEnt = nullptr;
|
||||
}
|
||||
else if (m_pszEntityName)
|
||||
{
|
||||
if (m_pCurrentEnt)
|
||||
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
|
||||
else
|
||||
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
|
||||
|
||||
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
|
||||
{
|
||||
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
|
||||
continue;
|
||||
|
||||
if (!m_pCurrentEnt->m_name.IsValid())
|
||||
continue;
|
||||
|
||||
if (!m_pCurrentEnt->NameMatches(m_pszEntityName))
|
||||
continue;
|
||||
|
||||
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
|
||||
continue;
|
||||
|
||||
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pCurrentEnt)
|
||||
return m_pCurrentEnt->m_pInstance;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EntityInstanceByClassIter_t::EntityInstanceByClassIter_t(const char* szClassName, IEntityFindFilter* pFilter, EntityIterType_t eIterType)
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
m_pFilter = pFilter;
|
||||
m_eIterType = eIterType;
|
||||
m_hWorldGroupId = WorldGroupId_t();
|
||||
|
||||
if (strchr(szClassName, '*') || eIterType == ENTITY_ITER_OVER_DORMANT)
|
||||
{
|
||||
m_pszClassName = szClassName;
|
||||
m_pEntityClass = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEntityClass = GameEntitySystem()->FindClassByDesignName(szClassName);
|
||||
|
||||
if (!m_pEntityClass)
|
||||
m_pszClassName = szClassName;
|
||||
else
|
||||
m_pszClassName = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceByClassIter_t::First()
|
||||
{
|
||||
m_pCurrentEnt = nullptr;
|
||||
return Next();
|
||||
}
|
||||
|
||||
CEntityInstance* EntityInstanceByClassIter_t::Next()
|
||||
{
|
||||
if (m_pEntityClass)
|
||||
{
|
||||
if (m_pCurrentEnt)
|
||||
m_pCurrentEnt = m_pCurrentEnt->m_pNextByClass;
|
||||
else
|
||||
m_pCurrentEnt = m_pEntityClass->m_pFirstEntity;
|
||||
|
||||
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNextByClass)
|
||||
{
|
||||
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
|
||||
continue;
|
||||
|
||||
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
|
||||
continue;
|
||||
|
||||
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_pszClassName)
|
||||
{
|
||||
if (m_pCurrentEnt)
|
||||
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
|
||||
else
|
||||
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
|
||||
|
||||
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
|
||||
{
|
||||
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
|
||||
continue;
|
||||
|
||||
if (!m_pCurrentEnt->m_designerName.IsValid())
|
||||
continue;
|
||||
|
||||
if (!m_pCurrentEnt->ClassMatches(m_pszClassName))
|
||||
continue;
|
||||
|
||||
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
|
||||
continue;
|
||||
|
||||
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pCurrentEnt)
|
||||
return m_pCurrentEnt->m_pInstance;
|
||||
|
||||
return nullptr;
|
||||
}
|
Reference in New Issue
Block a user