1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2024-12-23 01:59:43 +08:00
hl2sdk/entity2/entitysystem.cpp
2024-02-07 19:40:14 +03:00

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;
}