Page 1 of 1
Check if Entity exists
Posted: Sat Oct 22, 2016 3:37 pm
by velocity
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()
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 3:53 pm
by D3CEPTION
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 3:56 pm
by Kill
Maybe try to retrieve the entity Index, If it exists then continue?
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 3:59 pm
by L'In20Cible
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.
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 4:04 pm
by iPlayer
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...
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 4:09 pm
by satoon101
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.
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 4:25 pm
by decompile
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.
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 4:25 pm
by Ayuto
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.
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 4:39 pm
by L'In20Cible
For convenience, we could add an Entity.delay method that wrap the Delay class and internally cancel on entity deletion.
Re: Check if Entity exists
Posted: Sat Oct 22, 2016 11:36 pm
by velocity
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
Re: Check if Entity exists
Posted: Sun Oct 23, 2016 1:29 am
by L'In20Cible
Re: Check if Entity exists
Posted: Sun Oct 23, 2016 6:33 am
by iPlayer
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.
Re: Check if Entity exists
Posted: Sun Oct 23, 2016 6:40 am
by L'In20Cible
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
Re: Check if Entity exists
Posted: Sat Oct 29, 2016 12:43 pm
by velocity
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
Re: Check if Entity exists
Posted: Sat Oct 29, 2016 1:01 pm
by L'In20Cible
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.