<?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=TnTSCS</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=TnTSCS"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/TnTSCS"/>
	<updated>2026-04-28T23:40:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=9834</id>
		<title>Scripting FAQ (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=9834"/>
		<updated>2015-03-09T08:34:22Z</updated>

		<summary type="html">&lt;p&gt;TnTSCS: /* How do I add color to my messages? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Yak.gif]]&lt;br /&gt;
yak wuz heer&lt;br /&gt;
&lt;br /&gt;
=How do I learn SourcePawn?=&lt;br /&gt;
A good start is on the [[Introduction to SourcePawn]] page, which will teach you the SourcePawn language. Then go through the [[Introduction to SourceMod Plugins]], which will teach you how to write your first plug-in.&lt;br /&gt;
&lt;br /&gt;
=Where can I find all the SourcePawn functions and other information?=&lt;br /&gt;
All SourceMod plug-ins have this line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line instructs the compiler to retrieve the file &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;sourcemod/scripting/include&amp;lt;/tt&amp;gt; folder. Every function, variable, and definition can be found in the &amp;lt;tt&amp;gt;.inc&amp;lt;/tt&amp;gt; files inside the &amp;lt;tt&amp;gt;sourcemod/scripting/include&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
But searching through all those files can be quite tedious. Thankfully, the honourable [https://forums.alliedmods.net/member.php?u=9443 Nican] created an API reference viewable on the web, complete with searching and commenting: [http://docs.sourcemod.net/api/ http://docs.sourcemod.net/api/]&lt;br /&gt;
&lt;br /&gt;
Also, if you are in the SourceMod IRC channel ([irc://irc.gamesurge.net/sourcemod #sourcemod on GameSurge]), you can use the &amp;lt;tt&amp;gt;!api&amp;lt;/tt&amp;gt; command to search [https://forums.alliedmods.net/member.php?u=9443 Nican's] API reference:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;theY4Kman&amp;gt; !api Netclass&lt;br /&gt;
&amp;lt;yakbot&amp;gt; theY4Kman: GetEntityNetClass(edict, String:clsname[], maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=66)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I find the classname of an entity? (e.g., &amp;quot;&amp;lt;tt&amp;gt;weapon_knife&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;prop_physics&amp;lt;/tt&amp;gt;&amp;quot;)=&lt;br /&gt;
The classname of an entity (not to be confused with a netclass such as &amp;lt;tt&amp;gt;CCSPlayer&amp;lt;/tt&amp;gt;) is a unique identifier. It's the most well known of entity names. To find it, use the function [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=65 GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:classname[128];&lt;br /&gt;
GetEdictClassname(myentity, classname, sizeof(classname));&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;myentity classname: %s&amp;quot;, classname);&lt;br /&gt;
// myentity classname: weapon_knife&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I block regular commands, such as &amp;lt;tt&amp;gt;kill&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt;?=&lt;br /&gt;
As of version 1.3, the recommended way to hook and block commands is with [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()]. Previously, using [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=470 RegConsoleCmd()] with the command name was the only way to hook commands, but this creates a whole new command for the command dispatch to check every time any command is executed. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()] creates only a lightweight hook, processed only when the specific command is executed.&lt;br /&gt;
&lt;br /&gt;
Here's how to use it to block the &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    AddCommandListener(SayCallback, &amp;quot;say&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:SayCallback(client, const String:command[], argc)&lt;br /&gt;
{&lt;br /&gt;
    Return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I hook +commands, such as &amp;lt;tt&amp;gt;+zoom&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;+attack&amp;lt;/tt&amp;gt;?=&lt;br /&gt;
Unlike regular commands, &amp;lt;tt&amp;gt;+commands&amp;lt;/tt&amp;gt; are handled on the client's computer, then sent to the server in a more compressed fashion. This means [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()] cannot be used to hook &amp;lt;tt&amp;gt;+commands&amp;lt;/tt&amp;gt;. As of version 1.3, the recommended solution is to use the global forward [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=937 OnPlayerRunCmd()]. This forward is fired every time a player uses a movement button. To detect or block a &amp;lt;tt&amp;gt;+command&amp;lt;/tt&amp;gt;, you'll first have to find out its proper &amp;lt;tt&amp;gt;IN_&amp;lt;/tt&amp;gt; constant (see &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=47&amp;amp;file=&amp;amp; entity_prop_stocks.inc]&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Here's how to use it to block crouching when attacking:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:OnPlayerRunCmd(client, &amp;amp;buttons, &amp;amp;impulse, Float:vel[3], Float:angles[3], &amp;amp;weapon)&lt;br /&gt;
{&lt;br /&gt;
    // Check if the player is attacking (+attack)&lt;br /&gt;
    if ((buttons &amp;amp; IN_ATTACK) == IN_ATTACK)&lt;br /&gt;
    {&lt;br /&gt;
        // If so, block their crouching (+duck)&lt;br /&gt;
        buttons &amp;amp;= ~IN_DUCK;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // We must return Plugin_Continue to let the changes be processed.&lt;br /&gt;
    // Otherwise, we can return Plugin_Handled to block the commands&lt;br /&gt;
    return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I get rid of loose indentation warnings?=&lt;br /&gt;
&amp;lt;pre&amp;gt;myplugin.sp(#) : warning 217: loose indentation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Loose indentation warnings arise when indentation in your code is inconsistent. This usually means using both tabs and spaces as indentation. However, it can also mean a different amount of spaces or tabs are being used. Therefore, to correct it, use just one type of indentation. Because different editors have different settings for the size of tab stops, it is recommended you use 4 spaces to indent.&lt;br /&gt;
&lt;br /&gt;
Good:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    new myvar = 5;&lt;br /&gt;
    if (myvar == (2 + 3))&lt;br /&gt;
        PrintToServer(&amp;quot;myvar is %d&amp;quot;, myvar);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bad:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	new myvar = 5;&lt;br /&gt;
    if (myvar == (2 + 3))&lt;br /&gt;
		PrintToServer(&amp;quot;myvar is %d&amp;quot;, myvar);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I get rid of tag mismatch warnings?=&lt;br /&gt;
Though every variable in SourcePawn is one cell (4 bytes), with the exception of strings, there are many different ways to interpret what's inside a cell. To signify a cell's contents, tags are used. The most common are &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; (the default tag: a vanilla cell. This tag is implied when no other tag is specified.), &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;. See [[Introduction to SourcePawn#Variables_2]] for more information.&lt;br /&gt;
&lt;br /&gt;
Functions wear these tags on their parameters so you can tell what needs to be passed to the function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function calls for '''&amp;lt;tt&amp;gt;entity&amp;lt;/tt&amp;gt;''', a cell with the implied tag '''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''; '''&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;''', with the developer-defined tag '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;'''''; '''&amp;lt;tt&amp;gt;prop&amp;lt;/tt&amp;gt;''', with the built-in tag '''''&amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;'''''; and '''&amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;''', with the built-in tag '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''.&lt;br /&gt;
To call this function, then, you must pass values with the specified tags. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;SetEntPropFloat(1234, Prop_Send, &amp;quot;m_fNumber&amp;quot;, 1.0);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This calls the function correctly: &amp;lt;tt&amp;gt;1234&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''), &amp;lt;tt&amp;gt;Prop_Send&amp;lt;/tt&amp;gt; is a variable defined in the enum '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''' in [http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=4&amp;amp;file=&amp;amp; entity.inc], &amp;lt;tt&amp;gt;&amp;quot;m_fNumber&amp;quot;&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;''''', and &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''. For a nonexample:&lt;br /&gt;
&amp;lt;pawn&amp;gt;SetEntPropFloat(1234.0, 1, &amp;quot;m_fNumber&amp;quot;, 1337);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is incorrect! &amp;lt;tt&amp;gt;1234.0&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;''''' that should be a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''); &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;''''') that should be a '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;'''''; and &amp;lt;tt&amp;gt;1337&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;''''') that should be a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''. This call will generate a tag mismatch warning. To correct it, simply use a value with the correct tag. Most of the time, tags that are not built-in (such as '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''') can be found in the same file where a function uses them (you can find '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''' in [http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=4&amp;amp;file=&amp;amp; entity.inc]).&lt;br /&gt;
&lt;br /&gt;
=How do I add color to my messages?=&lt;br /&gt;
Though the actual colors will vary depending on the mod, you can add color to any chat message using the characters &amp;lt;tt&amp;gt;0x01&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;0x08&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChatAll (&amp;quot;\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example output from Left 4 Dead:&lt;br /&gt;
&lt;br /&gt;
[[Image:Left_4_Dead_Colors.png]]&lt;br /&gt;
&lt;br /&gt;
With a little experimenting, you can learn the colors for a mod. However, the meaning behind the colors is generally as follows:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x01&amp;lt;/tt&amp;gt; = Normal color&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x02&amp;lt;/tt&amp;gt; = Use team color to the end of a player's name. When used, it can be the only color used, and it must be at the start of the message.&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x03&amp;lt;/tt&amp;gt; = Team color&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x04&amp;lt;/tt&amp;gt; = Location color&lt;br /&gt;
&lt;br /&gt;
This data comes from Counter-Strike: Source.&lt;br /&gt;
&lt;br /&gt;
For CS:GO, here are some colors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(&amp;quot;\x011\x022\x033\x044\x055\x066\x077\x088\x099\x0AA\x0BB\x0CC\x0DD\x0EE\x0FF&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, to use players' team colors, you must use UserMessages, because there is no way for the current SourceMod functions to know which team color to use. Here's an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hBf;&lt;br /&gt;
hBf = StartMessageOne(&amp;quot;SayText2&amp;quot;, player_to); // To send the message to all players, use StartMessageAll(&amp;quot;SayText2&amp;quot;);&lt;br /&gt;
if (hBf != INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
    BfWriteByte(hBf, player_from); &lt;br /&gt;
    BfWriteByte(hBf, 0); &lt;br /&gt;
    BfWriteString(hBf, &amp;quot;&amp;lt;\x03player_from team color\x01&amp;gt; My message&amp;quot;);&lt;br /&gt;
    EndMessage();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;player_to&amp;lt;/tt&amp;gt; is the client index to send the message to (or use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=132&amp;amp; StartMessageAll()] instead of [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=133&amp;amp; StartMessageOne()] to send the message to all players). &amp;lt;tt&amp;gt;player_from&amp;lt;/tt&amp;gt; is the client index of the player whose team color will be utilized in the message. The message will now look like this (assuming &amp;lt;tt&amp;gt;player_from&amp;lt;/tt&amp;gt; is on the RED team):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#AA0&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#F00&amp;quot;&amp;gt;player_from team color&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#AA0&amp;quot;&amp;gt;&amp;amp;gt; My message&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's another catch, however: this is only known to work in CS:S and TF2. For other mods, your mileage may vary.&lt;br /&gt;
&lt;br /&gt;
==Color Libraries==&lt;br /&gt;
There are a few libraries that can handle colors for you, so you don't have to muck with UserMessages:&lt;br /&gt;
&lt;br /&gt;
===exvel's Colors===&lt;br /&gt;
This is a simple include file, allowing easy control over chat coloring. You can grab it [http://forums.alliedmods.net/showthread.php?t=96831 on the forums].  Instead of hex codes, colors are denoted with tags, such as &amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{default}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{green}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, or &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{blue}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Here's some example usage. Note that this code assumes client 1 is in game and on the &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU&amp;lt;/span&amp;gt; team:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;colors&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    CPrintToChatAll(&amp;quot;{green}Hello {red}World! {default}Test 1 concluded.&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    new client_on_blu_team = 1;&lt;br /&gt;
    CPrintToChatAllEx(client_on_blu_team, &amp;quot;{teamcolor}BLU team {default}says {green}hi!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;Hello &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #F00;&amp;quot;&amp;gt;World! &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;Test 1 concluded.&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU team &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;says &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;hi!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that to use a team color, there needs to be at least one player on that team. Otherwise, it will default to &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{green}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===SMLib===&lt;br /&gt;
[http://forums.alliedmods.net/showthread.php?p=1398699 SMLib] is a huge collection of stock functions to keep plug-in developers from reinventing the wheel. It includes a [http://forums.alliedmods.net/showthread.php?p=1398702#post1398702 colors API] very similar to [[#exvel's Colors|exvel's]]. The benefits of SMLib are it supports shorthand color names, such as &amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{N}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt; and &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{G}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, and all colors are supported in its &amp;lt;tt&amp;gt;Client_PrintToChat()&amp;lt;/tt&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
Here's how to print the same thing as the above example with SMLib. Note that this code also assumes client 1 is in game and on the &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU&amp;lt;/span&amp;gt; team:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;smlib&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    Client_PrintToChatAll(&amp;quot;{G}Hello {R}World! {N}Test 1 concluded.&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    new client_on_blu_team = 1;&lt;br /&gt;
    Client_PrintToChatAll(client_on_blu_team, &amp;quot;{T}BLU team {N}says {G}hi!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;Hello &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #F00;&amp;quot;&amp;gt;World! &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;Test 1 concluded.&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU team &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;says &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;hi!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Why do I get an &amp;quot;unknown symbol&amp;quot; error when using an SDKTools native?=&lt;br /&gt;
None of SourceMod's or SDKTools's functions are built into SourcePawn. Therefore, every time you use one of their functions, SourcePawn needs to know how to call the function. Normally, this is done using includes. Just like you would #include &amp;lt;sourcemod&amp;gt; to use SourceMod's functions, you need to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
to use an SDKTools native.&lt;br /&gt;
&lt;br /&gt;
=Why is Source telling me my command is an &amp;quot;Unknown command&amp;quot;?=&lt;br /&gt;
This is because you're not returning &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; in your callback. If you don't, SourceMod believes you didn't want the Source Engine to know the command was registered, and it handles it so.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:MyCommand(client, args)&lt;br /&gt;
{&lt;br /&gt;
    // Do something...&lt;br /&gt;
    &lt;br /&gt;
    return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;/div&gt;</summary>
		<author><name>TnTSCS</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=9061</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=9061"/>
		<updated>2013-09-13T16:34:16Z</updated>

		<summary type="html">&lt;p&gt;TnTSCS: /* Simple Values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
someFunction()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		numPrinted = 0;&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example without using handles is to use either UserID or ClientSerial (which is unique to each player):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(15.0, WelcomePlayer, GetClientSerial(client)) // You could also use GetClientUserId(client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:serial)&lt;br /&gt;
{&lt;br /&gt;
	new client = GetClientFromSerial(serial) // Validate the client serial&lt;br /&gt;
	&lt;br /&gt;
	if (client == 0) // The serial is no longer valid, the player must have disconnected&lt;br /&gt;
	{&lt;br /&gt;
		return Plugin_Continue&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
If you want to close or cancel a timer when a client disconnects, then use the first example with handles.&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking or hibernating), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>TnTSCS</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=9060</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=9060"/>
		<updated>2013-09-13T16:20:36Z</updated>

		<summary type="html">&lt;p&gt;TnTSCS: /* Accuracy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
someFunction()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		numPrinted = 0;&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking or hibernating), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>TnTSCS</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Upgrading_SourceMod&amp;diff=8621</id>
		<title>Upgrading SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Upgrading_SourceMod&amp;diff=8621"/>
		<updated>2012-08-11T16:48:30Z</updated>

		<summary type="html">&lt;p&gt;TnTSCS: Added note to shut down game server before updating&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When upgrading SourceMod, backwards compatibility is guaranteed except in rare cases.  To completely upgrade, you should:&lt;br /&gt;
&lt;br /&gt;
*Ensure your game server is completely stopped and not running as you cannot update some files while they are still in use.&lt;br /&gt;
*If you are upgrading to a stable release (not a nightly build), check its release notes for any specific instructions.&lt;br /&gt;
*Upgrade all &amp;lt;tt&amp;gt;.so&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;.dll&amp;lt;/tt&amp;gt; binaries in the following folders:&lt;br /&gt;
**&amp;lt;tt&amp;gt;sourcemod/bin&amp;lt;/tt&amp;gt;&lt;br /&gt;
**&amp;lt;tt&amp;gt;sourcemod/extensions&amp;lt;/tt&amp;gt;&lt;br /&gt;
*Upgrade all of the &amp;lt;tt&amp;gt;.txt&amp;lt;/tt&amp;gt; files in the &amp;lt;tt&amp;gt;sourcemod/gamedata&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
*Upgrade all of the &amp;lt;tt&amp;gt;.txt&amp;lt;/tt&amp;gt; files in the &amp;lt;tt&amp;gt;sourcemod/translations&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
*Upgrade all of the default &amp;lt;tt&amp;gt;.smx&amp;lt;/tt&amp;gt; binaries in the &amp;lt;tt&amp;gt;sourcemod/plugins&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
*Read the release notes to see if there were any configuration files that got new features.  If so, you should look and see if you want to tweak those new settings.  You may want to use a program such as [http://www.scootersoftware.com/ Beyond Compare] or [http://winmerge.org/ WinMerge].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If a plugin stops working due to a SourceMod upgrade, file a bug report and the development team will assess the situation.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' It is extremely important to update all &amp;lt;tt&amp;gt;gamedata&amp;lt;/tt&amp;gt; files, as those specify how SourceMod interacts with mod-specific properties.  &lt;br /&gt;
&lt;br /&gt;
'''Note:''' As of SourceMod 1.2.2, the &amp;quot;auto&amp;quot; folders for SourceMod extensions are no longer used by default. Third party extensions, however, may still use them.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If you update your base SourceMod plugins, you must update your translation files (and vice versa).  If you absolutely don't want to update your SourceMod base plugins, you should at least update the &amp;lt;tt&amp;gt;core.phrases.txt&amp;lt;/tt&amp;gt; translation file.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You only need to update the .inc files if you are a plugin developer.  If you do update .inc files, you must update the compiler (spcomp.exe for Windows, spcomp for Linux) as well.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>TnTSCS</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=8618</id>
		<title>Commands (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=8618"/>
		<updated>2012-08-03T01:30:52Z</updated>

		<summary type="html">&lt;p&gt;TnTSCS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[SourceMod]] allows you to create console commands similar to [[AMX Mod X]].  There are two main types of console commands:&lt;br /&gt;
*'''Server Commands''' - Fired from one of the following input methods:&lt;br /&gt;
**the server console itself&lt;br /&gt;
**the remote console (RCON)&lt;br /&gt;
**the ServerCommand() function, either from SourceMod or the [[Half-Life 2]] engine&lt;br /&gt;
*'''Console Commands''' - Fired from one of the following input methods:&lt;br /&gt;
**a client's console&lt;br /&gt;
**any of the server command input methods&lt;br /&gt;
&lt;br /&gt;
For server commands, there is no client index.  For console/client commands, there is a client index, but it may be 0 to indicate that the command is from the server.&lt;br /&gt;
&lt;br /&gt;
Note that button-bound &amp;quot;commands,&amp;quot; such as +attack and +duck, are not actually console commands.  They are a separate command stream sent over the network, as they need to be tied to a specific frame.  &lt;br /&gt;
&lt;br /&gt;
=Server Commands=&lt;br /&gt;
As noted above, server commands are fired through the server console, whether remote, local, or through the Source engine.  There is no client index associated with a server command.  &lt;br /&gt;
&lt;br /&gt;
Server commands are registered through the &amp;lt;tt&amp;gt;RegServerCmd()&amp;lt;/tt&amp;gt; function defined in &amp;lt;tt&amp;gt;console.inc&amp;lt;/tt&amp;gt;.  When registering a server command, you may be hooking an already existing command, and thus the return value is important.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; - The original server command will be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; - The original server command will not be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; - The original server command will not be processed, if there was one.  Additionally, no further hooks will be called for this command until it is fired again.&lt;br /&gt;
&lt;br /&gt;
==Adding Server Commands==&lt;br /&gt;
Let's say we want to add a test command to show how Half-Life 2 breaks down command arguments.  A possible implementation might be&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blocking Server Commands==&lt;br /&gt;
Let's say we wanted to disable the &amp;quot;kickid&amp;quot; command on the server.  There's no real good reason to do this, but for example's sake:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;kickid&amp;quot;, Command_KickId)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kickid(args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Console Commands=&lt;br /&gt;
Unlike server commands, console commands can be triggered by either the server or the client, so the callback function receives a client index as well as the argument count.  If the server fired the command, the client index will be 0.  &lt;br /&gt;
&lt;br /&gt;
When returning the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; from the callback, the following effects will happen:&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will still be processed.  If there was no original functionality, the client will receive &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will be blocked.  If there was no functionality originally, this prevents clients from seeing &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;: Same as &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;, except that this will be the last hook called.&lt;br /&gt;
&lt;br /&gt;
Note that, unlike AMX Mod X, SourceMod does not allow you to register command filters.  I.e., there is no equivalent to this notation:&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_clcmd(&amp;quot;say /ff&amp;quot;, &amp;quot;Command_SayFF&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This notation was removed to make our internal code simpler and faster.  Writing the same functionality is easy, and demonstrated below.&lt;br /&gt;
&lt;br /&gt;
==Adding Commands==&lt;br /&gt;
Adding client commands is very simple.  Let's port our earlier testing command to display information about the client as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	if (client)&lt;br /&gt;
	{&lt;br /&gt;
		new String:name[32]&lt;br /&gt;
		GetClientName(client, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Command from client: %s&amp;quot;, name);&lt;br /&gt;
	} else {&lt;br /&gt;
		PrintToServer(&amp;quot;Command from server.&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hooking Commands==&lt;br /&gt;
A common example is hooking the say command.  Let's say we want to tell players whether FF is enabled when they say '/ff' in game.  &lt;br /&gt;
&lt;br /&gt;
Before we implement this, a common point of confusion with the 'say' command is that Half-Life 2 (and Half-Life 1), by default, send it with the text in one big quoted string.  This means if you say &amp;quot;I like hot dogs,&amp;quot; your command will be broken down as such:&lt;br /&gt;
*Argument string: &amp;quot;I like hot dogs&amp;quot;&lt;br /&gt;
*Argument count: 1&lt;br /&gt;
*Argument #1: I like hot dogs&lt;br /&gt;
&lt;br /&gt;
However, if a player types this in their console: &amp;lt;tt&amp;gt;say I like yams&amp;lt;/tt&amp;gt;, it will be broken up as:&lt;br /&gt;
*Argument string: I like yams&lt;br /&gt;
*Argument count: 3&lt;br /&gt;
*Argument #1: I&lt;br /&gt;
*Argument #2: like&lt;br /&gt;
*Argument #3: yams&lt;br /&gt;
&lt;br /&gt;
Thus, to take into account both of these situations, we are going to use &amp;lt;tt&amp;gt;GetCmdArgString&amp;lt;/tt&amp;gt; and manually parse the input.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:ff = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say&amp;quot;)&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say2&amp;quot;)&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say_team&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	ff = FindConVar(&amp;quot;mp_friendlyfire&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Say(client, const String:command[], argc)&lt;br /&gt;
{&lt;br /&gt;
	decl String:text[192]&lt;br /&gt;
	new startidx = 0&lt;br /&gt;
	if (GetCmdArgString(text, sizeof(text)) &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		return Plugin_Continue&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (text[strlen(text)-1] == '&amp;quot;')&lt;br /&gt;
	{&lt;br /&gt;
		text[strlen(text)-1] = '\0'&lt;br /&gt;
		startidx = 1&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (strcmp(command, &amp;quot;say2&amp;quot;, false) == 0)&lt;br /&gt;
		startidx += 4&lt;br /&gt;
&lt;br /&gt;
	if (strcmp(text[startidx], &amp;quot;ff&amp;quot;, false) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		if (ff != INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			if (GetConVarBool(ff))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToChat(client, &amp;quot;Friendly fire is enabled.&amp;quot;)&lt;br /&gt;
			} else {&lt;br /&gt;
				PrintToChat(client, &amp;quot;Friendly fire is disabled.&amp;quot;)&lt;br /&gt;
			}&lt;br /&gt;
			/* Block the client's messsage from broadcasting */&lt;br /&gt;
			return Plugin_Handled&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Let say continue normally */&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating Admin Commands==&lt;br /&gt;
Let's create a simple admin command which kicks another player by their full name.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;admin_kick&amp;quot;,&lt;br /&gt;
		Command_Kick,&lt;br /&gt;
		ADMFLAG_KICK,&lt;br /&gt;
		&amp;quot;Kicks a player by name&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	for (new i=1; i&amp;lt;=MaxClients; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target));&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Immunity==&lt;br /&gt;
In our previous example, we did not take immunity into account.  Immunity is a much more complex system in SourceMod than it was in AMX Mod X, and there is no simple flag to denote its permissions.  Instead, two functions are provided:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanAdminTarget&amp;lt;/tt&amp;gt;: Tests raw AdminId values for immunity.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanUserTarget&amp;lt;/tt&amp;gt;: Tests in-game clients for immunity.&lt;br /&gt;
&lt;br /&gt;
While immunity is generally tested ''player versus player'', it is possible you might want to check for immunity and not have a targetting client.  While there is no convenience function for this yet, a good idea might be to check for either ''default'' or ''global'' immunity on the player's groups (these can be user-defined for non-player targeted scenarios).&lt;br /&gt;
&lt;br /&gt;
When checking for immunity, the following heuristics are performed in this exact order:&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;If the targeting AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targeting admin has &amp;lt;tt&amp;gt;Admin_Root&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;ADMFLAG_ROOT&amp;lt;/tt&amp;gt;), targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has global immunity, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has default immunity, and the targeting admin belongs to no groups, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has specific immunity from the targeting admin via group immunities, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If no conclusion is reached via the previous steps, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, how can we adapt our function about to use immunity?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	for (new i=1; i&amp;lt;=MaxClients; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (!CanUserTarget(client, target))&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;You cannot target this client.&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target))&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Client-Only Commands=&lt;br /&gt;
SourceMod exposes a forward that is called whenever a client executes any command string in their console, called &amp;lt;tt&amp;gt;OnClientCommand&amp;lt;/tt&amp;gt;.  An example of this looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:OnClientCommand(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:cmd[16]&lt;br /&gt;
	GetCmdArg(0, cmd, sizeof(cmd));	/* Get command name */&lt;br /&gt;
&lt;br /&gt;
	if (StrEqual(cmd, &amp;quot;test_command&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		/* Got the client command! Block it... */&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that not everything a client sends will be available through this command.  Command registered via external sources in C++ may not be available, especially if they are created via &amp;lt;tt&amp;gt;CON_COMMAND&amp;lt;/tt&amp;gt; in the game mod itself.  For example, &amp;quot;say&amp;quot; is usually implemented this way, because it can be used by both clients and the server, and thus it does not channel through this forward.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Chat Triggers=&lt;br /&gt;
SourceMod will automatically create chat triggers for every command you make (as of revision 900).  For example, if you create a console command called &amp;quot;sm_megaslap,&amp;quot; administrators will be able to type any of the following commands in &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;say_team&amp;lt;/tt&amp;gt; message modes:&lt;br /&gt;
&amp;lt;pre&amp;gt;!sm_megaslap&lt;br /&gt;
!megaslap&lt;br /&gt;
/sm_megaslap&lt;br /&gt;
/megaslap&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod then executes this command and its arguments as if it came from the client console.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt;&amp;quot; is the default ''public'' trigger (&amp;lt;tt&amp;gt;PublicChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be displayed to all clients as normal.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;&amp;quot; is the default ''silent'' trigger (&amp;lt;tt&amp;gt;SilentChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be blocked from being displayed.&lt;br /&gt;
&lt;br /&gt;
SourceMod will only execute commands registered with &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;RegAdminCmd&amp;lt;/tt&amp;gt;, and only if those commands are not already provided by Half-Life 2 or the game mod.  If the command is prefixed with &amp;quot;sm_&amp;quot; then the &amp;quot;sm_&amp;quot; can be omitted from the chat trigger.&lt;br /&gt;
&lt;br /&gt;
Console commands which wish to support usage as a chat trigger should not use &amp;lt;tt&amp;gt;PrintTo*&amp;lt;/tt&amp;gt; natives.  Instead, they should use &amp;lt;tt&amp;gt;ReplyToCommand()&amp;lt;/tt&amp;gt;, which will automatically print your message either as a chat message or to the client's console, depending on the source of the command.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>TnTSCS</name></author>
		
	</entry>
</feed>