Entity Lumps (SourceMod Scripting)

From AlliedModders Wiki
Jump to: navigation, search

Source Engine maps store entity data in an entity lump, which is a plain text file containing a list of key / value pairs describing each entity.

SourceMod implements functionality to manipulate this data in entitylump.inc. This functionality was added to the development branch in 1.12.0.6922, then backported to the stable branch in 1.11.0.6919 (after its release).

Introduction

The global EntityLump methodmap contains functions to access individual entity entries. Below is an example lump that will be used throughout the rest of this page:

{
"world_maxs" "2624 4720 1728"
"world_mins" "-3536 -4720 -560"
"skyname" "sky_tf2_04"
"minoccluderarea_x360" "110"
"maxpropscreenwidth" "-1"
"detailvbsp" "detail_2fort.vbsp"
"detailmaterial" "detail/detailsprites_2fort"
"classname" "worldspawn"
"mapversion" "4067"
"hammerid" "4396"
}
{
"origin" "212.201 1784.53 259.256"
"fademindist" "-1"
"AutoMaterialize" "1"
"angles" "0 180 0"
"classname" "item_ammopack_small"
"hammerid" "5314720"
}
{
"origin" "-48 84 617"
"spawnflags" "1"
"classname" "logic_auto"
"hammerid" "741865"
"OnMapSpawn" "tonemap_global,SetAutoExposureMin,.8,0,-1"
"OnMapSpawn" "tonemap_global,SetAutoExposureMax,1.1,0,-1"
"OnMapSpawn" "tonemap_global,SetBloomScale,.5,0,-1"
"OnMapSpawn" "tf_gamerules,SetBlueTeamGoalString,#2fort_blue_setup_goal,0,-1"
"OnMapSpawn" "tf_gamerules,SetRedTeamGoalString,#2fort_red_setup_goal,0,-1"
"OnMapSpawn" "tf_gamerules,SetStalemateOnTimelimit,1,0,-1"
}

Plugins must modify the entity lump during the OnMapInit forward. Attempting to use non-read operations (such as update, insert, append, and erase) outside of that forward will raise a runtime error.

Entity Lump

The global EntityLump behaves like an ArrayList; to get a specific entity lump entry you must call its Get function:

// get the worldspawn entity from the list
EntityLumpEntry entry = EntityLump.Get(0);
 
// release our handle to it when we are done
delete entry;

If you don't know where your desired entity is, you must iterate over the list:

for (int i, n = EntityLump.Length(); i < n; i++)
{
	EntityLumpEntry entry = EntityLump.Get(i);
	if (entry.FindKey("AutoMaterialize") != -1)
	{
		// this item has at least one 'AutoMaterialize' key
	}
	delete entry;
}

Entity Lump Entry

EntityLumpEntry handles contains a list of key / value pairs.

You can modify an entry's values:

// get the item_ammopack_small entity from the list
EntityLumpEntry entry = EntityLump.Get(1);
 
// find the 'classname' key in the list, then modify it
int icname = entry.FindKey("classname");
if (icname != -1)
{
	// keep the name as 'classname', but change the value to 'item_ammopack_full'
	entry.Update(icname, NULL_STRING, "item_ammopack_full");
}
delete entry;

Keys do not have a one-to-one mapping with values; there may be duplicates. You can iterate over the available key / value pairs matching the key name with EntityLumpEntry.GetNextKey():

// get the 'logic_auto' from the list
EntityLumpEntry entry = EntityLump.Get(2);
char outputString[256];
for (int i = -1; (i = entry.GetNextKey("OnMapSpawn", outputString, sizeof(outputString), i)) != -1;)
{
	// print all of the logic_auto's OnMapSpawn outputs
	LogMessage("OnMapSpawn output: %s", outputString);
}
delete entry;