<?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=Edon1337</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=Edon1337"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Edon1337"/>
	<updated>2026-04-19T12:07:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10289</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10289"/>
		<updated>2017-04-16T19:05:13Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how [[Pawn]] works. You should be reading this portion of the document, sitting at a computer, with a text editor and [[Pawn]] compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is [[Pawn]] enabled, try AMXX-Studio from the [http://www.amxmodx.org/downloads.php AMX Mod X downloads]section.&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section for details. You should also be familiar with [[Configuring_AMX_Mod_X#Installing|installing]] plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three defines&lt;br /&gt;
#define PLUGIN &amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
Note : If you don't call plugin_init in your plugin, nothing goes wrong, you simply can consider it as a custom forward. Just that your plugin won't be registered when you write 'amxx plugins'.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, charsmax(Arg1))&lt;br /&gt;
     read_argv(2, Arg2, charsmax(Arg2))&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, charsmax(Arg1))&lt;br /&gt;
     read_argv(2, Arg2, charsmax(Arg2))&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;cstrike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new g_iAMXXStartMoney&lt;br /&gt;
new g_iMPStartMoney&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     g_iAMXXStartMoney = register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
     g_iMPStartMoney = get_cvar_num(&amp;quot;mp_startmoney&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     new iCvarMoney = get_pcvar_num(g_iAMXXStartMoney)    &lt;br /&gt;
&lt;br /&gt;
     if(iCvarMoney &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, iCvarMoney)&lt;br /&gt;
     } else {&lt;br /&gt;
          cs_set_user_money(id, g_iMPStartMoney)&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10288</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10288"/>
		<updated>2017-04-16T18:59:50Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how [[Pawn]] works. You should be reading this portion of the document, sitting at a computer, with a text editor and [[Pawn]] compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is [[Pawn]] enabled, try AMXX-Studio from the [http://www.amxmodx.org/downloads.php AMX Mod X downloads]section.&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section for details. You should also be familiar with [[Configuring_AMX_Mod_X#Installing|installing]] plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three defines&lt;br /&gt;
#define PLUGIN &amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
Note : If you don't call plugin_init in your plugin, nothing goes wrong, you simply can consider it as a custom forward. Just that your plugin won't be registered when you write 'amxx plugins'.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, charsmax(Arg1))&lt;br /&gt;
     read_argv(2, Arg2, charsmax(Arg2))&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, charsmax(Arg1))&lt;br /&gt;
     read_argv(2, Arg2, 3charsmax(Arg2))&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;cstrike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10287</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10287"/>
		<updated>2017-04-16T18:58:59Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how [[Pawn]] works. You should be reading this portion of the document, sitting at a computer, with a text editor and [[Pawn]] compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is [[Pawn]] enabled, try AMXX-Studio from the [http://www.amxmodx.org/downloads.php AMX Mod X downloads]section.&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section for details. You should also be familiar with [[Configuring_AMX_Mod_X#Installing|installing]] plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three defines&lt;br /&gt;
#define PLUGIN &amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
Note : If you don't call plugin_init in your plugin, nothing goes wrong, you simply can consider it as a custom forward. Just that your plugin won't be registered when you write 'amxx plugins'.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;cstrike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10286</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10286"/>
		<updated>2017-04-16T18:58:18Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how [[Pawn]] works. You should be reading this portion of the document, sitting at a computer, with a text editor and [[Pawn]] compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is [[Pawn]] enabled, try AMXX-Studio from the [http://www.amxmodx.org/downloads.php AMX Mod X downloads]section.&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section for details. You should also be familiar with [[Configuring_AMX_Mod_X#Installing|installing]] plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three defines&lt;br /&gt;
#define PLUGIN &amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
Note : If you don't call plugin_init in your plugin, nothing goes wrong, you simply can consider it as a custom forward. Just that your plugin won't be registered when you write 'amxx plugins'.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PLUGIN &amp;quot;Change Health&amp;quot;&lt;br /&gt;
#define VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
#define AUTHOR &amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;cstrike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Finding_Entities_(AMX_Mod_X)&amp;diff=10278</id>
		<title>Finding Entities (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Finding_Entities_(AMX_Mod_X)&amp;diff=10278"/>
		<updated>2017-02-27T21:35:39Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
It is sometimes necessary to find an entity in the world for some reason. For example, you may need to find a button in the world, and then remove it (this example will be covered later). This article will explain how to do so.&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
There are a number of functions built into AMX Mod X / AMXX Modules that allow you to find entities. For a complete list, please consult this page: http://www.amxmodx.org/funcwiki.php?search=find_ent&amp;amp;go=search&lt;br /&gt;
&lt;br /&gt;
(As of last edit, these are the functions included):&lt;br /&gt;
*find_ent_by_class&lt;br /&gt;
*find_ent_by_model&lt;br /&gt;
*find_ent_by_owner&lt;br /&gt;
*find_ent_by_target&lt;br /&gt;
*find_ent_by_tname&lt;br /&gt;
*find_ent_in_sphere &lt;br /&gt;
*find_sphere_class&lt;br /&gt;
&lt;br /&gt;
==find_ent_by_class==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function allows you to find an entity based on it's classname. All entities have classnames. For example, a player's classname is &amp;quot;player&amp;quot;, while a button is either &amp;quot;func_button&amp;quot; or &amp;quot;func_rot_button&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would simply use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
find_ent_by_class(-1,&amp;quot;classname_to_find&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note : Index is -1 because that's the invalid entity index. We start from the invalid one so we can get all the entities, if you start from a different index, all entities with a lower index will be ignored.&lt;br /&gt;
&lt;br /&gt;
==find_ent_by_model==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to find an entity based on its model. Some entities do not have models, meaning they cannot be found using this method. Also, it is, most of the time, better to use another type of ent finding, as this can be highly inaccurate and be broken by something as simple as a model changing plugin. This function also takes into account the class name, and is generally used more for isolating a certain model from a set of classnames (ex you have 3 grenades, with different models, and want to find 1 of them)&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
find_ent_by_model(-1,&amp;quot;classname_to_find&amp;quot;,&amp;quot;model_to_find&amp;quot;)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==find_ent_by_owner==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to find an entity based on an owner. For example, if there is a player in the world, and you want to find if he has thrown a grenade out, you would use this and check for &amp;quot;grenade&amp;quot; entities that's owner is the player.&lt;br /&gt;
Note: planted C4 (in CS) also have &amp;quot;grenade&amp;quot; classname.&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
find_ent_by_owner(-1,&amp;quot;classname_to_find&amp;quot;,owner_id,0);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the last parameter. This is a mode to find in. To see a full list, consult this page:&lt;br /&gt;
http://www.amxmodx.org/funcwiki.php?go=func&amp;amp;id=345&lt;br /&gt;
&lt;br /&gt;
==find_ent_by_target==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function allows one to find an entity based on its target. This function also checks for classname.&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
find_ent_by_target(-1,&amp;quot;classname_to_find&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==find_ent_by_tname==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
This essentially functions the same as find_ent_by_target.&lt;br /&gt;
&lt;br /&gt;
==find_ent_in_sphere==&lt;br /&gt;
&amp;lt;Function is included in Engine&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to find an entity within a certain distance of another entity. This can be quite handy to, for example, see if a player is around another player, and then deal damage or slap that player. This is effectively a shortcut to using find_ent_by_class and get_distance(_f) together.&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
find_ent_in_sphere(-1,location_of_ent_vector,radius_float);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==find_sphere_class==&lt;br /&gt;
This function is probably the most complex of all the find_ent functions. This allows you to find an entity inside a certain radius of another entity, with a certian classname. This is effectively a shortcut to using find_ent_by_class &amp;amp; get_distance &amp;amp; entity_get_string(ent,EV_SZ_classname... or find_ent_in_sphere &amp;amp; entity_get_string(ent,EV_SZ_classname...&lt;br /&gt;
&lt;br /&gt;
To find an entity using this, one would use the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new entlist[513];&lt;br /&gt;
find_sphere_class(0,&amp;quot;classname_to_find&amp;quot;,radius_float,entlist,512,origin_vector);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, note that origin_vector and the first parameter (_aroundent) should not both be specified. If _aroundent is specified as 0, origin_vector is used. If origin_vector is not specified, or is 0, then _aroundent is used.&lt;br /&gt;
&lt;br /&gt;
==Looping==&lt;br /&gt;
If, for example, one wants to loop one of these, it is quite simple to do so.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while((ent = find_ent_by_class(ent,&amp;quot;classname_to_find&amp;quot;)) != 0)&lt;br /&gt;
{&lt;br /&gt;
	// do whatever&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will find every entity with classname &amp;quot;classname_to_find&amp;quot; and then execute the &amp;quot;// do whatever&amp;quot; code every time it finds one.&lt;br /&gt;
&lt;br /&gt;
==Wrap Up==&lt;br /&gt;
For complete usage, please consult the Engine Module page at:&lt;br /&gt;
http://www.amxmodx.org/funcwiki.php?go=module&amp;amp;id=3&lt;br /&gt;
&lt;br /&gt;
[[Category: Scripting_(AMX_Mod_X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10277</id>
		<title>Advanced Scripting (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10277"/>
		<updated>2017-02-26T13:04:30Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will briefly summarize some of the more advanced topics of [[:Category:Scripting (AMX Mod X)|AMX Mod X Scripting]].&lt;br /&gt;
&lt;br /&gt;
=Tasks=&lt;br /&gt;
&lt;br /&gt;
Tasks are timers that let you run code at an interval, either once or repeated. They are useful for things like waiting a few seconds, setting objects to destroy themselves, or just repeating a task over and over.&lt;br /&gt;
&lt;br /&gt;
A task can be set in a number of different ways. The actual function is set_task():&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_task(Float:time,const function[],id = 0,parameter[]=&amp;quot;&amp;quot;,len = 0,flags[]=&amp;quot;&amp;quot;, repeat = 0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameters break down as such:&lt;br /&gt;
&lt;br /&gt;
* Float:time - Interval of timer in seconds (minimum 0.1 seconds)&lt;br /&gt;
* function[] - A string that contains the public function to run on the timer&lt;br /&gt;
* id - A unique id to assign to the task&lt;br /&gt;
* parameter - An array contain data to send to the timer function&lt;br /&gt;
* len - Size of the array to send to the timer function&lt;br /&gt;
* flags - One of the following:&lt;br /&gt;
** &amp;quot;a&amp;quot; - Repeat task a specified number of times&lt;br /&gt;
** &amp;quot;b&amp;quot; - Loop task infinitely&lt;br /&gt;
** &amp;quot;c&amp;quot; - do task on time after a map timeleft&lt;br /&gt;
** &amp;quot;d&amp;quot; - do task on time before a map timeleft&lt;br /&gt;
* repeat - If flags is &amp;quot;a&amp;quot;, specifies the number of times to repeat the task&lt;br /&gt;
&lt;br /&gt;
An example of a task is below. It will slap a specified player 5 times, once per second.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//the timed function receives the parameter array and its task id&lt;br /&gt;
public slapTask(params[], id)&lt;br /&gt;
{&lt;br /&gt;
   new player = params[0]&lt;br /&gt;
   user_slap(player, 5)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public start_slapping(id)&lt;br /&gt;
{&lt;br /&gt;
   new params[1]&lt;br /&gt;
   params[0] = id&lt;br /&gt;
   //we don't need a specific id&lt;br /&gt;
   set_task(1.0, &amp;quot;slapTask&amp;quot;, 0, params, 1, &amp;quot;a&amp;quot;, 5)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that if you specify 0 for task id, then the task function should look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public slapTask()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Menus=&lt;br /&gt;
&lt;br /&gt;
Menus are HUD messages that give a player a choice of options to select. They are quite messy to deal with but can be very useful for things like voting and command selection.&lt;br /&gt;
&lt;br /&gt;
Menus must be registered by two things - a set of &amp;quot;keys&amp;quot; that tells how many options to register and a string which identifies the menu as unique. This string must appear in the beginning of every menu you want to trigger your function. When you display a menu, you can show it to one or more players. Once they hit a key, the result of their key press will be sent to the function you registered the menu to.&lt;br /&gt;
&lt;br /&gt;
For our example, we'll make a menu that displays a list of guns: AK47, M4A1, or AWP, to a player. Whichever he selects, he will be given.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two commands are apparent here - register_menuid and register_menucmd. register_menuid registers a short phrase that will appear at the beginning of the menu, then returns an id. This id is the first parameter to register_menucmd. The second parameter to register_menucmd is the key configuration. Our menu will have three options, so we've added three menu keys in. In actuality, these are bitwise flags totalling &amp;quot;7&amp;quot;, but that's not important. The last parameter is the public function that will handle the menu results.&lt;br /&gt;
&lt;br /&gt;
Next, how do we show the menu? Let's make a quick console command: &amp;quot;giveme&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    register_clcmd(&amp;quot;giveme&amp;quot;, &amp;quot;showWeaponMenu&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
register_clcmd is similar to register_concmd, except it only takes two parameters. It's used to register any command a client can use (except for special ones, like +attack).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//The clcmd function will just give us the player id&lt;br /&gt;
public showWeaponMenu(id)&lt;br /&gt;
{&lt;br /&gt;
    new menu[192]&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
&lt;br /&gt;
    format(menu, 191, &amp;quot;Which Weapon?^n^n1. AK47^n2. M4A1^n3. AWP&amp;quot;)&lt;br /&gt;
    show_menu(id, keys, menu)&lt;br /&gt;
    return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Our menu function will get the player id and the key they pressed&lt;br /&gt;
public giveWeapon(id, key)&lt;br /&gt;
{&lt;br /&gt;
    //key will start at zero&lt;br /&gt;
    if (key == 0)&lt;br /&gt;
    {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_ak47&amp;quot;)&lt;br /&gt;
    } else if (key == 1) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_m4a1&amp;quot;)&lt;br /&gt;
    } else if (key == 2) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_awp&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we're done! The format line may be a little confusing. The &amp;quot;^n&amp;quot; means &amp;quot;new line&amp;quot;, so the menu looks nicely formatted. You can use other modifiers in VGUI2 mods, such as &amp;quot;\w&amp;quot; for white text, &amp;quot;\r&amp;quot; for red text, and &amp;quot;\y&amp;quot; for yellow text. When a player types the command, he will see the menu. When he hits a key, the giveWeapon function will receive his id and the key number he pressed. Then he will get a gun corresponding to what he chose.&lt;br /&gt;
&lt;br /&gt;
=Events/Messages=&lt;br /&gt;
&lt;br /&gt;
For this demonstration, we're going to extend the above example. Every time a player respawns, he will be shown the menu to choose a weapon (note - we're ignoring other things like blocking buying and removing buyzones, this is just a demonstration).&lt;br /&gt;
&lt;br /&gt;
Messages are a way for Half-Life clients to talk to servers, and vice versa. They are specially formatted lists of parameters. For example, the message &amp;quot;DeathMsg&amp;quot; (message id 83) has three parameters: Attacker (byte), Victim (byte), and Weapon (string). You can either capture messages or send them. Here, we'll do a simple demonstration of both. First let's make it so a user gets their gun menu when they spawn.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    //flags - b means &amp;quot;sent to one target&amp;quot;, e means &amp;quot;target is alive&amp;quot;&lt;br /&gt;
    //this event is sent when a player spawns&lt;br /&gt;
    register_event(&amp;quot;ResetHUD&amp;quot;, &amp;quot;hook_hud&amp;quot;, &amp;quot;be&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_hud(id)&lt;br /&gt;
{&lt;br /&gt;
    //since we specify no parameters to the task,&lt;br /&gt;
    //the task id will be given to the function&lt;br /&gt;
    //this is useful because we can reuse our old&lt;br /&gt;
    //show menu function which takes an id&lt;br /&gt;
    set_task(0.2, &amp;quot;showWeaponMenu&amp;quot;, id)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we've set a small delay when we receive the message - this is to make sure that the user has had time to respawn. register_event can take more parameters in order to help restrict the event you catch - for example only matching certain parameters. You can read more about this in the function reference.&lt;br /&gt;
&lt;br /&gt;
Now, let's say we want to figure out when a player has died...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Message Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this message informs everyone of a death, so we use&lt;br /&gt;
    // flag &amp;quot;a&amp;quot; - global event&lt;br /&gt;
    register_event(&amp;quot;DeathMsg&amp;quot;, &amp;quot;hook_death&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_death()&lt;br /&gt;
{&lt;br /&gt;
    new Killer = read_data(1) //get the first message parameter&lt;br /&gt;
    new Victim = read_data(2) //get the second message parameter&lt;br /&gt;
    new headshot = read_data(3) //was this a headshot?&lt;br /&gt;
    new weapon[32]&lt;br /&gt;
    read_data(4, weapon, 31)  //get the weapon name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, let's say we want to make a simple function for generating a death message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock make_deathMsg(Killer, Victim, const weapon[])&lt;br /&gt;
{&lt;br /&gt;
    //message_begin starts a message.  NEVER start two messages at once.&lt;br /&gt;
    //MSG_ALL means send the message to everyone&lt;br /&gt;
    //get_user_msgid returns the id of a message name&lt;br /&gt;
    //{0,0,0} is the origin vector - not used here&lt;br /&gt;
    //0 is the target - no specific target here&lt;br /&gt;
    message_begin(MSG_ALL, get_user_msgid(&amp;quot;DeathMsg&amp;quot;), {0,0,0}, 0) &lt;br /&gt;
    write_byte(Killer)&lt;br /&gt;
    write_byte(Victim)&lt;br /&gt;
    write_string(weapon)&lt;br /&gt;
    message_end()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find more about messages, consult the HLSDK, AMX Mod X forums, HL-related programming sites, or other plugins. To list the messages a mod has, type &amp;quot;meta game&amp;quot; in the server console (with metamod loaded). You can also use register_message, the more advanced message disection method found in the Engine module.&lt;br /&gt;
&lt;br /&gt;
=Catching Log Messages=&lt;br /&gt;
&lt;br /&gt;
Catching log messages is not used heavily any more, but it's still good to know how to do it. As log messages are sent by the mod, AMX Mod X will be able to catch them and let you hook them. For our example, let's give everyone $16,000 on round start.&lt;br /&gt;
&lt;br /&gt;
The log messages for rounds are sent like this: World triggered &amp;quot;Round_Start&amp;quot;. AMX Mod X will consider &amp;quot;World_triggered&amp;quot; as the first parameter and &amp;quot;Round_Start&amp;quot; as the second parameter. So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Log Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this will filter for two parameters&lt;br /&gt;
    //roundstart is the public function&lt;br /&gt;
    register_logevent(&amp;quot;roundstart&amp;quot;, 2, &amp;quot;0=World triggered&amp;quot;, &amp;quot;1=Round_Start&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundstart()&lt;br /&gt;
{&lt;br /&gt;
    //set a small delay to make sure everyone spawns&lt;br /&gt;
    set_task(1.0, &amp;quot;roundDelay&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundDelay(taskId)&lt;br /&gt;
{&lt;br /&gt;
    new players[32], num&lt;br /&gt;
    get_players(players, num)&lt;br /&gt;
&lt;br /&gt;
    for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
         cs_set_user_money(players[i], 16000)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also read specific log parameters with read_logdata(), which can only be used inside the &amp;quot;plugin_log()&amp;quot; forward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//receives all log messages&lt;br /&gt;
public plugin_log()&lt;br /&gt;
{&lt;br /&gt;
    new data[32]&lt;br /&gt;
    read_logdata(data, 31)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Multi-Lingual Support=&lt;br /&gt;
&lt;br /&gt;
Adding multi-lingual support to a plugin can be difficult, but it's usually worth it if you have clients who are willing to translate your strings into their native language.&lt;br /&gt;
&lt;br /&gt;
The first step is to identify what needs to be translated. Say you have a call like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new score = get_score()&lt;br /&gt;
client_print(id, print_chat, &amp;quot;[AMXX] Your score is %d&amp;quot;, score)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a good candidate for being multi-lingual. First, create a .txt file (preferrably named after your plugin) and store it in addons\amxmodx\data\lang\. Let's use &amp;quot;myplugin.txt&amp;quot; for the example. For each language, add an entry to the file. Entries are set up as 'keys', which are matched to 'translation strings'. Observe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(addons\amxmodx\data\lang\myplugin.txt)&lt;br /&gt;
&lt;br /&gt;
[en]&lt;br /&gt;
SCORE_MSG = Your score is %d&lt;br /&gt;
&lt;br /&gt;
[de]&lt;br /&gt;
SCORE_MSG = Ihr Spielergebnis ist %d&lt;br /&gt;
&lt;br /&gt;
[es]&lt;br /&gt;
SCORE_MSG = Su cuenta es %d&lt;br /&gt;
&lt;br /&gt;
[fr]&lt;br /&gt;
SCORE_MSG = Votre score est %d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, in plugin_init(), you must register the language keys:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    //assumes placed in amxmodx\data\lang&lt;br /&gt;
    register_dictionary(&amp;quot;myplugin.txt&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, here comes the hard part. AMX Mod X's Multi-Lingual API is built into the format() style routines. For anything that looks like or uses format()-style strings, you can use the ML API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(id, print_chat, &amp;quot;[AMXX] %L&amp;quot;, id, &amp;quot;SCORE_MSG&amp;quot;, get_score())&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's break this down. For each %L that appears, we need at least two parameters. The first parameter is the TARGET. This must be a player id, LANG_SERVER (meaning show in the server's native language), or LANG_PLAYER. LANG_PLAYER is a special modifier that should only be used when sending a message to all players - it means &amp;quot;show in every player's native language&amp;quot;. The second parameter is the key string that identifies the language phrase to translate. Lastly, if the translated string requires any parameters itself (ours needs %d, one integer), that must be added as well.&lt;br /&gt;
&lt;br /&gt;
You can get very complicated designs with this, but it's recommended that you keep things simple for clarity. Here is a final example using a global message to all players, assuming the key HELLO is properly translated in all the languages available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(0, print_chat, &amp;quot;[AMXX] %L&amp;quot;, LANG_PLAYER, &amp;quot;HELLO&amp;quot;)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=SQL Support=&lt;br /&gt;
&lt;br /&gt;
SQL support has greatly improved in AMX Mod X. There is a common set of natives that work with a single driver, so as long as one (and only one) SQL module is loaded, the SQL (or DBI) natives will work. Here is a short primer on how to use the DBI natives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Create a connection&lt;br /&gt;
	new Sql:mysql = dbi_connect(&amp;quot;localhost&amp;quot;, &amp;quot;dvander&amp;quot;, &amp;quot;pass&amp;quot;, &amp;quot;dbase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the connection is less than 1, it is bad	&lt;br /&gt;
	if (mysql &amp;lt; SQL_OK) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error1: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Connection handle: %d&amp;quot;, mysql)&lt;br /&gt;
//Run a query&lt;br /&gt;
	new Result:ret = dbi_query(mysql, &amp;quot;INSERT INTO config (keyname, val) VALUES ('amx', 'yes')&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than RESULT_NONE, it failed	&lt;br /&gt;
	if (ret &amp;lt; RESULT_NONE) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error2: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Do a select query	&lt;br /&gt;
	new Result:res = dbi_query(mysql, &amp;quot;SELECT * FROM config&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than or equal to RESULT_FAILED, you got an invalid result and can't do anything with it.&lt;br /&gt;
	if (res &amp;lt;= RESULT_FAILED) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error3: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Result handle: %d&amp;quot;, res)&lt;br /&gt;
&lt;br /&gt;
//Loop through the result set	&lt;br /&gt;
	while (res &amp;amp;&amp;amp; dbi_nextrow(res)&amp;gt;0) {&lt;br /&gt;
		new qry[32]&lt;br /&gt;
//Get the column/field called &amp;quot;keyname&amp;quot; from the result set&lt;br /&gt;
		dbi_result(res, &amp;quot;keyname&amp;quot;, qry, 32)&lt;br /&gt;
		server_print(&amp;quot;result: %s&amp;quot;, qry)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Free the result set	&lt;br /&gt;
	dbi_free_result(res)&lt;br /&gt;
&lt;br /&gt;
//Close the connection	&lt;br /&gt;
	dbi_close(mysql)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Regular Expressions=&lt;br /&gt;
&lt;br /&gt;
Regular Expressions let you describe ways in which to break down strings. They are extremely powerful. AMX Mod X uses the Perl Compatible RE library, you can read the specifics at their site. AMX Mod X offers regular expressions with the regex_amxx module. Here is a short example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Regex&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    register_srvcmd(&amp;quot;amx_regex&amp;quot;, &amp;quot;cmdtest&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmdtest()&lt;br /&gt;
{&lt;br /&gt;
    new str[] = &amp;quot;It's Walky!&amp;quot;&lt;br /&gt;
    //this pattern will match any string which contains&lt;br /&gt;
    // two groupings of characters separated by a space&lt;br /&gt;
    // the two groupings are substrings 1 and 2&lt;br /&gt;
    new pattern[] = &amp;quot;(.+) (.+)&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    new num, error[128]&lt;br /&gt;
    //str = string&lt;br /&gt;
    //pattern = pattern to use&lt;br /&gt;
    //num = special return case code&lt;br /&gt;
    //error = if there's an error, it will go here&lt;br /&gt;
    //127 - error's max length&lt;br /&gt;
    new Regex:re = regex_match(str, pattern, num, error, 127)&lt;br /&gt;
&lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)    &lt;br /&gt;
&lt;br /&gt;
    //REGEX_OK means there was a match&lt;br /&gt;
    if (re &amp;gt;= REGEX_OK)&lt;br /&gt;
    {&lt;br /&gt;
        new str2[64]&lt;br /&gt;
        //since it returned REGEX_OK, num has&lt;br /&gt;
        // the number of substrings matched by the pattern.&lt;br /&gt;
        //the first substring (0) seems to match the whole string.&lt;br /&gt;
        for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
        {&lt;br /&gt;
            regex_substr(re, i, str2, 63)&lt;br /&gt;
            server_print(&amp;quot;Substring %d: %s&amp;quot;, i, str2)&lt;br /&gt;
        }&lt;br /&gt;
        //the regular expression matcher uses memory.&lt;br /&gt;
        //you must free it if you get REGEX_OK&lt;br /&gt;
        //This will also set re to 0.&lt;br /&gt;
        regex_free(re)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //note the invalid regular expression pattern&lt;br /&gt;
    //this will return REGEX_PATTERN_FAIL, -1&lt;br /&gt;
    re = regex_match(&amp;quot;Bruno the Bandit&amp;quot;, &amp;quot;.+(]&amp;quot;, num, error, 127)&lt;br /&gt;
    &lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you compile and run this script (amx_regex in server console) you will see the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Result=1, num=3, error=&lt;br /&gt;
Substring 0: It's Walky!&lt;br /&gt;
Substring 1: It's&lt;br /&gt;
Substring 2: Walky!&lt;br /&gt;
Result=-1, num=4, error=missing ) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the third parameter to &amp;quot;regex_match()&amp;quot; is special. It's either the number of substrings, a match error code, or a pattern error position (depending on the return value).&lt;br /&gt;
&lt;br /&gt;
=Entities=&lt;br /&gt;
&lt;br /&gt;
Entities are basically any dynamic structure in Half-Life. Players, weapons, grenades, and other little objects laying around are entities. They have a unique &amp;quot;entity id&amp;quot; which you can use to change their values.&lt;br /&gt;
&lt;br /&gt;
I won't go into this too deeply as it's a complicated subject, but the Engine module features natives that let you modify the properties of entities, or search for entities in game by their class/owner (class is the type of entity, such as &amp;quot;player&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
For this example, we'll make an entity that looks like a fake player holding a gun.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	//create a basic entity&lt;br /&gt;
	new entid = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	//set its classname&lt;br /&gt;
	entity_set_string(entid, EV_SZ_classname, &amp;quot;some_guy&amp;quot;)&lt;br /&gt;
	//set its model&lt;br /&gt;
	entity_set_model(entid, &amp;quot;models/w_suit.mdl&amp;quot;)&lt;br /&gt;
	new Float:Vec[3] = {0.0,0.0,0.0}&lt;br /&gt;
	//set its origin &lt;br /&gt;
	entity_set_origin(entid, Vec)&lt;br /&gt;
	//set some basic properties&lt;br /&gt;
	entity_set_int(entid, EV_INT_solid, 1)&lt;br /&gt;
	entity_set_int(entid, EV_INT_movetype, 6)&lt;br /&gt;
	//create the weapon - thanks to pimp_daddy!&lt;br /&gt;
	entWeapon = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	entity_set_string(entWeapon, EV_SZ_classname, weapString)&lt;br /&gt;
	//set to follow&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_movetype, MOVETYPE_FOLLOW)&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_solid, SOLID_NOT)&lt;br /&gt;
	entity_set_edict(entWeapon, EV_ENT_aiment, entid)&lt;br /&gt;
	entity_set_model(entWeapon, &amp;quot;models/p_m4a1.mdl&amp;quot;) &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change other basic things, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//how set_user_armor() works in the fun module&lt;br /&gt;
stock set_armor(player, Float:value)&lt;br /&gt;
{&lt;br /&gt;
    entity_set_int(player, EV_FL_armorvalue, value)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=FakeMeta=&lt;br /&gt;
&lt;br /&gt;
FakeMeta is the next generation of Half-Life scripting. It essentially lets you write MetaMod plugins in Pawn. It is extremely powerful, and for this reason, it won't really be covered here. This is just to tell you what it is capable of.&lt;br /&gt;
&lt;br /&gt;
* Engine/DLL Calls&lt;br /&gt;
**There are two types of functions in the HL namespace - Engine functions and DLL functions (DLL functions are ones the game/mod library must export). Both of these can be called using the FakeMeta module using the dllfunc() and engfunc() natives. The parameters are directly passed on to MetaMod, so be careful! You could easily crash a server doing the wrong thing.&lt;br /&gt;
* Engine/DLL Hooks&lt;br /&gt;
**As stated above, HL provides Engine and DLL functions. You can also hook/supercede these calls using register_forward. You can supercede these calls using fm_return() and return PLUGIN_HANDLED. Again, make sure you know what you are doing. Malformed hooks will cause crashes.&lt;br /&gt;
* Easy entity manipulation&lt;br /&gt;
**FakeMeta replaces Engine's entity__() function with a natives called &amp;quot;pev()&amp;quot; and &amp;quot;set_pev()&amp;quot;. They are a bit easier to use. For more information see the fakemeta includes.&lt;br /&gt;
* Private Offset Hacking&lt;br /&gt;
**Private offsets are offsets into a block of memory called &amp;quot;pvPrivateData&amp;quot;. The right offsets can often modify game-specific features, such as money in Counter-Strike, or resources in Natural-Selection. However, the wrong offsets can cause game crashes.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10276</id>
		<title>Advanced Scripting (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10276"/>
		<updated>2017-02-26T13:02:23Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will briefly summarize some of the more advanced topics of [[:Category:Scripting (AMX Mod X)|AMX Mod X Scripting]].&lt;br /&gt;
&lt;br /&gt;
=Tasks=&lt;br /&gt;
&lt;br /&gt;
Tasks are timers that let you run code at an interval, either once or repeated. They are useful for things like waiting a few seconds, setting objects to destroy themselves, or just repeating a task over and over.&lt;br /&gt;
&lt;br /&gt;
A task can be set in a number of different ways. The actual function is set_task():&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_task(Float:time,const function[],id = 0,parameter[]=&amp;quot;&amp;quot;,len = 0,flags[]=&amp;quot;&amp;quot;, repeat = 0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameters break down as such:&lt;br /&gt;
&lt;br /&gt;
* Float:time - Interval of timer in seconds (minimum 0.1 seconds)&lt;br /&gt;
* function[] - A string that contains the public function to run on the timer&lt;br /&gt;
* id - A unique id to assign to the task&lt;br /&gt;
* parameter - An array contain data to send to the timer function&lt;br /&gt;
* len - Size of the array to send to the timer function&lt;br /&gt;
* flags - One of the following:&lt;br /&gt;
** &amp;quot;a&amp;quot; - Repeat task a specified number of times&lt;br /&gt;
** &amp;quot;b&amp;quot; - Loop task infinitely&lt;br /&gt;
** &amp;quot;c&amp;quot; - do task on time after a map timeleft&lt;br /&gt;
** &amp;quot;d&amp;quot; - do task on time before a map timeleft&lt;br /&gt;
* repeat - If flags is &amp;quot;a&amp;quot;, specifies the number of times to repeat the task&lt;br /&gt;
&lt;br /&gt;
An example of a task is below. It will slap a specified player 5 times, once per second.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//the timed function receives the parameter array and its task id&lt;br /&gt;
public slapTask(params[], id)&lt;br /&gt;
{&lt;br /&gt;
   new player = params[0]&lt;br /&gt;
   user_slap(player, 5)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public start_slapping(id)&lt;br /&gt;
{&lt;br /&gt;
   new params[1]&lt;br /&gt;
   params[0] = id&lt;br /&gt;
   //we don't need a specific id&lt;br /&gt;
   set_task(1.0, &amp;quot;slapTask&amp;quot;, 0, params, 1, &amp;quot;a&amp;quot;, 5)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that if you specify 0 for task id, then the task function should look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public slapTask()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Menus=&lt;br /&gt;
&lt;br /&gt;
Menus are HUD messages that give a player a choice of options to select. They are quite messy to deal with but can be very useful for things like voting and command selection.&lt;br /&gt;
&lt;br /&gt;
Menus must be registered by two things - a set of &amp;quot;keys&amp;quot; that tells how many options to register and a string which identifies the menu as unique. This string must appear in the beginning of every menu you want to trigger your function. When you display a menu, you can show it to one or more players. Once they hit a key, the result of their key press will be sent to the function you registered the menu to.&lt;br /&gt;
&lt;br /&gt;
For our example, we'll make a menu that displays a list of guns: AK47, M4A1, or AWP, to a player. Whichever he selects, he will be given.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two commands are apparent here - register_menuid and register_menucmd. register_menuid registers a short phrase that will appear at the beginning of the menu, then returns an id. This id is the first parameter to register_menucmd. The second parameter to register_menucmd is the key configuration. Our menu will have three options, so we've added three menu keys in. In actuality, these are bitwise flags totalling &amp;quot;7&amp;quot;, but that's not important. The last parameter is the public function that will handle the menu results.&lt;br /&gt;
&lt;br /&gt;
Next, how do we show the menu? Let's make a quick console command: &amp;quot;giveme&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    register_clcmd(&amp;quot;giveme&amp;quot;, &amp;quot;showWeaponMenu&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
register_clcmd is similar to register_concmd, except it only takes two parameters. It's used to register any command a client can use (except for special ones, like +attack).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//The clcmd function will just give us the player id&lt;br /&gt;
public showWeaponMenu(id)&lt;br /&gt;
{&lt;br /&gt;
    new menu[192]&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
&lt;br /&gt;
    format(menu, 191, &amp;quot;Which Weapon?^n^n1. AK47^n2. M4A1^n3. AWP&amp;quot;)&lt;br /&gt;
    show_menu(id, keys, menu)&lt;br /&gt;
    return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Our menu function will get the player id and the key they pressed&lt;br /&gt;
public giveWeapon(id, key)&lt;br /&gt;
{&lt;br /&gt;
    //key will start at zero&lt;br /&gt;
    if (key == 0)&lt;br /&gt;
    {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_ak47&amp;quot;)&lt;br /&gt;
    } else if (key == 1) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_m4a1&amp;quot;)&lt;br /&gt;
    } else if (key == 2) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_awp&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we're done! The format line may be a little confusing. The &amp;quot;^n&amp;quot; means &amp;quot;new line&amp;quot;, so the menu looks nicely formatted. You can use other modifiers in VGUI2 mods, such as &amp;quot;\w&amp;quot; for white text, &amp;quot;\r&amp;quot; for red text, and &amp;quot;\y&amp;quot; for yellow text. When a player types the command, he will see the menu. When he hits a key, the giveWeapon function will receive his id and the key number he pressed. Then he will get a gun corresponding to what he chose.&lt;br /&gt;
&lt;br /&gt;
=Events/Messages=&lt;br /&gt;
&lt;br /&gt;
For this demonstration, we're going to extend the above example. Every time a player respawns, he will be shown the menu to choose a weapon (note - we're ignoring other things like blocking buying and removing buyzones, this is just a demonstration).&lt;br /&gt;
&lt;br /&gt;
Messages are a way for Half-Life clients to talk to servers, and vice versa. They are specially formatted lists of parameters. For example, the message &amp;quot;DeathMsg&amp;quot; (message id 83) has three parameters: Attacker (byte), Victim (byte), and Weapon (string). You can either capture messages or send them. Here, we'll do a simple demonstration of both. First let's make it so a user gets their gun menu when they spawn.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    //flags - b means &amp;quot;sent to one target&amp;quot;, e means &amp;quot;target is alive&amp;quot;&lt;br /&gt;
    //this event is sent when a player spawns&lt;br /&gt;
    register_event(&amp;quot;ResetHUD&amp;quot;, &amp;quot;hook_hud&amp;quot;, &amp;quot;be&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_hud(id)&lt;br /&gt;
{&lt;br /&gt;
    //since we specify no parameters to the task,&lt;br /&gt;
    //the task id will be given to the function&lt;br /&gt;
    //this is useful because we can reuse our old&lt;br /&gt;
    //show menu function which takes an id&lt;br /&gt;
    set_task(0.2, &amp;quot;showWeaponMenu&amp;quot;, id)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we've set a small delay when we receive the message - this is to make sure that the user has had time to respawn. register_event can take more parameters in order to help restrict the event you catch - for example only matching certain parameters. You can read more about this in the function reference.&lt;br /&gt;
&lt;br /&gt;
Now, let's say we want to figure out when a player has died...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Message Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this message informs everyone of a death, so we use&lt;br /&gt;
    // flag &amp;quot;a&amp;quot; - global event&lt;br /&gt;
    register_event(&amp;quot;DeathMsg&amp;quot;, &amp;quot;hook_death&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_death()&lt;br /&gt;
{&lt;br /&gt;
    new Killer = read_data(1) //get the first message parameter&lt;br /&gt;
    new Victim = read_data(2) //get the second message parameter&lt;br /&gt;
    new headshot = read_data(3) //was this a headshot?&lt;br /&gt;
    new weapon[32]&lt;br /&gt;
    read_data(4, weapon, 31)  //get the weapon name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, let's say we want to make a simple function for generating a death message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock make_deathMsg(Killer, Victim, const weapon[])&lt;br /&gt;
{&lt;br /&gt;
    //message_begin starts a message.  NEVER start two messages at once.&lt;br /&gt;
    //MSG_ALL means send the message to everyone&lt;br /&gt;
    //get_user_msgid returns the id of a message name&lt;br /&gt;
    //{0,0,0} is the origin vector - not used here&lt;br /&gt;
    //0 is the target - no specific target here&lt;br /&gt;
    message_begin(MSG_ALL, get_user_msgid(&amp;quot;DeathMsg&amp;quot;), {0,0,0}, 0) &lt;br /&gt;
    write_byte(Killer)&lt;br /&gt;
    write_byte(Victim)&lt;br /&gt;
    write_string(weapon)&lt;br /&gt;
    message_end()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find more about messages, consult the HLSDK, AMX Mod X forums, HL-related programming sites, or other plugins. To list the messages a mod has, type &amp;quot;meta game&amp;quot; in the server console (with metamod loaded). You can also use register_message, the more advanced message disection method found in the Engine module.&lt;br /&gt;
&lt;br /&gt;
=Catching Log Messages=&lt;br /&gt;
&lt;br /&gt;
Catching log messages is not used heavily any more, but it's still good to know how to do it. As log messages are sent by the mod, AMX Mod X will be able to catch them and let you hook them. For our example, let's give everyone $16,000 on round start.&lt;br /&gt;
&lt;br /&gt;
The log messages for rounds are sent like this: World triggered &amp;quot;Round_Start&amp;quot;. AMX Mod X will consider &amp;quot;World_triggered&amp;quot; as the first parameter and &amp;quot;Round_Start&amp;quot; as the second parameter. So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Log Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this will filter for two parameters&lt;br /&gt;
    //roundstart is the public function&lt;br /&gt;
    register_logevent(&amp;quot;roundstart&amp;quot;, 2, &amp;quot;0=World triggered&amp;quot;, &amp;quot;1=Round_Start&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundstart()&lt;br /&gt;
{&lt;br /&gt;
    //set a small delay to make sure everyone spawns&lt;br /&gt;
    set_task(1.0, &amp;quot;roundDelay&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundDelay(taskId)&lt;br /&gt;
{&lt;br /&gt;
    new players[32], num&lt;br /&gt;
    get_players(players, num)&lt;br /&gt;
    new i&lt;br /&gt;
    for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
         cs_set_user_money(players[i], 16000)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also read specific log parameters with read_logdata(), which can only be used inside the &amp;quot;plugin_log()&amp;quot; forward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//receives all log messages&lt;br /&gt;
public plugin_log()&lt;br /&gt;
{&lt;br /&gt;
    new data[32]&lt;br /&gt;
    read_logdata(data, 31)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Multi-Lingual Support=&lt;br /&gt;
&lt;br /&gt;
Adding multi-lingual support to a plugin can be difficult, but it's usually worth it if you have clients who are willing to translate your strings into their native language.&lt;br /&gt;
&lt;br /&gt;
The first step is to identify what needs to be translated. Say you have a call like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new score = get_score()&lt;br /&gt;
client_print(id, print_chat, &amp;quot;[AMXX] Your score is %d&amp;quot;, score)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a good candidate for being multi-lingual. First, create a .txt file (preferrably named after your plugin) and store it in addons\amxmodx\data\lang\. Let's use &amp;quot;myplugin.txt&amp;quot; for the example. For each language, add an entry to the file. Entries are set up as 'keys', which are matched to 'translation strings'. Observe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(addons\amxmodx\data\lang\myplugin.txt)&lt;br /&gt;
&lt;br /&gt;
[en]&lt;br /&gt;
SCORE_MSG = Your score is %d&lt;br /&gt;
&lt;br /&gt;
[de]&lt;br /&gt;
SCORE_MSG = Ihr Spielergebnis ist %d&lt;br /&gt;
&lt;br /&gt;
[es]&lt;br /&gt;
SCORE_MSG = Su cuenta es %d&lt;br /&gt;
&lt;br /&gt;
[fr]&lt;br /&gt;
SCORE_MSG = Votre score est %d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, in plugin_init(), you must register the language keys:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    //assumes placed in amxmodx\data\lang&lt;br /&gt;
    register_dictionary(&amp;quot;myplugin.txt&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, here comes the hard part. AMX Mod X's Multi-Lingual API is built into the format() style routines. For anything that looks like or uses format()-style strings, you can use the ML API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(id, print_chat, &amp;quot;[AMXX] %L&amp;quot;, id, &amp;quot;SCORE_MSG&amp;quot;, get_score())&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's break this down. For each %L that appears, we need at least two parameters. The first parameter is the TARGET. This must be a player id, LANG_SERVER (meaning show in the server's native language), or LANG_PLAYER. LANG_PLAYER is a special modifier that should only be used when sending a message to all players - it means &amp;quot;show in every player's native language&amp;quot;. The second parameter is the key string that identifies the language phrase to translate. Lastly, if the translated string requires any parameters itself (ours needs %d, one integer), that must be added as well.&lt;br /&gt;
&lt;br /&gt;
You can get very complicated designs with this, but it's recommended that you keep things simple for clarity. Here is a final example using a global message to all players, assuming the key HELLO is properly translated in all the languages available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(0, print_chat, &amp;quot;[AMXX] %L&amp;quot;, LANG_PLAYER, &amp;quot;HELLO&amp;quot;)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=SQL Support=&lt;br /&gt;
&lt;br /&gt;
SQL support has greatly improved in AMX Mod X. There is a common set of natives that work with a single driver, so as long as one (and only one) SQL module is loaded, the SQL (or DBI) natives will work. Here is a short primer on how to use the DBI natives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Create a connection&lt;br /&gt;
	new Sql:mysql = dbi_connect(&amp;quot;localhost&amp;quot;, &amp;quot;dvander&amp;quot;, &amp;quot;pass&amp;quot;, &amp;quot;dbase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the connection is less than 1, it is bad	&lt;br /&gt;
	if (mysql &amp;lt; SQL_OK) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error1: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Connection handle: %d&amp;quot;, mysql)&lt;br /&gt;
//Run a query&lt;br /&gt;
	new Result:ret = dbi_query(mysql, &amp;quot;INSERT INTO config (keyname, val) VALUES ('amx', 'yes')&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than RESULT_NONE, it failed	&lt;br /&gt;
	if (ret &amp;lt; RESULT_NONE) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error2: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Do a select query	&lt;br /&gt;
	new Result:res = dbi_query(mysql, &amp;quot;SELECT * FROM config&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than or equal to RESULT_FAILED, you got an invalid result and can't do anything with it.&lt;br /&gt;
	if (res &amp;lt;= RESULT_FAILED) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error3: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Result handle: %d&amp;quot;, res)&lt;br /&gt;
&lt;br /&gt;
//Loop through the result set	&lt;br /&gt;
	while (res &amp;amp;&amp;amp; dbi_nextrow(res)&amp;gt;0) {&lt;br /&gt;
		new qry[32]&lt;br /&gt;
//Get the column/field called &amp;quot;keyname&amp;quot; from the result set&lt;br /&gt;
		dbi_result(res, &amp;quot;keyname&amp;quot;, qry, 32)&lt;br /&gt;
		server_print(&amp;quot;result: %s&amp;quot;, qry)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Free the result set	&lt;br /&gt;
	dbi_free_result(res)&lt;br /&gt;
&lt;br /&gt;
//Close the connection	&lt;br /&gt;
	dbi_close(mysql)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Regular Expressions=&lt;br /&gt;
&lt;br /&gt;
Regular Expressions let you describe ways in which to break down strings. They are extremely powerful. AMX Mod X uses the Perl Compatible RE library, you can read the specifics at their site. AMX Mod X offers regular expressions with the regex_amxx module. Here is a short example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Regex&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    register_srvcmd(&amp;quot;amx_regex&amp;quot;, &amp;quot;cmdtest&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmdtest()&lt;br /&gt;
{&lt;br /&gt;
    new str[] = &amp;quot;It's Walky!&amp;quot;&lt;br /&gt;
    //this pattern will match any string which contains&lt;br /&gt;
    // two groupings of characters separated by a space&lt;br /&gt;
    // the two groupings are substrings 1 and 2&lt;br /&gt;
    new pattern[] = &amp;quot;(.+) (.+)&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    new num, error[128]&lt;br /&gt;
    //str = string&lt;br /&gt;
    //pattern = pattern to use&lt;br /&gt;
    //num = special return case code&lt;br /&gt;
    //error = if there's an error, it will go here&lt;br /&gt;
    //127 - error's max length&lt;br /&gt;
    new Regex:re = regex_match(str, pattern, num, error, 127)&lt;br /&gt;
&lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)    &lt;br /&gt;
&lt;br /&gt;
    //REGEX_OK means there was a match&lt;br /&gt;
    if (re &amp;gt;= REGEX_OK)&lt;br /&gt;
    {&lt;br /&gt;
        new str2[64]&lt;br /&gt;
        new i&lt;br /&gt;
        //since it returned REGEX_OK, num has&lt;br /&gt;
        // the number of substrings matched by the pattern.&lt;br /&gt;
        //the first substring (0) seems to match the whole string.&lt;br /&gt;
        for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
        {&lt;br /&gt;
            regex_substr(re, i, str2, 63)&lt;br /&gt;
            server_print(&amp;quot;Substring %d: %s&amp;quot;, i, str2)&lt;br /&gt;
        }&lt;br /&gt;
        //the regular expression matcher uses memory.&lt;br /&gt;
        //you must free it if you get REGEX_OK&lt;br /&gt;
        //This will also set re to 0.&lt;br /&gt;
        regex_free(re)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //note the invalid regular expression pattern&lt;br /&gt;
    //this will return REGEX_PATTERN_FAIL, -1&lt;br /&gt;
    re = regex_match(&amp;quot;Bruno the Bandit&amp;quot;, &amp;quot;.+(]&amp;quot;, num, error, 127)&lt;br /&gt;
    &lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you compile and run this script (amx_regex in server console) you will see the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Result=1, num=3, error=&lt;br /&gt;
Substring 0: It's Walky!&lt;br /&gt;
Substring 1: It's&lt;br /&gt;
Substring 2: Walky!&lt;br /&gt;
Result=-1, num=4, error=missing ) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the third parameter to &amp;quot;regex_match()&amp;quot; is special. It's either the number of substrings, a match error code, or a pattern error position (depending on the return value).&lt;br /&gt;
&lt;br /&gt;
=Entities=&lt;br /&gt;
&lt;br /&gt;
Entities are basically any dynamic structure in Half-Life. Players, weapons, grenades, and other little objects laying around are entities. They have a unique &amp;quot;entity id&amp;quot; which you can use to change their values.&lt;br /&gt;
&lt;br /&gt;
I won't go into this too deeply as it's a complicated subject, but the Engine module features natives that let you modify the properties of entities, or search for entities in game by their class/owner (class is the type of entity, such as &amp;quot;player&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
For this example, we'll make an entity that looks like a fake player holding a gun.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	//create a basic entity&lt;br /&gt;
	new entid = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	//set its classname&lt;br /&gt;
	entity_set_string(entid, EV_SZ_classname, &amp;quot;some_guy&amp;quot;)&lt;br /&gt;
	//set its model&lt;br /&gt;
	entity_set_model(entid, &amp;quot;models/w_suit.mdl&amp;quot;)&lt;br /&gt;
	new Float:Vec[3] = {0.0,0.0,0.0}&lt;br /&gt;
	//set its origin &lt;br /&gt;
	entity_set_origin(entid, Vec)&lt;br /&gt;
	//set some basic properties&lt;br /&gt;
	entity_set_int(entid, EV_INT_solid, 1)&lt;br /&gt;
	entity_set_int(entid, EV_INT_movetype, 6)&lt;br /&gt;
	//create the weapon - thanks to pimp_daddy!&lt;br /&gt;
	entWeapon = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	entity_set_string(entWeapon, EV_SZ_classname, weapString)&lt;br /&gt;
	//set to follow&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_movetype, MOVETYPE_FOLLOW)&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_solid, SOLID_NOT)&lt;br /&gt;
	entity_set_edict(entWeapon, EV_ENT_aiment, entid)&lt;br /&gt;
	entity_set_model(entWeapon, &amp;quot;models/p_m4a1.mdl&amp;quot;) &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change other basic things, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//how set_user_armor() works in the fun module&lt;br /&gt;
stock set_armor(player, Float:value)&lt;br /&gt;
{&lt;br /&gt;
    entity_set_int(player, EV_FL_armorvalue, value)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=FakeMeta=&lt;br /&gt;
&lt;br /&gt;
FakeMeta is the next generation of Half-Life scripting. It essentially lets you write MetaMod plugins in Pawn. It is extremely powerful, and for this reason, it won't really be covered here. This is just to tell you what it is capable of.&lt;br /&gt;
&lt;br /&gt;
* Engine/DLL Calls&lt;br /&gt;
**There are two types of functions in the HL namespace - Engine functions and DLL functions (DLL functions are ones the game/mod library must export). Both of these can be called using the FakeMeta module using the dllfunc() and engfunc() natives. The parameters are directly passed on to MetaMod, so be careful! You could easily crash a server doing the wrong thing.&lt;br /&gt;
* Engine/DLL Hooks&lt;br /&gt;
**As stated above, HL provides Engine and DLL functions. You can also hook/supercede these calls using register_forward. You can supercede these calls using fm_return() and return PLUGIN_HANDLED. Again, make sure you know what you are doing. Malformed hooks will cause crashes.&lt;br /&gt;
* Easy entity manipulation&lt;br /&gt;
**FakeMeta replaces Engine's entity__() function with a natives called &amp;quot;pev()&amp;quot; and &amp;quot;set_pev()&amp;quot;. They are a bit easier to use. For more information see the fakemeta includes.&lt;br /&gt;
* Private Offset Hacking&lt;br /&gt;
**Private offsets are offsets into a block of memory called &amp;quot;pvPrivateData&amp;quot;. The right offsets can often modify game-specific features, such as money in Counter-Strike, or resources in Natural-Selection. However, the wrong offsets can cause game crashes.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10275</id>
		<title>Advanced Scripting (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10275"/>
		<updated>2017-02-26T12:59:45Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will briefly summarize some of the more advanced topics of [[:Category:Scripting (AMX Mod X)|AMX Mod X Scripting]].&lt;br /&gt;
&lt;br /&gt;
=Tasks=&lt;br /&gt;
&lt;br /&gt;
Tasks are timers that let you run code at an interval, either once or repeated. They are useful for things like waiting a few seconds, setting objects to destroy themselves, or just repeating a task over and over.&lt;br /&gt;
&lt;br /&gt;
A task can be set in a number of different ways. The actual function is set_task():&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_task(Float:time,const function[],id = 0,parameter[]=&amp;quot;&amp;quot;,len = 0,flags[]=&amp;quot;&amp;quot;, repeat = 0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameters break down as such:&lt;br /&gt;
&lt;br /&gt;
* Float:time - Interval of timer in seconds (minimum 0.1 seconds)&lt;br /&gt;
* function[] - A string that contains the public function to run on the timer&lt;br /&gt;
* id - A unique id to assign to the task&lt;br /&gt;
* parameter - An array contain data to send to the timer function&lt;br /&gt;
* len - Size of the array to send to the timer function&lt;br /&gt;
* flags - One of the following:&lt;br /&gt;
** &amp;quot;a&amp;quot; - Repeat task a specified number of times&lt;br /&gt;
** &amp;quot;b&amp;quot; - Loop task infinitely&lt;br /&gt;
** &amp;quot;c&amp;quot; - do task on time after a map timeleft&lt;br /&gt;
** &amp;quot;d&amp;quot; - do task on time before a map timeleft&lt;br /&gt;
* repeat - If flags is &amp;quot;a&amp;quot;, specifies the number of times to repeat the task&lt;br /&gt;
&lt;br /&gt;
An example of a task is below. It will slap a specified player 5 times, once per second.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//the timed function receives the parameter array and its task id&lt;br /&gt;
public slapTask(params[], id)&lt;br /&gt;
{&lt;br /&gt;
   new player = params[0]&lt;br /&gt;
   user_slap(player, 5)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public start_slapping(id)&lt;br /&gt;
{&lt;br /&gt;
   new params[1]&lt;br /&gt;
   params[0] = id&lt;br /&gt;
   //we don't need a specific id&lt;br /&gt;
   set_task(1.0, &amp;quot;slapTask&amp;quot;, 0, params, 1, &amp;quot;a&amp;quot;, 5)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that if you specify 0 for parameter length, then the task function should look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public slapTask()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Menus=&lt;br /&gt;
&lt;br /&gt;
Menus are HUD messages that give a player a choice of options to select. They are quite messy to deal with but can be very useful for things like voting and command selection.&lt;br /&gt;
&lt;br /&gt;
Menus must be registered by two things - a set of &amp;quot;keys&amp;quot; that tells how many options to register and a string which identifies the menu as unique. This string must appear in the beginning of every menu you want to trigger your function. When you display a menu, you can show it to one or more players. Once they hit a key, the result of their key press will be sent to the function you registered the menu to.&lt;br /&gt;
&lt;br /&gt;
For our example, we'll make a menu that displays a list of guns: AK47, M4A1, or AWP, to a player. Whichever he selects, he will be given.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two commands are apparent here - register_menuid and register_menucmd. register_menuid registers a short phrase that will appear at the beginning of the menu, then returns an id. This id is the first parameter to register_menucmd. The second parameter to register_menucmd is the key configuration. Our menu will have three options, so we've added three menu keys in. In actuality, these are bitwise flags totalling &amp;quot;7&amp;quot;, but that's not important. The last parameter is the public function that will handle the menu results.&lt;br /&gt;
&lt;br /&gt;
Next, how do we show the menu? Let's make a quick console command: &amp;quot;giveme&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    register_clcmd(&amp;quot;giveme&amp;quot;, &amp;quot;showWeaponMenu&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
register_clcmd is similar to register_concmd, except it only takes two parameters. It's used to register any command a client can use (except for special ones, like +attack).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//The clcmd function will just give us the player id&lt;br /&gt;
public showWeaponMenu(id)&lt;br /&gt;
{&lt;br /&gt;
    new menu[192]&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
&lt;br /&gt;
    format(menu, 191, &amp;quot;Which Weapon?^n^n1. AK47^n2. M4A1^n3. AWP&amp;quot;)&lt;br /&gt;
    show_menu(id, keys, menu)&lt;br /&gt;
    return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Our menu function will get the player id and the key they pressed&lt;br /&gt;
public giveWeapon(id, key)&lt;br /&gt;
{&lt;br /&gt;
    //key will start at zero&lt;br /&gt;
    if (key == 0)&lt;br /&gt;
    {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_ak47&amp;quot;)&lt;br /&gt;
    } else if (key == 1) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_m4a1&amp;quot;)&lt;br /&gt;
    } else if (key == 2) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_awp&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we're done! The format line may be a little confusing. The &amp;quot;^n&amp;quot; means &amp;quot;new line&amp;quot;, so the menu looks nicely formatted. You can use other modifiers in VGUI2 mods, such as &amp;quot;\w&amp;quot; for white text, &amp;quot;\r&amp;quot; for red text, and &amp;quot;\y&amp;quot; for yellow text. When a player types the command, he will see the menu. When he hits a key, the giveWeapon function will receive his id and the key number he pressed. Then he will get a gun corresponding to what he chose.&lt;br /&gt;
&lt;br /&gt;
=Events/Messages=&lt;br /&gt;
&lt;br /&gt;
For this demonstration, we're going to extend the above example. Every time a player respawns, he will be shown the menu to choose a weapon (note - we're ignoring other things like blocking buying and removing buyzones, this is just a demonstration).&lt;br /&gt;
&lt;br /&gt;
Messages are a way for Half-Life clients to talk to servers, and vice versa. They are specially formatted lists of parameters. For example, the message &amp;quot;DeathMsg&amp;quot; (message id 83) has three parameters: Attacker (byte), Victim (byte), and Weapon (string). You can either capture messages or send them. Here, we'll do a simple demonstration of both. First let's make it so a user gets their gun menu when they spawn.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    //flags - b means &amp;quot;sent to one target&amp;quot;, e means &amp;quot;target is alive&amp;quot;&lt;br /&gt;
    //this event is sent when a player spawns&lt;br /&gt;
    register_event(&amp;quot;ResetHUD&amp;quot;, &amp;quot;hook_hud&amp;quot;, &amp;quot;be&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_hud(id)&lt;br /&gt;
{&lt;br /&gt;
    //since we specify no parameters to the task,&lt;br /&gt;
    //the task id will be given to the function&lt;br /&gt;
    //this is useful because we can reuse our old&lt;br /&gt;
    //show menu function which takes an id&lt;br /&gt;
    set_task(0.2, &amp;quot;showWeaponMenu&amp;quot;, id)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we've set a small delay when we receive the message - this is to make sure that the user has had time to respawn. register_event can take more parameters in order to help restrict the event you catch - for example only matching certain parameters. You can read more about this in the function reference.&lt;br /&gt;
&lt;br /&gt;
Now, let's say we want to figure out when a player has died...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Message Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this message informs everyone of a death, so we use&lt;br /&gt;
    // flag &amp;quot;a&amp;quot; - global event&lt;br /&gt;
    register_event(&amp;quot;DeathMsg&amp;quot;, &amp;quot;hook_death&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_death()&lt;br /&gt;
{&lt;br /&gt;
    new Killer = read_data(1) //get the first message parameter&lt;br /&gt;
    new Victim = read_data(2) //get the second message parameter&lt;br /&gt;
    new headshot = read_data(3) //was this a headshot?&lt;br /&gt;
    new weapon[32]&lt;br /&gt;
    read_data(4, weapon, 31)  //get the weapon name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, let's say we want to make a simple function for generating a death message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock make_deathMsg(Killer, Victim, const weapon[])&lt;br /&gt;
{&lt;br /&gt;
    //message_begin starts a message.  NEVER start two messages at once.&lt;br /&gt;
    //MSG_ALL means send the message to everyone&lt;br /&gt;
    //get_user_msgid returns the id of a message name&lt;br /&gt;
    //{0,0,0} is the origin vector - not used here&lt;br /&gt;
    //0 is the target - no specific target here&lt;br /&gt;
    message_begin(MSG_ALL, get_user_msgid(&amp;quot;DeathMsg&amp;quot;), {0,0,0}, 0) &lt;br /&gt;
    write_byte(Killer)&lt;br /&gt;
    write_byte(Victim)&lt;br /&gt;
    write_string(weapon)&lt;br /&gt;
    message_end()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find more about messages, consult the HLSDK, AMX Mod X forums, HL-related programming sites, or other plugins. To list the messages a mod has, type &amp;quot;meta game&amp;quot; in the server console (with metamod loaded). You can also use register_message, the more advanced message disection method found in the Engine module.&lt;br /&gt;
&lt;br /&gt;
=Catching Log Messages=&lt;br /&gt;
&lt;br /&gt;
Catching log messages is not used heavily any more, but it's still good to know how to do it. As log messages are sent by the mod, AMX Mod X will be able to catch them and let you hook them. For our example, let's give everyone $16,000 on round start.&lt;br /&gt;
&lt;br /&gt;
The log messages for rounds are sent like this: World triggered &amp;quot;Round_Start&amp;quot;. AMX Mod X will consider &amp;quot;World_triggered&amp;quot; as the first parameter and &amp;quot;Round_Start&amp;quot; as the second parameter. So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Log Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this will filter for two parameters&lt;br /&gt;
    //roundstart is the public function&lt;br /&gt;
    register_logevent(&amp;quot;roundstart&amp;quot;, 2, &amp;quot;0=World triggered&amp;quot;, &amp;quot;1=Round_Start&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundstart()&lt;br /&gt;
{&lt;br /&gt;
    //set a small delay to make sure everyone spawns&lt;br /&gt;
    set_task(1.0, &amp;quot;roundDelay&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundDelay(taskId)&lt;br /&gt;
{&lt;br /&gt;
    new players[32], num&lt;br /&gt;
    get_players(players, num)&lt;br /&gt;
    new i&lt;br /&gt;
    for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
         cs_set_user_money(players[i], 16000)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also read specific log parameters with read_logdata(), which can only be used inside the &amp;quot;plugin_log()&amp;quot; forward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//receives all log messages&lt;br /&gt;
public plugin_log()&lt;br /&gt;
{&lt;br /&gt;
    new data[32]&lt;br /&gt;
    read_logdata(data, 31)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Multi-Lingual Support=&lt;br /&gt;
&lt;br /&gt;
Adding multi-lingual support to a plugin can be difficult, but it's usually worth it if you have clients who are willing to translate your strings into their native language.&lt;br /&gt;
&lt;br /&gt;
The first step is to identify what needs to be translated. Say you have a call like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new score = get_score()&lt;br /&gt;
client_print(id, print_chat, &amp;quot;[AMXX] Your score is %d&amp;quot;, score)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a good candidate for being multi-lingual. First, create a .txt file (preferrably named after your plugin) and store it in addons\amxmodx\data\lang\. Let's use &amp;quot;myplugin.txt&amp;quot; for the example. For each language, add an entry to the file. Entries are set up as 'keys', which are matched to 'translation strings'. Observe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(addons\amxmodx\data\lang\myplugin.txt)&lt;br /&gt;
&lt;br /&gt;
[en]&lt;br /&gt;
SCORE_MSG = Your score is %d&lt;br /&gt;
&lt;br /&gt;
[de]&lt;br /&gt;
SCORE_MSG = Ihr Spielergebnis ist %d&lt;br /&gt;
&lt;br /&gt;
[es]&lt;br /&gt;
SCORE_MSG = Su cuenta es %d&lt;br /&gt;
&lt;br /&gt;
[fr]&lt;br /&gt;
SCORE_MSG = Votre score est %d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, in plugin_init(), you must register the language keys:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    //assumes placed in amxmodx\data\lang&lt;br /&gt;
    register_dictionary(&amp;quot;myplugin.txt&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, here comes the hard part. AMX Mod X's Multi-Lingual API is built into the format() style routines. For anything that looks like or uses format()-style strings, you can use the ML API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(id, print_chat, &amp;quot;[AMXX] %L&amp;quot;, id, &amp;quot;SCORE_MSG&amp;quot;, get_score())&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's break this down. For each %L that appears, we need at least two parameters. The first parameter is the TARGET. This must be a player id, LANG_SERVER (meaning show in the server's native language), or LANG_PLAYER. LANG_PLAYER is a special modifier that should only be used when sending a message to all players - it means &amp;quot;show in every player's native language&amp;quot;. The second parameter is the key string that identifies the language phrase to translate. Lastly, if the translated string requires any parameters itself (ours needs %d, one integer), that must be added as well.&lt;br /&gt;
&lt;br /&gt;
You can get very complicated designs with this, but it's recommended that you keep things simple for clarity. Here is a final example using a global message to all players, assuming the key HELLO is properly translated in all the languages available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(0, print_chat, &amp;quot;[AMXX] %L&amp;quot;, LANG_PLAYER, &amp;quot;HELLO&amp;quot;)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=SQL Support=&lt;br /&gt;
&lt;br /&gt;
SQL support has greatly improved in AMX Mod X. There is a common set of natives that work with a single driver, so as long as one (and only one) SQL module is loaded, the SQL (or DBI) natives will work. Here is a short primer on how to use the DBI natives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Create a connection&lt;br /&gt;
	new Sql:mysql = dbi_connect(&amp;quot;localhost&amp;quot;, &amp;quot;dvander&amp;quot;, &amp;quot;pass&amp;quot;, &amp;quot;dbase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the connection is less than 1, it is bad	&lt;br /&gt;
	if (mysql &amp;lt; SQL_OK) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error1: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Connection handle: %d&amp;quot;, mysql)&lt;br /&gt;
//Run a query&lt;br /&gt;
	new Result:ret = dbi_query(mysql, &amp;quot;INSERT INTO config (keyname, val) VALUES ('amx', 'yes')&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than RESULT_NONE, it failed	&lt;br /&gt;
	if (ret &amp;lt; RESULT_NONE) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error2: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Do a select query	&lt;br /&gt;
	new Result:res = dbi_query(mysql, &amp;quot;SELECT * FROM config&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than or equal to RESULT_FAILED, you got an invalid result and can't do anything with it.&lt;br /&gt;
	if (res &amp;lt;= RESULT_FAILED) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error3: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Result handle: %d&amp;quot;, res)&lt;br /&gt;
&lt;br /&gt;
//Loop through the result set	&lt;br /&gt;
	while (res &amp;amp;&amp;amp; dbi_nextrow(res)&amp;gt;0) {&lt;br /&gt;
		new qry[32]&lt;br /&gt;
//Get the column/field called &amp;quot;keyname&amp;quot; from the result set&lt;br /&gt;
		dbi_result(res, &amp;quot;keyname&amp;quot;, qry, 32)&lt;br /&gt;
		server_print(&amp;quot;result: %s&amp;quot;, qry)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Free the result set	&lt;br /&gt;
	dbi_free_result(res)&lt;br /&gt;
&lt;br /&gt;
//Close the connection	&lt;br /&gt;
	dbi_close(mysql)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Regular Expressions=&lt;br /&gt;
&lt;br /&gt;
Regular Expressions let you describe ways in which to break down strings. They are extremely powerful. AMX Mod X uses the Perl Compatible RE library, you can read the specifics at their site. AMX Mod X offers regular expressions with the regex_amxx module. Here is a short example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Regex&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    register_srvcmd(&amp;quot;amx_regex&amp;quot;, &amp;quot;cmdtest&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmdtest()&lt;br /&gt;
{&lt;br /&gt;
    new str[] = &amp;quot;It's Walky!&amp;quot;&lt;br /&gt;
    //this pattern will match any string which contains&lt;br /&gt;
    // two groupings of characters separated by a space&lt;br /&gt;
    // the two groupings are substrings 1 and 2&lt;br /&gt;
    new pattern[] = &amp;quot;(.+) (.+)&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    new num, error[128]&lt;br /&gt;
    //str = string&lt;br /&gt;
    //pattern = pattern to use&lt;br /&gt;
    //num = special return case code&lt;br /&gt;
    //error = if there's an error, it will go here&lt;br /&gt;
    //127 - error's max length&lt;br /&gt;
    new Regex:re = regex_match(str, pattern, num, error, 127)&lt;br /&gt;
&lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)    &lt;br /&gt;
&lt;br /&gt;
    //REGEX_OK means there was a match&lt;br /&gt;
    if (re &amp;gt;= REGEX_OK)&lt;br /&gt;
    {&lt;br /&gt;
        new str2[64]&lt;br /&gt;
        new i&lt;br /&gt;
        //since it returned REGEX_OK, num has&lt;br /&gt;
        // the number of substrings matched by the pattern.&lt;br /&gt;
        //the first substring (0) seems to match the whole string.&lt;br /&gt;
        for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
        {&lt;br /&gt;
            regex_substr(re, i, str2, 63)&lt;br /&gt;
            server_print(&amp;quot;Substring %d: %s&amp;quot;, i, str2)&lt;br /&gt;
        }&lt;br /&gt;
        //the regular expression matcher uses memory.&lt;br /&gt;
        //you must free it if you get REGEX_OK&lt;br /&gt;
        //This will also set re to 0.&lt;br /&gt;
        regex_free(re)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //note the invalid regular expression pattern&lt;br /&gt;
    //this will return REGEX_PATTERN_FAIL, -1&lt;br /&gt;
    re = regex_match(&amp;quot;Bruno the Bandit&amp;quot;, &amp;quot;.+(]&amp;quot;, num, error, 127)&lt;br /&gt;
    &lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you compile and run this script (amx_regex in server console) you will see the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Result=1, num=3, error=&lt;br /&gt;
Substring 0: It's Walky!&lt;br /&gt;
Substring 1: It's&lt;br /&gt;
Substring 2: Walky!&lt;br /&gt;
Result=-1, num=4, error=missing ) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the third parameter to &amp;quot;regex_match()&amp;quot; is special. It's either the number of substrings, a match error code, or a pattern error position (depending on the return value).&lt;br /&gt;
&lt;br /&gt;
=Entities=&lt;br /&gt;
&lt;br /&gt;
Entities are basically any dynamic structure in Half-Life. Players, weapons, grenades, and other little objects laying around are entities. They have a unique &amp;quot;entity id&amp;quot; which you can use to change their values.&lt;br /&gt;
&lt;br /&gt;
I won't go into this too deeply as it's a complicated subject, but the Engine module features natives that let you modify the properties of entities, or search for entities in game by their class/owner (class is the type of entity, such as &amp;quot;player&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
For this example, we'll make an entity that looks like a fake player holding a gun.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	//create a basic entity&lt;br /&gt;
	new entid = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	//set its classname&lt;br /&gt;
	entity_set_string(entid, EV_SZ_classname, &amp;quot;some_guy&amp;quot;)&lt;br /&gt;
	//set its model&lt;br /&gt;
	entity_set_model(entid, &amp;quot;models/w_suit.mdl&amp;quot;)&lt;br /&gt;
	new Float:Vec[3] = {0.0,0.0,0.0}&lt;br /&gt;
	//set its origin &lt;br /&gt;
	entity_set_origin(entid, Vec)&lt;br /&gt;
	//set some basic properties&lt;br /&gt;
	entity_set_int(entid, EV_INT_solid, 1)&lt;br /&gt;
	entity_set_int(entid, EV_INT_movetype, 6)&lt;br /&gt;
	//create the weapon - thanks to pimp_daddy!&lt;br /&gt;
	entWeapon = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	entity_set_string(entWeapon, EV_SZ_classname, weapString)&lt;br /&gt;
	//set to follow&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_movetype, MOVETYPE_FOLLOW)&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_solid, SOLID_NOT)&lt;br /&gt;
	entity_set_edict(entWeapon, EV_ENT_aiment, entid)&lt;br /&gt;
	entity_set_model(entWeapon, &amp;quot;models/p_m4a1.mdl&amp;quot;) &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change other basic things, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//how set_user_armor() works in the fun module&lt;br /&gt;
stock set_armor(player, Float:value)&lt;br /&gt;
{&lt;br /&gt;
    entity_set_int(player, EV_FL_armorvalue, value)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=FakeMeta=&lt;br /&gt;
&lt;br /&gt;
FakeMeta is the next generation of Half-Life scripting. It essentially lets you write MetaMod plugins in Pawn. It is extremely powerful, and for this reason, it won't really be covered here. This is just to tell you what it is capable of.&lt;br /&gt;
&lt;br /&gt;
* Engine/DLL Calls&lt;br /&gt;
**There are two types of functions in the HL namespace - Engine functions and DLL functions (DLL functions are ones the game/mod library must export). Both of these can be called using the FakeMeta module using the dllfunc() and engfunc() natives. The parameters are directly passed on to MetaMod, so be careful! You could easily crash a server doing the wrong thing.&lt;br /&gt;
* Engine/DLL Hooks&lt;br /&gt;
**As stated above, HL provides Engine and DLL functions. You can also hook/supercede these calls using register_forward. You can supercede these calls using fm_return() and return PLUGIN_HANDLED. Again, make sure you know what you are doing. Malformed hooks will cause crashes.&lt;br /&gt;
* Easy entity manipulation&lt;br /&gt;
**FakeMeta replaces Engine's entity__() function with a natives called &amp;quot;pev()&amp;quot; and &amp;quot;set_pev()&amp;quot;. They are a bit easier to use. For more information see the fakemeta includes.&lt;br /&gt;
* Private Offset Hacking&lt;br /&gt;
**Private offsets are offsets into a block of memory called &amp;quot;pvPrivateData&amp;quot;. The right offsets can often modify game-specific features, such as money in Counter-Strike, or resources in Natural-Selection. However, the wrong offsets can cause game crashes.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Adding_Admins_(AMX_Mod_X)&amp;diff=10274</id>
		<title>Adding Admins (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Adding_Admins_(AMX_Mod_X)&amp;diff=10274"/>
		<updated>2017-02-26T12:57:21Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Admins (non-SQL)=&lt;br /&gt;
==Adding an Admin==&lt;br /&gt;
First, open the amxmodx/configs/users.ini file with your favorite text editor.  Scroll to the bottom.  Admin entries are stored with four options: Authentication, Password, Access Right, Connection Properties.&lt;br /&gt;
&lt;br /&gt;
In the early days of [[Half-Life 1]] it was common to have admins authenticate by name.  However, now it is recommended to auth by steamid.  An example of a typical admin entry is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;STEAM_0:0:123456&amp;quot; &amp;quot;&amp;quot; &amp;quot;abcdefghijklmnopqrstu&amp;quot; &amp;quot;ce&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Entries are one-per-line, and each of the four options are space separated, contained in double-quotes.  This one means:&lt;br /&gt;
#The user has [[SteamID]] STEAM_0:0:123456&lt;br /&gt;
#The user has no password (steamid-authentication)&lt;br /&gt;
#Access rights are levels &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; through &amp;lt;tt&amp;gt;u&amp;lt;/tt&amp;gt;&lt;br /&gt;
#The user is a steamid (&amp;quot;c&amp;quot;) and has no password (&amp;quot;e&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
It is also possible to authenticate by username:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;BAILOPAN&amp;quot; &amp;quot;mypass&amp;quot; &amp;quot;abcdefghijklmnopqrstu&amp;quot; &amp;quot;a&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To authenticate, BAILOPAN would put this in his client's autoexec.cfg, where &amp;quot;_pw&amp;quot; is the value of &amp;quot;amx_password_field&amp;quot; in [[amxx.cfg]].&lt;br /&gt;
&amp;lt;pre&amp;gt;setinfo &amp;quot;_pw&amp;quot; &amp;quot;mypass&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For information on what access levels mean, see [[#Access Levels|Access Levels]].&lt;br /&gt;
&lt;br /&gt;
{{qnotice|It is important that you do not use the 'z' flag for admins because that's the non-admin flag.}}&lt;br /&gt;
&lt;br /&gt;
==Removing an Admin==&lt;br /&gt;
Find the admin's entry in your amxmodx/configs/users.ini file, and put a semicolon in front of it.  For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;;&amp;quot;STEAM_0:0:123456&amp;quot; &amp;quot;&amp;quot; &amp;quot;abcdefghijklmnopqrstu&amp;quot; &amp;quot;ce&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will prevent the entry from being read.&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
=Admins (SQL)=&lt;br /&gt;
AMX Mod X lets you store admin accounts in a MySQL database.  This is ideal if you have multiple servers with common administrators.&lt;br /&gt;
&lt;br /&gt;
==Configuring Server==&lt;br /&gt;
First, make sure you have configured your server for SQL by reading [[Configuring AMX Mod X#SQL|Configuring AMX Mod X: SQL]].  Then, enable the admin_sql.amxx plugin instead of admin.amxx, by opening amxmodx/configs/plugins.ini.  You should change the first two entries to look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;;admin.amxx ; Disabled &lt;br /&gt;
admin_sql.amxx ; SQL admins&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maintaining Admins==&lt;br /&gt;
&lt;br /&gt;
Once the server loads for the first time, it will automatically create the table specified with &amp;lt;tt&amp;gt;amx_sql_table&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can either add an admin through an SQL tool like an SQL Console or phpMyAdmin, or you can add an admin [[Adding Admins (AMX Mod X)#Console Command|using amx_addadmin]].  &lt;br /&gt;
&lt;br /&gt;
If you choose to use SQL directly (or an interface), you must learn the table layout.  There are four columns, each corresponding to one of the four properties listed above in [[#Adding an Admin|Adding an Admin]].  For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;INSERT INTO admins VALUES(&amp;quot;STEAM_0:1:23456&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;abcdefghijklmnopqrstu&amp;quot;, &amp;quot;ce&amp;quot;);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|It is important that you do not use the 'z' flag for admins.}}&lt;br /&gt;
&lt;br /&gt;
For information on what access levels mean, see [[AMX Mod X Access Levels]].&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
=Console Command=&lt;br /&gt;
&lt;br /&gt;
You can also use the console command amx_addadmin for adding admins.  It will work for both [[SQL]] and users.ini, depending on which plugin you have enabled.  An example of using the command in-game:&lt;br /&gt;
&amp;lt;pre&amp;gt;amx_addadmin &amp;quot;BAILOPAN&amp;quot; &amp;quot;abcdefghijklmnopqrstu&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Using the command from the server/[[rcon]] console:&lt;br /&gt;
&amp;lt;pre&amp;gt;amx_addadmin &amp;quot;STEAM_0:1:23456&amp;quot; &amp;quot;abcdefghijklmnopqrstu&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Access Levels=&lt;br /&gt;
These access levels are the default access levels for the base [[AMX Mod X]] plugins.  3rd party plugins may have different usages for them, although in general users try to stick to the intentions for each flag.&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Access Flag&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| a&lt;br /&gt;
| immunity (can't be kicked/baned/slayed/slaped and affected by other commmands)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| b&lt;br /&gt;
| reservation (can join on reserved slots)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| c &lt;br /&gt;
| amx_kick command&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| d &lt;br /&gt;
| amx_ban and amx_unban commands&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| e &lt;br /&gt;
| amx_slay and amx_slap commands&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| f&lt;br /&gt;
| amx_map command&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| g&lt;br /&gt;
| amx_cvar command (not all cvars will be available)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| h&lt;br /&gt;
| amx_cfg command&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| i&lt;br /&gt;
| amx_chat and other chat commands&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| j&lt;br /&gt;
| amx_vote and other vote commands&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| k&lt;br /&gt;
| access to sv_password cvar (by amx_cvar command)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| l&lt;br /&gt;
| access to amx_rcon command and rcon_password cvar (by amx_cvar command)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| m&lt;br /&gt;
| custom level A (for additional plugins)&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| n&lt;br /&gt;
| custom level B&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| o&lt;br /&gt;
| custom level C&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| p&lt;br /&gt;
| custom level D&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| q&lt;br /&gt;
| custom level E&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| r&lt;br /&gt;
| custom level F&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| s&lt;br /&gt;
| custom level G&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| t&lt;br /&gt;
| custom level H&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| u&lt;br /&gt;
| menu access&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| z&lt;br /&gt;
| user (no admin)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Connection Flags=&lt;br /&gt;
These flags control how [[AMX Mod X]] attempts to authorize a connecting admin.&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Connection Flag&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| a &lt;br /&gt;
| disconnect player on invalid password&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| b&lt;br /&gt;
| clan tag&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| c&lt;br /&gt;
| this is steamid/wonid&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| d&lt;br /&gt;
| this is ip&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| e&lt;br /&gt;
| password not checked (only name/ip/steamid needed)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10273</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=10273"/>
		<updated>2017-02-25T23:14:52Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how [[Pawn]] works. You should be reading this portion of the document, sitting at a computer, with a text editor and [[Pawn]] compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is [[Pawn]] enabled, try AMXX-Studio from the [http://www.amxmodx.org/downloads.php AMX Mod X downloads]section.&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section for details. You should also be familiar with [[Configuring_AMX_Mod_X#Installing|installing]] plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three string variables&lt;br /&gt;
new PLUGIN[]=&amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
Note : If you don't call plugin_init in your plugin, nothing goes wrong, you simply can consider it as a custom forward.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;cstrike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Using_New_Menu_System&amp;diff=10272</id>
		<title>Using New Menu System</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Using_New_Menu_System&amp;diff=10272"/>
		<updated>2017-02-25T23:03:49Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
Write some intro here&lt;br /&gt;
&lt;br /&gt;
== Beginners Menu Tutorial ==&lt;br /&gt;
Now lets discuss how to use the new menu system. We will go through the basics in this tutorial and make a simple Change Level vote.&lt;br /&gt;
&lt;br /&gt;
=== Includes ===&lt;br /&gt;
As always we will start out by adding the required includes&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Global Variables ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new g_Menu;	// Main Menu handler&lt;br /&gt;
new g_Votes[3];	// Store Yes votes at 1, No at 2&lt;br /&gt;
new g_maxplayers; // Store maxplayers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In here we created 2 global var's. One to hold our menu handle, and the other to store our menu votes. The 'Yes' votes will be stored in g_Votes[1] and the 'No' votes will be stored in g_Votes[2].&lt;br /&gt;
&lt;br /&gt;
=== Registering Plugin and Menu ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
	// Register Our Plugin&lt;br /&gt;
	register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
        // Cache maxplayers so we don't have to loop 32 times&lt;br /&gt;
        g_maxplayers = get_maxplayers()&lt;br /&gt;
 &lt;br /&gt;
	// Register our Change Level vote menu&lt;br /&gt;
	g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Now we need to build our menu&lt;br /&gt;
	build_menu();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets break this down. &lt;br /&gt;
&lt;br /&gt;
*Registers our plugin&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*g_Menu - Our menu handle. It will be set after menu_create gets called.&lt;br /&gt;
&amp;lt;pawn&amp;gt;g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//menu_create ( title[], handler[], ml=0 )&lt;br /&gt;
//title[] - Menu title&lt;br /&gt;
//handler[] - This is a function which will get called once someone presses a key on your menu.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We made this client command so we can start our vote.&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* This is a function call. build_menu() function will construct our vote menu.&lt;br /&gt;
&amp;lt;pawn&amp;gt;build_menu();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constructing Menu ===&lt;br /&gt;
Constructing the menu is just adding needed items to your menu. Before we go ahead with adding items we must look at menu_additem native.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_additem ( menu, const name[], const command[], paccess=0, callback=-1 )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* menu - menu handle. This tells menu_additem the menu to which we are adding our item.&lt;br /&gt;
* const name[] - the item name. This is what gets displayed into the menu.&lt;br /&gt;
* const command[] - item info.&lt;br /&gt;
&lt;br /&gt;
Now lets get into constructing our menu. As said, this is a simple vote for a Change of Level. So we will only need 2 items. A &amp;quot;Yes&amp;quot; and a &amp;quot;No&amp;quot;.&lt;br /&gt;
&amp;lt;pawn&amp;gt;build_menu()&lt;br /&gt;
{&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;Yes&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;No&amp;quot;, &amp;quot;2&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	menu_setprop(g_Menu, MPROP_PERPAGE, 0);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Notes&amp;lt;/tt&amp;gt;&lt;br /&gt;
** As you can see i set the const command[] to numbers. This is for us to identify the item easier.&lt;br /&gt;
** I have also added menu_setprop. This sets our menu to have no pages. For additional properties look into newmenus.inc&lt;br /&gt;
&lt;br /&gt;
=== Displaying the Vote Menu ===&lt;br /&gt;
To display our menu we must simply use menu_display.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_display ( id, menu, page )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* id - id of the user your displaying menu to.&lt;br /&gt;
* menu - which menu are you showing the user.&lt;br /&gt;
* page - what page (of the menu) to start on. Page of the menu starts at 0.&lt;br /&gt;
&lt;br /&gt;
Ok lets proceed to our code.&lt;br /&gt;
&amp;lt;pawn&amp;gt;public startvote(id)&lt;br /&gt;
{&lt;br /&gt;
	for(new i = 1; i &amp;lt;= g_maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if( is_user_alive(i) )&lt;br /&gt;
		{&lt;br /&gt;
			menu_display(i, g_Menu, 0);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Notes:&amp;lt;/tt&amp;gt;&lt;br /&gt;
** The for loop is used to cycle through players and display the menu to players that are alive. We are looping from 1 to Max Players. Note that if you don't use the get_maxplayers() native and server slot is lower than the one you specified it will throw an error.&lt;br /&gt;
&lt;br /&gt;
=== Handling Menu Choices ===&lt;br /&gt;
Last step is actualy handling the menu choices. This happens through the menu handler function. It will get called once someone chooses an item off the menu. There are &amp;lt;b&amp;gt;3&amp;lt;/b&amp;gt; variables that are passed to the function.&lt;br /&gt;
* id - the users id&lt;br /&gt;
* menu - the menu user had open&lt;br /&gt;
* item - and the item user chose&lt;br /&gt;
&lt;br /&gt;
Now there are a few of special items like the Exit item.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MENU_EXIT	-3&lt;br /&gt;
#define	MENU_BACK	-2&lt;br /&gt;
#define MENU_MORE	-1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we must check at first if the item chosen was not one of the special ones. Note that the only special item that may cause your handler to be called is MENU_EXIT, because MENU_BACK and MENU_MORE items are entirely handled in AMXX core (you can't hook them).&lt;br /&gt;
&amp;lt;pawn&amp;gt;if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we must retrieve the item information. What we are looking for is the number we gave the item (Yes = 1, No = 2). And to do this we use menu_item_getinfo.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_item_getinfo ( menu, item, &amp;amp;access, command[], cmdlen, name[]=&amp;quot;&amp;quot;, namelen=0, &amp;amp;callback )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* menu - the menu where the item exists.&lt;br /&gt;
* item - the item itself&lt;br /&gt;
* &amp;amp;access - (edit)&lt;br /&gt;
* command[] - (edit)(this is where we stored our item identification numbers)&lt;br /&gt;
* cmdlen - length of the command[]&lt;br /&gt;
* name[] - items name&lt;br /&gt;
* namelen - length of the name&lt;br /&gt;
* &amp;amp;callback - (edit)&lt;br /&gt;
&lt;br /&gt;
After we get our items info we will convert the command[] to a number (will either be a 1 or 2) and update the g_Votes array with the appropriate vote chosen.&lt;br /&gt;
Here is our finished handle function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public menu_handle(id, menu, item)&lt;br /&gt;
{&lt;br /&gt;
	if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&lt;br /&gt;
	&lt;br /&gt;
	// Get item info&lt;br /&gt;
	new cmd[3];&lt;br /&gt;
	new access, callback;&lt;br /&gt;
	&lt;br /&gt;
	menu_item_getinfo(menu, item, access, cmd,2,_,_, callback);&lt;br /&gt;
	&lt;br /&gt;
	new iChoice = str_to_num(cmd);&lt;br /&gt;
	&lt;br /&gt;
	g_Votes[iChoice]++;&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;
=== Fenito ===&lt;br /&gt;
The end. You have completed the Beginner's Menu Tutorial. Using the new menu system we have more control over the menu. In the next tutorial you will see how powerfull the new menu system is. The use of callbacks and destroying and creating menus.&lt;br /&gt;
Here is the completed code after the menu.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new g_Menu;	// Main Menu handler&lt;br /&gt;
new g_Votes[3];	// Store Yes votes at 1, No at 2&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
	// Register Our Plugin&lt;br /&gt;
	register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Register our Change Level vote menu&lt;br /&gt;
	g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Now we need to build our menu&lt;br /&gt;
	build_menu();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
build_menu()&lt;br /&gt;
{&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;Yes&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;No&amp;quot;, &amp;quot;2&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	menu_setprop(g_Menu, MPROP_PERPAGE, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public startvote(id)&lt;br /&gt;
{&lt;br /&gt;
	for(new i = 1; i &amp;lt;= g_maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if( is_user_alive(i) )&lt;br /&gt;
		{&lt;br /&gt;
			menu_display(i, g_Menu, 0);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public menu_handle(id, menu, item)&lt;br /&gt;
{&lt;br /&gt;
	if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&lt;br /&gt;
	&lt;br /&gt;
	// Get item info&lt;br /&gt;
	new cmd[3];&lt;br /&gt;
	new access, callback;&lt;br /&gt;
	&lt;br /&gt;
	menu_item_getinfo(menu, item, access, cmd,2,_,_, callback);&lt;br /&gt;
	&lt;br /&gt;
	new iChoice = str_to_num(cmd);&lt;br /&gt;
	&lt;br /&gt;
	g_Votes[iChoice]++;&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Using_New_Menu_System&amp;diff=10271</id>
		<title>Using New Menu System</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Using_New_Menu_System&amp;diff=10271"/>
		<updated>2017-02-25T22:59:18Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting (AMX Mod X)]]&lt;br /&gt;
{{LanguageSwitch}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
Write some intro here&lt;br /&gt;
&lt;br /&gt;
== Beginners Menu Tutorial ==&lt;br /&gt;
Now lets discuss how to use the new menu system. We will go through the basics in this tutorial and make a simple Change Level vote.&lt;br /&gt;
&lt;br /&gt;
=== Includes ===&lt;br /&gt;
As always we will start out by adding the required includes&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Global Variables ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new g_Menu;	// Main Menu handler&lt;br /&gt;
new g_Votes[3];	// Store Yes votes at 1, No at 2&lt;br /&gt;
new g_maxplayers; // Store maxplayers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In here we created 2 global var's. One to hold our menu handle, and the other to store our menu votes. The 'Yes' votes will be stored in g_Votes[1] and the 'No' votes will be stored in g_Votes[2].&lt;br /&gt;
&lt;br /&gt;
=== Registering Plugin and Menu ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
	// Register Our Plugin&lt;br /&gt;
	register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
        // Cache maxplayers so we don't have to loop 32 times&lt;br /&gt;
        g_maxplayers = get_maxplayers()&lt;br /&gt;
 &lt;br /&gt;
	// Register our Change Level vote menu&lt;br /&gt;
	g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Now we need to build our menu&lt;br /&gt;
	build_menu();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets break this down. &lt;br /&gt;
&lt;br /&gt;
*Registers our plugin&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*g_Menu - Our menu handle. It will be set after menu_create gets called.&lt;br /&gt;
&amp;lt;pawn&amp;gt;g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//menu_create ( title[], handler[], ml=0 )&lt;br /&gt;
//title[] - Menu title&lt;br /&gt;
//handler[] - This is a function which will get called once someone presses a key on your menu.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We made this client command so we can start our vote.&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* This is a function call. build_menu() function will construct our vote menu.&lt;br /&gt;
&amp;lt;pawn&amp;gt;build_menu();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constructing Menu ===&lt;br /&gt;
Constructing the menu is just adding needed items to your menu. Before we go ahead with adding items we must look at menu_additem native.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_additem ( menu, const name[], const command[], paccess=0, callback=-1 )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* menu - menu handle. This tells menu_additem the menu to which we are adding our item.&lt;br /&gt;
* const name[] - the item name. This is what gets displayed into the menu.&lt;br /&gt;
* const command[] - item info.&lt;br /&gt;
&lt;br /&gt;
Now lets get into constructing our menu. As said, this is a simple vote for a Change of Level. So we will only need 2 items. A &amp;quot;Yes&amp;quot; and a &amp;quot;No&amp;quot;.&lt;br /&gt;
&amp;lt;pawn&amp;gt;build_menu()&lt;br /&gt;
{&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;Yes&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;No&amp;quot;, &amp;quot;2&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	menu_setprop(g_Menu, MPROP_PERPAGE, 0);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Notes&amp;lt;/tt&amp;gt;&lt;br /&gt;
** As you can see i set the const command[] to numbers. This is for us to identify the item easier.&lt;br /&gt;
** I have also added menu_setprop. This sets our menu to have no pages. For additional properties look into newmenus.inc&lt;br /&gt;
&lt;br /&gt;
=== Displaying the Vote Menu ===&lt;br /&gt;
To display our menu we must simply use menu_display.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_display ( id, menu, page )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* id - id of the user your displaying menu to.&lt;br /&gt;
* menu - which menu are you showing the user.&lt;br /&gt;
* page - what page (of the menu) to start on. Page of the menu starts at 0.&lt;br /&gt;
&lt;br /&gt;
Ok lets proceed to our code.&lt;br /&gt;
&amp;lt;pawn&amp;gt;public startvote(id)&lt;br /&gt;
{&lt;br /&gt;
	for(new i = 1; i &amp;lt;= g_maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if( is_user_alive(i) )&lt;br /&gt;
		{&lt;br /&gt;
			menu_display(i, g_Menu, 0);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Notes:&amp;lt;/tt&amp;gt;&lt;br /&gt;
** The for loop is used to cycle through players and display the menu to players that are alive. We are looping from 1 to Max Players. Note that if you don't use the get_maxplayers() native and server slot is lower than the one you specified it will throw an error.&lt;br /&gt;
&lt;br /&gt;
=== Handling Menu Choices ===&lt;br /&gt;
Last step is actualy handling the menu choices. This happens through the menu handler function. It will get called once someone chooses an item off the menu. There are &amp;lt;b&amp;gt;3&amp;lt;/b&amp;gt; variables that are passed to the function.&lt;br /&gt;
* id - the users id&lt;br /&gt;
* menu - the menu user had open&lt;br /&gt;
* item - and the item user chose&lt;br /&gt;
&lt;br /&gt;
Now there are a few of special items like the Exit item.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MENU_EXIT	-3&lt;br /&gt;
#define	MENU_BACK	-2&lt;br /&gt;
#define MENU_MORE	-1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we must check at first if the item chosen was not one of the special ones. Note that the only special item that may cause your handler to be called is MENU_EXIT, because MENU_BACK and MENU_MORE items are entirely handled in AMXX core (you can't hook them).&lt;br /&gt;
&amp;lt;pawn&amp;gt;if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we must retrieve the item information. What we are looking for is the number we gave the item (Yes = 1, No = 2). And to do this we use menu_item_getinfo.&lt;br /&gt;
&amp;lt;pawn&amp;gt;menu_item_getinfo ( menu, item, &amp;amp;access, command[], cmdlen, name[]=&amp;quot;&amp;quot;, namelen=0, &amp;amp;callback )&amp;lt;/pawn&amp;gt;&lt;br /&gt;
* menu - the menu where the item exists.&lt;br /&gt;
* item - the item itself&lt;br /&gt;
* &amp;amp;access - (edit)&lt;br /&gt;
* command[] - (edit)(this is where we stored our item identification numbers)&lt;br /&gt;
* cmdlen - length of the command[]&lt;br /&gt;
* name[] - items name&lt;br /&gt;
* namelen - length of the name&lt;br /&gt;
* &amp;amp;callback - (edit)&lt;br /&gt;
&lt;br /&gt;
After we get our items info we will convert the command[] to a number (will either be a 1 or 2) and update the g_Votes array with the appropriate vote chosen.&lt;br /&gt;
Here is our finished handle function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public menu_handle(id, menu, item)&lt;br /&gt;
{&lt;br /&gt;
	if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&lt;br /&gt;
	&lt;br /&gt;
	// Get item info&lt;br /&gt;
	new cmd[3];&lt;br /&gt;
	new access, callback;&lt;br /&gt;
	&lt;br /&gt;
	menu_item_getinfo(menu, item, access, cmd,2,_,_, callback);&lt;br /&gt;
	&lt;br /&gt;
	new iChoice = str_to_num(cmd);&lt;br /&gt;
	&lt;br /&gt;
	g_Votes[iChoice]++;&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;
=== Fenito ===&lt;br /&gt;
The end. You have completed the Beginner's Menu Tutorial. Using the new menu system we have more control over the menu. In the next tutorial you will see how powerfull the new menu system is. The use of callbacks and destroying and creating menus.&lt;br /&gt;
Here is the completed code after the menu.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new g_Menu;	// Main Menu handler&lt;br /&gt;
new g_Votes[3];	// Store Yes votes at 1, No at 2&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
	// Register Our Plugin&lt;br /&gt;
	register_plugin(&amp;quot;Vote Menu&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;Freecode&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Register our Change Level vote menu&lt;br /&gt;
	g_Menu = menu_create(&amp;quot;Change Level?&amp;quot;,&amp;quot;menu_handle&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	register_clcmd(&amp;quot;amx_startvote&amp;quot;,&amp;quot;startvote&amp;quot;,ADMIN_CFG,&amp;quot;Gaben&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// Now we need to build our menu&lt;br /&gt;
	build_menu();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
build_menu()&lt;br /&gt;
{&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;Yes&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
	menu_additem(g_Menu, &amp;quot;No&amp;quot;, &amp;quot;2&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	menu_setprop(g_Menu, MPROP_PERPAGE, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public startvote(id)&lt;br /&gt;
{&lt;br /&gt;
	for(new i = 1; i =&amp;lt; g_maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if( is_user_alive(i) )&lt;br /&gt;
		{&lt;br /&gt;
			menu_display(i, g_Menu, 0);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public menu_handle(id, menu, item)&lt;br /&gt;
{&lt;br /&gt;
	if( item &amp;lt; 0 ) return PLUGIN_CONTINUE;&lt;br /&gt;
	&lt;br /&gt;
	// Get item info&lt;br /&gt;
	new cmd[3];&lt;br /&gt;
	new access, callback;&lt;br /&gt;
	&lt;br /&gt;
	menu_item_getinfo(menu, item, access, cmd,2,_,_, callback);&lt;br /&gt;
	&lt;br /&gt;
	new iChoice = str_to_num(cmd);&lt;br /&gt;
	&lt;br /&gt;
	g_Votes[iChoice]++;&lt;br /&gt;
	&lt;br /&gt;
	return PLUGIN_HANDLED;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_Cvars_(AMX_Mod_X)&amp;diff=10270</id>
		<title>Scripting Cvars (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Scripting_Cvars_(AMX_Mod_X)&amp;diff=10270"/>
		<updated>2017-02-25T22:51:54Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CVARs]], or Console VARiables, are an easy and efficient way to store configurable variables on the server.  Half-Life 1 supports both server-side cvars and client-side cvars.  Internally, cvars are stored as both a float and a string. CVARs can be used for easy access outside the plugin. Valid example would be : Storing Weapon Knock back in a CVAR then editing it via configurable files.&lt;br /&gt;
&lt;br /&gt;
== Server-Side ==&lt;br /&gt;
To create a cvar, use &amp;lt;tt&amp;gt;register_cvar&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;register_cvar(const name[],const string[],flags = 0,Float:fvalue = 0.0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The last parameter is for backwards compatibility only, and serves no purpose in AMXx.&lt;br /&gt;
It is recommended you register CVARs during [[Core Forwards (AMX Mod X)|plugin_init]], so that other plugins may alter them at [[Core Forwards (AMX Mod X)|plugin_cfg]].&lt;br /&gt;
&lt;br /&gt;
*Parameters:&lt;br /&gt;
** name[] : The name of the CVAR you want to register&lt;br /&gt;
** string[] : The default value of the CVAR&lt;br /&gt;
** flags : See [[#Flags|Cvars (AMX Mod X)]].&lt;br /&gt;
&lt;br /&gt;
=== Getting Values ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Gets a cvar float. */&lt;br /&gt;
Float:get_cvar_float(const cvarname[]);&lt;br /&gt;
&lt;br /&gt;
/* Gets a cvar integer value. */&lt;br /&gt;
get_cvar_num(const cvarname[]);&lt;br /&gt;
&lt;br /&gt;
/* Reads a cvar value. */&lt;br /&gt;
get_cvar_string(const cvarname[],output[],iLen);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Setting Value ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sets a cvar to given value. */&lt;br /&gt;
set_cvar_string(const cvar[],const value[]);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar to given float. */&lt;br /&gt;
set_cvar_float(const cvar[],Float:value);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar with integer value. */&lt;br /&gt;
set_cvar_num(const cvarname[],value);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Flags===&lt;br /&gt;
These flags can be used for the third parameter in the &amp;lt;tt&amp;gt;register_cvar&amp;lt;/tt&amp;gt; native:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define	FCVAR_ARCHIVE		1	/* set to cause it to be saved to vars.rc */&lt;br /&gt;
#define	FCVAR_USERINFO		2	/* changes the client's info string */&lt;br /&gt;
#define	FCVAR_SERVER		4	/* notifies players when changed */&lt;br /&gt;
#define FCVAR_EXTDLL		8	/* defined by external DLL */&lt;br /&gt;
#define FCVAR_CLIENTDLL		16	/* defined by the client dll */&lt;br /&gt;
#define FCVAR_PROTECTED		32	/* It's a server cvar, but we don't send the data since it's a password, etc.  Sends 1 if it's not bland/zero, 0 otherwise as value */&lt;br /&gt;
#define FCVAR_SPONLY		64	/* This cvar cannot be changed by clients connected to a multiplayer server. */&lt;br /&gt;
#define FCVAR_PRINTABLEONLY	128	/* This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). */&lt;br /&gt;
#define FCVAR_UNLOGGED		256	/* If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can alter these flags dynamically, using the cvar flag natives:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Returns a cvar flags. */&lt;br /&gt;
get_cvar_flags(const cvar[]);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar flags (not allowed for amx_version,&lt;br /&gt;
* fun_version and sv_cheats cvars). */&lt;br /&gt;
set_cvar_flags(const cvar[],flags);&lt;br /&gt;
&lt;br /&gt;
/* Removes a cvar flags (not allowed for amx_version,&lt;br /&gt;
* fun_version and sv_cheats cvars). */&lt;br /&gt;
remove_cvar_flags(const cvar[],flags = -1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Client Side CVARs ==&lt;br /&gt;
Client side cvars cannot be created in Half-Life 1.  The cvar must exist in advance.  Furthermore, since it must be retrieved or set over the network, knowing the value at a given point in time is impossible.  You can, however, query a client for a cvar and get an asynchronous response, and use client_cmd to set a new value if necessary.&lt;br /&gt;
&lt;br /&gt;
=== Getting ===&lt;br /&gt;
Recently, VALVE added a client CVAR checking interface, which has been added to AMX Mod X:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Dispatches a client cvar query&lt;br /&gt;
//  id: Player id&lt;br /&gt;
//  cvar: cvar name&lt;br /&gt;
//  resultFunc: public handler function&lt;br /&gt;
//  paramLen + params: optional array parameter&lt;br /&gt;
// resultFunc looks like:&lt;br /&gt;
//  public callbackCvarValue(id, const cvar[], const value[])&lt;br /&gt;
// or if you use the optional parameter:&lt;br /&gt;
//  public callbackCvarValue(id, const cvar[], const value[], const param[])&lt;br /&gt;
query_client_cvar(id, const cvar[], const resultFunc[], paramlen=0, const params[] = &amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This native may appear daunting, but it is actually quite simple; the first parameter is the player, the second the cvar, the third the function called which will contain the client CVAR, and the last two are for allowing the passage of strings.&lt;br /&gt;
&lt;br /&gt;
If you wish to get an array or strting back, simply put the length you want it, and fill params will a value. Then, in your return function, you will receive an array.&lt;br /&gt;
&lt;br /&gt;
=== Setting ===&lt;br /&gt;
Setting a client side CVAR is easy; execute a new value onto the client:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;client_cmd(player_id,&amp;quot;cvar value&amp;quot;)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Locking ===&lt;br /&gt;
&lt;br /&gt;
Since the client can change cvar values back as soon as they're set, it might be necessary to lock them. Since alias's are executed before cvars, you can create an alias of the same name of the cvar, thus locking the cvar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;//CVAR: cvar_ex.&lt;br /&gt;
client_cmd(player_id,&amp;quot;cvar_ex 1&amp;quot;)&lt;br /&gt;
client_cmd(player_id,&amp;quot;;alias cvar_ex&amp;quot;)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the cvar cannot be changed by the player or the server; it is locked.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_Cvars_(AMX_Mod_X)&amp;diff=10269</id>
		<title>Scripting Cvars (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Scripting_Cvars_(AMX_Mod_X)&amp;diff=10269"/>
		<updated>2017-02-25T22:51:09Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CVARs]], or Console VARiables, are an easy and efficient way to store configurable variables on the server.  Half-Life 1 supports both server-side cvars and client-side cvars.  Internally, cvars are stored as both a float and a string. CVARs can be used for easy access outside the plugin. Valid example would be : Storing Weapon Knock back in a CVAR then edit it via configurable files.&lt;br /&gt;
&lt;br /&gt;
== Server-Side ==&lt;br /&gt;
To create a cvar, use &amp;lt;tt&amp;gt;register_cvar&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;register_cvar(const name[],const string[],flags = 0,Float:fvalue = 0.0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The last parameter is for backwards compatibility only, and serves no purpose in AMXx.&lt;br /&gt;
It is recommended you register CVARs during [[Core Forwards (AMX Mod X)|plugin_init]], so that other plugins may alter them at [[Core Forwards (AMX Mod X)|plugin_cfg]].&lt;br /&gt;
&lt;br /&gt;
*Parameters:&lt;br /&gt;
** name[] : The name of the CVAR you want to register&lt;br /&gt;
** string[] : The default value of the CVAR&lt;br /&gt;
** flags : See [[#Flags|Cvars (AMX Mod X)]].&lt;br /&gt;
&lt;br /&gt;
=== Getting Values ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Gets a cvar float. */&lt;br /&gt;
Float:get_cvar_float(const cvarname[]);&lt;br /&gt;
&lt;br /&gt;
/* Gets a cvar integer value. */&lt;br /&gt;
get_cvar_num(const cvarname[]);&lt;br /&gt;
&lt;br /&gt;
/* Reads a cvar value. */&lt;br /&gt;
get_cvar_string(const cvarname[],output[],iLen);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Setting Value ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sets a cvar to given value. */&lt;br /&gt;
set_cvar_string(const cvar[],const value[]);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar to given float. */&lt;br /&gt;
set_cvar_float(const cvar[],Float:value);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar with integer value. */&lt;br /&gt;
set_cvar_num(const cvarname[],value);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Flags===&lt;br /&gt;
These flags can be used for the third parameter in the &amp;lt;tt&amp;gt;register_cvar&amp;lt;/tt&amp;gt; native:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define	FCVAR_ARCHIVE		1	/* set to cause it to be saved to vars.rc */&lt;br /&gt;
#define	FCVAR_USERINFO		2	/* changes the client's info string */&lt;br /&gt;
#define	FCVAR_SERVER		4	/* notifies players when changed */&lt;br /&gt;
#define FCVAR_EXTDLL		8	/* defined by external DLL */&lt;br /&gt;
#define FCVAR_CLIENTDLL		16	/* defined by the client dll */&lt;br /&gt;
#define FCVAR_PROTECTED		32	/* It's a server cvar, but we don't send the data since it's a password, etc.  Sends 1 if it's not bland/zero, 0 otherwise as value */&lt;br /&gt;
#define FCVAR_SPONLY		64	/* This cvar cannot be changed by clients connected to a multiplayer server. */&lt;br /&gt;
#define FCVAR_PRINTABLEONLY	128	/* This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). */&lt;br /&gt;
#define FCVAR_UNLOGGED		256	/* If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can alter these flags dynamically, using the cvar flag natives:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Returns a cvar flags. */&lt;br /&gt;
get_cvar_flags(const cvar[]);&lt;br /&gt;
&lt;br /&gt;
/* Sets a cvar flags (not allowed for amx_version,&lt;br /&gt;
* fun_version and sv_cheats cvars). */&lt;br /&gt;
set_cvar_flags(const cvar[],flags);&lt;br /&gt;
&lt;br /&gt;
/* Removes a cvar flags (not allowed for amx_version,&lt;br /&gt;
* fun_version and sv_cheats cvars). */&lt;br /&gt;
remove_cvar_flags(const cvar[],flags = -1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Client Side CVARs ==&lt;br /&gt;
Client side cvars cannot be created in Half-Life 1.  The cvar must exist in advance.  Furthermore, since it must be retrieved or set over the network, knowing the value at a given point in time is impossible.  You can, however, query a client for a cvar and get an asynchronous response, and use client_cmd to set a new value if necessary.&lt;br /&gt;
&lt;br /&gt;
=== Getting ===&lt;br /&gt;
Recently, VALVE added a client CVAR checking interface, which has been added to AMX Mod X:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Dispatches a client cvar query&lt;br /&gt;
//  id: Player id&lt;br /&gt;
//  cvar: cvar name&lt;br /&gt;
//  resultFunc: public handler function&lt;br /&gt;
//  paramLen + params: optional array parameter&lt;br /&gt;
// resultFunc looks like:&lt;br /&gt;
//  public callbackCvarValue(id, const cvar[], const value[])&lt;br /&gt;
// or if you use the optional parameter:&lt;br /&gt;
//  public callbackCvarValue(id, const cvar[], const value[], const param[])&lt;br /&gt;
query_client_cvar(id, const cvar[], const resultFunc[], paramlen=0, const params[] = &amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This native may appear daunting, but it is actually quite simple; the first parameter is the player, the second the cvar, the third the function called which will contain the client CVAR, and the last two are for allowing the passage of strings.&lt;br /&gt;
&lt;br /&gt;
If you wish to get an array or strting back, simply put the length you want it, and fill params will a value. Then, in your return function, you will receive an array.&lt;br /&gt;
&lt;br /&gt;
=== Setting ===&lt;br /&gt;
Setting a client side CVAR is easy; execute a new value onto the client:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;client_cmd(player_id,&amp;quot;cvar value&amp;quot;)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Locking ===&lt;br /&gt;
&lt;br /&gt;
Since the client can change cvar values back as soon as they're set, it might be necessary to lock them. Since alias's are executed before cvars, you can create an alias of the same name of the cvar, thus locking the cvar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;//CVAR: cvar_ex.&lt;br /&gt;
client_cmd(player_id,&amp;quot;cvar_ex 1&amp;quot;)&lt;br /&gt;
client_cmd(player_id,&amp;quot;;alias cvar_ex&amp;quot;)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the cvar cannot be changed by the player or the server; it is locked.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10253</id>
		<title>Advanced Scripting (AMX Mod X)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Advanced_Scripting_(AMX_Mod_X)&amp;diff=10253"/>
		<updated>2017-01-23T21:00:28Z</updated>

		<summary type="html">&lt;p&gt;Edon1337: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will briefly summarize some of the more advanced topics of [[:Category:Scripting (AMX Mod X)|AMX Mod X Scripting]].&lt;br /&gt;
&lt;br /&gt;
=Tasks=&lt;br /&gt;
&lt;br /&gt;
Tasks are timers that let you run code at an interval, either once or repeated. They are useful for things like waiting a few seconds, setting objects to destroy themselves, or just repeating a task over and over.&lt;br /&gt;
&lt;br /&gt;
A task can be set in a number of different ways. The actual function is set_task():&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_task(Float:time,const function[],id = 0,parameter[]=&amp;quot;&amp;quot;,len = 0,flags[]=&amp;quot;&amp;quot;, repeat = 0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameters break down as such:&lt;br /&gt;
&lt;br /&gt;
* Float:time - Interval of timer in seconds (minimum 0.1 seconds)&lt;br /&gt;
* function[] - A string that contains the public function to run on the timer&lt;br /&gt;
* id - A unique id to assign to the task&lt;br /&gt;
* parameter - An array contain data to send to the timer function&lt;br /&gt;
* len - Size of the array to send to the timer function&lt;br /&gt;
* flags - One of the following:&lt;br /&gt;
** &amp;quot;a&amp;quot; - Repeat task a specified number of times&lt;br /&gt;
** &amp;quot;b&amp;quot; - Loop task infinitely&lt;br /&gt;
** &amp;quot;c&amp;quot; - do task on time after a map timeleft&lt;br /&gt;
** &amp;quot;d&amp;quot; - do task on time before a map timeleft&lt;br /&gt;
* repeat - If flags is &amp;quot;a&amp;quot;, specifies the number of times to repeat the task&lt;br /&gt;
&lt;br /&gt;
An example of a task is below. It will slap a specified player 5 times, once per second.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//the timed function receives the parameter array and its task id&lt;br /&gt;
public slapTask(params[], id)&lt;br /&gt;
{&lt;br /&gt;
   new player = params[0]&lt;br /&gt;
   user_slap(player, 5)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public start_slapping(id)&lt;br /&gt;
{&lt;br /&gt;
   new params[1]&lt;br /&gt;
   params[0] = id&lt;br /&gt;
   //we don't need a specific id&lt;br /&gt;
   set_task(1.0, &amp;quot;slapTask&amp;quot;, 0, params, 1, &amp;quot;a&amp;quot;, 5)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that if you specify 0 for parameter length, then the task function should look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public slapTask(id)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Menus=&lt;br /&gt;
&lt;br /&gt;
Menus are HUD messages that give a player a choice of options to select. They are quite messy to deal with but can be very useful for things like voting and command selection.&lt;br /&gt;
&lt;br /&gt;
Menus must be registered by two things - a set of &amp;quot;keys&amp;quot; that tells how many options to register and a string which identifies the menu as unique. This string must appear in the beginning of every menu you want to trigger your function. When you display a menu, you can show it to one or more players. Once they hit a key, the result of their key press will be sent to the function you registered the menu to.&lt;br /&gt;
&lt;br /&gt;
For our example, we'll make a menu that displays a list of guns: AK47, M4A1, or AWP, to a player. Whichever he selects, he will be given.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two commands are apparent here - register_menuid and register_menucmd. register_menuid registers a short phrase that will appear at the beginning of the menu, then returns an id. This id is the first parameter to register_menucmd. The second parameter to register_menucmd is the key configuration. Our menu will have three options, so we've added three menu keys in. In actuality, these are bitwise flags totalling &amp;quot;7&amp;quot;, but that's not important. The last parameter is the public function that will handle the menu results.&lt;br /&gt;
&lt;br /&gt;
Next, how do we show the menu? Let's make a quick console command: &amp;quot;giveme&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    register_clcmd(&amp;quot;giveme&amp;quot;, &amp;quot;showWeaponMenu&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
register_clcmd is similar to register_concmd, except it only takes two parameters. It's used to register any command a client can use (except for special ones, like +attack).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//The clcmd function will just give us the player id&lt;br /&gt;
public showWeaponMenu(id)&lt;br /&gt;
{&lt;br /&gt;
    new menu[192]&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
&lt;br /&gt;
    format(menu, 191, &amp;quot;Which Weapon?^n^n1. AK47^n2. M4A1^n3. AWP&amp;quot;)&lt;br /&gt;
    show_menu(id, keys, menu)&lt;br /&gt;
    return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Our menu function will get the player id and the key they pressed&lt;br /&gt;
public giveWeapon(id, key)&lt;br /&gt;
{&lt;br /&gt;
    //key will start at zero&lt;br /&gt;
    if (key == 0)&lt;br /&gt;
    {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_ak47&amp;quot;)&lt;br /&gt;
    } else if (key == 1) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_m4a1&amp;quot;)&lt;br /&gt;
    } else if (key == 2) {&lt;br /&gt;
         give_item(id, &amp;quot;weapon_awp&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we're done! The format line may be a little confusing. The &amp;quot;^n&amp;quot; means &amp;quot;new line&amp;quot;, so the menu looks nicely formatted. You can use other modifiers in VGUI2 mods, such as &amp;quot;\w&amp;quot; for white text, &amp;quot;\r&amp;quot; for red text, and &amp;quot;\y&amp;quot; for yellow text. When a player types the command, he will see the menu. When he hits a key, the giveWeapon function will receive his id and the key number he pressed. Then he will get a gun corresponding to what he chose.&lt;br /&gt;
&lt;br /&gt;
=Events/Messages=&lt;br /&gt;
&lt;br /&gt;
For this demonstration, we're going to extend the above example. Every time a player respawns, he will be shown the menu to choose a weapon (note - we're ignoring other things like blocking buying and removing buyzones, this is just a demonstration).&lt;br /&gt;
&lt;br /&gt;
Messages are a way for Half-Life clients to talk to servers, and vice versa. They are specially formatted lists of parameters. For example, the message &amp;quot;DeathMsg&amp;quot; (message id 83) has three parameters: Attacker (byte), Victim (byte), and Weapon (string). You can either capture messages or send them. Here, we'll do a simple demonstration of both. First let's make it so a user gets their gun menu when they spawn.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Menu Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    new keys = MENU_KEY_0|MENU_KEY_1|MENU_KEY_2&lt;br /&gt;
    register_menucmd(register_menuid(&amp;quot;Which Weapon?&amp;quot;), keys, &amp;quot;giveWeapon&amp;quot;)&lt;br /&gt;
    //flags - b means &amp;quot;sent to one target&amp;quot;, e means &amp;quot;target is alive&amp;quot;&lt;br /&gt;
    //this event is sent when a player spawns&lt;br /&gt;
    register_event(&amp;quot;ResetHUD&amp;quot;, &amp;quot;hook_hud&amp;quot;, &amp;quot;be&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_hud(id)&lt;br /&gt;
{&lt;br /&gt;
    //since we specify no parameters to the task,&lt;br /&gt;
    //the task id will be given to the function&lt;br /&gt;
    //this is useful because we can reuse our old&lt;br /&gt;
    //show menu function which takes an id&lt;br /&gt;
    set_task(0.2, &amp;quot;showWeaponMenu&amp;quot;, id)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we've set a small delay when we receive the message - this is to make sure that the user has had time to respawn. register_event can take more parameters in order to help restrict the event you catch - for example only matching certain parameters. You can read more about this in the function reference.&lt;br /&gt;
&lt;br /&gt;
Now, let's say we want to figure out when a player has died...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Message Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this message informs everyone of a death, so we use&lt;br /&gt;
    // flag &amp;quot;a&amp;quot; - global event&lt;br /&gt;
    register_event(&amp;quot;DeathMsg&amp;quot;, &amp;quot;hook_death&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public hook_death()&lt;br /&gt;
{&lt;br /&gt;
    new Killer = read_data(1) //get the first message parameter&lt;br /&gt;
    new Victim = read_data(2) //get the second message parameter&lt;br /&gt;
    new headshot = read_data(3) //was this a headshot?&lt;br /&gt;
    new weapon[32]&lt;br /&gt;
    read_data(4, weapon, 31)  //get the weapon name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, let's say we want to make a simple function for generating a death message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock make_deathMsg(Killer, Victim, const weapon[])&lt;br /&gt;
{&lt;br /&gt;
    //message_begin starts a message.  NEVER start two messages at once.&lt;br /&gt;
    //MSG_ALL means send the message to everyone&lt;br /&gt;
    //get_user_msgid returns the id of a message name&lt;br /&gt;
    //{0,0,0} is the origin vector - not used here&lt;br /&gt;
    //0 is the target - no specific target here&lt;br /&gt;
    message_begin(MSG_ALL, get_user_msgid(&amp;quot;DeathMsg&amp;quot;), {0,0,0}, 0) &lt;br /&gt;
    write_byte(Killer)&lt;br /&gt;
    write_byte(Victim)&lt;br /&gt;
    write_string(weapon)&lt;br /&gt;
    message_end()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find more about messages, consult the HLSDK, AMX Mod X forums, HL-related programming sites, or other plugins. To list the messages a mod has, type &amp;quot;meta game&amp;quot; in the server console (with metamod loaded). You can also use register_message, the more advanced message disection method found in the Engine module.&lt;br /&gt;
&lt;br /&gt;
=Catching Log Messages=&lt;br /&gt;
&lt;br /&gt;
Catching log messages is not used heavily any more, but it's still good to know how to do it. As log messages are sent by the mod, AMX Mod X will be able to catch them and let you hook them. For our example, let's give everyone $16,000 on round start.&lt;br /&gt;
&lt;br /&gt;
The log messages for rounds are sent like this: World triggered &amp;quot;Round_Start&amp;quot;. AMX Mod X will consider &amp;quot;World_triggered&amp;quot; as the first parameter and &amp;quot;Round_Start&amp;quot; as the second parameter. So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Log Demo&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    //this will filter for two parameters&lt;br /&gt;
    //roundstart is the public function&lt;br /&gt;
    register_logevent(&amp;quot;roundstart&amp;quot;, 2, &amp;quot;0=World triggered&amp;quot;, &amp;quot;1=Round_Start&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundstart()&lt;br /&gt;
{&lt;br /&gt;
    //set a small delay to make sure everyone spawns&lt;br /&gt;
    set_task(1.0, &amp;quot;roundDelay&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public roundDelay(taskId)&lt;br /&gt;
{&lt;br /&gt;
    new players[32], num&lt;br /&gt;
    get_players(players, num)&lt;br /&gt;
    new i&lt;br /&gt;
    for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
         cs_set_user_money(players[i], 16000)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also read specific log parameters with read_logdata(), which can only be used inside the &amp;quot;plugin_log()&amp;quot; forward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//receives all log messages&lt;br /&gt;
public plugin_log()&lt;br /&gt;
{&lt;br /&gt;
    new data[32]&lt;br /&gt;
    read_logdata(data, 31)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Multi-Lingual Support=&lt;br /&gt;
&lt;br /&gt;
Adding multi-lingual support to a plugin can be difficult, but it's usually worth it if you have clients who are willing to translate your strings into their native language.&lt;br /&gt;
&lt;br /&gt;
The first step is to identify what needs to be translated. Say you have a call like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new score = get_score()&lt;br /&gt;
client_print(id, print_chat, &amp;quot;[AMXX] Your score is %d&amp;quot;, score)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a good candidate for being multi-lingual. First, create a .txt file (preferrably named after your plugin) and store it in addons\amxmodx\data\lang\. Let's use &amp;quot;myplugin.txt&amp;quot; for the example. For each language, add an entry to the file. Entries are set up as 'keys', which are matched to 'translation strings'. Observe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(addons\amxmodx\data\lang\myplugin.txt)&lt;br /&gt;
&lt;br /&gt;
[en]&lt;br /&gt;
SCORE_MSG = Your score is %d&lt;br /&gt;
&lt;br /&gt;
[de]&lt;br /&gt;
SCORE_MSG = Ihr Spielergebnis ist %d&lt;br /&gt;
&lt;br /&gt;
[es]&lt;br /&gt;
SCORE_MSG = Su cuenta es %d&lt;br /&gt;
&lt;br /&gt;
[fr]&lt;br /&gt;
SCORE_MSG = Votre score est %d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, in plugin_init(), you must register the language keys:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    //assumes placed in amxmodx\data\lang&lt;br /&gt;
    register_dictionary(&amp;quot;myplugin.txt&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, here comes the hard part. AMX Mod X's Multi-Lingual API is built into the format() style routines. For anything that looks like or uses format()-style strings, you can use the ML API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(id, print_chat, &amp;quot;[AMXX] %L&amp;quot;, id, &amp;quot;SCORE_MSG&amp;quot;, get_score())&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's break this down. For each %L that appears, we need at least two parameters. The first parameter is the TARGET. This must be a player id, LANG_SERVER (meaning show in the server's native language), or LANG_PLAYER. LANG_PLAYER is a special modifier that should only be used when sending a message to all players - it means &amp;quot;show in every player's native language&amp;quot;. The second parameter is the key string that identifies the language phrase to translate. Lastly, if the translated string requires any parameters itself (ours needs %d, one integer), that must be added as well.&lt;br /&gt;
&lt;br /&gt;
You can get very complicated designs with this, but it's recommended that you keep things simple for clarity. Here is a final example using a global message to all players, assuming the key HELLO is properly translated in all the languages available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;    client_print(0, print_chat, &amp;quot;[AMXX] %L&amp;quot;, LANG_PLAYER, &amp;quot;HELLO&amp;quot;)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=SQL Support=&lt;br /&gt;
&lt;br /&gt;
SQL support has greatly improved in AMX Mod X. There is a common set of natives that work with a single driver, so as long as one (and only one) SQL module is loaded, the SQL (or DBI) natives will work. Here is a short primer on how to use the DBI natives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Create a connection&lt;br /&gt;
	new Sql:mysql = dbi_connect(&amp;quot;localhost&amp;quot;, &amp;quot;dvander&amp;quot;, &amp;quot;pass&amp;quot;, &amp;quot;dbase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the connection is less than 1, it is bad	&lt;br /&gt;
	if (mysql &amp;lt; SQL_OK) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error1: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Connection handle: %d&amp;quot;, mysql)&lt;br /&gt;
//Run a query&lt;br /&gt;
	new Result:ret = dbi_query(mysql, &amp;quot;INSERT INTO config (keyname, val) VALUES ('amx', 'yes')&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than RESULT_NONE, it failed	&lt;br /&gt;
	if (ret &amp;lt; RESULT_NONE) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error2: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Do a select query	&lt;br /&gt;
	new Result:res = dbi_query(mysql, &amp;quot;SELECT * FROM config&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
//If the query is less than or equal to RESULT_FAILED, you got an invalid result and can't do anything with it.&lt;br /&gt;
	if (res &amp;lt;= RESULT_FAILED) {&lt;br /&gt;
		new err[255]&lt;br /&gt;
		new errNum = dbi_error(mysql, err, 254)&lt;br /&gt;
		server_print(&amp;quot;error3: %s|%d&amp;quot;, err, errNum)&lt;br /&gt;
		return 1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	server_print(&amp;quot;Result handle: %d&amp;quot;, res)&lt;br /&gt;
&lt;br /&gt;
//Loop through the result set	&lt;br /&gt;
	while (res &amp;amp;&amp;amp; dbi_nextrow(res)&amp;gt;0) {&lt;br /&gt;
		new qry[32]&lt;br /&gt;
//Get the column/field called &amp;quot;keyname&amp;quot; from the result set&lt;br /&gt;
		dbi_result(res, &amp;quot;keyname&amp;quot;, qry, 32)&lt;br /&gt;
		server_print(&amp;quot;result: %s&amp;quot;, qry)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Free the result set	&lt;br /&gt;
	dbi_free_result(res)&lt;br /&gt;
&lt;br /&gt;
//Close the connection	&lt;br /&gt;
	dbi_close(mysql)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Regular Expressions=&lt;br /&gt;
&lt;br /&gt;
Regular Expressions let you describe ways in which to break down strings. They are extremely powerful. AMX Mod X uses the Perl Compatible RE library, you can read the specifics at their site. AMX Mod X offers regular expressions with the regex_amxx module. Here is a short example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
    register_plugin(&amp;quot;Regex&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
    register_srvcmd(&amp;quot;amx_regex&amp;quot;, &amp;quot;cmdtest&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmdtest()&lt;br /&gt;
{&lt;br /&gt;
    new str[] = &amp;quot;It's Walky!&amp;quot;&lt;br /&gt;
    //this pattern will match any string which contains&lt;br /&gt;
    // two groupings of characters separated by a space&lt;br /&gt;
    // the two groupings are substrings 1 and 2&lt;br /&gt;
    new pattern[] = &amp;quot;(.+) (.+)&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    new num, error[128]&lt;br /&gt;
    //str = string&lt;br /&gt;
    //pattern = pattern to use&lt;br /&gt;
    //num = special return case code&lt;br /&gt;
    //error = if there's an error, it will go here&lt;br /&gt;
    //127 - error's max length&lt;br /&gt;
    new Regex:re = regex_match(str, pattern, num, error, 127)&lt;br /&gt;
&lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)    &lt;br /&gt;
&lt;br /&gt;
    //REGEX_OK means there was a match&lt;br /&gt;
    if (re &amp;gt;= REGEX_OK)&lt;br /&gt;
    {&lt;br /&gt;
        new str2[64]&lt;br /&gt;
        new i&lt;br /&gt;
        //since it returned REGEX_OK, num has&lt;br /&gt;
        // the number of substrings matched by the pattern.&lt;br /&gt;
        //the first substring (0) seems to match the whole string.&lt;br /&gt;
        for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
        {&lt;br /&gt;
            regex_substr(re, i, str2, 63)&lt;br /&gt;
            server_print(&amp;quot;Substring %d: %s&amp;quot;, i, str2)&lt;br /&gt;
        }&lt;br /&gt;
        //the regular expression matcher uses memory.&lt;br /&gt;
        //you must free it if you get REGEX_OK&lt;br /&gt;
        //This will also set re to 0.&lt;br /&gt;
        regex_free(re)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //note the invalid regular expression pattern&lt;br /&gt;
    //this will return REGEX_PATTERN_FAIL, -1&lt;br /&gt;
    re = regex_match(&amp;quot;Bruno the Bandit&amp;quot;, &amp;quot;.+(]&amp;quot;, num, error, 127)&lt;br /&gt;
    &lt;br /&gt;
    server_print(&amp;quot;Result=%d, num=%d, error=%s&amp;quot;, re, num, error)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you compile and run this script (amx_regex in server console) you will see the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Result=1, num=3, error=&lt;br /&gt;
Substring 0: It's Walky!&lt;br /&gt;
Substring 1: It's&lt;br /&gt;
Substring 2: Walky!&lt;br /&gt;
Result=-1, num=4, error=missing ) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the third parameter to &amp;quot;regex_match()&amp;quot; is special. It's either the number of substrings, a match error code, or a pattern error position (depending on the return value).&lt;br /&gt;
&lt;br /&gt;
=Entities=&lt;br /&gt;
&lt;br /&gt;
Entities are basically any dynamic structure in Half-Life. Players, weapons, grenades, and other little objects laying around are entities. They have a unique &amp;quot;entity id&amp;quot; which you can use to change their values.&lt;br /&gt;
&lt;br /&gt;
I won't go into this too deeply as it's a complicated subject, but the Engine module features natives that let you modify the properties of entities, or search for entities in game by their class/owner (class is the type of entity, such as &amp;quot;player&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
For this example, we'll make an entity that looks like a fake player holding a gun.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	//create a basic entity&lt;br /&gt;
	new entid = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	//set its classname&lt;br /&gt;
	entity_set_string(entid, EV_SZ_classname, &amp;quot;some_guy&amp;quot;)&lt;br /&gt;
	//set its model&lt;br /&gt;
	entity_set_model(entid, &amp;quot;models/w_suit.mdl&amp;quot;)&lt;br /&gt;
	new Float:Vec[3] = {0.0,0.0,0.0}&lt;br /&gt;
	//set its origin &lt;br /&gt;
	entity_set_origin(entid, Vec)&lt;br /&gt;
	//set some basic properties&lt;br /&gt;
	entity_set_int(entid, EV_INT_solid, 1)&lt;br /&gt;
	entity_set_int(entid, EV_INT_movetype, 6)&lt;br /&gt;
	//create the weapon - thanks to pimp_daddy!&lt;br /&gt;
	entWeapon = create_entity(&amp;quot;info_target&amp;quot;)&lt;br /&gt;
	entity_set_string(entWeapon, EV_SZ_classname, weapString)&lt;br /&gt;
	//set to follow&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_movetype, MOVETYPE_FOLLOW)&lt;br /&gt;
	entity_set_int(entWeapon, EV_INT_solid, SOLID_NOT)&lt;br /&gt;
	entity_set_edict(entWeapon, EV_ENT_aiment, entid)&lt;br /&gt;
	entity_set_model(entWeapon, &amp;quot;models/p_m4a1.mdl&amp;quot;) &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change other basic things, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//how set_user_armor() works in the fun module&lt;br /&gt;
stock set_armor(player, Float:value)&lt;br /&gt;
{&lt;br /&gt;
    entity_set_int(player, EV_FL_armorvalue, value)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=FakeMeta=&lt;br /&gt;
&lt;br /&gt;
FakeMeta is the next generation of Half-Life scripting. It essentially lets you write MetaMod plugins in Pawn. It is extremely powerful, and for this reason, it won't really be covered here. This is just to tell you what it is capable of.&lt;br /&gt;
&lt;br /&gt;
* Engine/DLL Calls&lt;br /&gt;
**There are two types of functions in the HL namespace - Engine functions and DLL functions (DLL functions are ones the game/mod library must export). Both of these can be called using the FakeMeta module using the dllfunc() and engfunc() natives. The parameters are directly passed on to MetaMod, so be careful! You could easily crash a server doing the wrong thing.&lt;br /&gt;
* Engine/DLL Hooks&lt;br /&gt;
**As stated above, HL provides Engine and DLL functions. You can also hook/supercede these calls using register_forward. You can supercede these calls using fm_return() and return PLUGIN_HANDLED. Again, make sure you know what you are doing. Malformed hooks will cause crashes.&lt;br /&gt;
* Easy entity manipulation&lt;br /&gt;
**FakeMeta replaces Engine's entity__() function with a natives called &amp;quot;pev()&amp;quot; and &amp;quot;set_pev()&amp;quot;. They are a bit easier to use. For more information see the fakemeta includes.&lt;br /&gt;
* Private Offset Hacking&lt;br /&gt;
**Private offsets are offsets into a block of memory called &amp;quot;pvPrivateData&amp;quot;. The right offsets can often modify game-specific features, such as money in Counter-Strike, or resources in Natural-Selection. However, the wrong offsets can cause game crashes.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Edon1337</name></author>
		
	</entry>
</feed>