mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
387 lines
9.8 KiB
C++
387 lines
9.8 KiB
C++
#include "const.h"
|
|
#include "entity2/entitysystem.h"
|
|
#include "entity2/entityclass.h"
|
|
|
|
CEntityIdentity* CEntitySystem::GetEntityIdentity(CEntityIndex entnum)
|
|
{
|
|
if (entnum.Get() <= -1 || entnum.Get() >= (MAX_TOTAL_ENTITIES - 1))
|
|
return nullptr;
|
|
|
|
CEntityIdentity* pChunkToUse = m_EntityList.m_pIdentityChunks[entnum.Get() / MAX_ENTITIES_IN_LIST];
|
|
if (!pChunkToUse)
|
|
return nullptr;
|
|
|
|
CEntityIdentity* pIdentity = &pChunkToUse[entnum.Get() % MAX_ENTITIES_IN_LIST];
|
|
if (!pIdentity)
|
|
return nullptr;
|
|
|
|
if (pIdentity->GetEntityIndex() != entnum)
|
|
return nullptr;
|
|
|
|
return pIdentity;
|
|
}
|
|
|
|
CEntityIdentity* CEntitySystem::GetEntityIdentity(const CEntityHandle& hEnt)
|
|
{
|
|
if (!hEnt.IsValid())
|
|
return nullptr;
|
|
|
|
CEntityIdentity* pChunkToUse = m_EntityList.m_pIdentityChunks[hEnt.GetEntryIndex() / MAX_ENTITIES_IN_LIST];
|
|
if (!pChunkToUse)
|
|
return nullptr;
|
|
|
|
CEntityIdentity* pIdentity = &pChunkToUse[hEnt.GetEntryIndex() % MAX_ENTITIES_IN_LIST];
|
|
if (!pIdentity)
|
|
return nullptr;
|
|
|
|
if (pIdentity->GetRefEHandle() != hEnt)
|
|
return nullptr;
|
|
|
|
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)
|
|
{
|
|
if (m_entityListeners.Find(pListener) == -1)
|
|
{
|
|
m_entityListeners.AddToTail(pListener);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
EntityInstanceByClassIter_t::EntityInstanceByClassIter_t(CEntityInstance* pStart, const char* szClassName, IEntityFindFilter* pFilter, EntityIterType_t eIterType)
|
|
{
|
|
m_pCurrentEnt = pStart ? pStart->m_pEntity : nullptr;
|
|
m_pFilter = pFilter;
|
|
m_eIterType = eIterType;
|
|
m_hWorldGroupId = WorldGroupId_t();
|
|
m_pszClassName = szClassName;
|
|
m_pEntityClass = NULL;
|
|
}
|
|
|
|
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;
|
|
} |