Check if Entity exists

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
velocity
Senior Member
Posts: 220
Joined: Sat May 10, 2014 6:17 pm

Check if Entity exists

Postby velocity » Sat Oct 22, 2016 3:37 pm

How would I check if an entity exists?


Let's say I initialize one Entity(index), how do I check if its still a valid index or if it even exists?

Syntax: Select all

from listeners.tick import Delay 

ENTITY_TARGET = "flashbang_projectile"

@OnEntityCreated
def on_entity_created(index, ptr):
entity = Entity(index)
if not entity.classname == ENTITY_TARGET:
return
Delay(1.2, entity_kill, entity)

def entity_kill(entity)
# if not entity == INVALID_ENTITY?
entity.remove()
User avatar
D3CEPTION
Senior Member
Posts: 129
Joined: Tue Jan 26, 2016 1:24 pm
Location: Switzerland

Re: Check if Entity exists

Postby D3CEPTION » Sat Oct 22, 2016 3:53 pm

Code: Select all

if entity
?
User avatar
Kill
Member
Posts: 88
Joined: Wed Aug 31, 2016 10:05 pm

Re: Check if Entity exists

Postby Kill » Sat Oct 22, 2016 3:56 pm

Maybe try to retrieve the entity Index, If it exists then continue?
User avatar
L'In20Cible
Project Leader
Posts: 1534
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Check if Entity exists

Postby L'In20Cible » Sat Oct 22, 2016 3:59 pm

Like I explained here about delaying spawn, same concept apply for delaying deletion.

L'In20Cible wrote:

  • Instead of having a function that call the spawn method on the passed player, you could simply delay that method to be called:

    Syntax: Select all

    Delay(cvars['autorespawn_delay'].get_int(), player.spawn)

    However, I would not recommend delaying any Player/Entity's method calls and/or passing them as argument. If the player leave the server/entity get removed before the call is made, you gonna either crash or your code will raise an error. In this specific case, I would rather recommend passing the index and recast the Player instance:

    Syntax: Select all

    # Into player_death...
    Delay(cvars['autorespawn_delay'].get_int(), respawn_player, player.index)

    def respawn_player(index):
    try:
    player = Player(index)
    except ValueError:
    # Player left the server, nothing to do here...
    return
    player.spawn()


    Another thing you should consider, is to store the Delay instances and cancel them on new round/map.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Check if Entity exists

Postby iPlayer » Sat Oct 22, 2016 4:04 pm

I'd pass the index to entity_kill. And then except ValueError, OverflowError when creating an Entity.

Operating with already deleted entity may crash the server.

Or, register OnEntityDeleted listener to cancel your delay for the specified entity.


Edit: too late...
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
satoon101
Project Leader
Posts: 2698
Joined: Sat Jul 07, 2012 1:59 am

Re: Check if Entity exists

Postby satoon101 » Sat Oct 22, 2016 4:09 pm

I would recommend this:
iPlayer wrote:Or, register OnEntityDeleted listener to cancel your delay for the specified entity.


It is 'possible' that during your delay, the entity is removed by other means. Not only that, but it is also 'possible' that after the entity was removed, another entity was created on the server and took the old entity's index. This means that if all you do is check that the entity index is valid, you could actually be removing the wrong entity.
Image
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Check if Entity exists

Postby decompile » Sat Oct 22, 2016 4:25 pm

satoon101 wrote:I would recommend this:
iPlayer wrote:Or, register OnEntityDeleted listener to cancel your delay for the specified entity.


It is 'possible' that during your delay, the entity is removed by other means. Not only that, but it is also 'possible' that after the entity was removed, another entity was created on the server and took the old entity's index. This means that if all you do is check that the entity index is valid, you could actually be removing the wrong entity.


Wait what?

Arent indexes & userids unique?

Thats the first time I heard that, good to know then.
User avatar
Ayuto
Project Leader
Posts: 2195
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Check if Entity exists

Postby Ayuto » Sat Oct 22, 2016 4:25 pm

Cancelling the delay is probably the best choice. However, you could also use something like this.

Syntax: Select all

from listeners.tick import Delay
from entities.entity import BaseEntity

ENTITY_TARGET = "flashbang_projectile"

@OnEntityCreated
def on_entity_created(entity):
if not entity.classname == ENTITY_TARGET:
return

Delay(1.2, entity_kill, entity.basehandle)

def entity_kill(handle):
if not handle.is_valid():
return

BaseEntity(handle.entry_index).remove()


decompile wrote:Arent indexes & userids unique?

Userids are unique, but indexes aren't.
User avatar
L'In20Cible
Project Leader
Posts: 1534
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Check if Entity exists

Postby L'In20Cible » Sat Oct 22, 2016 4:39 pm

For convenience, we could add an Entity.delay method that wrap the Delay class and internally cancel on entity deletion.
User avatar
velocity
Senior Member
Posts: 220
Joined: Sat May 10, 2014 6:17 pm

Re: Check if Entity exists

Postby velocity » Sat Oct 22, 2016 11:36 pm

L'In20Cible wrote:For convenience, we could add an Entity.delay method that wrap the Delay class and internally cancel on entity deletion.

That would be cool
User avatar
L'In20Cible
Project Leader
Posts: 1534
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Check if Entity exists

Postby L'In20Cible » Sun Oct 23, 2016 1:29 am

https://github.com/Source-Python-Dev-Te ... 93a29f64b3

Syntax: Select all

entity.delay(1.2, entity.remove)
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Check if Entity exists

Postby iPlayer » Sun Oct 23, 2016 6:33 am

Does that work with disconnecting clients? E.g. can't there be a case when a player has already disconnected, but their entity has yet to be removed or something? Other words, can I safely do this:

Syntax: Select all

player.delay(5.0, player.spawn)

? (omitting the "respawning a respawned player" issue)

Also, one thing I've noticed in your commits. You have only used cancel_on_level_end flag in your commit to tick_update branch, and in the master branch such flag will implicitly go to kwargs dictionary.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
L'In20Cible
Project Leader
Posts: 1534
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Check if Entity exists

Postby L'In20Cible » Sun Oct 23, 2016 6:40 am

iPlayer wrote:Does that work with disconnecting clients? E.g. can't there be a case when a player has already disconnected, but their entity has yet to be removed or something? Other words, can I safely do this:

Syntax: Select all

player.delay(5.0, player.spawn)

? (omitting the "respawning a respawned player" issue)

You can safely do that, yes.

iPlayer wrote:Also, one thing I've noticed in your commits. You have only used cancel_on_level_end flag in your commit to tick_update branch, and in the master branch such flag will implicitly go to kwargs dictionary.

Master doesn't have this flag yet: https://github.com/Source-Python-Dev-Te ... ck.py#L111
User avatar
velocity
Senior Member
Posts: 220
Joined: Sat May 10, 2014 6:17 pm

Re: Check if Entity exists

Postby velocity » Sat Oct 29, 2016 12:43 pm

Ayuto wrote:Cancelling the delay is probably the best choice. However, you could also use something like this.

Syntax: Select all

from listeners.tick import Delay
from entities.entity import BaseEntity

ENTITY_TARGET = "flashbang_projectile"

@OnEntityCreated
def on_entity_created(entity):
if not entity.classname == ENTITY_TARGET:
return

Delay(1.2, entity_kill, entity.basehandle)

def entity_kill(handle):
if not handle.is_valid():
return

BaseEntity(handle.entry_index).remove()


decompile wrote:Arent indexes & userids unique?

Userids are unique, but indexes aren't.




What's the difference between BaseEnttiy and Entity in the import
User avatar
L'In20Cible
Project Leader
Posts: 1534
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Check if Entity exists

Postby L'In20Cible » Sat Oct 29, 2016 1:01 pm

BaseEntity is a wrapper around CBaseEntity that get exported from the c++ side while Entity is an extension class that inherit from it and extend it adding some functionalities. A BaseEntity instance can either be a server-side entity (perform various task on the server but never sent to clients) or a networkable entity that get transmitted to clients every game frame. On the other hand, an Entity instance can only be networked as it accepts an index (that index is in reality only the "slot" of the entity in the networkable array) to get initialized. In that specific case, there is no point to get an Entity instance as you only use the remove method which is available on a BaseEntity directly thus for optimization purpose, it does make sense to avoid extra work done by the Entity class.

In short, if you don't need to work with any of the functionalities offered by the Entity class, you can directly use BaseEntity.

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 24 guests