Skip to content

Adds entity collisions functionalities. #443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from

Conversation

jordanbriere
Copy link
Contributor

@jordanbriere jordanbriere commented Dec 3, 2021

from listeners import OnPlayerCollision

@OnPlayerCollision
def on_player_collision(player, entity):
    """Called when a player is about to collide with an entity."""
    # Disable teammates collisions
    if not entity.is_player():
        return
    return player.team_index != entity.team_index
from listeners import OnEntityCollision

@OnEntityCollision
def on_entity_collision(entity, other):
    """Called when a non-player entity is about to collide with another entity."""
    # Disable weapons/projectiles collisions with everything except players
    return not (entity.is_weapon() and not other.is_player())
from entities.collisions import CollisionHash
from events import Event
from players.entity import Player

h = CollisionHash()

@Event('player_say')
def player_say(game_event):
    player = Player.from_userid(game_event['userid'])
    entity = player.view_entity
    if entity is None:
        return
    # Toggle collisions with aimed entity
    if h.has_pair(player, entity):
        h.remove_pair(player, entity)
    else:
        h.add_pair(player, entity)
from entities.collisions import CollisionSet
from events import Event
from players.entity import Player

s = CollisionSet()

@Event('player_say')
def player_say(game_event):
    player = Player.from_userid(game_event['userid'])
    # Toggle collisions with everything
    if player in s:
        s.remove(player)
    else:
        s.add(player)
from entities.collisions import CollisionMap
from events import Event
from players.entity import Player

m = CollisionMap()

@Event('player_say')
def player_say(game_event):
    player = Player.from_userid(game_event['userid'])
    entity = player.view_entity
    if entity is None:
        return
    # Toggle one-way collisions with aimed entity
    s = m[player]
    if entity in s:
        s.remove(entity)
    else:
        s.add(entity)
from entities.collisions import CollisionMap
from entities.collisions import CollisionMode
from events import Event
from players.entity import Player

# Setting the collision mode to ALLOW rather than PREVENT will negate the rules.
m = CollisionMap(CollisionMode.ALLOW)

@Event('player_say')
def player_say(game_event):
    player = Player.from_userid(game_event['userid'])
    entity = player.view_entity
    if entity is None:
        return
    s = m[player]
    if entity in s:
        s.remove(entity.index)
    else:
        # Player will now collide with nothing except this entity
        s.add(entity)
from engines.trace import ContentFlags
from entities.collisions import CollisionHook

@CollisionHook
def collision_hook(entity, other, trace_filter, mask):
    """Called whenever two entities are tested for colliding contents."""
    # Prevent hostages from being killed by bullets
    if not mask & ContentFlags.HITBOX:
        return
    return other.classname != 'hostage_entity'

@jordanbriere jordanbriere linked an issue Dec 3, 2021 that may be closed by this pull request
@jordanbriere
Copy link
Contributor Author

jordanbriere commented Dec 3, 2021

Just to clarify; if CCollisionManager::ShouldHitEntity is called, then that means the game allows the collision. If a CollisionHook (that is always called, regardless of the cache) prevent the collision then the cache for the current tick is updated. If the original m_pExtraShouldHitCheckFunction function prevents the collision, regardless of the cache, the cache is not updated and this decision takes precedence over any CollisionHash/OnEntityCollision/OnPlayerCollision callbacks. Basically, the cache is only used to limit CollisionHash lookups, as well as python calls to the listeners, and should not affect anything else beside being a major improvement because the game usually does one trace, then a dozen leaves/sweeps checks on the same test and this is what we no longer have to process.

@jordanbriere jordanbriere requested a review from Ayuto December 5, 2021 11:59
Some minors fixes to make potential physics support easier.
@CookStar
Copy link
Contributor

CookStar commented Dec 8, 2021

I'll leave this for the record and warning, CollisionHash will cause a crash if you add more than 256 entity combinations.

You should STOP using EntityIter or similar methods to add entities to CollisionHash.

See the comments for more details.
#444 (comment)
#444 (comment)

Various fixes and improvements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants