diff --git a/addons/source-python/packages/source-python/entities/collisions.py b/addons/source-python/packages/source-python/entities/collisions.py old mode 100644 new mode 100755 index 1ad6b3b52..7ae90ee6e --- a/addons/source-python/packages/source-python/entities/collisions.py +++ b/addons/source-python/packages/source-python/entities/collisions.py @@ -19,30 +19,30 @@ # ============================================================================= # Source.Python Imports # Entities -from _entities._collisions import BaseCollisionHash -from _entities._collisions import CollisionHash +from _entities._collisions import CollisionFilter from _entities._collisions import CollisionManager +from _entities._collisions import CollisionTable from _entities._collisions import collision_manager # ============================================================================= # >> ALL DECLARATION # ============================================================================= -__all__ = [ - 'BaseCollisionHash', - 'CollisionHash', - 'CollisionHook', - 'CollisionManager', - 'collision_manager', -] +__all__ = ('SOLID_MASKS', + 'CollisionFilter', + 'CollisionHook', + 'CollisionManager', + 'CollisionTable', + 'collision_manager', + ) # ============================================================================= # >> INITIALIZATION # ============================================================================= -# Inject AutoUnload into BaseCollisionHash's hierarchy. -if not issubclass(BaseCollisionHash, AutoUnload): - BaseCollisionHash.__bases__ = (AutoUnload,) + BaseCollisionHash.__bases__ +# Inject AutoUnload into CollisionFilter's hierarchy. +if not issubclass(CollisionFilter, AutoUnload): + CollisionFilter.__bases__ = (AutoUnload,) + CollisionFilter.__bases__ # ============================================================================= diff --git a/src/core/modules/entities/entities_collisions.cpp b/src/core/modules/entities/entities_collisions.cpp old mode 100644 new mode 100755 index 161d0efbb..ba9586334 --- a/src/core/modules/entities/entities_collisions.cpp +++ b/src/core/modules/entities/entities_collisions.cpp @@ -40,7 +40,7 @@ // Externals. //----------------------------------------------------------------------------- extern IEngineTrace *enginetrace; -extern IPhysics *physics; +extern IServerTools *servertools; extern CGlobalVars *gpGlobals; @@ -118,22 +118,22 @@ void CCollisionManager::Finalize() m_bInitialized = false; } -void CCollisionManager::RegisterHash(ICollisionHash *pHash) +void CCollisionManager::RegisterFilter(CCollisionFilter *pFilter) { - if (m_vecHashes.HasElement(pHash)) { + if (m_vecFilteres.HasElement(pFilter)) { BOOST_RAISE_EXCEPTION( PyExc_ValueError, - "The given hash is already registered." + "The given filter is already registered." ); } IncRef(); - m_vecHashes.AddToTail(pHash); + m_vecFilteres.AddToTail(pFilter); } -void CCollisionManager::UnregisterHash(ICollisionHash *pHash) +void CCollisionManager::UnregisterFilter(CCollisionFilter *pFilter) { - if (!m_vecHashes.FindAndRemove(pHash)) { + if (!m_vecFilteres.FindAndRemove(pFilter)) { return; } @@ -159,8 +159,8 @@ void CCollisionManager::OnNetworkedEntityCreated(object oEntity) void CCollisionManager::OnNetworkedEntityDeleted(CBaseEntity *pEntity) { - FOR_EACH_VEC(m_vecHashes, i) { - m_vecHashes[i]->RemovePairs((void *)pEntity); + FOR_EACH_VEC(m_vecFilteres, i) { + m_vecFilteres[i]->Erase(pEntity); } } @@ -421,8 +421,8 @@ bool CCollisionManager::ShouldHitEntity(IHandleEntity *pHandleEntity, int conten return true; } - FOR_EACH_VEC(pManager->m_vecHashes, i) { - if (pManager->m_vecHashes[i]->HasPair((void *)scope.m_pFilter->m_pPassEnt, (void *)pHandleEntity)) { + FOR_EACH_VEC(pManager->m_vecFilteres, i) { + if (pManager->m_vecFilteres[i]->IsSet(scope.m_uiIndex, uiIndex)) { scope.m_pCache->SetResult(uiIndex, false); return false; } @@ -499,131 +499,435 @@ CCollisionCache *CCollisionManager::GetCache(unsigned int uiIndex) //----------------------------------------------------------------------------- -// ICollisionHash class. +// CCollisionCache class. //----------------------------------------------------------------------------- -ICollisionHash::ICollisionHash() +bool CCollisionCache::HasResult(unsigned int uiIndex) { - static CCollisionManager *pManager = GetCollisionManager(); - pManager->RegisterHash(this); + return IsBitSet(uiIndex); } -ICollisionHash::~ICollisionHash() +bool CCollisionCache::GetResult(unsigned int uiIndex) { - UnloadInstance(); + return m_vecCache.IsBitSet(uiIndex); } -void ICollisionHash::UnloadInstance() +void CCollisionCache::SetResult(unsigned int uiIndex, bool bResult) { - static CCollisionManager *pManager = GetCollisionManager(); - pManager->UnregisterHash(this); + Set(uiIndex); + m_vecCache.Set((int)uiIndex, bResult); } //----------------------------------------------------------------------------- -// CCollisionCache class. +// CCollisionTable class. //----------------------------------------------------------------------------- -bool CCollisionCache::HasResult(unsigned int uiIndex) +CCollisionTable::CCollisionTable(unsigned int uiActivatorIndex, CBaseEntity *pActivator): + m_uiActivatorIndex(uiActivatorIndex) { - return IsBitSet(uiIndex); + if (((CBaseEntityWrapper *)pActivator)->IsPlayer()) + { + static object Player = import("players.entity").attr("Player"); + m_oActivator = Player(uiActivatorIndex); + } + else + { + static object Entity = import("entities.entity").attr("Entity"); + m_oActivator = Entity(uiActivatorIndex); + } } -bool CCollisionCache::GetResult(unsigned int uiIndex) +bool CCollisionTable::__getitem__(unsigned int uiIndex) { - return m_vecCache.IsBitSet(uiIndex); + edict_t* pEdict; + if(!EdictFromIndex(uiIndex, pEdict)) + return false; + + return IsBitSet((int)uiIndex); } -void CCollisionCache::SetResult(unsigned int uiIndex, bool bResult) +bool CCollisionTable::__setitem__(unsigned int uiIndex, bool bDisable) { - Set(uiIndex); - m_vecCache.Set((int)uiIndex, bResult); + if (uiIndex == m_uiActivatorIndex) + return false; + + edict_t* pEdict; + if(!EdictFromIndex(uiIndex, pEdict)) + return false; + + Set((int)uiIndex, bDisable); + return true; } +void CCollisionTable::Disable(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); -//----------------------------------------------------------------------------- -// CCollisionHash class. -//----------------------------------------------------------------------------- -CCollisionHash::CCollisionHash() + if (uiIndex == m_uiActivatorIndex) + return; + + Set((int)uiIndex, true); +} + +void CCollisionTable::Reset(CBaseEntity *pEntity) { - m_pHash = physics->CreateObjectPairHash(); + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + Set((int)uiIndex, false); +} - if (!m_pHash) { - BOOST_RAISE_EXCEPTION( - PyExc_RuntimeError, - "Failed to create a collision hash." - ) +bool CCollisionTable::IsDisabled(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + return IsBitSet((int)uiIndex); +} + +void CCollisionTable::DisableAll() +{ + CBaseEntity *pBaseEntity = (CBaseEntity *)servertools->FirstEntity(); + while (pBaseEntity) + { + unsigned int uiIndex; + if (IndexFromBaseEntity(pBaseEntity, uiIndex) && uiIndex != m_uiActivatorIndex) + Set((int)uiIndex, true); + + pBaseEntity = (CBaseEntity *)servertools->NextEntity(pBaseEntity); } } -CCollisionHash::~CCollisionHash() +int CCollisionTable::Count() { - if (!m_pHash) { - return; + int count = 0; + for (int i = 0; i < MAX_EDICTS; ++i) + { + if (IsBitSet(i)) + ++count; } - physics->DestroyObjectPairHash(m_pHash); + return count; } -void CCollisionHash::AddPair(void *pEntity, void *pOther) +list CCollisionTable::GetDisabled() { - if (!IsValidNetworkedEntityPointer(pEntity) || !IsValidNetworkedEntityPointer(pOther)) { - BOOST_RAISE_EXCEPTION( - PyExc_ValueError, - "Given entity pointer invalid or not networked." - ) + list oEntities; + + if (IsAllClear()) + return oEntities; + + for (int i = 0; i < MAX_EDICTS; ++i) + { + CBaseEntity *pBaseEntity; + if (IsBitSet(i) && BaseEntityFromIndex((unsigned int)i, pBaseEntity)) + { + if (((CBaseEntityWrapper *)pBaseEntity)->IsPlayer()) + { + static object Player = import("players.entity").attr("Player"); + oEntities.append(Player((unsigned int)i)); + } + else + { + static object Entity = import("entities.entity").attr("Entity"); + oEntities.append(Entity((unsigned int)i)); + } + } } - m_pHash->AddObjectPair(pEntity, pOther); + return oEntities; +} + + +//----------------------------------------------------------------------------- +// CCollisionFilter class. +//----------------------------------------------------------------------------- +CCollisionFilter::CCollisionFilter() +{ + static CCollisionManager *pManager = GetCollisionManager(); + pManager->RegisterFilter(this); +} + +CCollisionFilter::~CCollisionFilter() +{ + UnloadInstance(); } -void CCollisionHash::RemovePair(void *pEntity, void *pOther) +boost::shared_ptr CCollisionFilter::GetCollisionTable(CBaseEntity *pActivator) { - m_pHash->RemoveObjectPair(pEntity, pOther); + unsigned int uiActivatorIndex = ExcIndexFromBaseEntity(pActivator); + + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiActivatorIndex); + if (it != m_mapFilter.end()) + return it->second; + + boost::shared_ptr pCollisionTable(new CCollisionTable(uiActivatorIndex, pActivator)); + m_mapFilter.insert(std::make_pair(uiActivatorIndex, pCollisionTable)); + + return pCollisionTable; } -void CCollisionHash::RemovePairs(void *pEntity) +boost::shared_ptr CCollisionFilter::GetCollisionTable(unsigned int uiActivatorIndex) { - m_pHash->RemoveAllPairsForObject(pEntity); + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiActivatorIndex); + if (it != m_mapFilter.end()) + return it->second; + + CBaseEntity *pActivator = ExcBaseEntityFromIndex(uiActivatorIndex); + + boost::shared_ptr pCollisionTable(new CCollisionTable(uiActivatorIndex, pActivator)); + m_mapFilter.insert(std::make_pair(uiActivatorIndex, pCollisionTable)); + + return pCollisionTable; } -bool CCollisionHash::Contains(void *pEntity) +void CCollisionFilter::DisableFrom(CBaseEntity *pEntity, CBaseEntity *pActivator) { - return m_pHash->IsObjectInHash(pEntity); + GetCollisionTable(pActivator)->Disable(pEntity); } -bool CCollisionHash::HasPair(void *pEntity, void *pOther) +void CCollisionFilter::ResetFrom(CBaseEntity *pEntity, CBaseEntity *pActivator) { - return m_pHash->IsObjectPairInHash(pEntity, pOther); + GetCollisionTable(pActivator)->Reset(pEntity); } -int CCollisionHash::GetCount(void *pEntity) +bool CCollisionFilter::IsDisabledFrom(CBaseEntity *pEntity, CBaseEntity *pActivator) { - return m_pHash->GetPairCountForObject(pEntity); + return GetCollisionTable(pActivator)->IsDisabled(pEntity); } -list CCollisionHash::GetPairs(void *pEntity) +void CCollisionFilter::Disable(CBaseEntity *pEntity) { + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + + CBaseEntity *pBaseEntity = (CBaseEntity *)servertools->FirstEntity(); + while (pBaseEntity) + { + unsigned int uiActivatorIndex; + if (IndexFromBaseEntity(pBaseEntity, uiActivatorIndex) && uiIndex != uiActivatorIndex) + { + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiActivatorIndex); + if (it != m_mapFilter.end()) + { + it->second->Set((int)uiIndex, true); + } + else + { + boost::shared_ptr pCollisionTable(new CCollisionTable(uiActivatorIndex, pBaseEntity)); + m_mapFilter.insert(std::make_pair(uiActivatorIndex, pCollisionTable)); + pCollisionTable->Set((int)uiIndex, true); + } + } + + pBaseEntity = (CBaseEntity *)servertools->NextEntity(pBaseEntity); + } +} + +void CCollisionFilter::Reset(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + it->second->Set((int)uiIndex, false); + } +} + +bool CCollisionFilter::IsDisabled(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + if (it->second->IsBitSet((int)uiIndex)) + return true; + } + return false; +} + +int CCollisionFilter::CountDisabled(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + + int count = 0; + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + if (it->second->IsBitSet((int)uiIndex)) + ++count; + } + return count; +} + +list CCollisionFilter::GetDisabledActivator(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ExcIndexFromBaseEntity(pEntity); + list oEntities; - int nCount = m_pHash->GetPairCountForObject(pEntity); - if (!nCount) { - return oEntities; + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + boost::shared_ptr pCollisionTable = it->second; + if (pCollisionTable->IsBitSet((int)uiIndex)) + oEntities.append(pCollisionTable->m_oActivator); } - void **ppEntities = (void **)stackalloc(nCount * sizeof(void *)); - m_pHash->GetPairListForObject(pEntity, nCount, ppEntities); + return oEntities; +} + +void CCollisionFilter::AddPair(CBaseEntity *pEntity, CBaseEntity *pOther) +{ + if (pEntity == pOther) + return; + + boost::shared_ptr pEntityTable = GetCollisionTable(pEntity); + boost::shared_ptr pOtherTable = GetCollisionTable(pOther); + + pEntityTable->Set((int)pOtherTable->m_uiActivatorIndex, true); + pOtherTable->Set((int)pEntityTable->m_uiActivatorIndex, true); +} + +void CCollisionFilter::RemovePair(CBaseEntity *pEntity, CBaseEntity *pOther) +{ + unsigned int uiEntityIndex = ExcIndexFromBaseEntity(pEntity); + unsigned int uiOtherIndex = ExcIndexFromBaseEntity(pOther); + + CollisionFilterMap_t::iterator it; + + it = m_mapFilter.find(uiEntityIndex); + if (it != m_mapFilter.end()) + it->second->Set((int)uiOtherIndex, false); + + it = m_mapFilter.find(uiOtherIndex); + if (it != m_mapFilter.end()) + it->second->Set((int)uiEntityIndex, false); +} + +bool CCollisionFilter::HasPair(CBaseEntity *pEntity, CBaseEntity *pOther) +{ + unsigned int uiEntityIndex = ExcIndexFromBaseEntity(pEntity); + unsigned int uiOtherIndex = ExcIndexFromBaseEntity(pOther); + + CollisionFilterMap_t::iterator it; + + it = m_mapFilter.find(uiEntityIndex); + if (it == m_mapFilter.end() || !it->second->IsBitSet((int)uiOtherIndex)) + return false; + + it = m_mapFilter.find(uiOtherIndex); + if (it == m_mapFilter.end() || !it->second->IsBitSet((int)uiEntityIndex)) + return false; + + return true; +} - for (int i = 0; i < nCount; ++i) { - pEntity = ppEntities[i]; - if (!pEntity) { - continue; +void CCollisionFilter::RemovePairs(CBaseEntity *pEntity) +{ + unsigned int uiEntityIndex = ExcIndexFromBaseEntity(pEntity); + + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiEntityIndex); + if (it != m_mapFilter.end()) + { + boost::shared_ptr pEntityTable = it->second; + + for (unsigned int uiOtherIndex = 0; uiOtherIndex < MAX_EDICTS; ++uiOtherIndex) { + if (pEntityTable->IsBitSet((int)uiOtherIndex)) + { + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiOtherIndex); + if (it != m_mapFilter.end()) + { + boost::shared_ptr pOtherTable = it->second; + if (pOtherTable->IsBitSet((int)uiEntityIndex)) + { + pEntityTable->Set((int)uiOtherIndex, false); + pOtherTable->Set((int)uiEntityIndex, false); + } + } + } } + } +} + +int CCollisionFilter::CountPairs(CBaseEntity *pEntity) +{ + unsigned int uiEntityIndex = ExcIndexFromBaseEntity(pEntity); - oEntities.append(pEntity); + int count = 0; + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiEntityIndex); + if (it != m_mapFilter.end()) + { + boost::shared_ptr pEntityTable = it->second; + + for (unsigned int uiOtherIndex = 0; uiOtherIndex < MAX_EDICTS; ++uiOtherIndex) { + if (pEntityTable->IsBitSet((int)uiOtherIndex)) + { + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiOtherIndex); + if (it != m_mapFilter.end() && it->second->IsBitSet((int)uiEntityIndex)) + ++count; + } + } + } + + return count; +} + +list CCollisionFilter::GetPairs(CBaseEntity *pEntity) +{ + unsigned int uiEntityIndex = ExcIndexFromBaseEntity(pEntity); + + list oEntities; + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiEntityIndex); + if (it != m_mapFilter.end()) + { + boost::shared_ptr pEntityTable = it->second; + + for (unsigned int uiOtherIndex = 0; uiOtherIndex < MAX_EDICTS; ++uiOtherIndex) { + if (pEntityTable->IsBitSet((int)uiOtherIndex)) + { + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiOtherIndex); + if (it != m_mapFilter.end()) + { + boost::shared_ptr pOtherTable = it->second; + if (pOtherTable->IsBitSet((int)uiEntityIndex)) + { + oEntities.append(pOtherTable->m_oActivator); + } + } + } + } } return oEntities; } +void CCollisionFilter::Clear() +{ + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + it->second->ClearAll(); + } +} + +inline bool CCollisionFilter::IsSet(unsigned int uiActivatorIndex, unsigned int uiOtherIndex) +{ + CollisionFilterMap_t::iterator it = m_mapFilter.find(uiActivatorIndex); + if (it != m_mapFilter.end() && it->second->IsBitSet((int)uiOtherIndex)) + return true; + + return false; +} + +inline void CCollisionFilter::Erase(CBaseEntity *pEntity) +{ + unsigned int uiIndex = ((CBaseEntityWrapper *)pEntity)->GetIndex(); + m_mapFilter.erase(uiIndex); + + for (CollisionFilterMap_t::iterator it = m_mapFilter.begin(); it != m_mapFilter.end(); ++it) + { + it->second->Set((int)uiIndex, false); + } +} + +void CCollisionFilter::UnloadInstance() +{ + static CCollisionManager *pManager = GetCollisionManager(); + pManager->UnregisterFilter(this); +} + //----------------------------------------------------------------------------- // CCollisionListenerManager class. diff --git a/src/core/modules/entities/entities_collisions.h b/src/core/modules/entities/entities_collisions.h old mode 100644 new mode 100755 index 4b0bf0eeb..de1f9a4e5 --- a/src/core/modules/entities/entities_collisions.h +++ b/src/core/modules/entities/entities_collisions.h @@ -34,7 +34,6 @@ #include "sp_main.h" #include "modules/listeners/listeners_manager.h" #include "modules/entities/entities_entity.h" -#include "modules/physics/physics.h" #include "modules/memory/memory_hooks.h" // Boost @@ -42,7 +41,6 @@ #include "boost/unordered_set.hpp" // SDK -#include "vphysics/object_hash.h" #include "bitvec.h" @@ -50,6 +48,7 @@ // Forward declarations. //----------------------------------------------------------------------------- struct CollisionHookData_t; +class CCollisionTable; class CCollisionCache; @@ -62,6 +61,9 @@ class CCollisionCache; typedef boost::unordered_map CollisionHooksMap_t; +typedef CBitVec CollisionTable_t; +typedef boost::unordered_map> CollisionFilterMap_t; + typedef CBitVec CollisionCache_t; typedef boost::unordered_map CollisionCacheMap_t; @@ -105,49 +107,70 @@ struct CollisionHookData_t //----------------------------------------------------------------------------- -// ICollisionHash class. +// CCollisionTable class. //----------------------------------------------------------------------------- -class ICollisionHash +class CCollisionTable : public CollisionTable_t { public: - ICollisionHash(); - virtual ~ICollisionHash(); + CCollisionTable(unsigned int uiActivatorIndex, CBaseEntity *pActivator); - virtual void AddPair(void *pEntity, void *pOther) = 0; - virtual void RemovePair(void *pEntity, void *pOther) = 0; - virtual void RemovePairs(void *pEntity) = 0; + bool __getitem__(unsigned int uiIndex); + bool __setitem__(unsigned int uiIndex, bool bDisable); - virtual bool Contains(void *pEntity) = 0; - virtual bool HasPair(void *pEntity, void *pOther) = 0; + void Disable(CBaseEntity *pEntity); + void Reset(CBaseEntity *pEntity); + bool IsDisabled(CBaseEntity *pEntity); - virtual int GetCount(void *pEntity) = 0; - virtual list GetPairs(void *pEntity) = 0; + void DisableAll(); - void UnloadInstance(); + int Count(); + list GetDisabled(); + + unsigned int m_uiActivatorIndex; + object m_oActivator; }; //----------------------------------------------------------------------------- -// CCollisionHash class. +// CCollisionFilter class. //----------------------------------------------------------------------------- -class CCollisionHash : public ICollisionHash +class CCollisionFilter { public: - CCollisionHash(); - ~CCollisionHash(); + CCollisionFilter(); + ~CCollisionFilter(); + + boost::shared_ptr GetCollisionTable(CBaseEntity *pActivator); + boost::shared_ptr GetCollisionTable(unsigned int uiActivatorIndex); + + void DisableFrom(CBaseEntity *pEntity, CBaseEntity *pActivator); + void ResetFrom(CBaseEntity *pEntity, CBaseEntity *pActivator); + bool IsDisabledFrom(CBaseEntity *pEntity, CBaseEntity *pActivator); - void AddPair(void *pEntity, void *pOther); - void RemovePair(void *pEntity, void *pOther); - void RemovePairs(void *pEntity); + void Disable(CBaseEntity *pEntity); + void Reset(CBaseEntity *pEntity); + bool IsDisabled(CBaseEntity *pEntity); - bool Contains(void *pEntity); - bool HasPair(void *pEntity, void *pOther); + int CountDisabled(CBaseEntity *pEntity); + list GetDisabledActivator(CBaseEntity *pEntity); - int GetCount(void *pEntity); - list GetPairs(void *pEntity); + void AddPair(CBaseEntity *pEntity, CBaseEntity *pOther); + void RemovePair(CBaseEntity *pEntity, CBaseEntity *pOther); + bool HasPair(CBaseEntity *pEntity, CBaseEntity *pOther); + + void RemovePairs(CBaseEntity *pEntity); + int CountPairs(CBaseEntity *pEntity); + list GetPairs(CBaseEntity *pEntity); + + void Clear(); + + bool IsSet(unsigned int uiActivatorIndex, unsigned int uiOtherIndex); + void Erase(CBaseEntity *pEntity); + + void UnloadInstance(); private: - IPhysicsObjectPairHash *m_pHash; + CollisionFilterMap_t m_mapFilter; }; @@ -183,8 +206,8 @@ class CCollisionManager void Initialize(); void Finalize(); - void RegisterHash(ICollisionHash *pHash); - void UnregisterHash(ICollisionHash *pHash); + void RegisterFilter(CCollisionFilter *pFilter); + void UnregisterFilter(CCollisionFilter *pFilter); void OnNetworkedEntityCreated(object oEntity); void OnNetworkedEntityDeleted(CBaseEntity *pEntity); @@ -212,7 +235,7 @@ class CCollisionManager private: bool m_bInitialized; unsigned int m_uiRefCount; - CUtlVector m_vecHashes; + CUtlVector m_vecFilteres; CollisionHooksMap_t m_mapHooks; std::vector m_vecScopes; diff --git a/src/core/modules/entities/entities_collisions_wrap.cpp b/src/core/modules/entities/entities_collisions_wrap.cpp old mode 100644 new mode 100755 index dee2ff995..288e04c95 --- a/src/core/modules/entities/entities_collisions_wrap.cpp +++ b/src/core/modules/entities/entities_collisions_wrap.cpp @@ -36,8 +36,8 @@ // Forward declarations. //----------------------------------------------------------------------------- static void export_collision_manager(scope); -static void export_base_collision_hash(scope); -static void export_collision_hash(scope); +static void export_collision_table(scope); +static void export_collision_filter(scope); //----------------------------------------------------------------------------- @@ -46,13 +46,13 @@ static void export_collision_hash(scope); DECLARE_SP_SUBMODULE(_entities, _collisions) { export_collision_manager(_collisions); - export_base_collision_hash(_collisions); - export_collision_hash(_collisions); + export_collision_table(_collisions); + export_collision_filter(_collisions); } //----------------------------------------------------------------------------- -// Exports ICollisionHash. +// Exports CCollisionManager. //----------------------------------------------------------------------------- void export_collision_manager(scope _collisions) { @@ -84,69 +84,197 @@ void export_collision_manager(scope _collisions) //----------------------------------------------------------------------------- -// Exports ICollisionHash. +// Exports CCollisionTable. //----------------------------------------------------------------------------- -void export_base_collision_hash(scope _collisions) +void export_collision_table(scope _collisions) { - class_ BaseCollisionHash("BaseCollisionHash", no_init); + class_, boost::noncopyable> CollisionTable("CollisionTable", no_init); // Methods... - BaseCollisionHash.def( + CollisionTable.def( + "disable", + &CCollisionTable::Disable, + "Disables collision with the given entity." + ); + + CollisionTable.def( + "reset", + &CCollisionTable::Reset, + "Resets collision with the given entity." + ); + + CollisionTable.def( + "is_disabled", + &CCollisionTable::IsDisabled, + "Returns whether collision with the given entity is disabled." + ); + + CollisionTable.def( + "disable_all", + &CCollisionTable::DisableAll, + "Disables collision with all entities." + ); + + CollisionTable.def( + "clear", + &CCollisionTable::ClearAll, + "Resets collision with all entities." + ); + + CollisionTable.def( + "get_disabled", + &CCollisionTable::GetDisabled, + "Returns a list of entities with collision disabled." + ); + + CollisionTable.add_property( + "count", + &CCollisionTable::Count, + "Returns the amount of entities with collision disabled." + ); + + CollisionTable.def_readonly( + "activator", + &CCollisionTable::m_oActivator, + "Returns the activator entity that will disable collision." + ); + + // Special methods... + CollisionTable.def( + "__getitem__", + &CCollisionTable::__getitem__, + "Returns whether collision is disabled by an entity index." + ); + + CollisionTable.def( + "__setitem__", + &CCollisionTable::__setitem__, + "Set collision by entity index." + ); + + CollisionTable.def( + "__contains__", + &CCollisionTable::IsDisabled, + "Returns whether collision with the given entity is disabled." + ); +} + + +//----------------------------------------------------------------------------- +// Exports CCollisionFilter. +//----------------------------------------------------------------------------- +void export_collision_filter(scope _collisions) +{ + class_ CollisionFilter("CollisionFilter"); + + // Methods... + CollisionFilter.def( + "get_collision_table", + GET_METHOD(boost::shared_ptr, CCollisionFilter, GetCollisionTable, CBaseEntity *), + "Returns the CollisionTable for the given activator entity." + ); + + CollisionFilter.def( + "disable_from", + &CCollisionFilter::DisableFrom, + "Disables collision of the given entity from the activator entity." + ); + + CollisionFilter.def( + "reset_from", + &CCollisionFilter::ResetFrom, + "Resets collision of the given entity from the activator entity." + ); + + CollisionFilter.def( + "is_disabled_from", + &CCollisionFilter::IsDisabledFrom, + "Returns whether collision of the given entity is disabled from the activator entity." + ); + + CollisionFilter.def( + "disable", + &CCollisionFilter::Disable, + "Disables collision of the given entity in all activator entities." + ); + + CollisionFilter.def( + "reset", + &CCollisionFilter::Reset, + "Resets collision of the given entity in all activator entities." + ); + + CollisionFilter.def( + "is_disabled", + &CCollisionFilter::IsDisabled, + "Returns whether collision of the given entity has been disabled for any activator entity." + ); + + CollisionFilter.def( + "get_disabled_activator", + &CCollisionFilter::GetDisabledActivator, + "Returns a list of activator entities with collision disabled for the given entity." + ); + + CollisionFilter.def( "add_pair", - &ICollisionHash::AddPair, - "Adds the given entity pair to the hash." + &CCollisionFilter::AddPair, + "Adds the given entity pair to the filter." ); - BaseCollisionHash.def( + CollisionFilter.def( "remove_pair", - &ICollisionHash::RemovePair, - "Removes the given pair from the hash." + &CCollisionFilter::RemovePair, + "Removes the given pair from the filter." ); - BaseCollisionHash.def( - "remove_pairs", - &ICollisionHash::RemovePairs, - "Removes all pairs associated with the given entity." + CollisionFilter.def( + "has_pair", + &CCollisionFilter::HasPair, + "Returns whether the given pair is in the filter." ); - BaseCollisionHash.def( - "has_pair", - &ICollisionHash::HasPair, - "Returns whether the given pair is in the hash." + CollisionFilter.def( + "remove_pairs", + &CCollisionFilter::RemovePairs, + "Removes all pairs associated with the given entity." ); - BaseCollisionHash.def( - "get_count", - &ICollisionHash::GetCount, + CollisionFilter.def( + "count_pairs", + &CCollisionFilter::CountPairs, "Returns the amount of pairs associated with the given entity." ); - BaseCollisionHash.def( + CollisionFilter.def( "get_pairs", - &ICollisionHash::GetPairs, + &CCollisionFilter::GetPairs, "Returns a list of all entities associated with the given entity." ); + CollisionFilter.def( + "clear", + &CCollisionFilter::Clear, + "Resets collision across all entities in all activator entities." + ); + // Special methods... - BaseCollisionHash.def( + CollisionFilter.def( + "__getitem__", + GET_METHOD(boost::shared_ptr, CCollisionFilter, GetCollisionTable, unsigned int), + "Returns the CollisionTable for the given activator entity index." + ); + + CollisionFilter.def( "__contains__", - &ICollisionHash::Contains, - "Returns whether the given entity is in the hash." + &CCollisionFilter::IsDisabled, + "Returns whether collision of the given entity has been disabled for any activator entity." ); // AutoUnload... - BaseCollisionHash.def( + CollisionFilter.def( "_unload_instance", - &ICollisionHash::UnloadInstance, + &CCollisionFilter::UnloadInstance, "Called when an instance is being unloaded." ); } - - -//----------------------------------------------------------------------------- -// Exports CCollisionHash. -//----------------------------------------------------------------------------- -void export_collision_hash(scope _collisions) -{ - class_ >("CollisionHash"); -}