<?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=Xerox8521</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=Xerox8521"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Xerox8521"/>
	<updated>2026-05-08T15:44:20Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11270</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11270"/>
		<updated>2022-02-02T18:13:22Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Removed events that are not called by the game.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_feed ===&lt;br /&gt;
{{qnotice|Whenever the player feed is updated. This is also called whenever someone becomes infected by a player}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_feed|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died or got infected}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed or caused the infection}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|bool|death|true if the player died}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_spawn ===&lt;br /&gt;
{{qnotice|When a player spawns}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_spawn|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_exploded ===&lt;br /&gt;
{{qnotice|When a player explodes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_exploded|string}}&lt;br /&gt;
{{hl2msg|float|x|X Position of the player}}&lt;br /&gt;
{{hl2msg|float|y|Y Position of the player}}&lt;br /&gt;
{{hl2msg|float|z|Z Position of the player}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|short|userid|player who left}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound ===&lt;br /&gt;
{{qnotice|Called when a specific sound is played. Eg. Round Start, Round End, Survivor Escapes etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound|string}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{hl2msg|short|teamid|(optional) If specified, it will only send to clients within a specific team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound_player ===&lt;br /&gt;
{{qnotice|Called when a specific sound to a player is played. Eg. Using an Inoculator, Flashlight, Panic etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound_player|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index concerned by this sound}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song|string}}&lt;br /&gt;
{{hl2msg|string|song|File path for the song}}&lt;br /&gt;
{{hl2msg|string|title|Custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|short|entindex|player who's arm model got changed}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== reset_arms ===&lt;br /&gt;
{{qnotice|Called when player has fully turned into a zombie}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|reset_arms|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entindex of the player}}&lt;br /&gt;
{{hl2msg|bool|infected|Whether to use the infected model or not. Seems to be always true}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== discord_callstatusupdate ===&lt;br /&gt;
{{qnotice|Send an Update to Discord RPC}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|discord_callstatusupdate|string}}&lt;br /&gt;
{{hl2msg|string|hostname|Server Hostname}}&lt;br /&gt;
{{hl2msg|string|gamemode|Gamemode}}&lt;br /&gt;
{{hl2msg|string|party_id|}}&lt;br /&gt;
{{hl2msg|string|party_port|Server Port?}}&lt;br /&gt;
{{hl2msg|string|party_size|Player count currently playing}}&lt;br /&gt;
{{hl2msg|string|party_max|How many players can join}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== endslate ===&lt;br /&gt;
{{qnotice|Called when the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|endslate|string}}&lt;br /&gt;
{{hl2msg|string|win_text|Who won?}}&lt;br /&gt;
{{hl2msg|string|timespent|Time spent on the round}}&lt;br /&gt;
{{hl2msg|string|gamemode|Current Gamemode}}&lt;br /&gt;
{{hl2msg|string|map|Current Map (If official, it shows the title of the map)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote has started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|maxargs|Amount of arguments for the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|float|time|Duration of the vote?}}&lt;br /&gt;
{{hl2msg|float|time_real|Time when the vote started?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_update ===&lt;br /&gt;
{{qnotice|Called when a vote updates}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_update|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|byte|result|}}&lt;br /&gt;
{{hl2msg|byte|maxargs|}}&lt;br /&gt;
{{hl2msg|byte|option0|}}&lt;br /&gt;
{{hl2msg|byte|option1|}}&lt;br /&gt;
{{hl2msg|byte|option2|}}&lt;br /&gt;
{{hl2msg|byte|option3|}}&lt;br /&gt;
{{hl2msg|byte|option4|}}&lt;br /&gt;
{{hl2msg|byte|option5|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|string|endmsg|}}&lt;br /&gt;
{{hl2msg|short|target|player who got targeted by the caller}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|short|state|}}&lt;br /&gt;
{{hl2msg|short|result|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== badge_reward_announce ===&lt;br /&gt;
{{qnotice|Called when the player is notified about receiving a badge reward.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|badge_reward_announce|string}}&lt;br /&gt;
{{hl2msg|long|entindex|player who got the badge reward}}&lt;br /&gt;
{{hl2msg|string|name|Name of the badge reward}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the badge reward}}&lt;br /&gt;
{{hl2msg|string|icon|Icon which is shown}}&lt;br /&gt;
{{hl2msg|long|reward|}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11269</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11269"/>
		<updated>2022-02-02T17:52:03Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Fixed argument name in badge_reward_announce&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_feed ===&lt;br /&gt;
{{qnotice|Whenever the player feed is updated. This is also called whenever someone becomes infected by a player}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_feed|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died or got infected}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed or caused the infection}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|bool|death|true if the player died}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_spawn ===&lt;br /&gt;
{{qnotice|When a player spawns}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_spawn|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_exploded ===&lt;br /&gt;
{{qnotice|When a player explodes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_exploded|string}}&lt;br /&gt;
{{hl2msg|float|x|X Position of the player}}&lt;br /&gt;
{{hl2msg|float|y|Y Position of the player}}&lt;br /&gt;
{{hl2msg|float|z|Z Position of the player}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|short|userid|player who left}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound ===&lt;br /&gt;
{{qnotice|Called when a specific sound is played. Eg. Round Start, Round End, Survivor Escapes etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound|string}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{hl2msg|short|teamid|(optional) If specified, it will only send to clients within a specific team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound_player ===&lt;br /&gt;
{{qnotice|Called when a specific sound to a player is played. Eg. Using an Inoculator, Flashlight, Panic etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound_player|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index concerned by this sound}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song|string}}&lt;br /&gt;
{{hl2msg|string|song|File path for the song}}&lt;br /&gt;
{{hl2msg|string|title|Custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|short|entindex|player who's arm model got changed}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== reset_arms ===&lt;br /&gt;
{{qnotice|Called when player has fully turned into a zombie}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|reset_arms|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entindex of the player}}&lt;br /&gt;
{{hl2msg|bool|infected|Whether to use the infected model or not. Seems to be always true}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== discord_callstatusupdate ===&lt;br /&gt;
{{qnotice|Send an Update to Discord RPC}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|discord_callstatusupdate|string}}&lt;br /&gt;
{{hl2msg|string|hostname|Server Hostname}}&lt;br /&gt;
{{hl2msg|string|gamemode|Gamemode}}&lt;br /&gt;
{{hl2msg|string|party_id|}}&lt;br /&gt;
{{hl2msg|string|party_port|Server Port?}}&lt;br /&gt;
{{hl2msg|string|party_size|Player count currently playing}}&lt;br /&gt;
{{hl2msg|string|party_max|How many players can join}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== angelscript_callevent===&lt;br /&gt;
{{qnotice|When the AS calls the function CallEvent()}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|angelscript_callevent|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|short|typeid}}&lt;br /&gt;
{{hl2msg|string|msg}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== general_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|general_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who activated it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who needs the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint_success ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player succeeded}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group}}&lt;br /&gt;
{{hl2msg|short|enabled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== endslate ===&lt;br /&gt;
{{qnotice|Called when the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|endslate|string}}&lt;br /&gt;
{{hl2msg|string|win_text|Who won?}}&lt;br /&gt;
{{hl2msg|string|timespent|Time spent on the round}}&lt;br /&gt;
{{hl2msg|string|gamemode|Current Gamemode}}&lt;br /&gt;
{{hl2msg|string|map|Current Map (If official, it shows the title of the map)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote has started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|maxargs|Amount of arguments for the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|float|time|Duration of the vote?}}&lt;br /&gt;
{{hl2msg|float|time_real|Time when the vote started?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_update ===&lt;br /&gt;
{{qnotice|Called when a vote updates}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_update|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|byte|result|}}&lt;br /&gt;
{{hl2msg|byte|maxargs|}}&lt;br /&gt;
{{hl2msg|byte|option0|}}&lt;br /&gt;
{{hl2msg|byte|option1|}}&lt;br /&gt;
{{hl2msg|byte|option2|}}&lt;br /&gt;
{{hl2msg|byte|option3|}}&lt;br /&gt;
{{hl2msg|byte|option4|}}&lt;br /&gt;
{{hl2msg|byte|option5|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|string|endmsg|}}&lt;br /&gt;
{{hl2msg|short|target|player who got targeted by the caller}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|short|state|}}&lt;br /&gt;
{{hl2msg|short|result|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== badge_reward_announce ===&lt;br /&gt;
{{qnotice|Called when the player is notified about receiving a badge reward.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|badge_reward_announce|string}}&lt;br /&gt;
{{hl2msg|long|entindex|player who got the badge reward}}&lt;br /&gt;
{{hl2msg|string|name|Name of the badge reward}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the badge reward}}&lt;br /&gt;
{{hl2msg|string|icon|Icon which is shown}}&lt;br /&gt;
{{hl2msg|long|reward|}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11268</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=11268"/>
		<updated>2022-02-02T17:29:11Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated event information for 3.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_feed ===&lt;br /&gt;
{{qnotice|Whenever the player feed is updated. This is also called whenever someone becomes infected by a player}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_feed|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died or got infected}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed or caused the infection}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|bool|death|true if the player died}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_spawn ===&lt;br /&gt;
{{qnotice|When a player spawns}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_spawn|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_exploded ===&lt;br /&gt;
{{qnotice|When a player explodes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_exploded|string}}&lt;br /&gt;
{{hl2msg|float|x|X Position of the player}}&lt;br /&gt;
{{hl2msg|float|y|Y Position of the player}}&lt;br /&gt;
{{hl2msg|float|z|Z Position of the player}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|short|userid|player who left}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound ===&lt;br /&gt;
{{qnotice|Called when a specific sound is played. Eg. Round Start, Round End, Survivor Escapes etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound|string}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{hl2msg|short|teamid|(optional) If specified, it will only send to clients within a specific team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== clientsound_player ===&lt;br /&gt;
{{qnotice|Called when a specific sound to a player is played. Eg. Using an Inoculator, Flashlight, Panic etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|clientsound_player|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entity index concerned by this sound}}&lt;br /&gt;
{{hl2msg|string|sound|File path for the song, or the SoundScript}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song|string}}&lt;br /&gt;
{{hl2msg|string|song|File path for the song}}&lt;br /&gt;
{{hl2msg|string|title|Custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|short|entindex|player who's arm model got changed}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== reset_arms ===&lt;br /&gt;
{{qnotice|Called when player has fully turned into a zombie}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|reset_arms|string}}&lt;br /&gt;
{{hl2msg|short|entindex|Entindex of the player}}&lt;br /&gt;
{{hl2msg|bool|infected|Whether to use the infected model or not. Seems to be always true}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== discord_callstatusupdate ===&lt;br /&gt;
{{qnotice|Send an Update to Discord RPC}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|discord_callstatusupdate|string}}&lt;br /&gt;
{{hl2msg|string|hostname|Server Hostname}}&lt;br /&gt;
{{hl2msg|string|gamemode|Gamemode}}&lt;br /&gt;
{{hl2msg|string|party_id|}}&lt;br /&gt;
{{hl2msg|string|party_port|Server Port?}}&lt;br /&gt;
{{hl2msg|string|party_size|Player count currently playing}}&lt;br /&gt;
{{hl2msg|string|party_max|How many players can join}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== angelscript_callevent===&lt;br /&gt;
{{qnotice|When the AS calls the function CallEvent()}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|angelscript_callevent|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|short|typeid}}&lt;br /&gt;
{{hl2msg|string|msg}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== general_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|general_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who activated it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who needs the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint_success ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player succeeded}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group}}&lt;br /&gt;
{{hl2msg|short|enabled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== endslate ===&lt;br /&gt;
{{qnotice|Called when the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|endslate|string}}&lt;br /&gt;
{{hl2msg|string|win_text|Who won?}}&lt;br /&gt;
{{hl2msg|string|timespent|Time spent on the round}}&lt;br /&gt;
{{hl2msg|string|gamemode|Current Gamemode}}&lt;br /&gt;
{{hl2msg|string|map|Current Map (If official, it shows the title of the map)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote has started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|maxargs|Amount of arguments for the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|float|time|Duration of the vote?}}&lt;br /&gt;
{{hl2msg|float|time_real|Time when the vote started?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_update ===&lt;br /&gt;
{{qnotice|Called when a vote updates}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_update|string}}&lt;br /&gt;
{{hl2msg|string|title|Title of the vote}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the vote}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|byte|result|}}&lt;br /&gt;
{{hl2msg|byte|maxargs|}}&lt;br /&gt;
{{hl2msg|byte|option0|}}&lt;br /&gt;
{{hl2msg|byte|option1|}}&lt;br /&gt;
{{hl2msg|byte|option2|}}&lt;br /&gt;
{{hl2msg|byte|option3|}}&lt;br /&gt;
{{hl2msg|byte|option4|}}&lt;br /&gt;
{{hl2msg|byte|option5|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|string|arg|Argument(s) of the vote}}&lt;br /&gt;
{{hl2msg|string|endmsg|}}&lt;br /&gt;
{{hl2msg|short|target|player who got targeted by the caller}}&lt;br /&gt;
{{hl2msg|short|caller|player who started the vote}}&lt;br /&gt;
{{hl2msg|short|state|}}&lt;br /&gt;
{{hl2msg|short|result|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== badge_reward_announce ===&lt;br /&gt;
{{qnotice|Called when the player is notified about receiving a badge reward.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|badge_reward_announce|string}}&lt;br /&gt;
{{hl2msg|long|entindex|player who got the badge reward}}&lt;br /&gt;
{{hl2msg|string|name|Name of the badge reward}}&lt;br /&gt;
{{hl2msg|string|desc|Description of the badge reward}}&lt;br /&gt;
{{hl2msg|string|icon|Icon which is shown}}&lt;br /&gt;
{{hl2msg|long|state|}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=10748</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=10748"/>
		<updated>2019-04-10T11:54:31Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Fixed link to Pawn Lang Guide pdf file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.  If you're using SourcePawn (for SourceMod), there is actually a second type: String.  In a String, letters are stored as separate bytes... essentially having 4 characters stored in every cell.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number.&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
&lt;br /&gt;
//So this is valid:&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[33] = {true, ...}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&lt;br /&gt;
// If you're using SourcePawn, do this instead:&lt;br /&gt;
new String:myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|In SourcePawn, copy was renamed to strcopy and avoids the issue with copy noted below.}}&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asciitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
b = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 7&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Multiple conditions are also possible in pawn:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an multiple switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 1, 2, 3:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 1 or 2 or 3&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 4, 5, 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 4 or 5 or6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7, 8, 9:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7 or 8 or 9&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that switch cases do not &amp;quot;fall-through.&amp;quot; If a case is true, no other cases are evaluated.&lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [2][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = HELLO&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: https://github.com/compuphase/pawn/blob/master/doc/Pawn_Language_Guide.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[https://github.com/compuphase/pawn/blob/master/doc/Pawn_Language_Guide.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=10747</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=10747"/>
		<updated>2019-04-10T11:53:48Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Fixed link to Pawn Lang Guide pdf file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.  If you're using SourcePawn (for SourceMod), there is actually a second type: String.  In a String, letters are stored as separate bytes... essentially having 4 characters stored in every cell.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number.&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
&lt;br /&gt;
//So this is valid:&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[33] = {true, ...}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&lt;br /&gt;
// If you're using SourcePawn, do this instead:&lt;br /&gt;
new String:myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|In SourcePawn, copy was renamed to strcopy and avoids the issue with copy noted below.}}&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asciitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
b = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 7&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Multiple conditions are also possible in pawn:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an multiple switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 1, 2, 3:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 1 or 2 or 3&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 4, 5, 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 4 or 5 or6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7, 8, 9:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7 or 8 or 9&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that switch cases do not &amp;quot;fall-through.&amp;quot; If a case is true, no other cases are evaluated.&lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [2][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = HELLO&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: https://github.com/compuphase/pawn/blob/master/doc/Pawn_Language_Guide.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/Pawn_Language_Guide.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=10614</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=10614"/>
		<updated>2018-09-05T14:14:22Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Replaced ServerCommand with KickClient&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 void 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(int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg[128];&lt;br /&gt;
	char 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 (int 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;
	return Plugin_Handled;&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 void 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(int 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;
*&amp;lt;tt&amp;gt;Plugin_Changed&amp;lt;/tt&amp;gt;: Inputs or outputs have been overridden with new values.&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 void 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(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg[128];&lt;br /&gt;
	char 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;
		PrintToServer(&amp;quot;Command from client: %N&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 (int 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;
	return Plugin_Handled;&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;
&amp;lt;pawn&amp;gt;ConVar ff = null;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&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 OnClientSayCommand(int client, const char[] command, const char[] sArgs)&lt;br /&gt;
{&lt;br /&gt;
	if (strcmp(sArgs, &amp;quot;ff&amp;quot;, false) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		if (ff != null)&lt;br /&gt;
		{&lt;br /&gt;
			if (ff.BoolValue)&lt;br /&gt;
			{&lt;br /&gt;
				PrintToChat(client, &amp;quot;Friendly fire is enabled.&amp;quot;);&lt;br /&gt;
			} &lt;br /&gt;
                        else &lt;br /&gt;
                        {&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;
Here we use the OnClientSayCommand forward where as &amp;lt;tt&amp;gt;command&amp;lt;/tt&amp;gt; contains the type (example: &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;say_team&amp;lt;/tt&amp;gt;) and &amp;lt;tt&amp;gt;sArgs&amp;lt;/tt&amp;gt; containing the users input&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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;admin_kick&amp;quot;, Command_Kick, ADMFLAG_KICK, &amp;quot;Kicks a player by name&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_Kick(int client, int 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;
	char name[32];&lt;br /&gt;
        int target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (int 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;
		char 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;
	KickClient(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(int client, int 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;
	char name[32];&lt;br /&gt;
        int target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (int 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;
		char 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;
	KickClient(target);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;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(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char 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. For example, if you create a console command called &amp;lt;tt&amp;gt;&amp;quot;sm_megaslap&amp;quot;&amp;lt;/tt&amp;gt;, 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=10613</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=10613"/>
		<updated>2018-09-05T14:13:38Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Replaced ServerCommand with KickClient&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 void 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(int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg[128];&lt;br /&gt;
	char 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 (int 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;
	return Plugin_Handled;&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 void 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(int 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;
*&amp;lt;tt&amp;gt;Plugin_Changed&amp;lt;/tt&amp;gt;: Inputs or outputs have been overridden with new values.&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 void 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(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg[128];&lt;br /&gt;
	char 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;
		PrintToServer(&amp;quot;Command from client: %N&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 (int 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;
	return Plugin_Handled;&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;
&amp;lt;pawn&amp;gt;ConVar ff = null;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&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 OnClientSayCommand(int client, const char[] command, const char[] sArgs)&lt;br /&gt;
{&lt;br /&gt;
	if (strcmp(sArgs, &amp;quot;ff&amp;quot;, false) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		if (ff != null)&lt;br /&gt;
		{&lt;br /&gt;
			if (ff.BoolValue)&lt;br /&gt;
			{&lt;br /&gt;
				PrintToChat(client, &amp;quot;Friendly fire is enabled.&amp;quot;);&lt;br /&gt;
			} &lt;br /&gt;
                        else &lt;br /&gt;
                        {&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;
Here we use the OnClientSayCommand forward where as &amp;lt;tt&amp;gt;command&amp;lt;/tt&amp;gt; contains the type (example: &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;say_team&amp;lt;/tt&amp;gt;) and &amp;lt;tt&amp;gt;sArgs&amp;lt;/tt&amp;gt; containing the users input&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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;admin_kick&amp;quot;, Command_Kick, ADMFLAG_KICK, &amp;quot;Kicks a player by name&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_Kick(int client, int 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;
	char name[32];&lt;br /&gt;
        int target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (int 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;
		char 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;
	KickClient(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(int client, int 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;
	char name[32];&lt;br /&gt;
        int target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (int 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;
		char 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;
=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(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char 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. For example, if you create a console command called &amp;lt;tt&amp;gt;&amp;quot;sm_megaslap&amp;quot;&amp;lt;/tt&amp;gt;, 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10535</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10535"/>
		<updated>2018-05-14T15:46:59Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* discord_callstatusupdate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|When a player dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zombie_lives ===&lt;br /&gt;
{{qnotice|Called when the zombie lives changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zombie_lives|string}}&lt;br /&gt;
{{hl2msg|byte|count|amount of zombie lives left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_play ===&lt;br /&gt;
{{qnotice|Called when a sound plays}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_play|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound file which played}}&lt;br /&gt;
{{hl2msg|short|entity|entity which the sound plays from}}&lt;br /&gt;
{{hl2msg|bool|fade|should the sound fade}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song_play|string}}&lt;br /&gt;
{{hl2msg|string|song|file path for the song}}&lt;br /&gt;
{{hl2msg|string|title|custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_as ===&lt;br /&gt;
{{qnotice|Called when a sound is played from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_as|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound being played}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== discord_callstatusupdate ===&lt;br /&gt;
{{qnotice|Send an Update to Discord RPC}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|discord_callstatusupdate|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|string|hostname|Server Hostname}}&lt;br /&gt;
{{hl2msg|string|serverip|Server IP}}&lt;br /&gt;
{{hl2msg|string|serverport|Server Port}}&lt;br /&gt;
{{hl2msg|string|model|Current Model of the client}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== angelscript_callevent===&lt;br /&gt;
{{qnotice|When the AS calls the function CallEvent()}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|angelscript_callevent|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|short|typeid}}&lt;br /&gt;
{{hl2msg|string|msg}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_begins===&lt;br /&gt;
{{qnotice|When the round begins}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_begins|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_win===&lt;br /&gt;
{{qnotice|When the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_win|string}}&lt;br /&gt;
{{hl2msg|string|mapname|name of the current map}}&lt;br /&gt;
{{hl2msg|bool|humanwin|true if survivors won}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_round_restart ===&lt;br /&gt;
{{qnotice|When one team won the round and players can select their team again}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_round_restart|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_washuman ===&lt;br /&gt;
{{qnotice|The player was a human player before we turned into zombie team (Only applies if there is no zombie lives left, or if the zombies won)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_washuman|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that turned into a zombie}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== zp_infected ===&lt;br /&gt;
{{qnotice|Calls whenever someone got infected}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_infected|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that got infected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_entitypickedup ===&lt;br /&gt;
{{qnotice|Calls whenever a button is pressed, or if an item is picked up}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_entitypickedup|string}}&lt;br /&gt;
{{hl2msg|string|entkey|name of the button that is pressed or entity that is picked up}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== general_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|general_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who activated it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who needs the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint_success ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player succeeded}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group}}&lt;br /&gt;
{{hl2msg|short|enabled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_start ===&lt;br /&gt;
{{qnotice|Called when the round has started (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_start|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_end ===&lt;br /&gt;
{{qnotice|Called when the round ends (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_end|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_text ===&lt;br /&gt;
{{qnotice|Called when AS sets the win text}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_text|string}}&lt;br /&gt;
{{hl2msg|string|txt}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_created ===&lt;br /&gt;
{{qnotice|Called when a generic vote has been created}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_created|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_clr ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_clr|string}}&lt;br /&gt;
{{hl2msg|string|option}}&lt;br /&gt;
{{hl2msg|long|red}}&lt;br /&gt;
{{hl2msg|long|green}}&lt;br /&gt;
{{hl2msg|long|blue}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|issue}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|initiator|entity id of the player who initiated the vote}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_changed ===&lt;br /&gt;
{{qnotice|Called when a vote changed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_changed|string}}&lt;br /&gt;
{{hl2msg|byte|vote_option1}}&lt;br /&gt;
{{hl2msg|byte|vote_option2}}&lt;br /&gt;
{{hl2msg|byte|vote_option3}}&lt;br /&gt;
{{hl2msg|byte|vote_option4}}&lt;br /&gt;
{{hl2msg|byte|vote_option5}}&lt;br /&gt;
{{hl2msg|byte|yesVotes}}&lt;br /&gt;
{{hl2msg|byte|noVotes}}&lt;br /&gt;
{{hl2msg|byte|potentialVotes}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_passed ===&lt;br /&gt;
{{qnotice|Called when a vote passed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|string|details}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_failed ===&lt;br /&gt;
{{qnotice|Called when a vote failed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== vote_cast ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_cast|string}}&lt;br /&gt;
{{hl2msg|byte|vote|yes/no vote}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of the voter}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10534</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10534"/>
		<updated>2018-05-14T15:44:55Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Added discord_callstatusupdate and fixed angelscript_callevent params&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|When a player dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zombie_lives ===&lt;br /&gt;
{{qnotice|Called when the zombie lives changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zombie_lives|string}}&lt;br /&gt;
{{hl2msg|byte|count|amount of zombie lives left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_play ===&lt;br /&gt;
{{qnotice|Called when a sound plays}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_play|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound file which played}}&lt;br /&gt;
{{hl2msg|short|entity|entity which the sound plays from}}&lt;br /&gt;
{{hl2msg|bool|fade|should the sound fade}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song_play|string}}&lt;br /&gt;
{{hl2msg|string|song|file path for the song}}&lt;br /&gt;
{{hl2msg|string|title|custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_as ===&lt;br /&gt;
{{qnotice|Called when a sound is played from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_as|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound being played}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== discord_callstatusupdate ===&lt;br /&gt;
{{qnotice|Send an Update to Discord RPC}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|discord_callstatusupdate|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|string|hostname}}&lt;br /&gt;
{{hl2msg|string|serverip}}&lt;br /&gt;
{{hl2msg|string|serverport}}&lt;br /&gt;
{{hl2msg|string|model}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== angelscript_callevent===&lt;br /&gt;
{{qnotice|When the AS calls the function CallEvent()}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|angelscript_callevent|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|short|typeid}}&lt;br /&gt;
{{hl2msg|string|msg}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_begins===&lt;br /&gt;
{{qnotice|When the round begins}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_begins|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_win===&lt;br /&gt;
{{qnotice|When the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_win|string}}&lt;br /&gt;
{{hl2msg|string|mapname|name of the current map}}&lt;br /&gt;
{{hl2msg|bool|humanwin|true if survivors won}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_round_restart ===&lt;br /&gt;
{{qnotice|When one team won the round and players can select their team again}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_round_restart|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_washuman ===&lt;br /&gt;
{{qnotice|The player was a human player before we turned into zombie team (Only applies if there is no zombie lives left, or if the zombies won)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_washuman|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that turned into a zombie}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== zp_infected ===&lt;br /&gt;
{{qnotice|Calls whenever someone got infected}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_infected|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that got infected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_entitypickedup ===&lt;br /&gt;
{{qnotice|Calls whenever a button is pressed, or if an item is picked up}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_entitypickedup|string}}&lt;br /&gt;
{{hl2msg|string|entkey|name of the button that is pressed or entity that is picked up}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== general_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|general_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who activated it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who needs the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint_success ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player succeeded}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group}}&lt;br /&gt;
{{hl2msg|short|enabled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_start ===&lt;br /&gt;
{{qnotice|Called when the round has started (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_start|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_end ===&lt;br /&gt;
{{qnotice|Called when the round ends (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_end|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_text ===&lt;br /&gt;
{{qnotice|Called when AS sets the win text}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_text|string}}&lt;br /&gt;
{{hl2msg|string|txt}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_created ===&lt;br /&gt;
{{qnotice|Called when a generic vote has been created}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_created|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_clr ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_clr|string}}&lt;br /&gt;
{{hl2msg|string|option}}&lt;br /&gt;
{{hl2msg|long|red}}&lt;br /&gt;
{{hl2msg|long|green}}&lt;br /&gt;
{{hl2msg|long|blue}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|issue}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|initiator|entity id of the player who initiated the vote}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_changed ===&lt;br /&gt;
{{qnotice|Called when a vote changed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_changed|string}}&lt;br /&gt;
{{hl2msg|byte|vote_option1}}&lt;br /&gt;
{{hl2msg|byte|vote_option2}}&lt;br /&gt;
{{hl2msg|byte|vote_option3}}&lt;br /&gt;
{{hl2msg|byte|vote_option4}}&lt;br /&gt;
{{hl2msg|byte|vote_option5}}&lt;br /&gt;
{{hl2msg|byte|yesVotes}}&lt;br /&gt;
{{hl2msg|byte|noVotes}}&lt;br /&gt;
{{hl2msg|byte|potentialVotes}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_passed ===&lt;br /&gt;
{{qnotice|Called when a vote passed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|string|details}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_failed ===&lt;br /&gt;
{{qnotice|Called when a vote failed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== vote_cast ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_cast|string}}&lt;br /&gt;
{{hl2msg|byte|vote|yes/no vote}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of the voter}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10492</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10492"/>
		<updated>2017-12-19T16:25:17Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Added and Updated all events for ZPS 3.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|When a player dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_disconnected ===&lt;br /&gt;
{{qnotice|When a player leaves the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_disconnected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that left}}&lt;br /&gt;
{{hl2msg|short|flag}}&lt;br /&gt;
{{hl2msg|string|reason|reason why the player left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== map_change ===&lt;br /&gt;
{{qnotice|Called when the map changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_change|string}}&lt;br /&gt;
{{hl2msg|string|map|name of the map that is being switched to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zombie_lives ===&lt;br /&gt;
{{qnotice|Called when the zombie lives changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zombie_lives|string}}&lt;br /&gt;
{{hl2msg|byte|count|amount of zombie lives left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_play ===&lt;br /&gt;
{{qnotice|Called when a sound plays}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_play|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound file which played}}&lt;br /&gt;
{{hl2msg|short|entity|entity which the sound plays from}}&lt;br /&gt;
{{hl2msg|bool|fade|should the sound fade}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== force_song ===&lt;br /&gt;
{{qnotice|Called when the logic_music entity changes the song}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|force_song_play|string}}&lt;br /&gt;
{{hl2msg|string|song|file path for the song}}&lt;br /&gt;
{{hl2msg|string|title|custom song title}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_as ===&lt;br /&gt;
{{qnotice|Called when a sound is played from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_as|string}}&lt;br /&gt;
{{hl2msg|string|sound|sound being played}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== armmodel_as ===&lt;br /&gt;
{{qnotice|Called when a new arm model is set from AngelScript}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|armmodel_as|string}}&lt;br /&gt;
{{hl2msg|string|model|arm model that should be used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spawned_player ===&lt;br /&gt;
{{qnotice|Called when player has spawned}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawned_player|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that spawned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== angelscript_callevent ===&lt;br /&gt;
{{qnotice|when AS calls the function CallEvent()}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|angelscript_callevent|string}}&lt;br /&gt;
{{hl2msg|short|clientid}}&lt;br /&gt;
{{hl2msg|string|hostname}}&lt;br /&gt;
{{hl2msg|string|serverip}}&lt;br /&gt;
{{hl2msg|string|serverport}}&lt;br /&gt;
{{hl2msg|string|model}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== cleanupmap ===&lt;br /&gt;
{{qnotice|when the server calls CleanUpMap(), it will tell the client todo the same for temp and client sided entities}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|cleanupmap|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_begins===&lt;br /&gt;
{{qnotice|When the round begins}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_begins|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_win===&lt;br /&gt;
{{qnotice|When the round ends}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_win|string}}&lt;br /&gt;
{{hl2msg|string|mapname|name of the current map}}&lt;br /&gt;
{{hl2msg|bool|humanwin|true if survivors won}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_round_restart ===&lt;br /&gt;
{{qnotice|When one team won the round and players can select their team again}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_round_restart|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the achievement}}&lt;br /&gt;
{{hl2msg|string|achid|achievement id}}&lt;br /&gt;
{{hl2msg|string|achtitle|title of the achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_washuman ===&lt;br /&gt;
{{qnotice|The player was a human player before we turned into zombie team (Only applies if there is no zombie lives left, or if the zombies won)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_washuman|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that turned into a zombie}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== zp_infected ===&lt;br /&gt;
{{qnotice|Calls whenever someone got infected}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_infected|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that got infected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zp_entitypickedup ===&lt;br /&gt;
{{qnotice|Calls whenever a button is pressed, or if an item is picked up}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zp_entitypickedup|string}}&lt;br /&gt;
{{hl2msg|string|entkey|name of the button that is pressed or entity that is picked up}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== general_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|general_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who activated it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player who needs the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== movement_hint_success ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|movement_hint_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|the player succeeded}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group}}&lt;br /&gt;
{{hl2msg|short|enabled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_tutor ===&lt;br /&gt;
{{qnotice|Called from the instructor tutorial}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_tutor|string}}&lt;br /&gt;
{{hl2msg|long|userid}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|string|strbind}}&lt;br /&gt;
{{hl2msg|string|strmsg}}&lt;br /&gt;
{{hl2msg|string|icon_onscreen}}&lt;br /&gt;
{{hl2msg|string|icon_offscreen}}&lt;br /&gt;
{{hl2msg|bool|nooffscreen}}&lt;br /&gt;
{{hl2msg|int|posx}}&lt;br /&gt;
{{hl2msg|int|posy}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_create ===&lt;br /&gt;
{{qnotice|create a hint using data supplied entirely by the server/map. Intended for hints to smooth playtests before content is ready to make the hint unneccessary. NOT INTENDED AS A SHIPPABLE CRUTCH}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_create|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|what to name the hint. For referencing it again later (e.g. a kill command for the hint instead of a timeout)}}&lt;br /&gt;
{{hl2msg|string|hint_replace_key|type name so that messages of the same type will replace each other}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|long|hint_instance|the hint instance}}&lt;br /&gt;
{{hl2msg|short|hint_activator_userid|userid id of the activator}}&lt;br /&gt;
{{hl2msg|short|hint_timeout|how long in seconds until the hint automatically times out, 0 means never}}&lt;br /&gt;
{{hl2msg|string|hint_icon_onscreen|the hint icon to use when the hint is onscreen. e.g. &amp;quot;icon_alert_red&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_icon_offscreen|the hint icon to use when the hint is offscreen. e.g. &amp;quot;icon_alert&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_activator_caption|the hint caption that only the activator sees e.g. &amp;quot;#YouPushedItGood&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|hint_color|the hint color in &amp;quot;r,g,b&amp;quot; format where each component is 0-255}}&lt;br /&gt;
{{hl2msg|float|hint_icon_offset|how far on the z axis to offset the hint from entity origin}}&lt;br /&gt;
{{hl2msg|float|hint_range|range before the hint is culled}}&lt;br /&gt;
{{hl2msg|long|hint_flags|hint flags}}&lt;br /&gt;
{{hl2msg|string|hint_binding|bindings to use when use_binding is the onscreen icon}}&lt;br /&gt;
{{hl2msg|bool|hint_allow_nodraw_target|if false, the hint will dissappear if the target entity is invisible}}&lt;br /&gt;
{{hl2msg|bool|hint_nooffscreen|if true, the hint will not show when outside the player view}}&lt;br /&gt;
{{hl2msg|bool|hint_forcecaption|if true, the hint caption will show even if the hint is occluded}}&lt;br /&gt;
{{hl2msg|bool|hint_local_player_only|if true, only the local player will see the hint}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_server_hint_stop ===&lt;br /&gt;
{{qnotice|destroys a server/map created hint}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_server_hint_stop|string}}&lt;br /&gt;
{{hl2msg|string|hint_name|The hint to stop. Will stop ALL hints with this name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== instructor_survivor_supply ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|instructor_survivor_supply|string}}&lt;br /&gt;
{{hl2msg|long|hint_player|entity id that the hint will display for}}&lt;br /&gt;
{{hl2msg|long|hint_target|entity id that the hint should display at}}&lt;br /&gt;
{{hl2msg|string|hint_caption|the hint caption. e.g. &amp;quot;#ThisIsDangerous&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_start ===&lt;br /&gt;
{{qnotice|Called when the round has started (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_start|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== logicrounds_end ===&lt;br /&gt;
{{qnotice|Called when the round ends (from logic_rounds)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|logicrounds_end|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== set_text ===&lt;br /&gt;
{{qnotice|Called when AS sets the win text}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_text|string}}&lt;br /&gt;
{{hl2msg|string|txt}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|Called when a vote has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_created ===&lt;br /&gt;
{{qnotice|Called when a generic vote has been created}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_created|string}}&lt;br /&gt;
{{hl2msg|None|None|None}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_generic_clr ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_generic_clr|string}}&lt;br /&gt;
{{hl2msg|string|option}}&lt;br /&gt;
{{hl2msg|long|red}}&lt;br /&gt;
{{hl2msg|long|green}}&lt;br /&gt;
{{hl2msg|long|blue}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|Called when a vote started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|issue}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|initiator|entity id of the player who initiated the vote}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_changed ===&lt;br /&gt;
{{qnotice|Called when a vote changed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_changed|string}}&lt;br /&gt;
{{hl2msg|byte|vote_option1}}&lt;br /&gt;
{{hl2msg|byte|vote_option2}}&lt;br /&gt;
{{hl2msg|byte|vote_option3}}&lt;br /&gt;
{{hl2msg|byte|vote_option4}}&lt;br /&gt;
{{hl2msg|byte|vote_option5}}&lt;br /&gt;
{{hl2msg|byte|yesVotes}}&lt;br /&gt;
{{hl2msg|byte|noVotes}}&lt;br /&gt;
{{hl2msg|byte|potentialVotes}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_passed ===&lt;br /&gt;
{{qnotice|Called when a vote passed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|string|details}}&lt;br /&gt;
{{hl2msg|string|param1}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_failed ===&lt;br /&gt;
{{qnotice|Called when a vote failed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== vote_cast ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_cast|string}}&lt;br /&gt;
{{hl2msg|byte|vote|yes/no vote}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of the voter}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10491</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10491"/>
		<updated>2017-12-19T14:19:32Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated for ZPS 3.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|When a player dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_connected ===&lt;br /&gt;
{{qnotice|When a player joins the server}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_connected|string}}&lt;br /&gt;
{{hl2msg|string|name|name of the player that connected}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_play ===&lt;br /&gt;
{{qnotice|Called when a sound plays}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_play|string}}&lt;br /&gt;
{{hl2msg|string|sound|Sound file which played}}&lt;br /&gt;
{{hl2msg|bool|fade}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_round_restart ===&lt;br /&gt;
{{qnotice|When one team won the round and players can select their team again}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_round_restart|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|byte|player}}&lt;br /&gt;
{{hl2msg|short|achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10490</id>
		<title>Zombie Panic! Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zombie_Panic!_Source_Events&amp;diff=10490"/>
		<updated>2017-12-19T14:16:34Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated for ZPS 3.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|When a player dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who died}}&lt;br /&gt;
{{hl2msg|short|attacker|player who killed}}&lt;br /&gt;
{{hl2msg|short|assistant|player who assisted the attacker}}&lt;br /&gt;
{{hl2msg|string|weapon|name of the weapon}}&lt;br /&gt;
{{hl2msg|bool|headshot|true if player died from headshot}}&lt;br /&gt;
{{hl2msg|short|dmgbits|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== zombie_death ===&lt;br /&gt;
{{qnotice|When a zombie dies}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zombie_death|string}}&lt;br /&gt;
{{hl2msg|byte|count}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ambient_play ===&lt;br /&gt;
{{qnotice|Called when a sound plays}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ambient_play|string}}&lt;br /&gt;
{{hl2msg|string|sound|Sound file which played}}&lt;br /&gt;
{{hl2msg|bool|fade}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_round_restart ===&lt;br /&gt;
{{qnotice|When one team won the round and players can select their team again}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_round_restart|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== gravity_change ===&lt;br /&gt;
{{qnotice|When the gravity changes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gravity_change|string}}&lt;br /&gt;
{{hl2msg|float|newgravity|New value after the change}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|byte|player}}&lt;br /&gt;
{{hl2msg|short|achievement}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|None}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|none|none}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10384</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=10384"/>
		<updated>2017-08-18T02:40:51Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated API Links from &amp;quot;old&amp;quot; to &amp;quot;new&amp;quot;&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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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;char&amp;lt;/tt&amp;gt;. See [[Introduction_to_SourcePawn_1.7#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 int SetEntPropFloat(int entity, PropType type, const char[] prop, float value, int element)&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;int&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;char&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;char&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;int&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;int&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;int&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;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 != null)&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 [https://sm.alliedmods.net/new-api/usermessages/StartMessageAll StartMessageAll()] instead of [https://sm.alliedmods.net/new-api/usermessages/StartMessageOne 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 void 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;
    int 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 void 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;
    int 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(int client, int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Left_4_Dead_2_Events&amp;diff=10284</id>
		<title>Left 4 Dead 2 Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Left_4_Dead_2_Events&amp;diff=10284"/>
		<updated>2017-03-31T17:59:22Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Added missing ability_throw for tanks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|a game event, name may be 32 charaters long; this extents the original player_death by a new fields}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID who died}}&lt;br /&gt;
{{hl2msg|long|entityid|entity ID who died, userid should be used first, to get the dead Player.  Otherwise, it is not a player, so use this.}}&lt;br /&gt;
{{hl2msg|short|attacker|user ID who killed}}&lt;br /&gt;
{{hl2msg|string|attackername|What type of zombie, so we don't have zombie names}}&lt;br /&gt;
{{hl2msg|long|attackerentid|if killer not a player, the entindex of who killed.  Again, use attacker first}}&lt;br /&gt;
{{hl2msg|string|weapon|weapon name killer used}}&lt;br /&gt;
{{hl2msg|bool|headshot|signals a headshot}}&lt;br /&gt;
{{hl2msg|bool|attackerisbot|is the attacker a bot}}&lt;br /&gt;
{{hl2msg|string|victimname|What type of zombie, so we don't have zombie names}}&lt;br /&gt;
{{hl2msg|bool|victimisbot|is the victim a bot}}&lt;br /&gt;
{{hl2msg|bool|abort|did the victim abort}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{hl2msg|float|victim_x|}}&lt;br /&gt;
{{hl2msg|float|victim_y|}}&lt;br /&gt;
{{hl2msg|float|victim_z|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_hurt ===&lt;br /&gt;
{{qnotice|Registers all playable classes (Hunter, Smoker, Boomer, Tank, Survivors). See infected_hurt for Witch and Common Infected}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_hurt|string}}&lt;br /&gt;
{{hl2msg|1|local|Not networked}}&lt;br /&gt;
{{hl2msg|short|userid|user ID who was hurt}}&lt;br /&gt;
{{hl2msg|short|attacker|user id who attacked}}&lt;br /&gt;
{{hl2msg|long|attackerentid|entity id who attacked, if attacker not a player, and userid therefore invalid}}&lt;br /&gt;
{{hl2msg|short|health|remaining health points}}&lt;br /&gt;
{{hl2msg|byte|armor|remaining armor points}}&lt;br /&gt;
{{hl2msg|string|weapon|weapon name attacker used, if not the world}}&lt;br /&gt;
{{hl2msg|short|dmg_health|damage done to health}}&lt;br /&gt;
{{hl2msg|byte|dmg_armor|damage done to armor}}&lt;br /&gt;
{{hl2msg|byte|hitgroup|hitgroup that was damaged}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_team ===&lt;br /&gt;
{{qnotice|player change his team}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_team|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID on server}}&lt;br /&gt;
{{hl2msg|byte|team|team id}}&lt;br /&gt;
{{hl2msg|byte|oldteam|old team id}}&lt;br /&gt;
{{hl2msg|bool|disconnect|team change because player disconnects}}&lt;br /&gt;
{{hl2msg|string|name|}}&lt;br /&gt;
{{hl2msg|bool|isbot|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_bot_replace ===&lt;br /&gt;
{{qnotice|Bot replaced a player}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_bot_replace|string}}&lt;br /&gt;
{{hl2msg|short|player|user ID of the player}}&lt;br /&gt;
{{hl2msg|short|bot|user ID of the bot}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== bot_player_replace ===&lt;br /&gt;
{{qnotice|Player replaced a bot}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|bot_player_replace|string}}&lt;br /&gt;
{{hl2msg|short|bot|user ID of the bot}}&lt;br /&gt;
{{hl2msg|short|player|user ID of the player}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_afk ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_afk|string}}&lt;br /&gt;
{{hl2msg|short|player|user ID of the player}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_fire ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_fire|string}}&lt;br /&gt;
{{hl2msg|1|local|don't network this, its way too spammy}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|weapon|used weapon name}}&lt;br /&gt;
{{hl2msg|short|weaponid|used weapon ID}}&lt;br /&gt;
{{hl2msg|short|count|number of bullets}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_fire_on_empty ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_fire_on_empty|string}}&lt;br /&gt;
{{hl2msg|1|local|don't network this, its way too spammy}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|weapon|weapon name used}}&lt;br /&gt;
{{hl2msg|short|count|number of bullets}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_reload ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_reload|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|bool|manual|player manually started the reload}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_zoom ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_zoom|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ability_use ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{eventnote|Called|When an infected uses their ability}}&lt;br /&gt;
{{eventnote|Issues|Doesn't fire for jockey}}&lt;br /&gt;
{{begin-hl2msg|ability_use|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|ability|Classname of ability. Possible values:&lt;br /&gt;
*ability_lunge&lt;br /&gt;
*ability_toungue&lt;br /&gt;
*ability_vomit&lt;br /&gt;
*ability_charge&lt;br /&gt;
*ability_spit&lt;br /&gt;
*ability_throw&lt;br /&gt;
for the Hunter, Smoker, Boomer, Charger, Spitter and Tank respectively.}}&lt;br /&gt;
{{hl2msg|short|context|enum of the way it was used (different for each ability)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ammo_pickup ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pickup|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player who got some ammo from a weapon_ammo_spawner}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== item_pickup ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|item_pickup|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|item|either a weapon such as 'tmp' or 'hegrenade', or an item such as 'nvgs'}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== grenade_bounce ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|grenade_bounce|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== hegrenade_detonate ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|hegrenade_detonate|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== bullet_impact ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|bullet_impact|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|float|x|}}&lt;br /&gt;
{{hl2msg|float|y|}}&lt;br /&gt;
{{hl2msg|float|z|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_footstep ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_footstep|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_jump ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_jump|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_blind ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_blind|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_falldamage ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_falldamage|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who got hurt}}&lt;br /&gt;
{{hl2msg|float|damage|for how much}}&lt;br /&gt;
{{hl2msg|short|causer|Who caused them to do so (if anyone)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_ledge_grab ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_ledge_grab|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who grabbed the ledge}}&lt;br /&gt;
{{hl2msg|short|causer|Who caused them to do so (if anyone)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_ledge_release ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_ledge_release|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who released from the ledge}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== door_moving ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|door_moving|string}}&lt;br /&gt;
{{hl2msg|long|entindex|}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== door_open ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|door_open|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who opened the door}}&lt;br /&gt;
{{hl2msg|bool|checkpoint|Is the door a checkpoint door}}&lt;br /&gt;
{{hl2msg|bool|closed|Was the door closed when it started opening?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== door_close ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|door_close|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who closed the door}}&lt;br /&gt;
{{hl2msg|bool|checkpoint|Is the door a checkpoint door}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== door_unlocked ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|door_unlocked|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who opened the door}}&lt;br /&gt;
{{hl2msg|bool|checkpoint|Is the door a checkpoint door}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== rescue_door_open ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|rescue_door_open|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who opened the door}}&lt;br /&gt;
{{hl2msg|long|entindex|door that opened}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== waiting_checkpoint_door_used ===&lt;br /&gt;
{{qnotice|Someone tried to open a checkpoint door that is locked till everyone loads in}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|waiting_checkpoint_door_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who tried to open it}}&lt;br /&gt;
{{hl2msg|long|entindex|door that was used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== waiting_door_used_versus ===&lt;br /&gt;
{{qnotice|Someone tried to open a checkpoint door that is locked till everyone loads in}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|waiting_door_used_versus|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who tried to open it}}&lt;br /&gt;
{{hl2msg|long|entindex|door that was used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== waiting_checkpoint_button_used ===&lt;br /&gt;
{{qnotice|Someone tried to push a button that's locked until everyone is gathered}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|waiting_checkpoint_button_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who tried to open it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== success_checkpoint_button_used ===&lt;br /&gt;
{{qnotice|Someone pushed a button that's locked until everyone is gathered}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|success_checkpoint_button_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who openned it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== round_freeze_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_freeze_end|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== round_start_pre_entity ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_start_pre_entity|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== round_start_post_nav ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_start_post_nav|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== nav_blocked ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|nav_blocked|string}}&lt;br /&gt;
{{hl2msg|long|area|}}&lt;br /&gt;
{{hl2msg|bool|blocked|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== nav_generate ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|nav_generate|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== round_end_message ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_end_message|string}}&lt;br /&gt;
{{hl2msg|byte|winner|winner team/user i}}&lt;br /&gt;
{{hl2msg|byte|reason|reson why team won}}&lt;br /&gt;
{{hl2msg|string|message|end round message}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== round_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_end|string}}&lt;br /&gt;
{{hl2msg|byte|winner|winner team/user i}}&lt;br /&gt;
{{hl2msg|byte|reason|reson why team won}}&lt;br /&gt;
{{hl2msg|string|message|end round message}}&lt;br /&gt;
{{hl2msg|float|time|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== vote_ended ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_ended|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== vote_started ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_started|string}}&lt;br /&gt;
{{hl2msg|string|issue|}}&lt;br /&gt;
{{hl2msg|string|param1|}}&lt;br /&gt;
{{hl2msg|string|votedata|}}&lt;br /&gt;
{{hl2msg|byte|team|}}&lt;br /&gt;
{{hl2msg|long|initiator|entity id of the player who initiated the vote}}&lt;br /&gt;
{{hl2msg|1|reliable|this event is reliable}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_changed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_changed|string}}&lt;br /&gt;
{{hl2msg|byte|yesVotes|}}&lt;br /&gt;
{{hl2msg|byte|noVotes|}}&lt;br /&gt;
{{hl2msg|byte|potentialVotes|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== vote_passed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_passed|string}}&lt;br /&gt;
{{hl2msg|string|details|}}&lt;br /&gt;
{{hl2msg|string|param1|}}&lt;br /&gt;
{{hl2msg|byte|team|}}&lt;br /&gt;
{{hl2msg|1|reliable|this event is reliable}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_failed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_failed|string}}&lt;br /&gt;
{{hl2msg|byte|team|}}&lt;br /&gt;
{{hl2msg|1|reliable|this event is reliable}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== vote_cast_yes ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_cast_yes|string}}&lt;br /&gt;
{{hl2msg|byte|team|}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of the voter}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== vote_cast_no ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vote_cast_no|string}}&lt;br /&gt;
{{hl2msg|byte|team|}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of the voter}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== infected_hurt ===&lt;br /&gt;
{{qnotice|Registers for non-playable classes (Common Infected, Witch). See player_hurt for other playable classes}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|infected_hurt|string}}&lt;br /&gt;
{{hl2msg|1|local|don't network this, its way too spammy}}&lt;br /&gt;
{{hl2msg|short|attacker|player userid who attacked}}&lt;br /&gt;
{{hl2msg|long|entityid|entity id of infected}}&lt;br /&gt;
{{hl2msg|byte|hitgroup|hitgroup that was damaged}}&lt;br /&gt;
{{hl2msg|short|amount|how much damage was done}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== infected_death ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|infected_death|string}}&lt;br /&gt;
{{hl2msg|short|attacker|user ID who killed}}&lt;br /&gt;
{{hl2msg|short|infected_id|ID of the infected that died}}&lt;br /&gt;
{{hl2msg|short|gender|gender (type) of the infected}}&lt;br /&gt;
{{hl2msg|short|weapon_id|ID of the weapon used}}&lt;br /&gt;
{{hl2msg|bool|headshot|signals a headshot}}&lt;br /&gt;
{{hl2msg|bool|minigun|signals a minigun kill}}&lt;br /&gt;
{{hl2msg|bool|blast|signals a death from blast damage}}&lt;br /&gt;
{{hl2msg|bool|submerged|indicates the infected was submerged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== hostname_changed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|hostname_changed|string}}&lt;br /&gt;
{{hl2msg|string|hostname|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== difficulty_changed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|difficulty_changed|string}}&lt;br /&gt;
{{hl2msg|short|newDifficulty|}}&lt;br /&gt;
{{hl2msg|short|oldDifficulty|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_start|string}}&lt;br /&gt;
{{hl2msg|short|rushes|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_rush ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_rush|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_escape_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_escape_start|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_vehicle_incoming ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_vehicle_incoming|string}}&lt;br /&gt;
{{hl2msg|string|campaign|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_vehicle_ready ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_vehicle_ready|string}}&lt;br /&gt;
{{hl2msg|string|campaign|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_vehicle_leaving ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_vehicle_leaving|string}}&lt;br /&gt;
{{hl2msg|short|survivorcount|number of survivors that made it out}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_win ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_win|string}}&lt;br /&gt;
{{hl2msg|string|map_name|}}&lt;br /&gt;
{{hl2msg|short|difficulty|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== mission_lost ===&lt;br /&gt;
{{qnotice|As in, the survivor team failed.  Opposite of finale_win, but not necessarily during the finale.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|mission_lost|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_radio_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_radio_start|string}}&lt;br /&gt;
{{hl2msg|short|health|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_radio_damaged ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_radio_damaged|string}}&lt;br /&gt;
{{hl2msg|short|health|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== final_reportscreen ===&lt;br /&gt;
{{qnotice|Right before the final report screen comes up, let awards possibly fire}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|final_reportscreen|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== map_transition ===&lt;br /&gt;
{{qnotice|When campaign cinematics start}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|map_transition|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_transitioned ===&lt;br /&gt;
{{qnotice|When campaign cinematics end and player is transitioned to first person view}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_transitioned|string}}&lt;br /&gt;
{{hl2msg|short|userid|the person that just finished transitioning}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== heal_begin ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|heal_begin|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the healing}}&lt;br /&gt;
{{hl2msg|short|subject|person being healed}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== heal_success ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|heal_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the healing}}&lt;br /&gt;
{{hl2msg|short|subject|person being healed}}&lt;br /&gt;
{{hl2msg|short|health_restored|amount of health restored}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== heal_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{eventnote|Issues|subject is broken for this event, it always appears to be the player doing the healing}}&lt;br /&gt;
{{begin-hl2msg|heal_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the healing}}&lt;br /&gt;
{{hl2msg|short|subject|person being healed}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== heal_interrupted ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|heal_interrupted|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who was being healed, but moved.}}&lt;br /&gt;
{{hl2msg|short|subject|person being healed}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ammo_pack_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pack_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|person giving the ammo}}&lt;br /&gt;
{{hl2msg|short|subject|person receiving ammo}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== give_weapon ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|give_weapon|string}}&lt;br /&gt;
{{hl2msg|short|userid|The giver of the weapon}}&lt;br /&gt;
{{hl2msg|short|recipient|The recipient of the weapon}}&lt;br /&gt;
{{hl2msg|short|weapon|The ID of the weapon given}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== pills_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|pills_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who had the pills}}&lt;br /&gt;
{{hl2msg|short|subject|person swallowing the pills}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== pills_used_fail ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|pills_used_fail|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use the pills}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ammo_pack_used_fail_no_weapon ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pack_used_fail_no_weapon|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use the ammo pack}}&lt;br /&gt;
{{hl2msg|short|subject|person it failed to help}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ammo_pack_used_fail_full ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pack_used_fail_full|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use the ammo pack}}&lt;br /&gt;
{{hl2msg|short|subject|person it failed to help}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ammo_pack_used_fail_doesnt_use_ammo ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pack_used_fail_doesnt_use_ammo|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use the ammo pack}}&lt;br /&gt;
{{hl2msg|short|subject|person it failed to help}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ammo_pile_weapon_cant_use_ammo ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ammo_pile_weapon_cant_use_ammo|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use an ammo pile with a grenade launcher}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== defibrillator_begin ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|defibrillator_begin|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who is defibrillating.}}&lt;br /&gt;
{{hl2msg|short|subject|person being revived}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== defibrillator_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|defibrillator_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who used the defibrillator}}&lt;br /&gt;
{{hl2msg|short|subject|person it helped}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== defibrillator_used_fail ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|defibrillator_used_fail|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use the defibrillator}}&lt;br /&gt;
{{hl2msg|short|subject|person it failed to help}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== defibrillator_interrupted ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|defibrillator_interrupted|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who was defibrillating, but moved.}}&lt;br /&gt;
{{hl2msg|short|subject|person being revived}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_pack_begin ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_pack_begin|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who is deploying the pack}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_pack_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_pack_used|string}}&lt;br /&gt;
{{hl2msg|short|upgradeid|}}&lt;br /&gt;
{{hl2msg|short|userid|person who is deploying the pack}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_item_already_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_item_already_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use an ammo upgrade twice}}&lt;br /&gt;
{{hl2msg|string|upgradeclass|classname of the upgrade we tried to use}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_failed_no_primary ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_failed_no_primary|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who tried to use an upgrade without having a primary weapon}}&lt;br /&gt;
{{hl2msg|string|upgrade|name of the upgrade we tried to use, eg &amp;quot;INCENDIARY_AMMO&amp;quot;}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== dead_survivor_visible ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|dead_survivor_visible|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player who sees the entity}}&lt;br /&gt;
{{hl2msg|long|subject|Entindex of the entity they see}}&lt;br /&gt;
{{hl2msg|short|deadplayer|user id of the dead player represented}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== adrenaline_used ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|adrenaline_used|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who had and used the adrenaline}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== revive_begin ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|revive_begin|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the reviving}}&lt;br /&gt;
{{hl2msg|short|subject|person being revived}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== revive_success ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|revive_success|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the reviving}}&lt;br /&gt;
{{hl2msg|short|subject|person who was revived}}&lt;br /&gt;
{{hl2msg|bool|lastlife|person revived will die if they fall again}}&lt;br /&gt;
{{hl2msg|bool|ledge_hang|1 if person revived was ledge hanging}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== revive_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|revive_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the reviving}}&lt;br /&gt;
{{hl2msg|short|subject|person being revived}}&lt;br /&gt;
{{hl2msg|bool|ledge_hang|person is ledge hanging}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== drag_begin ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|drag_begin|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the dragging}}&lt;br /&gt;
{{hl2msg|short|subject|person being dragged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== drag_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|drag_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|person doing the dragging}}&lt;br /&gt;
{{hl2msg|short|subject|person being dragged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_incapacitated ===&lt;br /&gt;
{{qnotice|when a player becomes incapacitated.  This is also called when a tank is killed.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_incapacitated|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who became incapacitated}}&lt;br /&gt;
{{hl2msg|short|attacker|user ID who made us incapacitated}}&lt;br /&gt;
{{hl2msg|long|attackerentid|if attacker not player, entindex of who made us incapacitated}}&lt;br /&gt;
{{hl2msg|string|weapon|weapon name attacker used}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_incapacitated_start ===&lt;br /&gt;
{{qnotice|when a player is about to become incapacitated, so you can see his last living state}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_incapacitated_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who became incapacitated}}&lt;br /&gt;
{{hl2msg|short|attacker|user ID who made us incapacitated}}&lt;br /&gt;
{{hl2msg|long|attackerentid|if attacker not player, entindex of who made us incapacitated}}&lt;br /&gt;
{{hl2msg|string|weapon|weapon name attacker used}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_entered_start_area ===&lt;br /&gt;
{{qnotice|when a player spawns into the player start area}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_entered_start_area|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who entered}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_first_spawn ===&lt;br /&gt;
{{qnotice|when a player spawns for the first time in a given mission}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_first_spawn|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who spawned}}&lt;br /&gt;
{{hl2msg|string|map_name|}}&lt;br /&gt;
{{hl2msg|bool|isbot|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
{{qnotice|This Event doesnt exist anymore 1.10.2012}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== player_left_start_area ===&lt;br /&gt;
{{qnotice|when a player leaves the player start area}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_left_start_area|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who left}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_entered_checkpoint ===&lt;br /&gt;
{{qnotice|when a basecombatcharacter enters a checkpoint area}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_entered_checkpoint|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who entered}}&lt;br /&gt;
{{hl2msg|long|entityid|If not a player, the entity index of the one entering}}&lt;br /&gt;
{{hl2msg|long|door|Entindex of the checkpoint door the player entered to get here.}}&lt;br /&gt;
{{hl2msg|long|area|}}&lt;br /&gt;
{{hl2msg|string|doorname|name of the entity they see}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_left_checkpoint ===&lt;br /&gt;
{{qnotice|when a player leaves a checkpoint area}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_left_checkpoint|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who left}}&lt;br /&gt;
{{hl2msg|long|entityid|If not a player, the entity index of the one exiting}}&lt;br /&gt;
{{hl2msg|long|area|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_shoved ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_shoved|string}}&lt;br /&gt;
{{hl2msg|short|userid|player index who was shoved}}&lt;br /&gt;
{{hl2msg|short|attacker|player index who attacked them}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== entity_shoved ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|entity_shoved|string}}&lt;br /&gt;
{{hl2msg|short|entityid|the entity index of the one who was shoved}}&lt;br /&gt;
{{hl2msg|short|attacker|player index who attacked them}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_jump_apex ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_jump_apex|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who jumped}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_blocked ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_blocked|string}}&lt;br /&gt;
{{hl2msg|short|userid|player index who was trying to move}}&lt;br /&gt;
{{hl2msg|short|blocker|player index who kept them from moving}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_now_it ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_now_it|string}}&lt;br /&gt;
{{hl2msg|short|userid|Player who is now it}}&lt;br /&gt;
{{hl2msg|short|attacker|player that did the it-ing}}&lt;br /&gt;
{{hl2msg|bool|exploded|whether it was vomit or explosion}}&lt;br /&gt;
{{hl2msg|bool|infected|is the vomit infectious}}&lt;br /&gt;
{{hl2msg|bool|by_boomer|came from a boomer}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_no_longer_it ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_no_longer_it|string}}&lt;br /&gt;
{{hl2msg|short|userid|Player who is now no longer it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== witch_harasser_set ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|witch_harasser_set|string}}&lt;br /&gt;
{{hl2msg|short|userid|Player who woke up the witch}}&lt;br /&gt;
{{hl2msg|long|witchid|Entindex of witch woken up}}&lt;br /&gt;
{{hl2msg|bool|first|First time the witch set a harasser}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== witch_spawn ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|witch_spawn|string}}&lt;br /&gt;
{{hl2msg|long|witchid|Entindex of witch spawning right now.}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== witch_killed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|witch_killed|string}}&lt;br /&gt;
{{hl2msg|short|userid|Player who killed the witch}}&lt;br /&gt;
{{hl2msg|long|witchid|Entindex of witch that was killed.}}&lt;br /&gt;
{{hl2msg|bool|oneshot|TRUE if the Witch was killed with one shot}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tank_spawn ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tank_spawn|string}}&lt;br /&gt;
{{hl2msg|short|userid|User ID of the tank spawning now}}&lt;br /&gt;
{{hl2msg|long|tankid|Entindex of tank spawning right now.}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== melee_kill ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|melee_kill|string}}&lt;br /&gt;
{{hl2msg|short|userid|Player who bashed the infected}}&lt;br /&gt;
{{hl2msg|long|entityid|Entindex of infected what got killed}}&lt;br /&gt;
{{hl2msg|bool|ambush|Infected was unaware when killed}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== area_cleared ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|area_cleared|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who cleared the area}}&lt;br /&gt;
{{hl2msg|long|area|id of the cleared area}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== award_earned ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|award_earned|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who earned the award}}&lt;br /&gt;
{{hl2msg|long|entityid|client likes ent id}}&lt;br /&gt;
{{hl2msg|long|subjectentid|entity id of other party in the award, if any}}&lt;br /&gt;
{{hl2msg|short|award|id of award earned}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tongue_grab ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tongue_grab|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who did the grabbing}}&lt;br /&gt;
{{hl2msg|short|victim|player that got grabbed}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tongue_broke_bent ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tongue_broke_bent|string}}&lt;br /&gt;
{{hl2msg|short|userid|Tongue owner}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tongue_broke_victim_died ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tongue_broke_victim_died|string}}&lt;br /&gt;
{{hl2msg|short|userid|Tongue owner}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tongue_release ===&lt;br /&gt;
{{qnotice|Fired in all cases where the tongue releases a victim, whether choked or not, etc.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tongue_release|string}}&lt;br /&gt;
{{hl2msg|short|userid|The tongue owner}}&lt;br /&gt;
{{hl2msg|short|victim|The (now released) victim}}&lt;br /&gt;
{{hl2msg|long|distance|Distance the victim was dragged.}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== choke_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|choke_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|The choker}}&lt;br /&gt;
{{hl2msg|short|victim|The person being choked}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== choke_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|choke_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|The choker}}&lt;br /&gt;
{{hl2msg|short|victim|The person being choked}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== choke_stopped ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|choke_stopped|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who stopped it}}&lt;br /&gt;
{{hl2msg|short|victim|And who was being choked}}&lt;br /&gt;
{{hl2msg|short|smoker|The tongue owner}}&lt;br /&gt;
{{hl2msg|short|release_type|How did it break?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tongue_pull_stopped ===&lt;br /&gt;
{{qnotice|Called when a smoker tongue is cleared on a dragging player. Includes cuts.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tongue_pull_stopped|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who stopped it}}&lt;br /&gt;
{{hl2msg|short|victim|And who was being pulled}}&lt;br /&gt;
{{hl2msg|short|smoker|The tongue owner}}&lt;br /&gt;
{{hl2msg|short|release_type|How did it break?}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== lunge_shove ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|lunge_shove|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who did the lunging}}&lt;br /&gt;
{{hl2msg|short|victim|player that got lunged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== lunge_pounce ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|lunge_pounce|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who did the lunging}}&lt;br /&gt;
{{hl2msg|short|victim|player that got lunged}}&lt;br /&gt;
{{hl2msg|long|distance|Distance from pounce start to contact}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== pounce_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|pounce_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who stopped it}}&lt;br /&gt;
{{hl2msg|short|victim|And who was being pounced}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== pounce_stopped ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|pounce_stopped|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who stopped it}}&lt;br /&gt;
{{hl2msg|short|victim|And who was being pounced}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== fatal_vomit ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|fatal_vomit|string}}&lt;br /&gt;
{{hl2msg|short|userid|Who vomited}}&lt;br /&gt;
{{hl2msg|short|victim|And who was killed or incapped}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== survivor_call_for_help ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|survivor_call_for_help|string}}&lt;br /&gt;
{{hl2msg|short|userid|The actual player entity who is awaiting rescue.}}&lt;br /&gt;
{{hl2msg|long|subject|SurvivorRescue entity representing the player who needs to be rescued from the closet (used for position)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== survivor_rescued ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|survivor_rescued|string}}&lt;br /&gt;
{{hl2msg|short|rescuer|player that did the rescuing}}&lt;br /&gt;
{{hl2msg|short|victim|the survivor being rescued}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== survivor_rescue_abandoned ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|survivor_rescue_abandoned|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== relocated ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|relocated|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who was relocated}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== respawning ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|respawning|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who started respawning}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== tank_frustrated ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tank_frustrated|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who was culled}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_given ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_given|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who got the weapon}}&lt;br /&gt;
{{hl2msg|short|giver|player that did the giving}}&lt;br /&gt;
{{hl2msg|short|weapon|weapon id given}}&lt;br /&gt;
{{hl2msg|short|weaponentid|weapon entity id}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_drop ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{eventnote|Called|When an item is removed from a survivor's inventory}}&lt;br /&gt;
{{eventnote|Related Events|Called before heal_success, defibrillator_used, upgrade_pack_used, but called after pills_used and adrenaline_used}}&lt;br /&gt;
{{begin-hl2msg|weapon_drop|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who dropped the weapon}}&lt;br /&gt;
{{hl2msg|string|item|either a weapon such as 'tmp' or 'hegrenade', or an item such as 'nvgs'}}&lt;br /&gt;
{{hl2msg|short|propid|entindex of the dropped weapon}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== break_breakable ===&lt;br /&gt;
{{qnotice|Override from gameevents.res}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|break_breakable|string}}&lt;br /&gt;
{{hl2msg|short|userid|userid of breaker}}&lt;br /&gt;
{{hl2msg|long|entindex|entindex of thing breaking}}&lt;br /&gt;
{{hl2msg|byte|material|BREAK_GLASS, BREAK_WOOD, etc}}&lt;br /&gt;
{{hl2msg|bool|hulkonly|SF_BREAK_HULK_ONLY}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== achievement_earned ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_earned|string}}&lt;br /&gt;
{{hl2msg|byte|player|entindex of the player}}&lt;br /&gt;
{{hl2msg|short|achievement|achievement ID}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== spec_target_updated ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spec_target_updated|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== spawner_give_item ===&lt;br /&gt;
{{qnotice|A spawner has given a player an item (weapon, pills, ammo, health kit, etc)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spawner_give_item|string}}&lt;br /&gt;
{{hl2msg|short|userid|Item recipient}}&lt;br /&gt;
{{hl2msg|string|item|Name of item given}}&lt;br /&gt;
{{hl2msg|long|spawner|entindex of the spawner entity}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== create_panic_event ===&lt;br /&gt;
{{qnotice|A panic event has been created, though not necessarily started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|create_panic_event|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who was started the panic}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_pills ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_pills|string}}&lt;br /&gt;
{{hl2msg|long|subject|The weapon_pain_pills spawner that will be indicated}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_weapons ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_weapons|string}}&lt;br /&gt;
{{hl2msg|long|subject|The weapon_pain_pills spawner that will be indicated}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== entity_visible ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|entity_visible|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player who sees the entity}}&lt;br /&gt;
{{hl2msg|long|subject|Entindex of the entity they see}}&lt;br /&gt;
{{hl2msg|string|classname|Classname of the entity they see}}&lt;br /&gt;
{{hl2msg|string|entityname|name of the entity they see}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_spawn_visible ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_spawn_visible|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player who sees the entity}}&lt;br /&gt;
{{hl2msg|long|subject|Entindex of the entity they see}}&lt;br /&gt;
{{hl2msg|string|weaponname|weapon name, or &amp;quot;melee&amp;quot;}}&lt;br /&gt;
{{hl2msg|string|subtype|melee weapon name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== boomer_near ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|boomer_near|string}}&lt;br /&gt;
{{hl2msg|short|userid|The boomer}}&lt;br /&gt;
{{hl2msg|short|victim|The survivor whom the boomer has gotten very close to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_pre_radio ===&lt;br /&gt;
{{qnotice|explain the rescue radio will remind you to ready for the finale}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_pre_radio|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== started_pre_radio ===&lt;br /&gt;
{{qnotice|explain the rescue radio will remind you to ready for the finale}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|started_pre_radio|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_radio ===&lt;br /&gt;
{{qnotice|explain the rescue radio will start the finale}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_radio|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_gas_truck ===&lt;br /&gt;
{{qnotice|explain how pulling the lever on the gas truck will start the finale}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_gas_truck|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The lever}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_panic_button ===&lt;br /&gt;
{{qnotice|explain that pressing this button will start a panic event.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_panic_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The panic button}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_elevator_button ===&lt;br /&gt;
{{qnotice|explain how to operate the hospital elevator button.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_elevator_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The button}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_lift_button ===&lt;br /&gt;
{{qnotice|explain how to operate the lift button.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_lift_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The lift button}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_church_door ===&lt;br /&gt;
{{qnotice|explain how to provoke the crazy church guy.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_church_door|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The saferoom door}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_emergency_door ===&lt;br /&gt;
{{qnotice|explain how to open the emergency door.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_emergency_door|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The door}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_crane ===&lt;br /&gt;
{{qnotice|explain how to lower the box on the crane.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_crane|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The lever/button}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_bridge ===&lt;br /&gt;
{{qnotice|explain how to close the gates to make a bridge.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_bridge|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The button}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_gas_can_panic ===&lt;br /&gt;
{{qnotice|explain how to shoot the gas can.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_gas_can_panic|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The gas can}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_van_panic ===&lt;br /&gt;
{{qnotice|explain how to start the van.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_van_panic|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The van}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_mainstreet ===&lt;br /&gt;
{{qnotice|explain how to lower the forklift}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_mainstreet|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The forklift}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_train_lever ===&lt;br /&gt;
{{qnotice|explain how to operate the train lever.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_train_lever|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The lever on box car}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_disturbance ===&lt;br /&gt;
{{qnotice|explain that disturbances (car alarm) attract infected horde}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_disturbance|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The source of disturbance}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_scavenge_goal ===&lt;br /&gt;
{{qnotice|explain where to put the scavenge mode items}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_scavenge_goal|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The collection device}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_scavenge_leave_area ===&lt;br /&gt;
{{qnotice|explain that leaving the area, starts round}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_scavenge_leave_area|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|The entity}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== begin_scavenge_overtime ===&lt;br /&gt;
{{qnotice|enter overtime in a scavenge round}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|begin_scavenge_overtime|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== scavenge_round_start ===&lt;br /&gt;
{{qnotice|a scavenge round has begun}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_round_start|string}}&lt;br /&gt;
{{hl2msg|byte|round|round number, 1 based}}&lt;br /&gt;
{{hl2msg|bool|firsthalf|start of the first half of the round}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== scavenge_round_halftime ===&lt;br /&gt;
{{qnotice|a scavenge round is in halftime}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_round_halftime|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== scavenge_round_finished ===&lt;br /&gt;
{{qnotice|a scavenge round has ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_round_finished|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== scavenge_score_tied ===&lt;br /&gt;
{{qnotice|a team just tied the score}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_score_tied|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== versus_round_start ===&lt;br /&gt;
{{qnotice|a versus round has begun}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|versus_round_start|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gascan_pour_blocked ===&lt;br /&gt;
{{qnotice|can't pour the gas, someone else already is}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gascan_pour_blocked|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gascan_pour_completed ===&lt;br /&gt;
{{qnotice|player finished pouring a can}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gascan_pour_completed|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gascan_dropped ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gascan_dropped|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gascan_pour_interrupted ===&lt;br /&gt;
{{qnotice|we got interuppted pouring the gas can}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gascan_pour_interrupted|string}}&lt;br /&gt;
{{hl2msg|short|userid|person who interuppted us}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== scavenge_match_finished ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_match_finished|string}}&lt;br /&gt;
{{hl2msg|byte|winners|winner team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== versus_match_finished ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|versus_match_finished|string}}&lt;br /&gt;
{{hl2msg|byte|winners|winner team}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== use_target ===&lt;br /&gt;
{{qnotice|a new use target has been found}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|use_target|string}}&lt;br /&gt;
{{hl2msg|long|targetid|Entindex of the use target}}&lt;br /&gt;
{{hl2msg|string|classname|classname of the use target}}&lt;br /&gt;
{{hl2msg|bool|isprop|is this a prop that can be carried}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_use ===&lt;br /&gt;
{{qnotice|a new use target has been found}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{eventnote|Called|When a Survivor presses +USE on a useable entity. i.e. Weapons, items, doors}}&lt;br /&gt;
{{eventnote|Related Events|If targetid is an item, item_pickup will be called prior to player_use}}&lt;br /&gt;
{{begin-hl2msg|player_use|string}}&lt;br /&gt;
{{hl2msg|short|userid|userid of user}}&lt;br /&gt;
{{hl2msg|long|targetid|Entindex of the used entity}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== friendly_fire ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|friendly_fire|string}}&lt;br /&gt;
{{hl2msg|short|attacker|player who fired the weapon}}&lt;br /&gt;
{{hl2msg|short|victim|player who got shot}}&lt;br /&gt;
{{hl2msg|short|guilty|player who was at fault}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gameinstructor_draw ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_draw|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gameinstructor_nodraw ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gameinstructor_nodraw|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== request_weapon_stats ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|request_weapon_stats|string}}&lt;br /&gt;
{{hl2msg|short|userid|userid of user requesting their stats}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_talking_state ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_talking_state|string}}&lt;br /&gt;
{{hl2msg|byte|player|}}&lt;br /&gt;
{{hl2msg|bool|istalking|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_pickup ===&lt;br /&gt;
{{qnotice|client event for player has picked up a weapon}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_pickup|string}}&lt;br /&gt;
{{hl2msg|byte|context|split screen message context}}&lt;br /&gt;
{{hl2msg|byte|weaponid|}}&lt;br /&gt;
{{hl2msg|byte|weaponslot|}}&lt;br /&gt;
{{hl2msg|byte|dropped_by_infected|gender of the Infected that dropped the weapon}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== hunter_punched ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|hunter_punched|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who caused ignition}}&lt;br /&gt;
{{hl2msg|long|hunteruserid|user ID of Hunter}}&lt;br /&gt;
{{hl2msg|bool|islunging|TRUE if the Hunter was in the act of lunging}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== hunter_headshot ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|hunter_headshot|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who made the headshot}}&lt;br /&gt;
{{hl2msg|long|hunteruserid|user ID of Hunter}}&lt;br /&gt;
{{hl2msg|bool|islunging|TRUE if the Hunter was in the act of lunging}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== zombie_ignited ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|zombie_ignited|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who caused ignition}}&lt;br /&gt;
{{hl2msg|short|gender|gender (type) of the infected}}&lt;br /&gt;
{{hl2msg|long|entityid|entity ID of Tank}}&lt;br /&gt;
{{hl2msg|string|victimname|&amp;quot;Witch&amp;quot;, &amp;quot;Tank&amp;quot;, &amp;quot;Hunter&amp;quot;, &amp;quot;Smoker&amp;quot;, or &amp;quot;Infected&amp;quot;}}&lt;br /&gt;
{{hl2msg|bool|fire_ammo|true if incendiary ammo was used}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== boomer_exploded ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|boomer_exploded|string}}&lt;br /&gt;
{{hl2msg|short|userid|Boomer that exploded}}&lt;br /&gt;
{{hl2msg|short|attacker|player who caused the explosion}}&lt;br /&gt;
{{hl2msg|bool|splashedbile|Exploding boomer splashed bile on Survivors}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== non_pistol_fired ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|non_pistol_fired|string}}&lt;br /&gt;
{{hl2msg|short|userid|User that fired a non-pistol weapon}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== weapon_fire_at_40 ===&lt;br /&gt;
{{qnotice|This is networked, special event for game instructor}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|weapon_fire_at_40|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|weapon|used weapon name}}&lt;br /&gt;
{{hl2msg|short|weaponid|used weapon ID}}&lt;br /&gt;
{{hl2msg|short|count|number of bullets}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== total_ammo_below_40 ===&lt;br /&gt;
{{qnotice|sent for any ammo type, except those with max ammo 1, or infinite ammo, like pistols}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|total_ammo_below_40|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== player_hurt_concise ===&lt;br /&gt;
{{qnotice|Abbreviated version of 'player_hurt' that is networked}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_hurt_concise|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID who was hurt}}&lt;br /&gt;
{{hl2msg|long|attackerentid|entity id who attacked, if attacker not a player, and userid therefore invalid}}&lt;br /&gt;
{{hl2msg|long|type|damage type}}&lt;br /&gt;
{{hl2msg|short|dmg_health|damage done to health}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== tank_killed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|tank_killed|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of dead tank}}&lt;br /&gt;
{{hl2msg|short|attacker|user id of killer}}&lt;br /&gt;
{{hl2msg|bool|solo|TRUE if a player single-handedly killed the Tank}}&lt;br /&gt;
{{hl2msg|bool|melee_only|TRUE if the tank was only killed by melee attacks (no blast, burn, or bullet damage)}}&lt;br /&gt;
{{hl2msg|bool|l4d1_only|TRUE if l4d1 survivors inflicted damage and the l4d2 survivors did not)}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== achievement_write_failed ===&lt;br /&gt;
{{qnotice|Used for a notification message when an achievement fails to write}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|achievement_write_failed|string}}&lt;br /&gt;
{{hl2msg|None|None|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== ghost_spawn_time ===&lt;br /&gt;
{{qnotice|Used for clients to know how long until they become a ghost (and can spawn)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ghost_spawn_time|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the player that is becoming a ghost}}&lt;br /&gt;
{{hl2msg|short|spawntime|How long of a wait until player is a ghost}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== survival_at_30min ===&lt;br /&gt;
{{qnotice|Used to know when we elapse 30 minutes on a survival map}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|survival_at_30min|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_pre_drawbridge ===&lt;br /&gt;
{{qnotice|Point out the button that will start the gauntlet finale.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_pre_drawbridge|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_drawbridge ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_drawbridge|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_perimeter ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_perimeter|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_deactivate_alarm ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_deactivate_alarm|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_impound_lot ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_impound_lot|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_decon ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_decon|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_mall_window ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_mall_window|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_mall_alarm ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_mall_alarm|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_coaster ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_coaster|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_coaster_stop ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_coaster_stop|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_decon_wait ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_decon_wait|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gauntlet_finale_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gauntlet_finale_start|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_float ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_float|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_ferry_button ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_ferry_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_hatch_button ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_hatch_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_shack_button ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_shack_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_incendiary_ammo ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_incendiary_ammo|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== upgrade_explosive_ammo ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_explosive_ammo|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== receive_upgrade ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|receive_upgrade|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|upgrade|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_vehicle_arrival ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_vehicle_arrival|string}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== mounted_gun_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|mounted_gun_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== mounted_gun_overheated ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|mounted_gun_overheated|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_burger_sign ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_burger_sign|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_carousel_button ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_carousel_button|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_carousel_destination ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_carousel_destination|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_stage_lighting ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_stage_lighting|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_stage_finale_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_stage_finale_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_stage_survival_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_stage_survival_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== ability_out_of_range ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|ability_out_of_range|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|string|ability|ability classname}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_stage_pyrotechnics ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_stage_pyrotechnics|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c3m4_radio1 ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c3m4_radio1|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c3m4_radio2 ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c3m4_radio2|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_gates_are_open ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_gates_are_open|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c2m4_ticketbooth ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c2m4_ticketbooth|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c3m4_rescue ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c3m4_rescue|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_hotel_elevator_doors ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_hotel_elevator_doors|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_gun_shop_tanker ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_gun_shop_tanker|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_gun_shop ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_gun_shop|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_store_alarm ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_store_alarm|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_store_item ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_store_item|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_store_item_stop ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_store_item_stop|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_survival_generic ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_survival_generic|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_survival_alarm ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_survival_alarm|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_survival_radio ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_survival_radio|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_survival_carousel ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_survival_carousel|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_return_item ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_return_item|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_save_items ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_save_items|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== spit_burst ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spit_burst|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== entered_spit ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|entered_spit|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== temp_c4m1_getgas ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|temp_c4m1_getgas|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== temp_c4m3_return_to_boat ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|temp_c4m3_return_to_boat|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c1m4_finale ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c1m4_finale|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== c1m4_scavenge_instructions ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|c1m4_scavenge_instructions|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== punched_clown ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|punched_clown|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who punched the clown}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_killed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_killed|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of dead charger}}&lt;br /&gt;
{{hl2msg|short|attacker|user id of killer}}&lt;br /&gt;
{{hl2msg|bool|melee|TRUE if a player killed the charger with a melee weapon}}&lt;br /&gt;
{{hl2msg|bool|charging|TRUE if the charger was charging when it died}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== spitter_killed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|spitter_killed|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of dead spitter}}&lt;br /&gt;
{{hl2msg|short|attacker|user id of killer}}&lt;br /&gt;
{{hl2msg|bool|has_spit|TRUE if the spitter spit at some point}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== jockey_ride ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|jockey_ride|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who did the lunging}}&lt;br /&gt;
{{hl2msg|short|victim|player that got lunged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== jockey_ride_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|jockey_ride_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|player who did the lunging}}&lt;br /&gt;
{{hl2msg|short|victim|player that got lunged}}&lt;br /&gt;
{{hl2msg|short|rescuer|Who stopped it}}&lt;br /&gt;
{{hl2msg|float|ride_length|Duration of our ride}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== jockey_killed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|jockey_killed|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of dead jockey}}&lt;br /&gt;
{{hl2msg|short|attacker|user id of killer}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== non_melee_fired ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|non_melee_fired|string}}&lt;br /&gt;
{{hl2msg|short|userid|User that fired a non-melee weapon}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== infected_decapitated ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|infected_decapitated|string}}&lt;br /&gt;
{{hl2msg|short|userid|userid of the player who did the decapitation}}&lt;br /&gt;
{{hl2msg|string|weapon|melee weapon name}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== upgrade_pack_added ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|upgrade_pack_added|string}}&lt;br /&gt;
{{hl2msg|short|upgradeid|}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== vomit_bomb_tank ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|vomit_bomb_tank|string}}&lt;br /&gt;
{{hl2msg|short|userid|userid of the player who used the bomb}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== triggered_car_alarm ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|triggered_car_alarm|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== panic_event_finished ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|panic_event_finished|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_charge_start ===&lt;br /&gt;
{{qnotice|The moment when the charger starts charging}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_charge_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_charge_end ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_charge_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_carry_start ===&lt;br /&gt;
{{qnotice|The moment when the charger grabs a survivor}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_carry_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{hl2msg|short|victim|user ID of the player who was charged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_carry_end ===&lt;br /&gt;
{{qnotice|The moment when the charger stops charging a survivor (and will soon start pummeling)}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_carry_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{hl2msg|short|victim|user ID of the player who was charged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_impact ===&lt;br /&gt;
{{qnotice|When a charger impacts a survivor they aren't carrying}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_impact|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{hl2msg|short|victim|user ID of the player who was impacted}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_pummel_start ===&lt;br /&gt;
{{qnotice|The moment when the charger starts pummeling a survivor}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_pummel_start|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{hl2msg|short|victim|user ID of the player who was charged}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== charger_pummel_end ===&lt;br /&gt;
{{qnotice|When the charger is cleared from the survivor or the survivor dies.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|charger_pummel_end|string}}&lt;br /&gt;
{{hl2msg|short|userid|user ID of the charger}}&lt;br /&gt;
{{hl2msg|short|victim|}}&lt;br /&gt;
{{hl2msg|short|rescuer|user ID of the player who rescued them}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== strongman_bell_knocked_off ===&lt;br /&gt;
{{qnotice|The arcade bell on c2m4_barns}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|strongman_bell_knocked_off|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|short|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== molotov_thrown ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|molotov_thrown|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== gas_can_forced_drop ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|gas_can_forced_drop|string}}&lt;br /&gt;
{{hl2msg|short|userid|player that forced the drop}}&lt;br /&gt;
{{hl2msg|short|victim|player that dropped it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_need_gnome_to_continue ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_need_gnome_to_continue|string}}&lt;br /&gt;
{{hl2msg|none|none|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_survivor_glows_disabled ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_survivor_glows_disabled|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player we're explaining to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_item_glows_disabled ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_item_glows_disabled|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player we're explaining to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_rescue_disabled ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_rescue_disabled|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player we're explaining to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_bodyshots_reduced ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_bodyshots_reduced|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player we're explaining to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_witch_instant_kill ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_witch_instant_kill|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player we're explaining to}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== set_instructor_group_enabled ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|set_instructor_group_enabled|string}}&lt;br /&gt;
{{hl2msg|string|group|}}&lt;br /&gt;
{{hl2msg|short|enabled|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== stashwhacker_game_won ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|stashwhacker_game_won|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|short|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== versus_marker_reached ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|versus_marker_reached|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|short|marker|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== start_score_animation ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|start_score_animation|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== survival_round_start ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|survival_round_start|string}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== scavenge_gas_can_destroyed ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|scavenge_gas_can_destroyed|string}}&lt;br /&gt;
{{hl2msg|short|userid|The player that destroyed it}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_sewer_gate ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_sewer_gate|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_sewer_run ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_sewer_run|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== explain_c6m3_finale ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|explain_c6m3_finale|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== finale_bridge_lowering ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|finale_bridge_lowering|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{hl2msg|long|subject|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== m60_streak_ended ===&lt;br /&gt;
{{qnotice|I was holding down the m60 trigger, and now I'm not}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|m60_streak_ended|string}}&lt;br /&gt;
{{hl2msg|none|none|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== chair_charged ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|chair_charged|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== song_played ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|song_played|string}}&lt;br /&gt;
{{hl2msg|none|none|}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
=== foot_locker_opened ===&lt;br /&gt;
{{qnotice|}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|foot_locker_opened|string}}&lt;br /&gt;
{{hl2msg|short|userid|}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Handles_(SourceMod_Scripting)&amp;diff=10174</id>
		<title>Handles (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Handles_(SourceMod_Scripting)&amp;diff=10174"/>
		<updated>2016-06-17T12:26:47Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated to 1.7 Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Handles are a special data type used in [[:Category:SourceMod Scripting|SourceMod Scripting]].  They represent a single internal and unique object.  For example, there are &amp;quot;File&amp;quot; Handles for files, and &amp;quot;Menu&amp;quot; Handles for menus, but they are both encapsulated under the &amp;quot;Handle&amp;quot; [[Tags (SourceMod Scripting)|tag]].&lt;br /&gt;
&lt;br /&gt;
Handles are more than &amp;quot;pointers&amp;quot; from C or C++ because they have a ''reference count''.  This means that the number of copies floating around in memory is tracked.  The actual internal object is not destroyed until each copy is also destroyed.&lt;br /&gt;
&lt;br /&gt;
Since SourcePawn does not have [[Garbage Collection]], Handles are a special way of intelligently allowing plugins and SourceMod to manage their own memory.&lt;br /&gt;
&lt;br /&gt;
For more information on using Handles in the SourceMod API, see [[Handle API (SourceMod)]].&lt;br /&gt;
&lt;br /&gt;
=Opening Handles=&lt;br /&gt;
Opening a Handle is usually done implicitly by a native function.  For example, OpenDirectory opens a new Handle which is used in other Directory natives.  This associates a ''type'' with the Handle.  Trying to use a Directory Handle with any other non-Directory native will cause an error (HandleError_Type), because Handles are type checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Handle hndl = OpenDirectory(&amp;quot;addons/sourcemod/configs&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Closing Handles=&lt;br /&gt;
==Basic operation==&lt;br /&gt;
Closing a Handle means seeing if the internal object can be removed from memory.  For example, if a plugin creates an SQL connection, closing the Handle means closing and destroying the connection.  This is almost always done using the CloseHandle() native function.&lt;br /&gt;
&lt;br /&gt;
==When to close==&lt;br /&gt;
When a plugin unloads, all of its Handles are automatically destroyed.  This does not mean, however, that closing Handles is optional.  Consider the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock bool IsFileInFolder(const char[] path, const char[] file)&lt;br /&gt;
{&lt;br /&gt;
	char path[PLATFORM_MAX_PATH];&lt;br /&gt;
	FileType type;&lt;br /&gt;
&lt;br /&gt;
	Handle dir = OpenDirectory(path);&lt;br /&gt;
	if (dir == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	while (ReadDirEntry(dir, path, sizeof(path), type))&lt;br /&gt;
	{&lt;br /&gt;
		if (type == FileType_File &amp;amp;&amp;amp; StrEqual(path, file))&lt;br /&gt;
		{&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	delete dir;&lt;br /&gt;
&lt;br /&gt;
	return false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function searches a directory for a single file.  If this function were to omit the call to CloseHandle, it would [[Memory Leak|leak memory]] every time it was called, and eventually the script would fill up with a large number of lingering Handles that were left open.&lt;br /&gt;
&lt;br /&gt;
So, when do you close Handles?  There are generally two rules of thumb to go by:&lt;br /&gt;
*If the native uses terminology such as &amp;quot;Opens a [...]&amp;quot; or &amp;quot;Creates a [...]&amp;quot; or gives explicit directions for closing.&lt;br /&gt;
*If the Handle represents a temporary object or piece of information, and you will no longer be using it.&lt;br /&gt;
&lt;br /&gt;
Most of the time, you will be closing Handles.  Check the Handle Type documentation at the end of this page.&lt;br /&gt;
&lt;br /&gt;
==When you can't close==&lt;br /&gt;
There are a few Handle types that cannot be closed.  The major one is the Handle which identifies a plugin.  Plugins cannot unload themselves, and thus destroying their own Handles is not allowed.&lt;br /&gt;
&lt;br /&gt;
Furthermore, a script cannot close a Handle that is owned by another plugin.  This is for protection against API mistakes and accidental errors.  For example, if a Handle is shared between two plugins, one accidental free could invalidate a Handle unexpectedly.  To allow the sharing of Handles, see [[#Cloning Handles|Cloning Handles]].&lt;br /&gt;
&lt;br /&gt;
==Reference counters==&lt;br /&gt;
Closing Handles does not always destroy the internal data.  This is the case when Handles are [[#Cloning Handles|cloned]].  Each clone adds a ''reference count'' to the Handle, and closing each clone removes one reference count.  The original object is only actually destroyed once the Handle has no more reference counters.  &lt;br /&gt;
&lt;br /&gt;
=Cloning Handles=&lt;br /&gt;
As briefly described earlier, there is a problem when scripts try to share Handles.  Imagine this scenario:&lt;br /&gt;
*Plugin 'A' creates a Handle.&lt;br /&gt;
*Plugin 'B' received the Handle.&lt;br /&gt;
*Plugin 'A' is unloaded, and the Handle is destroyed.&lt;br /&gt;
*Plugin 'B' tries to use the Handle.&lt;br /&gt;
&lt;br /&gt;
To prevent this, the CloneHandle native is provided.  This function returns a ''new'' Handle that is a &amp;quot;copy&amp;quot; of the original.  While their values won't be equal, they contain the same internal data.  The data itself will not be destroyed until each copy and the original are closed with CloseHandle.  It does not matter what order they are freed in, however, each Handle can only be freed once.&lt;br /&gt;
&lt;br /&gt;
There are two ways of cloning.  A plugin can either clone a Handle itself, and become the owner, or it can explicitly set a new owner.  The difference is one of API design.  Example of the former:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DataBase g_hSQL;&lt;br /&gt;
/**&lt;br /&gt;
 * The other plugin calling this function must pass his ID in,&lt;br /&gt;
 * but doesn't have to call CloneHandle()&lt;br /&gt;
 */&lt;br /&gt;
public Database GetGlobalSQL(Handle otherPlugin)&lt;br /&gt;
{&lt;br /&gt;
   return view_as&amp;lt;DataBase&amp;gt;(CloneHandle(g_hSQL, otherPlugin));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This code would appear in the other plugin&lt;br /&gt;
 */&lt;br /&gt;
DataBase sql = GetGlobalSQL(myself);&lt;br /&gt;
/* ... */&lt;br /&gt;
delete sql;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of the latter:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DataBase g_hSQL;&lt;br /&gt;
/**&lt;br /&gt;
 * The calling plugin must call CloneHandle() himself.&lt;br /&gt;
 */&lt;br /&gt;
public DataBase GetGlobalSQL()&lt;br /&gt;
{&lt;br /&gt;
   return g_hSQL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This code would appear in the other plugin&lt;br /&gt;
 */&lt;br /&gt;
DataBase sql = GetGlobalSQL();&lt;br /&gt;
if (sql != INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
   sql = view_as&amp;lt;DataBase&amp;gt;(CloneHandle(sql));&lt;br /&gt;
}&lt;br /&gt;
delete sql;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Handle Types=&lt;br /&gt;
The following is a list of some common Handle types provided by SourceMod and some documentation on each.  Some Handles are exposed, by name, so that Extensions can create Handles of this type.  An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;HandleType_t g_DataPackType;&lt;br /&gt;
&lt;br /&gt;
handlesys-&amp;gt;FindHandleType(&amp;quot;DataPack&amp;quot;, &amp;amp;g_DataPackType);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==BitBuffers==&lt;br /&gt;
{{HandleType|bf_read or bf_write|Only if explicitly stated|Only if it can also be closed|Core|bitbuffer.inc}}&lt;br /&gt;
&lt;br /&gt;
There are four types of BitBuffer Handles.  They are separated into ''bf_write'' (writable buffer) and ''bf_read'' (readable buffer).  These are directly abstracted from their Half-Life 2 counterpart.  Internally, there are separate Handle types for each; certain functions will use BitBuffer handles that cannot be freed.&lt;br /&gt;
&lt;br /&gt;
==ConVars==&lt;br /&gt;
{{HandleType|ConVar|No|No|Core|convars.inc}}&lt;br /&gt;
&lt;br /&gt;
ConVar Handles are primarily used for getting and setting a console variable's value. They cannot be cloned nor deleted since they exist until SourceMod is shut down.&lt;br /&gt;
&lt;br /&gt;
==DataPacks==&lt;br /&gt;
{{HandleType|DataPack|Yes|Yes|Core|datapack.inc}}&lt;br /&gt;
&lt;br /&gt;
DataPack Handles are used to pack data into a sequential stream, for unpacking later.  They are unidirectional, meaning that reading and writing affects the same position in the stream.&lt;br /&gt;
&lt;br /&gt;
The DataPack type is exposed for Extensions to use.&lt;br /&gt;
&lt;br /&gt;
==Directories==&lt;br /&gt;
{{HandleType|Directory|Yes|Yes|Core|files.inc}}&lt;br /&gt;
&lt;br /&gt;
Directory Handles are used for opening and enumerating the contents of a directory (folder) on the filesystem.&lt;br /&gt;
&lt;br /&gt;
==Database Drivers==&lt;br /&gt;
{{HandleType|DBDriver|Yes|No|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
DBDriver Handles contain information about a database driver.  They are static and cannot be closed.&lt;br /&gt;
&lt;br /&gt;
==Database Queries==&lt;br /&gt;
{{HandleType|IQuery|Yes|No|Core|dbi.inc}}&lt;br /&gt;
{{HandleType|IPreparedQuery|Yes|No|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
Database Queries wrap an &amp;lt;tt&amp;gt;IQuery&amp;lt;/tt&amp;gt; pointer for database queries.  Closing a query frees its resources, including any prepared statement information and any result sets.&lt;br /&gt;
&lt;br /&gt;
==Databases==&lt;br /&gt;
{{HandleType|IDatabase|Yes|Yes|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
Database Handles wrap an &amp;lt;tt&amp;gt;IDatabase&amp;lt;/tt&amp;gt; pointer for database connections.  Closing these disconnects the database and frees any related resources.&lt;br /&gt;
&lt;br /&gt;
==Events==&lt;br /&gt;
{{HandleType|Event|No|No|Core|events.inc}}&lt;br /&gt;
&lt;br /&gt;
Event Handles are used for getting and setting data in Half-Life 2 game events as well as for firing them. They can only be closed using CancelCreatedEvent() if the event was not fired for some reason.&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
{{HandleType|File|Yes|Yes|Core|files.inc}}&lt;br /&gt;
&lt;br /&gt;
File Handles are used for opening, reading from, writing to, and creating to files on the file system.&lt;br /&gt;
&lt;br /&gt;
==Forwards==&lt;br /&gt;
{{HandleType|Forward|Yes|Only if explicitly stated|Core|functions.inc}}&lt;br /&gt;
&lt;br /&gt;
Forward Handles are primarily used when calling functions inside a forward container. There are two types of forwards: global and private. Only private forwards can be cloned.&lt;br /&gt;
&lt;br /&gt;
==KeyValues==&lt;br /&gt;
{{HandleType|KeyValues|Yes|No|Core|keyvalues.inc}}&lt;br /&gt;
&lt;br /&gt;
KeyValues Handles abstract the Valve data type &amp;lt;tt&amp;gt;KeyValues&amp;lt;/tt&amp;gt;, which are tree-based, recursive key to value mapping structures, often used to enumerate properties or configuration file directives.&lt;br /&gt;
&lt;br /&gt;
==Plugins==&lt;br /&gt;
{{HandleType|Plugin|No|No|Core|sourcemod.inc}}&lt;br /&gt;
&lt;br /&gt;
Plugin Handles are used for the unique identification of a Plugin.  They are owned by Core and cannot be cloned or closed by any other plugin or extension.  However, plugins can use Handles for certain natives which enumerate or retrieve information on plugins.  &lt;br /&gt;
&lt;br /&gt;
Plugin Handles should not be cached globally, as plugins can become unloaded, and the Handle will be invalid.&lt;br /&gt;
&lt;br /&gt;
==Plugin Iterators==&lt;br /&gt;
{{HandleType|PluginIter|Yes|No|Core|sourcemod.inc}}&lt;br /&gt;
&lt;br /&gt;
Plugin Iterators allow you to walk over a list of plugins.  They are intended for temporary use only.&lt;br /&gt;
&lt;br /&gt;
==Protobuf==&lt;br /&gt;
{{HandleType|protobuf|No|No|Core|protobuf.inc}}&lt;br /&gt;
&lt;br /&gt;
Protobuf Handles are currently used for usermessages in supported games. They directly reference protobuf Messages, which can be a usermessage or a Message field inside of a usermessage. They are owned and managed by Core and cannot be cloned or closed by a plugin.&lt;br /&gt;
&lt;br /&gt;
==SMC Parsers==&lt;br /&gt;
{{HandleType|SMC Parser|Yes|No|Core|textparse.inc}}&lt;br /&gt;
&lt;br /&gt;
SMC Parsers are Handles which contain a set of functions for hooking parse events in an SMC file.  Since they directly reference functions in a plugin, they cannot be cloned.&lt;br /&gt;
&lt;br /&gt;
==Timers==&lt;br /&gt;
{{HandleType|Timer|Yes|No|Core|timers.inc}}&lt;br /&gt;
&lt;br /&gt;
Timers are temporary Handles which are automatically closed on any of the following events:&lt;br /&gt;
*The timer ends (via Plugin_Stop or being a one-time timer that is finished)&lt;br /&gt;
*The timer is killed via &amp;lt;tt&amp;gt;KillTimer&amp;lt;/tt&amp;gt;&lt;br /&gt;
*The timer is closed via &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;&lt;br /&gt;
*The timer's parent plugin unloads&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Handles_(SourceMod_Scripting)&amp;diff=10173</id>
		<title>Handles (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Handles_(SourceMod_Scripting)&amp;diff=10173"/>
		<updated>2016-06-17T12:24:16Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated to 1.7 Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Handles are a special data type used in [[:Category:SourceMod Scripting|SourceMod Scripting]].  They represent a single internal and unique object.  For example, there are &amp;quot;File&amp;quot; Handles for files, and &amp;quot;Menu&amp;quot; Handles for menus, but they are both encapsulated under the &amp;quot;Handle&amp;quot; [[Tags (SourceMod Scripting)|tag]].&lt;br /&gt;
&lt;br /&gt;
Handles are more than &amp;quot;pointers&amp;quot; from C or C++ because they have a ''reference count''.  This means that the number of copies floating around in memory is tracked.  The actual internal object is not destroyed until each copy is also destroyed.&lt;br /&gt;
&lt;br /&gt;
Since SourcePawn does not have [[Garbage Collection]], Handles are a special way of intelligently allowing plugins and SourceMod to manage their own memory.&lt;br /&gt;
&lt;br /&gt;
For more information on using Handles in the SourceMod API, see [[Handle API (SourceMod)]].&lt;br /&gt;
&lt;br /&gt;
=Opening Handles=&lt;br /&gt;
Opening a Handle is usually done implicitly by a native function.  For example, OpenDirectory opens a new Handle which is used in other Directory natives.  This associates a ''type'' with the Handle.  Trying to use a Directory Handle with any other non-Directory native will cause an error (HandleError_Type), because Handles are type checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Handle hndl = OpenDirectory(&amp;quot;addons/sourcemod/configs&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Closing Handles=&lt;br /&gt;
==Basic operation==&lt;br /&gt;
Closing a Handle means seeing if the internal object can be removed from memory.  For example, if a plugin creates an SQL connection, closing the Handle means closing and destroying the connection.  This is almost always done using the CloseHandle() native function.&lt;br /&gt;
&lt;br /&gt;
==When to close==&lt;br /&gt;
When a plugin unloads, all of its Handles are automatically destroyed.  This does not mean, however, that closing Handles is optional.  Consider the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock bool IsFileInFolder(const char[] path, const char[] file)&lt;br /&gt;
{&lt;br /&gt;
	char path[PLATFORM_MAX_PATH];&lt;br /&gt;
	FileType type;&lt;br /&gt;
&lt;br /&gt;
	Handle dir = OpenDirectory(path);&lt;br /&gt;
	if (dir == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	while (ReadDirEntry(dir, path, sizeof(path), type))&lt;br /&gt;
	{&lt;br /&gt;
		if (type == FileType_File &amp;amp;&amp;amp; StrEqual(path, file))&lt;br /&gt;
		{&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	delete dir;&lt;br /&gt;
&lt;br /&gt;
	return false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function searches a directory for a single file.  If this function were to omit the call to CloseHandle, it would [[Memory Leak|leak memory]] every time it was called, and eventually the script would fill up with a large number of lingering Handles that were left open.&lt;br /&gt;
&lt;br /&gt;
So, when do you close Handles?  There are generally two rules of thumb to go by:&lt;br /&gt;
*If the native uses terminology such as &amp;quot;Opens a [...]&amp;quot; or &amp;quot;Creates a [...]&amp;quot; or gives explicit directions for closing.&lt;br /&gt;
*If the Handle represents a temporary object or piece of information, and you will no longer be using it.&lt;br /&gt;
&lt;br /&gt;
Most of the time, you will be closing Handles.  Check the Handle Type documentation at the end of this page.&lt;br /&gt;
&lt;br /&gt;
==When you can't close==&lt;br /&gt;
There are a few Handle types that cannot be closed.  The major one is the Handle which identifies a plugin.  Plugins cannot unload themselves, and thus destroying their own Handles is not allowed.&lt;br /&gt;
&lt;br /&gt;
Furthermore, a script cannot close a Handle that is owned by another plugin.  This is for protection against API mistakes and accidental errors.  For example, if a Handle is shared between two plugins, one accidental free could invalidate a Handle unexpectedly.  To allow the sharing of Handles, see [[#Cloning Handles|Cloning Handles]].&lt;br /&gt;
&lt;br /&gt;
==Reference counters==&lt;br /&gt;
Closing Handles does not always destroy the internal data.  This is the case when Handles are [[#Cloning Handles|cloned]].  Each clone adds a ''reference count'' to the Handle, and closing each clone removes one reference count.  The original object is only actually destroyed once the Handle has no more reference counters.  &lt;br /&gt;
&lt;br /&gt;
=Cloning Handles=&lt;br /&gt;
As briefly described earlier, there is a problem when scripts try to share Handles.  Imagine this scenario:&lt;br /&gt;
*Plugin 'A' creates a Handle.&lt;br /&gt;
*Plugin 'B' received the Handle.&lt;br /&gt;
*Plugin 'A' is unloaded, and the Handle is destroyed.&lt;br /&gt;
*Plugin 'B' tries to use the Handle.&lt;br /&gt;
&lt;br /&gt;
To prevent this, the CloneHandle native is provided.  This function returns a ''new'' Handle that is a &amp;quot;copy&amp;quot; of the original.  While their values won't be equal, they contain the same internal data.  The data itself will not be destroyed until each copy and the original are closed with CloseHandle.  It does not matter what order they are freed in, however, each Handle can only be freed once.&lt;br /&gt;
&lt;br /&gt;
There are two ways of cloning.  A plugin can either clone a Handle itself, and become the owner, or it can explicitly set a new owner.  The difference is one of API design.  Example of the former:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:g_hSQL;&lt;br /&gt;
/**&lt;br /&gt;
 * The other plugin calling this function must pass his ID in,&lt;br /&gt;
 * but doesn't have to call CloneHandle()&lt;br /&gt;
 */&lt;br /&gt;
public Handle:GetGlobalSQL(Handle:otherPlugin)&lt;br /&gt;
{&lt;br /&gt;
   return CloneHandle(g_hSQL, otherPlugin);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This code would appear in the other plugin&lt;br /&gt;
 */&lt;br /&gt;
new Handle:sql = GetGlobalSQL(myself);&lt;br /&gt;
/* ... */&lt;br /&gt;
CloseHandle(sql);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of the latter:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:g_hSQL;&lt;br /&gt;
/**&lt;br /&gt;
 * The calling plugin must call CloneHandle() himself.&lt;br /&gt;
 */&lt;br /&gt;
public Handle:GetGlobalSQL()&lt;br /&gt;
{&lt;br /&gt;
   return g_hSQL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This code would appear in the other plugin&lt;br /&gt;
 */&lt;br /&gt;
new Handle:sql = GetGlobalSQL();&lt;br /&gt;
if (sql != INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
   sql = CloneHandle(sql);&lt;br /&gt;
}&lt;br /&gt;
CloseHandle(sql);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Handle Types=&lt;br /&gt;
The following is a list of some common Handle types provided by SourceMod and some documentation on each.  Some Handles are exposed, by name, so that Extensions can create Handles of this type.  An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;HandleType_t g_DataPackType;&lt;br /&gt;
&lt;br /&gt;
handlesys-&amp;gt;FindHandleType(&amp;quot;DataPack&amp;quot;, &amp;amp;g_DataPackType);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==BitBuffers==&lt;br /&gt;
{{HandleType|bf_read or bf_write|Only if explicitly stated|Only if it can also be closed|Core|bitbuffer.inc}}&lt;br /&gt;
&lt;br /&gt;
There are four types of BitBuffer Handles.  They are separated into ''bf_write'' (writable buffer) and ''bf_read'' (readable buffer).  These are directly abstracted from their Half-Life 2 counterpart.  Internally, there are separate Handle types for each; certain functions will use BitBuffer handles that cannot be freed.&lt;br /&gt;
&lt;br /&gt;
==ConVars==&lt;br /&gt;
{{HandleType|ConVar|No|No|Core|convars.inc}}&lt;br /&gt;
&lt;br /&gt;
ConVar Handles are primarily used for getting and setting a console variable's value. They cannot be cloned nor deleted since they exist until SourceMod is shut down.&lt;br /&gt;
&lt;br /&gt;
==DataPacks==&lt;br /&gt;
{{HandleType|DataPack|Yes|Yes|Core|datapack.inc}}&lt;br /&gt;
&lt;br /&gt;
DataPack Handles are used to pack data into a sequential stream, for unpacking later.  They are unidirectional, meaning that reading and writing affects the same position in the stream.&lt;br /&gt;
&lt;br /&gt;
The DataPack type is exposed for Extensions to use.&lt;br /&gt;
&lt;br /&gt;
==Directories==&lt;br /&gt;
{{HandleType|Directory|Yes|Yes|Core|files.inc}}&lt;br /&gt;
&lt;br /&gt;
Directory Handles are used for opening and enumerating the contents of a directory (folder) on the filesystem.&lt;br /&gt;
&lt;br /&gt;
==Database Drivers==&lt;br /&gt;
{{HandleType|DBDriver|Yes|No|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
DBDriver Handles contain information about a database driver.  They are static and cannot be closed.&lt;br /&gt;
&lt;br /&gt;
==Database Queries==&lt;br /&gt;
{{HandleType|IQuery|Yes|No|Core|dbi.inc}}&lt;br /&gt;
{{HandleType|IPreparedQuery|Yes|No|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
Database Queries wrap an &amp;lt;tt&amp;gt;IQuery&amp;lt;/tt&amp;gt; pointer for database queries.  Closing a query frees its resources, including any prepared statement information and any result sets.&lt;br /&gt;
&lt;br /&gt;
==Databases==&lt;br /&gt;
{{HandleType|IDatabase|Yes|Yes|Core|dbi.inc}}&lt;br /&gt;
&lt;br /&gt;
Database Handles wrap an &amp;lt;tt&amp;gt;IDatabase&amp;lt;/tt&amp;gt; pointer for database connections.  Closing these disconnects the database and frees any related resources.&lt;br /&gt;
&lt;br /&gt;
==Events==&lt;br /&gt;
{{HandleType|Event|No|No|Core|events.inc}}&lt;br /&gt;
&lt;br /&gt;
Event Handles are used for getting and setting data in Half-Life 2 game events as well as for firing them. They can only be closed using CancelCreatedEvent() if the event was not fired for some reason.&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
{{HandleType|File|Yes|Yes|Core|files.inc}}&lt;br /&gt;
&lt;br /&gt;
File Handles are used for opening, reading from, writing to, and creating to files on the file system.&lt;br /&gt;
&lt;br /&gt;
==Forwards==&lt;br /&gt;
{{HandleType|Forward|Yes|Only if explicitly stated|Core|functions.inc}}&lt;br /&gt;
&lt;br /&gt;
Forward Handles are primarily used when calling functions inside a forward container. There are two types of forwards: global and private. Only private forwards can be cloned.&lt;br /&gt;
&lt;br /&gt;
==KeyValues==&lt;br /&gt;
{{HandleType|KeyValues|Yes|No|Core|keyvalues.inc}}&lt;br /&gt;
&lt;br /&gt;
KeyValues Handles abstract the Valve data type &amp;lt;tt&amp;gt;KeyValues&amp;lt;/tt&amp;gt;, which are tree-based, recursive key to value mapping structures, often used to enumerate properties or configuration file directives.&lt;br /&gt;
&lt;br /&gt;
==Plugins==&lt;br /&gt;
{{HandleType|Plugin|No|No|Core|sourcemod.inc}}&lt;br /&gt;
&lt;br /&gt;
Plugin Handles are used for the unique identification of a Plugin.  They are owned by Core and cannot be cloned or closed by any other plugin or extension.  However, plugins can use Handles for certain natives which enumerate or retrieve information on plugins.  &lt;br /&gt;
&lt;br /&gt;
Plugin Handles should not be cached globally, as plugins can become unloaded, and the Handle will be invalid.&lt;br /&gt;
&lt;br /&gt;
==Plugin Iterators==&lt;br /&gt;
{{HandleType|PluginIter|Yes|No|Core|sourcemod.inc}}&lt;br /&gt;
&lt;br /&gt;
Plugin Iterators allow you to walk over a list of plugins.  They are intended for temporary use only.&lt;br /&gt;
&lt;br /&gt;
==Protobuf==&lt;br /&gt;
{{HandleType|protobuf|No|No|Core|protobuf.inc}}&lt;br /&gt;
&lt;br /&gt;
Protobuf Handles are currently used for usermessages in supported games. They directly reference protobuf Messages, which can be a usermessage or a Message field inside of a usermessage. They are owned and managed by Core and cannot be cloned or closed by a plugin.&lt;br /&gt;
&lt;br /&gt;
==SMC Parsers==&lt;br /&gt;
{{HandleType|SMC Parser|Yes|No|Core|textparse.inc}}&lt;br /&gt;
&lt;br /&gt;
SMC Parsers are Handles which contain a set of functions for hooking parse events in an SMC file.  Since they directly reference functions in a plugin, they cannot be cloned.&lt;br /&gt;
&lt;br /&gt;
==Timers==&lt;br /&gt;
{{HandleType|Timer|Yes|No|Core|timers.inc}}&lt;br /&gt;
&lt;br /&gt;
Timers are temporary Handles which are automatically closed on any of the following events:&lt;br /&gt;
*The timer ends (via Plugin_Stop or being a one-time timer that is finished)&lt;br /&gt;
*The timer is killed via &amp;lt;tt&amp;gt;KillTimer&amp;lt;/tt&amp;gt;&lt;br /&gt;
*The timer is closed via &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;&lt;br /&gt;
*The timer's parent plugin unloads&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10172</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10172"/>
		<updated>2016-06-17T12:19:02Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated to 1.7 Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== Menu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Menu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [https://sm.alliedmods.net/new-api/menus/MenuHandler MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== menu.SetTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== menu.AddItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(menu, CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(menu, CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
menu.AddItem has 2 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 3 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Menu handle, the Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitBackButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== menu.Display ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.Display(client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 2 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.  Previous versions of this guide suggested using SetMenuTitle.  This is a ''bad'' idea, as it changes the title globally.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetInfo(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10171</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10171"/>
		<updated>2016-06-17T12:14:56Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Step by Step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== CreateMenu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Menu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [https://sm.alliedmods.net/new-api/menus/MenuHandler MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== menu.SetTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== menu.AddItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(menu, CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(menu, CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
menu.AddItem has 2 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 3 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Menu handle, the Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitBackButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== DisplayMenu ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	DisplayMenu(menu, client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 3 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MenuHandler1(Handle:menu, MenuAction:action, param1, param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		decl String:buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			new Handle:panel = Handle:param2;&lt;br /&gt;
			SetPanelTitle(panel, buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.  Previous versions of this guide suggested using SetMenuTitle.  This is a ''bad'' idea, as it changes the title globally.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			CloseHandle(menu);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			new style;&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			decl String:display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10170</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10170"/>
		<updated>2016-06-17T12:11:15Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* OnPluginStart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== CreateMenu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	new Handle:menu = CreateMenu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CreateMenu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=768&amp;amp; MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	new Handle:menu = CreateMenu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SetMenuTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	SetMenuTitle(menu, &amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== AddMenuItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	AddMenuItem(menu, CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	AddMenuItem(menu, CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	AddMenuItem(menu, CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
AddMenuItem has 3 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 3 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Menu handle, the Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitBackButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== DisplayMenu ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	DisplayMenu(menu, client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 3 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MenuHandler1(Handle:menu, MenuAction:action, param1, param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		decl String:buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			new Handle:panel = Handle:param2;&lt;br /&gt;
			SetPanelTitle(panel, buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.  Previous versions of this guide suggested using SetMenuTitle.  This is a ''bad'' idea, as it changes the title globally.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			CloseHandle(menu);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			new style;&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			decl String:display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10169</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10169"/>
		<updated>2016-06-17T12:10:45Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated to 1.7 Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== CreateMenu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	new Handle:menu = CreateMenu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CreateMenu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=768&amp;amp; MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	new Handle:menu = CreateMenu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SetMenuTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	SetMenuTitle(menu, &amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== AddMenuItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	AddMenuItem(menu, CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	AddMenuItem(menu, CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	AddMenuItem(menu, CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
AddMenuItem has 3 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 3 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Menu handle, the Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== SetMenuExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	SetMenuExitBackButton(menu, false);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== DisplayMenu ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	DisplayMenu(menu, client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 3 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MenuHandler1(Handle:menu, MenuAction:action, param1, param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		decl String:buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			new Handle:panel = Handle:param2;&lt;br /&gt;
			SetPanelTitle(panel, buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.  Previous versions of this guide suggested using SetMenuTitle.  This is a ''bad'' idea, as it changes the title globally.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			CloseHandle(menu);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			new style;&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			decl String:info[32];&lt;br /&gt;
			GetMenuItem(menu, param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			decl String:display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=CHL2MP_Player_Offset_List_(Zombie_Panic:_Source)&amp;diff=10121</id>
		<title>CHL2MP Player Offset List (Zombie Panic: Source)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=CHL2MP_Player_Offset_List_(Zombie_Panic:_Source)&amp;diff=10121"/>
		<updated>2016-03-25T11:26:04Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also for use when using [[Virtual Offsets (Source Mods)|virtual offsets]].&lt;br /&gt;
&lt;br /&gt;
These are the &amp;lt;b&amp;gt;Linux&amp;lt;/b&amp;gt; offsets. &amp;lt;b&amp;gt;Windows offsets are 1 smaller.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The List ==&lt;br /&gt;
This comes from the symbol tables, so you'll have to look in the SDK for return types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Last Updated Mar 25th 2016&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Auto reconstructed from vtable block @ 0x012B7420&lt;br /&gt;
// from &amp;quot;server_i486.so&amp;quot;, by ida_vtables.idc&lt;br /&gt;
0	CHL2MP_Player::~CHL2MP_Player()&lt;br /&gt;
1	CHL2MP_Player::~CHL2MP_Player()&lt;br /&gt;
2	CBaseEntity::SetRefEHandle(CBaseHandle  const&amp;amp;)&lt;br /&gt;
3	CBaseEntity::GetRefEHandle(void)const&lt;br /&gt;
4	CBaseEntity::GetCollideable(void)&lt;br /&gt;
5	CBaseEntity::GetNetworkable(void)&lt;br /&gt;
6	CBaseEntity::GetBaseEntity(void)&lt;br /&gt;
7	CBaseEntity::GetModelIndex(void)const&lt;br /&gt;
8	CBaseEntity::GetModelName(void)const&lt;br /&gt;
9	CBaseEntity::SetModelIndex(int)&lt;br /&gt;
10	CHL2MP_Player::GetServerClass(void)&lt;br /&gt;
11	CHL2MP_Player::YouForgotToImplementOrDeclareServerClass(void)&lt;br /&gt;
12	CHL2MP_Player::GetDataDescMap(void)&lt;br /&gt;
13	CBaseAnimating::TestCollision(Ray_t  const&amp;amp;,unsigned int,CGameTrace &amp;amp;)&lt;br /&gt;
14	CHL2_Player::TestHitboxes(Ray_t  const&amp;amp;,unsigned int,CGameTrace &amp;amp;)&lt;br /&gt;
15	CBaseEntity::ComputeWorldSpaceSurroundingBox(Vector *,Vector *)&lt;br /&gt;
16	CHL2MP_Player::ShouldCollide(int,int)const&lt;br /&gt;
17	CBaseEntity::SetOwnerEntity(CBaseEntity*)&lt;br /&gt;
18	CBasePlayer::ShouldTransmit(CCheckTransmitInfo  const*)&lt;br /&gt;
19	CBasePlayer::UpdateTransmitState(void)&lt;br /&gt;
20	CBaseCombatCharacter::SetTransmit(CCheckTransmitInfo *,bool)&lt;br /&gt;
21	CBasePlayer::GetTracerType(void)&lt;br /&gt;
22	CHL2MP_Player::Spawn(void)&lt;br /&gt;
23	CBaseEntity::ZPASpawn(void)&lt;br /&gt;
24	CHL2MP_Player::Precache(void)&lt;br /&gt;
25	CBasePlayer::SetModel(char  const*)&lt;br /&gt;
26	CBaseEntity::PostConstructor(char  const*)&lt;br /&gt;
27	CBaseEntity::PostClientActive(void)&lt;br /&gt;
28	CBaseEntity::ParseMapData(CEntityMapData *)&lt;br /&gt;
29	CBaseEntity::KeyValue(char  const*,char  const*)&lt;br /&gt;
30	CBaseEntity::KeyValue(char  const*,float)&lt;br /&gt;
31	CBaseEntity::KeyValue(char  const*,Vector  const&amp;amp;)&lt;br /&gt;
32	CBaseEntity::GetKeyValue(char  const*,char *,int)&lt;br /&gt;
33	CHL2_Player::Activate(void)&lt;br /&gt;
34	CBaseEntity::SetParent(CBaseEntity*,int)&lt;br /&gt;
35	CBasePlayer::ObjectCaps(void)&lt;br /&gt;
36	CBaseEntity::AcceptInput(char  const*,CBaseEntity*,CBaseEntity*,variant_t,int)&lt;br /&gt;
37	CBaseAnimating::GetInputDispatchEffectPosition(char  const*,Vector &amp;amp;,QAngle &amp;amp;)&lt;br /&gt;
38	CHL2_Player::DrawDebugGeometryOverlays(void)&lt;br /&gt;
39	CBaseAnimating::DrawDebugTextOverlays(void)&lt;br /&gt;
40	CBasePlayer::Save(ISave &amp;amp;)&lt;br /&gt;
41	CBasePlayer::Restore(IRestore &amp;amp;)&lt;br /&gt;
42	CBasePlayer::ShouldSavePhysics(void)&lt;br /&gt;
43	CBaseEntity::OnSave(IEntitySaveUtils *)&lt;br /&gt;
44	CHL2_Player::OnRestore(void)&lt;br /&gt;
45	CBasePlayer::RequiredEdictIndex(void)&lt;br /&gt;
46	CBaseEntity::MoveDone(void)&lt;br /&gt;
47	CBaseEntity::Think(void)&lt;br /&gt;
48	CBasePlayer::NetworkStateChanged_m_nNextThinkTick(void)&lt;br /&gt;
49	CBasePlayer::NetworkStateChanged_m_nNextThinkTick(void *)&lt;br /&gt;
50	CBaseAnimating::GetBaseAnimating(void)&lt;br /&gt;
51	CBaseEntity::GetResponseSystem(void)&lt;br /&gt;
52	CBaseEntity::DispatchResponse(char  const*)&lt;br /&gt;
53	CHL2_Player::Classify(void)&lt;br /&gt;
54	CBaseEntity::DeathNotice(CBaseEntity*)&lt;br /&gt;
55	CBaseEntity::ShouldAttractAutoAim(CBaseEntity*)&lt;br /&gt;
56	CBaseEntity::GetAutoAimRadius(void)&lt;br /&gt;
57	CBaseEntity::GetAutoAimCenter(void)&lt;br /&gt;
58	CBaseEntity::GetBeamTraceFilter(void)&lt;br /&gt;
59	CHL2_Player::PassesDamageFilter(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
60	CBasePlayer::TraceAttack(CTakeDamageInfo  const&amp;amp;,Vector  const&amp;amp;,CGameTrace *)&lt;br /&gt;
61	CBaseEntity::CanBeHitByMeleeAttack(CBaseEntity*)&lt;br /&gt;
62	CHL2MP_Player::OnTakeDamage(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
63	CHL2MP_Player::TakeHealth(float,int)&lt;br /&gt;
64	CBaseEntity::IsAlive(void)&lt;br /&gt;
65	CHL2MP_Player::Event_Killed(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
66	CHL2_Player::Event_KilledOther(CBaseEntity *,CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
67	CBaseCombatCharacter::BloodColor(void)&lt;br /&gt;
68	CBaseEntity::IsTriggered(CBaseEntity*)&lt;br /&gt;
69	CBaseEntity::IsNPC(void)const&lt;br /&gt;
70	CBaseCombatCharacter::MyCombatCharacterPointer(void)&lt;br /&gt;
71	CBaseEntity::GetDelay(void)&lt;br /&gt;
72	CBaseEntity::IsMoving(void)&lt;br /&gt;
73	CBaseEntity::DamageDecal(int,int)&lt;br /&gt;
74	CBaseEntity::DecalTrace(CGameTrace *,char  const*)&lt;br /&gt;
75	CBaseEntity::ImpactTrace(CGameTrace *,int,char *)&lt;br /&gt;
76	CBaseEntity::OnControls(CBaseEntity*)&lt;br /&gt;
77	CBaseEntity::HasTarget(string_t)&lt;br /&gt;
78	CBasePlayer::IsPlayer(void)const&lt;br /&gt;
79	CBasePlayer::IsNetClient(void)const&lt;br /&gt;
80	CBaseEntity::IsTemplate(void)&lt;br /&gt;
81	CBaseEntity::IsBaseObject(void)const&lt;br /&gt;
82	CBaseEntity::IsBaseTrain(void)const&lt;br /&gt;
83	CBaseEntity::IsPlayerUsableItem(void)&lt;br /&gt;
84	CBaseEntity::GetItemTypeID(void)&lt;br /&gt;
85	CBaseEntity::GetServerVehicle(void)&lt;br /&gt;
86	CBaseEntity::IsViewable(void)&lt;br /&gt;
87	CBasePlayer::GetZPMTeam(void)const&lt;br /&gt;
88	CHL2MP_Player::ChangeTeam(int)&lt;br /&gt;
89	CBaseEntity::OnEntityEvent(EntityEvent_t,void *)&lt;br /&gt;
90	CBaseEntity::CanStandOn(CBaseEntity*)const&lt;br /&gt;
91	CBaseEntity::CanStandOn(edict_t *)const&lt;br /&gt;
92	CBaseEntity::GetEnemy(void)&lt;br /&gt;
93	CBaseEntity::GetEnemy(void)const&lt;br /&gt;
94	CBaseEntity::Use(CBaseEntity*,CBaseEntity*,USE_TYPE,float)&lt;br /&gt;
95	CBaseEntity::StartTouch(CBaseEntity*)&lt;br /&gt;
96	CBasePlayer::Touch(CBaseEntity *)&lt;br /&gt;
97	CBaseEntity::EndTouch(CBaseEntity*)&lt;br /&gt;
98	CBaseEntity::StartBlocked(CBaseEntity*)&lt;br /&gt;
99	CBaseEntity::Blocked(CBaseEntity*)&lt;br /&gt;
100	CBaseEntity::EndBlocked(void)&lt;br /&gt;
101	CBasePlayer::PhysicsSimulate(void)&lt;br /&gt;
102	CHL2MP_Player::UpdateOnRemove(void)&lt;br /&gt;
103	CHL2_Player::StopLoopingSounds(void)&lt;br /&gt;
104	CBaseEntity::SUB_AllowedToFade(void)&lt;br /&gt;
105	CBaseFlex::Teleport(Vector  const*,QAngle  const*,Vector  const*)&lt;br /&gt;
106	CBaseEntity::NotifySystemEvent(CBaseEntity*,notify_system_event_t,notify_system_event_params_t  const&amp;amp;)&lt;br /&gt;
107	CBasePlayer::MakeTracer(Vector  const&amp;amp;,CGameTrace  const&amp;amp;,int)&lt;br /&gt;
108	CBaseEntity::GetTracerAttachment(void)&lt;br /&gt;
109	CHL2MP_Player::FireBullets(FireBulletsInfo_t  const&amp;amp;)&lt;br /&gt;
110	CBasePlayer::DoImpactEffect(CGameTrace &amp;amp;,int)&lt;br /&gt;
111	CBaseEntity::Respawn(void)&lt;br /&gt;
112	CBaseEntity::IsLockedByMaster(void)&lt;br /&gt;
113	CBaseAnimating::ModifyOrAppendCriteria(AI_CriteriaSet &amp;amp;)&lt;br /&gt;
114	CBaseEntity::NetworkStateChanged_m_iMaxHealth(void)&lt;br /&gt;
115	CBaseEntity::NetworkStateChanged_m_iMaxHealth(void *)&lt;br /&gt;
116	CBasePlayer::NetworkStateChanged_m_iHealth(void)&lt;br /&gt;
117	CBasePlayer::NetworkStateChanged_m_iHealth(void *)&lt;br /&gt;
118	CBasePlayer::NetworkStateChanged_m_lifeState(void)&lt;br /&gt;
119	CBasePlayer::NetworkStateChanged_m_lifeState(void *)&lt;br /&gt;
120	CBaseEntity::NetworkStateChanged_m_takedamage(void)&lt;br /&gt;
121	CBaseEntity::NetworkStateChanged_m_takedamage(void *)&lt;br /&gt;
122	CBaseEntity::GetDamageType(void)const&lt;br /&gt;
123	CBaseEntity::GetDamage(void)&lt;br /&gt;
124	CBaseEntity::SetDamage(float)&lt;br /&gt;
125	CBasePlayer::EyePosition(void)&lt;br /&gt;
126	CBasePlayer::EyeAngles(void)&lt;br /&gt;
127	CBasePlayer::LocalEyeAngles(void)&lt;br /&gt;
128	CBaseEntity::EarPosition(void)&lt;br /&gt;
129	CBasePlayer::BodyTarget(Vector  const&amp;amp;,bool)&lt;br /&gt;
130	CBaseEntity::HeadTarget(Vector  const&amp;amp;)&lt;br /&gt;
131	CBaseEntity::GetVectors(Vector *,Vector *,Vector *)const&lt;br /&gt;
132	CBaseEntity::GetViewOffset(void)&lt;br /&gt;
133	CBasePlayer::GetSmoothedVelocity(void)&lt;br /&gt;
134	CBaseAnimating::GetVelocity(Vector *,Vector *)&lt;br /&gt;
135	CBaseCombatCharacter::FVisible(CBaseEntity *,int,CBaseEntity **)&lt;br /&gt;
136	CBaseCombatCharacter::FVisible(Vector  const&amp;amp;,int,CBaseEntity **)&lt;br /&gt;
137	CBaseEntity::CanBeSeenBy(CAI_BaseNPC *)&lt;br /&gt;
138	CBaseEntity::GetAttackDamageScale(CBaseEntity*)&lt;br /&gt;
139	CBaseEntity::GetReceivedDamageScale(CBaseEntity*)&lt;br /&gt;
140	CBasePlayer::SetGroundEntity(CBaseEntity *)&lt;br /&gt;
141	CBaseEntity::GetGroundEntity(void)&lt;br /&gt;
142	CBaseEntity::GetGroundVelocityToApply(Vector &amp;amp;)&lt;br /&gt;
143	CBaseEntity::PhysicsSplash(Vector  const&amp;amp;,Vector  const&amp;amp;,float,float)&lt;br /&gt;
144	CHL2_Player::Splash(void)&lt;br /&gt;
145	CBaseEntity::WorldSpaceCenter(void)const&lt;br /&gt;
146	CBaseEntity::GetSoundEmissionOrigin(void)const&lt;br /&gt;
147	CBaseEntity::CreateVPhysics(void)&lt;br /&gt;
148	CBaseEntity::ForceVPhysicsCollide(CBaseEntity*)&lt;br /&gt;
149	CBasePlayer::VPhysicsDestroyObject(void)&lt;br /&gt;
150	CBasePlayer::VPhysicsUpdate(IPhysicsObject *)&lt;br /&gt;
151	CBaseEntity::VPhysicsTakeDamage(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
152	CBaseCombatCharacter::VPhysicsShadowCollision(int,gamevcollisionevent_t *)&lt;br /&gt;
153	CBasePlayer::VPhysicsShadowUpdate(IPhysicsObject *)&lt;br /&gt;
154	CBasePlayer::VPhysicsCollision(int,gamevcollisionevent_t *)&lt;br /&gt;
155	CBaseEntity::VPhysicsFriction(IPhysicsObject *,float,int,int)&lt;br /&gt;
156	CBaseEntity::UpdatePhysicsShadowToCurrentPosition(float)&lt;br /&gt;
157	CBaseEntity::VPhysicsGetObjectList(IPhysicsObject **,int)&lt;br /&gt;
158	CBaseEntity::VPhysicsIsFlesh(void)&lt;br /&gt;
159	CBaseEntity::HasPhysicsAttacker(float)&lt;br /&gt;
160	CBasePlayer::PhysicsSolidMaskForEntity(void)const&lt;br /&gt;
161	CBaseEntity::ResolveFlyCollisionCustom(CGameTrace &amp;amp;,Vector &amp;amp;)&lt;br /&gt;
162	CBaseEntity::PerformCustomPhysics(Vector *,Vector *,QAngle *,QAngle *)&lt;br /&gt;
163	CBaseAnimating::GetStepOrigin(void)const&lt;br /&gt;
164	CBaseAnimating::GetStepAngles(void)const&lt;br /&gt;
165	CBaseEntity::ShouldDrawWaterImpacts(void)&lt;br /&gt;
166	CBasePlayer::NetworkStateChanged_m_fFlags(void)&lt;br /&gt;
167	CBasePlayer::NetworkStateChanged_m_fFlags(void *)&lt;br /&gt;
168	CBasePlayer::NetworkStateChanged_m_nWaterLevel(void)&lt;br /&gt;
169	CBasePlayer::NetworkStateChanged_m_nWaterLevel(void *)&lt;br /&gt;
170	CBasePlayer::NetworkStateChanged_m_hGroundEntity(void)&lt;br /&gt;
171	CBasePlayer::NetworkStateChanged_m_hGroundEntity(void *)&lt;br /&gt;
172	CBasePlayer::NetworkStateChanged_m_vecBaseVelocity(void)&lt;br /&gt;
173	CBasePlayer::NetworkStateChanged_m_vecBaseVelocity(void *)&lt;br /&gt;
174	CBasePlayer::NetworkStateChanged_m_flFriction(void)&lt;br /&gt;
175	CBasePlayer::NetworkStateChanged_m_flFriction(void *)&lt;br /&gt;
176	CBasePlayer::NetworkStateChanged_m_vecVelocity(void)&lt;br /&gt;
177	CBasePlayer::NetworkStateChanged_m_vecVelocity(void *)&lt;br /&gt;
178	CBasePlayer::NetworkStateChanged_m_vecViewOffset(void)&lt;br /&gt;
179	CBasePlayer::NetworkStateChanged_m_vecViewOffset(void *)&lt;br /&gt;
180	CBaseAnimating::Hide(void)&lt;br /&gt;
181	CBaseAnimating::GetIdealSpeed(void)const&lt;br /&gt;
182	CBaseAnimating::GetIdealAccel(void)const&lt;br /&gt;
183	CBaseAnimatingOverlay::StudioFrameAdvance(void)&lt;br /&gt;
184	CBaseAnimating::IsActivityFinished(void)&lt;br /&gt;
185	CBaseAnimating::GetSequenceGroundSpeed(CStudioHdr *,int)&lt;br /&gt;
186	CBaseAnimating::ClampRagdollForce(Vector  const&amp;amp;,Vector*)&lt;br /&gt;
187	CHL2MP_Player::BecomeRagdollOnClient(Vector  const&amp;amp;)&lt;br /&gt;
188	CBaseAnimating::IsRagdoll(void)&lt;br /&gt;
189	CBaseAnimating::CanBecomeRagdoll(void)&lt;br /&gt;
190	CBaseAnimatingOverlay::GetSkeleton(CStudioHdr *,Vector *,Quaternion *,int)&lt;br /&gt;
191	CBaseAnimating::GetBoneTransform(int,matrix3x4_t &amp;amp;)&lt;br /&gt;
192	CBaseAnimating::SetupBones(matrix3x4_t *,int)&lt;br /&gt;
193	CBaseAnimating::CalculateIKLocks(float)&lt;br /&gt;
194	CBaseAnimatingOverlay::DispatchAnimEvents(CBaseAnimating *)&lt;br /&gt;
195	CBasePlayer::HandleAnimEvent(animevent_t *)&lt;br /&gt;
196	CBaseAnimating::PopulatePoseParameters(void)&lt;br /&gt;
197	CBaseAnimating::GetAttachment(int,matrix3x4_t &amp;amp;)&lt;br /&gt;
198	CBaseAnimating::InitBoneControllers(void)&lt;br /&gt;
199	CBaseAnimating::GetGroundSpeedVelocity(void)&lt;br /&gt;
200	CBaseAnimating::Ignite(float,bool,float,bool)&lt;br /&gt;
201	CBaseAnimating::IgniteLifetime(float)&lt;br /&gt;
202	CBaseAnimating::IgniteNumHitboxFires(int)&lt;br /&gt;
203	CBaseAnimating::IgniteHitboxFireScale(float)&lt;br /&gt;
204	CBaseAnimating::Extinguish(void)&lt;br /&gt;
205	CBaseCombatCharacter::SetLightingOriginRelative(CBaseEntity *)&lt;br /&gt;
206	CBaseAnimating::SetLightingOrigin(CBaseEntity *)&lt;br /&gt;
207	CBaseFlex::SetViewtarget(Vector  const&amp;amp;)&lt;br /&gt;
208	CBaseFlex::StartSceneEvent(CSceneEventInfo *,CChoreoScene *,CChoreoEvent *,CChoreoActor *,CBaseEntity *)&lt;br /&gt;
209	CBaseFlex::ProcessSceneEvents(void)&lt;br /&gt;
210	CBaseFlex::ProcessSceneEvent(CSceneEventInfo *,CChoreoScene *,CChoreoEvent *)&lt;br /&gt;
211	CBaseFlex::ClearSceneEvent(CSceneEventInfo *,bool,bool)&lt;br /&gt;
212	CBaseFlex::CheckSceneEventCompletion(CSceneEventInfo *,float,CChoreoScene *,CChoreoEvent *)&lt;br /&gt;
213	CBaseFlex::PlayScene(char  const*,float,AI_Response *,IRecipientFilter *)&lt;br /&gt;
214	CBaseFlex::PlayAutoGeneratedSoundScene(char  const*)&lt;br /&gt;
215	CHL2_Player::GetPhysicsImpactDamageTable(void)&lt;br /&gt;
216	CBaseCombatCharacter::FInViewCone(CBaseEntity *)&lt;br /&gt;
217	CBaseCombatCharacter::FInViewCone(Vector  const&amp;amp;)&lt;br /&gt;
218	CBaseCombatCharacter::FInAimCone(CBaseEntity *)&lt;br /&gt;
219	CBaseCombatCharacter::FInAimCone(Vector  const&amp;amp;)&lt;br /&gt;
220	CHL2_Player::ShouldShootMissTarget(CBaseCombatCharacter *)&lt;br /&gt;
221	CBaseCombatCharacter::FindMissTarget(void)&lt;br /&gt;
222	CHL2_Player::HandleInteraction(int,void *,CBaseCombatCharacter *)&lt;br /&gt;
223	CBasePlayer::BodyAngles(void)&lt;br /&gt;
224	CBaseCombatCharacter::BodyDirection2D(void)&lt;br /&gt;
225	CBaseCombatCharacter::BodyDirection3D(void)&lt;br /&gt;
226	CBaseCombatCharacter::HeadDirection2D(void)&lt;br /&gt;
227	CBaseCombatCharacter::HeadDirection3D(void)&lt;br /&gt;
228	CHL2_Player::EyeDirection2D(void)&lt;br /&gt;
229	CHL2_Player::EyeDirection3D(void)&lt;br /&gt;
230	CHL2MP_Player::GiveAmmo(int,int,bool)&lt;br /&gt;
231	CBaseCombatCharacter::NPC_TranslateActivity(Activity)&lt;br /&gt;
232	CBaseCombatCharacter::Weapon_TranslateActivity(Activity,bool *)&lt;br /&gt;
233	CBaseCombatCharacter::Weapon_FrameUpdate(void)&lt;br /&gt;
234	CBaseCombatCharacter::Weapon_HandleAnimEvent(animevent_t *)&lt;br /&gt;
235	CHL2_Player::Weapon_CanUse(CBaseCombatWeapon *)&lt;br /&gt;
236	CHL2_Player::Weapon_Equip(CBaseCombatWeapon *)&lt;br /&gt;
237	CBaseCombatCharacter::Weapon_EquipAmmoOnly(CBaseCombatWeapon *)&lt;br /&gt;
238	CHL2MP_Player::Weapon_Drop(CBaseCombatWeapon *,Vector  const*,Vector  const*)&lt;br /&gt;
239	CHL2MP_Player::Weapon_Switch(CBaseCombatWeapon *,int,bool)&lt;br /&gt;
240	CBasePlayer::Weapon_ShootPosition(void)&lt;br /&gt;
241	CHL2_Player::Weapon_CanSwitchTo(CBaseCombatWeapon *)&lt;br /&gt;
242	CBaseCombatCharacter::Weapon_SlotOccupied(CBaseCombatWeapon *)&lt;br /&gt;
243	CBaseCombatCharacter::Weapon_GetSlot(int)const&lt;br /&gt;
244	CBaseCombatCharacter::Weapon_SetSlot(int,CBaseCombatWeapon *)&lt;br /&gt;
245	CBaseCombatCharacter::Weapon_CleanupSlot(int)&lt;br /&gt;
246	CBaseCombatCharacter::Weapon_DeleteSlot(int)&lt;br /&gt;
247	CBaseCombatCharacter::AddPlayerItem(CBaseCombatWeapon *)&lt;br /&gt;
248	CBasePlayer::RemovePlayerItem(CBaseCombatWeapon *)&lt;br /&gt;
249	CBaseCombatCharacter::CanBecomeServerRagdoll(void)&lt;br /&gt;
250	CHL2_Player::OnTakeDamage_Alive(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
251	CBaseCombatCharacter::OnTakeDamage_Dying(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
252	CBaseCombatCharacter::OnTakeDamage_Dead(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
253	CBaseCombatCharacter::OnFriendDamaged(CBaseCombatCharacter*,CBaseEntity *)&lt;br /&gt;
254	CHL2_Player::NotifyFriendsOfDamage(CBaseEntity *)&lt;br /&gt;
255	CBaseCombatCharacter::OnPlayerKilledOther(CBaseEntity *,CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
256	CBaseCombatCharacter::GetDeathActivity(void)&lt;br /&gt;
257	CBaseCombatCharacter::CorpseGib(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
258	CBaseCombatCharacter::CorpseFade(void)&lt;br /&gt;
259	CBaseCombatCharacter::HasHumanGibs(void)&lt;br /&gt;
260	CBaseCombatCharacter::HasAlienGibs(void)&lt;br /&gt;
261	CHL2MP_Player::ShouldGib(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
262	CBaseCombatCharacter::OnKilledNPC(CBaseCombatCharacter*)&lt;br /&gt;
263	CBaseCombatCharacter::Event_Gibbed(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
264	CBasePlayer::Event_Dying(void)&lt;br /&gt;
265	CBaseCombatCharacter::BecomeRagdoll(CTakeDamageInfo  const&amp;amp;,Vector  const&amp;amp;)&lt;br /&gt;
266	CBaseCombatCharacter::FixupBurningServerRagdoll(CBaseEntity *)&lt;br /&gt;
267	CBaseCombatCharacter::BecomeRagdollBoogie(CBaseEntity *,Vector  const&amp;amp;,float,int)&lt;br /&gt;
268	CBaseCombatCharacter::CheckTraceHullAttack(float,Vector  const&amp;amp;,Vector  const&amp;amp;,int,int,float,bool)&lt;br /&gt;
269	CBaseCombatCharacter::CheckTraceHullAttack(Vector  const&amp;amp;,Vector  const&amp;amp;,Vector  const&amp;amp;,Vector  const&amp;amp;,int,int,float,bool)&lt;br /&gt;
270	CBaseCombatCharacter::PushawayTouch(CBaseEntity *)&lt;br /&gt;
271	CBaseCombatCharacter::IRelationType(CBaseEntity *)&lt;br /&gt;
272	CBaseCombatCharacter::IRelationPriority(CBaseEntity *)&lt;br /&gt;
273	CBasePlayer::IsInAVehicle(void)const&lt;br /&gt;
274	CBasePlayer::GetVehicle(void)&lt;br /&gt;
275	CBasePlayer::GetVehicleEntity(void)&lt;br /&gt;
276	CBaseCombatCharacter::ExitVehicle(void)&lt;br /&gt;
277	CHL2_Player::CalcWeaponProficiency(CBaseCombatWeapon *)&lt;br /&gt;
278	CBaseCombatCharacter::GetAttackSpread(CBaseCombatWeapon *,CBaseEntity *)&lt;br /&gt;
279	CBaseCombatCharacter::GetSpreadBias(CBaseCombatWeapon *,CBaseEntity *)&lt;br /&gt;
280	CBasePlayer::DoMuzzleFlash(void)&lt;br /&gt;
281	CBaseCombatCharacter::AddEntityRelationship(CBaseEntity *,Disposition_t,int)&lt;br /&gt;
282	CBaseCombatCharacter::RemoveEntityRelationship(CBaseEntity *)&lt;br /&gt;
283	CBaseCombatCharacter::AddClassRelationship(Class_T,Disposition_t,int)&lt;br /&gt;
284	CBaseCombatCharacter::OnChangeActiveWeapon(CBaseCombatWeapon *,CBaseCombatWeapon *)&lt;br /&gt;
285	CHL2MP_Player::CreateViewModel(int)&lt;br /&gt;
286	CHL2_Player::SetupVisibility(CBaseEntity *,unsigned char *,int)&lt;br /&gt;
287	CHL2MP_Player::WantsLagCompensationOnEntity(CBasePlayer  const*,CUserCmd  const*,CBitVec&amp;lt;2048&amp;gt;  const*)const&lt;br /&gt;
288	CHL2MP_Player::SharedSpawn(void)&lt;br /&gt;
289	CBasePlayer::ForceRespawn(void)&lt;br /&gt;
290	CHL2MP_Player::InitialSpawn(void)&lt;br /&gt;
291	CBasePlayer::InitHUD(void)&lt;br /&gt;
292	CBasePlayer::ShowViewPortPanel(char  const*,bool,KeyValues *)&lt;br /&gt;
293	CHL2MP_Player::PlayerDeathThink(void)&lt;br /&gt;
294	CHL2MP_Player::Jump(void)&lt;br /&gt;
295	CBasePlayer::Duck(void)&lt;br /&gt;
296	CHL2MP_Player::PreThink(void)&lt;br /&gt;
297	CHL2MP_Player::PostThink(void)&lt;br /&gt;
298	CHL2MP_Player::DamageEffect(float,int)&lt;br /&gt;
299	CHL2_Player::OnDamagedByExplosion(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
300	CBasePlayer::ShouldFadeOnDeath(void)&lt;br /&gt;
301	CBasePlayer::IsFakeClient(void)const&lt;br /&gt;
302	CBasePlayer::GetPlayerMins(void)const&lt;br /&gt;
303	CBasePlayer::GetPlayerMaxs(void)const&lt;br /&gt;
304	CBasePlayer::CalcRoll(QAngle  const&amp;amp;,Vector  const&amp;amp;,float,float)&lt;br /&gt;
305	CBasePlayer::PackDeadPlayerItems(void)&lt;br /&gt;
306	CBasePlayer::RemoveAllItems(bool)&lt;br /&gt;
307	CBasePlayer::Weapon_SetLast(CBaseCombatWeapon *)&lt;br /&gt;
308	CBasePlayer::Weapon_ShouldSetLast(CBaseCombatWeapon *,CBaseCombatWeapon *)&lt;br /&gt;
309	CBasePlayer::Weapon_ShouldSelectItem(CBaseCombatWeapon *)&lt;br /&gt;
310	CHL2_Player::UpdateClientData(void)&lt;br /&gt;
311	CHL2_Player::ExitLadder(void)&lt;br /&gt;
312	CHL2_Player::GetLadderSurface(Vector  const&amp;amp;)&lt;br /&gt;
313	CHL2_Player::SetFlashlightEnabled(bool)&lt;br /&gt;
314	CHL2MP_Player::FlashlightIsOn(void)&lt;br /&gt;
315	CHL2MP_Player::FlashlightTurnOn(void)&lt;br /&gt;
316	CHL2MP_Player::FlashlightTurnOff(void)&lt;br /&gt;
317	CHL2_Player::IsIlluminatedByFlashlight(CBaseEntity *,float *)&lt;br /&gt;
318	CBasePlayer::UpdateStepSound(surfacedata_t *,Vector  const&amp;amp;,Vector  const&amp;amp;)&lt;br /&gt;
319	CHL2MP_Player::PlayStepSound(Vector &amp;amp;,surfacedata_t *,float,bool)&lt;br /&gt;
320	CBasePlayer::GetStepSoundVelocities(float *,float *)&lt;br /&gt;
321	CBasePlayer::SetStepSoundTime(stepsoundtimes_t,bool)&lt;br /&gt;
322	CHL2MP_Player::DeathSound(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
323	CHL2MP_Player::SetAnimation(PLAYER_ANIM)&lt;br /&gt;
324	CBasePlayer::ImpulseCommands(void)&lt;br /&gt;
325	CHL2_Player::CheatImpulseCommands(int)&lt;br /&gt;
326	CHL2MP_Player::ClientCommand(CCommand  const&amp;amp;)&lt;br /&gt;
327	CHL2MP_Player::StartObserverMode(int)&lt;br /&gt;
328	CHL2MP_Player::StopObserverMode(void)&lt;br /&gt;
329	CBasePlayer::ModeWantsSpectatorGUI(int)&lt;br /&gt;
330	CBasePlayer::SetObserverMode(int)&lt;br /&gt;
331	CBasePlayer::GetObserverMode(void)&lt;br /&gt;
332	CBasePlayer::SetObserverTarget(CBaseEntity *)&lt;br /&gt;
333	CBasePlayer::ObserverUse(bool)&lt;br /&gt;
334	CBasePlayer::GetObserverTarget(void)&lt;br /&gt;
335	CBasePlayer::FindNextObserverTarget(bool)&lt;br /&gt;
336	CBasePlayer::GetNextObserverSearchStartPoint(bool)&lt;br /&gt;
337	CBasePlayer::IsValidObserverTarget(CBaseEntity *)&lt;br /&gt;
338	CBasePlayer::CheckObserverSettings(void)&lt;br /&gt;
339	CBasePlayer::JumptoPosition(Vector  const&amp;amp;,QAngle  const&amp;amp;)&lt;br /&gt;
340	CBasePlayer::ForceObserverMode(int)&lt;br /&gt;
341	CBasePlayer::ResetObserverMode(void)&lt;br /&gt;
342	CBasePlayer::ValidateCurrentObserverTarget(void)&lt;br /&gt;
343	CBasePlayer::AttemptToExitFreezeCam(void)&lt;br /&gt;
344	CBasePlayer::StartReplayMode(float,float,int)&lt;br /&gt;
345	CBasePlayer::StopReplayMode(void)&lt;br /&gt;
346	CBasePlayer::GetDelayTicks(void)&lt;br /&gt;
347	CBasePlayer::GetReplayEntity(void)&lt;br /&gt;
348	CHL2_Player::CreateCorpse(void)&lt;br /&gt;
349	CHL2MP_Player::EntSelectSpawnPoint(void)&lt;br /&gt;
350	CBasePlayer::GetInVehicle(IServerVehicle *,int)&lt;br /&gt;
351	CBasePlayer::LeaveVehicle(Vector  const&amp;amp;,QAngle  const&amp;amp;)&lt;br /&gt;
352	CBasePlayer::OnVehicleStart(void)&lt;br /&gt;
353	CBasePlayer::OnVehicleEnd(Vector &amp;amp;)&lt;br /&gt;
354	CBasePlayer::BumpWeapon(CBaseCombatWeapon *)&lt;br /&gt;
355	CBasePlayer::SelectLastItem(void)&lt;br /&gt;
356	CBasePlayer::SelectItem(char  const*,int)&lt;br /&gt;
357	CBasePlayer::SelectItem(int,int)&lt;br /&gt;
358	CHL2MP_Player::ItemPostFrame(void)&lt;br /&gt;
359	CBasePlayer::GiveNamedItem(char  const*,int)&lt;br /&gt;
360	CBasePlayer::CheckTrainUpdate(void)&lt;br /&gt;
361	CHL2_Player::SetPlayerUnderwater(bool)&lt;br /&gt;
362	CHL2MP_Player::CanBreatheUnderwater(void)const&lt;br /&gt;
363	CHL2MP_Player::PlayerUse(void)&lt;br /&gt;
364	CHL2_Player::PlayUseDenySound(void)&lt;br /&gt;
365	CBasePlayer::FindUseEntity(void)&lt;br /&gt;
366	CBasePlayer::IsUseableEntity(CBaseEntity *,unsigned int)&lt;br /&gt;
367	CHL2MP_Player::PickupObject(CBaseEntity *,bool)&lt;br /&gt;
368	CHL2_Player::ForceDropOfCarriedPhysObjects(CBaseEntity *)&lt;br /&gt;
369	CHL2_Player::GetHeldObjectMass(IPhysicsObject *)&lt;br /&gt;
370	CHL2_Player::GetHeldObject(void)&lt;br /&gt;
371	CBasePlayer::UpdateGeigerCounter(void)&lt;br /&gt;
372	CBasePlayer::GetAutoaimVector(float)&lt;br /&gt;
373	CBasePlayer::GetAutoaimVector(float,float)&lt;br /&gt;
374	CHL2_Player::GetAutoaimVector(autoaim_params_t &amp;amp;)&lt;br /&gt;
375	CBasePlayer::ShouldAutoaim(void)&lt;br /&gt;
376	CBasePlayer::ForceClientDllUpdate(void)&lt;br /&gt;
377	CBasePlayer::ProcessUsercmds(CUserCmd *,int,int,int,bool)&lt;br /&gt;
378	CHL2MP_Player::PlayerRunCommand(CUserCmd *,IMoveHelper *)&lt;br /&gt;
379	CHL2MP_Player::CanHearAndReadChatFrom(CBasePlayer *)&lt;br /&gt;
380	CHL2MP_Player::CanSpeak(void)&lt;br /&gt;
381	CHL2MP_Player::PlayCharacterSound(char  const*)&lt;br /&gt;
382	CHL2_Player::ModifyOrAppendPlayerCriteria(AI_CriteriaSet &amp;amp;)&lt;br /&gt;
383	CHL2MP_Player::CheckChatText(char *,int)&lt;br /&gt;
384	CHL2MP_Player::CreateRagdollEntity(void)&lt;br /&gt;
385	CBasePlayer::ShouldAnnounceAchievement(void)&lt;br /&gt;
386	CHL2_Player::OnDoneDamage(void)&lt;br /&gt;
387	CHL2_Player::IsWalking(void)&lt;br /&gt;
388	CHL2MP_Player::IsPracticallyZombie(void)const&lt;br /&gt;
389	CHL2MP_Player::IsInfectionKnown(void)const&lt;br /&gt;
390	CHL2MP_Player::DidZombieJustTurn(void)const&lt;br /&gt;
391	CHL2MP_Player::InfectPlayer(float)&lt;br /&gt;
392	CHL2MP_Player::DisinfectPlayer(void)&lt;br /&gt;
393	CHL2_Player::IsFollowingPhysics(void)&lt;br /&gt;
394	CHL2_Player::InitVCollision(Vector  const&amp;amp;,Vector  const&amp;amp;)&lt;br /&gt;
395	CBasePlayer::UpdatePhysicsShadowToCurrentPosition(void)&lt;br /&gt;
396	CBasePlayer::Hints(void)&lt;br /&gt;
397	CBasePlayer::IsReadyToPlay(void)&lt;br /&gt;
398	CBasePlayer::IsReadyToSpawn(void)&lt;br /&gt;
399	CBasePlayer::ShouldGainInstantSpawn(void)&lt;br /&gt;
400	CBasePlayer::ResetPerRoundStats(void)&lt;br /&gt;
401	CBasePlayer::ResetScores(void)&lt;br /&gt;
402	CBasePlayer::SpawnArmorValue(void)&lt;br /&gt;
403	CHL2_Player::EquipSuit(bool)&lt;br /&gt;
404	CHL2_Player::RemoveSuit(void)&lt;br /&gt;
405	CHL2MP_Player::CommitSuicide(bool,bool)&lt;br /&gt;
406	CHL2MP_Player::CommitSuicide(Vector  const&amp;amp;,bool,bool)&lt;br /&gt;
407	CBasePlayer::IsBot(void)const&lt;br /&gt;
408	CHL2MP_Player::NotePlayerTalked(void)&lt;br /&gt;
409	CBasePlayer::GetExpresser(void)&lt;br /&gt;
410	CBasePlayer::NetworkStateChanged_m_iAmmo(void)&lt;br /&gt;
411	CBasePlayer::NetworkStateChanged_m_iAmmo(void *)&lt;br /&gt;
412	CHL2_Player::SuspendUse(float)&lt;br /&gt;
413	CHL2_Player::CommanderMode(void)&lt;br /&gt;
414	CHL2MP_Player::StartSprinting(void)&lt;br /&gt;
415	CHL2_Player::GetIdleTime(void)const&lt;br /&gt;
416	CHL2_Player::GetMoveTime(void)const&lt;br /&gt;
417	CHL2_Player::GetLastDamageTime(void)const&lt;br /&gt;
418	CHL2_Player::IsDucking(void)const&lt;br /&gt;
419	CHL2_Player::Weapon_Lower(void)&lt;br /&gt;
420	CHL2_Player::Weapon_Ready(void)&lt;br /&gt;
421	CHL2_Player::IsHoldingEntity(CBaseEntity *)&lt;br /&gt;
422	CHL2_Player::UpdateWeaponPosture(void)&lt;br /&gt;
423	CHL2_Player::NetworkStateChanged_m_fIsWalking(void)&lt;br /&gt;
424	CHL2_Player::NetworkStateChanged_m_fIsWalking(void *)&lt;br /&gt;
425	CHL2MP_Player::GhostSpawn(void)&lt;br /&gt;
426	CHL2MP_Player::WaitSpawn(void)&lt;br /&gt;
427	CHL2MP_Player::ObserverSpawn(void)&lt;br /&gt;
428	CHL2MP_Player::HandleCommand_JoinTeam(int)&lt;br /&gt;
429	CHL2MP_Player::CanHearChatFrom(CBasePlayer *)&lt;br /&gt;
430	CHL2MP_Player::RemoveWeight(float)&lt;br /&gt;
431	CHL2MP_Player::RemoveAllItems(void)&lt;br /&gt;
432	CHL2MP_Player::ItemReticleSearch(void)&lt;br /&gt;
433	CHL2MP_Player::EnterPhoneTrigger(CPhoneTrigger *)&lt;br /&gt;
434	CHL2MP_Player::LeavePhoneTrigger(CPhoneTrigger *)&lt;br /&gt;
435	CHL2MP_Player::ActivatePhoneTriggers(void)&lt;br /&gt;
436	CHL2MP_Player::InPhoneTrigger(void)&lt;br /&gt;
437	CHL2MP_Player::InventoryStatus(void)&lt;br /&gt;
438	CHL2MP_Player::GiveNamedItem(char  const*)&lt;br /&gt;
439	CHL2MP_Player::PlayerWeaponPickup(CBaseCombatWeapon *)&lt;br /&gt;
440	CHL2MP_Player::GiveEmptyHands(void)&lt;br /&gt;
441	CHL2MP_Player::GivePhone(void)&lt;br /&gt;
442	CHL2MP_Player::SetPlayerTeamModel(int)&lt;br /&gt;
443	CHL2MP_Player::GiveDefaultGear(void)&lt;br /&gt;
444	CHL2MP_Player::GetPlayerModelSoundPrefix(void)&lt;br /&gt;
445	CHL2MP_Player::GetPlayerModelType(void)&lt;br /&gt;
446	CHL2MP_Player::DefuseIEDs(CTakeDamageInfo  const&amp;amp;)&lt;br /&gt;
447	CHL2MP_Player::ShowBriefingMenu(void)&lt;br /&gt;
448	CHL2MP_Player::HideBriefingMenu(void)&lt;br /&gt;
449	CHL2MP_Player::CreateAmmo(char  const*)&lt;br /&gt;
450	CHL2MP_Player::PrepWeaponForDrop(CBaseCombatWeapon *)&lt;br /&gt;
451	CHL2MP_Player::ScootInventory(void)&lt;br /&gt;
452	CHL2MP_Player::PlayerDropWeapon(void)&lt;br /&gt;
453	CHL2MP_Player::PlayerUnloadWeapon(void)&lt;br /&gt;
454	CHL2MP_Player::PlayerCycleAmmoType(void)&lt;br /&gt;
455	CHL2MP_Player::PlayerCycleDropAmount(void)&lt;br /&gt;
456	CHL2MP_Player::PrepAmmoForDrop(CItem *)&lt;br /&gt;
457	CHL2MP_Player::PlayerDropAmmo(void)&lt;br /&gt;
458	CHL2MP_Player::PlayerDropUnusedAmmo(void)&lt;br /&gt;
459	CHL2MP_Player::GiveAmmoToPlayer(void)&lt;br /&gt;
460	CHL2MP_Player::ResetTeamSwitch(void)&lt;br /&gt;
461	CHL2MP_Player::Panic(bool)&lt;br /&gt;
462	CHL2MP_Player::Melee(bool)&lt;br /&gt;
463	CHL2MP_Player::VoiceMenu(char  const*,char  const*)&lt;br /&gt;
464	CHL2MP_Player::VoiceMenuText(char  const*)&lt;br /&gt;
465	CHL2MP_Player::Taunt(bool)&lt;br /&gt;
466	CHL2MP_Player::KillTaunt(bool)&lt;br /&gt;
467	CHL2MP_Player::Berzerk(void)&lt;br /&gt;
468	CHL2MP_Player::Go(void)&lt;br /&gt;
469	CHL2MP_Player::Roar(void)&lt;br /&gt;
470	CHL2MP_Player::Camp(void)&lt;br /&gt;
471	CHL2MP_Player::PickedAsCarrier(void)&lt;br /&gt;
472	CHL2MP_Player::ResetCarrier(void)&lt;br /&gt;
473	CHL2MP_Player::IsCarrier(void)&lt;br /&gt;
474	CHL2MP_Player::HolsterWeapon(void)&lt;br /&gt;
475	CHL2MP_Player::SwitchToPhone(void)&lt;br /&gt;
476	CHL2MP_Player::Trace(void)&lt;br /&gt;
477	CHL2MP_Player::IsOnATeam(void)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10117</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=10117"/>
		<updated>2016-02-16T21:22:22Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Why is Source telling me my command is an &amp;quot;Unknown command&amp;quot;? */&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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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;char&amp;lt;/tt&amp;gt;. See [[Introduction_to_SourcePawn_1.7#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 int SetEntPropFloat(int entity, PropType type, const char[] prop, float value, int element)&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;int&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;char&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;char&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;int&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;int&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;int&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;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 != null)&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 void 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;
    int 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 void 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;
    int 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(int client, int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10116</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=10116"/>
		<updated>2016-02-16T21:22:02Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Color Libraries */&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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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;char&amp;lt;/tt&amp;gt;. See [[Introduction_to_SourcePawn_1.7#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 int SetEntPropFloat(int entity, PropType type, const char[] prop, float value, int element)&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;int&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;char&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;char&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;int&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;int&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;int&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;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 != null)&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 void 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;
    int 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 void 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;
    int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10115</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=10115"/>
		<updated>2016-02-16T21:21:17Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* 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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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;char&amp;lt;/tt&amp;gt;. See [[Introduction_to_SourcePawn_1.7#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 int SetEntPropFloat(int entity, PropType type, const char[] prop, float value, int element)&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;int&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;char&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;char&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;int&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;int&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;int&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;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 != null)&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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10114</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=10114"/>
		<updated>2016-02-16T21:20:41Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I get rid of tag mismatch warnings? */&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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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;char&amp;lt;/tt&amp;gt;. See [[Introduction_to_SourcePawn_1.7#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 int SetEntPropFloat(int entity, PropType type, const char[] prop, float value, int element)&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;int&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;char&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 [https://sm.alliedmods.net/new-api/entity/__raw 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;char&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;int&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;int&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;int&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 [https://sm.alliedmods.net/new-api/entity/__raw 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10113</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=10113"/>
		<updated>2016-02-16T21:16:17Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Where can I find all the SourcePawn functions and other information? */&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_1.7]] 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: [https://sm.alliedmods.net/new-api/ https://sm.alliedmods.net/new-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: bool GetEntityNetClass(int edict, char[] clsname, int maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (https://sm.alliedmods.net/new-api/entity/GetEntityNetClass)&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10112</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=10112"/>
		<updated>2016-02-16T21:14:34Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I learn SourcePawn? */&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_1.7]] 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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10111</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=10111"/>
		<updated>2016-02-16T21:06:21Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I get rid of loose indentation warnings? */&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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 void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    int 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 voidOnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10110</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=10110"/>
		<updated>2016-02-16T21:05:43Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I hook +commands, such as +zoom and +attack? */&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 [https://sm.alliedmods.net/new-api/sdktools_hooks/OnPlayerRunCmd 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;[https://sm.alliedmods.net/new-api/entity_prop_stocks/__raw 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(int client, int &amp;amp;buttons, int &amp;amp;impulse, float vel[3], float angles[3], int &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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10109</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=10109"/>
		<updated>2016-02-16T21:01:22Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I block regular commands, such as kill and say? */&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/AddCommandListener AddCommandListener()]. Previously, using [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10108</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=10108"/>
		<updated>2016-02-16T21:01:02Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I block regular commands, such as kill and say? */&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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 [https://sm.alliedmods.net/new-api/console/RegConsoleCmd 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. [https://sm.alliedmods.net/new-api/console/AddCommandListener 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 void 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(int client, const char[] command, int 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=10107</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=10107"/>
		<updated>2016-02-16T20:58:51Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* How do I find the classname of an entity? (e.g., &amp;quot;weapon_knife&amp;quot; or &amp;quot;prop_physics&amp;quot;) */&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 [https://sm.alliedmods.net/new-api/entity/GetEdictClassname GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char 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>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10106</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10106"/>
		<updated>2016-02-10T04:10:35Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBResultSet query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;);&lt;br /&gt;
if (query == null)&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	delete query;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	DBResultSet hQuery;&lt;br /&gt;
	char query[100];&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	int buffer_len = strlen(name) * 2 + 1;&lt;br /&gt;
	char[] new_name = new char[buffer_len];&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len);&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name);&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == null)&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	delete hQuery;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBStatement hUserStmt = null;&lt;br /&gt;
int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == null)&lt;br /&gt;
	{&lt;br /&gt;
		char error[255];&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == null)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;void PrintResults(Handle query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	char name[MAX_NAME_LENGTH];&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name));&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool GetByAge_Query(Database db, int age)&lt;br /&gt;
{&lt;br /&gt;
	char query[100];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age);&lt;br /&gt;
&lt;br /&gt;
	DBResultSet hQuery = SQL_Query(db, query);&lt;br /&gt;
	if (hQuery == null)&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery);&lt;br /&gt;
&lt;br /&gt;
	delete hQuery;&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DBStatement hAgeStmt = null;&lt;br /&gt;
bool GetByAge_Statement(Database db, int age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == null)&lt;br /&gt;
	{&lt;br /&gt;
		char error[255];&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == null)&lt;br /&gt;
		{&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age);&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt);&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations (except connecting) use the same callback for result notification: &amp;lt;tt&amp;gt;SQLQueryCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; - The cloned database handle.  If the db handle was not found or was invalidated, &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;results&amp;lt;/tt&amp;gt; - Result object, or null on failure.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established. &lt;br /&gt;
Connecting however uses a different callback: &amp;lt;tt&amp;gt;SQLConnectCallback&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt;: Handle to the database connection, or &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;Database hDatabase = null;&lt;br /&gt;
&lt;br /&gt;
void StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void GotDatabase(Database db, const char[] error, any data)&lt;br /&gt;
{&lt;br /&gt;
	if (db == null)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} &lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10105</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10105"/>
		<updated>2016-02-10T04:02:01Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Processing Results */ Updated to Transitional Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBResultSet query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;);&lt;br /&gt;
if (query == null)&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	delete query;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	DBResultSet hQuery;&lt;br /&gt;
	char query[100];&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	int buffer_len = strlen(name) * 2 + 1;&lt;br /&gt;
	char[] new_name = new char[buffer_len];&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len);&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name);&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == null)&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	delete hQuery;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBStatement hUserStmt = null;&lt;br /&gt;
int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == null)&lt;br /&gt;
	{&lt;br /&gt;
		char error[255];&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == null)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;void PrintResults(Handle query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	char name[MAX_NAME_LENGTH];&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name));&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool GetByAge_Query(Database db, int age)&lt;br /&gt;
{&lt;br /&gt;
	char query[100];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age);&lt;br /&gt;
&lt;br /&gt;
	DBResultSet hQuery = SQL_Query(db, query);&lt;br /&gt;
	if (hQuery == null)&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery);&lt;br /&gt;
&lt;br /&gt;
	delete hQuery;&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DBStatement hAgeStmt = null;&lt;br /&gt;
bool GetByAge_Statement(Database db, int age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == null)&lt;br /&gt;
	{&lt;br /&gt;
		char error[255];&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == null)&lt;br /&gt;
		{&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age);&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt);&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations use the same callback for result notification: &amp;lt;tt&amp;gt;SQLTCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt; - The &amp;quot;owner&amp;quot; of the operation.  For a query, this is a database.  For a database, this is a driver.  If the owner was not found or was invalidated, &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt; - The object being requested.  The value is defined by the SQL operation.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established.  &lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the driver, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the database, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if the connection failed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hDatabase = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} else {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10104</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10104"/>
		<updated>2016-02-10T03:53:26Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Prepared Statements */ Updated to Transitional Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBResultSet query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;);&lt;br /&gt;
if (query == null)&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	delete query;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	DBResultSet hQuery;&lt;br /&gt;
	char query[100];&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	int buffer_len = strlen(name) * 2 + 1;&lt;br /&gt;
	char[] new_name = new char[buffer_len];&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len);&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name);&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == null)&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	delete hQuery;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBStatement hUserStmt = null;&lt;br /&gt;
int GetSomeInfo(Database db, const char[] name)&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == null)&lt;br /&gt;
	{&lt;br /&gt;
		char error[255];&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == null)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintResults(Handle:query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	new String:name[65]&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Handle:hAgeStmt = INVALID_HANDLE&lt;br /&gt;
bool:GetByAge_Statement(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return false&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age)&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations use the same callback for result notification: &amp;lt;tt&amp;gt;SQLTCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt; - The &amp;quot;owner&amp;quot; of the operation.  For a query, this is a database.  For a database, this is a driver.  If the owner was not found or was invalidated, &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt; - The object being requested.  The value is defined by the SQL operation.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established.  &lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the driver, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the database, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if the connection failed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hDatabase = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} else {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10103</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10103"/>
		<updated>2016-02-10T03:48:16Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Results */ Updated to Transitional Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;DBResultSet query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;);&lt;br /&gt;
if (query == null)&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	delete query;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	new Handle:hQuery&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	new buffer_len = strlen(name) * 2 + 1&lt;br /&gt;
	new String:new_name[buffer_len]&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len)&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name)&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return 0&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hUserStmt = INVALID_HANDLE;&lt;br /&gt;
GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintResults(Handle:query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	new String:name[65]&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Handle:hAgeStmt = INVALID_HANDLE&lt;br /&gt;
bool:GetByAge_Statement(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return false&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age)&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations use the same callback for result notification: &amp;lt;tt&amp;gt;SQLTCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt; - The &amp;quot;owner&amp;quot; of the operation.  For a query, this is a database.  For a database, this is a driver.  If the owner was not found or was invalidated, &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt; - The object being requested.  The value is defined by the SQL operation.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established.  &lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the driver, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the database, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if the connection failed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hDatabase = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} else {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10102</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10102"/>
		<updated>2016-02-10T03:46:30Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* No Results */ Updated to Transitional Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	char error[255];&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error));&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;)&lt;br /&gt;
if (query == INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
	new String:error[255]&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error))&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error)&lt;br /&gt;
} else {&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	CloseHandle(query)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	new Handle:hQuery&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	new buffer_len = strlen(name) * 2 + 1&lt;br /&gt;
	new String:new_name[buffer_len]&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len)&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name)&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return 0&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hUserStmt = INVALID_HANDLE;&lt;br /&gt;
GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintResults(Handle:query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	new String:name[65]&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Handle:hAgeStmt = INVALID_HANDLE&lt;br /&gt;
bool:GetByAge_Statement(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return false&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age)&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations use the same callback for result notification: &amp;lt;tt&amp;gt;SQLTCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt; - The &amp;quot;owner&amp;quot; of the operation.  For a query, this is a database.  For a database, this is a driver.  If the owner was not found or was invalidated, &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt; - The object being requested.  The value is defined by the SQL operation.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established.  &lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the driver, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the database, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if the connection failed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hDatabase = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} else {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10101</id>
		<title>SQL (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_(SourceMod_Scripting)&amp;diff=10101"/>
		<updated>2016-02-10T03:45:42Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Updated to 1.7 Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is an introduction to using SourceMod's SQL features.  It is not an introduction or tutorial about SQL or any specific SQL implementation.&lt;br /&gt;
&lt;br /&gt;
SourceMod's SQL layer is formally called ''DBI'', or the '''D'''ata'''b'''ase '''I'''nterface.  The interface is a generic abstraction of common SQL functions.  To connect to a specific database implementation (such as MySQL, or sqLite), a SourceMod DBI &amp;quot;driver&amp;quot; must be loaded.  Currently, there are drivers for MySQL and SQLite&lt;br /&gt;
&lt;br /&gt;
SourceMod automatically detects and loads drivers on demand (if they exist, of course).  All database natives are in &amp;lt;tt&amp;gt;scripting/include/dbi.inc&amp;lt;/tt&amp;gt;.  The C++ API is in &amp;lt;tt&amp;gt;public/IDBDriver.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Connecting=&lt;br /&gt;
There are two ways to connect to a database.  The first is through named configurations.  Named configurations are preset configurations listed in &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt;.  SourceMod specifies that if SQL is being used, there should always be one configuration named &amp;quot;default.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
An example of such a configuration looks like:&lt;br /&gt;
&amp;lt;pre&amp;gt;	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;root&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;&amp;quot;&lt;br /&gt;
		//&amp;quot;timeout&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
		//&amp;quot;port&amp;quot;			&amp;quot;0&amp;quot;&lt;br /&gt;
	}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connections based on named configurations can be instantiated with either &amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SQL_DefConnect&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
The other option is to use &amp;lt;tt&amp;gt;SQL_ConnectCustom&amp;lt;/tt&amp;gt; and manually specify all connection parameters by passing a keyvalue handle containing them.&lt;br /&gt;
&lt;br /&gt;
Example of a typical connection:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char error[255];&lt;br /&gt;
Database db = SQL_DefConnect(error, sizeof(error));&lt;br /&gt;
&lt;br /&gt;
if (db == null)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Could not connect: %s&amp;quot;, error);&lt;br /&gt;
} &lt;br /&gt;
else &lt;br /&gt;
{&lt;br /&gt;
	delete db;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Queries=&lt;br /&gt;
&lt;br /&gt;
==No Results==&lt;br /&gt;
The simplest queries are ones which do not return results -- for example, CREATE, DROP, UPDATE, INSERT, and DELETE.  For such queries it is recommended to use &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;.  The name does not imply that the query will be faster, but rather, it is faster to write code using this function.  For example, given that &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; is a valid database Handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (!SQL_FastQuery(db, &amp;quot;UPDATE stats SET players = players + 1&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
	new String:error[255]&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error))&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
If a query returns a result set and the results must be processed, you must use &amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;SQL_FastQuery()&amp;lt;/tt&amp;gt;, this function returns a Handle which must be closed.&lt;br /&gt;
&lt;br /&gt;
An example of a query which will produce results is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:query = SQL_Query(db, &amp;quot;SELECT userid FROM vb_user WHERE username = 'BAILOPAN'&amp;quot;)&lt;br /&gt;
if (query == INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
	new String:error[255]&lt;br /&gt;
	SQL_GetError(db, error, sizeof(error))&lt;br /&gt;
	PrintToServer(&amp;quot;Failed to query (error: %s)&amp;quot;, error)&lt;br /&gt;
} else {&lt;br /&gt;
	/* Process results here!&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/* Free the Handle */&lt;br /&gt;
	CloseHandle(query)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Prepared Statements=&lt;br /&gt;
Prepared statements are another method of querying.  The idea behind a prepared statement is that you construct a query &amp;quot;template&amp;quot; once, and re-use it as many times as needed.  Prepared statements have the following benefits:&lt;br /&gt;
*A good SQL implementation will be able to cache the query better if it is a prepared statement.&lt;br /&gt;
*You don't have to rebuild the entire query string every execution.&lt;br /&gt;
*You don't have to allocate a new query structure on every execution.&lt;br /&gt;
*Input is &amp;quot;always&amp;quot; secure (more on this later).&lt;br /&gt;
&lt;br /&gt;
A prepared statement has &amp;quot;markers&amp;quot; for inputs.  For example, let's consider a function that takes in a database Handle and a name, and retrieves some info from a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	new Handle:hQuery&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
&lt;br /&gt;
	/* Create enough space to make sure our string is quoted properly  */&lt;br /&gt;
	new buffer_len = strlen(name) * 2 + 1&lt;br /&gt;
	new String:new_name[buffer_len]&lt;br /&gt;
&lt;br /&gt;
	/* Ask the SQL driver to make sure our string is safely quoted */&lt;br /&gt;
	SQL_EscapeString(db, name, new_name, buffer_len)&lt;br /&gt;
&lt;br /&gt;
	/* Build the query */&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM vb_user WHERE username = '%s'&amp;quot;, new_name)&lt;br /&gt;
	&lt;br /&gt;
	/* Execute the query */&lt;br /&gt;
	if ((hQuery = SQL_Query(query)) == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return 0&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe a version with prepared statements:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hUserStmt = INVALID_HANDLE;&lt;br /&gt;
GetSomeInfo(Handle:db, const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	/* Check if we haven't already created the statement */&lt;br /&gt;
	if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		hUserStmt = SQL_PrepareQuery(db, &amp;quot;SELECT userid FROM vb_user WHERE username = ?&amp;quot;, error, sizeof(error));&lt;br /&gt;
		if (hUserStmt == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamString(hUserStmt, 0, name, false);&lt;br /&gt;
	if (!SQL_Execute(hUserStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Get some info here&lt;br /&gt;
	 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The important differences:&lt;br /&gt;
*The input string (&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;) did not need to be backticked (quoted).  The SQL engine automatically performs all type safety and insertion checks.&lt;br /&gt;
*There was no need for quotation marks around the parameter marker, &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;, even though it accepted a string.&lt;br /&gt;
*We only needed to create the statement Handle once; after that it can live for the lifetime of the database connection.&lt;br /&gt;
&lt;br /&gt;
=Processing Results=&lt;br /&gt;
Processing results is done in the same manner for both normal queries and prepared statements.  The important functions are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_GetRowCount()&amp;lt;/tt&amp;gt; - Returns the number of rows.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FetchRow()&amp;lt;/tt&amp;gt; - Fetches the next row if one is available.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Fetch[Int|String|Float]()&amp;lt;/tt&amp;gt; - Fetches data from a field in the current row.&lt;br /&gt;
&lt;br /&gt;
Let's consider a sample table that looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CREATE TABLE users (&lt;br /&gt;
	name VARCHAR(64) NOT NULL PRIMARY KEY,&lt;br /&gt;
	age INT UNSIGNED NOT NULL&lt;br /&gt;
	);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following example has code that will print out all users matching a certain age.  There is an example for both prepared statements and normal queries.&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintResults(Handle:query)&lt;br /&gt;
{&lt;br /&gt;
	/* Even if we have just one row, you must call SQL_FetchRow() first */&lt;br /&gt;
	new String:name[65]&lt;br /&gt;
	while (SQL_FetchRow(query))&lt;br /&gt;
	{&lt;br /&gt;
		SQL_FetchString(query, 0, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Name \&amp;quot;%s\&amp;quot; was found.&amp;quot;, name)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Handle:hAgeStmt = INVALID_HANDLE&lt;br /&gt;
bool:GetByAge_Statement(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	if (hAgeSmt == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		new String:error[255]&lt;br /&gt;
		if ((hAgeStmt = SQL_PrepareQuery(db, &lt;br /&gt;
			&amp;quot;SELECT name FROM users WHERE age = ?&amp;quot;, &lt;br /&gt;
			error, &lt;br /&gt;
			sizeof(error))) &lt;br /&gt;
		     == INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			return false&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SQL_BindParamInt(hAgeStmt, 0, age)&lt;br /&gt;
	if (!SQL_Execute(hAgeStmt))&lt;br /&gt;
	{&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hAgeStmt)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these examples did not close the statement Handles.  These examples assume a global database instance that is only closed when the plugin is unloaded.  For plugins which maintain temporary database connections, prepared statement Handles must be freed or else the database connection will never be closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Threading=&lt;br /&gt;
SourceMod supports threaded SQL querying.  That is, SQL operations can be completed in a separate thread from main gameplay.  If your database server is remote or requires a network connection, queries can cause noticeable gameplay lag, and supporting threading is often a good idea if your queries occur in the middle of gameplay.&lt;br /&gt;
&lt;br /&gt;
Threaded queries are ''asynchronous''.  That is, they are dispatched and you can only find the results through a callback.  Although the callback is guaranteed to fire eventually, it may not fire in any specific given timeframe.  Certain drivers may not support threading; if this is the case, an RTE will be thrown.  If the threader cannot start or the threader is currently disabled, SourceMod will transparently execute the query in the main thread as a fallback.&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
All threaded operations use the same callback for result notification: &amp;lt;tt&amp;gt;SQLTCallback&amp;lt;/tt&amp;gt;.  The parameters are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt; - The &amp;quot;owner&amp;quot; of the operation.  For a query, this is a database.  For a database, this is a driver.  If the owner was not found or was invalidated, &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; is passed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt; - The object being requested.  The value is defined by the SQL operation.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt; - An error string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; - Custom data that can be passed via some SQL operations.&lt;br /&gt;
&lt;br /&gt;
The following operations can be done via threads:&lt;br /&gt;
*&amp;lt;b&amp;gt;Connection&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TConnect&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;Querying&amp;lt;/b&amp;gt;, via &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*''Note: prepared statements are not yet available for the threader.''&lt;br /&gt;
&lt;br /&gt;
It is always safe to chain one operation from another.&lt;br /&gt;
&lt;br /&gt;
===Connecting===&lt;br /&gt;
It is not necessary to make a threaded connection in order to make threaded queries.  However, creating a threaded connection will not pause the game server if a connection cannot be immediately established.  &lt;br /&gt;
&lt;br /&gt;
The following parameters are used for the threaded connection callback:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the driver, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if it could not be found.&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the database, or &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if the connection failed.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: The error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Unused (0)&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hDatabase = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
StartSQL()&lt;br /&gt;
{&lt;br /&gt;
	SQL_TConnect(GotDatabase);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Database failure: %s&amp;quot;, error);&lt;br /&gt;
	} else {&lt;br /&gt;
		hDatabase = hndl;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Querying===&lt;br /&gt;
Threaded queries can be performed on any database Handle as long as the driver supports threading.  All query results for the first result set are retrieved while in the thread.  If your query returns more than one set of results (for example, &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; on MySQL with certain functions), the behaviour of the threader is undefined at this time.  &amp;lt;b&amp;gt;Note that if you want to perform both threaded and non-threaded queries on the same connection, you MUST read the &amp;quot;Locking&amp;quot; section below.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Query operations use the following callback parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;owner&amp;lt;/tt&amp;gt;: A Handle to the database used to query.  The Handle is not the same as the Handle originally passed; however, it will test positively with &amp;lt;tt&amp;gt;SQL_IsSameConnection&amp;lt;/tt&amp;gt;.  The Handle can be cloned but it cannot be closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; in the case of a serious error (for example, the driver being unloaded).&lt;br /&gt;
*&amp;lt;tt&amp;gt;hndl&amp;lt;/tt&amp;gt;: A Handle to the query.  It can be cloned, but not closed (it is closed automatically).  It may be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; if there was an error.&lt;br /&gt;
*&amp;lt;tt&amp;gt;error&amp;lt;/tt&amp;gt;: Error string, if any.&lt;br /&gt;
*&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;: Optional user-defined data passed in through &amp;lt;tt&amp;gt;SQL_TQuery()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example, continuing from above:&lt;br /&gt;
&amp;lt;pawn&amp;gt;CheckSteamID(userid, const String:auth[])&lt;br /&gt;
{&lt;br /&gt;
	decl String:query[255];&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT userid FROM users WHERE steamid = '%s'&amp;quot;, auth);&lt;br /&gt;
	SQL_TQuery(hdatabase, T_CheckSteamID, query, userid)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public T_CheckSteamID(Handle:owner, Handle:hndl, const String:error[], any:data)&lt;br /&gt;
{&lt;br /&gt;
	new client;&lt;br /&gt;
&lt;br /&gt;
	/* Make sure the client didn't disconnect while the thread was running */&lt;br /&gt;
	if ((client = GetClientOfUserId(data)) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (hndl == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		LogError(&amp;quot;Query failed! %s&amp;quot;, error);&lt;br /&gt;
		KickClient(client, &amp;quot;Authorization failed&amp;quot;);&lt;br /&gt;
	} else if (!SQL_GetRowCount(hndl)) {&lt;br /&gt;
		KickClient(client, &amp;quot;You are not a member&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Locking==&lt;br /&gt;
It is possible to run both threaded and non-threaded queries on the same connection.  However, without the proper precautions, you could corrupt the network stream (even if it's local), corrupt memory, or otherwise cause a crash in the SQL driver.  To solve this, SourceMod has ''database locking''.  Locking is done via &amp;lt;tt&amp;gt;SQL_LockDatabase()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_UnlockDatabase&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Whenever performing any of the following non-threaded operations on a database, it is absolutely necessary to enclose the entire operation with a lock:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Query()&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;SQL_FetchMoreResults&amp;lt;/tt&amp;gt; pairings)&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FastQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Bind*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; pairings&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is: if your operation is going to use the database connection, it must be locked until the operation is fully completed.  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;bool:GetByAge_Query(Handle:db, age)&lt;br /&gt;
{&lt;br /&gt;
	new String:query[100]&lt;br /&gt;
	Format(query, sizeof(query), &amp;quot;SELECT name FROM users WHERE age = %d&amp;quot;, age)&lt;br /&gt;
&lt;br /&gt;
	SQL_LockDatabase(db);&lt;br /&gt;
	new Handle:hQuery = SQL_Query(db, query)&lt;br /&gt;
	if (hQuery == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		SQL_UnlockDatabase(db);&lt;br /&gt;
		return false&lt;br /&gt;
	}&lt;br /&gt;
	SQL_UnlockDatabase(db);&lt;br /&gt;
&lt;br /&gt;
	PrintResults(hQuery)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(hQuery)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it was only necessary to lock the query; SourceMod pre-fetches the result set, and thus the network queue is clean.&lt;br /&gt;
&lt;br /&gt;
===Warnings===&lt;br /&gt;
*&amp;lt;b&amp;gt;Never&amp;lt;/b&amp;gt; call &amp;lt;tt&amp;gt;SQL_LockDatabase&amp;lt;/tt&amp;gt; right before a threaded operation.  You will deadlock the server and have to terminate/kill it.  &lt;br /&gt;
*&amp;lt;b&amp;gt;Always pair every Lock with an Unlock.&amp;lt;/b&amp;gt;  Otherwise you risk a deadlock.&lt;br /&gt;
*If your query returns multiple result sets, for example, a procedure call on MySQL that returns results, you must lock both the query and the entire fetch operation.  SourceMod is only able to fetch one result set at a time, and all result sets must be cleared before a new query is started.&lt;br /&gt;
&lt;br /&gt;
==Priority==&lt;br /&gt;
Threaded SQL operations are placed in a simple priority queue.  The priority levels are &amp;lt;tt&amp;gt;High&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Medium&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Low&amp;lt;/tt&amp;gt;.  Connections always have the highest priority.  &lt;br /&gt;
&lt;br /&gt;
Changing the priority can be useful if you have many queries with different purposes.  For example, a statistics plugin might execute 10 queries on death, and one query on join.  Because the statistics might rely on the join info, the join query might need to be high priority, while the death queries can be low priority.&lt;br /&gt;
&lt;br /&gt;
You should &amp;lt;b&amp;gt;never&amp;lt;/b&amp;gt; simply assign a high priority to all of your queries simply because you want them to get done fast.  Not only does it not work that way, but you may be inserting subtle problems into other plugins by being greedy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLite=&lt;br /&gt;
==Introduction==&lt;br /&gt;
[http://www.sqlite.org/ SQLite] is a fast local-file SQL database engine and SourceMod provides a DBI driver for it.  SQLite differs from MySQL, and thus MySQL queries may not work in SQLite.  The driver type for connections is &amp;lt;tt&amp;gt;sqlite&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLite is local only, most of the connection parameters can be ignored.  The only connection parameter required is &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, which specifies the file name of the database.  Databases are created on demand if they do not already exist, and are stored in &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite&amp;lt;/tt&amp;gt;.  An extension of &amp;quot;.sq3&amp;quot; is automatically appended to the file name.&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify sub-folders in the database name.  For example, &amp;quot;cssdm/players&amp;quot; will become &amp;lt;tt&amp;gt;addons/sourcemod/data/sqlite/cssdm/players.sq3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
SQLite supports the threading layer, and requires all of the same rules as the MySQL driver (including locks on shared connections).&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.sqlite.org SQLite Homepage]&lt;br /&gt;
*[http://sqlitebrowser.sourceforge.net/ SQLite Browser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10096</id>
		<title>Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10096"/>
		<updated>2015-12-29T16:31:58Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Making your function Format-Class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; function, which looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If userName contains &amp;quot;&amp;lt;tt&amp;gt;Mark&amp;lt;/tt&amp;gt;,&amp;quot; the contents of &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; will then be: &amp;quot;&amp;lt;tt&amp;gt;Your name is: Mark&amp;lt;/tt&amp;gt;.&amp;quot;  The prototype of these functions almost always contains the following parameters:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const char[] fmt, {Handle,Float,_} ...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, observe the following two natives:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native void Format(char[] buffer, int maxlength, const char[] fmt, {Handle,Float,_} ...);&lt;br /&gt;
native void PrintToClient(int client, char[] fmt, {Handle,Float,_} ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; is a format-class function.  It can be used exactly as shown earlier:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''u''': Unsigned integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Usage_in_a_Plugin|Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;float fNum = 5.0;&lt;br /&gt;
int iNum = 5;&lt;br /&gt;
char[] str = &amp;quot;5&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Advanced Formatting=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
todo: examples&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
=Making your function Format-Class=&lt;br /&gt;
&lt;br /&gt;
Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables.&lt;br /&gt;
Here's an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void formatExample(const char[] myString , any ...)&lt;br /&gt;
{&lt;br /&gt;
	char[] myFormattedString = new char[strlen(myString)+255];&lt;br /&gt;
	VFormat(myFormattedString, sizeof(myFormattedString), myString, 2);&lt;br /&gt;
	&lt;br /&gt;
	PrintToServer(myFormattedString);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the parameter &amp;quot;any ...&amp;quot;, we can pass data(s) to format our string.&lt;br /&gt;
Now, in order to replace the Format Specifiers by our data(s), we use the API &amp;quot;VFormat&amp;quot;, which documentation can be found here : [https://sm.alliedmods.net/new-api/].&lt;br /&gt;
&lt;br /&gt;
The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.&lt;br /&gt;
&lt;br /&gt;
The 4th parameter indicate the &amp;quot;any ...&amp;quot; parameter position in your function prototype.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10095</id>
		<title>Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10095"/>
		<updated>2015-12-29T16:30:33Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; function, which looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If userName contains &amp;quot;&amp;lt;tt&amp;gt;Mark&amp;lt;/tt&amp;gt;,&amp;quot; the contents of &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; will then be: &amp;quot;&amp;lt;tt&amp;gt;Your name is: Mark&amp;lt;/tt&amp;gt;.&amp;quot;  The prototype of these functions almost always contains the following parameters:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const char[] fmt, {Handle,Float,_} ...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, observe the following two natives:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native void Format(char[] buffer, int maxlength, const char[] fmt, {Handle,Float,_} ...);&lt;br /&gt;
native void PrintToClient(int client, char[] fmt, {Handle,Float,_} ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; is a format-class function.  It can be used exactly as shown earlier:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''u''': Unsigned integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Usage_in_a_Plugin|Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;float fNum = 5.0;&lt;br /&gt;
int iNum = 5;&lt;br /&gt;
char[] str = &amp;quot;5&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Advanced Formatting=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
todo: examples&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
=Making your function Format-Class=&lt;br /&gt;
&lt;br /&gt;
Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables.&lt;br /&gt;
Here's an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public formatExample(const String:myString[] , any:...)&lt;br /&gt;
{&lt;br /&gt;
	new String:myFormattedString[strlen(myString)+255];&lt;br /&gt;
	VFormat(myFormattedString, sizeof(myFormattedString), myString, 2);&lt;br /&gt;
	&lt;br /&gt;
	PrintToServer(myFormattedString);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the parameter &amp;quot;any: ...&amp;quot;, we can pass data(s) to format our string.&lt;br /&gt;
Now, in order to replace the Format Specifiers by our data(s), we use the API &amp;quot;VFormat&amp;quot;, which documentation can be found here : [http://docs.sourcemod.net/api/].&lt;br /&gt;
&lt;br /&gt;
The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.&lt;br /&gt;
&lt;br /&gt;
The 4th parameter indicate the &amp;quot;any: ...&amp;quot; parameter position in your function prototype.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10094</id>
		<title>Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Format_Class_Functions_(SourceMod_Scripting)&amp;diff=10094"/>
		<updated>2015-12-29T16:29:45Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; function, which looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;char buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If userName contains &amp;quot;&amp;lt;tt&amp;gt;Mark&amp;lt;/tt&amp;gt;,&amp;quot; the contents of &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; will then be: &amp;quot;&amp;lt;tt&amp;gt;Your name is: Mark&amp;lt;/tt&amp;gt;.&amp;quot;  The prototype of these functions almost always contains the following parameters:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const char[] fmt, {Handle,Float,_} ...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, observe the following two natives:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native void Format(char[] buffer, int maxlength, const char[] fmt, {Handle,Float,_} ...);&lt;br /&gt;
native void PrintToClient(int client, char[] fmt, {Handle,Float,_} ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; is a format-class function.  It can be used exactly as shown earlier:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''u''': Unsigned integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Usage_in_a_Plugin|Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Advanced Formatting=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
todo: examples&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
=Making your function Format-Class=&lt;br /&gt;
&lt;br /&gt;
Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables.&lt;br /&gt;
Here's an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public formatExample(const String:myString[] , any:...)&lt;br /&gt;
{&lt;br /&gt;
	new String:myFormattedString[strlen(myString)+255];&lt;br /&gt;
	VFormat(myFormattedString, sizeof(myFormattedString), myString, 2);&lt;br /&gt;
	&lt;br /&gt;
	PrintToServer(myFormattedString);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the parameter &amp;quot;any: ...&amp;quot;, we can pass data(s) to format our string.&lt;br /&gt;
Now, in order to replace the Format Specifiers by our data(s), we use the API &amp;quot;VFormat&amp;quot;, which documentation can be found here : [http://docs.sourcemod.net/api/].&lt;br /&gt;
&lt;br /&gt;
The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.&lt;br /&gt;
&lt;br /&gt;
The 4th parameter indicate the &amp;quot;any: ...&amp;quot; parameter position in your function prototype.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10060</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10060"/>
		<updated>2015-11-15T18:41:46Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Extended Variable Declarations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;int float or char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10059</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10059"/>
		<updated>2015-11-15T18:41:01Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: Removal of decl as it is removed as of 1.7&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10058</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10058"/>
		<updated>2015-11-15T18:37:59Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Scope */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero. If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token. At a local scope, this can be a run-time expense. The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables. There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
char blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0. The run-time expense of this initialization is negligible. However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations. &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed. In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read. Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents. For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present). Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined. It could be any value, negative or positive. &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe. The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10057</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10057"/>
		<updated>2015-11-15T18:37:02Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Dynamic Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero. If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token. At a local scope, this can be a run-time expense. The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables. There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
char blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0. The run-time expense of this initialization is negligible. However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations. &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed. In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read. Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents. For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present). Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined. It could be any value, negative or positive. &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe. The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10056</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10056"/>
		<updated>2015-11-15T18:36:25Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Loop Control */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero. If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token. At a local scope, this can be a run-time expense. The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables. There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
char blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0. The run-time expense of this initialization is negligible. However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations. &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed. In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read. Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents. For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present). Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined. It could be any value, negative or positive. &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe. The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10055</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10055"/>
		<updated>2015-11-15T18:35:46Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* While Loops */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero. If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token. At a local scope, this can be a run-time expense. The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables. There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
char blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0. The run-time expense of this initialization is negligible. However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations. &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed. In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read. Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents. For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present). Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined. It could be any value, negative or positive. &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe. The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10054</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10054"/>
		<updated>2015-11-15T18:35:19Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* For Loops */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;s &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero. If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token. At a local scope, this can be a run-time expense. The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables. There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
char blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0. The run-time expense of this initialization is negligible. However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations. &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed. In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read. Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents. For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
int d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present). Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined. It could be any value, negative or positive. &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe. The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SourceMod_SDK&amp;diff=10031</id>
		<title>SourceMod SDK</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SourceMod_SDK&amp;diff=10031"/>
		<updated>2015-10-03T16:48:01Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Further Reading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod SDK is the Software Development Kit for writing SourceMod Extensions and Plugins.  This article briefly introduces it.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
*'''configs''': Configuration files that SourceMod uses&lt;br /&gt;
*'''editor''': Editor related files&lt;br /&gt;
**'''Pawn Studio''': [http://sourceforge.net/projects/pawnstudio Official IDE for SourceMod]&lt;br /&gt;
**'''crimson''': Drop-in syntax highlighting for [http://www.crimsoneditor.com/ Crimson Editor]&lt;br /&gt;
**'''textpad''': Drop-in syntax highlighting for [http://www.textpad.com/ TextPad]&lt;br /&gt;
**'''ultraedit''': Drop-in syntax highlighting for [http://www.ultraedit.com/ UltraEdit/UEStudio]&lt;br /&gt;
*'''extensions''': Publicly open-sourced extensions.&lt;br /&gt;
**'''geoip''': GeoIP extension.&lt;br /&gt;
**'''threader''': Threading extension.&lt;br /&gt;
*'''plugins''': SourceMod plugin implementations.&lt;br /&gt;
**'''include''': Include files and their documentation.&lt;br /&gt;
*'''public''': Public interface files.&lt;br /&gt;
**'''doxygen''': The SDK Doxygen file.&lt;br /&gt;
**'''extensions''': Public interface files that come from extensions.&lt;br /&gt;
**'''licenses''': License information.&lt;br /&gt;
**'''sample_ext''': A sample extension.&lt;br /&gt;
**'''sourcepawn''': SourcePawn header files.&lt;br /&gt;
*'''sourcepawn''': SourcePawn files.&lt;br /&gt;
**'''compiler''': SourcePawn compiler source code.&lt;br /&gt;
*'''translations''': Translation files.&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
*For writing extensions, see [[Writing Extensions]].&lt;br /&gt;
*For documentation, see [[SourceMod Documentation]].&lt;br /&gt;
*For the nightly source code tree, see [https://github.com/alliedmodders/sourcemod SourceMod Central].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SourceMod_SDK&amp;diff=10030</id>
		<title>SourceMod SDK</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SourceMod_SDK&amp;diff=10030"/>
		<updated>2015-10-03T16:46:52Z</updated>

		<summary type="html">&lt;p&gt;Xerox8521: /* Further Reading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod SDK is the Software Development Kit for writing SourceMod Extensions and Plugins.  This article briefly introduces it.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
*'''configs''': Configuration files that SourceMod uses&lt;br /&gt;
*'''editor''': Editor related files&lt;br /&gt;
**'''Pawn Studio''': [http://sourceforge.net/projects/pawnstudio Official IDE for SourceMod]&lt;br /&gt;
**'''crimson''': Drop-in syntax highlighting for [http://www.crimsoneditor.com/ Crimson Editor]&lt;br /&gt;
**'''textpad''': Drop-in syntax highlighting for [http://www.textpad.com/ TextPad]&lt;br /&gt;
**'''ultraedit''': Drop-in syntax highlighting for [http://www.ultraedit.com/ UltraEdit/UEStudio]&lt;br /&gt;
*'''extensions''': Publicly open-sourced extensions.&lt;br /&gt;
**'''geoip''': GeoIP extension.&lt;br /&gt;
**'''threader''': Threading extension.&lt;br /&gt;
*'''plugins''': SourceMod plugin implementations.&lt;br /&gt;
**'''include''': Include files and their documentation.&lt;br /&gt;
*'''public''': Public interface files.&lt;br /&gt;
**'''doxygen''': The SDK Doxygen file.&lt;br /&gt;
**'''extensions''': Public interface files that come from extensions.&lt;br /&gt;
**'''licenses''': License information.&lt;br /&gt;
**'''sample_ext''': A sample extension.&lt;br /&gt;
**'''sourcepawn''': SourcePawn header files.&lt;br /&gt;
*'''sourcepawn''': SourcePawn files.&lt;br /&gt;
**'''compiler''': SourcePawn compiler source code.&lt;br /&gt;
*'''translations''': Translation files.&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
*For writing extensions, see [[Writing Extensions]].&lt;br /&gt;
*For documentation, see [https://wiki.alliedmods.net/SourceMod_Documentation https://wiki.alliedmods.net/SourceMod_Documentation].&lt;br /&gt;
*For the nightly source code tree, see [https://github.com/alliedmodders/sourcemod SourceMod Central].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>Xerox8521</name></author>
		
	</entry>
</feed>