Entity References (SourceMod)

From AlliedModders Wiki
Revision as of 17:59, 29 March 2020 by Joinedsenses (talk | contribs) (Update highlighting)
Jump to: navigation, search

DataPacks are a way to store and move around various types of data in SourceMod Scripting. Since some things are not possible in SourcePawn, such as a function consuming a String, DataPacks help us get these Strings and other items where they need to go.

Example of using a DataPack

Syntax:

//writing
DataPack pack = new DataPack();
pack.WriteCell(23);
pack.WriteString("I'm a little teapot.");
 
//reading
pack.Reset(); //resets the index to the beginning, necessary for read.
int cellValue = pack.ReadCell();
char buffer[1024];
pack.ReadString(buffer, 1024);

Creating a DataPack

Creating a DataPack is very simple; all you need is a Handle to write to.

Datapack dataPackHandle = new DataPack();

For more information on using Handles, see Handle API (SourceMod).

DataPack Functions

On you have created your DataPack, you can use a variety of functions to manage the DataPack.

WritePackCell

Syntax:

native void WritePackCell(Handle pack, any cell);

WritePackFloat

This function can be used to write a Float to a DataPack.

Syntax:

native void WritePackFloat(Handle pack, float val);

WritePackString

This function can be used to write a String to a DataPack.

Syntax:

native void WritePackString(Handle pack, const char[] str);

ReadPackCell

Syntax:

native any ReadPackCell(Handle pack);

ReadPackFloat

This function can be used to read a Float from a DataPack.

Syntax:

native float ReadPackFloat(Handle pack);

ReadPackString

This function can be used to read a String from a DataPack.

Syntax:

native void ReadPackString(Handle pack, char[] buffer, maxlen);

ResetPack

This function resets your position in the DataPack.

Syntax:

native void ResetPack(Handle pack, bool clear=false);

GetPackPosition

This function gets your current position in the DataPack.

Syntax:

native int GetPackPosition(Handle pack);

SetPackPosition

This function sets your current position in the DataPack.

Syntax:

native void SetPackPosition(Handle pack, int position);

Disposing of a DataPack

To dispose of a DataPack, all you have to do is close its Handle.

Example:

CloseHandle(dataPackHandle);

An entity reference is a combination of a standard entity index (used for all entities in SourceMod previously) and a pseudo-unique serial number that identifies the entity. Since entities are constantly being created and destroyed a cached index doesn't guarantee the underlying entity is the same, references provide a way of verifying the same entity still exists. Generally speaking, if you have an entity index you wish to cache you should convert it to a reference first. Most Sourcemod-provided natives should be able to accept references in place of indexes (wherever the parameter asks for an entity - Not clients), and these will use the serial to check that the entity index contained in the reference is the same as when the reference was created. If you find a native that does not seem to support references in place of indexes, please file a bug report.

SourceMod now also supports handling of logical (non-networked entities) and these use references exclusively. Natives that used to return an entity index will continue to do so in the case of networked entities (for backwards compatability) and will only return a reference for non-networked ones.

Converting a backwards-compat index/ref to a guaranteed reference for safely caching

int index = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon");
 
/* Convert our backwards-compat index/ref to a guaranteed reference */
int ref = EntIndexToEntRef(index);

Converting a reference back to an entity index

int index = EntRefToEntIndex(ref);
 
if (index == INVALID_ENT_REFERENCE)
{
  /* Reference wasn't valid - Entity must have been deleted */
}

Using References to handle a logic entity

int ent = -1;  
 
while ((ent = FindEntityByClassname(ent, "logic_auto")) != -1)  
{  
    /**   
     * Get the entity index from this reference - This works on references and indexes for convenience.   
     * Should be a number >2048 since logic_auto is a non networked entity   
     */  
    int ref = EntIndexToEntRef(ent);  
 
    /* Fire an input on this entity - We use the reference version since this includes a serial check */  
    AcceptEntityInput(ref, "Kill");  
 
}