<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=BrianD</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=BrianD"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/BrianD"/>
	<updated>2026-05-28T04:02:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SDKTools_(SourceMod_Scripting)&amp;diff=11196</id>
		<title>SDKTools (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SDKTools_(SourceMod_Scripting)&amp;diff=11196"/>
		<updated>2021-06-23T14:22:17Z</updated>

		<summary type="html">&lt;p&gt;BrianD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SDKTools extension is an extension for various functions provided by the Source SDK.  Additionally, it has the ability to dynamically call many C++ functions in the SDK, for example, from CBaseEntity or any derived class.&lt;br /&gt;
&lt;br /&gt;
SDKTools contains simplified versions of SDK functions pre-written for ease of use.  These can be found in the additional include files:&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdktools_functions.inc&amp;lt;/tt&amp;gt; - Popular functions from the SDK.&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdktools_sound.inc&amp;lt;/tt&amp;gt; - [[#Sound Functions|Sound-related functions]].&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdktools_tempents.inc&amp;lt;/tt&amp;gt; - [[#TempEnt Functions|TempEnt-related functions]].&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdktools_tempents_stocks.inc&amp;lt;/tt&amp;gt; - [[TempEnts (SourceMod SDKTools)|TempEnt Stocks for convenience]].&lt;br /&gt;
&lt;br /&gt;
SDKTools is powered by &amp;quot;BinTools,&amp;quot; a powerful extension for creating dynamic C/C++ calls.  BinTools is automatically loaded by SDKTools.&lt;br /&gt;
&lt;br /&gt;
=GameConfigs=&lt;br /&gt;
GameConfig files go into the &amp;quot;gamedata&amp;quot; folder under &amp;quot;sourcemod.&amp;quot;  In older revisions it was under &amp;quot;sourcemod/configs&amp;quot; which is now deprecated.&lt;br /&gt;
&lt;br /&gt;
==Virtual Offsets==&lt;br /&gt;
For adding virtual offsets, add sub-sections to the &amp;quot;Offsets&amp;quot; section of your game config file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;Games&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;cstrike&amp;quot;&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;Offsets&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;GiveNamedItem&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;windows&amp;quot; &amp;quot;329&amp;quot;&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;330&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
      &amp;quot;EyePosition&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;windows&amp;quot; &amp;quot;117&amp;quot;&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;118&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      // Get offset of CPlayerResource::m_iBotDifficulty sendprop.&lt;br /&gt;
      // Dynamic way for FindSendPropInfo(class, prop);&lt;br /&gt;
      &amp;quot;BotDifficulty&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;class&amp;quot; &amp;quot;CPlayerResource&amp;quot;&lt;br /&gt;
        &amp;quot;prop&amp;quot;    &amp;quot;m_iBotDifficulty&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Signature Scans==&lt;br /&gt;
For automated signature scans, add sub-sections to the &amp;quot;Signatures&amp;quot; section of your game config file.  These are the properties for a signature:&lt;br /&gt;
*&amp;lt;tt&amp;gt;library&amp;lt;/tt&amp;gt;: The library to search for the pattern or symbol for: &amp;quot;server&amp;quot;, &amp;quot;engine&amp;quot; or &amp;quot;matchmaking_ds&amp;quot; (defaults to &amp;quot;server&amp;quot;).&lt;br /&gt;
*&amp;lt;tt&amp;gt;windows&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;linux&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;mac&amp;lt;/tt&amp;gt;: A pattern or symbol for that platform:&lt;br /&gt;
&lt;br /&gt;
You can put a pattern to search for in memory or a symbol name to lookup:&lt;br /&gt;
*A signature written in binary; for example, &amp;quot;\x56&amp;quot; instead of &amp;quot;0x56&amp;quot; -- the '*' (\x2A) character is a single byte wildcard.&lt;br /&gt;
*A named symbol.  To use a named symbol, start the string with the '@' character.  If a signature begins with '@', write the character in hexadecimal as above.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;Games&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;cstrike&amp;quot;&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;Signatures&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;RoundRespawn&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;library&amp;quot; &amp;quot;server&amp;quot;&lt;br /&gt;
        &amp;quot;windows&amp;quot; &amp;quot;\x56\x8B\xF1\x8B\x06\xFF\x90*\x04\x00\x00\x8B\x86*\x0D\x00&amp;quot;&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;@_ZN9CCSPlayer12RoundRespawnEv&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Raw address lookups==&lt;br /&gt;
Lets you peek and poke (limitation may apply) the Source Dedicated Server memory space, and get a raw address value in an automated way.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;Games&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;left4dead2&amp;quot;&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;Addresses&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;CDirector&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;windows&amp;quot;&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;signature&amp;quot; &amp;quot;DirectorMusicBanks_OnRoundStart&amp;quot;&lt;br /&gt;
          &amp;quot;read&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        &amp;quot;linux&amp;quot;&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;signature&amp;quot; &amp;quot;TheDirector&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        &amp;quot;read&amp;quot; &amp;quot;0&amp;quot;&lt;br /&gt;
        // Since SourceMod 1.9&lt;br /&gt;
        &amp;quot;offset&amp;quot; &amp;quot;4&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;quot;Signatures&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      /* Used solely to get the offset for TheDirector */&lt;br /&gt;
      &amp;quot;DirectorMusicBanks_OnRoundStart&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;library&amp;quot; &amp;quot;server&amp;quot;&lt;br /&gt;
        &amp;quot;windows&amp;quot;       &amp;quot;\x83\xEC\x14\x57\x8B\xF9\x8B\x0D\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x0F\x2A\x2A\x2A\x2A\x2A\x53\x55\x6A\x24\xE8&amp;quot;&lt;br /&gt;
        /* 83 EC 14 57 8B F9 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 0F ? ? ? ? ? 53 55 6A 24 E8 */&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      /* Find the Director/ZombieManager singleton classes */&lt;br /&gt;
      &lt;br /&gt;
      &amp;quot;TheDirector&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;library&amp;quot; &amp;quot;server&amp;quot;&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;@TheDirector&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The data in an Address entry is parse from top to bottom as commands. This example would accomplish the same thing as the following pseudo-C++ code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BYTE * GetCDirectorAddress()&lt;br /&gt;
{&lt;br /&gt;
    BYTE * pAddr;&lt;br /&gt;
&lt;br /&gt;
#if WINDOWS&lt;br /&gt;
&lt;br /&gt;
    pAddr = FindSignature(&amp;quot;DirectorMusicBanks_OnRoundStart&amp;quot;);&lt;br /&gt;
    pAddr = *(pAddr + 8);&lt;br /&gt;
&lt;br /&gt;
#elif LINUX&lt;br /&gt;
&lt;br /&gt;
    pAddr = FindSignature(&amp;quot;TheDirector&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    pAddr = *(pAddr + 0);&lt;br /&gt;
    // Since SourceMod 1.9&lt;br /&gt;
    pAddr = pAddr + 4;&lt;br /&gt;
&lt;br /&gt;
    return pAddr;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To invoke this address lookup in your Sourcepawn code, you would simply set up your GameConf handle and run something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
stock Address:GetTheDirector()&lt;br /&gt;
{&lt;br /&gt;
   return GameConfGetAddress(g_hMyGameConf, &amp;quot;CDirector&amp;quot;);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more code examples, [https://github.com/confoglteam/l4d2_direct l4d2_direct] relies heavily on Address: functions.&lt;br /&gt;
&lt;br /&gt;
==Custom Key Values==&lt;br /&gt;
To read arbitary key value pairs from a gamedata file, add them to the &amp;quot;Keys&amp;quot; section of your game config file.&lt;br /&gt;
You can have different values per platform or have a key only be available on selected platforms.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;Games&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;cstrike&amp;quot;&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;Keys&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;INTERFACEVERSION_GAMEEVENTSMANAGER2&amp;quot; &amp;quot;GAMEEVENTSMANAGER002&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      // Different values per platform (since SourceMod 1.10+)&lt;br /&gt;
      &amp;quot;MyGreatKey&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;windows&amp;quot; &amp;quot;this is wundows speaking&amp;quot;&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;linux best linux&amp;quot;&lt;br /&gt;
        &amp;quot;mac&amp;quot;   &amp;quot;wat&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;JustForLinux&amp;quot;&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;linux&amp;quot;   &amp;quot;not relevant for other platforms!&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the keys using&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char buffer[512];&lt;br /&gt;
GameConfGetKeyValue(g_hMyGameConf, &amp;quot;MyGreatKey&amp;quot;, buffer, sizeof(buffer));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Inheritance==&lt;br /&gt;
If you wish for multiple mods to inherit from one block, you can add a special &amp;quot;#supported&amp;quot; section under a &amp;quot;#default&amp;quot; section.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;Games&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;#default&amp;quot;&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;#supported&amp;quot;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;game&amp;quot;    &amp;quot;dod&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies that the given block will be read for Day of Defeat as well.&lt;br /&gt;
&lt;br /&gt;
=Calling Functions=&lt;br /&gt;
Calling functions is complicated and requires strict attention to the C++ API you are trying to use.  If you make a mistake, something bad '''will''' happen (and if not, you got lucky!)  SDKTools is more complicated than PimpinJuice's &amp;quot;Hacks&amp;quot; extension because it precompiles all of the information needed to convert from Plugin memory to C++ types.  This precompilation step ensures better safety and speed, but it lengthens the preparation process.&lt;br /&gt;
&lt;br /&gt;
With that said, let's look at an overview of the call creation process.  Before making calls, we must ''prepare'' the call.  This will give us a &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; which will let us make as many calls as we like.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Init&amp;lt;/b&amp;gt; - The preparation must be initialized.  Here we can specify the calling convention, which is either static, or BaseEntity/BasePlayer-based.  BasePlayer should be used when only player entities should be allowed as the &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; pointer.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Destination&amp;lt;/b&amp;gt; - The call must have a destination address or virtual index to use.  This is normally done via &amp;lt;tt&amp;gt;PrepSDKCall_SetFromConf&amp;lt;/tt&amp;gt; which ties into gameconf files.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Return Info&amp;lt;/b&amp;gt; - If the call has return information, it must be set via &amp;lt;tt&amp;gt;PrepSDKCall_SetReturnInfo&amp;lt;/tt&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Parameters&amp;lt;/b&amp;gt; - Each parameter (if any) must be added with &amp;lt;tt&amp;gt;PrepSDKCall_AddParameter&amp;lt;/tt&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Finalize&amp;lt;/b&amp;gt; - The call must be finalized with &amp;lt;tt&amp;gt;EndPrepSDKCall&amp;lt;/tt&amp;gt;, which will return a &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.  If it doesn't, one or more of the preparation operations failed.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the examples below, consider a plugin called &amp;quot;sdkexamples.sp&amp;quot; which has a gamedata file of &amp;quot;plugin.sdkexamples.txt&amp;quot; containing the definitions in the first section.&lt;br /&gt;
&lt;br /&gt;
==RoundRespawn Example==&lt;br /&gt;
CCSPlayer::RoundRespawn is a Counter-Strike Source function which respawns players.  It used by CS:S DM.  Prototype:&lt;br /&gt;
&amp;lt;pre&amp;gt;void CCSPlayer::RoundRespawn()&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SDKCall example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Handle hGameConf;&lt;br /&gt;
Handle hRoundRespawn;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
  hGameConf = LoadGameConfigFile(&amp;quot;plugin.sdkexamples&amp;quot;);&lt;br /&gt;
  StartPrepSDKCall(SDKCall_Player);&lt;br /&gt;
  PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, &amp;quot;RoundRespawn&amp;quot;);&lt;br /&gt;
  hRoundRespawn = EndPrepSDKCall();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void RespawnPlayer(int client)&lt;br /&gt;
{&lt;br /&gt;
  SDKCall(hRoundRespawn, client);&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we did not have to set any extra information for parameters or return info, since CCSPlayer::RoundRespawn has no parameters and has a void return.&lt;br /&gt;
&lt;br /&gt;
==GiveNamedItem Example==&lt;br /&gt;
GiveNamedItem will give a player a named item.  Prototype:&lt;br /&gt;
&amp;lt;pre&amp;gt;virtual CBaseEntity *CBasePlayer::GiveNamedItem(const char *item, int iSubType = 0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Handle hGameConf;&lt;br /&gt;
Handle hGiveNamedItem;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
  hGameConf = LoadGameConfigFile(&amp;quot;plugin.sdkexamples&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  StartPrepSDKCall(SDKCall_Player);&lt;br /&gt;
  PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, &amp;quot;GiveNamedItem&amp;quot;);&lt;br /&gt;
  PrepSDKCall_SetReturnInfo(SDKType_CBaseEntity, SDKPass_Pointer);&lt;br /&gt;
  PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);&lt;br /&gt;
  PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);&lt;br /&gt;
  hGiveNamedItem = EndPrepSDKCall();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
any GiveItem(int client, const char[] item)&lt;br /&gt;
{&lt;br /&gt;
  return SDKCall(hGiveNamedItem, client, item, 0);&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==GetEyePosition Example==&lt;br /&gt;
Prototype:&lt;br /&gt;
&amp;lt;pre&amp;gt;virtual Vector CBaseEntity::EyePosition();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Handle hGameConf;&lt;br /&gt;
Handle hGetEyePosition;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
  hGameConf = LoadGameConfigFile(&amp;quot;plugin.sdkexamples&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  StartPrepSDKCall(SDKCall_Player);&lt;br /&gt;
  PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, &amp;quot;EyePosition&amp;quot;);&lt;br /&gt;
  PrepSDKCall_SetReturnInfo(SDKType_Vector, SDKPass_ByValue);&lt;br /&gt;
  hGetEyePosition= EndPrepSDKCall();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
any GetEyePosition(int client, float pos[3])&lt;br /&gt;
{&lt;br /&gt;
  SDKCall(hGetEyePosition, client, pos);&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the vector is returned as the third parameter (first parameter after the &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; pointer).&lt;br /&gt;
&lt;br /&gt;
=TempEnt Functions=&lt;br /&gt;
TempEnts, also called &amp;quot;temporary entities,&amp;quot; &amp;quot;tempentities,&amp;quot; or &amp;quot;TEs,&amp;quot; are quick graphical displays that are too simple to justify the overhead of a &amp;lt;tt&amp;gt;CBaseEntity&amp;lt;/tt&amp;gt; instantiation or full server-side networkability.  In the SDK, they are statically defined instances that can be &amp;quot;played back&amp;quot; to the client by simply sending a copy of its network class properties.&lt;br /&gt;
&lt;br /&gt;
Temporary Entities are mod-dependent, in that a mod can change any of their properties or even the &amp;lt;tt&amp;gt;ITempEnts&amp;lt;/tt&amp;gt; class definition.  Because of this, SourceMod takes a very flexible approach:&lt;br /&gt;
*&amp;lt;b&amp;gt;First&amp;lt;/b&amp;gt;, a temp entity is ''started'' by name using &amp;lt;tt&amp;gt;TE_Start&amp;lt;/tt&amp;gt;.  A list of all tempent names and their network classes can be dumped with &amp;lt;tt&amp;gt;sm_print_telist&amp;lt;/tt&amp;gt; (SDKTools must be loaded).&lt;br /&gt;
*&amp;lt;b&amp;gt;Second&amp;lt;/b&amp;gt;, all of the tempent's properties are set via the &amp;lt;tt&amp;gt;TE_Write&amp;lt;/tt&amp;gt; natives.  All tempent properties can be dumped to a file using &amp;lt;tt&amp;gt;sm_dump_teprops&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Third&amp;lt;/b&amp;gt;, the properties are transmitted using &amp;lt;tt&amp;gt;TE_Send&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;TE_SendToAll&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;TE_SendToClient&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As a convenience, SourceMod provides a number of pre-written stocks for SDK-defined temporary entities.  While the &amp;lt;tt&amp;gt;TE_*&amp;lt;/tt&amp;gt; natives are guaranteed to work on any fully-supported SourceMod mod, the &amp;lt;tt&amp;gt;TE_Setup*&amp;lt;/tt&amp;gt; stocks are not, as a mod might change the property layouts or the functionalities of the SDK-defined tempents.&lt;br /&gt;
&lt;br /&gt;
Some examples are below.  For pictures, see [[TempEnts (SourceMod SDKTools)]].&lt;br /&gt;
&lt;br /&gt;
Using stocks:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void SparkClient(int client, const float pos[3], const float dir[3])&lt;br /&gt;
{&lt;br /&gt;
  TE_SetupMetalSparks(pos, dir);&lt;br /&gt;
  TE_SendToClient(client);&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not using stocks:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void SparkClient(int client, const float pos[3], const float dir[3])&lt;br /&gt;
{&lt;br /&gt;
  TE_Start(&amp;quot;Metal Sparks&amp;quot;);&lt;br /&gt;
  TE_WriteVector(&amp;quot;m_vecPos&amp;quot;, pos);&lt;br /&gt;
  TE_WriteVector(&amp;quot;m_vecDir&amp;quot;, dir);&lt;br /&gt;
  TE_SendToClient(client);&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Sound Functions=&lt;br /&gt;
SDKTools exposes various sound-related members of IVEngineServer and IEngineSound.  The basic functions are in &amp;lt;tt&amp;gt;sdktools_sound.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
*&amp;lt;tt&amp;gt;EmitAmbientSound&amp;lt;/tt&amp;gt;: Plays an ambient sound from an origin.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EmitSound, EmitSoundToClient, EmitSoundToAll&amp;lt;/tt&amp;gt;: Plays a sound to a list of clients from a specific entity.&lt;br /&gt;
&lt;br /&gt;
There are a few important properties about sounds:&lt;br /&gt;
*&amp;lt;b&amp;gt;Entity&amp;lt;/b&amp;gt;: The entity the sound should come from.  When playing a generic sound file to player(s), you should use &amp;lt;tt&amp;gt;SOUND_FROM_PLAYER&amp;lt;/tt&amp;gt;, which is a special SourceMod macro for making the sound come from the player target.  For ambient sounds you'd use &amp;lt;tt&amp;gt;SOUND_FROM_WORLD&amp;lt;/tt&amp;gt;, and for sounds from an entity you'd use the entity index.&lt;br /&gt;
*&amp;lt;b&amp;gt;Channel&amp;lt;/b&amp;gt;: Exposed as &amp;lt;tt&amp;gt;SNDCHAN_*&amp;lt;/tt&amp;gt;, normally you only need to use &amp;lt;tt&amp;gt;SNDCHAN_AUTO&amp;lt;/tt&amp;gt;.  The channel affects how the sound is spatialized[?]&lt;br /&gt;
*&amp;lt;b&amp;gt;Level&amp;lt;/b&amp;gt;: The decibel level.  There are a number of predefined levels as &amp;lt;tt&amp;gt;SNDLEVEL_*&amp;lt;/tt&amp;gt; -- the standard one is &amp;lt;tt&amp;gt;SNDLEVEL_NORMAL&amp;lt;/tt&amp;gt;.  Half-Life 1 used attenuation values instead; you can convert from these using &amp;lt;tt&amp;gt;ATTN_TO_SNDLEVEL()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Volume&amp;lt;/b&amp;gt;: The volume, on a scale of 0.0 to 1.0.  To use a volume other than the default, the &amp;lt;tt&amp;gt;SND_CHANGEVOL&amp;lt;/tt&amp;gt; flag should be included in the &amp;quot;flags&amp;quot; parameter.  The default volume is &amp;lt;tt&amp;gt;SNDVOL_NORMAL&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Pitch&amp;lt;/b&amp;gt;: The pitch; predefined values are &amp;lt;tt&amp;gt;SNDPITCH_*&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;SNDPITCH_NORMAL&amp;lt;/tt&amp;gt; being the default.  &amp;lt;tt&amp;gt;SND_CHANGEPITCH&amp;lt;/tt&amp;gt; should be passed to use a non-default pitch.&lt;br /&gt;
*&amp;lt;b&amp;gt;Origin&amp;lt;/b&amp;gt;: If specified, an origin to play the sound from.&lt;br /&gt;
&lt;br /&gt;
Some very simple examples:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
EmitSoundToClient(client, &amp;quot;bot/affirmative.wav&amp;quot;);&lt;br /&gt;
EmitSoundToAll(&amp;quot;radio/terwin.wav&amp;quot;);&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Supported Mods=&lt;br /&gt;
SDKTools must have specific support added for each mod.  So far, default support exists for the following modifications:&lt;br /&gt;
*Counter-Strike: Source&lt;br /&gt;
*Day of Defeat: Source&lt;br /&gt;
*Dystopia&lt;br /&gt;
*Half-Life 2: Deathmatch&lt;br /&gt;
*Insurgency (only some of the CBasePlayer SDK functions are available)&lt;br /&gt;
*Pirates, Vikings, and Knights II&lt;br /&gt;
*The Ship&lt;br /&gt;
*SourceForts&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
*[[Vfunc_offsets_%28SourceMM%29|Virtual Functions]]&lt;br /&gt;
*[[TempEnts (SourceMod SDKTools)|TempEnts]]&lt;br /&gt;
*[[Useful_Signatures_%28Source%29|Useful Signatures]]&lt;br /&gt;
*[[Signature_Scanning|Signature Scanning]]&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>BrianD</name></author>
		
	</entry>
</feed>