AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   [TUT] SourcePawn Scripting - Tips, Basics to Advanced (https://forums.alliedmods.net/showthread.php?t=321089)

Silvers 03-16-2022 14:22

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Quote:

Originally Posted by Dragokas (Post 2774339)
I think it's required. However, you can try remove entity and experiment with dereference on your own to see if error persist.

I would have thought deref would be enough but I recall having one or two reports of invalid entities after deref so it seems to be required, very rare cases nonetheless.

NoroHime 03-16-2022 23:29

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
thanks everyone patiently anser, i got point that unique is important,
although it is a bit unsightly code to use, but i tend to use like this
PHP Code:

timer(int entref){
    
int ent;
    if (
ent UnpackEnt(entref)) {
    
/*operation*/
    
}
}

int UnpackEnt(int entref) {
    
int unpacked EntRefToEntIndex(entref);
    if (
unpacked != INVALID_ENT_REFERENCE && IsValidEdict(unpacked))
        return 
unpacked;



AdRiAnIlloO 03-21-2022 12:04

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
I recently realized cleaning entity index trackers was also an option (from OnEntityDestroyed) and lately used that approach instead of entity references system, for just one entity as max. in my case. However, cleaning the appropiate variable can become inconvenient once handling enough amount of possible tracked entities, as it requires conditioning to match against the appropiate variable each case.

But as long as you handle few entity tracking variables, storing indices is perfectly adequate and efficient in terms of a gameplay session (vs. calling EntRefToEntIndex continuatedly) as long as you clear the variables at OnEntityDestroyed (aka assigning them to e.g. INVALID_ENT_REFERENCE).

Obviously this approach is unproductive if perfoming extra checks other than entity != INVALID_ENT_REFERENCE for validating.

Dragokas 03-21-2022 12:36

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
AdRiAnIlloO, same mistake as I described above. Those entity can be replaced very soon. So, your kind of check will return "entity exists and valid", however, that is other entity, not the one you initially tracked. As a result you will target (and perhaps, further delete) someone else's entity, causing hard-to-trace bug. EntIndexToEntRef guarantee the index become unique and will not be replaced with another one newly created entity having same ref index.

AdRiAnIlloO 03-23-2022 04:03

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Citing your own quote.

Quote:

Originally Posted by Dragokas (Post 2774339)
You could use OnEntityDestoyed with your entities array. However, usually a single IsValidEntity operation is more efficient.

This is what I exactly suggested, expanding the reasoning with how to ensure it overcomes EntRefToEntIndex approach (basically not calling that nor IsValidEntity, etc.) as one already has the tracked value set/cleaned to e.g. INVALID_ENTITY_REFERENCE at OnEntityDestroyed.

Or, is it that OnEntityDestroyed could be called after engine assigned the passed index to a new entity? From the SDK, entities are usually totally removed one frame after requested, for security reasons, during which I wonder if engine could free their index (haven't reached to confirm it).

But basically what he is saying is the same than you and me pointed, why not to use the OnEntityDestroyed approach when it seems perfectly valid (if not loosing productivity, as I explained) against ent ref checks.

Dragokas 03-23-2022 09:36

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Well, I already explained. But, ok, show me code example of a real task according to your suggestion and I'll tell you why.

AdRiAnIlloO 03-26-2022 07:54

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Sorry for the delay, was busy. Here goes the parts of interest for my entity-tracking variable (which aims to refer to an env_sprite):

Code:

int gKingSprite = INVALID_ENT_REFERENCE; // Global scope declaration

public void OnEntityDestroyed(int entity)
{
        if (entity == gKingSprite)
        {
                gKingSprite = INVALID_ENT_REFERENCE; // The "cleaning"
        }
}

void AwardKingSprite() // One of the functions of entity validating interest (called at times from my specific needs)
{
        if (gKingSprite == INVALID_ENT_REFERENCE) // Safe cheap checking thanks to the OnEntityDestroyed cleaning
        {
                if ((gKingSprite = CreateEntityByName("env_sprite")) == INVALID_ENT_REFERENCE)
                {
                        return;
                }

                // <Entity setup code>...
        }
}

As you can see, this is a clear example of the previous reasonings. In case the entity gets deleted, the variable should go INVALID_ENT_REFERENCE, eliminating the need to perform expensiver checks (EntRefToEntIndex, IsValidEntity...) other than '==' (or '!=' depending on the concrete direction of interest) at the highlighted line of the code fragment.

Note SM should always pass entity indices for networked (edict-full) entities (and internal entrefs for non-networked entities instead) to the entity forwards.

PS: Also, I've confirmed OnEntityDestroyed only gets called upon total entity destruction (that is, after the security game frame happens originated from the common entity destroy requests from Source games): CGlobalEntityList::NotifyRemoveEntity -> SDKHooks::OnEntityDeleted, but it seems the edict (and thus, index) should be destroyed right after.

Dragokas 03-26-2022 08:21

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Yeah, in such way it is safe.
I don't remember which one case I told above, sorry.

Silvers 03-26-2022 09:21

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Quote:

Originally Posted by AdRiAnIlloO (Post 2775245)
eliminating the need to perform expensiver checks (EntRefToEntIndex, IsValidEntity...) other than '==' (or '!=' depending on the concrete direction of interest) at the highlighted line of the code fragment.

If the entity is not being accessed very often then this may end up using more CPU cycles than EntRefToEntIndex and check. They are not expensive at all, so that statement of yours is wrong.

plug344 03-28-2022 05:05

Re: [TUT] SourcePawn Scripting - Tips, Basics to Advanced
 
Which is faster, FormatEx or strcopy?


All times are GMT -4. The time now is 22:27.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.