Skip to content

Commit 62730cf

Browse files
committed
Added OnPlayerCollision.
1 parent 702d9ac commit 62730cf

File tree

5 files changed

+122
-22
lines changed

5 files changed

+122
-22
lines changed

addons/source-python/docs/source-python/source/developing/module_tutorials/listeners.rst

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ Called when a networked entity has been spawned.
327327
OnEntityCollision
328328
-----------------
329329

330-
Called when an entity is about to collide with another.
330+
Called when a non-player entity is about to collide with another entity.
331331

332332
.. note:: This listener can be extremely noisy. Use :class:`entities.collisions.CollisionHash` if you don't have dynamic conditions to test for.
333333

@@ -337,8 +337,8 @@ Called when an entity is about to collide with another.
337337
338338
@OnEntityCollision
339339
def on_entity_collision(entity, other):
340-
# Disable teammates collisions
341-
return entity.team_index != other.team_index
340+
# Disable weapons/projectiles collisions with everything except players
341+
return not (entity.is_weapon() and not other.is_player())
342342
343343
344344
OnLevelInit
@@ -423,6 +423,25 @@ Called when the button state of a player changed.
423423
button or button combination has been pressed or released.
424424

425425

426+
OnPlayerCollision
427+
-----------------
428+
429+
Called when a player is about to collide with an entity.
430+
431+
.. note:: This listener can be extremely noisy. Use :class:`entities.collisions.CollisionHash` if you don't have dynamic conditions to test for.
432+
433+
.. code-block:: python
434+
435+
from listeners import OnPlayerCollision
436+
437+
@OnPlayerCollision
438+
def on_player_collision(player, entity):
439+
# Disable teammates collisions
440+
if not entity.is_player():
441+
return
442+
return player.team_index != entity.team_index
443+
444+
426445
OnPlayerRunCommand
427446
--------------------
428447

addons/source-python/packages/source-python/listeners/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
from _listeners import on_server_activate_listener_manager
7474
from _listeners import on_tick_listener_manager
7575
from _listeners import on_server_output_listener_manager
76+
from _listeners import on_player_collision_listener_manager
7677
from _listeners import on_player_run_command_listener_manager
7778
from _listeners import on_button_state_changed_listener_manager
7879

@@ -111,6 +112,7 @@
111112
'OnLevelEnd',
112113
'OnNetworkidValidated',
113114
'OnButtonStateChanged',
115+
'OnPlayerCollision',
114116
'OnPlayerRunCommand',
115117
'OnPluginLoaded',
116118
'OnPluginLoading',
@@ -157,6 +159,7 @@
157159
'on_tick_listener_manager',
158160
'on_version_update_listener_manager',
159161
'on_server_output_listener_manager',
162+
'on_player_collision_listener_manager',
160163
'on_player_run_command_listener_manager',
161164
'on_button_state_changed_listener_manager',
162165
)
@@ -498,6 +501,12 @@ class OnLevelEnd(ListenerManagerDecorator):
498501
_level_initialized = False
499502

500503

504+
class OnPlayerCollision(ListenerManagerDecorator):
505+
"""Register/unregister a OnPlayerCollision listener."""
506+
507+
manager = on_player_collision_listener_manager
508+
509+
501510
class OnPlayerRunCommand(ListenerManagerDecorator):
502511
"""Register/unregister a run command listener."""
503512

src/core/modules/entities/entities_collisions.cpp

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ bool CCollisionManager::EnterScope(HookType_t eHookType, CHook *pHook)
301301
scope.m_nMask = nMask;
302302
scope.m_bSolidContents = bSolidContents;
303303
scope.m_uiIndex = uiIndex;
304+
scope.m_bIsPlayer = ((CBaseEntityWrapper *)pWrapper->m_pPassEnt)->IsPlayer();
304305
scope.m_pCache = pManager->GetCache(uiIndex);
305306
scope.m_pExtraShouldHitCheckFunction = pWrapper->m_pExtraShouldHitCheckFunction;
306307
pWrapper->m_pExtraShouldHitCheckFunction = (ShouldHitFunc_t)CCollisionManager::ShouldHitEntity;
@@ -400,8 +401,31 @@ bool CCollisionManager::ShouldHitEntity(IHandleEntity *pHandleEntity, int conten
400401
}
401402
}
402403

403-
static CEntityCollisionListenerManager *pListener = GetOnEntityCollisionListenerManager();
404-
if (!pListener->GetCount()) {
404+
if (scope.m_bIsPlayer) {
405+
static CPlayerCollisionListenerManager *OnPlayerCollision = GetOnPlayerCollisionListenerManager();
406+
if (!OnPlayerCollision->GetCount()) {
407+
scope.m_pCache->SetResult(uiIndex, true);
408+
return true;
409+
}
410+
411+
static object Player = import("players.entity").attr("Player");
412+
object oPlayer = Player(scope.m_uiIndex);
413+
414+
if (oOther.is_none()) {
415+
oOther = Entity(uiIndex);
416+
}
417+
418+
if (!OnPlayerCollision->CallCallbacks(oPlayer, oOther)) {
419+
scope.m_pCache->SetResult(uiIndex, false);
420+
return false;
421+
}
422+
423+
scope.m_pCache->SetResult(uiIndex, true);
424+
return true;
425+
}
426+
427+
static CEntityCollisionListenerManager *OnEntityCollision = GetOnEntityCollisionListenerManager();
428+
if (!OnEntityCollision->GetCount()) {
405429
scope.m_pCache->SetResult(uiIndex, true);
406430
return true;
407431
}
@@ -414,14 +438,9 @@ bool CCollisionManager::ShouldHitEntity(IHandleEntity *pHandleEntity, int conten
414438
oOther = Entity(uiIndex);
415439
}
416440

417-
FOR_EACH_VEC(pListener->m_vecCallables, i) {
418-
BEGIN_BOOST_PY()
419-
object oResult = pListener->m_vecCallables[i](oEntity, oOther);
420-
if (!oResult.is_none() && !extract<bool>(oResult)) {
421-
scope.m_pCache->SetResult(uiIndex, false);
422-
return false;
423-
}
424-
END_BOOST_PY_NORET()
441+
if (!OnEntityCollision->CallCallbacks(oEntity, oOther)) {
442+
scope.m_pCache->SetResult(uiIndex, false);
443+
return false;
425444
}
426445

427446
scope.m_pCache->SetResult(uiIndex, true);
@@ -579,15 +598,15 @@ list CCollisionHash::GetPairs(void *pEntity)
579598

580599

581600
//-----------------------------------------------------------------------------
582-
// CEntityCollisionListenerManager class.
601+
// CCollisionListenerManager class.
583602
//-----------------------------------------------------------------------------
584-
CEntityCollisionListenerManager::CEntityCollisionListenerManager():
603+
CCollisionListenerManager::CCollisionListenerManager():
585604
m_bInitialized(false)
586605
{
587606

588607
}
589608

590-
void CEntityCollisionListenerManager::Initialize()
609+
void CCollisionListenerManager::Initialize()
591610
{
592611
if (m_bInitialized) {
593612
return;
@@ -597,7 +616,7 @@ void CEntityCollisionListenerManager::Initialize()
597616
m_bInitialized = true;
598617
}
599618

600-
void CEntityCollisionListenerManager::Finalize()
619+
void CCollisionListenerManager::Finalize()
601620
{
602621
if (!m_bInitialized) {
603622
return;
@@ -607,9 +626,36 @@ void CEntityCollisionListenerManager::Finalize()
607626
m_bInitialized = false;
608627
}
609628

610-
// Singleton accessor.
629+
bool CCollisionListenerManager::CallCallbacks(object oEntity, object oOther)
630+
{
631+
FOR_EACH_VEC(m_vecCallables, i) {
632+
BEGIN_BOOST_PY()
633+
object oResult = m_vecCallables[i](oEntity, oOther);
634+
if (!oResult.is_none() && !extract<bool>(oResult)) {
635+
return false;
636+
}
637+
END_BOOST_PY_NORET()
638+
}
639+
640+
return true;
641+
}
642+
643+
644+
//-----------------------------------------------------------------------------
645+
// CEntityCollisionListenerManager singleton accessor.
646+
//-----------------------------------------------------------------------------
611647
static CEntityCollisionListenerManager s_OnEntityCollision;
612648
CEntityCollisionListenerManager *GetOnEntityCollisionListenerManager()
613649
{
614650
return &s_OnEntityCollision;
615651
}
652+
653+
654+
//-----------------------------------------------------------------------------
655+
// CPlayerCollisionListenerManager singleton accessor.
656+
//-----------------------------------------------------------------------------
657+
static CPlayerCollisionListenerManager s_OnPlayerCollision;
658+
CPlayerCollisionListenerManager *GetOnPlayerCollisionListenerManager()
659+
{
660+
return &s_OnPlayerCollision;
661+
}

src/core/modules/entities/entities_collisions.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
// Source.Python
3434
#include "sp_main.h"
3535
#include "modules/listeners/listeners_manager.h"
36+
#include "modules/entities/entities_entity.h"
3637
#include "modules/physics/physics.h"
3738
#include "modules/memory/memory_hooks.h"
3839

@@ -84,6 +85,7 @@ struct CollisionScope_t
8485
{
8586
bool m_bSkip;
8687
unsigned int m_uiIndex;
88+
bool m_bIsPlayer;
8789
CTraceFilterSimpleWrapper *m_pFilter;
8890
ShouldHitFunc_t m_pExtraShouldHitCheckFunction;
8991
CCollisionCache *m_pCache;
@@ -171,7 +173,7 @@ class CCollisionManager
171173
{
172174
public:
173175
friend CCollisionManager *GetCollisionManager();
174-
friend class CEntityCollisionListenerManager;
176+
friend class CCollisionListenerManager;
175177

176178
private:
177179
CCollisionManager();
@@ -228,22 +230,45 @@ inline CCollisionManager *GetCollisionManager()
228230

229231

230232
//-----------------------------------------------------------------------------
231-
// CEntityCollisionListenerManager class.
233+
// CCollisionListenerManager class.
232234
//-----------------------------------------------------------------------------
233-
class CEntityCollisionListenerManager: public CListenerManager
235+
class CCollisionListenerManager : public CListenerManager
234236
{
235237
public:
236-
CEntityCollisionListenerManager();
238+
CCollisionListenerManager();
237239

238240
void Initialize();
239241
void Finalize();
240242

243+
bool CallCallbacks(object oEntity, object oOther);
244+
241245
private:
242246
bool m_bInitialized;
243247
};
244248

249+
250+
//-----------------------------------------------------------------------------
251+
// CEntityCollisionListenerManager class.
252+
//-----------------------------------------------------------------------------
253+
class CEntityCollisionListenerManager: public CCollisionListenerManager
254+
{
255+
256+
};
257+
245258
// Singleton accessor.
246259
CEntityCollisionListenerManager *GetOnEntityCollisionListenerManager();
247260

248261

262+
//-----------------------------------------------------------------------------
263+
// CPlayerCollisionListenerManager class.
264+
//-----------------------------------------------------------------------------
265+
class CPlayerCollisionListenerManager: public CCollisionListenerManager
266+
{
267+
268+
};
269+
270+
// Singleton accessor.
271+
CPlayerCollisionListenerManager *GetOnPlayerCollisionListenerManager();
272+
273+
249274
#endif // _ENTITIES_COLLISIONS_H

src/core/modules/listeners/listeners_wrap.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ void export_listener_managers(scope _listeners)
174174
_listeners.attr("on_entity_deleted_listener_manager") = object(ptr(GetOnEntityDeletedListenerManager()));
175175
_listeners.attr("on_networked_entity_deleted_listener_manager") = object(ptr(GetOnNetworkedEntityDeletedListenerManager()));
176176
_listeners.attr("on_entity_collision_listener_manager") = object(ptr((CListenerManager *)GetOnEntityCollisionListenerManager()));
177+
_listeners.attr("on_player_collision_listener_manager") = object(ptr((CListenerManager *)GetOnPlayerCollisionListenerManager()));
177178

178179
_listeners.attr("on_data_loaded_listener_manager") = object(ptr(GetOnDataLoadedListenerManager()));
179180
_listeners.attr("on_combiner_pre_cache_listener_manager") = object(ptr(GetOnCombinerPreCacheListenerManager()));

0 commit comments

Comments
 (0)