Add functions for working with entity lumps (#1673)
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
#if defined _entitylump_included
|
||||
#endinput
|
||||
#endif
|
||||
|
||||
#define _entitylump_included
|
||||
|
||||
/**
|
||||
* An ordered list of key / value pairs for a map entity.
|
||||
* If the entry in the EntityLump is removed, the handle will error on all operations.
|
||||
* (The handle will remain valid on the scripting side, and will still need to be deleted.)
|
||||
*
|
||||
* Write operations (update, insert, erase, append) are only allowed during OnMapInit.
|
||||
*/
|
||||
methodmap EntityLumpEntry < Handle {
|
||||
/**
|
||||
* Copies the key / value at the given index into buffers.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @param keybuf Key name buffer.
|
||||
* @param keylen Maximum length of the key name buffer.
|
||||
* @param valbuf Value buffer.
|
||||
* @param vallen Maximum length of the value buffer.
|
||||
* @error Index is out of bounds.
|
||||
*/
|
||||
public native void Get(int index, char[] keybuf = "", int keylen = 0, char[] valbuf = "", int vallen = 0);
|
||||
|
||||
/**
|
||||
* Updates the key / value pair at the given index.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @param key New key name, or NULL_STRING to preserve the existing key name.
|
||||
* @param value New value, or NULL_STRING to preserve the existing value.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public native void Update(int index, const char[] key = NULL_STRING, const char[] value = NULL_STRING);
|
||||
|
||||
/**
|
||||
* Inserts a new key / value pair at the given index, shifting the pair at that index and beyond up.
|
||||
* If EntityLumpEntry.Length is passed in, this is an append operation.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @param key New key name.
|
||||
* @param value New value.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public native void Insert(int index, const char[] key, const char[] value);
|
||||
|
||||
/**
|
||||
* Removes the key / value pair at the given index, shifting all entries past it down.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public native void Erase(int index);
|
||||
|
||||
/**
|
||||
* Inserts a new key / value pair at the end of the entry's list.
|
||||
*
|
||||
* @param key New key name.
|
||||
* @param value New value.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public native void Append(const char[] key, const char[] value);
|
||||
|
||||
/**
|
||||
* Searches the entry list for an index matching a key starting from a position.
|
||||
*
|
||||
* @param key Key name to search.
|
||||
* @param start A position after which to begin searching from. Use -1 to start from the
|
||||
* first entry.
|
||||
* @return Position after start with an entry matching the given key, or -1 if no
|
||||
* match was found.
|
||||
* @error Invalid start position; must be a value between -1 and one less than the
|
||||
* length of the entry.
|
||||
*/
|
||||
public native int FindKey(const char[] key, int start = -1);
|
||||
|
||||
/**
|
||||
* Searches the entry list for an index matching a key starting from a position.
|
||||
* This also copies the value from that index into the given buffer.
|
||||
*
|
||||
* This can be used to find the first / only value matching a key, or to iterate over all
|
||||
* the values that match said key.
|
||||
*
|
||||
* @param key Key name to search.
|
||||
* @param buffer Value buffer. This will contain the result of the next match, or empty
|
||||
* if no match was found.
|
||||
* @param maxlen Maximum length of the value buffer.
|
||||
* @param start An index after which to begin searching from. Use -1 to start from the
|
||||
* first entry.
|
||||
* @return Position after start with an entry matching the given key, or -1 if no
|
||||
* match was found.
|
||||
* @error Invalid start position; must be a value between -1 and one less than the
|
||||
* length of the entry.
|
||||
*/
|
||||
public int GetNextKey(const char[] key, char[] buffer, int maxlen, int start = -1) {
|
||||
int result = this.FindKey(key, start);
|
||||
if (result != -1) {
|
||||
this.Get(result, .valbuf = buffer, .vallen = maxlen);
|
||||
} else {
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of key / value pairs in the entry.
|
||||
*/
|
||||
property int Length {
|
||||
public native get();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A group of natives for a singleton entity lump, representing all the entities defined in the map.
|
||||
*
|
||||
* Write operations (insert, erase, append) are only allowed during OnMapInit.
|
||||
*/
|
||||
methodmap EntityLump {
|
||||
/**
|
||||
* Returns the EntityLumpEntry at the given index.
|
||||
* This handle should be freed by the calling plugin.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @error Index is out of bounds.
|
||||
*/
|
||||
public static native EntityLumpEntry Get(int index);
|
||||
|
||||
/**
|
||||
* Erases an EntityLumpEntry at the given index, shifting all entries past it down.
|
||||
* Any handles referencing the erased EntityLumpEntry will throw on any operations aside from delete.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public static native void Erase(int index);
|
||||
|
||||
/**
|
||||
* Inserts an empty EntityLumpEntry at the given index, shifting the existing entry and ones past it up.
|
||||
*
|
||||
* @param index Position, starting from 0.
|
||||
* @error Index is out of bounds or entity lump is read-only.
|
||||
*/
|
||||
public static native void Insert(int index);
|
||||
|
||||
/**
|
||||
* Creates an empty EntityLumpEntry, returning its index.
|
||||
*
|
||||
* @error Entity lump is read-only.
|
||||
*/
|
||||
public static native int Append();
|
||||
|
||||
/**
|
||||
* Returns the number of entities currently in the lump.
|
||||
*/
|
||||
public static native int Length();
|
||||
};
|
||||
@@ -76,6 +76,7 @@ struct Plugin
|
||||
#include <commandfilters>
|
||||
#include <nextmap>
|
||||
#include <commandline>
|
||||
#include <entitylump>
|
||||
|
||||
enum APLRes
|
||||
{
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
#pragma semicolon 1
|
||||
#include <sourcemod>
|
||||
|
||||
#include <sdktools>
|
||||
#include <entitylump>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
#define PLUGIN_VERSION "0.0.0"
|
||||
public Plugin myinfo = {
|
||||
name = "Entity Lump Core Native Test",
|
||||
author = "nosoop",
|
||||
description = "A port of the Level KeyValues entity test to the Entity Lump implementation in core SourceMod",
|
||||
}
|
||||
|
||||
#define OUTPUT_NAME "OnCapTeam2"
|
||||
|
||||
public void OnMapInit() {
|
||||
// set every area_time_to_cap value to 30
|
||||
for (int i, n = EntityLump.Length(); i < n; i++) {
|
||||
EntityLumpEntry entry = EntityLump.Get(i);
|
||||
|
||||
int ttc = entry.FindKey("area_time_to_cap");
|
||||
if (ttc != -1) {
|
||||
entry.Update(ttc, NULL_STRING, "30");
|
||||
PrintToServer("Set time to cap for item %d to 30", i);
|
||||
}
|
||||
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMapStart() {
|
||||
int captureArea = FindEntityByClassname(-1, "trigger_capture_area");
|
||||
|
||||
if (!IsValidEntity(captureArea)) {
|
||||
LogMessage("---- %s", "No capture area");
|
||||
return;
|
||||
}
|
||||
|
||||
int hammerid = GetEntProp(captureArea, Prop_Data, "m_iHammerID");
|
||||
EntityLumpEntry entry = FindEntityLumpEntryByHammerID(hammerid);
|
||||
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogMessage("---- %s", "Found a trigger_capture_area with keys:");
|
||||
|
||||
for (int i, n = entry.Length; i < n; i++) {
|
||||
char keyBuffer[128], valueBuffer[128];
|
||||
entry.Get(i, keyBuffer, sizeof(keyBuffer), valueBuffer, sizeof(valueBuffer));
|
||||
|
||||
LogMessage("%s -> %s", keyBuffer, valueBuffer);
|
||||
}
|
||||
|
||||
LogMessage("---- %s", "List of " ... OUTPUT_NAME ... " outputs:");
|
||||
char outputString[256];
|
||||
for (int k = -1; (k = entry.GetNextKey(OUTPUT_NAME, outputString, sizeof(outputString), k)) != -1;) {
|
||||
char targetName[32], inputName[64], variantValue[32];
|
||||
float delay;
|
||||
int nFireCount;
|
||||
|
||||
ParseEntityOutputString(outputString, targetName, sizeof(targetName),
|
||||
inputName, sizeof(inputName), variantValue, sizeof(variantValue),
|
||||
delay, nFireCount);
|
||||
|
||||
LogMessage("target %s -> input %s (value %s, delay %.2f, refire %d)",
|
||||
targetName, inputName, variantValue, delay, nFireCount);
|
||||
}
|
||||
delete entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first EntityLumpEntry with a matching hammerid.
|
||||
*/
|
||||
EntityLumpEntry FindEntityLumpEntryByHammerID(int hammerid) {
|
||||
for (int i, n = EntityLump.Length(); i < n; i++) {
|
||||
EntityLumpEntry entry = EntityLump.Get(i);
|
||||
|
||||
char value[32];
|
||||
if (entry.GetNextKey("hammerid", value, sizeof(value)) != -1
|
||||
&& StringToInt(value) == hammerid) {
|
||||
return entry;
|
||||
}
|
||||
delete entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an entity's output value (as formatted in the entity string).
|
||||
* Refer to https://developer.valvesoftware.com/wiki/AddOutput for the format.
|
||||
*
|
||||
* @return True if the output string was successfully parsed, false if not.
|
||||
*/
|
||||
stock bool ParseEntityOutputString(const char[] output, char[] targetName, int targetNameLength,
|
||||
char[] inputName, int inputNameLength, char[] variantValue, int variantValueLength,
|
||||
float &delay, int &nFireCount) {
|
||||
int delimiter;
|
||||
char buffer[32];
|
||||
|
||||
{
|
||||
// validate that we have something resembling an output string (four commas)
|
||||
int i, c, nDelim;
|
||||
while ((c = FindCharInString(output[i], ',')) != -1) {
|
||||
nDelim++;
|
||||
i += c + 1;
|
||||
}
|
||||
if (nDelim < 4) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
delimiter = SplitString(output, ",", targetName, targetNameLength);
|
||||
delimiter += SplitString(output[delimiter], ",", inputName, inputNameLength);
|
||||
delimiter += SplitString(output[delimiter], ",", variantValue, variantValueLength);
|
||||
|
||||
delimiter += SplitString(output[delimiter], ",", buffer, sizeof(buffer));
|
||||
delay = StringToFloat(buffer);
|
||||
|
||||
nFireCount = StringToInt(output[delimiter]);
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user